mirror of
https://github.com/tobast/libunwind-eh_elf.git
synced 2024-12-23 20:03:43 +01:00
Support .debug_frame based unwinding in _UPTi_find_unwind_table()
Signed-off-by: Andris Zeila <andris.zeila@accenture.com>
This commit is contained in:
parent
546463d1e7
commit
46e10c5abe
4 changed files with 39 additions and 8 deletions
|
@ -119,6 +119,8 @@ typedef struct unw_addr_space *unw_addr_space_t;
|
||||||
/* Each target may define it's own set of flags, but bits 0-15 are
|
/* Each target may define it's own set of flags, but bits 0-15 are
|
||||||
reserved for general libunwind-use. */
|
reserved for general libunwind-use. */
|
||||||
#define UNW_PI_FLAG_FIRST_TDEP_BIT 16
|
#define UNW_PI_FLAG_FIRST_TDEP_BIT 16
|
||||||
|
/* The information comes from a .debug_frame section. */
|
||||||
|
#define UNW_PI_FLAG_DEBUG_FRAME 32
|
||||||
|
|
||||||
typedef struct unw_proc_info
|
typedef struct unw_proc_info
|
||||||
{
|
{
|
||||||
|
|
|
@ -895,13 +895,11 @@ dwarf_search_unwind_table (unw_addr_space_t as, unw_word_t ip,
|
||||||
#ifndef UNW_REMOTE_ONLY
|
#ifndef UNW_REMOTE_ONLY
|
||||||
struct unw_debug_frame_list *fdesc = (void *) di->u.ti.table_data;
|
struct unw_debug_frame_list *fdesc = (void *) di->u.ti.table_data;
|
||||||
|
|
||||||
/* UNW_INFO_FORMAT_TABLE (i.e. .debug_frame) is currently only
|
/* UNW_INFO_FORMAT_TABLE (i.e. .debug_frame) is read from local address
|
||||||
supported for the local address space. Both the index and
|
space. Both the index and the unwind tables live in local memory, but
|
||||||
the unwind tables live in local memory, but the address space
|
the address space to check for properties like the address size and
|
||||||
to check for properties like the address size and endianness
|
endianness is the target one. */
|
||||||
is the target one. When the ptrace code adds support for
|
as = unw_local_addr_space;
|
||||||
.debug_frame something will have to change. */
|
|
||||||
assert (as == unw_local_addr_space);
|
|
||||||
table = fdesc->index;
|
table = fdesc->index;
|
||||||
table_len = fdesc->index_size * sizeof (struct table_entry);
|
table_len = fdesc->index_size * sizeof (struct table_entry);
|
||||||
debug_frame_base = (uintptr_t) fdesc->debug_frame;
|
debug_frame_base = (uintptr_t) fdesc->debug_frame;
|
||||||
|
@ -958,6 +956,7 @@ dwarf_search_unwind_table (unw_addr_space_t as, unw_word_t ip,
|
||||||
{
|
{
|
||||||
pi->start_ip += segbase;
|
pi->start_ip += segbase;
|
||||||
pi->end_ip += segbase;
|
pi->end_ip += segbase;
|
||||||
|
pi->flags = UNW_PI_FLAG_DEBUG_FRAME;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ip < pi->start_ip || ip >= pi->end_ip)
|
if (ip < pi->start_ip || ip >= pi->end_ip)
|
||||||
|
|
|
@ -73,6 +73,12 @@ run_cfi_program (struct dwarf_cursor *c, dwarf_state_record_t *sr,
|
||||||
|
|
||||||
as = c->as;
|
as = c->as;
|
||||||
arg = c->as_arg;
|
arg = c->as_arg;
|
||||||
|
if (c->pi.flags & UNW_PI_FLAG_DEBUG_FRAME)
|
||||||
|
{
|
||||||
|
/* .debug_frame CFI is stored in local address space. */
|
||||||
|
as = unw_local_addr_space;
|
||||||
|
arg = NULL;
|
||||||
|
}
|
||||||
a = unw_get_accessors (as);
|
a = unw_get_accessors (as);
|
||||||
curr_ip = c->pi.start_ip;
|
curr_ip = c->pi.start_ip;
|
||||||
|
|
||||||
|
|
|
@ -210,7 +210,31 @@ _UPTi_find_unwind_table (struct UPT_info *ui, unw_addr_space_t as,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!ptxt || !peh_hdr)
|
if (!ptxt || !peh_hdr)
|
||||||
return NULL;
|
{
|
||||||
|
/* No .eh_frame found, try .debug_frame. */
|
||||||
|
struct dl_phdr_info info;
|
||||||
|
|
||||||
|
info.dlpi_name = path;
|
||||||
|
info.dlpi_phdr = phdr;
|
||||||
|
info.dlpi_phnum = ehdr->e_phnum;
|
||||||
|
|
||||||
|
/* Fixup segbase to match correct base address. */
|
||||||
|
for (i = 0; i < info.dlpi_phnum; i++)
|
||||||
|
{
|
||||||
|
if (info.dlpi_phdr[i].p_type == PT_LOAD &&
|
||||||
|
info.dlpi_phdr[i].p_offset == 0)
|
||||||
|
{
|
||||||
|
segbase -= info.dlpi_phdr[i].p_vaddr;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
info.dlpi_addr = segbase;
|
||||||
|
|
||||||
|
if (dwarf_find_debug_frame (0, &ui->di_cache, &info, ip))
|
||||||
|
return &ui->di_cache;
|
||||||
|
else
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
if (pdyn)
|
if (pdyn)
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in a new issue