aboutsummaryrefslogtreecommitdiffstats
path: root/tools/perf/util/header.c
diff options
context:
space:
mode:
Diffstat (limited to 'tools/perf/util/header.c')
-rw-r--r--tools/perf/util/header.c110
1 files changed, 75 insertions, 35 deletions
diff --git a/tools/perf/util/header.c b/tools/perf/util/header.c
index 9709d38113b1..ebed4f44ed36 100644
--- a/tools/perf/util/header.c
+++ b/tools/perf/util/header.c
@@ -186,41 +186,58 @@ static void write_buildid_table(int fd, struct list_head *id_head)
186} 186}
187 187
188static void 188static void
189perf_header__adds_write(struct perf_header *self, int fd, bool at_exit) 189perf_header__adds_write(struct perf_header *self, int fd)
190{ 190{
191 struct perf_file_section trace_sec; 191 LIST_HEAD(id_list);
192 u64 cur_offset = lseek(fd, 0, SEEK_CUR); 192 int nr_sections;
193 struct perf_file_section *feat_sec;
194 int sec_size;
195 u64 sec_start;
196 int idx = 0;
197
198 if (fetch_build_id_table(&id_list))
199 perf_header__set_feat(self, HEADER_BUILD_ID);
200
201 nr_sections = bitmap_weight(self->adds_features, HEADER_FEAT_BITS);
202 if (!nr_sections)
203 return;
204
205 feat_sec = calloc(sizeof(*feat_sec), nr_sections);
206 if (!feat_sec)
207 die("No memory");
208
209 sec_size = sizeof(*feat_sec) * nr_sections;
210
211 sec_start = self->data_offset + self->data_size;
212 lseek(fd, sec_start + sec_size, SEEK_SET);
193 213
194 if (perf_header__has_feat(self, HEADER_TRACE_INFO)) { 214 if (perf_header__has_feat(self, HEADER_TRACE_INFO)) {
215 struct perf_file_section *trace_sec;
216
217 trace_sec = &feat_sec[idx++];
218
195 /* Write trace info */ 219 /* Write trace info */
196 trace_sec.offset = lseek(fd, sizeof(trace_sec), SEEK_CUR); 220 trace_sec->offset = lseek(fd, 0, SEEK_CUR);
197 read_tracing_data(fd, attrs, nr_counters); 221 read_tracing_data(fd, attrs, nr_counters);
198 trace_sec.size = lseek(fd, 0, SEEK_CUR) - trace_sec.offset; 222 trace_sec->size = lseek(fd, 0, SEEK_CUR) - trace_sec->offset;
199
200 /* Write trace info headers */
201 lseek(fd, cur_offset, SEEK_SET);
202 do_write(fd, &trace_sec, sizeof(trace_sec));
203
204 /*
205 * Update cur_offset. So that other (future)
206 * features can set their own infos in this place. But if we are
207 * the only feature, at least that seeks to the place the data
208 * should begin.
209 */
210 cur_offset = lseek(fd, trace_sec.offset + trace_sec.size, SEEK_SET);
211 } 223 }
212 224
213 if (at_exit) {
214 LIST_HEAD(id_list);
215 225
216 if (fetch_build_id_table(&id_list)) { 226 if (perf_header__has_feat(self, HEADER_BUILD_ID)) {
217 lseek(fd, self->data_offset + self->data_size, SEEK_SET); 227 struct perf_file_section *buildid_sec;
218 perf_header__set_feat(self, HEADER_BUILD_ID); 228
219 write_buildid_table(fd, &id_list); 229 buildid_sec = &feat_sec[idx++];
220 lseek(fd, cur_offset, SEEK_SET); 230
221 } 231 /* Write build-ids */
232 buildid_sec->offset = lseek(fd, 0, SEEK_CUR);
233 write_buildid_table(fd, &id_list);
234 buildid_sec->size = lseek(fd, 0, SEEK_CUR) - buildid_sec->offset;
222 } 235 }
223}; 236
237 lseek(fd, sec_start, SEEK_SET);
238 do_write(fd, feat_sec, sec_size);
239 free(feat_sec);
240}
224 241
225void perf_header__write(struct perf_header *self, int fd, bool at_exit) 242void perf_header__write(struct perf_header *self, int fd, bool at_exit)
226{ 243{
@@ -260,10 +277,11 @@ void perf_header__write(struct perf_header *self, int fd, bool at_exit)
260 if (events) 277 if (events)
261 do_write(fd, events, self->event_size); 278 do_write(fd, events, self->event_size);
262 279
263 perf_header__adds_write(self, fd, at_exit);
264
265 self->data_offset = lseek(fd, 0, SEEK_CUR); 280 self->data_offset = lseek(fd, 0, SEEK_CUR);
266 281
282 if (at_exit)
283 perf_header__adds_write(self, fd);
284
267 f_header = (struct perf_file_header){ 285 f_header = (struct perf_file_header){
268 .magic = PERF_MAGIC, 286 .magic = PERF_MAGIC,
269 .size = sizeof(f_header), 287 .size = sizeof(f_header),
@@ -308,22 +326,44 @@ static void do_read(int fd, void *buf, size_t size)
308 326
309static void perf_header__adds_read(struct perf_header *self, int fd) 327static void perf_header__adds_read(struct perf_header *self, int fd)
310{ 328{
329 struct perf_file_section *feat_sec;
330 int nr_sections;
331 int sec_size;
332 int idx = 0;
333
334
335 nr_sections = bitmap_weight(self->adds_features, HEADER_FEAT_BITS);
336 if (!nr_sections)
337 return;
338
339 feat_sec = calloc(sizeof(*feat_sec), nr_sections);
340 if (!feat_sec)
341 die("No memory");
342
343 sec_size = sizeof(*feat_sec) * nr_sections;
344
345 lseek(fd, self->data_offset + self->data_size, SEEK_SET);
346
347 do_read(fd, feat_sec, sec_size);
348
311 if (perf_header__has_feat(self, HEADER_TRACE_INFO)) { 349 if (perf_header__has_feat(self, HEADER_TRACE_INFO)) {
312 struct perf_file_section trace_sec; 350 struct perf_file_section *trace_sec;
313 351
314 do_read(fd, &trace_sec, sizeof(trace_sec)); 352 trace_sec = &feat_sec[idx++];
315 lseek(fd, trace_sec.offset, SEEK_SET); 353 lseek(fd, trace_sec->offset, SEEK_SET);
316 trace_report(fd); 354 trace_report(fd);
317 lseek(fd, trace_sec.offset + trace_sec.size, SEEK_SET);
318 } 355 }
319 356
320 if (perf_header__has_feat(self, HEADER_BUILD_ID)) { 357 if (perf_header__has_feat(self, HEADER_BUILD_ID)) {
321 struct stat input_stat; 358 struct perf_file_section *buildid_sec;
322 359
323 fstat(fd, &input_stat); 360 buildid_sec = &feat_sec[idx++];
324 if (perf_header__read_build_ids(self, fd, input_stat.st_size)) 361 lseek(fd, buildid_sec->offset, SEEK_SET);
362 if (perf_header__read_build_ids(fd, buildid_sec->size))
325 pr_debug("failed to read buildids, continuing...\n"); 363 pr_debug("failed to read buildids, continuing...\n");
326 } 364 }
365
366 free(feat_sec);
327}; 367};
328 368
329struct perf_header *perf_header__read(int fd) 369struct perf_header *perf_header__read(int fd)