1
0
Fork 0
mirror of https://github.com/tobast/libunwind-eh_elf.git synced 2024-12-23 03:53:43 +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 *
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];
else if (reg >= UNW_AARCH64_V0 && reg <= UNW_AARCH64_V31)
return &GET_FPCTX(uc)->vregs[reg - UNW_AARCH64_V0];
else
return NULL;
}

View file

@ -110,6 +110,9 @@ HIDDEN int
tdep_access_fpreg (struct cursor *c, unw_regnum_t reg, unw_fpreg_t *valp,
int write)
{
Debug (1, "bad register number %u\n", reg);
return -UNW_EBADREG;
dwarf_loc_t loc = c->dwarf.loc[reg];
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
registers only. */
unsigned long regs[15];
unsigned long regs[24];
regs[0] = uc->uc_mcontext.regs[0];
regs[1] = uc->uc_mcontext.regs[1];
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[12] = uc->uc_mcontext.regs[27];
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;
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 x25, x26, [x4,80]\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"
"ret \n"
:
@ -147,7 +160,7 @@ establish_machine_state (struct cursor *c)
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);
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)
#endif
#define GET_FPCTX(uc) ((struct fpsimd_context *)(&uc->uc_mcontext.__reserved))
#endif /* unwind_i_h */