summaryrefslogtreecommitdiff
path: root/include
diff options
context:
space:
mode:
authorJan Vorlicek <jan.vorlicek@volny.cz>2022-07-08 23:51:21 +0300
committerStephen M. Webb <stephen.webb@bregmasoft.ca>2022-07-26 22:26:14 -0400
commite09164e88c9bd934d17f476ba56be0334ff28699 (patch)
tree69887e205d49d3ebf94a0bb570f776845180312a /include
parentd3e137a8008f3261f0a21406212264330c519703 (diff)
downloadlibunwind-e09164e88c9bd934d17f476ba56be0334ff28699.tar.gz
Add support for arm fp registers unwind
Diffstat (limited to 'include')
-rw-r--r--include/libunwind-arm.h58
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