summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--tools/perf/util/event.c27
-rw-r--r--tools/perf/util/machine.c27
-rw-r--r--tools/perf/util/machine.h2
-rw-r--r--tools/perf/util/thread.h4
4 files changed, 60 insertions, 0 deletions
diff --git a/tools/perf/util/event.c b/tools/perf/util/event.c
index e9c108a6b1c3..9431b20c1337 100644
--- a/tools/perf/util/event.c
+++ b/tools/perf/util/event.c
@@ -1577,6 +1577,24 @@ struct map *thread__find_map(struct thread *thread, u8 cpumode, u64 addr,
1577 return al->map; 1577 return al->map;
1578} 1578}
1579 1579
1580/*
1581 * For branch stacks or branch samples, the sample cpumode might not be correct
1582 * because it applies only to the sample 'ip' and not necessary to 'addr' or
1583 * branch stack addresses. If possible, use a fallback to deal with those cases.
1584 */
1585struct map *thread__find_map_fb(struct thread *thread, u8 cpumode, u64 addr,
1586 struct addr_location *al)
1587{
1588 struct map *map = thread__find_map(thread, cpumode, addr, al);
1589 struct machine *machine = thread->mg->machine;
1590 u8 addr_cpumode = machine__addr_cpumode(machine, cpumode, addr);
1591
1592 if (map || addr_cpumode == cpumode)
1593 return map;
1594
1595 return thread__find_map(thread, addr_cpumode, addr, al);
1596}
1597
1580struct symbol *thread__find_symbol(struct thread *thread, u8 cpumode, 1598struct symbol *thread__find_symbol(struct thread *thread, u8 cpumode,
1581 u64 addr, struct addr_location *al) 1599 u64 addr, struct addr_location *al)
1582{ 1600{
@@ -1586,6 +1604,15 @@ struct symbol *thread__find_symbol(struct thread *thread, u8 cpumode,
1586 return al->sym; 1604 return al->sym;
1587} 1605}
1588 1606
1607struct symbol *thread__find_symbol_fb(struct thread *thread, u8 cpumode,
1608 u64 addr, struct addr_location *al)
1609{
1610 al->sym = NULL;
1611 if (thread__find_map_fb(thread, cpumode, addr, al))
1612 al->sym = map__find_symbol(al->map, al->addr);
1613 return al->sym;
1614}
1615
1589/* 1616/*
1590 * Callers need to drop the reference to al->thread, obtained in 1617 * Callers need to drop the reference to al->thread, obtained in
1591 * machine__findnew_thread() 1618 * machine__findnew_thread()
diff --git a/tools/perf/util/machine.c b/tools/perf/util/machine.c
index 8f36ce813bc5..9397e3f2444d 100644
--- a/tools/perf/util/machine.c
+++ b/tools/perf/util/machine.c
@@ -2592,6 +2592,33 @@ int machine__get_kernel_start(struct machine *machine)
2592 return err; 2592 return err;
2593} 2593}
2594 2594
2595u8 machine__addr_cpumode(struct machine *machine, u8 cpumode, u64 addr)
2596{
2597 u8 addr_cpumode = cpumode;
2598 bool kernel_ip;
2599
2600 if (!machine->single_address_space)
2601 goto out;
2602
2603 kernel_ip = machine__kernel_ip(machine, addr);
2604 switch (cpumode) {
2605 case PERF_RECORD_MISC_KERNEL:
2606 case PERF_RECORD_MISC_USER:
2607 addr_cpumode = kernel_ip ? PERF_RECORD_MISC_KERNEL :
2608 PERF_RECORD_MISC_USER;
2609 break;
2610 case PERF_RECORD_MISC_GUEST_KERNEL:
2611 case PERF_RECORD_MISC_GUEST_USER:
2612 addr_cpumode = kernel_ip ? PERF_RECORD_MISC_GUEST_KERNEL :
2613 PERF_RECORD_MISC_GUEST_USER;
2614 break;
2615 default:
2616 break;
2617 }
2618out:
2619 return addr_cpumode;
2620}
2621
2595struct dso *machine__findnew_dso(struct machine *machine, const char *filename) 2622struct dso *machine__findnew_dso(struct machine *machine, const char *filename)
2596{ 2623{
2597 return dsos__findnew(&machine->dsos, filename); 2624 return dsos__findnew(&machine->dsos, filename);
diff --git a/tools/perf/util/machine.h b/tools/perf/util/machine.h
index ca897a73014c..ebde3ea70225 100644
--- a/tools/perf/util/machine.h
+++ b/tools/perf/util/machine.h
@@ -100,6 +100,8 @@ static inline bool machine__kernel_ip(struct machine *machine, u64 ip)
100 return ip >= kernel_start; 100 return ip >= kernel_start;
101} 101}
102 102
103u8 machine__addr_cpumode(struct machine *machine, u8 cpumode, u64 addr);
104
103struct thread *machine__find_thread(struct machine *machine, pid_t pid, 105struct thread *machine__find_thread(struct machine *machine, pid_t pid,
104 pid_t tid); 106 pid_t tid);
105struct comm *machine__thread_exec_comm(struct machine *machine, 107struct comm *machine__thread_exec_comm(struct machine *machine,
diff --git a/tools/perf/util/thread.h b/tools/perf/util/thread.h
index 30e2b4c165fe..5920c3bb8ffe 100644
--- a/tools/perf/util/thread.h
+++ b/tools/perf/util/thread.h
@@ -96,9 +96,13 @@ struct thread *thread__main_thread(struct machine *machine, struct thread *threa
96 96
97struct map *thread__find_map(struct thread *thread, u8 cpumode, u64 addr, 97struct map *thread__find_map(struct thread *thread, u8 cpumode, u64 addr,
98 struct addr_location *al); 98 struct addr_location *al);
99struct map *thread__find_map_fb(struct thread *thread, u8 cpumode, u64 addr,
100 struct addr_location *al);
99 101
100struct symbol *thread__find_symbol(struct thread *thread, u8 cpumode, 102struct symbol *thread__find_symbol(struct thread *thread, u8 cpumode,
101 u64 addr, struct addr_location *al); 103 u64 addr, struct addr_location *al);
104struct symbol *thread__find_symbol_fb(struct thread *thread, u8 cpumode,
105 u64 addr, struct addr_location *al);
102 106
103void thread__find_cpumode_addr_location(struct thread *thread, u64 addr, 107void thread__find_cpumode_addr_location(struct thread *thread, u64 addr,
104 struct addr_location *al); 108 struct addr_location *al);