static int access_dso_mem(struct unwind_info *ui, Dwarf_Addr addr, Dwarf_Word *data) { struct addr_location al; ssize_t size; if (!thread__find_map(ui->thread, PERF_RECORD_MISC_USER, addr, &al)) { pr_debug("unwind: no map for %lx\n", (unsigned long)addr); return -1; } if (!al.map->dso) return -1; size = dso__data_read_addr(al.map->dso, al.map, ui->machine, addr, (u8 *) data, sizeof(*data)); return !(size == sizeof(*data)); }
void thread__find_addr_location(struct thread *self, u8 cpumode, enum map_type type, u64 addr, struct addr_location *al, symbol_filter_t filter) { struct thread *thread = al->thread = self; al->addr = addr; if (cpumode & PERF_RECORD_MISC_KERNEL) { al->level = 'k'; thread = kthread; } else if (cpumode & PERF_RECORD_MISC_USER) al->level = '.'; else { al->level = 'H'; al->map = NULL; al->sym = NULL; return; } try_again: al->map = thread__find_map(thread, type, al->addr); if (al->map == NULL) { /* * If this is outside of all known maps, and is a negative * address, try to look it up in the kernel dso, as it might be * a vsyscall or vdso (which executes in user-mode). * * XXX This is nasty, we should have a symbol list in the * "[vdso]" dso, but for now lets use the old trick of looking * in the whole kernel symbol list. */ if ((long long)al->addr < 0 && thread != kthread) { thread = kthread; goto try_again; } al->sym = NULL; } else { al->addr = al->map->map_ip(al->map, al->addr); al->sym = map__find_symbol(al->map, al->addr, filter); } }