summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
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
commitd80314c0b8c907ac98841a00cb3cc6a78caacdf9 (patch)
tree71bc0a71806e750e588def380da05da76175bda3
parent886312516ce9bceca5f7d2a84a42aae224c0fa67 (diff)
downloadcrash-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.c72
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;