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