1*9712c20fSFrederick Mayle // -*- mode: c++ -*- 2*9712c20fSFrederick Mayle 3*9712c20fSFrederick Mayle // Copyright 2010 Google LLC 4*9712c20fSFrederick Mayle // 5*9712c20fSFrederick Mayle // Redistribution and use in source and binary forms, with or without 6*9712c20fSFrederick Mayle // modification, are permitted provided that the following conditions are 7*9712c20fSFrederick Mayle // met: 8*9712c20fSFrederick Mayle // 9*9712c20fSFrederick Mayle // * Redistributions of source code must retain the above copyright 10*9712c20fSFrederick Mayle // notice, this list of conditions and the following disclaimer. 11*9712c20fSFrederick Mayle // * Redistributions in binary form must reproduce the above 12*9712c20fSFrederick Mayle // copyright notice, this list of conditions and the following disclaimer 13*9712c20fSFrederick Mayle // in the documentation and/or other materials provided with the 14*9712c20fSFrederick Mayle // distribution. 15*9712c20fSFrederick Mayle // * Neither the name of Google LLC nor the names of its 16*9712c20fSFrederick Mayle // contributors may be used to endorse or promote products derived from 17*9712c20fSFrederick Mayle // this software without specific prior written permission. 18*9712c20fSFrederick Mayle // 19*9712c20fSFrederick Mayle // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 20*9712c20fSFrederick Mayle // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 21*9712c20fSFrederick Mayle // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 22*9712c20fSFrederick Mayle // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 23*9712c20fSFrederick Mayle // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 24*9712c20fSFrederick Mayle // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 25*9712c20fSFrederick Mayle // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 26*9712c20fSFrederick Mayle // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 27*9712c20fSFrederick Mayle // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 28*9712c20fSFrederick Mayle // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 29*9712c20fSFrederick Mayle // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30*9712c20fSFrederick Mayle 31*9712c20fSFrederick Mayle // Original author: Jim Blandy <[email protected]> <[email protected]> 32*9712c20fSFrederick Mayle 33*9712c20fSFrederick Mayle // module.h: Define google_breakpad::Module. A Module holds debugging 34*9712c20fSFrederick Mayle // information, and can write that information out as a Breakpad 35*9712c20fSFrederick Mayle // symbol file. 36*9712c20fSFrederick Mayle 37*9712c20fSFrederick Mayle #ifndef COMMON_LINUX_MODULE_H__ 38*9712c20fSFrederick Mayle #define COMMON_LINUX_MODULE_H__ 39*9712c20fSFrederick Mayle 40*9712c20fSFrederick Mayle #include <functional> 41*9712c20fSFrederick Mayle #include <iostream> 42*9712c20fSFrederick Mayle #include <limits> 43*9712c20fSFrederick Mayle #include <map> 44*9712c20fSFrederick Mayle #include <memory> 45*9712c20fSFrederick Mayle #include <set> 46*9712c20fSFrederick Mayle #include <string> 47*9712c20fSFrederick Mayle #include <vector> 48*9712c20fSFrederick Mayle 49*9712c20fSFrederick Mayle #include "common/string_view.h" 50*9712c20fSFrederick Mayle #include "common/symbol_data.h" 51*9712c20fSFrederick Mayle #include "common/unordered.h" 52*9712c20fSFrederick Mayle #include "common/using_std_string.h" 53*9712c20fSFrederick Mayle #include "google_breakpad/common/breakpad_types.h" 54*9712c20fSFrederick Mayle 55*9712c20fSFrederick Mayle namespace google_breakpad { 56*9712c20fSFrederick Mayle 57*9712c20fSFrederick Mayle using std::set; 58*9712c20fSFrederick Mayle using std::vector; 59*9712c20fSFrederick Mayle using std::map; 60*9712c20fSFrederick Mayle 61*9712c20fSFrederick Mayle // A Module represents the contents of a module, and supports methods 62*9712c20fSFrederick Mayle // for adding information produced by parsing STABS or DWARF data 63*9712c20fSFrederick Mayle // --- possibly both from the same file --- and then writing out the 64*9712c20fSFrederick Mayle // unified contents as a Breakpad-format symbol file. 65*9712c20fSFrederick Mayle class Module { 66*9712c20fSFrederick Mayle public: 67*9712c20fSFrederick Mayle // The type of addresses and sizes in a symbol table. 68*9712c20fSFrederick Mayle typedef uint64_t Address; 69*9712c20fSFrederick Mayle static constexpr uint64_t kMaxAddress = std::numeric_limits<Address>::max(); 70*9712c20fSFrederick Mayle struct File; 71*9712c20fSFrederick Mayle struct Function; 72*9712c20fSFrederick Mayle struct InlineOrigin; 73*9712c20fSFrederick Mayle struct Inline; 74*9712c20fSFrederick Mayle struct Line; 75*9712c20fSFrederick Mayle struct Extern; 76*9712c20fSFrederick Mayle 77*9712c20fSFrederick Mayle // Addresses appearing in File, Function, and Line structures are 78*9712c20fSFrederick Mayle // absolute, not relative to the the module's load address. That 79*9712c20fSFrederick Mayle // is, if the module were loaded at its nominal load address, the 80*9712c20fSFrederick Mayle // addresses would be correct. 81*9712c20fSFrederick Mayle 82*9712c20fSFrederick Mayle // A source file. 83*9712c20fSFrederick Mayle struct File { FileFile84*9712c20fSFrederick Mayle explicit File(const string& name_input) : name(name_input), source_id(0) {} 85*9712c20fSFrederick Mayle 86*9712c20fSFrederick Mayle // The name of the source file. 87*9712c20fSFrederick Mayle const string name; 88*9712c20fSFrederick Mayle 89*9712c20fSFrederick Mayle // The file's source id. The Write member function clears this 90*9712c20fSFrederick Mayle // field and assigns source ids a fresh, so any value placed here 91*9712c20fSFrederick Mayle // before calling Write will be lost. 92*9712c20fSFrederick Mayle int source_id; 93*9712c20fSFrederick Mayle }; 94*9712c20fSFrederick Mayle 95*9712c20fSFrederick Mayle // An address range. 96*9712c20fSFrederick Mayle struct Range { RangeRange97*9712c20fSFrederick Mayle Range(const Address address_input, const Address size_input) : 98*9712c20fSFrederick Mayle address(address_input), size(size_input) { } 99*9712c20fSFrederick Mayle 100*9712c20fSFrederick Mayle Address address; 101*9712c20fSFrederick Mayle Address size; 102*9712c20fSFrederick Mayle }; 103*9712c20fSFrederick Mayle 104*9712c20fSFrederick Mayle // A function. 105*9712c20fSFrederick Mayle struct Function { FunctionFunction106*9712c20fSFrederick Mayle Function(StringView name_input, const Address& address_input) : 107*9712c20fSFrederick Mayle name(name_input), address(address_input), parameter_size(0) {} 108*9712c20fSFrederick Mayle 109*9712c20fSFrederick Mayle // For sorting by address. (Not style-guide compliant, but it's 110*9712c20fSFrederick Mayle // stupid not to put this in the struct.) CompareByAddressFunction111*9712c20fSFrederick Mayle static bool CompareByAddress(const Function* x, const Function* y) { 112*9712c20fSFrederick Mayle return x->address < y->address; 113*9712c20fSFrederick Mayle } 114*9712c20fSFrederick Mayle 115*9712c20fSFrederick Mayle // The function's name. 116*9712c20fSFrederick Mayle StringView name; 117*9712c20fSFrederick Mayle 118*9712c20fSFrederick Mayle // The start address and the address ranges covered by the function. 119*9712c20fSFrederick Mayle const Address address; 120*9712c20fSFrederick Mayle vector<Range> ranges; 121*9712c20fSFrederick Mayle 122*9712c20fSFrederick Mayle // The function's parameter size. 123*9712c20fSFrederick Mayle Address parameter_size; 124*9712c20fSFrederick Mayle 125*9712c20fSFrederick Mayle // Source lines belonging to this function, sorted by increasing 126*9712c20fSFrederick Mayle // address. 127*9712c20fSFrederick Mayle vector<Line> lines; 128*9712c20fSFrederick Mayle 129*9712c20fSFrederick Mayle // Inlined call sites belonging to this functions. 130*9712c20fSFrederick Mayle vector<std::unique_ptr<Inline>> inlines; 131*9712c20fSFrederick Mayle 132*9712c20fSFrederick Mayle // If this symbol has been folded with other symbols in the linked binary. 133*9712c20fSFrederick Mayle bool is_multiple = false; 134*9712c20fSFrederick Mayle 135*9712c20fSFrederick Mayle // If the function's name should be filled out from a matching Extern, 136*9712c20fSFrederick Mayle // should they not match. 137*9712c20fSFrederick Mayle bool prefer_extern_name = false; 138*9712c20fSFrederick Mayle }; 139*9712c20fSFrederick Mayle 140*9712c20fSFrederick Mayle struct InlineOrigin { InlineOriginInlineOrigin141*9712c20fSFrederick Mayle explicit InlineOrigin(StringView name) : id(-1), name(name) {} 142*9712c20fSFrederick Mayle 143*9712c20fSFrederick Mayle // A unique id for each InlineOrigin object. INLINE records use the id to 144*9712c20fSFrederick Mayle // refer to its INLINE_ORIGIN record. 145*9712c20fSFrederick Mayle int id; 146*9712c20fSFrederick Mayle 147*9712c20fSFrederick Mayle // The inlined function's name. 148*9712c20fSFrederick Mayle StringView name; 149*9712c20fSFrederick Mayle }; 150*9712c20fSFrederick Mayle 151*9712c20fSFrederick Mayle // A inlined call site. 152*9712c20fSFrederick Mayle struct Inline { InlineInline153*9712c20fSFrederick Mayle Inline(InlineOrigin* origin, 154*9712c20fSFrederick Mayle const vector<Range>& ranges, 155*9712c20fSFrederick Mayle int call_site_line, 156*9712c20fSFrederick Mayle int call_site_file_id, 157*9712c20fSFrederick Mayle int inline_nest_level, 158*9712c20fSFrederick Mayle vector<std::unique_ptr<Inline>> child_inlines) 159*9712c20fSFrederick Mayle : origin(origin), 160*9712c20fSFrederick Mayle ranges(ranges), 161*9712c20fSFrederick Mayle call_site_line(call_site_line), 162*9712c20fSFrederick Mayle call_site_file_id(call_site_file_id), 163*9712c20fSFrederick Mayle call_site_file(nullptr), 164*9712c20fSFrederick Mayle inline_nest_level(inline_nest_level), 165*9712c20fSFrederick Mayle child_inlines(std::move(child_inlines)) {} 166*9712c20fSFrederick Mayle 167*9712c20fSFrederick Mayle InlineOrigin* origin; 168*9712c20fSFrederick Mayle 169*9712c20fSFrederick Mayle // The list of addresses and sizes. 170*9712c20fSFrederick Mayle vector<Range> ranges; 171*9712c20fSFrederick Mayle 172*9712c20fSFrederick Mayle int call_site_line; 173*9712c20fSFrederick Mayle 174*9712c20fSFrederick Mayle // The id is only meanful inside a CU. It's only used for looking up real 175*9712c20fSFrederick Mayle // File* after scanning a CU. 176*9712c20fSFrederick Mayle int call_site_file_id; 177*9712c20fSFrederick Mayle 178*9712c20fSFrederick Mayle File* call_site_file; 179*9712c20fSFrederick Mayle 180*9712c20fSFrederick Mayle int inline_nest_level; 181*9712c20fSFrederick Mayle 182*9712c20fSFrederick Mayle // A list of inlines which are children of this inline. 183*9712c20fSFrederick Mayle vector<std::unique_ptr<Inline>> child_inlines; 184*9712c20fSFrederick Mayle getCallSiteFileIDInline185*9712c20fSFrederick Mayle int getCallSiteFileID() const { 186*9712c20fSFrederick Mayle return call_site_file ? call_site_file->source_id : -1; 187*9712c20fSFrederick Mayle } 188*9712c20fSFrederick Mayle InlineDFSInline189*9712c20fSFrederick Mayle static void InlineDFS( 190*9712c20fSFrederick Mayle vector<std::unique_ptr<Module::Inline>>& inlines, 191*9712c20fSFrederick Mayle std::function<void(std::unique_ptr<Module::Inline>&)> const& forEach) { 192*9712c20fSFrederick Mayle for (std::unique_ptr<Module::Inline>& in : inlines) { 193*9712c20fSFrederick Mayle forEach(in); 194*9712c20fSFrederick Mayle InlineDFS(in->child_inlines, forEach); 195*9712c20fSFrederick Mayle } 196*9712c20fSFrederick Mayle } 197*9712c20fSFrederick Mayle }; 198*9712c20fSFrederick Mayle 199*9712c20fSFrederick Mayle typedef map<uint64_t, InlineOrigin*> InlineOriginByOffset; 200*9712c20fSFrederick Mayle 201*9712c20fSFrederick Mayle class InlineOriginMap { 202*9712c20fSFrederick Mayle public: 203*9712c20fSFrederick Mayle // Add INLINE ORIGIN to the module. Return a pointer to origin . 204*9712c20fSFrederick Mayle InlineOrigin* GetOrCreateInlineOrigin(uint64_t offset, StringView name); 205*9712c20fSFrederick Mayle 206*9712c20fSFrederick Mayle // offset is the offset of a DW_TAG_subprogram. specification_offset is the 207*9712c20fSFrederick Mayle // value of its DW_AT_specification or equals to offset if 208*9712c20fSFrederick Mayle // DW_AT_specification doesn't exist in that DIE. 209*9712c20fSFrederick Mayle void SetReference(uint64_t offset, uint64_t specification_offset); 210*9712c20fSFrederick Mayle ~InlineOriginMap()211*9712c20fSFrederick Mayle ~InlineOriginMap() { 212*9712c20fSFrederick Mayle for (const auto& iter : inline_origins_) { 213*9712c20fSFrederick Mayle delete iter.second; 214*9712c20fSFrederick Mayle } 215*9712c20fSFrederick Mayle } 216*9712c20fSFrederick Mayle 217*9712c20fSFrederick Mayle private: 218*9712c20fSFrederick Mayle // A map from a DW_TAG_subprogram's offset to the DW_TAG_subprogram. 219*9712c20fSFrederick Mayle InlineOriginByOffset inline_origins_; 220*9712c20fSFrederick Mayle 221*9712c20fSFrederick Mayle // A map from a DW_TAG_subprogram's offset to the offset of its 222*9712c20fSFrederick Mayle // specification or abstract origin subprogram. The set of values in this 223*9712c20fSFrederick Mayle // map should always be the same set of keys in inline_origins_. 224*9712c20fSFrederick Mayle map<uint64_t, uint64_t> references_; 225*9712c20fSFrederick Mayle }; 226*9712c20fSFrederick Mayle 227*9712c20fSFrederick Mayle map<std::string, InlineOriginMap> inline_origin_maps; 228*9712c20fSFrederick Mayle 229*9712c20fSFrederick Mayle // A source line. 230*9712c20fSFrederick Mayle struct Line { 231*9712c20fSFrederick Mayle // For sorting by address. (Not style-guide compliant, but it's 232*9712c20fSFrederick Mayle // stupid not to put this in the struct.) CompareByAddressLine233*9712c20fSFrederick Mayle static bool CompareByAddress(const Module::Line& x, const Module::Line& y) { 234*9712c20fSFrederick Mayle return x.address < y.address; 235*9712c20fSFrederick Mayle } 236*9712c20fSFrederick Mayle 237*9712c20fSFrederick Mayle Address address, size; // The address and size of the line's code. 238*9712c20fSFrederick Mayle File* file; // The source file. 239*9712c20fSFrederick Mayle int number; // The source line number. 240*9712c20fSFrederick Mayle }; 241*9712c20fSFrederick Mayle 242*9712c20fSFrederick Mayle // An exported symbol. 243*9712c20fSFrederick Mayle struct Extern { ExternExtern244*9712c20fSFrederick Mayle explicit Extern(const Address& address_input) : address(address_input) {} 245*9712c20fSFrederick Mayle const Address address; 246*9712c20fSFrederick Mayle string name; 247*9712c20fSFrederick Mayle // If this symbol has been folded with other symbols in the linked binary. 248*9712c20fSFrederick Mayle bool is_multiple = false; 249*9712c20fSFrederick Mayle }; 250*9712c20fSFrederick Mayle 251*9712c20fSFrederick Mayle // A map from register names to postfix expressions that recover 252*9712c20fSFrederick Mayle // their their values. This can represent a complete set of rules to 253*9712c20fSFrederick Mayle // follow at some address, or a set of changes to be applied to an 254*9712c20fSFrederick Mayle // extant set of rules. 255*9712c20fSFrederick Mayle typedef map<string, string> RuleMap; 256*9712c20fSFrederick Mayle 257*9712c20fSFrederick Mayle // A map from addresses to RuleMaps, representing changes that take 258*9712c20fSFrederick Mayle // effect at given addresses. 259*9712c20fSFrederick Mayle typedef map<Address, RuleMap> RuleChangeMap; 260*9712c20fSFrederick Mayle 261*9712c20fSFrederick Mayle // A range of 'STACK CFI' stack walking information. An instance of 262*9712c20fSFrederick Mayle // this structure corresponds to a 'STACK CFI INIT' record and the 263*9712c20fSFrederick Mayle // subsequent 'STACK CFI' records that fall within its range. 264*9712c20fSFrederick Mayle struct StackFrameEntry { 265*9712c20fSFrederick Mayle // The starting address and number of bytes of machine code this 266*9712c20fSFrederick Mayle // entry covers. 267*9712c20fSFrederick Mayle Address address, size; 268*9712c20fSFrederick Mayle 269*9712c20fSFrederick Mayle // The initial register recovery rules, in force at the starting 270*9712c20fSFrederick Mayle // address. 271*9712c20fSFrederick Mayle RuleMap initial_rules; 272*9712c20fSFrederick Mayle 273*9712c20fSFrederick Mayle // A map from addresses to rule changes. To find the rules in 274*9712c20fSFrederick Mayle // force at a given address, start with initial_rules, and then 275*9712c20fSFrederick Mayle // apply the changes given in this map for all addresses up to and 276*9712c20fSFrederick Mayle // including the address you're interested in. 277*9712c20fSFrederick Mayle RuleChangeMap rule_changes; 278*9712c20fSFrederick Mayle }; 279*9712c20fSFrederick Mayle 280*9712c20fSFrederick Mayle struct FunctionCompare { operatorFunctionCompare281*9712c20fSFrederick Mayle bool operator() (const Function* lhs, const Function* rhs) const { 282*9712c20fSFrederick Mayle if (lhs->address == rhs->address) 283*9712c20fSFrederick Mayle return lhs->name < rhs->name; 284*9712c20fSFrederick Mayle return lhs->address < rhs->address; 285*9712c20fSFrederick Mayle } 286*9712c20fSFrederick Mayle }; 287*9712c20fSFrederick Mayle 288*9712c20fSFrederick Mayle struct InlineOriginCompare { operatorInlineOriginCompare289*9712c20fSFrederick Mayle bool operator()(const InlineOrigin* lhs, const InlineOrigin* rhs) const { 290*9712c20fSFrederick Mayle return lhs->name < rhs->name; 291*9712c20fSFrederick Mayle } 292*9712c20fSFrederick Mayle }; 293*9712c20fSFrederick Mayle 294*9712c20fSFrederick Mayle struct ExternCompare { 295*9712c20fSFrederick Mayle // Defining is_transparent allows 296*9712c20fSFrederick Mayle // std::set<std::unique_ptr<Extern>, ExternCompare>::find() to be called 297*9712c20fSFrederick Mayle // with an Extern* and have set use the overloads below. 298*9712c20fSFrederick Mayle using is_transparent = void; operatorExternCompare299*9712c20fSFrederick Mayle bool operator() (const std::unique_ptr<Extern>& lhs, 300*9712c20fSFrederick Mayle const std::unique_ptr<Extern>& rhs) const { 301*9712c20fSFrederick Mayle return lhs->address < rhs->address; 302*9712c20fSFrederick Mayle } operatorExternCompare303*9712c20fSFrederick Mayle bool operator() (const Extern* lhs, const std::unique_ptr<Extern>& rhs) const { 304*9712c20fSFrederick Mayle return lhs->address < rhs->address; 305*9712c20fSFrederick Mayle } operatorExternCompare306*9712c20fSFrederick Mayle bool operator() (const std::unique_ptr<Extern>& lhs, const Extern* rhs) const { 307*9712c20fSFrederick Mayle return lhs->address < rhs->address; 308*9712c20fSFrederick Mayle } 309*9712c20fSFrederick Mayle }; 310*9712c20fSFrederick Mayle 311*9712c20fSFrederick Mayle // Create a new module with the given name, operating system, 312*9712c20fSFrederick Mayle // architecture, and ID string. 313*9712c20fSFrederick Mayle // NB: `enable_multiple_field` is temporary while transitioning to enabling 314*9712c20fSFrederick Mayle // writing the multiple field permanently. 315*9712c20fSFrederick Mayle Module(const string& name, 316*9712c20fSFrederick Mayle const string& os, 317*9712c20fSFrederick Mayle const string& architecture, 318*9712c20fSFrederick Mayle const string& id, 319*9712c20fSFrederick Mayle const string& code_id = "", 320*9712c20fSFrederick Mayle bool enable_multiple_field = false, 321*9712c20fSFrederick Mayle bool prefer_extern_name = false); 322*9712c20fSFrederick Mayle ~Module(); 323*9712c20fSFrederick Mayle 324*9712c20fSFrederick Mayle // Set the module's load address to LOAD_ADDRESS; addresses given 325*9712c20fSFrederick Mayle // for functions and lines will be written to the Breakpad symbol 326*9712c20fSFrederick Mayle // file as offsets from this address. Construction initializes this 327*9712c20fSFrederick Mayle // module's load address to zero: addresses written to the symbol 328*9712c20fSFrederick Mayle // file will be the same as they appear in the Function, Line, and 329*9712c20fSFrederick Mayle // StackFrameEntry structures. 330*9712c20fSFrederick Mayle // 331*9712c20fSFrederick Mayle // Note that this member function has no effect on addresses stored 332*9712c20fSFrederick Mayle // in the data added to this module; the Write member function 333*9712c20fSFrederick Mayle // simply subtracts off the load address from addresses before it 334*9712c20fSFrederick Mayle // prints them. Only the last load address given before calling 335*9712c20fSFrederick Mayle // Write is used. 336*9712c20fSFrederick Mayle void SetLoadAddress(Address load_address); 337*9712c20fSFrederick Mayle 338*9712c20fSFrederick Mayle // Sets address filtering on elements added to the module. This allows 339*9712c20fSFrederick Mayle // libraries with extraneous debug symbols to generate symbol files containing 340*9712c20fSFrederick Mayle // only relevant symbols. For example, an LLD-generated partition library may 341*9712c20fSFrederick Mayle // contain debug information pertaining to all partitions derived from a 342*9712c20fSFrederick Mayle // single "combined" library. Filtering applies only to elements added after 343*9712c20fSFrederick Mayle // this method is called. 344*9712c20fSFrederick Mayle void SetAddressRanges(const vector<Range>& ranges); 345*9712c20fSFrederick Mayle 346*9712c20fSFrederick Mayle // Add FUNCTION to the module. FUNCTION's name must not be empty. 347*9712c20fSFrederick Mayle // This module owns all Function objects added with this function: 348*9712c20fSFrederick Mayle // destroying the module destroys them as well. 349*9712c20fSFrederick Mayle // Return false if the function is duplicate and needs to be freed. 350*9712c20fSFrederick Mayle bool AddFunction(Function* function); 351*9712c20fSFrederick Mayle 352*9712c20fSFrederick Mayle // Add STACK_FRAME_ENTRY to the module. 353*9712c20fSFrederick Mayle // This module owns all StackFrameEntry objects added with this 354*9712c20fSFrederick Mayle // function: destroying the module destroys them as well. 355*9712c20fSFrederick Mayle void AddStackFrameEntry(std::unique_ptr<StackFrameEntry> stack_frame_entry); 356*9712c20fSFrederick Mayle 357*9712c20fSFrederick Mayle // Add PUBLIC to the module. 358*9712c20fSFrederick Mayle // This module owns all Extern objects added with this function: 359*9712c20fSFrederick Mayle // destroying the module destroys them as well. 360*9712c20fSFrederick Mayle void AddExtern(std::unique_ptr<Extern> ext); 361*9712c20fSFrederick Mayle 362*9712c20fSFrederick Mayle // If this module has a file named NAME, return a pointer to it. If 363*9712c20fSFrederick Mayle // it has none, then create one and return a pointer to the new 364*9712c20fSFrederick Mayle // file. This module owns all File objects created using these 365*9712c20fSFrederick Mayle // functions; destroying the module destroys them as well. 366*9712c20fSFrederick Mayle File* FindFile(const string& name); 367*9712c20fSFrederick Mayle File* FindFile(const char* name); 368*9712c20fSFrederick Mayle 369*9712c20fSFrederick Mayle // If this module has a file named NAME, return a pointer to it. 370*9712c20fSFrederick Mayle // Otherwise, return NULL. 371*9712c20fSFrederick Mayle File* FindExistingFile(const string& name); 372*9712c20fSFrederick Mayle 373*9712c20fSFrederick Mayle // Insert pointers to the functions added to this module at I in 374*9712c20fSFrederick Mayle // VEC. The pointed-to Functions are still owned by this module. 375*9712c20fSFrederick Mayle // (Since this is effectively a copy of the function list, this is 376*9712c20fSFrederick Mayle // mostly useful for testing; other uses should probably get a more 377*9712c20fSFrederick Mayle // appropriate interface.) 378*9712c20fSFrederick Mayle void GetFunctions(vector<Function*>* vec, vector<Function*>::iterator i); 379*9712c20fSFrederick Mayle 380*9712c20fSFrederick Mayle // Insert pointers to the externs added to this module at I in 381*9712c20fSFrederick Mayle // VEC. The pointed-to Externs are still owned by this module. 382*9712c20fSFrederick Mayle // (Since this is effectively a copy of the extern list, this is 383*9712c20fSFrederick Mayle // mostly useful for testing; other uses should probably get a more 384*9712c20fSFrederick Mayle // appropriate interface.) 385*9712c20fSFrederick Mayle void GetExterns(vector<Extern*>* vec, vector<Extern*>::iterator i); 386*9712c20fSFrederick Mayle 387*9712c20fSFrederick Mayle // Clear VEC and fill it with pointers to the Files added to this 388*9712c20fSFrederick Mayle // module, sorted by name. The pointed-to Files are still owned by 389*9712c20fSFrederick Mayle // this module. (Since this is effectively a copy of the file list, 390*9712c20fSFrederick Mayle // this is mostly useful for testing; other uses should probably get 391*9712c20fSFrederick Mayle // a more appropriate interface.) 392*9712c20fSFrederick Mayle void GetFiles(vector<File*>* vec); 393*9712c20fSFrederick Mayle 394*9712c20fSFrederick Mayle // Clear VEC and fill it with pointers to the StackFrameEntry 395*9712c20fSFrederick Mayle // objects that have been added to this module. (Since this is 396*9712c20fSFrederick Mayle // effectively a copy of the stack frame entry list, this is mostly 397*9712c20fSFrederick Mayle // useful for testing; other uses should probably get 398*9712c20fSFrederick Mayle // a more appropriate interface.) 399*9712c20fSFrederick Mayle void GetStackFrameEntries(vector<StackFrameEntry*>* vec) const; 400*9712c20fSFrederick Mayle 401*9712c20fSFrederick Mayle // Find those files in this module that are actually referred to by 402*9712c20fSFrederick Mayle // functions' line number data, and assign them source id numbers. 403*9712c20fSFrederick Mayle // Set the source id numbers for all other files --- unused by the 404*9712c20fSFrederick Mayle // source line data --- to -1. We do this before writing out the 405*9712c20fSFrederick Mayle // symbol file, at which point we omit any unused files. 406*9712c20fSFrederick Mayle void AssignSourceIds(); 407*9712c20fSFrederick Mayle 408*9712c20fSFrederick Mayle // This function should be called before AssignSourceIds() to get the set of 409*9712c20fSFrederick Mayle // valid InlineOrigins*. 410*9712c20fSFrederick Mayle void CreateInlineOrigins( 411*9712c20fSFrederick Mayle set<InlineOrigin*, InlineOriginCompare>& inline_origins); 412*9712c20fSFrederick Mayle 413*9712c20fSFrederick Mayle // Call AssignSourceIds, and write this module to STREAM in the 414*9712c20fSFrederick Mayle // breakpad symbol format. Return true if all goes well, or false if 415*9712c20fSFrederick Mayle // an error occurs. This method writes out: 416*9712c20fSFrederick Mayle // - a header based on the values given to the constructor, 417*9712c20fSFrederick Mayle // If symbol_data is not CFI then: 418*9712c20fSFrederick Mayle // - the source files added via FindFile, 419*9712c20fSFrederick Mayle // - the functions added via AddFunctions, each with its lines, 420*9712c20fSFrederick Mayle // - all public records, 421*9712c20fSFrederick Mayle // If symbol_data is CFI then: 422*9712c20fSFrederick Mayle // - all CFI records. 423*9712c20fSFrederick Mayle // Addresses in the output are all relative to the load address 424*9712c20fSFrederick Mayle // established by SetLoadAddress. 425*9712c20fSFrederick Mayle bool Write(std::ostream& stream, SymbolData symbol_data); 426*9712c20fSFrederick Mayle 427*9712c20fSFrederick Mayle // Place the name in the global set of strings. Return a StringView points to 428*9712c20fSFrederick Mayle // a string inside the pool. AddStringToPool(const string & str)429*9712c20fSFrederick Mayle StringView AddStringToPool(const string& str) { 430*9712c20fSFrederick Mayle auto result = common_strings_.insert(str); 431*9712c20fSFrederick Mayle return *(result.first); 432*9712c20fSFrederick Mayle } 433*9712c20fSFrederick Mayle name()434*9712c20fSFrederick Mayle string name() const { return name_; } os()435*9712c20fSFrederick Mayle string os() const { return os_; } architecture()436*9712c20fSFrederick Mayle string architecture() const { return architecture_; } identifier()437*9712c20fSFrederick Mayle string identifier() const { return id_; } code_identifier()438*9712c20fSFrederick Mayle string code_identifier() const { return code_id_; } 439*9712c20fSFrederick Mayle 440*9712c20fSFrederick Mayle private: 441*9712c20fSFrederick Mayle // Report an error that has occurred writing the symbol file, using 442*9712c20fSFrederick Mayle // errno to find the appropriate cause. Return false. 443*9712c20fSFrederick Mayle static bool ReportError(); 444*9712c20fSFrederick Mayle 445*9712c20fSFrederick Mayle // Write RULE_MAP to STREAM, in the form appropriate for 'STACK CFI' 446*9712c20fSFrederick Mayle // records, without a final newline. Return true if all goes well; 447*9712c20fSFrederick Mayle // if an error occurs, return false, and leave errno set. 448*9712c20fSFrederick Mayle static bool WriteRuleMap(const RuleMap& rule_map, std::ostream& stream); 449*9712c20fSFrederick Mayle 450*9712c20fSFrederick Mayle // Returns true of the specified address resides with an specified address 451*9712c20fSFrederick Mayle // range, or if no ranges have been specified. 452*9712c20fSFrederick Mayle bool AddressIsInModule(Address address) const; 453*9712c20fSFrederick Mayle 454*9712c20fSFrederick Mayle // Module header entries. 455*9712c20fSFrederick Mayle string name_, os_, architecture_, id_, code_id_; 456*9712c20fSFrederick Mayle 457*9712c20fSFrederick Mayle // The module's nominal load address. Addresses for functions and 458*9712c20fSFrederick Mayle // lines are absolute, assuming the module is loaded at this 459*9712c20fSFrederick Mayle // address. 460*9712c20fSFrederick Mayle Address load_address_; 461*9712c20fSFrederick Mayle 462*9712c20fSFrederick Mayle // The set of valid address ranges of the module. If specified, attempts to 463*9712c20fSFrederick Mayle // add elements residing outside these ranges will be silently filtered. 464*9712c20fSFrederick Mayle vector<Range> address_ranges_; 465*9712c20fSFrederick Mayle 466*9712c20fSFrederick Mayle // Relation for maps whose keys are strings shared with some other 467*9712c20fSFrederick Mayle // structure. 468*9712c20fSFrederick Mayle struct CompareStringPtrs { operatorCompareStringPtrs469*9712c20fSFrederick Mayle bool operator()(const string* x, const string* y) const { return *x < *y; } 470*9712c20fSFrederick Mayle }; 471*9712c20fSFrederick Mayle 472*9712c20fSFrederick Mayle // A map from filenames to File structures. The map's keys are 473*9712c20fSFrederick Mayle // pointers to the Files' names. 474*9712c20fSFrederick Mayle typedef map<const string*, File*, CompareStringPtrs> FileByNameMap; 475*9712c20fSFrederick Mayle 476*9712c20fSFrederick Mayle // A set containing Function structures, sorted by address. 477*9712c20fSFrederick Mayle typedef set<Function*, FunctionCompare> FunctionSet; 478*9712c20fSFrederick Mayle 479*9712c20fSFrederick Mayle // A set containing Extern structures, sorted by address. 480*9712c20fSFrederick Mayle typedef set<std::unique_ptr<Extern>, ExternCompare> ExternSet; 481*9712c20fSFrederick Mayle 482*9712c20fSFrederick Mayle // The module owns all the files and functions that have been added 483*9712c20fSFrederick Mayle // to it; destroying the module frees the Files and Functions these 484*9712c20fSFrederick Mayle // point to. 485*9712c20fSFrederick Mayle FileByNameMap files_; // This module's source files. 486*9712c20fSFrederick Mayle FunctionSet functions_; // This module's functions. 487*9712c20fSFrederick Mayle // Used to quickly look up whether a function exists at a particular address. 488*9712c20fSFrederick Mayle unordered_set<Address> function_addresses_; 489*9712c20fSFrederick Mayle 490*9712c20fSFrederick Mayle // The module owns all the call frame info entries that have been 491*9712c20fSFrederick Mayle // added to it. 492*9712c20fSFrederick Mayle vector<std::unique_ptr<StackFrameEntry>> stack_frame_entries_; 493*9712c20fSFrederick Mayle 494*9712c20fSFrederick Mayle // The module owns all the externs that have been added to it; 495*9712c20fSFrederick Mayle // destroying the module frees the Externs these point to. 496*9712c20fSFrederick Mayle ExternSet externs_; 497*9712c20fSFrederick Mayle 498*9712c20fSFrederick Mayle unordered_set<string> common_strings_; 499*9712c20fSFrederick Mayle 500*9712c20fSFrederick Mayle // Whether symbols sharing an address should be collapsed into a single entry 501*9712c20fSFrederick Mayle // and marked with an `m` in the output. See 502*9712c20fSFrederick Mayle // https://bugs.chromium.org/p/google-breakpad/issues/detail?id=751 and docs 503*9712c20fSFrederick Mayle // at 504*9712c20fSFrederick Mayle // https://chromium.googlesource.com/breakpad/breakpad/+/master/docs/symbol_files.md#records-3 505*9712c20fSFrederick Mayle bool enable_multiple_field_; 506*9712c20fSFrederick Mayle 507*9712c20fSFrederick Mayle // If a Function and an Extern share the same address but have a different 508*9712c20fSFrederick Mayle // name, prefer the name of the Extern. 509*9712c20fSFrederick Mayle // 510*9712c20fSFrederick Mayle // Use this when dumping Mach-O .dSYMs built with -gmlt (Minimum Line Tables), 511*9712c20fSFrederick Mayle // as the Function's fully-qualified name will only be present in the STABS 512*9712c20fSFrederick Mayle // (which are placed in the Extern), not in the DWARF symbols (which are 513*9712c20fSFrederick Mayle // placed in the Function). 514*9712c20fSFrederick Mayle bool prefer_extern_name_; 515*9712c20fSFrederick Mayle }; 516*9712c20fSFrederick Mayle 517*9712c20fSFrederick Mayle } // namespace google_breakpad 518*9712c20fSFrederick Mayle 519*9712c20fSFrederick Mayle #endif // COMMON_LINUX_MODULE_H__ 520