aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--tools/perf/util/data_map.c11
-rw-r--r--tools/perf/util/data_map.h3
-rw-r--r--tools/perf/util/header.c110
-rw-r--r--tools/perf/util/include/linux/bitmap.h1
-rw-r--r--tools/perf/util/include/linux/ctype.h2
-rw-r--r--tools/perf/util/util.h3
6 files changed, 85 insertions, 45 deletions
diff --git a/tools/perf/util/data_map.c b/tools/perf/util/data_map.c
index 66e58aaecce3..aacb814a4eff 100644
--- a/tools/perf/util/data_map.c
+++ b/tools/perf/util/data_map.c
@@ -70,18 +70,15 @@ process_event(event_t *event, unsigned long offset, unsigned long head)
70 } 70 }
71} 71}
72 72
73int perf_header__read_build_ids(const struct perf_header *self, 73int perf_header__read_build_ids(int input, off_t size)
74 int input, off_t file_size)
75{ 74{
76 off_t offset = self->data_offset + self->data_size;
77 struct build_id_event bev; 75 struct build_id_event bev;
78 char filename[PATH_MAX]; 76 char filename[PATH_MAX];
77 off_t offset = lseek(input, 0, SEEK_CUR);
78 off_t limit = offset + size;
79 int err = -1; 79 int err = -1;
80 80
81 if (lseek(input, offset, SEEK_SET) < 0) 81 while (offset < limit) {
82 return -1;
83
84 while (offset < file_size) {
85 struct dso *dso; 82 struct dso *dso;
86 ssize_t len; 83 ssize_t len;
87 84
diff --git a/tools/perf/util/data_map.h b/tools/perf/util/data_map.h
index c4122810e489..20b4037a8236 100644
--- a/tools/perf/util/data_map.h
+++ b/tools/perf/util/data_map.h
@@ -27,7 +27,6 @@ int mmap_dispatch_perf_file(struct perf_header **pheader,
27 int full_paths, 27 int full_paths,
28 int *cwdlen, 28 int *cwdlen,
29 char **cwd); 29 char **cwd);
30int perf_header__read_build_ids(const struct perf_header *self, 30int perf_header__read_build_ids(int input, off_t file_size);
31 int input, off_t file_size);
32 31
33#endif 32#endif
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)
diff --git a/tools/perf/util/include/linux/bitmap.h b/tools/perf/util/include/linux/bitmap.h
index 821c1033bccf..94507639a8c4 100644
--- a/tools/perf/util/include/linux/bitmap.h
+++ b/tools/perf/util/include/linux/bitmap.h
@@ -1,2 +1,3 @@
1#include "../../../../include/linux/bitmap.h" 1#include "../../../../include/linux/bitmap.h"
2#include "../../../../include/asm-generic/bitops/find.h" 2#include "../../../../include/asm-generic/bitops/find.h"
3#include <linux/errno.h>
diff --git a/tools/perf/util/include/linux/ctype.h b/tools/perf/util/include/linux/ctype.h
index bae5783282ef..a53d4ee1e0b7 100644
--- a/tools/perf/util/include/linux/ctype.h
+++ b/tools/perf/util/include/linux/ctype.h
@@ -1 +1 @@
#include "../../../../include/linux/ctype.h" #include "../util.h"
diff --git a/tools/perf/util/util.h b/tools/perf/util/util.h
index 9de2329dd44d..7bd5bdaeb235 100644
--- a/tools/perf/util/util.h
+++ b/tools/perf/util/util.h
@@ -306,6 +306,7 @@ static inline int has_extension(const char *filename, const char *ext)
306#undef isascii 306#undef isascii
307#undef isspace 307#undef isspace
308#undef isdigit 308#undef isdigit
309#undef isxdigit
309#undef isalpha 310#undef isalpha
310#undef isprint 311#undef isprint
311#undef isalnum 312#undef isalnum
@@ -323,6 +324,8 @@ extern unsigned char sane_ctype[256];
323#define isascii(x) (((x) & ~0x7f) == 0) 324#define isascii(x) (((x) & ~0x7f) == 0)
324#define isspace(x) sane_istest(x,GIT_SPACE) 325#define isspace(x) sane_istest(x,GIT_SPACE)
325#define isdigit(x) sane_istest(x,GIT_DIGIT) 326#define isdigit(x) sane_istest(x,GIT_DIGIT)
327#define isxdigit(x) \
328 (sane_istest(toupper(x), GIT_ALPHA | GIT_DIGIT) && toupper(x) < 'G')
326#define isalpha(x) sane_istest(x,GIT_ALPHA) 329#define isalpha(x) sane_istest(x,GIT_ALPHA)
327#define isalnum(x) sane_istest(x,GIT_ALPHA | GIT_DIGIT) 330#define isalnum(x) sane_istest(x,GIT_ALPHA | GIT_DIGIT)
328#define isprint(x) sane_istest(x,GIT_PRINT) 331#define isprint(x) sane_istest(x,GIT_PRINT)