diff options
Diffstat (limited to 'tools/perf/util')
-rw-r--r-- | tools/perf/util/session.c | 44 |
1 files changed, 27 insertions, 17 deletions
diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c index f07b8ecb91bc..8454a650146b 100644 --- a/tools/perf/util/session.c +++ b/tools/perf/util/session.c @@ -1958,8 +1958,8 @@ out_err: } static union perf_event * -fetch_mmaped_event(struct perf_session *session, - u64 head, size_t mmap_size, char *buf) +prefetch_event(char *buf, u64 head, size_t mmap_size, + bool needs_swap, union perf_event *error) { union perf_event *event; @@ -1971,20 +1971,32 @@ fetch_mmaped_event(struct perf_session *session, return NULL; event = (union perf_event *)(buf + head); + if (needs_swap) + perf_event_header__bswap(&event->header); - if (session->header.needs_swap) + if (head + event->header.size <= mmap_size) + return event; + + /* We're not fetching the event so swap back again */ + if (needs_swap) perf_event_header__bswap(&event->header); - if (head + event->header.size > mmap_size) { - /* We're not fetching the event so swap back again */ - if (session->header.needs_swap) - perf_event_header__bswap(&event->header); - pr_debug("%s: head=%#" PRIx64 " event->header_size=%#x, mmap_size=%#zx: fuzzed perf.data?\n", - __func__, head, event->header.size, mmap_size); - return ERR_PTR(-EINVAL); - } + pr_debug("%s: head=%#" PRIx64 " event->header_size=%#x, mmap_size=%#zx:" + " fuzzed or compressed perf.data?\n",__func__, head, event->header.size, mmap_size); - return event; + return error; +} + +static union perf_event * +fetch_mmaped_event(u64 head, size_t mmap_size, char *buf, bool needs_swap) +{ + return prefetch_event(buf, head, mmap_size, needs_swap, ERR_PTR(-EINVAL)); +} + +static union perf_event * +fetch_decomp_event(u64 head, size_t mmap_size, char *buf, bool needs_swap) +{ + return prefetch_event(buf, head, mmap_size, needs_swap, NULL); } static int __perf_session__process_decomp_events(struct perf_session *session) @@ -1997,10 +2009,8 @@ static int __perf_session__process_decomp_events(struct perf_session *session) return 0; while (decomp->head < decomp->size && !session_done()) { - union perf_event *event = fetch_mmaped_event(session, decomp->head, decomp->size, decomp->data); - - if (IS_ERR(event)) - return PTR_ERR(event); + union perf_event *event = fetch_decomp_event(decomp->head, decomp->size, decomp->data, + session->header.needs_swap); if (!event) break; @@ -2100,7 +2110,7 @@ remap: } more: - event = fetch_mmaped_event(session, head, mmap_size, buf); + event = fetch_mmaped_event(head, mmap_size, buf, session->header.needs_swap); if (IS_ERR(event)) return PTR_ERR(event); |