1
0
Fork 0
mirror of https://github.com/tobast/libunwind-eh_elf.git synced 2024-12-23 12:03:41 +01:00

arm64: Support for restore of ARM64 Neon callee-saved registers during unwind

This commit is contained in:
Leonid Chistov 2015-10-01 11:23:50 +03:00 committed by Dave Watson
parent 1c190a8f9e
commit 5a491cb2d8
4 changed files with 27 additions and 7 deletions

View file

@ -43,8 +43,10 @@ PROTECTED unw_addr_space_t unw_local_addr_space = &local_addr_space;
static inline void * static inline void *
uc_addr (ucontext_t *uc, int reg) uc_addr (ucontext_t *uc, int reg)
{ {
if (reg >= UNW_AARCH64_X0 && reg <= UNW_AARCH64_V31) if (reg >= UNW_AARCH64_X0 && reg < UNW_AARCH64_V0)
return &uc->uc_mcontext.regs[reg]; return &uc->uc_mcontext.regs[reg];
else if (reg >= UNW_AARCH64_V0 && reg <= UNW_AARCH64_V31)
return &GET_FPCTX(uc)->vregs[reg - UNW_AARCH64_V0];
else else
return NULL; return NULL;
} }

View file

@ -110,6 +110,9 @@ HIDDEN int
tdep_access_fpreg (struct cursor *c, unw_regnum_t reg, unw_fpreg_t *valp, tdep_access_fpreg (struct cursor *c, unw_regnum_t reg, unw_fpreg_t *valp,
int write) int write)
{ {
Debug (1, "bad register number %u\n", reg); dwarf_loc_t loc = c->dwarf.loc[reg];
return -UNW_EBADREG; if (write)
return dwarf_putfp (&c->dwarf, loc, *valp);
else
return dwarf_getfp (&c->dwarf, loc, valp);
} }

View file

@ -40,7 +40,7 @@ aarch64_local_resume (unw_addr_space_t as, unw_cursor_t *cursor, void *arg)
{ {
/* Since there are no signals involved here we restore EH and non scratch /* Since there are no signals involved here we restore EH and non scratch
registers only. */ registers only. */
unsigned long regs[15]; unsigned long regs[24];
regs[0] = uc->uc_mcontext.regs[0]; regs[0] = uc->uc_mcontext.regs[0];
regs[1] = uc->uc_mcontext.regs[1]; regs[1] = uc->uc_mcontext.regs[1];
regs[2] = uc->uc_mcontext.regs[2]; regs[2] = uc->uc_mcontext.regs[2];
@ -55,7 +55,16 @@ aarch64_local_resume (unw_addr_space_t as, unw_cursor_t *cursor, void *arg)
regs[11] = uc->uc_mcontext.regs[26]; regs[11] = uc->uc_mcontext.regs[26];
regs[12] = uc->uc_mcontext.regs[27]; regs[12] = uc->uc_mcontext.regs[27];
regs[13] = uc->uc_mcontext.regs[28]; regs[13] = uc->uc_mcontext.regs[28];
regs[14] = uc->uc_mcontext.regs[30]; /* LR */ regs[14] = uc->uc_mcontext.regs[29]; /* FP */
regs[15] = uc->uc_mcontext.regs[30]; /* LR */
regs[16] = GET_FPCTX(uc)->vregs[8];
regs[17] = GET_FPCTX(uc)->vregs[9];
regs[18] = GET_FPCTX(uc)->vregs[10];
regs[19] = GET_FPCTX(uc)->vregs[11];
regs[20] = GET_FPCTX(uc)->vregs[12];
regs[21] = GET_FPCTX(uc)->vregs[13];
regs[22] = GET_FPCTX(uc)->vregs[14];
regs[23] = GET_FPCTX(uc)->vregs[15];
unsigned long sp = uc->uc_mcontext.sp; unsigned long sp = uc->uc_mcontext.sp;
struct regs_overlay { struct regs_overlay {
@ -72,7 +81,11 @@ aarch64_local_resume (unw_addr_space_t as, unw_cursor_t *cursor, void *arg)
"ldp x23, x24, [x4,64]\n" "ldp x23, x24, [x4,64]\n"
"ldp x25, x26, [x4,80]\n" "ldp x25, x26, [x4,80]\n"
"ldp x27, x28, [x4,96]\n" "ldp x27, x28, [x4,96]\n"
"ldr x30, [x4,112]\n" "ldp x29, x30, [x4,112]\n"
"ldp d8, d9, [x4,128]\n"
"ldp d10, d11, [x4,144]\n"
"ldp d12, d13, [x4,160]\n"
"ldp d14, d15, [x4,176]\n"
"mov sp, x5\n" "mov sp, x5\n"
"ret \n" "ret \n"
: :
@ -147,7 +160,7 @@ establish_machine_state (struct cursor *c)
Debug (8, "copying out cursor state\n"); Debug (8, "copying out cursor state\n");
for (reg = 0; reg <= UNW_AARCH64_PSTATE; ++reg) for (reg = 0; reg <= UNW_AARCH64_V31; ++reg)
{ {
Debug (16, "copying %s %d\n", unw_regname (reg), reg); Debug (16, "copying %s %d\n", unw_regname (reg), reg);
if (unw_is_fpreg (reg)) if (unw_is_fpreg (reg))

View file

@ -59,4 +59,6 @@ extern int aarch64_local_resume (unw_addr_space_t as, unw_cursor_t *cursor,
} while (0) } while (0)
#endif #endif
#define GET_FPCTX(uc) ((struct fpsimd_context *)(&uc->uc_mcontext.__reserved))
#endif /* unwind_i_h */ #endif /* unwind_i_h */