1 // Copyright (c) 2006, Google Inc. 2 // All rights reserved. 3 // 4 // Redistribution and use in source and binary forms, with or without 5 // modification, are permitted provided that the following conditions are 6 // met: 7 // 8 // * Redistributions of source code must retain the above copyright 9 // notice, this list of conditions and the following disclaimer. 10 // * Redistributions in binary form must reproduce the above 11 // copyright notice, this list of conditions and the following disclaimer 12 // in the documentation and/or other materials provided with the 13 // distribution. 14 // * Neither the name of Google Inc. nor the names of its 15 // contributors may be used to endorse or promote products derived from 16 // this software without specific prior written permission. 17 // 18 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 30 // windows_frame_info.h: Holds debugging information about a stack frame. 31 // 32 // This structure is specific to Windows debugging information obtained 33 // from pdb files using the DIA API. 34 // 35 // Author: Mark Mentovai 36 37 38 #ifndef PROCESSOR_WINDOWS_FRAME_INFO_H__ 39 #define PROCESSOR_WINDOWS_FRAME_INFO_H__ 40 41 #include <string.h> 42 #include <stdlib.h> 43 44 #include <string> 45 #include <vector> 46 47 #include "common/using_std_string.h" 48 #include "google_breakpad/common/breakpad_types.h" 49 #include "processor/logging.h" 50 #include "processor/tokenize.h" 51 52 namespace google_breakpad { 53 54 #ifdef _WIN32 55 #define strtoull _strtoui64 56 #endif 57 58 struct WindowsFrameInfo { 59 public: 60 enum Validity { 61 VALID_NONE = 0, 62 VALID_PARAMETER_SIZE = 1, 63 VALID_ALL = -1 64 }; 65 66 // The types for stack_info_. This is equivalent to MS DIA's 67 // StackFrameTypeEnum. Each identifies a different type of frame 68 // information, although all are represented in the symbol file in the 69 // same format. These are used as indices to the stack_info_ array. 70 enum StackInfoTypes { 71 STACK_INFO_FPO = 0, 72 STACK_INFO_TRAP, // not used here 73 STACK_INFO_TSS, // not used here 74 STACK_INFO_STANDARD, 75 STACK_INFO_FRAME_DATA, 76 STACK_INFO_LAST, // must be the last sequentially-numbered item 77 STACK_INFO_UNKNOWN = -1 78 }; 79 WindowsFrameInfoWindowsFrameInfo80 WindowsFrameInfo() : type_(STACK_INFO_UNKNOWN), 81 valid(VALID_NONE), 82 prolog_size(0), 83 epilog_size(0), 84 parameter_size(0), 85 saved_register_size(0), 86 local_size(0), 87 max_stack_size(0), 88 allocates_base_pointer(0), 89 program_string() {} 90 WindowsFrameInfoWindowsFrameInfo91 WindowsFrameInfo(StackInfoTypes type, 92 uint32_t set_prolog_size, 93 uint32_t set_epilog_size, 94 uint32_t set_parameter_size, 95 uint32_t set_saved_register_size, 96 uint32_t set_local_size, 97 uint32_t set_max_stack_size, 98 int set_allocates_base_pointer, 99 const string set_program_string) 100 : type_(type), 101 valid(VALID_ALL), 102 prolog_size(set_prolog_size), 103 epilog_size(set_epilog_size), 104 parameter_size(set_parameter_size), 105 saved_register_size(set_saved_register_size), 106 local_size(set_local_size), 107 max_stack_size(set_max_stack_size), 108 allocates_base_pointer(set_allocates_base_pointer), 109 program_string(set_program_string) {} 110 111 // Parse a textual serialization of a WindowsFrameInfo object from 112 // a string. Returns NULL if parsing fails, or a new object 113 // otherwise. type, rva and code_size are present in the STACK line, 114 // but not the StackFrameInfo structure, so return them as outparams. ParseFromStringWindowsFrameInfo115 static WindowsFrameInfo *ParseFromString(const string string, 116 int &type, 117 uint64_t &rva, 118 uint64_t &code_size) { 119 // The format of a STACK WIN record is documented at: 120 // 121 // http://code.google.com/p/google-breakpad/wiki/SymbolFiles 122 123 std::vector<char> buffer; 124 StringToVector(string, buffer); 125 std::vector<char*> tokens; 126 if (!Tokenize(&buffer[0], " \r\n", 11, &tokens)) 127 return NULL; 128 129 type = strtol(tokens[0], NULL, 16); 130 if (type < 0 || type > STACK_INFO_LAST - 1) 131 return NULL; 132 133 rva = strtoull(tokens[1], NULL, 16); 134 code_size = strtoull(tokens[2], NULL, 16); 135 uint32_t prolog_size = strtoul(tokens[3], NULL, 16); 136 uint32_t epilog_size = strtoul(tokens[4], NULL, 16); 137 uint32_t parameter_size = strtoul(tokens[5], NULL, 16); 138 uint32_t saved_register_size = strtoul(tokens[6], NULL, 16); 139 uint32_t local_size = strtoul(tokens[7], NULL, 16); 140 uint32_t max_stack_size = strtoul(tokens[8], NULL, 16); 141 int has_program_string = strtoul(tokens[9], NULL, 16); 142 143 const char *program_string = ""; 144 int allocates_base_pointer = 0; 145 if (has_program_string) { 146 program_string = tokens[10]; 147 } else { 148 allocates_base_pointer = strtoul(tokens[10], NULL, 16); 149 } 150 151 return new WindowsFrameInfo(static_cast<StackInfoTypes>(type), 152 prolog_size, 153 epilog_size, 154 parameter_size, 155 saved_register_size, 156 local_size, 157 max_stack_size, 158 allocates_base_pointer, 159 program_string); 160 } 161 162 // CopyFrom makes "this" WindowsFrameInfo object identical to "that". CopyFromWindowsFrameInfo163 void CopyFrom(const WindowsFrameInfo &that) { 164 type_ = that.type_; 165 valid = that.valid; 166 prolog_size = that.prolog_size; 167 epilog_size = that.epilog_size; 168 parameter_size = that.parameter_size; 169 saved_register_size = that.saved_register_size; 170 local_size = that.local_size; 171 max_stack_size = that.max_stack_size; 172 allocates_base_pointer = that.allocates_base_pointer; 173 program_string = that.program_string; 174 } 175 176 // Clears the WindowsFrameInfo object so that users will see it as though 177 // it contains no information. ClearWindowsFrameInfo178 void Clear() { 179 type_ = STACK_INFO_UNKNOWN; 180 valid = VALID_NONE; 181 program_string.erase(); 182 } 183 184 StackInfoTypes type_; 185 186 // Identifies which fields in the structure are valid. This is of 187 // type Validity, but it is defined as an int because it's not 188 // possible to OR values into an enumerated type. Users must check 189 // this field before using any other. 190 int valid; 191 192 // These values come from IDiaFrameData. 193 uint32_t prolog_size; 194 uint32_t epilog_size; 195 uint32_t parameter_size; 196 uint32_t saved_register_size; 197 uint32_t local_size; 198 uint32_t max_stack_size; 199 200 // Only one of allocates_base_pointer or program_string will be valid. 201 // If program_string is empty, use allocates_base_pointer. 202 bool allocates_base_pointer; 203 string program_string; 204 }; 205 206 } // namespace google_breakpad 207 208 209 #endif // PROCESSOR_WINDOWS_FRAME_INFO_H__ 210