diff options
Diffstat (limited to 'tools/perf/util/session.c')
-rw-r--r-- | tools/perf/util/session.c | 119 |
1 files changed, 69 insertions, 50 deletions
diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c index 061bb4d6a3f5..d0d7d25b23e3 100644 --- a/tools/perf/util/session.c +++ b/tools/perf/util/session.c @@ -227,9 +227,13 @@ struct perf_session *perf_session__new(struct perf_data *data, /* Open the directory data. */ if (data->is_dir) { ret = perf_data__open_dir(data); - if (ret) - goto out_delete; + if (ret) + goto out_delete; } + + if (!symbol_conf.kallsyms_name && + !symbol_conf.vmlinux_name) + symbol_conf.kallsyms_name = perf_data__kallsyms_name(data); } } else { session->machines.host.env = &perf_env; @@ -748,6 +752,7 @@ do { \ bswap_field_32(sample_stack_user); bswap_field_32(aux_watermark); bswap_field_16(sample_max_stack); + bswap_field_32(aux_sample_size); /* * After read_format are bitfields. Check read_format because @@ -1491,8 +1496,13 @@ static int perf_session__deliver_event(struct perf_session *session, if (ret > 0) return 0; - return machines__deliver_event(&session->machines, session->evlist, - event, &sample, tool, file_offset); + ret = machines__deliver_event(&session->machines, session->evlist, + event, &sample, tool, file_offset); + + if (dump_trace && sample.aux_sample.size) + auxtrace__dump_auxtrace_sample(session, &sample); + + return ret; } static s64 perf_session__process_user_event(struct perf_session *session, @@ -1649,6 +1659,34 @@ out_parse_sample: return 0; } +int perf_session__peek_events(struct perf_session *session, u64 offset, + u64 size, peek_events_cb_t cb, void *data) +{ + u64 max_offset = offset + size; + char buf[PERF_SAMPLE_MAX_SIZE]; + union perf_event *event; + int err; + + do { + err = perf_session__peek_event(session, offset, buf, + PERF_SAMPLE_MAX_SIZE, &event, + NULL); + if (err) + return err; + + err = cb(session, event, offset, data); + if (err) + return err; + + offset += event->header.size; + if (event->header.type == PERF_RECORD_AUXTRACE) + offset += event->auxtrace.size; + + } while (offset < max_offset); + + return err; +} + static s64 perf_session__process_event(struct perf_session *session, union perf_event *event, u64 file_offset) { @@ -1954,8 +1992,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; @@ -1967,20 +2005,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 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)); +} - return event; +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) @@ -1993,10 +2043,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; @@ -2096,7 +2144,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); @@ -2355,35 +2403,6 @@ void perf_session__fprintf_info(struct perf_session *session, FILE *fp, fprintf(fp, "# ========\n#\n"); } - -int __perf_session__set_tracepoints_handlers(struct perf_session *session, - const struct evsel_str_handler *assocs, - size_t nr_assocs) -{ - struct evsel *evsel; - size_t i; - int err; - - for (i = 0; i < nr_assocs; i++) { - /* - * Adding a handler for an event not in the session, - * just ignore it. - */ - evsel = perf_evlist__find_tracepoint_by_name(session->evlist, assocs[i].name); - if (evsel == NULL) - continue; - - err = -EEXIST; - if (evsel->handler != NULL) - goto out; - evsel->handler = assocs[i].handler; - } - - err = 0; -out: - return err; -} - int perf_event__process_id_index(struct perf_session *session, union perf_event *event) { |