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