diff options
Diffstat (limited to 'tools/perf/builtin-report.c')
-rw-r--r-- | tools/perf/builtin-report.c | 37 |
1 files changed, 28 insertions, 9 deletions
diff --git a/tools/perf/builtin-report.c b/tools/perf/builtin-report.c index b4e76f75ba87..e575f3039766 100644 --- a/tools/perf/builtin-report.c +++ b/tools/perf/builtin-report.c | |||
@@ -17,6 +17,7 @@ | |||
17 | #include "util/string.h" | 17 | #include "util/string.h" |
18 | 18 | ||
19 | #include "perf.h" | 19 | #include "perf.h" |
20 | #include "util/header.h" | ||
20 | 21 | ||
21 | #include "util/parse-options.h" | 22 | #include "util/parse-options.h" |
22 | #include "util/parse-events.h" | 23 | #include "util/parse-events.h" |
@@ -1385,13 +1386,27 @@ process_event(event_t *event, unsigned long offset, unsigned long head) | |||
1385 | return 0; | 1386 | return 0; |
1386 | } | 1387 | } |
1387 | 1388 | ||
1388 | static struct perf_file_header file_header; | 1389 | static struct perf_header *header; |
1390 | |||
1391 | static int perf_header__has_sample(u64 sample_mask) | ||
1392 | { | ||
1393 | int i; | ||
1394 | |||
1395 | for (i = 0; i < header->attrs; i++) { | ||
1396 | struct perf_header_attr *attr = header->attr[i]; | ||
1397 | |||
1398 | if (!(attr->attr.sample_type & sample_mask)) | ||
1399 | return 0; | ||
1400 | } | ||
1401 | |||
1402 | return 1; | ||
1403 | } | ||
1389 | 1404 | ||
1390 | static int __cmd_report(void) | 1405 | static int __cmd_report(void) |
1391 | { | 1406 | { |
1392 | int ret, rc = EXIT_FAILURE; | 1407 | int ret, rc = EXIT_FAILURE; |
1393 | unsigned long offset = 0; | 1408 | unsigned long offset = 0; |
1394 | unsigned long head = sizeof(file_header); | 1409 | unsigned long head, shift; |
1395 | struct stat stat; | 1410 | struct stat stat; |
1396 | event_t *event; | 1411 | event_t *event; |
1397 | uint32_t size; | 1412 | uint32_t size; |
@@ -1419,13 +1434,11 @@ static int __cmd_report(void) | |||
1419 | exit(0); | 1434 | exit(0); |
1420 | } | 1435 | } |
1421 | 1436 | ||
1422 | if (read(input, &file_header, sizeof(file_header)) == -1) { | 1437 | header = perf_header__read(input); |
1423 | perror("failed to read file headers"); | 1438 | head = header->data_offset; |
1424 | exit(-1); | ||
1425 | } | ||
1426 | 1439 | ||
1427 | if (sort__has_parent && | 1440 | if (sort__has_parent && |
1428 | !(file_header.sample_type & PERF_SAMPLE_CALLCHAIN)) { | 1441 | !perf_header__has_sample(PERF_SAMPLE_CALLCHAIN)) { |
1429 | fprintf(stderr, "selected --sort parent, but no callchain data\n"); | 1442 | fprintf(stderr, "selected --sort parent, but no callchain data\n"); |
1430 | exit(-1); | 1443 | exit(-1); |
1431 | } | 1444 | } |
@@ -1445,6 +1458,11 @@ static int __cmd_report(void) | |||
1445 | cwd = NULL; | 1458 | cwd = NULL; |
1446 | cwdlen = 0; | 1459 | cwdlen = 0; |
1447 | } | 1460 | } |
1461 | |||
1462 | shift = page_size * (head / page_size); | ||
1463 | offset += shift; | ||
1464 | head -= shift; | ||
1465 | |||
1448 | remap: | 1466 | remap: |
1449 | buf = (char *)mmap(NULL, page_size * mmap_window, PROT_READ, | 1467 | buf = (char *)mmap(NULL, page_size * mmap_window, PROT_READ, |
1450 | MAP_SHARED, input, offset); | 1468 | MAP_SHARED, input, offset); |
@@ -1461,9 +1479,10 @@ more: | |||
1461 | size = 8; | 1479 | size = 8; |
1462 | 1480 | ||
1463 | if (head + event->header.size >= page_size * mmap_window) { | 1481 | if (head + event->header.size >= page_size * mmap_window) { |
1464 | unsigned long shift = page_size * (head / page_size); | ||
1465 | int ret; | 1482 | int ret; |
1466 | 1483 | ||
1484 | shift = page_size * (head / page_size); | ||
1485 | |||
1467 | ret = munmap(buf, page_size * mmap_window); | 1486 | ret = munmap(buf, page_size * mmap_window); |
1468 | assert(ret == 0); | 1487 | assert(ret == 0); |
1469 | 1488 | ||
@@ -1501,7 +1520,7 @@ more: | |||
1501 | 1520 | ||
1502 | head += size; | 1521 | head += size; |
1503 | 1522 | ||
1504 | if (offset + head >= sizeof(file_header) + file_header.data_size) | 1523 | if (offset + head >= header->data_offset + header->data_size) |
1505 | goto done; | 1524 | goto done; |
1506 | 1525 | ||
1507 | if (offset + head < stat.st_size) | 1526 | if (offset + head < stat.st_size) |