diff options
-rw-r--r-- | tools/perf/util/data_map.c | 11 | ||||
-rw-r--r-- | tools/perf/util/data_map.h | 3 | ||||
-rw-r--r-- | tools/perf/util/header.c | 110 | ||||
-rw-r--r-- | tools/perf/util/include/linux/bitmap.h | 1 | ||||
-rw-r--r-- | tools/perf/util/include/linux/ctype.h | 2 | ||||
-rw-r--r-- | tools/perf/util/util.h | 3 |
6 files changed, 85 insertions, 45 deletions
diff --git a/tools/perf/util/data_map.c b/tools/perf/util/data_map.c index 66e58aaecce..aacb814a4ef 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) } } -int perf_header__read_build_ids(const struct perf_header *self, - int input, off_t file_size) +int perf_header__read_build_ids(int input, off_t size) { - off_t offset = self->data_offset + self->data_size; struct build_id_event bev; char filename[PATH_MAX]; + off_t offset = lseek(input, 0, SEEK_CUR); + off_t limit = offset + size; int err = -1; - if (lseek(input, offset, SEEK_SET) < 0) - return -1; - - while (offset < file_size) { + while (offset < limit) { struct dso *dso; ssize_t len; diff --git a/tools/perf/util/data_map.h b/tools/perf/util/data_map.h index c4122810e48..20b4037a823 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, int full_paths, int *cwdlen, char **cwd); -int perf_header__read_build_ids(const struct perf_header *self, - int input, off_t file_size); +int perf_header__read_build_ids(int input, off_t file_size); #endif diff --git a/tools/perf/util/header.c b/tools/perf/util/header.c index 9709d38113b..ebed4f44ed3 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) } static void -perf_header__adds_write(struct perf_header *self, int fd, bool at_exit) +perf_header__adds_write(struct perf_header *self, int fd) { - struct perf_file_section trace_sec; - u64 cur_offset = lseek(fd, 0, SEEK_CUR); + LIST_HEAD(id_list); + int nr_sections; + struct perf_file_section *feat_sec; + int sec_size; + u64 sec_start; + int idx = 0; + + if (fetch_build_id_table(&id_list)) + perf_header__set_feat(self, HEADER_BUILD_ID); + + nr_sections = bitmap_weight(self->adds_features, HEADER_FEAT_BITS); + if (!nr_sections) + return; + + feat_sec = calloc(sizeof(*feat_sec), nr_sections); + if (!feat_sec) + die("No memory"); + + sec_size = sizeof(*feat_sec) * nr_sections; + + sec_start = self->data_offset + self->data_size; + lseek(fd, sec_start + sec_size, SEEK_SET); if (perf_header__has_feat(self, HEADER_TRACE_INFO)) { + struct perf_file_section *trace_sec; + + trace_sec = &feat_sec[idx++]; + /* Write trace info */ - trace_sec.offset = lseek(fd, sizeof(trace_sec), SEEK_CUR); + trace_sec->offset = lseek(fd, 0, SEEK_CUR); read_tracing_data(fd, attrs, nr_counters); - trace_sec.size = lseek(fd, 0, SEEK_CUR) - trace_sec.offset; - - /* Write trace info headers */ - lseek(fd, cur_offset, SEEK_SET); - do_write(fd, &trace_sec, sizeof(trace_sec)); - - /* - * Update cur_offset. So that other (future) - * features can set their own infos in this place. But if we are - * the only feature, at least that seeks to the place the data - * should begin. - */ - cur_offset = lseek(fd, trace_sec.offset + trace_sec.size, SEEK_SET); + trace_sec->size = lseek(fd, 0, SEEK_CUR) - trace_sec->offset; } - if (at_exit) { - LIST_HEAD(id_list); - if (fetch_build_id_table(&id_list)) { - lseek(fd, self->data_offset + self->data_size, SEEK_SET); - perf_header__set_feat(self, HEADER_BUILD_ID); - write_buildid_table(fd, &id_list); - lseek(fd, cur_offset, SEEK_SET); - } + if (perf_header__has_feat(self, HEADER_BUILD_ID)) { + struct perf_file_section *buildid_sec; + + buildid_sec = &feat_sec[idx++]; + + /* Write build-ids */ + buildid_sec->offset = lseek(fd, 0, SEEK_CUR); + write_buildid_table(fd, &id_list); + buildid_sec->size = lseek(fd, 0, SEEK_CUR) - buildid_sec->offset; } -}; + + lseek(fd, sec_start, SEEK_SET); + do_write(fd, feat_sec, sec_size); + free(feat_sec); +} void perf_header__write(struct perf_header *self, int fd, bool at_exit) { @@ -260,10 +277,11 @@ void perf_header__write(struct perf_header *self, int fd, bool at_exit) if (events) do_write(fd, events, self->event_size); - perf_header__adds_write(self, fd, at_exit); - self->data_offset = lseek(fd, 0, SEEK_CUR); + if (at_exit) + perf_header__adds_write(self, fd); + f_header = (struct perf_file_header){ .magic = PERF_MAGIC, .size = sizeof(f_header), @@ -308,22 +326,44 @@ static void do_read(int fd, void *buf, size_t size) static void perf_header__adds_read(struct perf_header *self, int fd) { + struct perf_file_section *feat_sec; + int nr_sections; + int sec_size; + int idx = 0; + + + nr_sections = bitmap_weight(self->adds_features, HEADER_FEAT_BITS); + if (!nr_sections) + return; + + feat_sec = calloc(sizeof(*feat_sec), nr_sections); + if (!feat_sec) + die("No memory"); + + sec_size = sizeof(*feat_sec) * nr_sections; + + lseek(fd, self->data_offset + self->data_size, SEEK_SET); + + do_read(fd, feat_sec, sec_size); + if (perf_header__has_feat(self, HEADER_TRACE_INFO)) { - struct perf_file_section trace_sec; + struct perf_file_section *trace_sec; - do_read(fd, &trace_sec, sizeof(trace_sec)); - lseek(fd, trace_sec.offset, SEEK_SET); + trace_sec = &feat_sec[idx++]; + lseek(fd, trace_sec->offset, SEEK_SET); trace_report(fd); - lseek(fd, trace_sec.offset + trace_sec.size, SEEK_SET); } if (perf_header__has_feat(self, HEADER_BUILD_ID)) { - struct stat input_stat; + struct perf_file_section *buildid_sec; - fstat(fd, &input_stat); - if (perf_header__read_build_ids(self, fd, input_stat.st_size)) + buildid_sec = &feat_sec[idx++]; + lseek(fd, buildid_sec->offset, SEEK_SET); + if (perf_header__read_build_ids(fd, buildid_sec->size)) pr_debug("failed to read buildids, continuing...\n"); } + + free(feat_sec); }; struct 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 821c1033bcc..94507639a8c 100644 --- a/tools/perf/util/include/linux/bitmap.h +++ b/tools/perf/util/include/linux/bitmap.h @@ -1,2 +1,3 @@ #include "../../../../include/linux/bitmap.h" #include "../../../../include/asm-generic/bitops/find.h" +#include <linux/errno.h> diff --git a/tools/perf/util/include/linux/ctype.h b/tools/perf/util/include/linux/ctype.h index bae5783282e..a53d4ee1e0b 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 9de2329dd44..7bd5bdaeb23 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) #undef isascii #undef isspace #undef isdigit +#undef isxdigit #undef isalpha #undef isprint #undef isalnum @@ -323,6 +324,8 @@ extern unsigned char sane_ctype[256]; #define isascii(x) (((x) & ~0x7f) == 0) #define isspace(x) sane_istest(x,GIT_SPACE) #define isdigit(x) sane_istest(x,GIT_DIGIT) +#define isxdigit(x) \ + (sane_istest(toupper(x), GIT_ALPHA | GIT_DIGIT) && toupper(x) < 'G') #define isalpha(x) sane_istest(x,GIT_ALPHA) #define isalnum(x) sane_istest(x,GIT_ALPHA | GIT_DIGIT) #define isprint(x) sane_istest(x,GIT_PRINT) |