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