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