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.c66
1 files changed, 53 insertions, 13 deletions
diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c
index c9ed7e3cf231..f7bb7ae328da 100644
--- a/tools/perf/util/session.c
+++ b/tools/perf/util/session.c
@@ -16,6 +16,7 @@
16#include "cpumap.h" 16#include "cpumap.h"
17#include "event-parse.h" 17#include "event-parse.h"
18#include "perf_regs.h" 18#include "perf_regs.h"
19#include "unwind.h"
19 20
20static int perf_session__open(struct perf_session *self, bool force) 21static int perf_session__open(struct perf_session *self, bool force)
21{ 22{
@@ -289,10 +290,11 @@ struct branch_info *machine__resolve_bstack(struct machine *self,
289 return bi; 290 return bi;
290} 291}
291 292
292int machine__resolve_callchain(struct machine *self, 293static int machine__resolve_callchain_sample(struct machine *machine,
293 struct thread *thread, 294 struct thread *thread,
294 struct ip_callchain *chain, 295 struct ip_callchain *chain,
295 struct symbol **parent) 296 struct symbol **parent)
297
296{ 298{
297 u8 cpumode = PERF_RECORD_MISC_USER; 299 u8 cpumode = PERF_RECORD_MISC_USER;
298 unsigned int i; 300 unsigned int i;
@@ -317,11 +319,14 @@ int machine__resolve_callchain(struct machine *self,
317 if (ip >= PERF_CONTEXT_MAX) { 319 if (ip >= PERF_CONTEXT_MAX) {
318 switch (ip) { 320 switch (ip) {
319 case PERF_CONTEXT_HV: 321 case PERF_CONTEXT_HV:
320 cpumode = PERF_RECORD_MISC_HYPERVISOR; break; 322 cpumode = PERF_RECORD_MISC_HYPERVISOR;
323 break;
321 case PERF_CONTEXT_KERNEL: 324 case PERF_CONTEXT_KERNEL:
322 cpumode = PERF_RECORD_MISC_KERNEL; break; 325 cpumode = PERF_RECORD_MISC_KERNEL;
326 break;
323 case PERF_CONTEXT_USER: 327 case PERF_CONTEXT_USER:
324 cpumode = PERF_RECORD_MISC_USER; break; 328 cpumode = PERF_RECORD_MISC_USER;
329 break;
325 default: 330 default:
326 pr_debug("invalid callchain context: " 331 pr_debug("invalid callchain context: "
327 "%"PRId64"\n", (s64) ip); 332 "%"PRId64"\n", (s64) ip);
@@ -336,7 +341,7 @@ int machine__resolve_callchain(struct machine *self,
336 } 341 }
337 342
338 al.filtered = false; 343 al.filtered = false;
339 thread__find_addr_location(thread, self, cpumode, 344 thread__find_addr_location(thread, machine, cpumode,
340 MAP__FUNCTION, ip, &al, NULL); 345 MAP__FUNCTION, ip, &al, NULL);
341 if (al.sym != NULL) { 346 if (al.sym != NULL) {
342 if (sort__has_parent && !*parent && 347 if (sort__has_parent && !*parent &&
@@ -355,6 +360,40 @@ int machine__resolve_callchain(struct machine *self,
355 return 0; 360 return 0;
356} 361}
357 362
363static int unwind_entry(struct unwind_entry *entry, void *arg)
364{
365 struct callchain_cursor *cursor = arg;
366 return callchain_cursor_append(cursor, entry->ip,
367 entry->map, entry->sym);
368}
369
370int machine__resolve_callchain(struct machine *machine,
371 struct perf_evsel *evsel,
372 struct thread *thread,
373 struct perf_sample *sample,
374 struct symbol **parent)
375
376{
377 int ret;
378
379 callchain_cursor_reset(&callchain_cursor);
380
381 ret = machine__resolve_callchain_sample(machine, thread,
382 sample->callchain, parent);
383 if (ret)
384 return ret;
385
386 /* Can we do dwarf post unwind? */
387 if (!((evsel->attr.sample_type & PERF_SAMPLE_REGS_USER) &&
388 (evsel->attr.sample_type & PERF_SAMPLE_STACK_USER)))
389 return 0;
390
391 return unwind__get_entries(unwind_entry, &callchain_cursor, machine,
392 thread, evsel->attr.sample_regs_user,
393 sample);
394
395}
396
358static int process_event_synth_tracing_data_stub(union perf_event *event __used, 397static int process_event_synth_tracing_data_stub(union perf_event *event __used,
359 struct perf_session *session __used) 398 struct perf_session *session __used)
360{ 399{
@@ -1533,9 +1572,9 @@ struct perf_evsel *perf_session__find_first_evtype(struct perf_session *session,
1533 return NULL; 1572 return NULL;
1534} 1573}
1535 1574
1536void perf_event__print_ip(union perf_event *event, struct perf_sample *sample, 1575void perf_evsel__print_ip(struct perf_evsel *evsel, union perf_event *event,
1537 struct machine *machine, int print_sym, 1576 struct perf_sample *sample, struct machine *machine,
1538 int print_dso, int print_symoffset) 1577 int print_sym, int print_dso, int print_symoffset)
1539{ 1578{
1540 struct addr_location al; 1579 struct addr_location al;
1541 struct callchain_cursor_node *node; 1580 struct callchain_cursor_node *node;
@@ -1549,8 +1588,9 @@ void perf_event__print_ip(union perf_event *event, struct perf_sample *sample,
1549 1588
1550 if (symbol_conf.use_callchain && sample->callchain) { 1589 if (symbol_conf.use_callchain && sample->callchain) {
1551 1590
1552 if (machine__resolve_callchain(machine, al.thread, 1591
1553 sample->callchain, NULL) != 0) { 1592 if (machine__resolve_callchain(machine, evsel, al.thread,
1593 sample, NULL) != 0) {
1554 if (verbose) 1594 if (verbose)
1555 error("Failed to resolve callchain. Skipping\n"); 1595 error("Failed to resolve callchain. Skipping\n");
1556 return; 1596 return;