From 729772149fcd72379e8118361c43e4632ffa3f01 Mon Sep 17 00:00:00 2001 From: Dave Watson Date: Tue, 10 Apr 2018 10:55:45 -0700 Subject: 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. --- include/libunwind-aarch64.h | 32 ++++++++++++++++++++++++++++---- src/aarch64/Ginit.c | 8 ++++---- src/aarch64/Ginit_local.c | 2 +- 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) { -- cgit v1.2.1