/ src / google_breakpad / processor / stack_frame_cpu.h
stack_frame_cpu.h
  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  
 72    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  
111    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  
137    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  
176    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  
206    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  
249    StackFrameARM() : context(), context_validity(CONTEXT_VALID_NONE) {}
250  
251    // Return the ContextValidity flag for register rN.
252    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  
320    StackFrameARM64() : context(),
321                        context_validity(CONTEXT_VALID_NONE) {}
322  
323    // Return the validity flag for register xN.
324    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.
377    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  
388    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  
444    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  
500    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__