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