Changeset View
Changeset View
Standalone View
Standalone View
src/DwarfInstructions.hpp
Show First 20 Lines • Show All 153 Lines • ▼ Show 20 Lines | |||||
int DwarfInstructions<A, R>::stepWithDwarf(A &addressSpace, pint_t pc, | int DwarfInstructions<A, R>::stepWithDwarf(A &addressSpace, pint_t pc, | ||||
pint_t fdeStart, R ®isters) { | pint_t fdeStart, R ®isters) { | ||||
FDE_Info fdeInfo; | FDE_Info fdeInfo; | ||||
CIE_Info cieInfo; | CIE_Info cieInfo; | ||||
if (CFI_Parser<A>::decodeFDE(addressSpace, fdeStart, &fdeInfo, | if (CFI_Parser<A>::decodeFDE(addressSpace, fdeStart, &fdeInfo, | ||||
&cieInfo) == NULL) { | &cieInfo) == NULL) { | ||||
PrologInfo prolog; | PrologInfo prolog; | ||||
if (CFI_Parser<A>::parseFDEInstructions(addressSpace, fdeInfo, cieInfo, pc, | if (CFI_Parser<A>::parseFDEInstructions(addressSpace, fdeInfo, cieInfo, pc, | ||||
&prolog)) { | R::getArch(), &prolog)) { | ||||
// get pointer to cfa (architecture specific) | // get pointer to cfa (architecture specific) | ||||
pint_t cfa = getCFA(addressSpace, prolog, registers); | pint_t cfa = getCFA(addressSpace, prolog, registers); | ||||
// restore registers that DWARF says were saved | // restore registers that DWARF says were saved | ||||
R newRegisters = registers; | R newRegisters = registers; | ||||
pint_t returnAddress = 0; | pint_t returnAddress = 0; | ||||
const int lastReg = R::lastDwarfRegNum(); | const int lastReg = R::lastDwarfRegNum(); | ||||
assert(static_cast<int>(CFI_Parser<A>::kMaxRegisterNumber) >= lastReg && | assert(static_cast<int>(CFI_Parser<A>::kMaxRegisterNumber) >= lastReg && | ||||
Show All 30 Lines | |||||
#if defined(_LIBUNWIND_TARGET_AARCH64) | #if defined(_LIBUNWIND_TARGET_AARCH64) | ||||
// If the target is aarch64 then the return address may have been signed | // If the target is aarch64 then the return address may have been signed | ||||
// using the v8.3 pointer authentication extensions. The original | // using the v8.3 pointer authentication extensions. The original | ||||
// return address needs to be authenticated before the return address is | // return address needs to be authenticated before the return address is | ||||
// restored. autia1716 is used instead of autia as autia1716 assembles | // restored. autia1716 is used instead of autia as autia1716 assembles | ||||
// to a NOP on pre-v8.3a architectures. | // to a NOP on pre-v8.3a architectures. | ||||
if (prolog.savedRegisters[UNW_ARM64_RA_SIGN_STATE].value) { | if (prolog.savedRegisters[UNW_ARM64_RA_SIGN_STATE].value) { | ||||
#if !defined(_LIBUNWIND_IS_NATIVE_ONLY) | #if !defined(_LIBUNWIND_IS_NATIVE_ONLY) | ||||
if (R::getArch() == REGISTERS_ARM64) | |||||
return UNW_ECROSSRASIGNING; | return UNW_ECROSSRASIGNING; | ||||
jyknight: I think this architecture conditional ought to be outside of the entire if block checking… | |||||
#else | #else | ||||
register unsigned long long x17 __asm("x17") = returnAddress; | register unsigned long long x17 __asm("x17") = returnAddress; | ||||
register unsigned long long x16 __asm("x16") = cfa; | register unsigned long long x16 __asm("x16") = cfa; | ||||
// These are the autia1716/autib1716 instructions. The hint instructions | // These are the autia1716/autib1716 instructions. The hint instructions | ||||
// are used here as gcc does not assemble autia1716/autib1716 for pre | // are used here as gcc does not assemble autia1716/autib1716 for pre | ||||
// armv8.3a targets. | // armv8.3a targets. | ||||
if (cieInfo.addressesSignedWithBKey) | if (cieInfo.addressesSignedWithBKey) | ||||
asm("hint 0xe" : "+r"(x17) : "r"(x16)); // autib1716 | asm("hint 0xe" : "+r"(x17) : "r"(x16)); // autib1716 | ||||
else | else | ||||
asm("hint 0xc" : "+r"(x17) : "r"(x16)); // autia1716 | asm("hint 0xc" : "+r"(x17) : "r"(x16)); // autia1716 | ||||
returnAddress = x17; | returnAddress = x17; | ||||
#endif | #endif | ||||
} | } | ||||
#endif | #endif | ||||
#if defined(_LIBUNWIND_TARGET_SPARC) | |||||
if (R::getArch() == REGISTERS_SPARC) { | |||||
// Skip call site instruction and delay slot | |||||
returnAddress += 8; | |||||
// Skip unimp instruction if function returns a struct | |||||
if ((addressSpace.get32(returnAddress) & 0xC1C00000) == 0) | |||||
returnAddress += 4; | |||||
} | |||||
#endif | |||||
// Return address is address after call site instruction, so setting IP to | // Return address is address after call site instruction, so setting IP to | ||||
// that does simualates a return. | // that does simualates a return. | ||||
newRegisters.setIP(returnAddress); | newRegisters.setIP(returnAddress); | ||||
// Simulate the step by replacing the register set with the new ones. | // Simulate the step by replacing the register set with the new ones. | ||||
registers = newRegisters; | registers = newRegisters; | ||||
return UNW_STEP_SUCCESS; | return UNW_STEP_SUCCESS; | ||||
▲ Show 20 Lines • Show All 551 Lines • Show Last 20 Lines |
I think this architecture conditional ought to be outside of the entire if block checking UNW_ARM64_RA_SIGN_STATE. LGTM other than this.