.. | .. |
---|
5 | 5 | #include <inttypes.h> |
---|
6 | 6 | #include <errno.h> |
---|
7 | 7 | #include "debug.h" |
---|
| 8 | +#include "dso.h" |
---|
8 | 9 | #include "unwind.h" |
---|
9 | 10 | #include "unwind-libdw.h" |
---|
10 | 11 | #include "machine.h" |
---|
| 12 | +#include "map.h" |
---|
| 13 | +#include "symbol.h" |
---|
11 | 14 | #include "thread.h" |
---|
12 | 15 | #include <linux/types.h> |
---|
| 16 | +#include <linux/zalloc.h> |
---|
13 | 17 | #include "event.h" |
---|
14 | 18 | #include "perf_regs.h" |
---|
15 | 19 | #include "callchain.h" |
---|
16 | | -#include "util.h" |
---|
17 | 20 | |
---|
18 | 21 | static char *debuginfo_path; |
---|
19 | 22 | |
---|
| 23 | +static int __find_debuginfo(Dwfl_Module *mod __maybe_unused, void **userdata, |
---|
| 24 | + const char *modname __maybe_unused, Dwarf_Addr base __maybe_unused, |
---|
| 25 | + const char *file_name, const char *debuglink_file __maybe_unused, |
---|
| 26 | + GElf_Word debuglink_crc __maybe_unused, char **debuginfo_file_name) |
---|
| 27 | +{ |
---|
| 28 | + const struct dso *dso = *userdata; |
---|
| 29 | + |
---|
| 30 | + assert(dso); |
---|
| 31 | + if (dso->symsrc_filename && strcmp (file_name, dso->symsrc_filename)) |
---|
| 32 | + *debuginfo_file_name = strdup(dso->symsrc_filename); |
---|
| 33 | + return -1; |
---|
| 34 | +} |
---|
| 35 | + |
---|
20 | 36 | static const Dwfl_Callbacks offline_callbacks = { |
---|
21 | | - .find_debuginfo = dwfl_standard_find_debuginfo, |
---|
| 37 | + .find_debuginfo = __find_debuginfo, |
---|
22 | 38 | .debuginfo_path = &debuginfo_path, |
---|
23 | 39 | .section_address = dwfl_offline_section_address, |
---|
| 40 | + // .find_elf is not set as we use dwfl_report_elf() instead. |
---|
24 | 41 | }; |
---|
25 | 42 | |
---|
26 | 43 | static int __report_module(struct addr_location *al, u64 ip, |
---|
.. | .. |
---|
50 | 67 | } |
---|
51 | 68 | |
---|
52 | 69 | if (!mod) |
---|
53 | | - mod = dwfl_report_elf(ui->dwfl, dso->short_name, |
---|
54 | | - (dso->symsrc_filename ? dso->symsrc_filename : dso->long_name), -1, al->map->start - al->map->pgoff, |
---|
55 | | - false); |
---|
| 70 | + mod = dwfl_report_elf(ui->dwfl, dso->short_name, dso->long_name, -1, |
---|
| 71 | + al->map->start - al->map->pgoff, false); |
---|
| 72 | + if (!mod) { |
---|
| 73 | + char filename[PATH_MAX]; |
---|
| 74 | + |
---|
| 75 | + if (dso__build_id_filename(dso, filename, sizeof(filename), false)) |
---|
| 76 | + mod = dwfl_report_elf(ui->dwfl, dso->short_name, filename, -1, |
---|
| 77 | + al->map->start - al->map->pgoff, false); |
---|
| 78 | + } |
---|
| 79 | + |
---|
| 80 | + if (mod) { |
---|
| 81 | + void **userdatap; |
---|
| 82 | + |
---|
| 83 | + dwfl_module_info(mod, &userdatap, NULL, NULL, NULL, NULL, NULL, NULL); |
---|
| 84 | + *userdatap = dso; |
---|
| 85 | + } |
---|
56 | 86 | |
---|
57 | 87 | return mod && dwfl_addrmodule(ui->dwfl, ip) == mod ? 0 : -1; |
---|
58 | 88 | } |
---|
.. | .. |
---|
77 | 107 | if (__report_module(&al, ip, ui)) |
---|
78 | 108 | return -1; |
---|
79 | 109 | |
---|
80 | | - e->ip = ip; |
---|
81 | | - e->map = al.map; |
---|
82 | | - e->sym = al.sym; |
---|
| 110 | + e->ip = ip; |
---|
| 111 | + e->ms.maps = al.maps; |
---|
| 112 | + e->ms.map = al.map; |
---|
| 113 | + e->ms.sym = al.sym; |
---|
83 | 114 | |
---|
84 | 115 | pr_debug("unwind: %s:ip = 0x%" PRIx64 " (0x%" PRIx64 ")\n", |
---|
85 | 116 | al.sym ? al.sym->name : "''", |
---|
.. | .. |
---|
196 | 227 | struct unwind_info *ui, ui_buf = { |
---|
197 | 228 | .sample = data, |
---|
198 | 229 | .thread = thread, |
---|
199 | | - .machine = thread->mg->machine, |
---|
| 230 | + .machine = thread->maps->machine, |
---|
200 | 231 | .cb = cb, |
---|
201 | 232 | .arg = arg, |
---|
202 | 233 | .max_stack = max_stack, |
---|