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 // basic_source_line_types.h: definition of nested classes/structs in 30 // BasicSourceLineResolver. It moves the definitions out of 31 // basic_source_line_resolver.cc, so that other classes could have access 32 // to these private nested types without including basic_source_line_resolver.cc 33 // 34 // Author: Siyang Xie ([email protected]) 35 36 #ifndef PROCESSOR_BASIC_SOURCE_LINE_RESOLVER_TYPES_H__ 37 #define PROCESSOR_BASIC_SOURCE_LINE_RESOLVER_TYPES_H__ 38 39 #include <map> 40 #include <string> 41 42 #include "common/scoped_ptr.h" 43 #include "google_breakpad/processor/basic_source_line_resolver.h" 44 #include "processor/source_line_resolver_base_types.h" 45 46 #include "processor/address_map-inl.h" 47 #include "processor/range_map-inl.h" 48 #include "processor/contained_range_map-inl.h" 49 50 #include "processor/linked_ptr.h" 51 #include "google_breakpad/processor/stack_frame.h" 52 #include "processor/cfi_frame_info.h" 53 #include "processor/windows_frame_info.h" 54 55 namespace google_breakpad { 56 57 struct 58 BasicSourceLineResolver::Function : public SourceLineResolverBase::Function { FunctionFunction59 Function(const string& function_name, 60 MemAddr function_address, 61 MemAddr code_size, 62 int set_parameter_size, 63 bool is_mutiple) 64 : Base(function_name, 65 function_address, 66 code_size, 67 set_parameter_size, 68 is_mutiple), 69 inlines(true), 70 last_added_inline_nest_level(0) {} 71 72 // Append inline into corresponding RangeMap. 73 // This function assumes it's called in the order of reading INLINE records. 74 bool AppendInline(linked_ptr<Inline> in); 75 76 ContainedRangeMap<MemAddr, linked_ptr<Inline>> inlines; 77 RangeMap<MemAddr, linked_ptr<Line>> lines; 78 79 private: 80 typedef SourceLineResolverBase::Function Base; 81 82 // The last added inline_nest_level from INLINE record. 83 int last_added_inline_nest_level; 84 }; 85 86 87 class BasicSourceLineResolver::Module : public SourceLineResolverBase::Module { 88 public: Module(const string & name)89 explicit Module(const string& name) : name_(name), is_corrupt_(false) { } ~Module()90 virtual ~Module() { } 91 92 // Loads a map from the given buffer in char* type. 93 // Does NOT have ownership of memory_buffer. 94 // The passed in |memory buffer| is of size |memory_buffer_size|. If it is 95 // not null terminated, LoadMapFromMemory() will null terminate it by 96 // modifying the passed in buffer. 97 virtual bool LoadMapFromMemory(char* memory_buffer, 98 size_t memory_buffer_size); 99 100 // Tells whether the loaded symbol data is corrupt. Return value is 101 // undefined, if the symbol data hasn't been loaded yet. IsCorrupt()102 virtual bool IsCorrupt() const { return is_corrupt_; } 103 104 // Looks up the given relative address, and fills the StackFrame struct 105 // with the result. 106 virtual void LookupAddress( 107 StackFrame* frame, 108 std::deque<std::unique_ptr<StackFrame>>* inlined_frame) const; 109 110 // Construct inlined frames for |frame| and store them in |inline_frames|. 111 // |frame|'s source line and source file name may be updated if an inlined 112 // frame is found inside |frame|. As a result, the innermost inlined frame 113 // will be the first one in |inline_frames|. 114 virtual void ConstructInlineFrames( 115 StackFrame* frame, 116 MemAddr address, 117 const ContainedRangeMap<uint64_t, linked_ptr<Inline>>& inline_map, 118 std::deque<std::unique_ptr<StackFrame>>* inline_frames) const; 119 120 // If Windows stack walking information is available covering ADDRESS, 121 // return a WindowsFrameInfo structure describing it. If the information 122 // is not available, returns NULL. A NULL return value does not indicate 123 // an error. The caller takes ownership of any returned WindowsFrameInfo 124 // object. 125 virtual WindowsFrameInfo* FindWindowsFrameInfo(const StackFrame* frame) const; 126 127 // If CFI stack walking information is available covering ADDRESS, 128 // return a CFIFrameInfo structure describing it. If the information 129 // is not available, return NULL. The caller takes ownership of any 130 // returned CFIFrameInfo object. 131 virtual CFIFrameInfo* FindCFIFrameInfo(const StackFrame* frame) const; 132 133 private: 134 // Friend declarations. 135 friend class BasicSourceLineResolver; 136 friend class ModuleComparer; 137 friend class ModuleSerializer; 138 139 typedef std::map<int, string> FileMap; 140 141 // Logs parse errors. |*num_errors| is increased every time LogParseError is 142 // called. 143 static void LogParseError( 144 const string& message, 145 int line_number, 146 int* num_errors); 147 148 // Parses a file declaration 149 bool ParseFile(char* file_line); 150 151 // Parses an inline origin declaration. 152 bool ParseInlineOrigin(char* inline_origin_line); 153 154 // Parses an inline declaration. 155 linked_ptr<Inline> ParseInline(char* inline_line); 156 157 // Parses a function declaration, returning a new Function object. 158 Function* ParseFunction(char* function_line); 159 160 // Parses a line declaration, returning a new Line object. 161 Line* ParseLine(char* line_line); 162 163 // Parses a PUBLIC symbol declaration, storing it in public_symbols_. 164 // Returns false if an error occurs. 165 bool ParsePublicSymbol(char* public_line); 166 167 // Parses a STACK WIN or STACK CFI frame info declaration, storing 168 // it in the appropriate table. 169 bool ParseStackInfo(char* stack_info_line); 170 171 // Parses a STACK CFI record, storing it in cfi_frame_info_. 172 bool ParseCFIFrameInfo(char* stack_info_line); 173 174 string name_; 175 FileMap files_; 176 std::map<int, linked_ptr<InlineOrigin>> inline_origins_; 177 RangeMap< MemAddr, linked_ptr<Function> > functions_; 178 AddressMap< MemAddr, linked_ptr<PublicSymbol> > public_symbols_; 179 bool is_corrupt_; 180 181 // Each element in the array is a ContainedRangeMap for a type 182 // listed in WindowsFrameInfoTypes. These are split by type because 183 // there may be overlaps between maps of different types, but some 184 // information is only available as certain types. 185 ContainedRangeMap< MemAddr, linked_ptr<WindowsFrameInfo> > 186 windows_frame_info_[WindowsFrameInfo::STACK_INFO_LAST]; 187 188 // DWARF CFI stack walking data. The Module stores the initial rule sets 189 // and rule deltas as strings, just as they appear in the symbol file: 190 // although the file may contain hundreds of thousands of STACK CFI 191 // records, walking a stack will only ever use a few of them, so it's 192 // best to delay parsing a record until it's actually needed. 193 194 // STACK CFI INIT records: for each range, an initial set of register 195 // recovery rules. The RangeMap's itself gives the starting and ending 196 // addresses. 197 RangeMap<MemAddr, string> cfi_initial_rules_; 198 199 // STACK CFI records: at a given address, the changes to the register 200 // recovery rules that take effect at that address. The map key is the 201 // starting address; the ending address is the key of the next entry in 202 // this map, or the end of the range as given by the cfi_initial_rules_ 203 // entry (which FindCFIFrameInfo looks up first). 204 std::map<MemAddr, string> cfi_delta_rules_; 205 }; 206 207 } // namespace google_breakpad 208 209 #endif // PROCESSOR_BASIC_SOURCE_LINE_RESOLVER_TYPES_H__ 210