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