The trace decoder library requires access to the instruction opcodes of the program that was traced in order to be able to decode the trace stream into a series of executed instruction ranges.
This patch implements a function that will be used by the trace decoder interface to enable the trace decoder library to access instruction opcodes stored in DSOs.
Signed-off-by: Tor Jeremiassen tor@ti.com --- tools/perf/util/cs-etm.c | 49 ++++++++++++++++++++++++++++++++++++++++++++++++ tools/perf/util/cs-etm.h | 4 ++++ 2 files changed, 53 insertions(+)
diff --git a/tools/perf/util/cs-etm.c b/tools/perf/util/cs-etm.c index dede50c..b81b7f4 100644 --- a/tools/perf/util/cs-etm.c +++ b/tools/perf/util/cs-etm.c @@ -207,6 +207,55 @@ static void cs_etm__free(struct perf_session *session) zfree(&aux); }
+uint32_t cs_etm__mem_access(struct cs_etm_queue *etmq, + uint64_t address, + size_t size, + uint8_t *buffer) +{ + struct addr_location al; + uint64_t offset; + struct thread *thread; + struct machine *machine; + uint8_t cpumode; + int len; + + if (!etmq) + return -1; + + machine = etmq->etm->machine; + if (address >= etmq->etm->kernel_start) + cpumode = PERF_RECORD_MISC_KERNEL; + else + cpumode = PERF_RECORD_MISC_USER; + + thread = etmq->thread; + if (!thread) { + if (cpumode != PERF_RECORD_MISC_KERNEL) + return -EINVAL; + thread = etmq->etm->unknown_thread; + } + + thread__find_addr_map(thread, cpumode, MAP__FUNCTION, address, &al); + + if (!al.map || !al.map->dso) + return 0; + + if (al.map->dso->data.status == DSO_DATA_STATUS_ERROR && + dso__data_status_seen(al.map->dso, DSO_DATA_STATUS_SEEN_ITRACE)) + return 0; + + offset = al.map->map_ip(al.map, address); + + map__load(al.map); + + len = dso__data_read_offset(al.map->dso, machine, offset, buffer, size); + + if (len <= 0) + return 0; + + return len; +} + static int cs_etm__process_event(struct perf_session *session, union perf_event *event, struct perf_sample *sample, diff --git a/tools/perf/util/cs-etm.h b/tools/perf/util/cs-etm.h index 6139280..d0205a3 100644 --- a/tools/perf/util/cs-etm.h +++ b/tools/perf/util/cs-etm.h @@ -96,4 +96,8 @@ struct auxtrace_buffer; void cs_etm__dump_event(struct cs_etm_auxtrace *etm, struct auxtrace_buffer *buffer);
+struct cs_etm_queue; + +uint32_t cs_etm__mem_access(struct cs_etm_queue *etmq, uint64_t address, + size_t size, uint8_t *buffer); #endif