diff options
author | Łukasz Stelmach <l.stelmach@samsung.com> | 2018-08-07 11:53:11 +0200 |
---|---|---|
committer | Łukasz Stelmach <l.stelmach@samsung.com> | 2018-08-07 13:37:55 +0200 |
commit | d80314c0b8c907ac98841a00cb3cc6a78caacdf9 (patch) | |
tree | 71bc0a71806e750e588def380da05da76175bda3 | |
parent | 886312516ce9bceca5f7d2a84a42aae224c0fa67 (diff) | |
download | crash-worker-sandbox/lstelmach/vip-unwind.tar.gz crash-worker-sandbox/lstelmach/vip-unwind.tar.bz2 crash-worker-sandbox/lstelmach/vip-unwind.zip |
WIP: find unwind table arch specific waysandbox/lstelmach/vip-unwind
Change-Id: Ic716b69b2ccd93bc61cf87e29c1413fe50c46977
-rw-r--r-- | src/crash-stack/unwind.c | 72 |
1 files changed, 41 insertions, 31 deletions
diff --git a/src/crash-stack/unwind.c b/src/crash-stack/unwind.c index 364f66d..9d43ae2 100644 --- a/src/crash-stack/unwind.c +++ b/src/crash-stack/unwind.c @@ -62,19 +62,15 @@ size_t stack_size = 0xa00000; /* * search unwind table for a procedure (used by find_proc_info) */ -#define dwarf_search_unwind_table UNW_OBJ(dwarf_search_unwind_table) - -extern int dwarf_search_unwind_table(unw_addr_space_t as, unw_word_t ip, +#if defined(__arm__) +#define search_unwind_table UNW_OBJ(search_unwind_table) +#else +#define search_unwind_table UNW_OBJ(dwarf_search_unwind_table) +#endif +extern int search_unwind_table(unw_addr_space_t as, unw_word_t ip, unw_dyn_info_t *di, unw_proc_info_t *pip, int need_unwind_info, void *arg); -#define arm_search_unwind_table UNW_OBJ(search_unwind_table) - -extern int -arm_search_unwind_table (unw_addr_space_t as, unw_word_t ip, - unw_dyn_info_t *di, unw_proc_info_t *pi, - int need_unwind_info, void *arg); - static struct mem_map *map = NULL; static unsigned long eip = 0; static unsigned long esp = 0; @@ -255,6 +251,7 @@ elf_section_offset_end: /* * find section .ARM.exidx in ELF binary */ +#if defined(__arm__) static int find_exidx(int fd, char *image, uint64_t size, uint64_t *table_data, uint64_t *table_len) { @@ -295,6 +292,23 @@ find_exidx_end: elf_end(elf); return (offset ? 0 : -1); } +#endif + +static int find_unwind_table(int fd, char *image, uint64_t size, + uint64_t *table_data, int *table_format, + uint64_t *segbase, uint64_t *table_len) +{ +#if defined(__arm__) + (void) segbase; + *table_format = UNW_INFO_FORMAT_ARM_EXIDX; + return find_exidx(fd, image, size, table_data, table_len); +#else + (void) table_data; + *table_format = UNW_INFO_FORMAT_REMOTE_TABLE; + return find_eh_frame_hdr(fd, image, size, table_data, segbase, table_len); +#endif +} + /* * dynamic array of symbols @@ -528,6 +542,7 @@ static int find_proc_info(unw_addr_space_t as, unw_word_t ip, unw_dyn_info_t di; uint64_t table_data = 0; uint64_t segbase, fde_count; + int table_format = -1; int rc = -UNW_EINVAL; (void) arg; @@ -548,32 +563,27 @@ static int find_proc_info(unw_addr_space_t as, unw_word_t ip, memset(&di, 0, sizeof(di)); - if (find_eh_frame_hdr(region->fd, elf_image, elf_length, - &table_data, &segbase, &fde_count) !=0) { + if (find_unwind_table(region->fd, elf_image, elf_length, + &table_data, &table_format, &segbase, + &fde_count) !=0) { rc = -UNW_ENOINFO; } else { - di.format = UNW_INFO_FORMAT_REMOTE_TABLE; - di.start_ip = (unw_word_t)region->start; - di.end_ip = (unw_word_t)region->start + region->length; - di.u.rti.segbase = (unw_word_t)(region->start - region->offset) + segbase; - di.u.rti.table_data = (unw_word_t)(region->start - region->offset) + table_data; - di.u.rti.table_len = - fde_count * sizeof(uint32_t) * 2 / sizeof(unw_word_t); - - rc = dwarf_search_unwind_table(as, ip, &di, pip, need_unwind_info, arg); - } - - if ((rc == -UNW_ENOINFO) && find_exidx(region->fd, elf_image, - elf_length, &table_data, - &fde_count) == 0) { - di.format = UNW_INFO_FORMAT_ARM_EXIDX; + di.format = table_format; di.start_ip = (unw_word_t)region->start; di.end_ip = (unw_word_t)region->start + region->length; - di.u.rti.name_ptr = to_unw_word(region->path); - di.u.rti.table_data = (unw_word_t)region->start + table_data; - di.u.rti.table_len = fde_count; - rc = arm_search_unwind_table(as, ip, &di, pip, need_unwind_info, arg); + if (table_format == UNW_INFO_FORMAT_REMOTE_TABLE) { + di.u.rti.name_ptr = 0; + di.u.rti.segbase = (unw_word_t)(region->start - region->offset) + segbase; + di.u.rti.table_data = (unw_word_t)(region->start - region->offset) + table_data; + di.u.rti.table_len = fde_count * sizeof(uint32_t) * 2 / sizeof(unw_word_t); + } else if (table_format == UNW_INFO_FORMAT_ARM_EXIDX) { + di.u.rti.name_ptr = to_unw_word(region->path); + di.u.rti.table_data = (unw_word_t)region->start + table_data; + di.u.rti.table_len = fde_count; + _D("find_exidx()->path=%s table_data=%llx table_len=%lld", region->path, table_data, fde_count); + } + rc = search_unwind_table(as, ip, &di, pip, need_unwind_info, arg); } return rc; |