24 #include <linux/list.h>
25 #include <libunwind.h>
26 #include <libunwind-ptrace.h>
38 int need_unwind_info,
void *
arg);
40 #define dwarf_search_unwind_table UNW_OBJ(dwarf_search_unwind_table)
42 #define DW_EH_PE_FORMAT_MASK 0x0f
43 #define DW_EH_PE_APPL_MASK 0x70
46 #define DW_EH_PE_omit 0xff
47 #define DW_EH_PE_ptr 0x00
48 #define DW_EH_PE_udata4 0x03
49 #define DW_EH_PE_udata8 0x04
50 #define DW_EH_PE_sdata4 0x0b
51 #define DW_EH_PE_sdata8 0x0c
54 #define DW_EH_PE_absptr 0x00
55 #define DW_EH_PE_pcrel 0x10
62 #define DW_EH_PE_funcrel 0x40
63 #define DW_EH_PE_aligned 0x50
82 #define dw_read(ptr, type, end) ({ \
83 type *__p = (type *) ptr; \
85 if ((__p + 1) > (type *) end) \
88 ptr = (typeof(ptr)) __p; \
103 *val =
dw_read(cur,
unsigned long, end);
113 *val = (
unsigned long) cur;
119 if ((encoding & 0x07) == 0x00)
144 #define dw_read_encoded_value(ptr, end, enc) ({ \
146 if (__dw_read_encoded_value(&ptr, end, &__v, enc)) { \
152 static Elf_Scn *elf_section_by_name(Elf *elf, GElf_Ehdr *ep,
153 GElf_Shdr *shp,
const char *
name)
157 while ((sec = elf_nextscn(elf, sec)) !=
NULL) {
160 gelf_getshdr(sec, shp);
161 str = elf_strptr(elf, ep->e_shstrndx, shp->sh_name);
169 static u64 elf_section_offset(
int fd,
const char *
name)
181 if (gelf_getehdr(elf, &ehdr) ==
NULL)
184 if (!elf_section_by_name(elf, &ehdr, &shdr, name))
187 offset = shdr.sh_offset;
226 u64 offset,
u64 *table_data,
u64 *segbase,
235 (
u8 *) &hdr,
sizeof(hdr));
236 if (r !=
sizeof(hdr))
244 *table_data = (enc - (
u8 *) &hdr) +
offset;
249 u64 *table_data,
u64 *segbase,
u64 *fde_count)
258 offset = elf_section_offset(fd,
".eh_frame_hdr");
262 ret = unwind_spec_ehframe(dso, machine, offset,
280 find_proc_info(unw_addr_space_t
as, unw_word_t
ip, unw_proc_info_t *pi,
281 int need_unwind_info,
void *
arg)
286 u64 table_data, segbase, fde_count;
288 map = find_map(ip, ui);
289 if (!map || !map->
dso)
292 pr_debug(
"unwind: find_proc_info dso %s\n", map->
dso->name);
295 &table_data, &segbase, &fde_count))
298 memset(&di, 0,
sizeof(di));
299 di.format = UNW_INFO_FORMAT_REMOTE_TABLE;
300 di.start_ip = map->
start;
301 di.end_ip = map->
end;
302 di.u.rti.segbase = map->
start + segbase;
303 di.u.rti.table_data = map->
start + table_data;
304 di.u.rti.table_len = fde_count *
sizeof(
struct table_entry)
307 need_unwind_info, arg);
316 pr_err(
"unwind: access_fpreg unsupported\n");
320 static int get_dyn_info_list_addr(unw_addr_space_t
__maybe_unused as,
331 pr_err(
"unwind: resume unsupported\n");
341 pr_err(
"unwind: get_proc_name unsupported\n");
354 pr_debug(
"unwind: no map for %lx\n", (
unsigned long)addr);
362 addr, (
u8 *) data,
sizeof(*data));
364 return !(size ==
sizeof(*data));
367 static int reg_value(unw_word_t *valp,
struct regs_dump *
regs,
int id,
372 if (!(sample_regs & (1 <<
id)))
375 for (i = 0; i <
id; i++) {
376 if (sample_regs & (1 << i))
385 unw_word_t addr, unw_word_t *valp,
386 int __write,
void *arg)
395 if (__write || !stack || !ui->
sample->user_regs.regs) {
405 end = start + stack->
size;
408 if (addr +
sizeof(unw_word_t) < addr)
411 if (addr < start || addr +
sizeof(unw_word_t) >= end) {
412 ret = access_dso_mem(ui, addr, valp);
414 pr_debug(
"unwind: access_mem %p not inside range %p-%p\n",
415 (
void *)addr, (
void *)start, (
void *)end);
422 offset = addr -
start;
423 *valp = *(unw_word_t *)&stack->
data[offset];
424 pr_debug(
"unwind: access_mem addr %p, val %lx, offset %d\n",
425 (
void *)
addr, (
unsigned long)*valp, offset);
430 unw_regnum_t regnum, unw_word_t *valp,
431 int __write,
void *arg)
438 pr_err(
"unwind: access_reg w %d\n", regnum);
442 if (!ui->
sample->user_regs.regs) {
453 pr_err(
"unwind: can't read reg %d\n", regnum);
457 pr_debug(
"unwind: reg %d, val %lx\n", regnum, (
unsigned long)*valp);
463 void *arg __maybe_unused)
465 pr_debug(
"unwind: put_unwind_info called\n");
483 al.sym ? al.sym->name :
"''",
485 al.map ? al.map->map_ip(al.map, ip) : (
u64) 0);
490 static void display_error(
int err)
494 pr_err(
"unwind: Only supports local.\n");
497 pr_err(
"unwind: Unspecified error.\n");
500 pr_err(
"unwind: Register unavailable.\n");
507 static unw_accessors_t accessors = {
508 .find_proc_info = find_proc_info,
509 .put_unwind_info = put_unwind_info,
510 .get_dyn_info_list_addr = get_dyn_info_list_addr,
511 .access_mem = access_mem,
512 .access_reg = access_reg,
513 .access_fpreg = access_fpreg,
515 .get_proc_name = get_proc_name,
521 unw_addr_space_t addr_space;
525 addr_space = unw_create_addr_space(&accessors, 0);
527 pr_err(
"unwind: Can't create unwind address space.\n");
531 ret = unw_init_remote(&c, addr_space, ui);
535 while (!ret && (unw_step(&c) > 0)) {
538 unw_get_reg(&c, UNW_REG_IP, &ip);
542 unw_destroy_addr_space(addr_space);
566 ret =
entry(ip, thread, machine, cb, arg);
570 return get_entries(&ui, cb, arg);