mirror of
https://github.com/tobast/libunwind-eh_elf.git
synced 2025-01-22 16:20:29 +01:00
Use ARM-specific unwinding tables in unw_step
Uses ex_tables routines to provide a new means of unwinding the stack. Set UNW_ARM_UNWIND_METHOD=4 to use ARM-specific unwinding tables. Signed-off-by: Ken Werner <ken.werner@linaro.org>
This commit is contained in:
parent
ffc474b8c8
commit
6a67154674
3 changed files with 56 additions and 2 deletions
|
@ -261,6 +261,7 @@ extern int tdep_access_fpreg (struct cursor *c, unw_regnum_t reg,
|
|||
#define UNW_ARM_METHOD_ALL 0xFF
|
||||
#define UNW_ARM_METHOD_DWARF 0x01
|
||||
#define UNW_ARM_METHOD_FRAME 0x02
|
||||
#define UNW_ARM_METHOD_EXIDX 0x04
|
||||
|
||||
#define unwi_unwind_method UNW_OBJ(unwind_method)
|
||||
extern int unwi_unwind_method;
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
/* libunwind - a platform-independent unwind library
|
||||
Copyright (C) 2008 CodeSourcery
|
||||
Copyright 2011 Linaro Limited
|
||||
|
||||
This file is part of libunwind.
|
||||
|
||||
|
@ -38,6 +39,7 @@ unw_init_local (unw_cursor_t *cursor, ucontext_t *uc)
|
|||
PROTECTED int
|
||||
unw_init_local (unw_cursor_t *cursor, ucontext_t *uc)
|
||||
{
|
||||
register void *current_sp asm ("sp");
|
||||
struct cursor *c = (struct cursor *) cursor;
|
||||
|
||||
if (tdep_needs_initialization)
|
||||
|
@ -47,6 +49,21 @@ unw_init_local (unw_cursor_t *cursor, ucontext_t *uc)
|
|||
|
||||
c->dwarf.as = unw_local_addr_space;
|
||||
c->dwarf.as_arg = uc;
|
||||
|
||||
if (UNW_TRY_METHOD (UNW_ARM_METHOD_EXIDX))
|
||||
{
|
||||
int arm_exidx_init_done = 0;
|
||||
if (!arm_exidx_init_done)
|
||||
{
|
||||
arm_exidx_init_done = 1;
|
||||
arm_exidx_init_local ("libunwind");
|
||||
}
|
||||
c->frame.fp = __builtin_frame_address (0);
|
||||
c->frame.sp = current_sp;
|
||||
c->frame.lr = __builtin_return_address (0);
|
||||
c->frame.pc = &unw_init_local;
|
||||
}
|
||||
|
||||
return common_init (c, 1);
|
||||
}
|
||||
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
/* libunwind - a platform-independent unwind library
|
||||
Copyright (C) 2008 CodeSourcery
|
||||
Copyright 2011 Linaro Limited
|
||||
|
||||
This file is part of libunwind.
|
||||
|
||||
|
@ -24,6 +25,33 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
|||
|
||||
#include "unwind_i.h"
|
||||
#include "offsets.h"
|
||||
#include "ex_tables.h"
|
||||
|
||||
static inline int
|
||||
arm_exidx_step (struct cursor *c)
|
||||
{
|
||||
struct arm_exidx_table *table = arm_exidx_table_find (c->frame.pc);
|
||||
if (NULL == table)
|
||||
return -UNW_ENOINFO;
|
||||
|
||||
struct arm_exidx_entry *entry = arm_exidx_table_lookup (table, c->frame.pc);
|
||||
if (NULL == entry)
|
||||
return -UNW_ENOINFO;
|
||||
|
||||
struct arm_exidx_vrs s;
|
||||
arm_exidx_frame_to_vrs (&c->frame, &s);
|
||||
|
||||
uint8_t buf[32];
|
||||
int ret = arm_exidx_extract (entry, buf);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
ret = arm_exidx_decode (buf, ret, &arm_exidx_vrs_callback, &s);
|
||||
if (ret < 0)
|
||||
return -ret;
|
||||
|
||||
return arm_exidx_vrs_to_frame (&s, &c->frame);
|
||||
}
|
||||
|
||||
PROTECTED int
|
||||
unw_step (unw_cursor_t *cursor)
|
||||
|
@ -33,8 +61,16 @@ unw_step (unw_cursor_t *cursor)
|
|||
|
||||
Debug (1, "(cursor=%p)\n", c);
|
||||
|
||||
/* Try DWARF-based unwinding... this is the only method likely to work for
|
||||
ARM. */
|
||||
if (UNW_TRY_METHOD (UNW_ARM_METHOD_EXIDX))
|
||||
{
|
||||
ret = arm_exidx_step (c);
|
||||
if (ret >= 0)
|
||||
return ret;
|
||||
if (ret < 0 && ret != -UNW_ENOINFO)
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Next, try DWARF-based unwinding. */
|
||||
if (UNW_TRY_METHOD(UNW_ARM_METHOD_DWARF))
|
||||
{
|
||||
ret = dwarf_step (&c->dwarf);
|
||||
|
|
Loading…
Reference in a new issue