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 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 | ||
| 73 | int perf_header__read_build_ids(const struct perf_header *self, | 73 | int 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); |
| 30 | int perf_header__read_build_ids(const struct perf_header *self, | 30 | int 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 | ||
| 188 | static void | 188 | static void |
| 189 | perf_header__adds_write(struct perf_header *self, int fd, bool at_exit) | 189 | perf_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 | ||
| 225 | void perf_header__write(struct perf_header *self, int fd, bool at_exit) | 242 | void 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 | ||
| 309 | static void perf_header__adds_read(struct perf_header *self, int fd) | 327 | static 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 | ||
| 329 | struct perf_header *perf_header__read(int fd) | 369 | 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 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) |
