2 #include <linux/compiler.h> 3 #include <elfutils/libdw.h> 4 #include <elfutils/libdwfl.h> 12 #include <linux/types.h> 21 .find_debuginfo = dwfl_standard_find_debuginfo,
23 .section_address = dwfl_offline_section_address,
43 mod = dwfl_addrmodule(ui->
dwfl, ip);
47 dwfl_module_info(mod, NULL, &s, NULL, NULL, NULL, NULL, NULL);
57 return mod && dwfl_addrmodule(ui->
dwfl, ip) == mod ? 0 : -1;
84 pr_debug(
"unwind: %s:ip = 0x%" PRIx64
" (0x%" PRIx64
")\n",
91 static pid_t
next_thread(Dwfl *dwfl,
void *arg,
void **thread_argp)
94 if (*thread_argp != NULL)
98 return dwfl_pid(dwfl);
108 pr_debug(
"unwind: no map for %lx\n", (
unsigned long)addr);
116 addr, (u8 *) data,
sizeof(*data));
118 return !(size ==
sizeof(*data));
134 end = start + stack->
size;
137 if (addr +
sizeof(Dwarf_Word) < addr)
140 if (addr < start || addr +
sizeof(Dwarf_Word) > end) {
143 pr_debug(
"unwind: access_mem 0x%" PRIx64
" not inside range" 144 " 0x%" PRIx64
"-0x%" PRIx64
"\n",
151 offset = addr -
start;
152 *result = *(Dwarf_Word *)&stack->
data[offset];
153 pr_debug(
"unwind: access_mem addr 0x%" PRIx64
", val %lx, offset %d\n",
171 if (!dwfl_frame_pc(state, &pc, NULL)) {
172 pr_err(
"%s", dwfl_errmsg(-1));
173 return DWARF_CB_ABORT;
179 if (!dwfl_frame_pc(state, &pc, &isactivation)) {
180 pr_err(
"%s", dwfl_errmsg(-1));
181 return DWARF_CB_ABORT;
188 DWARF_CB_ABORT : DWARF_CB_OK;
205 int err = -EINVAL, i;
210 ui =
zalloc(
sizeof(ui_buf) +
sizeof(ui_buf.
entries[0]) * max_stack);
240 for (i = 0; i < ui->
idx && !
err; i++) {
251 pr_debug(
"unwind: failed with '%s'\n", dwfl_errmsg(-1));
static char * debuginfo_path
u64(* map_ip)(struct map *, u64)
static int __report_module(struct addr_location *al, u64 ip, struct unwind_info *ui)
struct map * thread__find_map(struct thread *thread, u8 cpumode, u64 addr, struct addr_location *al)
static int perf_reg_value(u64 *valp __maybe_unused, struct regs_dump *regs __maybe_unused, int id __maybe_unused)
static int report_module(u64 ip, struct unwind_info *ui)
static int access_dso_mem(struct unwind_info *ui, Dwarf_Addr addr, Dwarf_Word *data)
int(* unwind_entry_cb_t)(struct unwind_entry *entry, void *arg)
int unwind__get_entries(unwind_entry_cb_t cb, void *arg, struct thread *thread, struct perf_sample *data, int max_stack)
ssize_t dso__data_read_addr(struct dso *dso, struct map *map, struct machine *machine, u64 addr, u8 *data, ssize_t size)
#define pr_debug(fmt,...)
static int frame_callback(Dwfl_Frame *state, void *arg)
static int entry(u64 ip, struct unwind_info *ui)
struct regs_dump user_regs
static bool memory_read(Dwfl *dwfl __maybe_unused, Dwarf_Addr addr, Dwarf_Word *result, void *arg)
static pid_t next_thread(Dwfl *dwfl, void *arg, void **thread_argp)
static struct rb_root result
bool libdw__arch_set_initial_registers(Dwfl_Thread *thread, void *arg)
struct unwind_entry entries[]
struct symbol * thread__find_symbol(struct thread *thread, u8 cpumode, u64 addr, struct addr_location *al)
struct perf_sample * sample
struct stack_dump user_stack
static const Dwfl_Callbacks offline_callbacks
static const Dwfl_Thread_Callbacks callbacks
void static void * zalloc(size_t size)