aboutsummaryrefslogtreecommitdiffstats
path: root/tools/perf/util/session.c
diff options
context:
space:
mode:
Diffstat (limited to 'tools/perf/util/session.c')
-rw-r--r--tools/perf/util/session.c72
1 files changed, 72 insertions, 0 deletions
diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c
index 9f833cf9c6a..bec8a328b1b 100644
--- a/tools/perf/util/session.c
+++ b/tools/perf/util/session.c
@@ -229,6 +229,63 @@ static bool symbol__match_parent_regex(struct symbol *sym)
229 return 0; 229 return 0;
230} 230}
231 231
232static const u8 cpumodes[] = {
233 PERF_RECORD_MISC_USER,
234 PERF_RECORD_MISC_KERNEL,
235 PERF_RECORD_MISC_GUEST_USER,
236 PERF_RECORD_MISC_GUEST_KERNEL
237};
238#define NCPUMODES (sizeof(cpumodes)/sizeof(u8))
239
240static void ip__resolve_ams(struct machine *self, struct thread *thread,
241 struct addr_map_symbol *ams,
242 u64 ip)
243{
244 struct addr_location al;
245 size_t i;
246 u8 m;
247
248 memset(&al, 0, sizeof(al));
249
250 for (i = 0; i < NCPUMODES; i++) {
251 m = cpumodes[i];
252 /*
253 * We cannot use the header.misc hint to determine whether a
254 * branch stack address is user, kernel, guest, hypervisor.
255 * Branches may straddle the kernel/user/hypervisor boundaries.
256 * Thus, we have to try consecutively until we find a match
257 * or else, the symbol is unknown
258 */
259 thread__find_addr_location(thread, self, m, MAP__FUNCTION,
260 ip, &al, NULL);
261 if (al.sym)
262 goto found;
263 }
264found:
265 ams->addr = ip;
266 ams->sym = al.sym;
267 ams->map = al.map;
268}
269
270struct branch_info *machine__resolve_bstack(struct machine *self,
271 struct thread *thr,
272 struct branch_stack *bs)
273{
274 struct branch_info *bi;
275 unsigned int i;
276
277 bi = calloc(bs->nr, sizeof(struct branch_info));
278 if (!bi)
279 return NULL;
280
281 for (i = 0; i < bs->nr; i++) {
282 ip__resolve_ams(self, thr, &bi[i].to, bs->entries[i].to);
283 ip__resolve_ams(self, thr, &bi[i].from, bs->entries[i].from);
284 bi[i].flags = bs->entries[i].flags;
285 }
286 return bi;
287}
288
232int machine__resolve_callchain(struct machine *self, struct perf_evsel *evsel, 289int machine__resolve_callchain(struct machine *self, struct perf_evsel *evsel,
233 struct thread *thread, 290 struct thread *thread,
234 struct ip_callchain *chain, 291 struct ip_callchain *chain,
@@ -697,6 +754,18 @@ static void callchain__printf(struct perf_sample *sample)
697 i, sample->callchain->ips[i]); 754 i, sample->callchain->ips[i]);
698} 755}
699 756
757static void branch_stack__printf(struct perf_sample *sample)
758{
759 uint64_t i;
760
761 printf("... branch stack: nr:%" PRIu64 "\n", sample->branch_stack->nr);
762
763 for (i = 0; i < sample->branch_stack->nr; i++)
764 printf("..... %2"PRIu64": %016" PRIx64 " -> %016" PRIx64 "\n",
765 i, sample->branch_stack->entries[i].from,
766 sample->branch_stack->entries[i].to);
767}
768
700static void perf_session__print_tstamp(struct perf_session *session, 769static void perf_session__print_tstamp(struct perf_session *session,
701 union perf_event *event, 770 union perf_event *event,
702 struct perf_sample *sample) 771 struct perf_sample *sample)
@@ -744,6 +813,9 @@ static void dump_sample(struct perf_session *session, union perf_event *event,
744 813
745 if (session->sample_type & PERF_SAMPLE_CALLCHAIN) 814 if (session->sample_type & PERF_SAMPLE_CALLCHAIN)
746 callchain__printf(sample); 815 callchain__printf(sample);
816
817 if (session->sample_type & PERF_SAMPLE_BRANCH_STACK)
818 branch_stack__printf(sample);
747} 819}
748 820
749static struct machine * 821static struct machine *