The Pedigree Project  0.1
DwarfUnwinder.cc
1 /*
2  * Copyright (c) 2008-2014, Pedigree Developers
3  *
4  * Please see the CONTRIB file in the root of the source tree for a full
5  * list of contributors.
6  *
7  * Permission to use, copy, modify, and distribute this software for any
8  * purpose with or without fee is hereby granted, provided that the above
9  * copyright notice and this permission notice appear in all copies.
10  *
11  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
12  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
13  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
14  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
15  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
16  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
17  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
18  */
19 
20 #include "pedigree/kernel/debugger/DwarfUnwinder.h"
21 #include "pedigree/kernel/Log.h"
22 #include "pedigree/kernel/debugger/DwarfCfiAutomaton.h"
23 #include "pedigree/kernel/debugger/DwarfState.h"
24 #include "pedigree/kernel/processor/state.h"
25 
26 DwarfUnwinder::DwarfUnwinder(uintptr_t nData, size_t nLength)
27  : m_nData(nData), m_nLength(nLength)
28 {
29 }
30 
31 DwarfUnwinder::~DwarfUnwinder()
32 {
33 }
34 
36  const ProcessorState &inState, ProcessorState &outState,
37  uintptr_t &frameBase)
38 {
39  // Construct a DwarfState object and populate it.
40  DwarfState startState;
41 
42 // Unfortunately the next few lines are highly architecture dependent.
43 #ifdef X86
44  startState.m_R[DWARF_REG_EAX] = inState.eax;
45  startState.m_R[DWARF_REG_EBX] = inState.ebx;
46  startState.m_R[DWARF_REG_ECX] = inState.ecx;
47  startState.m_R[DWARF_REG_EDX] = inState.edx;
48  startState.m_R[DWARF_REG_ESI] = inState.esi;
49  startState.m_R[DWARF_REG_EDI] = inState.edi;
50  startState.m_R[DWARF_REG_ESP] = inState.esp;
51  startState.m_R[DWARF_REG_EBP] = inState.ebp;
52 #endif
53 #ifdef X64
54  startState.m_R[DWARF_REG_RAX] = inState.rax;
55  startState.m_R[DWARF_REG_RDX] = inState.rdx;
56  startState.m_R[DWARF_REG_RCX] = inState.rcx;
57  startState.m_R[DWARF_REG_RBX] = inState.rbx;
58  startState.m_R[DWARF_REG_RSI] = inState.rsi;
59  startState.m_R[DWARF_REG_RDI] = inState.rdi;
60  startState.m_R[DWARF_REG_RBP] = inState.rbp;
61  startState.m_R[DWARF_REG_RSP] = inState.rsp;
62  startState.m_R[DWARF_REG_R8] = inState.r8;
63  startState.m_R[DWARF_REG_R9] = inState.r9;
64  startState.m_R[DWARF_REG_R10] = inState.r10;
65  startState.m_R[DWARF_REG_R11] = inState.r11;
66  startState.m_R[DWARF_REG_R12] = inState.r12;
67  startState.m_R[DWARF_REG_R13] = inState.r13;
68  startState.m_R[DWARF_REG_R14] = inState.r14;
69  startState.m_R[DWARF_REG_R15] = inState.r15;
70  startState.m_R[DWARF_REG_RFLAGS] = inState.rflags;
71 #endif
72 #ifdef MIPS_COMMON
73  startState.m_R[DWARF_REG_AT] = inState.m_At;
74  startState.m_R[DWARF_REG_V0] = inState.m_V0;
75  startState.m_R[DWARF_REG_V1] = inState.m_V1;
76  startState.m_R[DWARF_REG_A0] = inState.m_A0;
77  startState.m_R[DWARF_REG_A1] = inState.m_A1;
78  startState.m_R[DWARF_REG_A2] = inState.m_A2;
79  startState.m_R[DWARF_REG_A3] = inState.m_A3;
80  startState.m_R[DWARF_REG_T0] = inState.m_T0;
81  startState.m_R[DWARF_REG_T1] = inState.m_T1;
82  startState.m_R[DWARF_REG_T2] = inState.m_T2;
83  startState.m_R[DWARF_REG_T3] = inState.m_T3;
84  startState.m_R[DWARF_REG_T4] = inState.m_T4;
85  startState.m_R[DWARF_REG_T5] = inState.m_T5;
86  startState.m_R[DWARF_REG_T6] = inState.m_T6;
87  startState.m_R[DWARF_REG_T7] = inState.m_T7;
88  startState.m_R[DWARF_REG_S0] = inState.m_S0;
89  startState.m_R[DWARF_REG_S1] = inState.m_S1;
90  startState.m_R[DWARF_REG_S2] = inState.m_S2;
91  startState.m_R[DWARF_REG_S3] = inState.m_S3;
92  startState.m_R[DWARF_REG_S4] = inState.m_S4;
93  startState.m_R[DWARF_REG_S5] = inState.m_S5;
94  startState.m_R[DWARF_REG_S6] = inState.m_S6;
95  startState.m_R[DWARF_REG_S7] = inState.m_S7;
96  startState.m_R[DWARF_REG_T8] = inState.m_T8;
97  startState.m_R[DWARF_REG_T9] = inState.m_T9;
98  // startState.m_R[DWARF_REG_K0] = inState.m_K0;
99  // startState.m_R[DWARF_REG_K1] = inState.m_K1;
100  startState.m_R[DWARF_REG_GP] = inState.m_Gp;
101  startState.m_R[DWARF_REG_SP] = inState.m_Sp;
102  startState.m_R[DWARF_REG_FP] = inState.m_Fp;
103  startState.m_R[DWARF_REG_RA] = inState.m_Ra;
104 #endif
105 #ifdef PPC_COMMON
106  startState.m_R[DWARF_REG_R0] = inState.m_R0;
107  startState.m_R[DWARF_REG_R1] = inState.m_R1;
108  startState.m_R[DWARF_REG_R2] = inState.m_R2;
109  startState.m_R[DWARF_REG_R3] = inState.m_R3;
110  startState.m_R[DWARF_REG_R4] = inState.m_R4;
111  startState.m_R[DWARF_REG_R5] = inState.m_R5;
112  startState.m_R[DWARF_REG_R6] = inState.m_R6;
113  startState.m_R[DWARF_REG_R7] = inState.m_R7;
114  startState.m_R[DWARF_REG_R8] = inState.m_R8;
115  startState.m_R[DWARF_REG_R9] = inState.m_R9;
116  startState.m_R[DWARF_REG_R10] = inState.m_R10;
117  startState.m_R[DWARF_REG_R11] = inState.m_R11;
118  startState.m_R[DWARF_REG_R12] = inState.m_R12;
119  startState.m_R[DWARF_REG_R13] = inState.m_R13;
120  startState.m_R[DWARF_REG_R14] = inState.m_R14;
121  startState.m_R[DWARF_REG_R15] = inState.m_R15;
122  startState.m_R[DWARF_REG_R16] = inState.m_R16;
123  startState.m_R[DWARF_REG_R17] = inState.m_R17;
124  startState.m_R[DWARF_REG_R18] = inState.m_R18;
125  startState.m_R[DWARF_REG_R19] = inState.m_R19;
126  startState.m_R[DWARF_REG_R20] = inState.m_R20;
127  startState.m_R[DWARF_REG_R21] = inState.m_R21;
128  startState.m_R[DWARF_REG_R22] = inState.m_R22;
129  startState.m_R[DWARF_REG_R23] = inState.m_R23;
130  startState.m_R[DWARF_REG_R24] = inState.m_R24;
131  startState.m_R[DWARF_REG_R25] = inState.m_R25;
132  startState.m_R[DWARF_REG_R26] = inState.m_R26;
133  startState.m_R[DWARF_REG_R27] = inState.m_R27;
134  startState.m_R[DWARF_REG_R28] = inState.m_R28;
135  startState.m_R[DWARF_REG_R29] = inState.m_R29;
136  startState.m_R[DWARF_REG_R30] = inState.m_R30;
137  startState.m_R[DWARF_REG_R31] = inState.m_R31;
138  startState.m_R[DWARF_REG_CR] = inState.m_Cr;
139  startState.m_R[DWARF_REG_LR] = inState.m_Lr;
140 // startState.m_R[DWARF_REG_CTR] = inState.m_Ctr;
141 #endif
142 
143  // For each CIE or FDE...
144  size_t nIndex = 0;
145  while (nIndex < m_nLength)
146  {
147  // Get the length of this entry.
148  uint32_t nLength = *reinterpret_cast<uint32_t *>(m_nData + nIndex);
149 
150  nIndex += sizeof(uint32_t);
151  const uint32_t k_nCieId = 0xFFFFFFFF;
152 
153  if (nLength == 0xFFFFFFFF)
154  {
155  ERROR_NOLOCK("64-bit DWARF file detected, but not supported!");
156  return false;
157  }
158 
159  // Get the type of this entry (or CIE pointer if this is a FDE).
160  uint32_t nCie = *reinterpret_cast<uint32_t *>(m_nData + nIndex);
161  nIndex += sizeof(uint32_t);
162 
163  // Is this a CIE?
164  if (nCie == k_nCieId)
165  {
166  // Skip over everything.
167  nIndex += nLength - sizeof(processor_register_t);
168  continue;
169  }
170 
171  // This is a FDE. Get its initial location.
172  uintptr_t nInitialLocation =
173  *reinterpret_cast<uintptr_t *>(m_nData + nIndex);
174  nIndex += sizeof(uintptr_t);
175 
176  // Get its addressing range.
177  size_t nAddressRange = *reinterpret_cast<size_t *>(m_nData + nIndex);
178  nIndex += sizeof(size_t);
179 
180  uintptr_t nInstructionStart = nIndex;
181  size_t nInstructionLength =
182  nLength - sizeof(uint32_t) - sizeof(uintptr_t) - sizeof(size_t);
183 
184  // Are we in this range?
185  if ((inState.getInstructionPointer() < nInitialLocation) ||
186  (inState.getInstructionPointer() >=
187  nInitialLocation + nAddressRange))
188  {
189  nIndex += nInstructionLength;
190  continue;
191  }
192 
193  // This is a FDE. Get the CIE it corresponds to.
194  uint32_t nCieEnd = *reinterpret_cast<uint32_t *>(m_nData + nCie) + nCie;
195  nCie += sizeof(uint32_t);
196  nCieEnd += sizeof(uint32_t);
197 
198  // Ensure our CIE ID is correct.
199  uint32_t nCieId = *reinterpret_cast<uint32_t *>(m_nData + nCie);
200  if (nCieId != k_nCieId)
201  {
202  WARNING_NOLOCK("DwarfUnwinder::unwind - CIE ID incorrect!");
203  return false;
204  }
205  nCie += sizeof(uint32_t);
206  nCie += 1; // Increment over version byte.
207 
208  const char *pAugmentationString =
209  reinterpret_cast<const char *>(m_nData + nCie);
210  while (*pAugmentationString++) // Pass over the augmentation string,
211  // waiting for a NULL char.
212  nCie++;
213  nCie++; // Step over null byte.
214 
215  uint8_t *pData = reinterpret_cast<uint8_t *>(m_nData);
216  int32_t nCodeAlignmentFactor = decodeUleb128(pData, nCie);
217  int32_t nDataAlignmentFactor = decodeSleb128(pData, nCie);
218 #ifndef HOSTED
219  uint32_t nReturnAddressRegister = decodeUleb128(pData, nCie);
220 #endif
221 
222  DwarfCfiAutomaton automaton;
223  automaton.initialise(
224  startState, m_nData + nCie, nCieEnd - nCie, nCodeAlignmentFactor,
225  nDataAlignmentFactor, nInitialLocation);
226  DwarfState *endState = automaton.execute(
227  m_nData + nInstructionStart, nInstructionLength,
228  inState.getInstructionPointer());
229  frameBase = endState->getCfa(startState);
230 
231 #ifdef X86
232  outState.eax = endState->getRegister(DWARF_REG_EAX, startState);
233  outState.ebx = endState->getRegister(DWARF_REG_EBX, startState);
234  outState.ecx = endState->getRegister(DWARF_REG_ECX, startState);
235  outState.edx = endState->getRegister(DWARF_REG_EDX, startState);
236  outState.esi = endState->getRegister(DWARF_REG_ESI, startState);
237  outState.edi = endState->getRegister(DWARF_REG_EDI, startState);
238  outState.esp = endState->getCfa(startState); // Architectural rule.
239  outState.ebp = endState->getRegister(DWARF_REG_EBP, startState);
240  outState.eip =
241  endState->getRegister(nReturnAddressRegister, startState);
242 #endif
243 #ifdef X64
244  outState.rax = endState->getRegister(DWARF_REG_RAX, startState);
245  outState.rdx = endState->getRegister(DWARF_REG_RDX, startState);
246  outState.rcx = endState->getRegister(DWARF_REG_RCX, startState);
247  outState.rbx = endState->getRegister(DWARF_REG_RBX, startState);
248  outState.rsi = endState->getRegister(DWARF_REG_RSI, startState);
249  outState.rdi = endState->getRegister(DWARF_REG_RDI, startState);
250  outState.rbp = endState->getRegister(DWARF_REG_RBP, startState);
251  outState.rsp = endState->getCfa(startState); // Architectural rule.
252  outState.r8 = endState->getRegister(DWARF_REG_R8, startState);
253  outState.r9 = endState->getRegister(DWARF_REG_R9, startState);
254  outState.r10 = endState->getRegister(DWARF_REG_R10, startState);
255  outState.r11 = endState->getRegister(DWARF_REG_R11, startState);
256  outState.r12 = endState->getRegister(DWARF_REG_R12, startState);
257  outState.r13 = endState->getRegister(DWARF_REG_R13, startState);
258  outState.r14 = endState->getRegister(DWARF_REG_R14, startState);
259  outState.r15 = endState->getRegister(DWARF_REG_R15, startState);
260  outState.rflags = endState->getRegister(DWARF_REG_RFLAGS, startState);
261  outState.rip =
262  endState->getRegister(nReturnAddressRegister, startState);
263 #endif
264 #ifdef MIPS_COMMON
265  outState.m_At = endState->getRegister(DWARF_REG_AT, startState);
266  outState.m_V0 = endState->getRegister(DWARF_REG_V0, startState);
267  outState.m_V1 = endState->getRegister(DWARF_REG_V1, startState);
268  outState.m_A0 = endState->getRegister(DWARF_REG_A0, startState);
269  outState.m_A1 = endState->getRegister(DWARF_REG_A1, startState);
270  outState.m_A2 = endState->getRegister(DWARF_REG_A2, startState);
271  outState.m_A3 = endState->getRegister(DWARF_REG_A3, startState);
272  outState.m_T0 = endState->getRegister(DWARF_REG_T0, startState);
273  outState.m_T1 = endState->getRegister(DWARF_REG_T1, startState);
274  outState.m_T2 = endState->getRegister(DWARF_REG_T2, startState);
275  outState.m_T3 = endState->getRegister(DWARF_REG_T3, startState);
276  outState.m_T4 = endState->getRegister(DWARF_REG_T4, startState);
277  outState.m_T5 = endState->getRegister(DWARF_REG_T5, startState);
278  outState.m_T6 = endState->getRegister(DWARF_REG_T6, startState);
279  outState.m_T7 = endState->getRegister(DWARF_REG_T7, startState);
280  outState.m_S0 = endState->getRegister(DWARF_REG_S0, startState);
281  outState.m_S1 = endState->getRegister(DWARF_REG_S1, startState);
282  outState.m_S2 = endState->getRegister(DWARF_REG_S2, startState);
283  outState.m_S3 = endState->getRegister(DWARF_REG_S3, startState);
284  outState.m_S4 = endState->getRegister(DWARF_REG_S4, startState);
285  outState.m_S5 = endState->getRegister(DWARF_REG_S5, startState);
286  outState.m_S6 = endState->getRegister(DWARF_REG_S6, startState);
287  outState.m_S7 = endState->getRegister(DWARF_REG_S7, startState);
288  outState.m_T8 = endState->getRegister(DWARF_REG_T8, startState);
289  outState.m_T9 = endState->getRegister(DWARF_REG_T9, startState);
290  // outState.m_K0 = endState->getRegister(DWARF_REG_K0, startState);
291  // outState.m_K1 = endState->getRegister(DWARF_REG_K1, startState);
292  outState.m_Gp = endState->getRegister(DWARF_REG_GP, startState);
293  outState.m_Sp = endState->getCfa(startState); // Architectural rule.
294  outState.m_Fp = endState->getRegister(DWARF_REG_FP, startState);
295  outState.m_Ra = endState->getRegister(DWARF_REG_RA, startState);
296  outState.m_Epc =
297  endState->getRegister(nReturnAddressRegister, startState);
298 #endif
299 #ifdef PPC_COMMON
300  outState.m_R0 = endState->getRegister(DWARF_REG_R0, startState);
301  outState.m_R1 = endState->getCfa(startState); // Architectural rule.
302  outState.m_R2 = endState->getRegister(DWARF_REG_R2, startState);
303  outState.m_R3 = endState->getRegister(DWARF_REG_R3, startState);
304  outState.m_R4 = endState->getRegister(DWARF_REG_R4, startState);
305  outState.m_R5 = endState->getRegister(DWARF_REG_R5, startState);
306  outState.m_R6 = endState->getRegister(DWARF_REG_R6, startState);
307  outState.m_R7 = endState->getRegister(DWARF_REG_R7, startState);
308  outState.m_R8 = endState->getRegister(DWARF_REG_R8, startState);
309  outState.m_R9 = endState->getRegister(DWARF_REG_R9, startState);
310  outState.m_R10 = endState->getRegister(DWARF_REG_R10, startState);
311  outState.m_R11 = endState->getRegister(DWARF_REG_R11, startState);
312  outState.m_R12 = endState->getRegister(DWARF_REG_R12, startState);
313  outState.m_R13 = endState->getRegister(DWARF_REG_R13, startState);
314  outState.m_R14 = endState->getRegister(DWARF_REG_R14, startState);
315  outState.m_R15 = endState->getRegister(DWARF_REG_R15, startState);
316  outState.m_R16 = endState->getRegister(DWARF_REG_R16, startState);
317  outState.m_R17 = endState->getRegister(DWARF_REG_R17, startState);
318  outState.m_R18 = endState->getRegister(DWARF_REG_R18, startState);
319  outState.m_R19 = endState->getRegister(DWARF_REG_R19, startState);
320  outState.m_R20 = endState->getRegister(DWARF_REG_R20, startState);
321  outState.m_R21 = endState->getRegister(DWARF_REG_R21, startState);
322  outState.m_R22 = endState->getRegister(DWARF_REG_R22, startState);
323  outState.m_R23 = endState->getRegister(DWARF_REG_R23, startState);
324  outState.m_R24 = endState->getRegister(DWARF_REG_R24, startState);
325  outState.m_R25 = endState->getRegister(DWARF_REG_R25, startState);
326  outState.m_R26 = endState->getRegister(DWARF_REG_R26, startState);
327  outState.m_R27 = endState->getRegister(DWARF_REG_R27, startState);
328  outState.m_R28 = endState->getRegister(DWARF_REG_R28, startState);
329  outState.m_R29 = endState->getRegister(DWARF_REG_R29, startState);
330  outState.m_R30 = endState->getRegister(DWARF_REG_R30, startState);
331  outState.m_R31 = endState->getRegister(DWARF_REG_R31, startState);
332  outState.m_Cr = endState->getRegister(DWARF_REG_CR, startState);
333  outState.m_Lr = endState->getRegister(DWARF_REG_LR, startState);
334  // outState.m_Ctr = endState->getRegister(DWARF_REG_CTR, startState);
335  // Ah so. G++ doesn't really support the DWARF standard (AGAIN) it
336  // seems, it leaves the return address in LR, and doesn't use the
337  // correct numbering. Nice.
338  outState.m_Srr0 =
339  outState.m_Lr; // endState->getRegister(nReturnAddressRegister,
340  // startState);
341 #endif
342  return true;
343  }
344 
345  return false;
346 }
347 
348 uint32_t DwarfUnwinder::decodeUleb128(uint8_t *pBase, uint32_t &nOffset)
349 {
350  uint32_t result = 0;
351  uint32_t shift = 0;
352  while (true)
353  {
354  uint8_t byte = pBase[nOffset++];
355  result |= (byte & 0x7f) << shift;
356  if ((byte & 0x80) == 0)
357  break;
358  shift += 7;
359  }
360  return result;
361 }
362 
363 int32_t DwarfUnwinder::decodeSleb128(uint8_t *pBase, uint32_t &nOffset)
364 {
365  int32_t result = 0;
366  uint32_t shift = 0;
367  uint8_t byte;
368  while (true)
369  {
370  byte = pBase[nOffset++];
371  result |= (byte & 0x7f) << shift;
372  shift += 7;
373  if ((byte & 0x80) == 0)
374  break;
375  }
376  if ((shift < sizeof(int32_t) * 8) &&
377  (byte & 0x40)) /* If sign bit of byte is set */
378  result |= -(1 << shift); /* sign extend */
379  return result;
380 }
size_t m_nLength
Definition: DwarfUnwinder.h:80
bool unwind(const ProcessorState &inState, ProcessorState &outState, uintptr_t &frameBase)
DwarfUnwinder(uintptr_t nData, size_t nLength)
static int32_t decodeSleb128(uint8_t *pBase, uint32_t &nOffset)
processor_register_t getRegister(unsigned int nRegister, const DwarfState &initialState)
Definition: DwarfState.h:230
void initialise(const DwarfState &startingState, uintptr_t nCodeLocation, size_t nCodeLen, int32_t nCodeAlignmentFactor, int32_t nDataAlignmentFactor, uintptr_t nStartingPc)
static uint32_t decodeUleb128(uint8_t *pBase, uint32_t &nOffset)
processor_register_t m_R[DWARF_MAX_REGISTERS]
Definition: DwarfState.h:306
DwarfState * execute(uintptr_t nCodeLocation, size_t nCodeLen, uintptr_t nBreakAt)
uintptr_t m_nData
Definition: DwarfUnwinder.h:75