return al->map;
 }
 
+/*
+ * For branch stacks or branch samples, the sample cpumode might not be correct
+ * because it applies only to the sample 'ip' and not necessary to 'addr' or
+ * branch stack addresses. If possible, use a fallback to deal with those cases.
+ */
+struct map *thread__find_map_fb(struct thread *thread, u8 cpumode, u64 addr,
+                               struct addr_location *al)
+{
+       struct map *map = thread__find_map(thread, cpumode, addr, al);
+       struct machine *machine = thread->mg->machine;
+       u8 addr_cpumode = machine__addr_cpumode(machine, cpumode, addr);
+
+       if (map || addr_cpumode == cpumode)
+               return map;
+
+       return thread__find_map(thread, addr_cpumode, addr, al);
+}
+
 struct symbol *thread__find_symbol(struct thread *thread, u8 cpumode,
                                   u64 addr, struct addr_location *al)
 {
        return al->sym;
 }
 
+struct symbol *thread__find_symbol_fb(struct thread *thread, u8 cpumode,
+                                     u64 addr, struct addr_location *al)
+{
+       al->sym = NULL;
+       if (thread__find_map_fb(thread, cpumode, addr, al))
+               al->sym = map__find_symbol(al->map, al->addr);
+       return al->sym;
+}
+
 /*
  * Callers need to drop the reference to al->thread, obtained in
  * machine__findnew_thread()
 
        return err;
 }
 
+u8 machine__addr_cpumode(struct machine *machine, u8 cpumode, u64 addr)
+{
+       u8 addr_cpumode = cpumode;
+       bool kernel_ip;
+
+       if (!machine->single_address_space)
+               goto out;
+
+       kernel_ip = machine__kernel_ip(machine, addr);
+       switch (cpumode) {
+       case PERF_RECORD_MISC_KERNEL:
+       case PERF_RECORD_MISC_USER:
+               addr_cpumode = kernel_ip ? PERF_RECORD_MISC_KERNEL :
+                                          PERF_RECORD_MISC_USER;
+               break;
+       case PERF_RECORD_MISC_GUEST_KERNEL:
+       case PERF_RECORD_MISC_GUEST_USER:
+               addr_cpumode = kernel_ip ? PERF_RECORD_MISC_GUEST_KERNEL :
+                                          PERF_RECORD_MISC_GUEST_USER;
+               break;
+       default:
+               break;
+       }
+out:
+       return addr_cpumode;
+}
+
 struct dso *machine__findnew_dso(struct machine *machine, const char *filename)
 {
        return dsos__findnew(&machine->dsos, filename);
 
        return ip >= kernel_start;
 }
 
+u8 machine__addr_cpumode(struct machine *machine, u8 cpumode, u64 addr);
+
 struct thread *machine__find_thread(struct machine *machine, pid_t pid,
                                    pid_t tid);
 struct comm *machine__thread_exec_comm(struct machine *machine,
 
 
 struct map *thread__find_map(struct thread *thread, u8 cpumode, u64 addr,
                             struct addr_location *al);
+struct map *thread__find_map_fb(struct thread *thread, u8 cpumode, u64 addr,
+                               struct addr_location *al);
 
 struct symbol *thread__find_symbol(struct thread *thread, u8 cpumode,
                                   u64 addr, struct addr_location *al);
+struct symbol *thread__find_symbol_fb(struct thread *thread, u8 cpumode,
+                                     u64 addr, struct addr_location *al);
 
 void thread__find_cpumode_addr_location(struct thread *thread, u64 addr,
                                        struct addr_location *al);