/thirdparty/breakpad/common/dwarf_cu_to_module.h

http://github.com/tomahawk-player/tomahawk · C Header · 276 lines · 107 code · 47 blank · 122 comment · 0 complexity · fae057819531fc564479524a07a38deb MD5 · raw file

  1. // -*- mode: c++ -*-
  2. // Copyright (c) 2010 Google Inc.
  3. // All rights reserved.
  4. //
  5. // Redistribution and use in source and binary forms, with or without
  6. // modification, are permitted provided that the following conditions are
  7. // met:
  8. //
  9. // * Redistributions of source code must retain the above copyright
  10. // notice, this list of conditions and the following disclaimer.
  11. // * Redistributions in binary form must reproduce the above
  12. // copyright notice, this list of conditions and the following disclaimer
  13. // in the documentation and/or other materials provided with the
  14. // distribution.
  15. // * Neither the name of Google Inc. nor the names of its
  16. // contributors may be used to endorse or promote products derived from
  17. // this software without specific prior written permission.
  18. //
  19. // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  20. // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  21. // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  22. // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
  23. // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  24. // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  25. // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  26. // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  27. // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  28. // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  29. // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  30. // Original author: Jim Blandy <jimb@mozilla.com> <jimb@red-bean.com>
  31. // Add DWARF debugging information to a Breakpad symbol file. This
  32. // file defines the DwarfCUToModule class, which accepts parsed DWARF
  33. // data and populates a google_breakpad::Module with the results; the
  34. // Module can then write its contents as a Breakpad symbol file.
  35. #ifndef COMMON_LINUX_DWARF_CU_TO_MODULE_H__
  36. #define COMMON_LINUX_DWARF_CU_TO_MODULE_H__
  37. #include <string>
  38. #include "common/language.h"
  39. #include "common/module.h"
  40. #include "common/dwarf/bytereader.h"
  41. #include "common/dwarf/dwarf2diehandler.h"
  42. #include "common/dwarf/dwarf2reader.h"
  43. namespace google_breakpad {
  44. using dwarf2reader::AttributeList;
  45. using dwarf2reader::DwarfAttribute;
  46. using dwarf2reader::DwarfForm;
  47. using dwarf2reader::DwarfLanguage;
  48. using dwarf2reader::DwarfTag;
  49. // Populate a google_breakpad::Module with DWARF debugging information.
  50. //
  51. // An instance of this class can be provided as a handler to a
  52. // dwarf2reader::DIEDispatcher, which can in turn be a handler for a
  53. // dwarf2reader::CompilationUnit DWARF parser. The handler uses the results
  54. // of parsing to populate a google_breakpad::Module with source file,
  55. // function, and source line information.
  56. class DwarfCUToModule: public dwarf2reader::RootDIEHandler {
  57. struct FilePrivate;
  58. public:
  59. // Information global to the DWARF-bearing file we are processing,
  60. // for use by DwarfCUToModule. Each DwarfCUToModule instance deals
  61. // with a single compilation unit within the file, but information
  62. // global to the whole file is held here. The client is responsible
  63. // for filling it in appropriately (except for the 'file_private'
  64. // field, which the constructor and destructor take care of), and
  65. // then providing it to the DwarfCUToModule instance for each
  66. // compilation unit we process in that file.
  67. struct FileContext {
  68. FileContext(const string &filename_arg, Module *module_arg);
  69. ~FileContext();
  70. // The name of this file, for use in error messages.
  71. string filename;
  72. // A map of this file's sections, used for finding other DWARF
  73. // sections that the .debug_info section may refer to.
  74. dwarf2reader::SectionMap section_map;
  75. // The Module to which we're contributing definitions.
  76. Module *module;
  77. // Inter-compilation unit data used internally by the handlers.
  78. FilePrivate *file_private;
  79. };
  80. // An abstract base class for functors that handle DWARF line data
  81. // for DwarfCUToModule. DwarfCUToModule could certainly just use
  82. // dwarf2reader::LineInfo itself directly, but decoupling things
  83. // this way makes unit testing a little easier.
  84. class LineToModuleFunctor {
  85. public:
  86. LineToModuleFunctor() { }
  87. virtual ~LineToModuleFunctor() { }
  88. // Populate MODULE and LINES with source file names and code/line
  89. // mappings, given a pointer to some DWARF line number data
  90. // PROGRAM, and an overestimate of its size. Add no zero-length
  91. // lines to LINES.
  92. virtual void operator()(const char *program, uint64 length,
  93. Module *module, vector<Module::Line> *lines) = 0;
  94. };
  95. // The interface DwarfCUToModule uses to report warnings. The member
  96. // function definitions for this class write messages to stderr, but
  97. // you can override them if you'd like to detect or report these
  98. // conditions yourself.
  99. class WarningReporter {
  100. public:
  101. // Warn about problems in the DWARF file FILENAME, in the
  102. // compilation unit at OFFSET.
  103. WarningReporter(const string &filename, uint64 cu_offset)
  104. : filename_(filename), cu_offset_(cu_offset), printed_cu_header_(false),
  105. printed_unpaired_header_(false),
  106. uncovered_warnings_enabled_(false) { }
  107. virtual ~WarningReporter() { }
  108. // Set the name of the compilation unit we're processing to NAME.
  109. virtual void SetCUName(const string &name) { cu_name_ = name; }
  110. // Accessor and setter for uncovered_warnings_enabled_.
  111. // UncoveredFunction and UncoveredLine only report a problem if that is
  112. // true. By default, these warnings are disabled, because those
  113. // conditions occur occasionally in healthy code.
  114. virtual bool uncovered_warnings_enabled() const {
  115. return uncovered_warnings_enabled_;
  116. }
  117. virtual void set_uncovered_warnings_enabled(bool value) {
  118. uncovered_warnings_enabled_ = value;
  119. }
  120. // A DW_AT_specification in the DIE at OFFSET refers to a DIE we
  121. // haven't processed yet, or that wasn't marked as a declaration,
  122. // at TARGET.
  123. virtual void UnknownSpecification(uint64 offset, uint64 target);
  124. // A DW_AT_abstract_origin in the DIE at OFFSET refers to a DIE we
  125. // haven't processed yet, or that wasn't marked as inline, at TARGET.
  126. virtual void UnknownAbstractOrigin(uint64 offset, uint64 target);
  127. // We were unable to find the DWARF section named SECTION_NAME.
  128. virtual void MissingSection(const string &section_name);
  129. // The CU's DW_AT_stmt_list offset OFFSET is bogus.
  130. virtual void BadLineInfoOffset(uint64 offset);
  131. // FUNCTION includes code covered by no line number data.
  132. virtual void UncoveredFunction(const Module::Function &function);
  133. // Line number NUMBER in LINE_FILE, of length LENGTH, includes code
  134. // covered by no function.
  135. virtual void UncoveredLine(const Module::Line &line);
  136. // The DW_TAG_subprogram DIE at OFFSET has no name specified directly
  137. // in the DIE, nor via a DW_AT_specification or DW_AT_abstract_origin
  138. // link.
  139. virtual void UnnamedFunction(uint64 offset);
  140. protected:
  141. string filename_;
  142. uint64 cu_offset_;
  143. string cu_name_;
  144. bool printed_cu_header_;
  145. bool printed_unpaired_header_;
  146. bool uncovered_warnings_enabled_;
  147. private:
  148. // Print a per-CU heading, once.
  149. void CUHeading();
  150. // Print an unpaired function/line heading, once.
  151. void UncoveredHeading();
  152. };
  153. // Create a DWARF debugging info handler for a compilation unit
  154. // within FILE_CONTEXT. This uses information received from the
  155. // dwarf2reader::CompilationUnit DWARF parser to populate
  156. // FILE_CONTEXT->module. Use LINE_READER to handle the compilation
  157. // unit's line number data. Use REPORTER to report problems with the
  158. // data we find.
  159. DwarfCUToModule(FileContext *file_context,
  160. LineToModuleFunctor *line_reader,
  161. WarningReporter *reporter);
  162. ~DwarfCUToModule();
  163. void ProcessAttributeSigned(enum DwarfAttribute attr,
  164. enum DwarfForm form,
  165. int64 data);
  166. void ProcessAttributeUnsigned(enum DwarfAttribute attr,
  167. enum DwarfForm form,
  168. uint64 data);
  169. void ProcessAttributeString(enum DwarfAttribute attr,
  170. enum DwarfForm form,
  171. const string &data);
  172. bool EndAttributes();
  173. DIEHandler *FindChildHandler(uint64 offset, enum DwarfTag tag,
  174. const AttributeList &attrs);
  175. // Assign all our source Lines to the Functions that cover their
  176. // addresses, and then add them to module_.
  177. void Finish();
  178. bool StartCompilationUnit(uint64 offset, uint8 address_size,
  179. uint8 offset_size, uint64 cu_length,
  180. uint8 dwarf_version);
  181. bool StartRootDIE(uint64 offset, enum DwarfTag tag,
  182. const AttributeList& attrs);
  183. private:
  184. // Used internally by the handler. Full definitions are in
  185. // dwarf_cu_to_module.cc.
  186. struct FilePrivate;
  187. struct Specification;
  188. struct CUContext;
  189. struct DIEContext;
  190. class GenericDIEHandler;
  191. class FuncHandler;
  192. class NamedScopeHandler;
  193. // A map from section offsets to specifications.
  194. typedef map<uint64, Specification> SpecificationByOffset;
  195. // Set this compilation unit's source language to LANGUAGE.
  196. void SetLanguage(DwarfLanguage language);
  197. // Read source line information at OFFSET in the .debug_line
  198. // section. Record source files in module_, but record source lines
  199. // in lines_; we apportion them to functions in
  200. // AssignLinesToFunctions.
  201. void ReadSourceLines(uint64 offset);
  202. // Assign the lines in lines_ to the individual line lists of the
  203. // functions in functions_. (DWARF line information maps an entire
  204. // compilation unit at a time, and gives no indication of which
  205. // lines belong to which functions, beyond their addresses.)
  206. void AssignLinesToFunctions();
  207. // The only reason cu_context_ and child_context_ are pointers is
  208. // that we want to keep their definitions private to
  209. // dwarf_cu_to_module.cc, instead of listing them all here. They are
  210. // owned by this DwarfCUToModule: the constructor sets them, and the
  211. // destructor deletes them.
  212. // The functor to use to handle line number data.
  213. LineToModuleFunctor *line_reader_;
  214. // This compilation unit's context.
  215. CUContext *cu_context_;
  216. // A context for our children.
  217. DIEContext *child_context_;
  218. // True if this compilation unit has source line information.
  219. bool has_source_line_info_;
  220. // The offset of this compilation unit's line number information in
  221. // the .debug_line section.
  222. uint64 source_line_offset_;
  223. // The line numbers we have seen thus far. We accumulate these here
  224. // during parsing. Then, in Finish, we call AssignLinesToFunctions
  225. // to dole them out to the appropriate functions.
  226. vector<Module::Line> lines_;
  227. };
  228. } // namespace google_breakpad
  229. #endif // COMMON_LINUX_DWARF_CU_TO_MODULE_H__