From 2f1b7695c44f59de880b532f92453e65bbcd9880 Mon Sep 17 00:00:00 2001 From: joerg Date: Sun, 11 May 2014 02:07:35 +0000 Subject: [PATCH] Support DWARFish unwind for ARM. --- sys/lib/libunwind/Registers.hpp | 37 ++++++++++++++++++++++------ sys/lib/libunwind/unwind_registers.S | 30 +++++++++++++++++++--- 2 files changed, 56 insertions(+), 11 deletions(-) diff --git a/sys/lib/libunwind/Registers.hpp b/sys/lib/libunwind/Registers.hpp index 7e6b0d71f025..0467525edcb3 100644 --- a/sys/lib/libunwind/Registers.hpp +++ b/sys/lib/libunwind/Registers.hpp @@ -240,21 +240,24 @@ enum { DWARF_ARM32_R0 = 0, DWARF_ARM32_R15 = 15, DWARF_ARM32_SPSR = 128, - DWARF_ARM32_D0 = 256, // VFP-v3/Neon + DWARF_ARM32_OLD_S0 = 64, + DWARF_ARM32_OLD_S31 = 91, + DWARF_ARM32_D0 = 256, DWARF_ARM32_D31 = 287, REGNO_ARM32_R0 = 0, REGNO_ARM32_SP = 13, REGNO_ARM32_R15 = 15, REGNO_ARM32_SPSR = 16, - REGNO_ARM32_D0 = 0, - REGNO_ARM32_D31 = 31, + REGNO_ARM32_D0 = 17, + REGNO_ARM32_D15 = 32, + REGNO_ARM32_D31 = 48, }; class Registers_arm32 { public: enum { LAST_REGISTER = REGNO_ARM32_D31, - LAST_RESTORE_REG = REGNO_ARM32_SPSR, + LAST_RESTORE_REG = REGNO_ARM32_D31, RETURN_OFFSET = 0, }; @@ -263,15 +266,19 @@ public: static int dwarf2regno(int num) { if (num >= DWARF_ARM32_R0 && num <= DWARF_ARM32_R15) return REGNO_ARM32_R0 + (num - DWARF_ARM32_R0); - if (num >= DWARF_ARM32_D0 && num <= DWARF_ARM32_D31) - return REGNO_ARM32_D0 + (num - DWARF_ARM32_D0); if (num == DWARF_ARM32_SPSR) return REGNO_ARM32_SPSR; + if (num >= DWARF_ARM32_D0 && num <= DWARF_ARM32_D31) + return REGNO_ARM32_D0 + (num - DWARF_ARM32_D0); + if (num >= DWARF_ARM32_OLD_S0 && num <= DWARF_ARM32_OLD_S31) { + assert(num % 2 == 0); + return REGNO_ARM32_D0 + (num - DWARF_ARM32_OLD_S0) / 2; + } return LAST_REGISTER + 1; } bool validRegister(int num) const { - return num >= 0 && num <= LAST_RESTORE_REG; + return num >= 0 && num <= REGNO_ARM32_SPSR; } uint64_t getRegister(int num) const { @@ -297,14 +304,28 @@ public: } void copyFloatVectorRegister(int num, uint64_t addr_) { + if (num <= REGNO_ARM32_D15) { + if ((flags & 1) == 0) { + lazyVFP1(); + flags |= 1; + } + } else { + if ((flags & 2) == 0) { + lazyVFP3(); + flags |= 2; + } + } const void *addr = reinterpret_cast(addr_); memcpy(fpreg + (num - REGNO_ARM32_D0), addr, sizeof(fpreg[0])); } + __dso_hidden void lazyVFP1(); + __dso_hidden void lazyVFP3(); __dso_hidden void jumpto() const __dead; private: uint32_t reg[REGNO_ARM32_SPSR + 1]; + uint32_t flags; uint64_t fpreg[32]; }; @@ -930,7 +951,7 @@ typedef Registers_x86 NativeUnwindRegisters; typedef Registers_x86_64 NativeUnwindRegisters; #elif __powerpc__ typedef Registers_ppc32 NativeUnwindRegisters; -#elif __arm__ && !defined(__ARM_EABI__) +#elif __arm__ typedef Registers_arm32 NativeUnwindRegisters; #elif __vax__ typedef Registers_vax NativeUnwindRegisters; diff --git a/sys/lib/libunwind/unwind_registers.S b/sys/lib/libunwind/unwind_registers.S index ee1d5eac8d7d..4f34a2e081ab 100644 --- a/sys/lib/libunwind/unwind_registers.S +++ b/sys/lib/libunwind/unwind_registers.S @@ -269,20 +269,44 @@ ENTRY(_ZNK7_Unwind15Registers_ppc326jumptoEv) bctr #endif -#if defined(__arm__) && !defined(__ARM_EABI__) +#if defined(__arm__) + .fpu vfpv3 .hidden _ZN7_Unwind15Registers_arm32C1Ev ENTRY(_ZN7_Unwind15Registers_arm32C1Ev) stmia r0, {r0-r14} - str lr, [r0, #60] /* PC */ mrs r1, cpsr str r1, [r0, #64] /* CPSR */ - + mov r1, #0 + str r1, [r0, #68] RET END(_ZN7_Unwind15Registers_arm32C1Ev) + .hidden _ZN7_Unwind15Registers_arm328lazyVFP1Ev +ENTRY(_ZN7_Unwind15Registers_arm328lazyVFP1Ev) + add r0, #72 + vstmia r0, {d0-d15} +END(_ZN7_Unwind15Registers_arm328lazyVFP1Ev) + + .hidden _ZN7_Unwind15Registers_arm328lazyVFP3Ev +ENTRY(_ZN7_Unwind15Registers_arm328lazyVFP3Ev) + add r0, #200 + vstmia r0, {d16-d31} +END(_ZN7_Unwind15Registers_arm328lazyVFP3Ev) + .hidden _ZNK7_Unwind15Registers_arm326jumptoEv ENTRY(_ZNK7_Unwind15Registers_arm326jumptoEv) + ldrb r1, [r0, #68] + tst r1, #1 + beq .Lnovfp1 + add r2, r0, #72 + vldmia r2, {d0-d15} +.Lnovfp1: + tst r1, #2 + beq .Lnovfp3 + add r2, r0, #200 + vldmia r2, {d16-d31} +.Lnovfp3: ldr r1, [r0, #64] msr cpsr_sxc, r1 ldmia r0, {r0-r15}