1
0
Fork 0
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:
Doug Moore 2017-06-20 11:47:27 -05:00 committed by Dave Watson
parent 4f14d9714f
commit 0e74e583ae
3 changed files with 94 additions and 117 deletions

View file

@ -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)

View file

@ -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;
}

View file

@ -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;
}