27 #include <linux/list.h> 28 #ifndef REMOTE_UNWIND_LIBUNWIND 29 #include <libunwind.h> 30 #include <libunwind-ptrace.h> 48 int need_unwind_info,
void *arg);
50 #define dwarf_search_unwind_table UNW_OBJ(dwarf_search_unwind_table) 56 const char *obj_name, unw_word_t
start,
59 #define dwarf_find_debug_frame UNW_OBJ(dwarf_find_debug_frame) 61 #define DW_EH_PE_FORMAT_MASK 0x0f 62 #define DW_EH_PE_APPL_MASK 0x70 65 #define DW_EH_PE_omit 0xff 66 #define DW_EH_PE_ptr 0x00 67 #define DW_EH_PE_udata4 0x03 68 #define DW_EH_PE_udata8 0x04 69 #define DW_EH_PE_sdata4 0x0b 70 #define DW_EH_PE_sdata8 0x0c 73 #define DW_EH_PE_absptr 0x00 74 #define DW_EH_PE_pcrel 0x10 81 #define DW_EH_PE_funcrel 0x40 82 #define DW_EH_PE_aligned 0x50 100 #define dw_read(ptr, type, end) ({ \ 101 type *__p = (type *) ptr; \ 103 if ((__p + 1) > (type *) end) \ 106 ptr = (typeof(ptr)) __p; \ 121 *val =
dw_read(cur,
unsigned long, end);
131 *val = (
unsigned long) cur;
137 if ((encoding & 0x07) == 0x00)
142 *val +=
dw_read(cur, s32, end);
145 *val +=
dw_read(cur, u32, end);
148 *val +=
dw_read(cur, s64, end);
151 *val +=
dw_read(cur, u64, end);
162 #define dw_read_encoded_value(ptr, end, enc) ({ \ 164 if (__dw_read_encoded_value(&ptr, end, &__v, enc)) { \ 182 if (gelf_getehdr(elf, &ehdr) == NULL)
188 offset = shdr.sh_offset;
195 #ifndef NO_LIBUNWIND_DEBUG_FRAME 205 if (gelf_getehdr(elf, &ehdr) == NULL)
208 retval = (ehdr.e_type == ET_EXEC);
212 pr_debug(
"unwind: elf_is_exec(%s): %d\n", name, retval);
249 u64 offset, u64 *table_data, u64 *segbase,
253 u8 *
enc = (u8 *) &hdr.
enc;
254 u8 *end = (u8 *) &hdr.
data;
258 (u8 *) &hdr,
sizeof(hdr));
259 if (r !=
sizeof(hdr))
267 *table_data = (enc - (u8 *) &hdr) + offset;
272 u64 *table_data, u64 *segbase,
275 int ret = -EINVAL, fd;
297 #ifndef NO_LIBUNWIND_DEBUG_FRAME 333 fd = open(debuglink, O_RDONLY);
343 "%s: overwrite symsrc(%s,%s)\n",
374 int need_unwind_info,
void *
arg)
379 u64 table_data, segbase, fde_count;
383 if (!map || !map->
dso)
390 &table_data, &segbase, &fde_count)) {
391 memset(&di, 0,
sizeof(di));
392 di.format = UNW_INFO_FORMAT_REMOTE_TABLE;
393 di.start_ip = map->
start;
394 di.end_ip = map->
end;
395 di.u.rti.segbase = map->
start + segbase - map->
pgoff;
396 di.u.rti.table_data = map->
start + table_data - map->
pgoff;
397 di.u.rti.table_len = fde_count *
sizeof(
struct table_entry)
398 / sizeof(unw_word_t);
400 need_unwind_info, arg);
403 #ifndef NO_LIBUNWIND_DEBUG_FRAME 409 unw_word_t base = is_exec ? 0 : map->
start;
417 memset(&di, 0,
sizeof(di));
421 need_unwind_info, arg);
429 unw_regnum_t __maybe_unused num,
430 unw_fpreg_t __maybe_unused *val,
431 int __maybe_unused __write,
432 void __maybe_unused *
arg)
434 pr_err(
"unwind: access_fpreg unsupported\n");
439 unw_word_t __maybe_unused *dil_addr,
440 void __maybe_unused *
arg)
445 static int resume(unw_addr_space_t __maybe_unused as,
446 unw_cursor_t __maybe_unused *cu,
447 void __maybe_unused *
arg)
449 pr_err(
"unwind: resume unsupported\n");
455 unw_word_t __maybe_unused addr,
456 char __maybe_unused *bufp,
size_t __maybe_unused buf_len,
457 unw_word_t __maybe_unused *offp,
void __maybe_unused *
arg)
459 pr_err(
"unwind: get_proc_name unsupported\n");
471 pr_debug(
"unwind: no map for %lx\n", (
unsigned long)addr);
479 addr, (u8 *) data,
sizeof(*data));
481 return !(size ==
sizeof(*data));
485 unw_word_t addr, unw_word_t *valp,
486 int __write,
void *
arg)
505 end = start + stack->
size;
508 if (addr +
sizeof(unw_word_t) < addr)
511 if (addr < start || addr +
sizeof(unw_word_t) >= end) {
514 pr_debug(
"unwind: access_mem %p not inside range" 515 " 0x%" PRIx64
"-0x%" PRIx64
"\n",
516 (
void *) (uintptr_t) addr, start, end);
523 offset = addr -
start;
524 *valp = *(unw_word_t *)&stack->
data[offset];
525 pr_debug(
"unwind: access_mem addr %p val %lx, offset %d\n",
526 (
void *) (uintptr_t) addr, (
unsigned long)*valp,
offset);
531 unw_regnum_t regnum, unw_word_t *valp,
532 int __write,
void *
arg)
540 pr_err(
"unwind: access_reg w %d\n", regnum);
555 pr_err(
"unwind: can't read reg %d\n", regnum);
559 *valp = (unw_word_t) val;
560 pr_debug(
"unwind: reg %d, val %lx\n", regnum, (
unsigned long)*valp);
565 unw_proc_info_t *pi __maybe_unused,
566 void *
arg __maybe_unused)
568 pr_debug(
"unwind: put_unwind_info called\n");
581 pr_debug(
"unwind: %s:ip = 0x%" PRIx64
" (0x%" PRIx64
")\n",
593 pr_err(
"unwind: Only supports local.\n");
596 pr_err(
"unwind: Unspecified error.\n");
599 pr_err(
"unwind: Register unavailable.\n");
621 thread->addr_space = unw_create_addr_space(&
accessors, 0);
622 if (!thread->addr_space) {
623 pr_err(
"unwind: Can't create unwind address space.\n");
627 unw_set_caching_policy(thread->addr_space, UNW_CACHE_GLOBAL);
635 unw_flush_cache(thread->addr_space, 0, 0);
642 unw_destroy_addr_space(thread->addr_space);
650 unw_addr_space_t addr_space;
659 ips[i++] = (unw_word_t) val;
665 if (max_stack - 1 > 0) {
666 WARN_ONCE(!ui->
thread,
"WARNING: ui->thread is NULL");
667 addr_space = ui->
thread->addr_space;
669 if (addr_space == NULL)
672 ret = unw_init_remote(&c, addr_space, ui);
676 while (!ret && (unw_step(&c) > 0) && i < max_stack) {
677 unw_get_reg(&c, UNW_REG_IP, &ips[i]);
686 if (unw_is_signal_frame(&c) <= 0)
698 for (i = 0; i < max_stack && !ret; i++) {
702 j = max_stack - i - 1;
703 ret = ips[j] ?
entry(ips[j], ui->
thread, cb, arg) : 0;
736 #ifndef REMOTE_UNWIND_LIBUNWIND static int find_proc_info(unw_addr_space_t as, unw_word_t ip, unw_proc_info_t *pi, int need_unwind_info, void *arg)
static int access_reg(unw_addr_space_t __maybe_unused as, unw_regnum_t regnum, unw_word_t *valp, int __write, void *arg)
u64(* map_ip)(struct map *, u64)
static int get_proc_name(unw_addr_space_t __maybe_unused as, unw_word_t __maybe_unused addr, char __maybe_unused *bufp, size_t __maybe_unused buf_len, unw_word_t __maybe_unused *offp, void __maybe_unused *arg)
#define DW_EH_PE_APPL_MASK
static int _unwind__prepare_access(struct thread *thread)
static int access_fpreg(unw_addr_space_t __maybe_unused as, unw_regnum_t __maybe_unused num, unw_fpreg_t __maybe_unused *val, int __maybe_unused __write, void __maybe_unused *arg)
static int read_unwind_spec_eh_frame(struct dso *dso, struct machine *machine, u64 *table_data, u64 *segbase, u64 *fde_count)
static int resume(unw_addr_space_t __maybe_unused as, unw_cursor_t __maybe_unused *cu, void __maybe_unused *arg)
static void _unwind__finish_access(struct thread *thread)
struct map * thread__find_map(struct thread *thread, u8 cpumode, u64 addr, struct addr_location *al)
static struct unwind_libunwind_ops _unwind_libunwind_ops
struct unwind_libunwind_ops * local_unwind_libunwind_ops
static int perf_reg_value(u64 *valp __maybe_unused, struct regs_dump *regs __maybe_unused, int id __maybe_unused)
int dso__data_get_fd(struct dso *dso, struct machine *machine)
#define LIBUNWIND__ARCH_REG_ID(regnum)
int(* unwind_entry_cb_t)(struct unwind_entry *entry, void *arg)
static int read_unwind_spec_debug_frame(struct dso *dso, struct machine *machine, u64 *offset)
x86 movsq based memset() in arch/x86/lib/memset_64.S") MEMSET_FN(memset_erms
#define PERF_ELF_C_READ_MMAP
#define dw_read_encoded_value(ptr, end, enc)
static struct map * find_map(unw_word_t ip, struct unwind_info *ui)
ssize_t dso__data_read_addr(struct dso *dso, struct map *map, struct machine *machine, u64 addr, u8 *data, ssize_t size)
bool dwarf_callchain_users
static int get_dyn_info_list_addr(unw_addr_space_t __maybe_unused as, unw_word_t __maybe_unused *dil_addr, void __maybe_unused *arg)
#define pr_debug(fmt,...)
static int access_mem(unw_addr_space_t __maybe_unused as, unw_word_t addr, unw_word_t *valp, int __write, void *arg)
static int _unwind__get_entries(unwind_entry_cb_t cb, void *arg, struct thread *thread, struct perf_sample *data, int max_stack)
static int get_entries(struct unwind_info *ui, unwind_entry_cb_t cb, void *arg, int max_stack)
static void put_unwind_info(unw_addr_space_t __maybe_unused as, unw_proc_info_t *pi __maybe_unused, void *arg __maybe_unused)
int dso__read_binary_type_filename(const struct dso *dso, enum dso_binary_type type, char *root_dir, char *filename, size_t size)
struct regs_dump user_regs
#define dw_read(ptr, type, end)
#define LIBUNWIND__ARCH_REG_IP
Elf_Scn * elf_section_by_name(Elf *elf, GElf_Ehdr *ep, GElf_Shdr *shp, const char *name, size_t *idx)
static int access_dso_mem(struct unwind_info *ui, unw_word_t addr, unw_word_t *data)
struct eh_frame_hdr __packed
static void display_error(int err)
#define DW_EH_PE_FORMAT_MASK
static int unwind_spec_ehframe(struct dso *dso, struct machine *machine, u64 offset, u64 *table_data, u64 *segbase, u64 *fde_count)
#define dwarf_search_unwind_table
struct symbol * thread__find_symbol(struct thread *thread, u8 cpumode, u64 addr, struct addr_location *al)
unsigned char eh_frame_ptr_enc
unsigned char fde_count_enc
ssize_t dso__data_read_offset(struct dso *dso, struct machine *machine, u64 offset, u8 *data, ssize_t size)
static int elf_is_exec(int fd, const char *name)
#define pr_warning(fmt,...)
static u64 elf_section_offset(int fd, const char *name)
struct perf_sample * sample
static unw_accessors_t accessors
#define LIBUNWIND__ARCH_REG_SP
static int entry(u64 ip, struct thread *thread, unwind_entry_cb_t cb, void *arg)
static void _unwind__flush_access(struct thread *thread)
void dso__data_put_fd(struct dso *dso __maybe_unused)
#define dwarf_find_debug_frame
struct stack_dump user_stack
static int __dw_read_encoded_value(u8 **p, u8 *end, u64 *val, u8 encoding)
int(* prepare_access)(struct thread *thread)