PageRenderTime 36ms CodeModel.GetById 24ms app.highlight 8ms RepoModel.GetById 1ms app.codeStats 0ms

/thirdparty/breakpad/common/module.h

http://github.com/tomahawk-player/tomahawk
C++ Header | 321 lines | 102 code | 54 blank | 165 comment | 2 complexity | 4997679f5d699b0a6c0aed4bcfe8e321 MD5 | raw file
  1// -*- mode: c++ -*-
  2
  3// Copyright (c) 2010 Google Inc.
  4// All rights reserved.
  5//
  6// Redistribution and use in source and binary forms, with or without
  7// modification, are permitted provided that the following conditions are
  8// met:
  9//
 10//     * Redistributions of source code must retain the above copyright
 11// notice, this list of conditions and the following disclaimer.
 12//     * Redistributions in binary form must reproduce the above
 13// copyright notice, this list of conditions and the following disclaimer
 14// in the documentation and/or other materials provided with the
 15// distribution.
 16//     * Neither the name of Google Inc. nor the names of its
 17// contributors may be used to endorse or promote products derived from
 18// this software without specific prior written permission.
 19//
 20// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 21// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 22// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 23// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 24// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 25// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 26// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 27// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 28// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 29// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 30// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 31
 32// Original author: Jim Blandy <jimb@mozilla.com> <jimb@red-bean.com>
 33
 34// module.h: Define google_breakpad::Module. A Module holds debugging
 35// information, and can write that information out as a Breakpad
 36// symbol file.
 37
 38#ifndef COMMON_LINUX_MODULE_H__
 39#define COMMON_LINUX_MODULE_H__
 40
 41#include <iostream>
 42#include <map>
 43#include <set>
 44#include <string>
 45#include <vector>
 46
 47#include "google_breakpad/common/breakpad_types.h"
 48
 49namespace google_breakpad {
 50
 51using std::set;
 52using std::string;
 53using std::vector;
 54using std::map;
 55
 56// A Module represents the contents of a module, and supports methods
 57// for adding information produced by parsing STABS or DWARF data
 58// --- possibly both from the same file --- and then writing out the
 59// unified contents as a Breakpad-format symbol file.
 60class Module {
 61 public:
 62  // The type of addresses and sizes in a symbol table.
 63  typedef u_int64_t Address;
 64  struct File;
 65  struct Function;
 66  struct Line;
 67  struct Extern;
 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  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  struct Function {
 87    // For sorting by address.  (Not style-guide compliant, but it's
 88    // stupid not to put this in the struct.)
 89    static bool CompareByAddress(const Function *x, const Function *y) {
 90      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    static bool CompareByAddress(const Module::Line &x, const Module::Line &y) {
112      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  // An exported symbol.
121  struct Extern {
122    Address address;
123    string name;
124  };
125
126  // A map from register names to postfix expressions that recover
127  // their their values. This can represent a complete set of rules to
128  // follow at some address, or a set of changes to be applied to an
129  // extant set of rules.
130  typedef map<string, string> RuleMap;
131
132  // A map from addresses to RuleMaps, representing changes that take
133  // effect at given addresses.
134  typedef map<Address, RuleMap> RuleChangeMap;
135
136  // A range of 'STACK CFI' stack walking information. An instance of
137  // this structure corresponds to a 'STACK CFI INIT' record and the
138  // subsequent 'STACK CFI' records that fall within its range.
139  struct StackFrameEntry {
140    // The starting address and number of bytes of machine code this
141    // entry covers.
142    Address address, size;
143
144    // The initial register recovery rules, in force at the starting
145    // address.
146    RuleMap initial_rules;
147
148    // A map from addresses to rule changes. To find the rules in
149    // force at a given address, start with initial_rules, and then
150    // apply the changes given in this map for all addresses up to and
151    // including the address you're interested in.
152    RuleChangeMap rule_changes;
153  };
154
155  struct FunctionCompare {
156    bool operator() (const Function *lhs,
157                     const Function *rhs) const {
158      if (lhs->address == rhs->address)
159        return lhs->name < rhs->name;
160      return lhs->address < rhs->address;
161    }
162  };
163
164  struct ExternCompare {
165    bool operator() (const Extern *lhs,
166                     const Extern *rhs) const {
167      return lhs->address < rhs->address;
168    }
169  };
170
171  // Create a new module with the given name, operating system,
172  // architecture, and ID string.
173  Module(const string &name, const string &os, const string &architecture,
174         const string &id);
175  ~Module();
176
177  // Set the module's load address to LOAD_ADDRESS; addresses given
178  // for functions and lines will be written to the Breakpad symbol
179  // file as offsets from this address.  Construction initializes this
180  // module's load address to zero: addresses written to the symbol
181  // file will be the same as they appear in the Function, Line, and
182  // StackFrameEntry structures.
183  //
184  // Note that this member function has no effect on addresses stored
185  // in the data added to this module; the Write member function
186  // simply subtracts off the load address from addresses before it
187  // prints them. Only the last load address given before calling
188  // Write is used.
189  void SetLoadAddress(Address load_address);
190
191  // Add FUNCTION to the module. FUNCTION's name must not be empty.
192  // This module owns all Function objects added with this function:
193  // destroying the module destroys them as well.
194  void AddFunction(Function *function);
195
196  // Add all the functions in [BEGIN,END) to the module.
197  // This module owns all Function objects added with this function:
198  // destroying the module destroys them as well.
199  void AddFunctions(vector<Function *>::iterator begin,
200                    vector<Function *>::iterator end);
201
202  // Add STACK_FRAME_ENTRY to the module.
203  // This module owns all StackFrameEntry objects added with this
204  // function: destroying the module destroys them as well.
205  void AddStackFrameEntry(StackFrameEntry *stack_frame_entry);
206
207  // Add PUBLIC to the module.
208  // This module owns all Extern objects added with this function:
209  // destroying the module destroys them as well.
210  void AddExtern(Extern *ext);
211
212  // If this module has a file named NAME, return a pointer to it. If
213  // it has none, then create one and return a pointer to the new
214  // file. This module owns all File objects created using these
215  // functions; destroying the module destroys them as well.
216  File *FindFile(const string &name);
217  File *FindFile(const char *name);
218
219  // If this module has a file named NAME, return a pointer to it.
220  // Otherwise, return NULL.
221  File *FindExistingFile(const string &name);
222
223  // Insert pointers to the functions added to this module at I in
224  // VEC. The pointed-to Functions are still owned by this module.
225  // (Since this is effectively a copy of the function list, this is
226  // mostly useful for testing; other uses should probably get a more
227  // appropriate interface.)
228  void GetFunctions(vector<Function *> *vec, vector<Function *>::iterator i);
229
230  // Insert pointers to the externs added to this module at I in
231  // VEC. The pointed-to Externs are still owned by this module.
232  // (Since this is effectively a copy of the extern list, this is
233  // mostly useful for testing; other uses should probably get a more
234  // appropriate interface.)
235  void GetExterns(vector<Extern *> *vec, vector<Extern *>::iterator i);
236
237  // Clear VEC and fill it with pointers to the Files added to this
238  // module, sorted by name. The pointed-to Files are still owned by
239  // this module. (Since this is effectively a copy of the file list,
240  // this is mostly useful for testing; other uses should probably get
241  // a more appropriate interface.)
242  void GetFiles(vector<File *> *vec);
243
244  // Clear VEC and fill it with pointers to the StackFrameEntry
245  // objects that have been added to this module. (Since this is
246  // effectively a copy of the stack frame entry list, this is mostly
247  // useful for testing; other uses should probably get
248  // a more appropriate interface.)
249  void GetStackFrameEntries(vector<StackFrameEntry *> *vec);
250
251  // Find those files in this module that are actually referred to by
252  // functions' line number data, and assign them source id numbers.
253  // Set the source id numbers for all other files --- unused by the
254  // source line data --- to -1.  We do this before writing out the
255  // symbol file, at which point we omit any unused files.
256  void AssignSourceIds();
257
258  // Call AssignSourceIds, and write this module to STREAM in the
259  // breakpad symbol format. Return true if all goes well, or false if
260  // an error occurs. This method writes out:
261  // - a header based on the values given to the constructor,
262  // - the source files added via FindFile,
263  // - the functions added via AddFunctions, each with its lines,
264  // - all public records,
265  // - and if CFI is true, all CFI records.
266  // Addresses in the output are all relative to the load address
267  // established by SetLoadAddress.
268  bool Write(std::ostream &stream, bool cfi);
269
270 private:
271  // Report an error that has occurred writing the symbol file, using
272  // errno to find the appropriate cause.  Return false.
273  static bool ReportError();
274
275  // Write RULE_MAP to STREAM, in the form appropriate for 'STACK CFI'
276  // records, without a final newline. Return true if all goes well;
277  // if an error occurs, return false, and leave errno set.
278  static bool WriteRuleMap(const RuleMap &rule_map, std::ostream &stream);
279
280  // Module header entries.
281  string name_, os_, architecture_, id_;
282
283  // The module's nominal load address.  Addresses for functions and
284  // lines are absolute, assuming the module is loaded at this
285  // address.
286  Address load_address_;
287
288  // Relation for maps whose keys are strings shared with some other
289  // structure.
290  struct CompareStringPtrs {
291    bool operator()(const string *x, const string *y) { return *x < *y; }
292  };
293
294  // A map from filenames to File structures.  The map's keys are
295  // pointers to the Files' names.
296  typedef map<const string *, File *, CompareStringPtrs> FileByNameMap;
297
298  // A set containing Function structures, sorted by address.
299  typedef set<Function *, FunctionCompare> FunctionSet;
300
301  // A set containing Extern structures, sorted by address.
302  typedef set<Extern *, ExternCompare> ExternSet;
303
304  // The module owns all the files and functions that have been added
305  // to it; destroying the module frees the Files and Functions these
306  // point to.
307  FileByNameMap files_;    // This module's source files.
308  FunctionSet functions_;  // This module's functions.
309
310  // The module owns all the call frame info entries that have been
311  // added to it.
312  vector<StackFrameEntry *> stack_frame_entries_;
313
314  // The module owns all the externs that have been added to it;
315  // destroying the module frees the Externs these point to.
316  ExternSet externs_;
317};
318
319}  // namespace google_breakpad
320
321#endif  // COMMON_LINUX_MODULE_H__