Support DWARFish unwind for ARM.
This commit is contained in:
parent
c8a1f8aef9
commit
2f1b7695c4
@ -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;
|
||||||
|
@ -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}
|
||||||
|
Loading…
Reference in New Issue
Block a user