[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Libunwind-devel] [PATCH 3/4] Use ARM-specific unwinding tables in unw_s
From: |
Ken Werner |
Subject: |
[Libunwind-devel] [PATCH 3/4] Use ARM-specific unwinding tables in unw_step |
Date: |
Tue, 15 Mar 2011 18:15:43 +0000 |
From: Zachary T Welch <address@hidden>
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 <address@hidden>
---
include/tdep-arm/libunwind_i.h | 1 +
src/arm/Ginit_local.c | 17 +++++++++++++++++
src/arm/Gstep.c | 40 ++++++++++++++++++++++++++++++++++++++--
3 files changed, 56 insertions(+), 2 deletions(-)
diff --git a/include/tdep-arm/libunwind_i.h b/include/tdep-arm/libunwind_i.h
index a565d9b..839415c 100644
--- a/include/tdep-arm/libunwind_i.h
+++ b/include/tdep-arm/libunwind_i.h
@@ -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;
diff --git a/src/arm/Ginit_local.c b/src/arm/Ginit_local.c
index debf5bb..2a0d73a 100644
--- a/src/arm/Ginit_local.c
+++ b/src/arm/Ginit_local.c
@@ -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);
}
diff --git a/src/arm/Gstep.c b/src/arm/Gstep.c
index 5eac5f0..ab556d7 100644
--- a/src/arm/Gstep.c
+++ b/src/arm/Gstep.c
@@ -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);
--
1.7.4.1
- [Libunwind-devel] [PATCH 0/4] ARM enhancements, Ken Werner, 2011/03/15
- [Libunwind-devel] [PATCH 3/4] Use ARM-specific unwinding tables in unw_step,
Ken Werner <=
- [Libunwind-devel] [PATCH 4/4] Add test of backtracing using ARM-specific tables, Ken Werner, 2011/03/15
- [Libunwind-devel] [PATCH 1/4] Add ARM signal frame detection, Ken Werner, 2011/03/15
- [Libunwind-devel] [PATCH 2/4] Add module for parsing ARM-specific unwind tables, Ken Werner, 2011/03/15
- [Libunwind-devel] Re: [PATCH 0/4] ARM enhancements, Henrik Grindal Bakken, 2011/03/18
- Re: [Libunwind-devel] [PATCH 0/4] ARM enhancements, Arun Sharma, 2011/03/22