mirror of
https://github.com/capstone-engine/llvm-capstone.git
synced 2025-01-25 10:48:14 +00:00
Use return address register from CIE. Move DwarfInstructions::lastRestoreReg() to Register::lastDwarfRegNum().
llvm-svn: 207467
This commit is contained in:
parent
275c5fc9c2
commit
0c790015df
@ -74,21 +74,6 @@ private:
|
||||
assert(0 && "getCFA(): unknown location");
|
||||
__builtin_unreachable();
|
||||
}
|
||||
// x86 specific variants
|
||||
static int lastRestoreReg(const Registers_x86 &);
|
||||
static bool isReturnAddressRegister(int regNum, const Registers_x86 &);
|
||||
|
||||
// x86_64 specific variants
|
||||
static int lastRestoreReg(const Registers_x86_64 &);
|
||||
static bool isReturnAddressRegister(int regNum, const Registers_x86_64 &);
|
||||
|
||||
// ppc specific variants
|
||||
static int lastRestoreReg(const Registers_ppc &);
|
||||
static bool isReturnAddressRegister(int regNum, const Registers_ppc &);
|
||||
|
||||
// arm64 specific variants
|
||||
static bool isReturnAddressRegister(int regNum, const Registers_arm64 &);
|
||||
static int lastRestoreReg(const Registers_arm64 &);
|
||||
};
|
||||
|
||||
|
||||
@ -176,17 +161,21 @@ int DwarfInstructions<A, R>::stepWithDwarf(A &addressSpace, pint_t pc,
|
||||
PrologInfo prolog;
|
||||
if (CFI_Parser<A>::parseFDEInstructions(addressSpace, fdeInfo, cieInfo, pc,
|
||||
&prolog)) {
|
||||
R newRegisters = registers;
|
||||
|
||||
// get pointer to cfa (architecture specific)
|
||||
pint_t cfa = getCFA(addressSpace, prolog, registers);
|
||||
|
||||
// restore registers that dwarf says were saved
|
||||
// restore registers that dwarf says were saved
|
||||
R newRegisters = registers;
|
||||
pint_t returnAddress = 0;
|
||||
for (int i = 0; i <= lastRestoreReg(newRegisters); ++i) {
|
||||
if (prolog.savedRegisters[i].location !=
|
||||
CFI_Parser<A>::kRegisterUnused) {
|
||||
if (registers.validFloatRegister(i))
|
||||
const int lastReg = R::lastDwarfRegNum();
|
||||
assert((int)CFI_Parser<A>::kMaxRegisterNumber > lastReg
|
||||
&& "register range too large");
|
||||
assert(lastReg <= (int)cieInfo.returnAddressRegister
|
||||
&& "register range does not contain return address register");
|
||||
for (int i = 0; i <= lastReg; ++i) {
|
||||
if (prolog.savedRegisters[i].location !=
|
||||
CFI_Parser<A>::kRegisterUnused) {
|
||||
if (registers.validFloatRegister(i))
|
||||
newRegisters.setFloatRegister(
|
||||
i, getSavedFloatRegister(addressSpace, registers, cfa,
|
||||
prolog.savedRegisters[i]));
|
||||
@ -194,7 +183,7 @@ int DwarfInstructions<A, R>::stepWithDwarf(A &addressSpace, pint_t pc,
|
||||
newRegisters.setVectorRegister(
|
||||
i, getSavedVectorRegister(addressSpace, registers, cfa,
|
||||
prolog.savedRegisters[i]));
|
||||
else if (isReturnAddressRegister(i, registers))
|
||||
else if (i == (int)cieInfo.returnAddressRegister)
|
||||
returnAddress = getSavedRegister(addressSpace, registers, cfa,
|
||||
prolog.savedRegisters[i]);
|
||||
else if (registers.validRegister(i))
|
||||
@ -763,73 +752,6 @@ DwarfInstructions<A, R>::evaluateExpression(pint_t expression, A &addressSpace,
|
||||
return *sp;
|
||||
}
|
||||
|
||||
//
|
||||
// x86_64 specific functions
|
||||
//
|
||||
template <typename A, typename R>
|
||||
int DwarfInstructions<A, R>::lastRestoreReg(const Registers_x86_64 &) {
|
||||
static_assert((int)CFI_Parser<A>::kMaxRegisterNumber
|
||||
> (int)DW_X86_64_RET_ADDR, "register number out of range");
|
||||
return DW_X86_64_RET_ADDR;
|
||||
}
|
||||
|
||||
template <typename A, typename R>
|
||||
bool
|
||||
DwarfInstructions<A, R>::isReturnAddressRegister(int regNum,
|
||||
const Registers_x86_64 &) {
|
||||
return (regNum == DW_X86_64_RET_ADDR);
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// x86 specific functions
|
||||
//
|
||||
template <typename A, typename R>
|
||||
int DwarfInstructions<A, R>::lastRestoreReg(const Registers_x86 &) {
|
||||
static_assert((int)CFI_Parser<A>::kMaxRegisterNumber
|
||||
> (int)DW_X86_RET_ADDR, "register number out of range");
|
||||
return DW_X86_RET_ADDR;
|
||||
}
|
||||
|
||||
template <typename A, typename R>
|
||||
bool DwarfInstructions<A, R>::isReturnAddressRegister(int regNum,
|
||||
const Registers_x86 &) {
|
||||
return (regNum == DW_X86_RET_ADDR);
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// ppc specific functions
|
||||
//
|
||||
template <typename A, typename R>
|
||||
int DwarfInstructions<A, R>::lastRestoreReg(const Registers_ppc &) {
|
||||
static_assert((int)CFI_Parser<A>::kMaxRegisterNumber
|
||||
> (int)UNW_PPC_SPEFSCR, "register number out of range");
|
||||
return UNW_PPC_SPEFSCR;
|
||||
}
|
||||
|
||||
template <typename A, typename R>
|
||||
bool DwarfInstructions<A, R>::isReturnAddressRegister(int regNum,
|
||||
const Registers_ppc &) {
|
||||
return (regNum == UNW_PPC_LR);
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// arm64 specific functions
|
||||
//
|
||||
template <typename A, typename R>
|
||||
bool DwarfInstructions<A, R>::isReturnAddressRegister(int regNum,
|
||||
const Registers_arm64 &) {
|
||||
return (regNum == UNW_ARM64_LR);
|
||||
}
|
||||
|
||||
template <typename A, typename R>
|
||||
int DwarfInstructions<A, R>::lastRestoreReg(const Registers_arm64 &) {
|
||||
static_assert((int)CFI_Parser<A>::kMaxRegisterNumber
|
||||
> (int)UNW_ARM64_D31, "register number out of range");
|
||||
return UNW_ARM64_D31;
|
||||
}
|
||||
|
||||
|
||||
} // namespace libunwind
|
||||
|
@ -49,6 +49,7 @@ public:
|
||||
int dataAlignFactor;
|
||||
bool isSignalFrame;
|
||||
bool fdesHaveAugmentationData;
|
||||
uint8_t returnAddressRegister;
|
||||
};
|
||||
|
||||
/// Information about an FDE (Frame Description Entry)
|
||||
@ -295,7 +296,9 @@ const char *CFI_Parser<A>::parseCIE(A &addressSpace, pint_t cie,
|
||||
// parse data alignment factor
|
||||
cieInfo->dataAlignFactor = (int)addressSpace.getSLEB128(p, cieContentEnd);
|
||||
// parse return address register
|
||||
addressSpace.getULEB128(p, cieContentEnd);
|
||||
uint64_t raReg = addressSpace.getULEB128(p, cieContentEnd);
|
||||
assert(raReg < 255 && "return address register too large");
|
||||
cieInfo->returnAddressRegister = (uint8_t)raReg;
|
||||
// parse augmentation data based on augmentation string
|
||||
const char *result = NULL;
|
||||
if (addressSpace.get8(strStart) == 'z') {
|
||||
|
@ -44,6 +44,7 @@ public:
|
||||
void setVectorRegister(int num, v128 value);
|
||||
const char *getRegisterName(int num);
|
||||
void jumpto();
|
||||
static int lastDwarfRegNum() { return 8; }
|
||||
|
||||
uint32_t getSP() const { return _registers.__esp; }
|
||||
void setSP(uint32_t value) { _registers.__esp = value; }
|
||||
@ -231,6 +232,7 @@ public:
|
||||
void setVectorRegister(int num, v128 value);
|
||||
const char *getRegisterName(int num);
|
||||
void jumpto();
|
||||
static int lastDwarfRegNum() { return 16; }
|
||||
|
||||
uint64_t getSP() const { return _registers.__rsp; }
|
||||
void setSP(uint64_t value) { _registers.__rsp = value; }
|
||||
@ -478,6 +480,7 @@ public:
|
||||
void setVectorRegister(int num, v128 value);
|
||||
const char *getRegisterName(int num);
|
||||
void jumpto();
|
||||
static int lastDwarfRegNum() { return 112; }
|
||||
|
||||
uint64_t getSP() const { return _registers.__r1; }
|
||||
void setSP(uint32_t value) { _registers.__r1 = value; }
|
||||
@ -1031,6 +1034,7 @@ public:
|
||||
void setVectorRegister(int num, v128 value);
|
||||
const char *getRegisterName(int num);
|
||||
void jumpto();
|
||||
static int lastDwarfRegNum() { return 95; }
|
||||
|
||||
uint64_t getSP() const { return _registers.__sp; }
|
||||
void setSP(uint64_t value) { _registers.__sp = value; }
|
||||
|
Loading…
x
Reference in New Issue
Block a user