20#include "pedigree/kernel/Log.h"
21#include "pedigree/kernel/debugger/DwarfCfiAutomaton.h"
22#include "pedigree/kernel/debugger/DwarfState.h"
23#include "pedigree/kernel/debugger/DwarfUnwinder.h"
24#include "pedigree/kernel/processor/state.h"
27void fillDwarfState(
DwarfState& outState,
const T& inState);
31 uint32_t nReturnAddressRegister);
35 outState.
m_R[DWARF_REG_RAX] = inState.
rax;
36 outState.
m_R[DWARF_REG_RDX] = inState.
rdx;
37 outState.
m_R[DWARF_REG_RCX] = inState.
rcx;
38 outState.
m_R[DWARF_REG_RBX] = inState.
rbx;
39 outState.
m_R[DWARF_REG_RSI] = inState.
rsi;
40 outState.
m_R[DWARF_REG_RDI] = inState.
rdi;
41 outState.
m_R[DWARF_REG_RBP] = inState.
rbp;
42 outState.
m_R[DWARF_REG_RSP] = inState.
rsp;
43 outState.
m_R[DWARF_REG_R8] = inState.
r8;
44 outState.
m_R[DWARF_REG_R9] = inState.
r9;
45 outState.
m_R[DWARF_REG_R10] = inState.
r10;
46 outState.
m_R[DWARF_REG_R11] = inState.
r11;
47 outState.
m_R[DWARF_REG_R12] = inState.
r12;
48 outState.
m_R[DWARF_REG_R13] = inState.
r13;
49 outState.
m_R[DWARF_REG_R14] = inState.
r14;
50 outState.
m_R[DWARF_REG_R15] = inState.
r15;
51 outState.
m_R[DWARF_REG_RFLAGS] = inState.
rflags;
64 outState.
rsp = endState->getCfa(startState);
65 outState.
r8 = endState->
getRegister(DWARF_REG_R8, startState);
66 outState.
r9 = endState->
getRegister(DWARF_REG_R9, startState);
74 outState.
rip = endState->
getRegister(nReturnAddressRegister, startState);
91 for (
size_t i = 0; i < 31; ++i) {
92 outState.
m_R[i] = inState.x[i];
94 outState.
m_R[31] = inState.sp;
95 outState.
m_R[32] = inState.pc;
96 outState.
m_R[33] = inState.pstate;
102 for (
size_t i = 0; i < 31; ++i) {
103 outState.x[i] = endState->
getRegister(i, startState);
105 outState.sp = endState->getCfa(startState);
106 outState.pc = endState->
getRegister(returnRegister, startState);
107 outState.pstate = startState.
m_R[33];
114 for (
size_t i = 0; i < 13; ++i) {
115 outState.
m_R[i] = inState.r[i];
117 outState.
m_R[13] = inState.sp;
118 outState.
m_R[14] = inState.lr;
119 outState.
m_R[15] = inState.pc;
120 outState.
m_R[16] = inState.cpsr;
126 for (
size_t i = 0; i < 13; ++i) {
127 outState.r[i] = endState->
getRegister(i, startState);
129 outState.sp = endState->getCfa(startState);
130 outState.lr = endState->
getRegister(14, startState);
131 outState.pc = endState->
getRegister(returnRegister, startState);
132 outState.cpsr = startState.
m_R[16];
137 : m_nData(nData), m_nLength(nLength) {}
139DwarfUnwinder::~DwarfUnwinder() {}
142 uintptr_t& frameBase) {
146 fillDwarfState(startState, inState);
152 uint32_t nLength = *
reinterpret_cast<uint32_t*
>(
m_nData + nIndex);
154 nIndex +=
sizeof(uint32_t);
155 const uint32_t k_nCieId = 0xFFFFFFFF;
157 if (nLength == 0xFFFFFFFF) {
158 ERROR_NOLOCK(
"64-bit DWARF file detected, but not supported!");
163 uint32_t nCie = *
reinterpret_cast<uint32_t*
>(
m_nData + nIndex);
164 nIndex +=
sizeof(uint32_t);
167 if (nCie == k_nCieId) {
169 nIndex += nLength -
sizeof(processor_register_t);
174 uintptr_t nInitialLocation = *
reinterpret_cast<uintptr_t*
>(
m_nData + nIndex);
175 nIndex +=
sizeof(uintptr_t);
178 size_t nAddressRange = *
reinterpret_cast<size_t*
>(
m_nData + nIndex);
179 nIndex +=
sizeof(size_t);
181 uintptr_t nInstructionStart = nIndex;
182 size_t nInstructionLength = nLength -
sizeof(uint32_t) -
sizeof(uintptr_t) -
sizeof(size_t);
185 if ((inState.getInstructionPointer() < nInitialLocation) ||
186 (inState.getInstructionPointer() >= nInitialLocation + nAddressRange)) {
187 nIndex += nInstructionLength;
192 uint32_t nCieEnd = *
reinterpret_cast<uint32_t*
>(
m_nData + nCie) + nCie;
193 nCie +=
sizeof(uint32_t);
194 nCieEnd +=
sizeof(uint32_t);
197 uint32_t nCieId = *
reinterpret_cast<uint32_t*
>(
m_nData + nCie);
198 if (nCieId != k_nCieId) {
199 WARNING_NOLOCK(
"DwarfUnwinder::unwind - CIE ID incorrect!");
202 nCie +=
sizeof(uint32_t);
205 const char* pAugmentationString =
reinterpret_cast<const char*
>(
m_nData + nCie);
206 while (*pAugmentationString++)
211 uint8_t* pData =
reinterpret_cast<uint8_t*
>(
m_nData);
214 uint32_t nReturnAddressRegister = 0;
220 automaton.
initialise(startState,
m_nData + nCie, nCieEnd - nCie, nCodeAlignmentFactor,
221 nDataAlignmentFactor, nInitialLocation);
223 inState.getInstructionPointer());
224 frameBase = endState->getCfa(startState);
226 extractDwarfState(endState, startState, outState, nReturnAddressRegister);
238 uint8_t
byte = pBase[nOffset++];
239 result |= (
byte & 0x7f) << shift;
240 if ((
byte & 0x80) == 0)
252 byte = pBase[nOffset++];
253 result |= (
byte & 0x7f) << shift;
255 if ((
byte & 0x80) == 0)
258 if ((shift <
sizeof(int32_t) * 8) && (
byte & 0x40))
259 result |= -(1 << shift);
void initialise(const DwarfState &startingState, uintptr_t nCodeLocation, size_t nCodeLen, int32_t nCodeAlignmentFactor, int32_t nDataAlignmentFactor, uintptr_t nStartingPc)
DwarfState * execute(uintptr_t nCodeLocation, size_t nCodeLen, uintptr_t nBreakAt)
processor_register_t getRegister(unsigned int nRegister, const DwarfState &initialState) const
processor_register_t m_R[DWARF_MAX_REGISTERS]
DwarfUnwinder(uintptr_t nData, size_t nLength)
static uint32_t decodeUleb128(uint8_t *pBase, uint32_t &nOffset)
static int32_t decodeSleb128(uint8_t *pBase, uint32_t &nOffset)
bool unwind(const ProcessorState &inState, ProcessorState &outState, uintptr_t &frameBase)