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 // Original author: Jim Blandy <jimb@mozilla.com> <jimb@red-bean.com> 33 34 // module.h: Define google_breakpad::Module. A Module holds debugging 35 // information, and can write that information out as a Breakpad 36 // symbol file. 37 38 #ifndef COMMON_LINUX_MODULE_H__ 39 #define COMMON_LINUX_MODULE_H__ 40 41 #include <iostream> 42 #include <limits> 43 #include <map> 44 #include <set> 45 #include <string> 46 #include <vector> 47 48 #include "common/symbol_data.h" 49 #include "common/using_std_string.h" 50 #include "google_breakpad/common/breakpad_types.h" 51 52 namespace google_breakpad { 53 54 using std::set; 55 using std::vector; 56 using std::map; 57 58 // A Module represents the contents of a module, and supports methods 59 // for adding information produced by parsing STABS or DWARF data 60 // --- possibly both from the same file --- and then writing out the 61 // unified contents as a Breakpad-format symbol file. 62 class Module { 63 public: 64 // The type of addresses and sizes in a symbol table. 65 typedef uint64_t Address; 66 static constexpr uint64_t kMaxAddress = std::numeric_limits<Address>::max(); 67 struct File; 68 struct Function; 69 struct Line; 70 struct Extern; 71 72 // Addresses appearing in File, Function, and Line structures are 73 // absolute, not relative to the the module's load address. That 74 // is, if the module were loaded at its nominal load address, the 75 // addresses would be correct. 76 77 // A source file. 78 struct File { FileFile79 explicit File(const string& name_input) : name(name_input), source_id(0) {} 80 81 // The name of the source file. 82 const string name; 83 84 // The file's source id. The Write member function clears this 85 // field and assigns source ids a fresh, so any value placed here 86 // before calling Write will be lost. 87 int source_id; 88 }; 89 90 // An address range. 91 struct Range { RangeRange92 Range(const Address address_input, const Address size_input) : 93 address(address_input), size(size_input) { } 94 95 Address address; 96 Address size; 97 }; 98 99 // A function. 100 struct Function { FunctionFunction101 Function(const string& name_input, const Address& address_input) : 102 name(name_input), address(address_input), parameter_size(0) {} 103 104 // For sorting by address. (Not style-guide compliant, but it's 105 // stupid not to put this in the struct.) CompareByAddressFunction106 static bool CompareByAddress(const Function* x, const Function* y) { 107 return x->address < y->address; 108 } 109 110 // The function's name. 111 string name; 112 113 // The start address and the address ranges covered by the function. 114 const Address address; 115 vector<Range> ranges; 116 117 // The function's parameter size. 118 Address parameter_size; 119 120 // Source lines belonging to this function, sorted by increasing 121 // address. 122 vector<Line> lines; 123 }; 124 125 // A source line. 126 struct Line { 127 // For sorting by address. (Not style-guide compliant, but it's 128 // stupid not to put this in the struct.) CompareByAddressLine129 static bool CompareByAddress(const Module::Line& x, const Module::Line& y) { 130 return x.address < y.address; 131 } 132 133 Address address, size; // The address and size of the line's code. 134 File* file; // The source file. 135 int number; // The source line number. 136 }; 137 138 // An exported symbol. 139 struct Extern { ExternExtern140 explicit Extern(const Address& address_input) : address(address_input) {} 141 const Address address; 142 string name; 143 }; 144 145 // A map from register names to postfix expressions that recover 146 // their their values. This can represent a complete set of rules to 147 // follow at some address, or a set of changes to be applied to an 148 // extant set of rules. 149 typedef map<string, string> RuleMap; 150 151 // A map from addresses to RuleMaps, representing changes that take 152 // effect at given addresses. 153 typedef map<Address, RuleMap> RuleChangeMap; 154 155 // A range of 'STACK CFI' stack walking information. An instance of 156 // this structure corresponds to a 'STACK CFI INIT' record and the 157 // subsequent 'STACK CFI' records that fall within its range. 158 struct StackFrameEntry { 159 // The starting address and number of bytes of machine code this 160 // entry covers. 161 Address address, size; 162 163 // The initial register recovery rules, in force at the starting 164 // address. 165 RuleMap initial_rules; 166 167 // A map from addresses to rule changes. To find the rules in 168 // force at a given address, start with initial_rules, and then 169 // apply the changes given in this map for all addresses up to and 170 // including the address you're interested in. 171 RuleChangeMap rule_changes; 172 }; 173 174 struct FunctionCompare { operatorFunctionCompare175 bool operator() (const Function* lhs, const Function* rhs) const { 176 if (lhs->address == rhs->address) 177 return lhs->name < rhs->name; 178 return lhs->address < rhs->address; 179 } 180 }; 181 182 struct ExternCompare { operatorExternCompare183 bool operator() (const Extern* lhs, const Extern* rhs) const { 184 return lhs->address < rhs->address; 185 } 186 }; 187 188 // Create a new module with the given name, operating system, 189 // architecture, and ID string. 190 Module(const string& name, const string& os, const string& architecture, 191 const string& id, const string& code_id = ""); 192 ~Module(); 193 194 // Set the module's load address to LOAD_ADDRESS; addresses given 195 // for functions and lines will be written to the Breakpad symbol 196 // file as offsets from this address. Construction initializes this 197 // module's load address to zero: addresses written to the symbol 198 // file will be the same as they appear in the Function, Line, and 199 // StackFrameEntry structures. 200 // 201 // Note that this member function has no effect on addresses stored 202 // in the data added to this module; the Write member function 203 // simply subtracts off the load address from addresses before it 204 // prints them. Only the last load address given before calling 205 // Write is used. 206 void SetLoadAddress(Address load_address); 207 208 // Sets address filtering on elements added to the module. This allows 209 // libraries with extraneous debug symbols to generate symbol files containing 210 // only relevant symbols. For example, an LLD-generated partition library may 211 // contain debug information pertaining to all partitions derived from a 212 // single "combined" library. Filtering applies only to elements added after 213 // this method is called. 214 void SetAddressRanges(const vector<Range>& ranges); 215 216 // Add FUNCTION to the module. FUNCTION's name must not be empty. 217 // This module owns all Function objects added with this function: 218 // destroying the module destroys them as well. 219 void AddFunction(Function* function); 220 221 // Add all the functions in [BEGIN,END) to the module. 222 // This module owns all Function objects added with this function: 223 // destroying the module destroys them as well. 224 void AddFunctions(vector<Function*>::iterator begin, 225 vector<Function*>::iterator end); 226 227 // Add STACK_FRAME_ENTRY to the module. 228 // This module owns all StackFrameEntry objects added with this 229 // function: destroying the module destroys them as well. 230 void AddStackFrameEntry(StackFrameEntry* stack_frame_entry); 231 232 // Add PUBLIC to the module. 233 // This module owns all Extern objects added with this function: 234 // destroying the module destroys them as well. 235 void AddExtern(Extern* ext); 236 237 // If this module has a file named NAME, return a pointer to it. If 238 // it has none, then create one and return a pointer to the new 239 // file. This module owns all File objects created using these 240 // functions; destroying the module destroys them as well. 241 File* FindFile(const string& name); 242 File* FindFile(const char* name); 243 244 // If this module has a file named NAME, return a pointer to it. 245 // Otherwise, return NULL. 246 File* FindExistingFile(const string& name); 247 248 // Insert pointers to the functions added to this module at I in 249 // VEC. The pointed-to Functions are still owned by this module. 250 // (Since this is effectively a copy of the function list, this is 251 // mostly useful for testing; other uses should probably get a more 252 // appropriate interface.) 253 void GetFunctions(vector<Function*>* vec, vector<Function*>::iterator i); 254 255 // Insert pointers to the externs added to this module at I in 256 // VEC. The pointed-to Externs are still owned by this module. 257 // (Since this is effectively a copy of the extern list, this is 258 // mostly useful for testing; other uses should probably get a more 259 // appropriate interface.) 260 void GetExterns(vector<Extern*>* vec, vector<Extern*>::iterator i); 261 262 // Clear VEC and fill it with pointers to the Files added to this 263 // module, sorted by name. The pointed-to Files are still owned by 264 // this module. (Since this is effectively a copy of the file list, 265 // this is mostly useful for testing; other uses should probably get 266 // a more appropriate interface.) 267 void GetFiles(vector<File*>* vec); 268 269 // Clear VEC and fill it with pointers to the StackFrameEntry 270 // objects that have been added to this module. (Since this is 271 // effectively a copy of the stack frame entry list, this is mostly 272 // useful for testing; other uses should probably get 273 // a more appropriate interface.) 274 void GetStackFrameEntries(vector<StackFrameEntry*>* vec) const; 275 276 // Find those files in this module that are actually referred to by 277 // functions' line number data, and assign them source id numbers. 278 // Set the source id numbers for all other files --- unused by the 279 // source line data --- to -1. We do this before writing out the 280 // symbol file, at which point we omit any unused files. 281 void AssignSourceIds(); 282 283 // Call AssignSourceIds, and write this module to STREAM in the 284 // breakpad symbol format. Return true if all goes well, or false if 285 // an error occurs. This method writes out: 286 // - a header based on the values given to the constructor, 287 // If symbol_data is not ONLY_CFI then: 288 // - the source files added via FindFile, 289 // - the functions added via AddFunctions, each with its lines, 290 // - all public records, 291 // If symbol_data is not NO_CFI then: 292 // - all CFI records. 293 // Addresses in the output are all relative to the load address 294 // established by SetLoadAddress. 295 bool Write(std::ostream& stream, SymbolData symbol_data); 296 name()297 string name() const { return name_; } os()298 string os() const { return os_; } architecture()299 string architecture() const { return architecture_; } identifier()300 string identifier() const { return id_; } code_identifier()301 string code_identifier() const { return code_id_; } 302 303 private: 304 // Report an error that has occurred writing the symbol file, using 305 // errno to find the appropriate cause. Return false. 306 static bool ReportError(); 307 308 // Write RULE_MAP to STREAM, in the form appropriate for 'STACK CFI' 309 // records, without a final newline. Return true if all goes well; 310 // if an error occurs, return false, and leave errno set. 311 static bool WriteRuleMap(const RuleMap& rule_map, std::ostream& stream); 312 313 // Returns true of the specified address resides with an specified address 314 // range, or if no ranges have been specified. 315 bool AddressIsInModule(Address address) const; 316 317 // Module header entries. 318 string name_, os_, architecture_, id_, code_id_; 319 320 // The module's nominal load address. Addresses for functions and 321 // lines are absolute, assuming the module is loaded at this 322 // address. 323 Address load_address_; 324 325 // The set of valid address ranges of the module. If specified, attempts to 326 // add elements residing outside these ranges will be silently filtered. 327 vector<Range> address_ranges_; 328 329 // Relation for maps whose keys are strings shared with some other 330 // structure. 331 struct CompareStringPtrs { operatorCompareStringPtrs332 bool operator()(const string* x, const string* y) const { return *x < *y; } 333 }; 334 335 // A map from filenames to File structures. The map's keys are 336 // pointers to the Files' names. 337 typedef map<const string*, File*, CompareStringPtrs> FileByNameMap; 338 339 // A set containing Function structures, sorted by address. 340 typedef set<Function*, FunctionCompare> FunctionSet; 341 342 // A set containing Extern structures, sorted by address. 343 typedef set<Extern*, ExternCompare> ExternSet; 344 345 // The module owns all the files and functions that have been added 346 // to it; destroying the module frees the Files and Functions these 347 // point to. 348 FileByNameMap files_; // This module's source files. 349 FunctionSet functions_; // This module's functions. 350 351 // The module owns all the call frame info entries that have been 352 // added to it. 353 vector<StackFrameEntry*> stack_frame_entries_; 354 355 // The module owns all the externs that have been added to it; 356 // destroying the module frees the Externs these point to. 357 ExternSet externs_; 358 }; 359 360 } // namespace google_breakpad 361 362 #endif // COMMON_LINUX_MODULE_H__ 363