mirror of
https://github.com/tobast/libunwind-eh_elf.git
synced 2024-12-22 19:43:42 +01:00
arm64: Support for restore of ARM64 Neon callee-saved registers during unwind
This commit is contained in:
parent
1c190a8f9e
commit
5a491cb2d8
4 changed files with 27 additions and 7 deletions
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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))
|
||||
|
|
|
@ -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 */
|
||||
|
|
Loading…
Reference in a new issue