• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // -*- mode: c++ -*-
2 
3 // Copyright (c) 2010 Google Inc.
4 // All rights reserved.
5 //
6 // Redistribution and use in source and binary forms, with or without
7 // modification, are permitted provided that the following conditions are
8 // met:
9 //
10 //     * Redistributions of source code must retain the above copyright
11 // notice, this list of conditions and the following disclaimer.
12 //     * Redistributions in binary form must reproduce the above
13 // copyright notice, this list of conditions and the following disclaimer
14 // in the documentation and/or other materials provided with the
15 // distribution.
16 //     * Neither the name of Google Inc. nor the names of its
17 // contributors may be used to endorse or promote products derived from
18 // this software without specific prior written permission.
19 //
20 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
23 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
24 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
25 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
26 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 
32 // stack_frame_cpu.h: CPU-specific StackFrame extensions.
33 //
34 // These types extend the StackFrame structure to carry CPU-specific register
35 // state.  They are defined in this header instead of stack_frame.h to
36 // avoid the need to include minidump_format.h when only the generic
37 // StackFrame type is needed.
38 //
39 // Author: Mark Mentovai
40 
41 #ifndef GOOGLE_BREAKPAD_PROCESSOR_STACK_FRAME_CPU_H__
42 #define GOOGLE_BREAKPAD_PROCESSOR_STACK_FRAME_CPU_H__
43 
44 #include "google_breakpad/common/minidump_format.h"
45 #include "google_breakpad/processor/stack_frame.h"
46 
47 namespace google_breakpad {
48 
49 struct WindowsFrameInfo;
50 class CFIFrameInfo;
51 
52 struct StackFrameX86 : public StackFrame {
53   // ContextValidity has one entry for each relevant hardware pointer
54   // register (%eip and %esp) and one entry for each general-purpose
55   // register. It's worthwhile having validity flags for caller-saves
56   // registers: they are valid in the youngest frame, and such a frame
57   // might save a callee-saves register in a caller-saves register, but
58   // SimpleCFIWalker won't touch registers unless they're marked as valid.
59   enum ContextValidity {
60     CONTEXT_VALID_NONE = 0,
61     CONTEXT_VALID_EIP  = 1 << 0,
62     CONTEXT_VALID_ESP  = 1 << 1,
63     CONTEXT_VALID_EBP  = 1 << 2,
64     CONTEXT_VALID_EAX  = 1 << 3,
65     CONTEXT_VALID_EBX  = 1 << 4,
66     CONTEXT_VALID_ECX  = 1 << 5,
67     CONTEXT_VALID_EDX  = 1 << 6,
68     CONTEXT_VALID_ESI  = 1 << 7,
69     CONTEXT_VALID_EDI  = 1 << 8,
70     CONTEXT_VALID_ALL  = -1
71   };
72 
StackFrameX86StackFrameX8673   StackFrameX86()
74      : context(),
75        context_validity(CONTEXT_VALID_NONE),
76        windows_frame_info(NULL),
77        cfi_frame_info(NULL) {}
78   ~StackFrameX86();
79 
80   // Overriden to return the return address as saved on the stack.
81   virtual uint64_t ReturnAddress() const;
82 
83   // Register state.  This is only fully valid for the topmost frame in a
84   // stack.  In other frames, the values of nonvolatile registers may be
85   // present, given sufficient debugging information.  Refer to
86   // context_validity.
87   MDRawContextX86 context;
88 
89   // context_validity is actually ContextValidity, but int is used because
90   // the OR operator doesn't work well with enumerated types.  This indicates
91   // which fields in context are valid.
92   int context_validity;
93 
94   // Any stack walking information we found describing this.instruction.
95   // These may be NULL if there is no such information for that address.
96   WindowsFrameInfo *windows_frame_info;
97   CFIFrameInfo *cfi_frame_info;
98 };
99 
100 struct StackFramePPC : public StackFrame {
101   // ContextValidity should eventually contain entries for the validity of
102   // other nonvolatile (callee-save) registers as in
103   // StackFrameX86::ContextValidity, but the ppc stackwalker doesn't currently
104   // locate registers other than the ones listed here.
105   enum ContextValidity {
106     CONTEXT_VALID_NONE = 0,
107     CONTEXT_VALID_SRR0 = 1 << 0,
108     CONTEXT_VALID_GPR1 = 1 << 1,
109     CONTEXT_VALID_ALL  = -1
110   };
111 
StackFramePPCStackFramePPC112   StackFramePPC() : context(), context_validity(CONTEXT_VALID_NONE) {}
113 
114   // Register state.  This is only fully valid for the topmost frame in a
115   // stack.  In other frames, the values of nonvolatile registers may be
116   // present, given sufficient debugging information.  Refer to
117   // context_validity.
118   MDRawContextPPC context;
119 
120   // context_validity is actually ContextValidity, but int is used because
121   // the OR operator doesn't work well with enumerated types.  This indicates
122   // which fields in context are valid.
123   int context_validity;
124 };
125 
126 struct StackFramePPC64 : public StackFrame {
127   // ContextValidity should eventually contain entries for the validity of
128   // other nonvolatile (callee-save) registers as in
129   // StackFrameX86::ContextValidity, but the ppc stackwalker doesn't currently
130   // locate registers other than the ones listed here.
131   enum ContextValidity {
132     CONTEXT_VALID_NONE = 0,
133     CONTEXT_VALID_SRR0 = 1 << 0,
134     CONTEXT_VALID_GPR1 = 1 << 1,
135     CONTEXT_VALID_ALL  = -1
136   };
137 
StackFramePPC64StackFramePPC64138   StackFramePPC64() : context(), context_validity(CONTEXT_VALID_NONE) {}
139 
140   // Register state.  This is only fully valid for the topmost frame in a
141   // stack.  In other frames, the values of nonvolatile registers may be
142   // present, given sufficient debugging information.  Refer to
143   // context_validity.
144   MDRawContextPPC64 context;
145 
146   // context_validity is actually ContextValidity, but int is used because
147   // the OR operator doesn't work well with enumerated types.  This indicates
148   // which fields in context are valid.
149   int context_validity;
150 };
151 
152 struct StackFrameAMD64 : public StackFrame {
153   // ContextValidity has one entry for each register that we might be able
154   // to recover.
155   enum ContextValidity {
156     CONTEXT_VALID_NONE  = 0,
157     CONTEXT_VALID_RAX   = 1 << 0,
158     CONTEXT_VALID_RDX   = 1 << 1,
159     CONTEXT_VALID_RCX   = 1 << 2,
160     CONTEXT_VALID_RBX   = 1 << 3,
161     CONTEXT_VALID_RSI   = 1 << 4,
162     CONTEXT_VALID_RDI   = 1 << 5,
163     CONTEXT_VALID_RBP   = 1 << 6,
164     CONTEXT_VALID_RSP   = 1 << 7,
165     CONTEXT_VALID_R8    = 1 << 8,
166     CONTEXT_VALID_R9    = 1 << 9,
167     CONTEXT_VALID_R10   = 1 << 10,
168     CONTEXT_VALID_R11   = 1 << 11,
169     CONTEXT_VALID_R12   = 1 << 12,
170     CONTEXT_VALID_R13   = 1 << 13,
171     CONTEXT_VALID_R14   = 1 << 14,
172     CONTEXT_VALID_R15   = 1 << 15,
173     CONTEXT_VALID_RIP   = 1 << 16,
174     CONTEXT_VALID_ALL  = -1
175   };
176 
StackFrameAMD64StackFrameAMD64177   StackFrameAMD64() : context(), context_validity(CONTEXT_VALID_NONE) {}
178 
179   // Overriden to return the return address as saved on the stack.
180   virtual uint64_t ReturnAddress() const;
181 
182   // Register state. This is only fully valid for the topmost frame in a
183   // stack. In other frames, which registers are present depends on what
184   // debugging information we had available. Refer to context_validity.
185   MDRawContextAMD64 context;
186 
187   // For each register in context whose value has been recovered, we set
188   // the corresponding CONTEXT_VALID_ bit in context_validity.
189   //
190   // context_validity's type should actually be ContextValidity, but
191   // we use int instead because the bitwise inclusive or operator
192   // yields an int when applied to enum values, and C++ doesn't
193   // silently convert from ints to enums.
194   int context_validity;
195 };
196 
197 struct StackFrameSPARC : public StackFrame {
198   // to be confirmed
199   enum ContextValidity {
200     CONTEXT_VALID_NONE = 0,
201     CONTEXT_VALID_PC   = 1 << 0,
202     CONTEXT_VALID_SP   = 1 << 1,
203     CONTEXT_VALID_FP   = 1 << 2,
204     CONTEXT_VALID_ALL  = -1
205   };
206 
StackFrameSPARCStackFrameSPARC207   StackFrameSPARC() : context(), context_validity(CONTEXT_VALID_NONE) {}
208 
209   // Register state.  This is only fully valid for the topmost frame in a
210   // stack.  In other frames, the values of nonvolatile registers may be
211   // present, given sufficient debugging information.  Refer to
212   // context_validity.
213   MDRawContextSPARC context;
214 
215   // context_validity is actually ContextValidity, but int is used because
216   // the OR operator doesn't work well with enumerated types.  This indicates
217   // which fields in context are valid.
218   int context_validity;
219 };
220 
221 struct StackFrameARM : public StackFrame {
222   // A flag for each register we might know.
223   enum ContextValidity {
224     CONTEXT_VALID_NONE = 0,
225     CONTEXT_VALID_R0   = 1 << 0,
226     CONTEXT_VALID_R1   = 1 << 1,
227     CONTEXT_VALID_R2   = 1 << 2,
228     CONTEXT_VALID_R3   = 1 << 3,
229     CONTEXT_VALID_R4   = 1 << 4,
230     CONTEXT_VALID_R5   = 1 << 5,
231     CONTEXT_VALID_R6   = 1 << 6,
232     CONTEXT_VALID_R7   = 1 << 7,
233     CONTEXT_VALID_R8   = 1 << 8,
234     CONTEXT_VALID_R9   = 1 << 9,
235     CONTEXT_VALID_R10  = 1 << 10,
236     CONTEXT_VALID_R11  = 1 << 11,
237     CONTEXT_VALID_R12  = 1 << 12,
238     CONTEXT_VALID_R13  = 1 << 13,
239     CONTEXT_VALID_R14  = 1 << 14,
240     CONTEXT_VALID_R15  = 1 << 15,
241     CONTEXT_VALID_ALL  = ~CONTEXT_VALID_NONE,
242 
243     // Aliases for registers with dedicated or conventional roles.
244     CONTEXT_VALID_FP   = CONTEXT_VALID_R11,
245     CONTEXT_VALID_SP   = CONTEXT_VALID_R13,
246     CONTEXT_VALID_LR   = CONTEXT_VALID_R14,
247     CONTEXT_VALID_PC   = CONTEXT_VALID_R15
248   };
249 
StackFrameARMStackFrameARM250   StackFrameARM() : context(), context_validity(CONTEXT_VALID_NONE) {}
251 
252   // Return the ContextValidity flag for register rN.
RegisterValidFlagStackFrameARM253   static ContextValidity RegisterValidFlag(int n) {
254     return ContextValidity(1 << n);
255   }
256 
257   // Register state.  This is only fully valid for the topmost frame in a
258   // stack.  In other frames, the values of nonvolatile registers may be
259   // present, given sufficient debugging information.  Refer to
260   // context_validity.
261   MDRawContextARM context;
262 
263   // For each register in context whose value has been recovered, we set
264   // the corresponding CONTEXT_VALID_ bit in context_validity.
265   //
266   // context_validity's type should actually be ContextValidity, but
267   // we use int instead because the bitwise inclusive or operator
268   // yields an int when applied to enum values, and C++ doesn't
269   // silently convert from ints to enums.
270   int context_validity;
271 };
272 
273 struct StackFrameARM64 : public StackFrame {
274   // A flag for each register we might know. Note that we can't use an enum
275   // here as there are 33 values to represent.
276   static const uint64_t CONTEXT_VALID_NONE = 0;
277   static const uint64_t CONTEXT_VALID_X0   = 1ULL << 0;
278   static const uint64_t CONTEXT_VALID_X1   = 1ULL << 1;
279   static const uint64_t CONTEXT_VALID_X2   = 1ULL << 2;
280   static const uint64_t CONTEXT_VALID_X3   = 1ULL << 3;
281   static const uint64_t CONTEXT_VALID_X4   = 1ULL << 4;
282   static const uint64_t CONTEXT_VALID_X5   = 1ULL << 5;
283   static const uint64_t CONTEXT_VALID_X6   = 1ULL << 6;
284   static const uint64_t CONTEXT_VALID_X7   = 1ULL << 7;
285   static const uint64_t CONTEXT_VALID_X8   = 1ULL << 8;
286   static const uint64_t CONTEXT_VALID_X9   = 1ULL << 9;
287   static const uint64_t CONTEXT_VALID_X10  = 1ULL << 10;
288   static const uint64_t CONTEXT_VALID_X11  = 1ULL << 11;
289   static const uint64_t CONTEXT_VALID_X12  = 1ULL << 12;
290   static const uint64_t CONTEXT_VALID_X13  = 1ULL << 13;
291   static const uint64_t CONTEXT_VALID_X14  = 1ULL << 14;
292   static const uint64_t CONTEXT_VALID_X15  = 1ULL << 15;
293   static const uint64_t CONTEXT_VALID_X16  = 1ULL << 16;
294   static const uint64_t CONTEXT_VALID_X17  = 1ULL << 17;
295   static const uint64_t CONTEXT_VALID_X18  = 1ULL << 18;
296   static const uint64_t CONTEXT_VALID_X19  = 1ULL << 19;
297   static const uint64_t CONTEXT_VALID_X20  = 1ULL << 20;
298   static const uint64_t CONTEXT_VALID_X21  = 1ULL << 21;
299   static const uint64_t CONTEXT_VALID_X22  = 1ULL << 22;
300   static const uint64_t CONTEXT_VALID_X23  = 1ULL << 23;
301   static const uint64_t CONTEXT_VALID_X24  = 1ULL << 24;
302   static const uint64_t CONTEXT_VALID_X25  = 1ULL << 25;
303   static const uint64_t CONTEXT_VALID_X26  = 1ULL << 26;
304   static const uint64_t CONTEXT_VALID_X27  = 1ULL << 27;
305   static const uint64_t CONTEXT_VALID_X28  = 1ULL << 28;
306   static const uint64_t CONTEXT_VALID_X29  = 1ULL << 29;
307   static const uint64_t CONTEXT_VALID_X30  = 1ULL << 30;
308   static const uint64_t CONTEXT_VALID_X31  = 1ULL << 31;
309   static const uint64_t CONTEXT_VALID_X32  = 1ULL << 32;
310   static const uint64_t CONTEXT_VALID_ALL  = ~CONTEXT_VALID_NONE;
311 
312   // Aliases for registers with dedicated or conventional roles.
313   static const uint64_t CONTEXT_VALID_FP   = CONTEXT_VALID_X29;
314   static const uint64_t CONTEXT_VALID_LR   = CONTEXT_VALID_X30;
315   static const uint64_t CONTEXT_VALID_SP   = CONTEXT_VALID_X31;
316   static const uint64_t CONTEXT_VALID_PC   = CONTEXT_VALID_X32;
317 
StackFrameARM64StackFrameARM64318   StackFrameARM64() : context(),
319                       context_validity(CONTEXT_VALID_NONE) {}
320 
321   // Return the validity flag for register xN.
RegisterValidFlagStackFrameARM64322   static uint64_t RegisterValidFlag(int n) {
323     return 1ULL << n;
324   }
325 
326   // Register state.  This is only fully valid for the topmost frame in a
327   // stack.  In other frames, the values of nonvolatile registers may be
328   // present, given sufficient debugging information.  Refer to
329   // context_validity.
330   MDRawContextARM64 context;
331 
332   // For each register in context whose value has been recovered, we set
333   // the corresponding CONTEXT_VALID_ bit in context_validity.
334   uint64_t context_validity;
335 };
336 
337 struct StackFrameMIPS : public StackFrame {
338   // MIPS callee save registers for o32 ABI (32bit registers) are:
339   // 1. $s0-$s7,
340   // 2. $sp, $fp
341   // 3. $f20-$f31
342   //
343   // The register structure is available at
344   // http://en.wikipedia.org/wiki/MIPS_architecture#Compiler_register_usage
345 
346 #define INDEX_MIPS_REG_S0 MD_CONTEXT_MIPS_REG_S0  // 16
347 #define INDEX_MIPS_REG_S7 MD_CONTEXT_MIPS_REG_S7  // 23
348 #define INDEX_MIPS_REG_GP MD_CONTEXT_MIPS_REG_GP  // 28
349 #define INDEX_MIPS_REG_RA MD_CONTEXT_MIPS_REG_RA  // 31
350 #define INDEX_MIPS_REG_PC 34
351 #define SHIFT_MIPS_REG_S0 0
352 #define SHIFT_MIPS_REG_GP 8
353 #define SHIFT_MIPS_REG_PC 12
354 
355   enum ContextValidity {
356     CONTEXT_VALID_NONE = 0,
357     CONTEXT_VALID_S0 = 1 << 0,  // $16
358     CONTEXT_VALID_S1 = 1 << 1,  // $17
359     CONTEXT_VALID_S2 = 1 << 2,  // $18
360     CONTEXT_VALID_S3 = 1 << 3,  // $19
361     CONTEXT_VALID_S4 = 1 << 4,  // $20
362     CONTEXT_VALID_S5 = 1 << 5,  // $21
363     CONTEXT_VALID_S6 = 1 << 6,  // $22
364     CONTEXT_VALID_S7 = 1 << 7,  // $23
365     // GP is not calee-save for o32 abi.
366     CONTEXT_VALID_GP = 1 << 8,  // $28
367     CONTEXT_VALID_SP = 1 << 9,  // $29
368     CONTEXT_VALID_FP = 1 << 10,  // $30
369     CONTEXT_VALID_RA = 1 << 11,  // $31
370     CONTEXT_VALID_PC = 1 << 12,  // $34
371     CONTEXT_VALID_ALL = ~CONTEXT_VALID_NONE
372   };
373 
374   // Return the ContextValidity flag for register rN.
RegisterValidFlagStackFrameMIPS375   static ContextValidity RegisterValidFlag(int n) {
376     if (n >= INDEX_MIPS_REG_S0 && n <= INDEX_MIPS_REG_S7)
377       return ContextValidity(1 << (n - INDEX_MIPS_REG_S0 + SHIFT_MIPS_REG_S0));
378     else if (n >= INDEX_MIPS_REG_GP && n <= INDEX_MIPS_REG_RA)
379       return ContextValidity(1 << (n - INDEX_MIPS_REG_GP + SHIFT_MIPS_REG_GP));
380     else if (n == INDEX_MIPS_REG_PC)
381       return ContextValidity(1 << SHIFT_MIPS_REG_PC);
382 
383     return CONTEXT_VALID_NONE;
384   }
385 
StackFrameMIPSStackFrameMIPS386   StackFrameMIPS() : context(), context_validity(CONTEXT_VALID_NONE) {}
387 
388   // Register state. This is only fully valid for the topmost frame in a
389   // stack. In other frames, which registers are present depends on what
390   // debugging information were available. Refer to 'context_validity' below.
391   MDRawContextMIPS context;
392 
393   // For each register in context whose value has been recovered,
394   // the corresponding CONTEXT_VALID_ bit in 'context_validity' is set.
395   //
396   // context_validity's type should actually be ContextValidity, but
397   // type int is used instead because the bitwise inclusive or operator
398   // yields an int when applied to enum values, and C++ doesn't
399   // silently convert from ints to enums.
400   int context_validity;
401 };
402 
403 }  // namespace google_breakpad
404 
405 #endif  // GOOGLE_BREAKPAD_PROCESSOR_STACK_FRAME_CPU_H__
406