summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDave Watson <davejwatson@fb.com>2018-04-10 10:55:45 -0700
committerGitHub <noreply@github.com>2018-04-10 10:55:45 -0700
commit729772149fcd72379e8118361c43e4632ffa3f01 (patch)
treed6c3020d8d8253a723965f2da77e3dd4a7b59e32
parentb5cbcaee13233ddbc2e6a3fffe85374031f51000 (diff)
downloadlibunwind-729772149fcd72379e8118361c43e4632ffa3f01.tar.gz
aarch64: tune down size of unw_context_t and unw_cursor_t (#71)
aarch64 defines a huge __reserved field in sigcontext. Cut it down to only the used FP fields. unw_cursor_t can also be cut down a bit, while still maintaining some reserved space.
-rw-r--r--include/libunwind-aarch64.h32
-rw-r--r--src/aarch64/Ginit.c8
-rw-r--r--src/aarch64/Ginit_local.c2
3 files changed, 33 insertions, 9 deletions
diff --git a/include/libunwind-aarch64.h b/include/libunwind-aarch64.h
index 85812e15..11e2a9c1 100644
--- a/include/libunwind-aarch64.h
+++ b/include/libunwind-aarch64.h
@@ -44,9 +44,13 @@ extern "C" {
leaving some slack for future expansion. Changing this value will
require recompiling all users of this library. Stack allocation is
relatively cheap and unwind-state copying is relatively rare, so we
- want to err on making it rather too big than too small. */
+ want to err on making it rather too big than too small.
-#define UNW_TDEP_CURSOR_LEN 512
+ Calculation is regs used (64 + 34) * 2 + 40 (bytes of rest of
+ cursor) + padding
+*/
+
+#define UNW_TDEP_CURSOR_LEN 250
typedef uint64_t unw_word_t;
typedef int64_t unw_sword_t;
@@ -169,8 +173,28 @@ typedef struct unw_tdep_save_loc
unw_tdep_save_loc_t;
-/* On AArch64, we can directly use ucontext_t as the unwind context. */
-typedef ucontext_t unw_tdep_context_t;
+/* On AArch64, we can directly use ucontext_t as the unwind context,
+ * however, the __reserved struct is quite large: tune it down to only
+ * the necessary used fields. */
+
+struct unw_sigcontext
+ {
+ uint64_t fault_address;
+ uint64_t regs[31];
+ uint64_t sp;
+ uint64_t pc;
+ uint64_t pstate;
+ uint8_t __reserved[(34 * 8)] __attribute__((__aligned__(16)));
+};
+
+typedef struct
+ {
+ unsigned long uc_flags;
+ struct ucontext *uc_link;
+ stack_t uc_stack;
+ __sigset_t uc_sigmask;
+ struct unw_sigcontext uc_mcontext;
+ } unw_tdep_context_t;
#include "libunwind-common.h"
#include "libunwind-dynamic.h"
diff --git a/src/aarch64/Ginit.c b/src/aarch64/Ginit.c
index 9c4eae82..dec235c8 100644
--- a/src/aarch64/Ginit.c
+++ b/src/aarch64/Ginit.c
@@ -41,7 +41,7 @@ static struct unw_addr_space local_addr_space;
unw_addr_space_t unw_local_addr_space = &local_addr_space;
static inline void *
-uc_addr (ucontext_t *uc, int reg)
+uc_addr (unw_tdep_context_t *uc, int reg)
{
if (reg >= UNW_AARCH64_X0 && reg < UNW_AARCH64_V0)
return &uc->uc_mcontext.regs[reg];
@@ -54,7 +54,7 @@ uc_addr (ucontext_t *uc, int reg)
# ifdef UNW_LOCAL_ONLY
HIDDEN void *
-tdep_uc_addr (ucontext_t *uc, int reg)
+tdep_uc_addr (unw_tdep_context_t *uc, int reg)
{
return uc_addr (uc, reg);
}
@@ -104,7 +104,7 @@ access_reg (unw_addr_space_t as, unw_regnum_t reg, unw_word_t *val, int write,
void *arg)
{
unw_word_t *addr;
- ucontext_t *uc = arg;
+ unw_tdep_context_t *uc = arg;
if (unw_is_fpreg (reg))
goto badreg;
@@ -133,7 +133,7 @@ static int
access_fpreg (unw_addr_space_t as, unw_regnum_t reg, unw_fpreg_t *val,
int write, void *arg)
{
- ucontext_t *uc = arg;
+ unw_tdep_context_t *uc = arg;
unw_fpreg_t *addr;
if (!unw_is_fpreg (reg))
diff --git a/src/aarch64/Ginit_local.c b/src/aarch64/Ginit_local.c
index cd60ca84..69d4ed38 100644
--- a/src/aarch64/Ginit_local.c
+++ b/src/aarch64/Ginit_local.c
@@ -59,7 +59,7 @@ unw_init_local (unw_cursor_t *cursor, unw_context_t *uc)
}
int
-unw_init_local2 (unw_cursor_t *cursor, ucontext_t *uc, int flag)
+unw_init_local2 (unw_cursor_t *cursor, unw_tdep_context_t *uc, int flag)
{
if (!flag)
{