mirror of
https://github.com/tobast/libunwind-eh_elf.git
synced 2025-01-24 17:20:30 +01:00
arm: Use dwarf_find_proc_info for arm dwarf processing
Rather than using a copy of dwarf_find_proc_info that differs from it slightly. By using dwarf_find_proc_info, a potential search of the di table is allowed, where it is omitted now. Also, for ARM, avoid runtime checks about which kind of unwind table search to use after dl_iterate_phdr. A couple of Debug() warnings about ip lookup failure are lost here. The dwarf callback struct defintion is moved to Gfind_proc_info-lsb.c, which becomes the only source file that needs it.
This commit is contained in:
parent
4f14d9714f
commit
0e74e583ae
3 changed files with 94 additions and 117 deletions
|
@ -382,18 +382,6 @@ struct unw_debug_frame_list
|
|||
struct unw_debug_frame_list *next;
|
||||
};
|
||||
|
||||
struct dwarf_callback_data
|
||||
{
|
||||
/* in: */
|
||||
unw_word_t ip; /* instruction-pointer we're looking for */
|
||||
unw_proc_info_t *pi; /* proc-info pointer */
|
||||
int need_unwind_info;
|
||||
/* out: */
|
||||
int single_fde; /* did we find a single FDE? (vs. a table) */
|
||||
unw_dyn_info_t di; /* table info (if single_fde is false) */
|
||||
unw_dyn_info_t di_debug; /* additional table info for .debug_frame */
|
||||
};
|
||||
|
||||
/* Convenience macros: */
|
||||
#define dwarf_init UNW_ARCH_OBJ (dwarf_init)
|
||||
#define dwarf_callback UNW_OBJ (dwarf_callback)
|
||||
|
|
|
@ -382,13 +382,10 @@ arm_exidx_extract (struct dwarf_cursor *c, uint8_t *buf)
|
|||
}
|
||||
|
||||
PROTECTED int
|
||||
tdep_search_unwind_table (unw_addr_space_t as, unw_word_t ip,
|
||||
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)
|
||||
{
|
||||
if (UNW_TRY_METHOD (UNW_ARM_METHOD_EXIDX)
|
||||
&& di->format == UNW_INFO_FORMAT_ARM_EXIDX)
|
||||
{
|
||||
/* The .ARM.exidx section contains a sorted list of key-value pairs -
|
||||
the unwind entries. The 'key' is a prel31 offset to the start of a
|
||||
function. We binary search this section in order to find the
|
||||
|
@ -445,7 +442,16 @@ tdep_search_unwind_table (unw_addr_space_t as, unw_word_t ip,
|
|||
pi->format = UNW_INFO_FORMAT_ARM_EXIDX;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
PROTECTED int
|
||||
tdep_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)
|
||||
{
|
||||
if (UNW_TRY_METHOD (UNW_ARM_METHOD_EXIDX)
|
||||
&& di->format == UNW_INFO_FORMAT_ARM_EXIDX)
|
||||
return arm_search_unwind_table (as, ip, di, pi, need_unwind_info, arg);
|
||||
else if (UNW_TRY_METHOD(UNW_ARM_METHOD_DWARF)
|
||||
&& di->format != UNW_INFO_FORMAT_ARM_EXIDX)
|
||||
return dwarf_search_unwind_table (as, ip, di, pi, need_unwind_info, arg);
|
||||
|
@ -509,33 +515,7 @@ arm_find_proc_info (unw_addr_space_t as, unw_word_t ip,
|
|||
Debug (14, "looking for IP=0x%lx\n", (long) ip);
|
||||
|
||||
if (UNW_TRY_METHOD(UNW_ARM_METHOD_DWARF))
|
||||
{
|
||||
struct dwarf_callback_data cb_data;
|
||||
|
||||
memset (&cb_data, 0, sizeof (cb_data));
|
||||
cb_data.ip = ip;
|
||||
cb_data.pi = pi;
|
||||
cb_data.need_unwind_info = need_unwind_info;
|
||||
cb_data.di.format = -1;
|
||||
cb_data.di_debug.format = -1;
|
||||
|
||||
SIGPROCMASK (SIG_SETMASK, &unwi_full_mask, &saved_mask);
|
||||
ret = dl_iterate_phdr (dwarf_callback, &cb_data);
|
||||
SIGPROCMASK (SIG_SETMASK, &saved_mask, NULL);
|
||||
|
||||
if (ret > 0)
|
||||
{
|
||||
if (cb_data.single_fde)
|
||||
/* already got the result in *pi */
|
||||
return 0;
|
||||
|
||||
if (cb_data.di_debug.format != -1)
|
||||
ret = tdep_search_unwind_table (as, ip, &cb_data.di_debug, pi,
|
||||
need_unwind_info, arg);
|
||||
else
|
||||
ret = -UNW_ENOINFO;
|
||||
}
|
||||
}
|
||||
ret = dwarf_find_proc_info (as, ip, pi, need_unwind_info, arg);
|
||||
|
||||
if (ret < 0 && UNW_TRY_METHOD (UNW_ARM_METHOD_EXIDX))
|
||||
{
|
||||
|
@ -551,15 +531,12 @@ arm_find_proc_info (unw_addr_space_t as, unw_word_t ip,
|
|||
SIGPROCMASK (SIG_SETMASK, &saved_mask, NULL);
|
||||
|
||||
if (cb_data.di.format != -1)
|
||||
ret = tdep_search_unwind_table (as, ip, &cb_data.di, pi,
|
||||
ret = arm_search_unwind_table (as, ip, &cb_data.di, pi,
|
||||
need_unwind_info, arg);
|
||||
else
|
||||
ret = -UNW_ENOINFO;
|
||||
}
|
||||
|
||||
if (ret < 0)
|
||||
Debug (14, "IP=0x%lx not found\n", (long) ip);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
|
@ -453,6 +453,18 @@ out:
|
|||
return eh_frame;
|
||||
}
|
||||
|
||||
struct dwarf_callback_data
|
||||
{
|
||||
/* in: */
|
||||
unw_word_t ip; /* instruction-pointer we're looking for */
|
||||
unw_proc_info_t *pi; /* proc-info pointer */
|
||||
int need_unwind_info;
|
||||
/* out: */
|
||||
int single_fde; /* did we find a single FDE? (vs. a table) */
|
||||
unw_dyn_info_t di; /* table info (if single_fde is false) */
|
||||
unw_dyn_info_t di_debug; /* additional table info for .debug_frame */
|
||||
};
|
||||
|
||||
/* ptr is a pointer to a dwarf_callback_data structure and, on entry,
|
||||
member ip contains the instruction-pointer we're looking
|
||||
for. */
|
||||
|
@ -685,12 +697,8 @@ dwarf_find_proc_info (unw_addr_space_t as, unw_word_t ip,
|
|||
ret = dl_iterate_phdr (dwarf_callback, &cb_data);
|
||||
SIGPROCMASK (SIG_SETMASK, &saved_mask, NULL);
|
||||
|
||||
if (ret <= 0)
|
||||
if (ret > 0)
|
||||
{
|
||||
Debug (14, "IP=0x%lx not found\n", (long) ip);
|
||||
return -UNW_ENOINFO;
|
||||
}
|
||||
|
||||
if (cb_data.single_fde)
|
||||
/* already got the result in *pi */
|
||||
return 0;
|
||||
|
@ -705,6 +713,10 @@ dwarf_find_proc_info (unw_addr_space_t as, unw_word_t ip,
|
|||
if (ret == -UNW_ENOINFO && cb_data.di_debug.format != -1)
|
||||
ret = dwarf_search_unwind_table (as, ip, &cb_data.di_debug, pi,
|
||||
need_unwind_info, arg);
|
||||
}
|
||||
else
|
||||
ret = -UNW_ENOINFO;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue