1 // Copyright 2010 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 // source_line_resolver_base_types.h: definition of nested classes/structs in 30 // SourceLineResolverBase. It moves the definitions out of 31 // source_line_resolver_base.cc, so that other classes may have access 32 // to these private nested types without including source_line_resolver_base.cc 33 // In addition, Module is defined as a pure abstract class to be implemented by 34 // each concrete source line resolver class. 35 // 36 // See source_line_resolver_base.h for more documentation. 37 // 38 // Author: Siyang Xie ([email protected]) 39 40 #include <stdio.h> 41 42 #include <deque> 43 #include <map> 44 #include <memory> 45 #include <string> 46 47 #include "google_breakpad/common/breakpad_types.h" 48 #include "google_breakpad/processor/source_line_resolver_base.h" 49 #include "google_breakpad/processor/stack_frame.h" 50 #include "processor/cfi_frame_info.h" 51 #include "processor/linked_ptr.h" 52 #include "processor/range_map.h" 53 #include "processor/windows_frame_info.h" 54 55 #ifndef PROCESSOR_SOURCE_LINE_RESOLVER_BASE_TYPES_H__ 56 #define PROCESSOR_SOURCE_LINE_RESOLVER_BASE_TYPES_H__ 57 58 namespace google_breakpad { 59 60 class SourceLineResolverBase::AutoFileCloser { 61 public: AutoFileCloser(FILE * file)62 explicit AutoFileCloser(FILE* file) : file_(file) {} ~AutoFileCloser()63 ~AutoFileCloser() { 64 if (file_) 65 fclose(file_); 66 } 67 68 private: 69 FILE* file_; 70 }; 71 72 struct SourceLineResolverBase::InlineOrigin { InlineOriginInlineOrigin73 InlineOrigin() {} InlineOriginInlineOrigin74 InlineOrigin(bool has_file_id, int32_t source_file_id, const string& name) 75 : has_file_id(has_file_id), 76 source_file_id(source_file_id), 77 name(name) {} 78 // If it's old format, source file id is set, otherwise not useful. 79 bool has_file_id; 80 int32_t source_file_id; 81 string name; 82 }; 83 84 struct SourceLineResolverBase::Inline { 85 // A vector of (address, size) pair for a INLINE record. 86 using InlineRanges = std::vector<std::pair<MemAddr, MemAddr>>; InlineInline87 Inline() {} InlineInline88 Inline(bool has_call_site_file_id, 89 int32_t inline_nest_level, 90 int32_t call_site_line, 91 int32_t call_site_file_id, 92 int32_t origin_id, 93 InlineRanges inline_ranges) 94 : has_call_site_file_id(has_call_site_file_id), 95 inline_nest_level(inline_nest_level), 96 call_site_line(call_site_line), 97 call_site_file_id(call_site_file_id), 98 origin_id(origin_id), 99 inline_ranges(inline_ranges) {} 100 // If it's new format, call site file id is set, otherwise not useful. 101 bool has_call_site_file_id; 102 int32_t inline_nest_level; 103 int32_t call_site_line; 104 int32_t call_site_file_id; 105 int32_t origin_id; 106 InlineRanges inline_ranges; 107 }; 108 109 struct SourceLineResolverBase::Line { LineLine110 Line() { } LineLine111 Line(MemAddr addr, MemAddr code_size, int file_id, int source_line) 112 : address(addr) 113 , size(code_size) 114 , source_file_id(file_id) 115 , line(source_line) { } 116 117 MemAddr address; 118 MemAddr size; 119 int32_t source_file_id; 120 int32_t line; 121 }; 122 123 struct SourceLineResolverBase::Function { FunctionFunction124 Function() { } FunctionFunction125 Function(const string& function_name, 126 MemAddr function_address, 127 MemAddr code_size, 128 int set_parameter_size, 129 bool is_multiple) 130 : name(function_name), address(function_address), size(code_size), 131 parameter_size(set_parameter_size), is_multiple(is_multiple) { } 132 133 string name; 134 MemAddr address; 135 MemAddr size; 136 137 // The size of parameters passed to this function on the stack. 138 int32_t parameter_size; 139 140 // If the function's instructions correspond to multiple symbols. 141 bool is_multiple; 142 }; 143 144 struct SourceLineResolverBase::PublicSymbol { PublicSymbolPublicSymbol145 PublicSymbol() { } PublicSymbolPublicSymbol146 PublicSymbol(const string& set_name, 147 MemAddr set_address, 148 int set_parameter_size, 149 bool is_multiple) 150 : name(set_name), 151 address(set_address), 152 parameter_size(set_parameter_size), 153 is_multiple(is_multiple) {} 154 155 string name; 156 MemAddr address; 157 158 // If the public symbol is used as a function entry point, parameter_size 159 // is set to the size of the parameters passed to the funciton on the 160 // stack, if known. 161 int32_t parameter_size; 162 163 // If the function's instructions correspond to multiple symbols. 164 bool is_multiple; 165 }; 166 167 class SourceLineResolverBase::Module { 168 public: ~Module()169 virtual ~Module() { }; 170 // Loads a map from the given buffer in char* type. 171 // Does NOT take ownership of memory_buffer (the caller, source line resolver, 172 // is the owner of memory_buffer). 173 // The passed in |memory buffer| is of size |memory_buffer_size|. If it is 174 // not null terminated, LoadMapFromMemory will null terminate it by modifying 175 // the passed in buffer. 176 virtual bool LoadMapFromMemory(char* memory_buffer, 177 size_t memory_buffer_size) = 0; 178 179 // Tells whether the loaded symbol data is corrupt. Return value is 180 // undefined, if the symbol data hasn't been loaded yet. 181 virtual bool IsCorrupt() const = 0; 182 183 // Looks up the given relative address, and fills the StackFrame struct 184 // with the result. 185 virtual void LookupAddress( 186 StackFrame* frame, 187 std::deque<std::unique_ptr<StackFrame>>* inlined_frames) const = 0; 188 189 // If Windows stack walking information is available covering ADDRESS, 190 // return a WindowsFrameInfo structure describing it. If the information 191 // is not available, returns NULL. A NULL return value does not indicate 192 // an error. The caller takes ownership of any returned WindowsFrameInfo 193 // object. 194 virtual WindowsFrameInfo* 195 FindWindowsFrameInfo(const StackFrame* frame) const = 0; 196 197 // If CFI stack walking information is available covering ADDRESS, 198 // return a CFIFrameInfo structure describing it. If the information 199 // is not available, return NULL. The caller takes ownership of any 200 // returned CFIFrameInfo object. 201 virtual CFIFrameInfo* FindCFIFrameInfo(const StackFrame* frame) const = 0; 202 protected: 203 virtual bool ParseCFIRuleSet(const string& rule_set, 204 CFIFrameInfo* frame_info) const; 205 }; 206 207 } // namespace google_breakpad 208 209 #endif // PROCESSOR_SOURCE_LINE_RESOLVER_BASE_TYPES_H__ 210