Home | History | Annotate | Download | only in processor
      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 
     73   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 
    112   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 
    138   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 
    177   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 
    207   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 
    250   StackFrameARM() : context(), context_validity(CONTEXT_VALID_NONE) {}
    251 
    252   // Return the ContextValidity flag for register rN.
    253   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 
    318   StackFrameARM64() : context(),
    319                       context_validity(CONTEXT_VALID_NONE) {}
    320 
    321   // Return the validity flag for register xN.
    322   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.
    375   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 
    386   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