Support DWARFish unwind for ARM.

This commit is contained in:
joerg 2014-05-11 02:07:35 +00:00
parent c8a1f8aef9
commit 2f1b7695c4
2 changed files with 56 additions and 11 deletions

View File

@ -240,21 +240,24 @@ enum {
DWARF_ARM32_R0 = 0, DWARF_ARM32_R0 = 0,
DWARF_ARM32_R15 = 15, DWARF_ARM32_R15 = 15,
DWARF_ARM32_SPSR = 128, 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, DWARF_ARM32_D31 = 287,
REGNO_ARM32_R0 = 0, REGNO_ARM32_R0 = 0,
REGNO_ARM32_SP = 13, REGNO_ARM32_SP = 13,
REGNO_ARM32_R15 = 15, REGNO_ARM32_R15 = 15,
REGNO_ARM32_SPSR = 16, REGNO_ARM32_SPSR = 16,
REGNO_ARM32_D0 = 0, REGNO_ARM32_D0 = 17,
REGNO_ARM32_D31 = 31, REGNO_ARM32_D15 = 32,
REGNO_ARM32_D31 = 48,
}; };
class Registers_arm32 { class Registers_arm32 {
public: public:
enum { enum {
LAST_REGISTER = REGNO_ARM32_D31, LAST_REGISTER = REGNO_ARM32_D31,
LAST_RESTORE_REG = REGNO_ARM32_SPSR, LAST_RESTORE_REG = REGNO_ARM32_D31,
RETURN_OFFSET = 0, RETURN_OFFSET = 0,
}; };
@ -263,15 +266,19 @@ public:
static int dwarf2regno(int num) { static int dwarf2regno(int num) {
if (num >= DWARF_ARM32_R0 && num <= DWARF_ARM32_R15) if (num >= DWARF_ARM32_R0 && num <= DWARF_ARM32_R15)
return REGNO_ARM32_R0 + (num - DWARF_ARM32_R0); 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) if (num == DWARF_ARM32_SPSR)
return REGNO_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; return LAST_REGISTER + 1;
} }
bool validRegister(int num) const { 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 { uint64_t getRegister(int num) const {
@ -297,14 +304,28 @@ public:
} }
void copyFloatVectorRegister(int num, uint64_t addr_) { 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<const void *>(addr_); const void *addr = reinterpret_cast<const void *>(addr_);
memcpy(fpreg + (num - REGNO_ARM32_D0), addr, sizeof(fpreg[0])); memcpy(fpreg + (num - REGNO_ARM32_D0), addr, sizeof(fpreg[0]));
} }
__dso_hidden void lazyVFP1();
__dso_hidden void lazyVFP3();
__dso_hidden void jumpto() const __dead; __dso_hidden void jumpto() const __dead;
private: private:
uint32_t reg[REGNO_ARM32_SPSR + 1]; uint32_t reg[REGNO_ARM32_SPSR + 1];
uint32_t flags;
uint64_t fpreg[32]; uint64_t fpreg[32];
}; };
@ -930,7 +951,7 @@ typedef Registers_x86 NativeUnwindRegisters;
typedef Registers_x86_64 NativeUnwindRegisters; typedef Registers_x86_64 NativeUnwindRegisters;
#elif __powerpc__ #elif __powerpc__
typedef Registers_ppc32 NativeUnwindRegisters; typedef Registers_ppc32 NativeUnwindRegisters;
#elif __arm__ && !defined(__ARM_EABI__) #elif __arm__
typedef Registers_arm32 NativeUnwindRegisters; typedef Registers_arm32 NativeUnwindRegisters;
#elif __vax__ #elif __vax__
typedef Registers_vax NativeUnwindRegisters; typedef Registers_vax NativeUnwindRegisters;

View File

@ -269,20 +269,44 @@ ENTRY(_ZNK7_Unwind15Registers_ppc326jumptoEv)
bctr bctr
#endif #endif
#if defined(__arm__) && !defined(__ARM_EABI__) #if defined(__arm__)
.fpu vfpv3
.hidden _ZN7_Unwind15Registers_arm32C1Ev .hidden _ZN7_Unwind15Registers_arm32C1Ev
ENTRY(_ZN7_Unwind15Registers_arm32C1Ev) ENTRY(_ZN7_Unwind15Registers_arm32C1Ev)
stmia r0, {r0-r14} stmia r0, {r0-r14}
str lr, [r0, #60] /* PC */ str lr, [r0, #60] /* PC */
mrs r1, cpsr mrs r1, cpsr
str r1, [r0, #64] /* CPSR */ str r1, [r0, #64] /* CPSR */
mov r1, #0
str r1, [r0, #68]
RET RET
END(_ZN7_Unwind15Registers_arm32C1Ev) 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 .hidden _ZNK7_Unwind15Registers_arm326jumptoEv
ENTRY(_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] ldr r1, [r0, #64]
msr cpsr_sxc, r1 msr cpsr_sxc, r1
ldmia r0, {r0-r15} ldmia r0, {r0-r15}