1 // SPDX-License-Identifier: GPL-2.0 2 #include <linux/compiler.h> 3 #include <elfutils/libdw.h> 4 #include <elfutils/libdwfl.h> 5 #include <inttypes.h> 6 #include <errno.h> 7 #include "debug.h" 8 #include "dso.h" 9 #include <dwarf-regs.h> 10 #include "unwind.h" 11 #include "unwind-libdw.h" 12 #include "machine.h" 13 #include "map.h" 14 #include "symbol.h" 15 #include "thread.h" 16 #include <linux/types.h> 17 #include <linux/zalloc.h> 18 #include "event.h" 19 #include "perf_regs.h" 20 #include "callchain.h" 21 #include "util/env.h" 22 23 static char *debuginfo_path; 24 25 static int __find_debuginfo(Dwfl_Module *mod __maybe_unused, void **userdata, 26 const char *modname __maybe_unused, Dwarf_Addr base __maybe_unused, 27 const char *file_name, const char *debuglink_file __maybe_unused, 28 GElf_Word debuglink_crc __maybe_unused, char **debuginfo_file_name) 29 { 30 const struct dso *dso = *userdata; 31 32 assert(dso); 33 if (dso__symsrc_filename(dso) && strcmp(file_name, dso__symsrc_filename(dso))) 34 *debuginfo_file_name = strdup(dso__symsrc_filename(dso)); 35 return -1; 36 } 37 38 static const Dwfl_Callbacks offline_callbacks = { 39 .find_debuginfo = __find_debuginfo, 40 .debuginfo_path = &debuginfo_path, 41 .section_address = dwfl_offline_section_address, 42 // .find_elf is not set as we use dwfl_report_elf() instead. 43 }; 44 45 static int __report_module(struct addr_location *al, u64 ip, 46 struct unwind_info *ui) 47 { 48 Dwfl_Module *mod; 49 struct dso *dso = NULL; 50 Dwarf_Addr base; 51 /* 52 * Some callers will use al->sym, so we can't just use the 53 * cheaper thread__find_map() here. 54 */ 55 thread__find_symbol(ui->thread, PERF_RECORD_MISC_USER, ip, al); 56 57 if (al->map) 58 dso = map__dso(al->map); 59 60 if (!dso) 61 return 0; 62 63 /* 64 * The generated JIT DSO files only map the code segment without 65 * ELF headers. Since JIT codes used to be packed in a memory 66 * segment, calculating the base address using pgoff falls into 67 * a different code in another DSO. So just use the map->start 68 * directly to pick the correct one. 69 */ 70 if (!strncmp(dso__long_name(dso), "/tmp/jitted-", 12)) 71 base = map__start(al->map); 72 else 73 base = map__start(al->map) - map__pgoff(al->map); 74 75 mod = dwfl_addrmodule(ui->dwfl, ip); 76 if (mod) { 77 Dwarf_Addr s; 78 79 dwfl_module_info(mod, NULL, &s, NULL, NULL, NULL, NULL, NULL); 80 if (s != base) 81 mod = NULL; 82 } 83 84 if (!mod) { 85 char filename[PATH_MAX]; 86 87 __symbol__join_symfs(filename, sizeof(filename), dso__long_name(dso)); 88 /* Don't hang up on device files like /dev/dri/renderD128. */ 89 if (is_regular_file(filename)) { 90 mod = dwfl_report_elf(ui->dwfl, dso__short_name(dso), filename, -1, 91 base, false); 92 } 93 } 94 if (!mod) { 95 char filename[PATH_MAX]; 96 97 if (dso__build_id_filename(dso, filename, sizeof(filename), false)) 98 mod = dwfl_report_elf(ui->dwfl, dso__short_name(dso), filename, -1, 99 base, false); 100 } 101 102 if (mod) { 103 void **userdatap; 104 105 dwfl_module_info(mod, &userdatap, NULL, NULL, NULL, NULL, NULL, NULL); 106 *userdatap = dso; 107 } 108 109 return mod && dwfl_addrmodule(ui->dwfl, ip) == mod ? 0 : -1; 110 } 111 112 static int report_module(u64 ip, struct unwind_info *ui) 113 { 114 struct addr_location al; 115 int res; 116 117 addr_location__init(&al); 118 res = __report_module(&al, ip, ui); 119 addr_location__exit(&al); 120 return res; 121 } 122 123 /* 124 * Store all entries within entries array, 125 * we will process it after we finish unwind. 126 */ 127 static int entry(u64 ip, struct unwind_info *ui) 128 129 { 130 struct unwind_entry *e = &ui->entries[ui->idx++]; 131 struct addr_location al; 132 133 addr_location__init(&al); 134 if (__report_module(&al, ip, ui)) { 135 addr_location__exit(&al); 136 return -1; 137 } 138 139 e->ip = ip; 140 e->ms.maps = maps__get(al.maps); 141 e->ms.map = map__get(al.map); 142 e->ms.sym = al.sym; 143 144 pr_debug("unwind: %s:ip = 0x%" PRIx64 " (0x%" PRIx64 ")\n", 145 al.sym ? al.sym->name : "''", 146 ip, 147 al.map ? map__map_ip(al.map, ip) : (u64) 0); 148 addr_location__exit(&al); 149 return 0; 150 } 151 152 static pid_t next_thread(Dwfl *dwfl, void *arg, void **thread_argp) 153 { 154 /* We want only single thread to be processed. */ 155 if (*thread_argp != NULL) 156 return 0; 157 158 *thread_argp = arg; 159 return dwfl_pid(dwfl); 160 } 161 162 static int access_dso_mem(struct unwind_info *ui, Dwarf_Addr addr, 163 Dwarf_Word *data) 164 { 165 struct addr_location al; 166 ssize_t size; 167 struct dso *dso; 168 169 addr_location__init(&al); 170 if (!thread__find_map(ui->thread, PERF_RECORD_MISC_USER, addr, &al)) { 171 pr_debug("unwind: no map for %lx\n", (unsigned long)addr); 172 goto out_fail; 173 } 174 dso = map__dso(al.map); 175 if (!dso) 176 goto out_fail; 177 178 size = dso__data_read_addr(dso, al.map, ui->machine, addr, (u8 *) data, sizeof(*data)); 179 180 addr_location__exit(&al); 181 return !(size == sizeof(*data)); 182 out_fail: 183 addr_location__exit(&al); 184 return -1; 185 } 186 187 static bool memory_read(Dwfl *dwfl __maybe_unused, Dwarf_Addr addr, Dwarf_Word *result, 188 void *arg) 189 { 190 struct unwind_info *ui = arg; 191 uint16_t e_machine = thread__e_machine(ui->thread, ui->machine); 192 struct stack_dump *stack = &ui->sample->user_stack; 193 u64 start, end; 194 int offset; 195 int ret; 196 197 if (!ui->sample->user_regs) 198 return false; 199 200 ret = perf_reg_value(&start, ui->sample->user_regs, 201 perf_arch_reg_sp(e_machine)); 202 if (ret) 203 return false; 204 205 end = start + stack->size; 206 207 /* Check overflow. */ 208 if (addr + sizeof(Dwarf_Word) < addr) 209 return false; 210 211 if (addr < start || addr + sizeof(Dwarf_Word) > end) { 212 ret = access_dso_mem(ui, addr, result); 213 if (ret) { 214 pr_debug("unwind: access_mem 0x%" PRIx64 " not inside range" 215 " 0x%" PRIx64 "-0x%" PRIx64 "\n", 216 addr, start, end); 217 return false; 218 } 219 return true; 220 } 221 222 offset = addr - start; 223 *result = *(Dwarf_Word *)&stack->data[offset]; 224 pr_debug("unwind: access_mem addr 0x%" PRIx64 ", val %lx, offset %d\n", 225 addr, (unsigned long)*result, offset); 226 return true; 227 } 228 229 static bool libdw_set_initial_registers_generic(Dwfl_Thread *thread, void *arg) 230 { 231 struct unwind_info *ui = arg; 232 struct regs_dump *user_regs = perf_sample__user_regs(ui->sample); 233 Dwarf_Word *dwarf_regs; 234 int max_dwarf_reg = 0; 235 bool ret; 236 uint16_t e_machine = ui->e_machine; 237 int e_flags = 0; 238 uint64_t ip_perf_reg = perf_arch_reg_ip(e_machine); 239 Dwarf_Word val = 0; 240 241 242 /* 243 * For every possible perf register in the bitmap determine the dwarf 244 * register and use to compute the max. 245 */ 246 for (int perf_reg = 0; perf_reg < 64; perf_reg++) { 247 if (user_regs->mask & (1ULL << perf_reg)) { 248 int dwarf_reg = 249 get_dwarf_regnum_for_perf_regnum(perf_reg, e_machine, 250 e_flags, 251 /*only_libdw_supported=*/true); 252 if (dwarf_reg > max_dwarf_reg) 253 max_dwarf_reg = dwarf_reg; 254 } 255 } 256 257 dwarf_regs = calloc(max_dwarf_reg + 1, sizeof(*dwarf_regs)); 258 if (!dwarf_regs) 259 return false; 260 261 for (int perf_reg = 0; perf_reg < 64; perf_reg++) { 262 if (user_regs->mask & (1ULL << perf_reg)) { 263 int dwarf_reg = 264 get_dwarf_regnum_for_perf_regnum(perf_reg, e_machine, 265 e_flags, 266 /*only_libdw_supported=*/true); 267 if (dwarf_reg >= 0) { 268 val = 0; 269 if (perf_reg_value(&val, user_regs, perf_reg) == 0) 270 dwarf_regs[dwarf_reg] = val; 271 } 272 } 273 } 274 if (perf_reg_value(&val, user_regs, ip_perf_reg) == 0) 275 dwfl_thread_state_register_pc(thread, val); 276 277 ret = dwfl_thread_state_registers(thread, 0, max_dwarf_reg + 1, dwarf_regs); 278 free(dwarf_regs); 279 return ret; 280 } 281 282 #define DEFINE_DWFL_THREAD_CALLBACKS(arch) \ 283 static const Dwfl_Thread_Callbacks callbacks_##arch = { \ 284 .next_thread = next_thread, \ 285 .memory_read = memory_read, \ 286 .set_initial_registers = libdw_set_initial_registers_##arch, \ 287 } 288 289 static const Dwfl_Thread_Callbacks callbacks_generic = { 290 .next_thread = next_thread, 291 .memory_read = memory_read, 292 .set_initial_registers = libdw_set_initial_registers_generic, 293 }; 294 295 DEFINE_DWFL_THREAD_CALLBACKS(powerpc); 296 DEFINE_DWFL_THREAD_CALLBACKS(riscv); 297 DEFINE_DWFL_THREAD_CALLBACKS(s390); 298 299 static const Dwfl_Thread_Callbacks *get_thread_callbacks(const char *arch) 300 { 301 if (!strcmp(arch, "powerpc")) 302 return &callbacks_powerpc; 303 else if (!strcmp(arch, "riscv")) 304 return &callbacks_riscv; 305 else if (!strcmp(arch, "s390")) 306 return &callbacks_s390; 307 308 return &callbacks_generic; 309 } 310 311 static int 312 frame_callback(Dwfl_Frame *state, void *arg) 313 { 314 struct unwind_info *ui = arg; 315 Dwarf_Addr pc; 316 bool isactivation; 317 318 if (!dwfl_frame_pc(state, &pc, NULL)) { 319 if (!ui->best_effort) 320 pr_err("%s", dwfl_errmsg(-1)); 321 return DWARF_CB_ABORT; 322 } 323 324 // report the module before we query for isactivation 325 report_module(pc, ui); 326 327 if (!dwfl_frame_pc(state, &pc, &isactivation)) { 328 if (!ui->best_effort) 329 pr_err("%s", dwfl_errmsg(-1)); 330 return DWARF_CB_ABORT; 331 } 332 333 if (!isactivation) 334 --pc; 335 336 return entry(pc, ui) || !(--ui->max_stack) ? 337 DWARF_CB_ABORT : DWARF_CB_OK; 338 } 339 340 int unwind__get_entries(unwind_entry_cb_t cb, void *arg, 341 struct thread *thread, 342 struct perf_sample *data, 343 int max_stack, 344 bool best_effort) 345 { 346 struct machine *machine = maps__machine(thread__maps(thread)); 347 uint16_t e_machine = thread__e_machine(thread, machine); 348 struct unwind_info *ui, ui_buf = { 349 .sample = data, 350 .thread = thread, 351 .machine = machine, 352 .cb = cb, 353 .arg = arg, 354 .max_stack = max_stack, 355 .e_machine = e_machine, 356 .best_effort = best_effort 357 }; 358 const char *arch = perf_env__arch(machine->env); 359 Dwarf_Word ip; 360 int err = -EINVAL, i; 361 const Dwfl_Thread_Callbacks *callbacks; 362 363 if (!data->user_regs || !data->user_regs->regs) 364 return -EINVAL; 365 366 ui = zalloc(sizeof(ui_buf) + sizeof(ui_buf.entries[0]) * max_stack); 367 if (!ui) 368 return -ENOMEM; 369 370 *ui = ui_buf; 371 372 ui->dwfl = dwfl_begin(&offline_callbacks); 373 if (!ui->dwfl) 374 goto out; 375 376 err = perf_reg_value(&ip, data->user_regs, perf_arch_reg_ip(e_machine)); 377 if (err) 378 goto out; 379 380 err = report_module(ip, ui); 381 if (err) 382 goto out; 383 384 callbacks = get_thread_callbacks(arch); 385 if (!callbacks) 386 goto out; 387 388 err = !dwfl_attach_state(ui->dwfl, /*elf=*/NULL, thread__tid(thread), callbacks, ui); 389 if (err) 390 goto out; 391 392 err = dwfl_getthread_frames(ui->dwfl, thread__tid(thread), frame_callback, ui); 393 394 if (err && ui->max_stack != max_stack) 395 err = 0; 396 397 /* 398 * Display what we got based on the order setup. 399 */ 400 for (i = 0; i < ui->idx && !err; i++) { 401 int j = i; 402 403 if (callchain_param.order == ORDER_CALLER) 404 j = ui->idx - i - 1; 405 406 err = ui->entries[j].ip ? ui->cb(&ui->entries[j], ui->arg) : 0; 407 } 408 409 out: 410 if (err) 411 pr_debug("unwind: failed with '%s'\n", dwfl_errmsg(-1)); 412 413 for (i = 0; i < ui->idx; i++) 414 map_symbol__exit(&ui->entries[i].ms); 415 416 dwfl_end(ui->dwfl); 417 free(ui); 418 return 0; 419 } 420