diff options
Diffstat (limited to 'tools/perf/util')
| -rw-r--r-- | tools/perf/util/event.c | 46 | ||||
| -rw-r--r-- | tools/perf/util/event.h | 12 | ||||
| -rw-r--r-- | tools/perf/util/evlist.c | 31 | ||||
| -rw-r--r-- | tools/perf/util/evlist.h | 3 | ||||
| -rw-r--r-- | tools/perf/util/evsel.c | 32 | ||||
| -rw-r--r-- | tools/perf/util/header.c | 31 | ||||
| -rw-r--r-- | tools/perf/util/header.h | 2 | ||||
| -rw-r--r-- | tools/perf/util/include/linux/list.h | 4 | ||||
| -rw-r--r-- | tools/perf/util/python.c | 13 | ||||
| -rw-r--r-- | tools/perf/util/session.c | 50 | ||||
| -rw-r--r-- | tools/perf/util/session.h | 2 | ||||
| -rw-r--r-- | tools/perf/util/ui/browsers/annotate.c | 1 |
12 files changed, 159 insertions, 68 deletions
diff --git a/tools/perf/util/event.c b/tools/perf/util/event.c index 1023f67633a4..6635fcd11ca5 100644 --- a/tools/perf/util/event.c +++ b/tools/perf/util/event.c | |||
| @@ -9,21 +9,21 @@ | |||
| 9 | #include "thread_map.h" | 9 | #include "thread_map.h" |
| 10 | 10 | ||
| 11 | static const char *perf_event__names[] = { | 11 | static const char *perf_event__names[] = { |
| 12 | [0] = "TOTAL", | 12 | [0] = "TOTAL", |
| 13 | [PERF_RECORD_MMAP] = "MMAP", | 13 | [PERF_RECORD_MMAP] = "MMAP", |
| 14 | [PERF_RECORD_LOST] = "LOST", | 14 | [PERF_RECORD_LOST] = "LOST", |
| 15 | [PERF_RECORD_COMM] = "COMM", | 15 | [PERF_RECORD_COMM] = "COMM", |
| 16 | [PERF_RECORD_EXIT] = "EXIT", | 16 | [PERF_RECORD_EXIT] = "EXIT", |
| 17 | [PERF_RECORD_THROTTLE] = "THROTTLE", | 17 | [PERF_RECORD_THROTTLE] = "THROTTLE", |
| 18 | [PERF_RECORD_UNTHROTTLE] = "UNTHROTTLE", | 18 | [PERF_RECORD_UNTHROTTLE] = "UNTHROTTLE", |
| 19 | [PERF_RECORD_FORK] = "FORK", | 19 | [PERF_RECORD_FORK] = "FORK", |
| 20 | [PERF_RECORD_READ] = "READ", | 20 | [PERF_RECORD_READ] = "READ", |
| 21 | [PERF_RECORD_SAMPLE] = "SAMPLE", | 21 | [PERF_RECORD_SAMPLE] = "SAMPLE", |
| 22 | [PERF_RECORD_HEADER_ATTR] = "ATTR", | 22 | [PERF_RECORD_HEADER_ATTR] = "ATTR", |
| 23 | [PERF_RECORD_HEADER_EVENT_TYPE] = "EVENT_TYPE", | 23 | [PERF_RECORD_HEADER_EVENT_TYPE] = "EVENT_TYPE", |
| 24 | [PERF_RECORD_HEADER_TRACING_DATA] = "TRACING_DATA", | 24 | [PERF_RECORD_HEADER_TRACING_DATA] = "TRACING_DATA", |
| 25 | [PERF_RECORD_HEADER_BUILD_ID] = "BUILD_ID", | 25 | [PERF_RECORD_HEADER_BUILD_ID] = "BUILD_ID", |
| 26 | [PERF_RECORD_FINISHED_ROUND] = "FINISHED_ROUND", | 26 | [PERF_RECORD_FINISHED_ROUND] = "FINISHED_ROUND", |
| 27 | }; | 27 | }; |
| 28 | 28 | ||
| 29 | const char *perf_event__name(unsigned int id) | 29 | const char *perf_event__name(unsigned int id) |
| @@ -35,6 +35,22 @@ const char *perf_event__name(unsigned int id) | |||
| 35 | return perf_event__names[id]; | 35 | return perf_event__names[id]; |
| 36 | } | 36 | } |
| 37 | 37 | ||
| 38 | int perf_sample_size(u64 sample_type) | ||
| 39 | { | ||
| 40 | u64 mask = sample_type & PERF_SAMPLE_MASK; | ||
| 41 | int size = 0; | ||
| 42 | int i; | ||
| 43 | |||
| 44 | for (i = 0; i < 64; i++) { | ||
| 45 | if (mask & (1ULL << i)) | ||
| 46 | size++; | ||
| 47 | } | ||
| 48 | |||
| 49 | size *= sizeof(u64); | ||
| 50 | |||
| 51 | return size; | ||
| 52 | } | ||
| 53 | |||
| 38 | static struct perf_sample synth_sample = { | 54 | static struct perf_sample synth_sample = { |
| 39 | .pid = -1, | 55 | .pid = -1, |
| 40 | .tid = -1, | 56 | .tid = -1, |
diff --git a/tools/perf/util/event.h b/tools/perf/util/event.h index 9c35170fb379..c08332871408 100644 --- a/tools/perf/util/event.h +++ b/tools/perf/util/event.h | |||
| @@ -56,6 +56,13 @@ struct read_event { | |||
| 56 | u64 id; | 56 | u64 id; |
| 57 | }; | 57 | }; |
| 58 | 58 | ||
| 59 | |||
| 60 | #define PERF_SAMPLE_MASK \ | ||
| 61 | (PERF_SAMPLE_IP | PERF_SAMPLE_TID | \ | ||
| 62 | PERF_SAMPLE_TIME | PERF_SAMPLE_ADDR | \ | ||
| 63 | PERF_SAMPLE_ID | PERF_SAMPLE_STREAM_ID | \ | ||
| 64 | PERF_SAMPLE_CPU | PERF_SAMPLE_PERIOD) | ||
| 65 | |||
| 59 | struct sample_event { | 66 | struct sample_event { |
| 60 | struct perf_event_header header; | 67 | struct perf_event_header header; |
| 61 | u64 array[]; | 68 | u64 array[]; |
| @@ -75,6 +82,8 @@ struct perf_sample { | |||
| 75 | struct ip_callchain *callchain; | 82 | struct ip_callchain *callchain; |
| 76 | }; | 83 | }; |
| 77 | 84 | ||
| 85 | int perf_sample_size(u64 sample_type); | ||
| 86 | |||
| 78 | #define BUILD_ID_SIZE 20 | 87 | #define BUILD_ID_SIZE 20 |
| 79 | 88 | ||
| 80 | struct build_id_event { | 89 | struct build_id_event { |
| @@ -178,6 +187,7 @@ int perf_event__preprocess_sample(const union perf_event *self, | |||
| 178 | const char *perf_event__name(unsigned int id); | 187 | const char *perf_event__name(unsigned int id); |
| 179 | 188 | ||
| 180 | int perf_event__parse_sample(const union perf_event *event, u64 type, | 189 | int perf_event__parse_sample(const union perf_event *event, u64 type, |
| 181 | bool sample_id_all, struct perf_sample *sample); | 190 | int sample_size, bool sample_id_all, |
| 191 | struct perf_sample *sample); | ||
| 182 | 192 | ||
| 183 | #endif /* __PERF_RECORD_H */ | 193 | #endif /* __PERF_RECORD_H */ |
diff --git a/tools/perf/util/evlist.c b/tools/perf/util/evlist.c index 23eb22b05d27..50aa34879c33 100644 --- a/tools/perf/util/evlist.c +++ b/tools/perf/util/evlist.c | |||
| @@ -459,3 +459,34 @@ int perf_evlist__set_filters(struct perf_evlist *evlist) | |||
| 459 | 459 | ||
| 460 | return 0; | 460 | return 0; |
| 461 | } | 461 | } |
| 462 | |||
| 463 | u64 perf_evlist__sample_type(struct perf_evlist *evlist) | ||
| 464 | { | ||
| 465 | struct perf_evsel *pos; | ||
| 466 | u64 type = 0; | ||
| 467 | |||
| 468 | list_for_each_entry(pos, &evlist->entries, node) { | ||
| 469 | if (!type) | ||
| 470 | type = pos->attr.sample_type; | ||
| 471 | else if (type != pos->attr.sample_type) | ||
| 472 | die("non matching sample_type"); | ||
| 473 | } | ||
| 474 | |||
| 475 | return type; | ||
| 476 | } | ||
| 477 | |||
| 478 | bool perf_evlist__sample_id_all(const struct perf_evlist *evlist) | ||
| 479 | { | ||
| 480 | bool value = false, first = true; | ||
| 481 | struct perf_evsel *pos; | ||
| 482 | |||
| 483 | list_for_each_entry(pos, &evlist->entries, node) { | ||
| 484 | if (first) { | ||
| 485 | value = pos->attr.sample_id_all; | ||
| 486 | first = false; | ||
| 487 | } else if (value != pos->attr.sample_id_all) | ||
| 488 | die("non matching sample_id_all"); | ||
| 489 | } | ||
| 490 | |||
| 491 | return value; | ||
| 492 | } | ||
diff --git a/tools/perf/util/evlist.h b/tools/perf/util/evlist.h index 7109d7add14e..0a1ef1f051f0 100644 --- a/tools/perf/util/evlist.h +++ b/tools/perf/util/evlist.h | |||
| @@ -66,4 +66,7 @@ int perf_evlist__create_maps(struct perf_evlist *evlist, pid_t target_pid, | |||
| 66 | void perf_evlist__delete_maps(struct perf_evlist *evlist); | 66 | void perf_evlist__delete_maps(struct perf_evlist *evlist); |
| 67 | int perf_evlist__set_filters(struct perf_evlist *evlist); | 67 | int perf_evlist__set_filters(struct perf_evlist *evlist); |
| 68 | 68 | ||
| 69 | u64 perf_evlist__sample_type(struct perf_evlist *evlist); | ||
| 70 | bool perf_evlist__sample_id_all(const struct perf_evlist *evlist); | ||
| 71 | |||
| 69 | #endif /* __PERF_EVLIST_H */ | 72 | #endif /* __PERF_EVLIST_H */ |
diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c index d6fd59beb860..ee0fe0dffa71 100644 --- a/tools/perf/util/evsel.c +++ b/tools/perf/util/evsel.c | |||
| @@ -303,8 +303,20 @@ static int perf_event__parse_id_sample(const union perf_event *event, u64 type, | |||
| 303 | return 0; | 303 | return 0; |
| 304 | } | 304 | } |
| 305 | 305 | ||
| 306 | static bool sample_overlap(const union perf_event *event, | ||
| 307 | const void *offset, u64 size) | ||
| 308 | { | ||
| 309 | const void *base = event; | ||
| 310 | |||
| 311 | if (offset + size > base + event->header.size) | ||
| 312 | return true; | ||
| 313 | |||
| 314 | return false; | ||
| 315 | } | ||
| 316 | |||
| 306 | int perf_event__parse_sample(const union perf_event *event, u64 type, | 317 | int perf_event__parse_sample(const union perf_event *event, u64 type, |
| 307 | bool sample_id_all, struct perf_sample *data) | 318 | int sample_size, bool sample_id_all, |
| 319 | struct perf_sample *data) | ||
| 308 | { | 320 | { |
| 309 | const u64 *array; | 321 | const u64 *array; |
| 310 | 322 | ||
| @@ -319,6 +331,9 @@ int perf_event__parse_sample(const union perf_event *event, u64 type, | |||
| 319 | 331 | ||
| 320 | array = event->sample.array; | 332 | array = event->sample.array; |
| 321 | 333 | ||
| 334 | if (sample_size + sizeof(event->header) > event->header.size) | ||
| 335 | return -EFAULT; | ||
| 336 | |||
| 322 | if (type & PERF_SAMPLE_IP) { | 337 | if (type & PERF_SAMPLE_IP) { |
| 323 | data->ip = event->ip.ip; | 338 | data->ip = event->ip.ip; |
| 324 | array++; | 339 | array++; |
| @@ -369,14 +384,29 @@ int perf_event__parse_sample(const union perf_event *event, u64 type, | |||
| 369 | } | 384 | } |
| 370 | 385 | ||
| 371 | if (type & PERF_SAMPLE_CALLCHAIN) { | 386 | if (type & PERF_SAMPLE_CALLCHAIN) { |
| 387 | if (sample_overlap(event, array, sizeof(data->callchain->nr))) | ||
| 388 | return -EFAULT; | ||
| 389 | |||
| 372 | data->callchain = (struct ip_callchain *)array; | 390 | data->callchain = (struct ip_callchain *)array; |
| 391 | |||
| 392 | if (sample_overlap(event, array, data->callchain->nr)) | ||
| 393 | return -EFAULT; | ||
| 394 | |||
| 373 | array += 1 + data->callchain->nr; | 395 | array += 1 + data->callchain->nr; |
| 374 | } | 396 | } |
| 375 | 397 | ||
| 376 | if (type & PERF_SAMPLE_RAW) { | 398 | if (type & PERF_SAMPLE_RAW) { |
| 377 | u32 *p = (u32 *)array; | 399 | u32 *p = (u32 *)array; |
| 400 | |||
| 401 | if (sample_overlap(event, array, sizeof(u32))) | ||
| 402 | return -EFAULT; | ||
| 403 | |||
| 378 | data->raw_size = *p; | 404 | data->raw_size = *p; |
| 379 | p++; | 405 | p++; |
| 406 | |||
| 407 | if (sample_overlap(event, p, data->raw_size)) | ||
| 408 | return -EFAULT; | ||
| 409 | |||
| 380 | data->raw_data = p; | 410 | data->raw_data = p; |
| 381 | } | 411 | } |
| 382 | 412 | ||
diff --git a/tools/perf/util/header.c b/tools/perf/util/header.c index 93862a8027ea..0717bebc7649 100644 --- a/tools/perf/util/header.c +++ b/tools/perf/util/header.c | |||
| @@ -934,37 +934,6 @@ out_delete_evlist: | |||
| 934 | return -ENOMEM; | 934 | return -ENOMEM; |
| 935 | } | 935 | } |
| 936 | 936 | ||
| 937 | u64 perf_evlist__sample_type(struct perf_evlist *evlist) | ||
| 938 | { | ||
| 939 | struct perf_evsel *pos; | ||
| 940 | u64 type = 0; | ||
| 941 | |||
| 942 | list_for_each_entry(pos, &evlist->entries, node) { | ||
| 943 | if (!type) | ||
| 944 | type = pos->attr.sample_type; | ||
| 945 | else if (type != pos->attr.sample_type) | ||
| 946 | die("non matching sample_type"); | ||
| 947 | } | ||
| 948 | |||
| 949 | return type; | ||
| 950 | } | ||
| 951 | |||
| 952 | bool perf_evlist__sample_id_all(const struct perf_evlist *evlist) | ||
| 953 | { | ||
| 954 | bool value = false, first = true; | ||
| 955 | struct perf_evsel *pos; | ||
| 956 | |||
| 957 | list_for_each_entry(pos, &evlist->entries, node) { | ||
| 958 | if (first) { | ||
| 959 | value = pos->attr.sample_id_all; | ||
| 960 | first = false; | ||
| 961 | } else if (value != pos->attr.sample_id_all) | ||
| 962 | die("non matching sample_id_all"); | ||
| 963 | } | ||
| 964 | |||
| 965 | return value; | ||
| 966 | } | ||
| 967 | |||
| 968 | int perf_event__synthesize_attr(struct perf_event_attr *attr, u16 ids, u64 *id, | 937 | int perf_event__synthesize_attr(struct perf_event_attr *attr, u16 ids, u64 *id, |
| 969 | perf_event__handler_t process, | 938 | perf_event__handler_t process, |
| 970 | struct perf_session *session) | 939 | struct perf_session *session) |
diff --git a/tools/perf/util/header.h b/tools/perf/util/header.h index 456661d7f10e..1886256768a1 100644 --- a/tools/perf/util/header.h +++ b/tools/perf/util/header.h | |||
| @@ -64,8 +64,6 @@ int perf_header__write_pipe(int fd); | |||
| 64 | int perf_header__push_event(u64 id, const char *name); | 64 | int perf_header__push_event(u64 id, const char *name); |
| 65 | char *perf_header__find_event(u64 id); | 65 | char *perf_header__find_event(u64 id); |
| 66 | 66 | ||
| 67 | u64 perf_evlist__sample_type(struct perf_evlist *evlist); | ||
| 68 | bool perf_evlist__sample_id_all(const struct perf_evlist *evlist); | ||
| 69 | void perf_header__set_feat(struct perf_header *header, int feat); | 67 | void perf_header__set_feat(struct perf_header *header, int feat); |
| 70 | void perf_header__clear_feat(struct perf_header *header, int feat); | 68 | void perf_header__clear_feat(struct perf_header *header, int feat); |
| 71 | bool perf_header__has_feat(const struct perf_header *header, int feat); | 69 | bool perf_header__has_feat(const struct perf_header *header, int feat); |
diff --git a/tools/perf/util/include/linux/list.h b/tools/perf/util/include/linux/list.h index 356c7e467b83..1d928a0ce997 100644 --- a/tools/perf/util/include/linux/list.h +++ b/tools/perf/util/include/linux/list.h | |||
| @@ -1,4 +1,6 @@ | |||
| 1 | #include <linux/kernel.h> | 1 | #include <linux/kernel.h> |
| 2 | #include <linux/prefetch.h> | ||
| 3 | |||
| 2 | #include "../../../../include/linux/list.h" | 4 | #include "../../../../include/linux/list.h" |
| 3 | 5 | ||
| 4 | #ifndef PERF_LIST_H | 6 | #ifndef PERF_LIST_H |
| @@ -23,5 +25,5 @@ static inline void list_del_range(struct list_head *begin, | |||
| 23 | * @head: the head for your list. | 25 | * @head: the head for your list. |
| 24 | */ | 26 | */ |
| 25 | #define list_for_each_from(pos, head) \ | 27 | #define list_for_each_from(pos, head) \ |
| 26 | for (; prefetch(pos->next), pos != (head); pos = pos->next) | 28 | for (; pos != (head); pos = pos->next) |
| 27 | #endif | 29 | #endif |
diff --git a/tools/perf/util/python.c b/tools/perf/util/python.c index b5c7d818001c..69436b3200a4 100644 --- a/tools/perf/util/python.c +++ b/tools/perf/util/python.c | |||
| @@ -675,6 +675,7 @@ static PyObject *pyrf_evlist__read_on_cpu(struct pyrf_evlist *pevlist, | |||
| 675 | union perf_event *event; | 675 | union perf_event *event; |
| 676 | int sample_id_all = 1, cpu; | 676 | int sample_id_all = 1, cpu; |
| 677 | static char *kwlist[] = {"sample_id_all", NULL, NULL}; | 677 | static char *kwlist[] = {"sample_id_all", NULL, NULL}; |
| 678 | int err; | ||
| 678 | 679 | ||
| 679 | if (!PyArg_ParseTupleAndKeywords(args, kwargs, "i|i", kwlist, | 680 | if (!PyArg_ParseTupleAndKeywords(args, kwargs, "i|i", kwlist, |
| 680 | &cpu, &sample_id_all)) | 681 | &cpu, &sample_id_all)) |
| @@ -690,11 +691,17 @@ static PyObject *pyrf_evlist__read_on_cpu(struct pyrf_evlist *pevlist, | |||
| 690 | return PyErr_NoMemory(); | 691 | return PyErr_NoMemory(); |
| 691 | 692 | ||
| 692 | first = list_entry(evlist->entries.next, struct perf_evsel, node); | 693 | first = list_entry(evlist->entries.next, struct perf_evsel, node); |
| 693 | perf_event__parse_sample(event, first->attr.sample_type, sample_id_all, | 694 | err = perf_event__parse_sample(event, first->attr.sample_type, |
| 694 | &pevent->sample); | 695 | perf_sample_size(first->attr.sample_type), |
| 696 | sample_id_all, &pevent->sample); | ||
| 697 | if (err) { | ||
| 698 | pr_err("Can't parse sample, err = %d\n", err); | ||
| 699 | goto end; | ||
| 700 | } | ||
| 701 | |||
| 695 | return pyevent; | 702 | return pyevent; |
| 696 | } | 703 | } |
| 697 | 704 | end: | |
| 698 | Py_INCREF(Py_None); | 705 | Py_INCREF(Py_None); |
| 699 | return Py_None; | 706 | return Py_None; |
| 700 | } | 707 | } |
diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c index fff66741f18d..64500fc78799 100644 --- a/tools/perf/util/session.c +++ b/tools/perf/util/session.c | |||
| @@ -97,6 +97,7 @@ out: | |||
| 97 | void perf_session__update_sample_type(struct perf_session *self) | 97 | void perf_session__update_sample_type(struct perf_session *self) |
| 98 | { | 98 | { |
| 99 | self->sample_type = perf_evlist__sample_type(self->evlist); | 99 | self->sample_type = perf_evlist__sample_type(self->evlist); |
| 100 | self->sample_size = perf_sample_size(self->sample_type); | ||
| 100 | self->sample_id_all = perf_evlist__sample_id_all(self->evlist); | 101 | self->sample_id_all = perf_evlist__sample_id_all(self->evlist); |
| 101 | perf_session__id_header_size(self); | 102 | perf_session__id_header_size(self); |
| 102 | } | 103 | } |
| @@ -479,6 +480,7 @@ static void flush_sample_queue(struct perf_session *s, | |||
| 479 | struct perf_sample sample; | 480 | struct perf_sample sample; |
| 480 | u64 limit = os->next_flush; | 481 | u64 limit = os->next_flush; |
| 481 | u64 last_ts = os->last_sample ? os->last_sample->timestamp : 0ULL; | 482 | u64 last_ts = os->last_sample ? os->last_sample->timestamp : 0ULL; |
| 483 | int ret; | ||
| 482 | 484 | ||
| 483 | if (!ops->ordered_samples || !limit) | 485 | if (!ops->ordered_samples || !limit) |
| 484 | return; | 486 | return; |
| @@ -487,9 +489,12 @@ static void flush_sample_queue(struct perf_session *s, | |||
| 487 | if (iter->timestamp > limit) | 489 | if (iter->timestamp > limit) |
| 488 | break; | 490 | break; |
| 489 | 491 | ||
| 490 | perf_session__parse_sample(s, iter->event, &sample); | 492 | ret = perf_session__parse_sample(s, iter->event, &sample); |
| 491 | perf_session_deliver_event(s, iter->event, &sample, ops, | 493 | if (ret) |
| 492 | iter->file_offset); | 494 | pr_err("Can't parse sample, err = %d\n", ret); |
| 495 | else | ||
| 496 | perf_session_deliver_event(s, iter->event, &sample, ops, | ||
| 497 | iter->file_offset); | ||
| 493 | 498 | ||
| 494 | os->last_flush = iter->timestamp; | 499 | os->last_flush = iter->timestamp; |
| 495 | list_del(&iter->list); | 500 | list_del(&iter->list); |
| @@ -805,7 +810,9 @@ static int perf_session__process_event(struct perf_session *session, | |||
| 805 | /* | 810 | /* |
| 806 | * For all kernel events we get the sample data | 811 | * For all kernel events we get the sample data |
| 807 | */ | 812 | */ |
| 808 | perf_session__parse_sample(session, event, &sample); | 813 | ret = perf_session__parse_sample(session, event, &sample); |
| 814 | if (ret) | ||
| 815 | return ret; | ||
| 809 | 816 | ||
| 810 | /* Preprocess sample records - precheck callchains */ | 817 | /* Preprocess sample records - precheck callchains */ |
| 811 | if (perf_session__preprocess_sample(session, event, &sample)) | 818 | if (perf_session__preprocess_sample(session, event, &sample)) |
| @@ -953,6 +960,30 @@ out_err: | |||
| 953 | return err; | 960 | return err; |
| 954 | } | 961 | } |
| 955 | 962 | ||
| 963 | static union perf_event * | ||
| 964 | fetch_mmaped_event(struct perf_session *session, | ||
| 965 | u64 head, size_t mmap_size, char *buf) | ||
| 966 | { | ||
| 967 | union perf_event *event; | ||
| 968 | |||
| 969 | /* | ||
| 970 | * Ensure we have enough space remaining to read | ||
| 971 | * the size of the event in the headers. | ||
| 972 | */ | ||
| 973 | if (head + sizeof(event->header) > mmap_size) | ||
| 974 | return NULL; | ||
| 975 | |||
| 976 | event = (union perf_event *)(buf + head); | ||
| 977 | |||
| 978 | if (session->header.needs_swap) | ||
| 979 | perf_event_header__bswap(&event->header); | ||
| 980 | |||
| 981 | if (head + event->header.size > mmap_size) | ||
| 982 | return NULL; | ||
| 983 | |||
| 984 | return event; | ||
| 985 | } | ||
| 986 | |||
| 956 | int __perf_session__process_events(struct perf_session *session, | 987 | int __perf_session__process_events(struct perf_session *session, |
| 957 | u64 data_offset, u64 data_size, | 988 | u64 data_offset, u64 data_size, |
| 958 | u64 file_size, struct perf_event_ops *ops) | 989 | u64 file_size, struct perf_event_ops *ops) |
| @@ -1007,15 +1038,8 @@ remap: | |||
| 1007 | file_pos = file_offset + head; | 1038 | file_pos = file_offset + head; |
| 1008 | 1039 | ||
| 1009 | more: | 1040 | more: |
| 1010 | event = (union perf_event *)(buf + head); | 1041 | event = fetch_mmaped_event(session, head, mmap_size, buf); |
| 1011 | 1042 | if (!event) { | |
| 1012 | if (session->header.needs_swap) | ||
| 1013 | perf_event_header__bswap(&event->header); | ||
| 1014 | size = event->header.size; | ||
| 1015 | if (size == 0) | ||
| 1016 | size = 8; | ||
| 1017 | |||
| 1018 | if (head + event->header.size > mmap_size) { | ||
| 1019 | if (mmaps[map_idx]) { | 1043 | if (mmaps[map_idx]) { |
| 1020 | munmap(mmaps[map_idx], mmap_size); | 1044 | munmap(mmaps[map_idx], mmap_size); |
| 1021 | mmaps[map_idx] = NULL; | 1045 | mmaps[map_idx] = NULL; |
diff --git a/tools/perf/util/session.h b/tools/perf/util/session.h index 8daaa2d15396..66d4e1490879 100644 --- a/tools/perf/util/session.h +++ b/tools/perf/util/session.h | |||
| @@ -43,6 +43,7 @@ struct perf_session { | |||
| 43 | */ | 43 | */ |
| 44 | struct hists hists; | 44 | struct hists hists; |
| 45 | u64 sample_type; | 45 | u64 sample_type; |
| 46 | int sample_size; | ||
| 46 | int fd; | 47 | int fd; |
| 47 | bool fd_pipe; | 48 | bool fd_pipe; |
| 48 | bool repipe; | 49 | bool repipe; |
| @@ -159,6 +160,7 @@ static inline int perf_session__parse_sample(struct perf_session *session, | |||
| 159 | struct perf_sample *sample) | 160 | struct perf_sample *sample) |
| 160 | { | 161 | { |
| 161 | return perf_event__parse_sample(event, session->sample_type, | 162 | return perf_event__parse_sample(event, session->sample_type, |
| 163 | session->sample_size, | ||
| 162 | session->sample_id_all, sample); | 164 | session->sample_id_all, sample); |
| 163 | } | 165 | } |
| 164 | 166 | ||
diff --git a/tools/perf/util/ui/browsers/annotate.c b/tools/perf/util/ui/browsers/annotate.c index 15633d608133..0229723aceb3 100644 --- a/tools/perf/util/ui/browsers/annotate.c +++ b/tools/perf/util/ui/browsers/annotate.c | |||
| @@ -5,7 +5,6 @@ | |||
| 5 | #include "../../hist.h" | 5 | #include "../../hist.h" |
| 6 | #include "../../sort.h" | 6 | #include "../../sort.h" |
| 7 | #include "../../symbol.h" | 7 | #include "../../symbol.h" |
| 8 | #include "../../annotate.h" | ||
| 9 | #include <pthread.h> | 8 | #include <pthread.h> |
| 10 | 9 | ||
| 11 | static void ui__error_window(const char *fmt, ...) | 10 | static void ui__error_window(const char *fmt, ...) |
