xref: /aosp_15_r20/external/google-breakpad/src/common/module.h (revision 9712c20fc9bbfbac4935993a2ca0b3958c5adad2)
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