The Pedigree Project  0.1
DwarfState.h
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 #ifndef DWARFSTATE_H
21 #define DWARFSTATE_H
22 
23 #include "pedigree/kernel/Log.h"
24 #include "pedigree/kernel/processor/types.h"
25 #include "pedigree/kernel/utilities/utility.h"
26 
29 #ifdef PPC_COMMON
30 #define DWARF_MAX_REGISTERS 66
31 #else
32 #define DWARF_MAX_REGISTERS 50
33 #endif
34 
35 #ifdef X86
36 #define DWARF_REG_EAX 0
37 #define DWARF_REG_ECX 1
38 #define DWARF_REG_EDX 2
39 #define DWARF_REG_EBX 3
40 #define DWARF_REG_ESP 4
41 #define DWARF_REG_EBP 5
42 #define DWARF_REG_ESI 6
43 #define DWARF_REG_EDI 7
44 #endif
45 #ifdef X64
46 #define DWARF_REG_RAX 0
47 #define DWARF_REG_RDX 1
48 #define DWARF_REG_RCX 2
49 #define DWARF_REG_RBX 3
50 #define DWARF_REG_RSI 4
51 #define DWARF_REG_RDI 5
52 #define DWARF_REG_RBP 6
53 #define DWARF_REG_RSP 7
54 #define DWARF_REG_R8 8
55 #define DWARF_REG_R9 9
56 #define DWARF_REG_R10 10
57 #define DWARF_REG_R11 11
58 #define DWARF_REG_R12 12
59 #define DWARF_REG_R13 13
60 #define DWARF_REG_R14 14
61 #define DWARF_REG_R15 15
62 #define DWARF_REG_RFLAGS 49
63 #endif
64 #ifdef MIPS_COMMON
65 #define DWARF_REG_ZERO 0
66 #define DWARF_REG_AT 1
67 #define DWARF_REG_V0 2
68 #define DWARF_REG_V1 3
69 #define DWARF_REG_A0 4
70 #define DWARF_REG_A1 5
71 #define DWARF_REG_A2 6
72 #define DWARF_REG_A3 7
73 #define DWARF_REG_T0 8
74 #define DWARF_REG_T1 9
75 #define DWARF_REG_T2 10
76 #define DWARF_REG_T3 11
77 #define DWARF_REG_T4 12
78 #define DWARF_REG_T5 13
79 #define DWARF_REG_T6 14
80 #define DWARF_REG_T7 15
81 #define DWARF_REG_S0 16
82 #define DWARF_REG_S1 17
83 #define DWARF_REG_S2 18
84 #define DWARF_REG_S3 19
85 #define DWARF_REG_S4 20
86 #define DWARF_REG_S5 21
87 #define DWARF_REG_S6 22
88 #define DWARF_REG_S7 23
89 #define DWARF_REG_T8 24
90 #define DWARF_REG_T9 25
91 #define DWARF_REG_K0 26
92 #define DWARF_REG_K1 27
93 #define DWARF_REG_GP 28
94 #define DWARF_REG_SP 29
95 #define DWARF_REG_FP 30
96 #define DWARF_REG_RA 31
97 #endif
98 #ifdef PPC_COMMON
99 #define DWARF_REG_R0 0
100 #define DWARF_REG_R1 1
101 #define DWARF_REG_R2 2
102 #define DWARF_REG_R3 3
103 #define DWARF_REG_R4 4
104 #define DWARF_REG_R5 5
105 #define DWARF_REG_R6 6
106 #define DWARF_REG_R7 7
107 #define DWARF_REG_R8 8
108 #define DWARF_REG_R9 9
109 #define DWARF_REG_R10 10
110 #define DWARF_REG_R11 11
111 #define DWARF_REG_R12 12
112 #define DWARF_REG_R13 13
113 #define DWARF_REG_R14 14
114 #define DWARF_REG_R15 15
115 #define DWARF_REG_R16 16
116 #define DWARF_REG_R17 17
117 #define DWARF_REG_R18 18
118 #define DWARF_REG_R19 19
119 #define DWARF_REG_R20 20
120 #define DWARF_REG_R21 21
121 #define DWARF_REG_R22 22
122 #define DWARF_REG_R23 23
123 #define DWARF_REG_R24 24
124 #define DWARF_REG_R25 25
125 #define DWARF_REG_R26 26
126 #define DWARF_REG_R27 27
127 #define DWARF_REG_R28 28
128 #define DWARF_REG_R29 29
129 #define DWARF_REG_R30 30
130 #define DWARF_REG_R31 31
131 #define DWARF_REG_CR 64
132 #define DWARF_REG_LR 65 // DWARF standard says this should be 108. G++ differs.
133 // define DWARF_REG_CTR 109
134 #endif
135 
136 // Watch out! Register numbering is seemingly random - x86 and x86_64 ones are
137 // here: http://wikis.sun.com/display/SunStudio/Dwarf+Register+Numbering
143 {
144  public:
145  enum RegisterState
146  {
147  SameValue = 0,
148  Undefined,
149  Offset,
150  ValOffset,
151  Register,
152  Expression,
153  ValExpression,
154  Architectural
155  };
156 
157  DwarfState()
158  : m_CfaState(ValOffset), m_CfaRegister(0), m_CfaOffset(0),
160  {
161  ByteSet(
162  static_cast<void *>(m_RegisterStates), 0,
163  sizeof(RegisterState) * DWARF_MAX_REGISTERS);
164  ByteSet(
165  static_cast<void *>(m_R), 0,
166  sizeof(uintptr_t) * DWARF_MAX_REGISTERS);
167  }
168  ~DwarfState()
169  {
170  }
171 
175  DwarfState(const DwarfState &other)
177  m_CfaOffset(other.m_CfaOffset),
180  {
181  MemoryCopy(
182  static_cast<void *>(m_RegisterStates),
183  static_cast<const void *>(other.m_RegisterStates),
184  sizeof(RegisterState) * DWARF_MAX_REGISTERS);
185  MemoryCopy(
186  static_cast<void *>(m_R), static_cast<const void *>(other.m_R),
187  sizeof(uintptr_t) * DWARF_MAX_REGISTERS);
188  }
189 
190  DwarfState &operator=(const DwarfState &other)
191  {
192  m_CfaState = other.m_CfaState;
194  m_CfaOffset = other.m_CfaOffset;
197  MemoryCopy(
198  static_cast<void *>(m_RegisterStates),
199  static_cast<const void *>(other.m_RegisterStates),
200  sizeof(RegisterState) * DWARF_MAX_REGISTERS);
201  MemoryCopy(
202  static_cast<void *>(m_R), static_cast<const void *>(other.m_R),
203  sizeof(uintptr_t) * DWARF_MAX_REGISTERS);
204  return *this;
205  }
206 
207  processor_register_t getCfa(const DwarfState &initialState)
208  {
209  switch (m_CfaState)
210  {
211  case ValOffset:
212  {
213  return initialState.m_R[m_CfaRegister] +
214  static_cast<ssize_t>(m_CfaOffset);
215  }
216  case ValExpression:
217  {
218  WARNING("DwarfState::getCfa: Expression type not implemented.");
219  break;
220  }
221  default:
222  ERROR("CfaState invalid!");
223  return 0;
224  }
225 
226  return 0;
227  }
228 
229  processor_register_t
230  getRegister(unsigned int nRegister, const DwarfState &initialState)
231  {
232  // NOTICE("GetRegister: r" << Dec << nRegister);
233  switch (m_RegisterStates[nRegister])
234  {
235  case Undefined:
236  // WARNING ("Request for undefined register: r" << Dec
237  // << nRegister);
238  break;
239  case SameValue:
240  // WARNING ("SameValue.");
241  return initialState.m_R[nRegister];
242  case Offset:
243  {
244  // NOTICE("Offset: " << Hex << getCfa(initialState) <<
245  // ", " << m_R[nRegister]);
250  if (getCfa(initialState) < 0x2000)
251  {
252  WARNING("Malformed CFA!");
253  return 0x0;
254  }
255  // "The previous value of this register is saved at the address
256  // CFA+N where CFA is the
257  // current CFA value and N is a signed offset."
258  return *reinterpret_cast<processor_register_t *>(
259  getCfa(initialState) +
260  static_cast<ssize_t>(m_R[nRegister]));
261  }
262  case ValOffset:
263  {
264  // WARNING ("ValOffset.");
265  // "The previous value of this register is the value CFA+N where
266  // CFA is the current
267  // CFA value and N is a signed offset."
268  return getCfa(initialState) +
269  static_cast<ssize_t>(m_R[nRegister]);
270  }
271  case Register:
272  {
273  // WARNING ("Register.");
274  // "The previous value of this register is stored in another
275  // register numbered R."
276  return initialState.m_R[nRegister];
277  }
278  case Expression:
279  {
280  // WARNING ("Expression not implemented, r" << Dec <<
281  // nRegister);
282  return 0;
283  }
284  case ValExpression:
285  {
286  // WARNING ("ValExpression not implemented, r" << Dec
287  // << nRegister);
288  return 0;
289  }
290  case Architectural:
291  // WARNING ("Request for 'architectural' register: r"
292  // << Dec << nRegister);
293  return 0;
294  }
295  return 0;
296  }
297 
301  RegisterState m_RegisterStates[DWARF_MAX_REGISTERS];
302 
306  processor_register_t m_R[DWARF_MAX_REGISTERS];
307 
312  RegisterState m_CfaState;
316  uint32_t m_CfaRegister;
317  processor_register_t m_CfaOffset;
321  uint8_t *m_CfaExpression;
322 
326  uintptr_t m_ReturnAddress;
327 };
328 
331 #endif
uint8_t * m_CfaExpression
Definition: DwarfState.h:321
uint32_t m_CfaRegister
Definition: DwarfState.h:316
uintptr_t m_ReturnAddress
Definition: DwarfState.h:326
RegisterState m_RegisterStates[DWARF_MAX_REGISTERS]
Definition: DwarfState.h:301
processor_register_t getRegister(unsigned int nRegister, const DwarfState &initialState)
Definition: DwarfState.h:230
RegisterState m_CfaState
Definition: DwarfState.h:312
#define WARNING(text)
Definition: Log.h:78
processor_register_t m_R[DWARF_MAX_REGISTERS]
Definition: DwarfState.h:306
DwarfState(const DwarfState &other)
Definition: DwarfState.h:175
#define ERROR(text)
Definition: Log.h:82