diff options
author | Jan Vorlicek <jan.vorlicek@volny.cz> | 2022-07-08 23:51:21 +0300 |
---|---|---|
committer | Stephen M. Webb <stephen.webb@bregmasoft.ca> | 2022-07-26 22:26:14 -0400 |
commit | e09164e88c9bd934d17f476ba56be0334ff28699 (patch) | |
tree | 69887e205d49d3ebf94a0bb570f776845180312a /include | |
parent | d3e137a8008f3261f0a21406212264330c519703 (diff) | |
download | libunwind-e09164e88c9bd934d17f476ba56be0334ff28699.tar.gz |
Add support for arm fp registers unwind
Diffstat (limited to 'include')
-rw-r--r-- | include/libunwind-arm.h | 58 |
1 files changed, 30 insertions, 28 deletions
diff --git a/include/libunwind-arm.h b/include/libunwind-arm.h index 85134b40..c4b90fdd 100644 --- a/include/libunwind-arm.h +++ b/include/libunwind-arm.h @@ -261,6 +261,7 @@ unw_tdep_save_loc_t; typedef struct unw_tdep_context { unsigned long regs[16]; + unsigned long long fpregs[16]; } unw_tdep_context_t; @@ -269,36 +270,37 @@ unw_tdep_context_t; In thumb mode, we return directly back to thumb mode on return (with bx), to avoid altering any registers after unw_resume. */ #ifndef __thumb__ -#define unw_tdep_getcontext(uc) ({ \ - unw_tdep_context_t *unw_ctx = (uc); \ - register unsigned long *r0 __asm__ ("r0"); \ - unsigned long *unw_base = unw_ctx->regs; \ - __asm__ __volatile__ ( \ - "mov r0, #0\n" \ - "stmia %[base], {r0-r15}\n" \ - "nop\n" /* align return address to value stored by stmia */ \ - : [r0] "=r" (r0) : [base] "r" (unw_base) : "memory"); \ +#define unw_tdep_getcontext(uc) ({ \ + unw_tdep_context_t *unw_ctx = (uc); \ + register unsigned long *r0 __asm__ ("r0"); \ + register unsigned long *unw_base __asm__ ("r1") = unw_ctx->regs; \ + __asm__ __volatile__ ( \ + "mov r0, #0\n" \ + "stmia %[base]!, {r0-r15}\n" \ + "vstmia %[base], {d0-d15}\n" /* this also aligns return address to value stored by stmia */ \ + : [r0] "=r" (r0) : [base] "r" (unw_base) : "memory"); \ (int)r0; }) #else /* __thumb__ */ -#define unw_tdep_getcontext(uc) ({ \ - unw_tdep_context_t *unw_ctx = (uc); \ - register unsigned long *r0 __asm__ ("r0"); \ - unsigned long *unw_base = unw_ctx->regs; \ - __asm__ __volatile__ ( \ - ".align 2\n" \ - "bx pc\n" \ - "nop\n" \ - ".code 32\n" \ - "mov r0, #0\n" \ - "stmia %[base], {r0-r14}\n" \ - "adr r0, ret%=+1\n" \ - "str r0, [%[base], #60]\n" \ - "orr r0, pc, #1\n" \ - "bx r0\n" \ - ".code 16\n" \ - "mov r0, #0\n" \ - "ret%=:\n" \ - : [r0] "=r" (r0) : [base] "r" (unw_base) : "memory", "cc"); \ +#define unw_tdep_getcontext(uc) ({ \ + unw_tdep_context_t *unw_ctx = (uc); \ + register unsigned long *r0 __asm__ ("r0"); \ + register unsigned long *unw_base __asm__ ("r1") = unw_ctx->regs; \ + __asm__ __volatile__ ( \ + ".align 2\n" \ + "bx pc\n" \ + "nop\n" \ + ".code 32\n" \ + "mov r0, #0\n" \ + "stmia %[base], {r0-r14}\n" \ + "adr r0, ret%=+1\n" \ + "stmia %[base]!, {r0}\n" \ + "vstmia %[base], {d0-d15}\n" \ + "orr r0, pc, #1\n" \ + "bx r0\n" \ + ".code 16\n" \ + "mov r0, #0\n" \ + "ret%=:\n" \ + : [r0] "=r" (r0), [base] "+r" (unw_base) : : "memory", "cc"); \ (int)r0; }) #endif |