LLVM  9.0.0svn
DWARFContext.h
Go to the documentation of this file.
1 //===- DWARFContext.h -------------------------------------------*- C++ -*-===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===/
8 
9 #ifndef LLVM_DEBUGINFO_DWARF_DWARFCONTEXT_H
10 #define LLVM_DEBUGINFO_DWARF_DWARFCONTEXT_H
11 
12 #include "llvm/ADT/MapVector.h"
13 #include "llvm/ADT/SmallString.h"
14 #include "llvm/ADT/SmallVector.h"
15 #include "llvm/ADT/StringMap.h"
16 #include "llvm/ADT/StringRef.h"
34 #include "llvm/Object/Binary.h"
35 #include "llvm/Object/ObjectFile.h"
37 #include "llvm/Support/Error.h"
38 #include "llvm/Support/Host.h"
39 #include <cstdint>
40 #include <deque>
41 #include <map>
42 #include <memory>
43 
44 namespace llvm {
45 
46 class MCRegisterInfo;
47 class MemoryBuffer;
48 class raw_ostream;
49 
50 /// Used as a return value for a error callback passed to DWARF context.
51 /// Callback should return Halt if client application wants to stop
52 /// object parsing, or should return Continue otherwise.
53 enum class ErrorPolicy { Halt, Continue };
54 
55 /// DWARFContext
56 /// This data structure is the top level entity that deals with dwarf debug
57 /// information parsing. The actual data is supplied through DWARFObj.
58 class DWARFContext : public DIContext {
59  DWARFUnitVector NormalUnits;
60  std::unique_ptr<DWARFUnitIndex> CUIndex;
61  std::unique_ptr<DWARFGdbIndex> GdbIndex;
62  std::unique_ptr<DWARFUnitIndex> TUIndex;
63  std::unique_ptr<DWARFDebugAbbrev> Abbrev;
64  std::unique_ptr<DWARFDebugLoc> Loc;
65  std::unique_ptr<DWARFDebugAranges> Aranges;
66  std::unique_ptr<DWARFDebugLine> Line;
67  std::unique_ptr<DWARFDebugFrame> DebugFrame;
68  std::unique_ptr<DWARFDebugFrame> EHFrame;
69  std::unique_ptr<DWARFDebugMacro> Macro;
70  std::unique_ptr<DWARFDebugNames> Names;
71  std::unique_ptr<AppleAcceleratorTable> AppleNames;
72  std::unique_ptr<AppleAcceleratorTable> AppleTypes;
73  std::unique_ptr<AppleAcceleratorTable> AppleNamespaces;
74  std::unique_ptr<AppleAcceleratorTable> AppleObjC;
75 
76  DWARFUnitVector DWOUnits;
77  std::unique_ptr<DWARFDebugAbbrev> AbbrevDWO;
78  std::unique_ptr<DWARFDebugLoclists> LocDWO;
79 
80  /// The maximum DWARF version of all units.
81  unsigned MaxVersion = 0;
82 
83  struct DWOFile {
85  std::unique_ptr<DWARFContext> Context;
86  };
88  std::weak_ptr<DWOFile> DWP;
89  bool CheckedForDWP = false;
90  std::string DWPName;
91 
92  std::unique_ptr<MCRegisterInfo> RegInfo;
93 
94  /// Read compile units from the debug_info section (if necessary)
95  /// and type units from the debug_types sections (if necessary)
96  /// and store them in NormalUnits.
97  void parseNormalUnits();
98 
99  /// Read compile units from the debug_info.dwo section (if necessary)
100  /// and type units from the debug_types.dwo section (if necessary)
101  /// and store them in DWOUnits.
102  /// If \p Lazy is true, set up to parse but don't actually parse them.
103  enum { EagerParse = false, LazyParse = true };
104  void parseDWOUnits(bool Lazy = false);
105 
106  std::unique_ptr<const DWARFObject> DObj;
107 
108 public:
109  DWARFContext(std::unique_ptr<const DWARFObject> DObj,
110  std::string DWPName = "");
111  ~DWARFContext();
112 
113  DWARFContext(DWARFContext &) = delete;
114  DWARFContext &operator=(DWARFContext &) = delete;
115 
116  const DWARFObject &getDWARFObj() const { return *DObj; }
117 
118  static bool classof(const DIContext *DICtx) {
119  return DICtx->getKind() == CK_DWARF;
120  }
121 
122  /// Dump a textual representation to \p OS. If any \p DumpOffsets are present,
123  /// dump only the record at the specified offset.
124  void dump(raw_ostream &OS, DIDumpOptions DumpOpts,
125  std::array<Optional<uint64_t>, DIDT_ID_Count> DumpOffsets);
126 
127  void dump(raw_ostream &OS, DIDumpOptions DumpOpts) override {
128  std::array<Optional<uint64_t>, DIDT_ID_Count> DumpOffsets;
129  dump(OS, DumpOpts, DumpOffsets);
130  }
131 
132  bool verify(raw_ostream &OS, DIDumpOptions DumpOpts = {}) override;
133 
135 
136  /// Get units from .debug_info in this context.
138  parseNormalUnits();
139  return unit_iterator_range(NormalUnits.begin(),
140  NormalUnits.begin() +
141  NormalUnits.getNumInfoUnits());
142  }
143 
144  /// Get units from .debug_types in this context.
146  parseNormalUnits();
147  return unit_iterator_range(
148  NormalUnits.begin() + NormalUnits.getNumInfoUnits(), NormalUnits.end());
149  }
150 
151  /// Get compile units in this context.
152  unit_iterator_range compile_units() { return info_section_units(); }
153 
154  /// Get type units in this context.
155  unit_iterator_range type_units() { return types_section_units(); }
156 
157  /// Get all normal compile/type units in this context.
159  parseNormalUnits();
160  return unit_iterator_range(NormalUnits.begin(), NormalUnits.end());
161  }
162 
163  /// Get units from .debug_info..dwo in the DWO context.
165  parseDWOUnits();
166  return unit_iterator_range(DWOUnits.begin(),
167  DWOUnits.begin() + DWOUnits.getNumInfoUnits());
168  }
169 
170  /// Get units from .debug_types.dwo in the DWO context.
172  parseDWOUnits();
173  return unit_iterator_range(DWOUnits.begin() + DWOUnits.getNumInfoUnits(),
174  DWOUnits.end());
175  }
176 
177  /// Get compile units in the DWO context.
178  unit_iterator_range dwo_compile_units() { return dwo_info_section_units(); }
179 
180  /// Get type units in the DWO context.
181  unit_iterator_range dwo_type_units() { return dwo_types_section_units(); }
182 
183  /// Get all units in the DWO context.
185  parseDWOUnits();
186  return unit_iterator_range(DWOUnits.begin(), DWOUnits.end());
187  }
188 
189  /// Get the number of compile units in this context.
190  unsigned getNumCompileUnits() {
191  parseNormalUnits();
192  return NormalUnits.getNumInfoUnits();
193  }
194 
195  /// Get the number of type units in this context.
196  unsigned getNumTypeUnits() {
197  parseNormalUnits();
198  return NormalUnits.getNumTypesUnits();
199  }
200 
201  /// Get the number of compile units in the DWO context.
203  parseDWOUnits();
204  return DWOUnits.getNumInfoUnits();
205  }
206 
207  /// Get the number of type units in the DWO context.
208  unsigned getNumDWOTypeUnits() {
209  parseDWOUnits();
210  return DWOUnits.getNumTypesUnits();
211  }
212 
213  /// Get the unit at the specified index.
214  DWARFUnit *getUnitAtIndex(unsigned index) {
215  parseNormalUnits();
216  return NormalUnits[index].get();
217  }
218 
219  /// Get the unit at the specified index for the DWO units.
220  DWARFUnit *getDWOUnitAtIndex(unsigned index) {
221  parseDWOUnits();
222  return DWOUnits[index].get();
223  }
224 
225  DWARFCompileUnit *getDWOCompileUnitForHash(uint64_t Hash);
226 
227  /// Return the compile unit that includes an offset (relative to .debug_info).
228  DWARFCompileUnit *getCompileUnitForOffset(uint32_t Offset);
229 
230  /// Get a DIE given an exact offset.
231  DWARFDie getDIEForOffset(uint32_t Offset);
232 
233  unsigned getMaxVersion() {
234  // Ensure info units have been parsed to discover MaxVersion
235  info_section_units();
236  return MaxVersion;
237  }
238 
239  unsigned getMaxDWOVersion() {
240  // Ensure DWO info units have been parsed to discover MaxVersion
241  dwo_info_section_units();
242  return MaxVersion;
243  }
244 
246  if (Version > MaxVersion)
247  MaxVersion = Version;
248  }
249 
250  const DWARFUnitIndex &getCUIndex();
251  DWARFGdbIndex &getGdbIndex();
252  const DWARFUnitIndex &getTUIndex();
253 
254  /// Get a pointer to the parsed DebugAbbrev object.
255  const DWARFDebugAbbrev *getDebugAbbrev();
256 
257  /// Get a pointer to the parsed DebugLoc object.
258  const DWARFDebugLoc *getDebugLoc();
259 
260  /// Get a pointer to the parsed dwo abbreviations object.
261  const DWARFDebugAbbrev *getDebugAbbrevDWO();
262 
263  /// Get a pointer to the parsed DebugLoc object.
264  const DWARFDebugLoclists *getDebugLocDWO();
265 
266  /// Get a pointer to the parsed DebugAranges object.
267  const DWARFDebugAranges *getDebugAranges();
268 
269  /// Get a pointer to the parsed frame information object.
270  const DWARFDebugFrame *getDebugFrame();
271 
272  /// Get a pointer to the parsed eh frame information object.
273  const DWARFDebugFrame *getEHFrame();
274 
275  /// Get a pointer to the parsed DebugMacro object.
276  const DWARFDebugMacro *getDebugMacro();
277 
278  /// Get a reference to the parsed accelerator table object.
279  const DWARFDebugNames &getDebugNames();
280 
281  /// Get a reference to the parsed accelerator table object.
282  const AppleAcceleratorTable &getAppleNames();
283 
284  /// Get a reference to the parsed accelerator table object.
285  const AppleAcceleratorTable &getAppleTypes();
286 
287  /// Get a reference to the parsed accelerator table object.
288  const AppleAcceleratorTable &getAppleNamespaces();
289 
290  /// Get a reference to the parsed accelerator table object.
291  const AppleAcceleratorTable &getAppleObjC();
292 
293  /// Get a pointer to a parsed line table corresponding to a compile unit.
294  /// Report any parsing issues as warnings on stderr.
295  const DWARFDebugLine::LineTable *getLineTableForUnit(DWARFUnit *U);
296 
297  /// Get a pointer to a parsed line table corresponding to a compile unit.
298  /// Report any recoverable parsing problems using the callback.
300  getLineTableForUnit(DWARFUnit *U,
301  std::function<void(Error)> RecoverableErrorCallback);
302 
304  return DataExtractor(DObj->getStringSection(), false, 0);
305  }
307  return DataExtractor(DObj->getLineStringSection(), false, 0);
308  }
309 
310  /// Wraps the returned DIEs for a given address.
311  struct DIEsForAddress {
312  DWARFCompileUnit *CompileUnit = nullptr;
315  explicit operator bool() const { return CompileUnit != nullptr; }
316  };
317 
318  /// Get the compilation unit, the function DIE and lexical block DIE for the
319  /// given address where applicable.
320  DIEsForAddress getDIEsForAddress(uint64_t Address);
321 
322  DILineInfo getLineInfoForAddress(uint64_t Address,
323  DILineInfoSpecifier Specifier = DILineInfoSpecifier()) override;
324  DILineInfoTable getLineInfoForAddressRange(uint64_t Address, uint64_t Size,
325  DILineInfoSpecifier Specifier = DILineInfoSpecifier()) override;
326  DIInliningInfo getInliningInfoForAddress(uint64_t Address,
327  DILineInfoSpecifier Specifier = DILineInfoSpecifier()) override;
328 
329  bool isLittleEndian() const { return DObj->isLittleEndian(); }
330  static bool isSupportedVersion(unsigned version) {
331  return version == 2 || version == 3 || version == 4 || version == 5;
332  }
333 
334  std::shared_ptr<DWARFContext> getDWOContext(StringRef AbsolutePath);
335 
336  const MCRegisterInfo *getRegisterInfo() const { return RegInfo.get(); }
337 
338  /// Function used to handle default error reporting policy. Prints a error
339  /// message and returns Continue, so DWARF context ignores the error.
340  static ErrorPolicy defaultErrorHandler(Error E);
341  static std::unique_ptr<DWARFContext>
342  create(const object::ObjectFile &Obj, const LoadedObjectInfo *L = nullptr,
343  function_ref<ErrorPolicy(Error)> HandleError = defaultErrorHandler,
344  std::string DWPName = "");
345 
346  static std::unique_ptr<DWARFContext>
347  create(const StringMap<std::unique_ptr<MemoryBuffer>> &Sections,
348  uint8_t AddrSize, bool isLittleEndian = sys::IsLittleEndianHost);
349 
350  /// Loads register info for the architecture of the provided object file.
351  /// Improves readability of dumped DWARF expressions. Requires the caller to
352  /// have initialized the relevant target descriptions.
353  Error loadRegisterInfo(const object::ObjectFile &Obj);
354 
355  /// Get address size from CUs.
356  /// TODO: refactor compile_units() to make this const.
357  uint8_t getCUAddrSize();
358 
359  /// Dump Error as warning message to stderr.
360  static void dumpWarning(Error Warning);
361 
363  return getDWARFObj().getFile()->getArch();
364  }
365 
366 private:
367  /// Return the compile unit which contains instruction with provided
368  /// address.
369  DWARFCompileUnit *getCompileUnitForAddress(uint64_t Address);
370 };
371 
372 } // end namespace llvm
373 
374 #endif // LLVM_DEBUGINFO_DWARF_DWARFCONTEXT_H
DWARFUnit * getDWOUnitAtIndex(unsigned index)
Get the unit at the specified index for the DWO units.
Definition: DWARFContext.h:220
unsigned getMaxDWOVersion()
Definition: DWARFContext.h:239
LLVMContext & Context
unit_iterator_range dwo_type_units()
Get type units in the DWO context.
Definition: DWARFContext.h:181
A parsed .debug_frame or .eh_frame section.
This class represents lattice values for constants.
Definition: AllocatorList.h:23
ErrorPolicy
Used as a return value for a error callback passed to DWARF context.
Definition: DWARFContext.h:53
This provides a very simple, boring adaptor for a begin and end iterator into a range type...
unsigned getNumDWOCompileUnits()
Get the number of compile units in the DWO context.
Definition: DWARFContext.h:202
An efficient, type-erasing, non-owning reference to a callable.
Definition: STLExtras.h:116
This class is the base class for all object file types.
Definition: ObjectFile.h:201
unsigned getNumTypeUnits()
Get the number of type units in this context.
Definition: DWARFContext.h:196
unit_iterator_range dwo_info_section_units()
Get units from .debug_info..dwo in the DWO context.
Definition: DWARFContext.h:164
A format-neutral container for source line information.
Definition: DIContext.h:30
Triple::ArchType getArch() const
Definition: DWARFContext.h:362
unit_iterator_range normal_units()
Get all normal compile/type units in this context.
Definition: DWARFContext.h:158
unsigned getNumCompileUnits()
Get the number of compile units in this context.
Definition: DWARFContext.h:190
unit_iterator_range compile_units()
Get compile units in this context.
Definition: DWARFContext.h:152
Tagged union holding either a T or a Error.
Definition: CachePruning.h:22
const MCRegisterInfo * getRegisterInfo() const
Definition: DWARFContext.h:336
unsigned getNumDWOTypeUnits()
Get the number of type units in the DWO context.
Definition: DWARFContext.h:208
DataExtractor getStringExtractor() const
Definition: DWARFContext.h:303
static const bool IsLittleEndianHost
Definition: Host.h:49
llvm::iterator_range< typename UnitVector::iterator > iterator_range
Definition: DWARFUnit.h:119
DIContextKind getKind() const
Definition: DIContext.h:197
MCRegisterInfo base class - We assume that the target defines a static array of MCRegisterDesc object...
Container for dump options that control which debug information will be dumped.
Definition: DIContext.h:158
unit_iterator_range info_section_units()
Get units from .debug_info in this context.
Definition: DWARFContext.h:137
Utility class that carries the DWARF compile/type unit and the debug info entry in an object...
Definition: DWARFDie.h:42
unsigned getMaxVersion()
Definition: DWARFContext.h:233
void dump(const SparseBitVector< ElementSize > &LHS, raw_ostream &out)
This implements the Apple accelerator table format, a precursor of the DWARF 5 accelerator table form...
unit_iterator_range dwo_types_section_units()
Get units from .debug_types.dwo in the DWO context.
Definition: DWARFContext.h:171
Controls which fields of DILineInfo container should be filled with data.
Definition: DIContext.h:122
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
A format-neutral container for inlined code description.
Definition: DIContext.h:77
DataExtractor getLineStringExtractor() const
Definition: DWARFContext.h:306
bool verify(const TargetRegisterInfo &TRI) const
Check that information hold by this instance make sense for the given TRI.
unit_iterator_range dwo_compile_units()
Get compile units in the DWO context.
Definition: DWARFContext.h:178
.debug_names section consists of one or more units.
unit_iterator_range type_units()
Get type units in this context.
Definition: DWARFContext.h:155
const MCRegisterDesc & get(unsigned RegNo) const
Provide a get method, equivalent to [], but more useful with a pointer to this object.
void dump(raw_ostream &OS, DIDumpOptions DumpOpts) override
Definition: DWARFContext.h:127
This is a &#39;vector&#39; (really, a variable-sized array), optimized for the case when the array is small...
Definition: SmallVector.h:839
DWARFContext This data structure is the top level entity that deals with dwarf debug information pars...
Definition: DWARFContext.h:58
Describe a collection of units.
Definition: DWARFUnit.h:109
A range adaptor for a pair of iterators.
StringMap - This is an unconventional map that is specialized for handling keys that are "strings"...
Definition: StringMap.h:219
An inferface for inquiring the load address of a loaded object file to be used by the DIContext imple...
Definition: DIContext.h:220
unit_iterator_range types_section_units()
Get units from .debug_types in this context.
Definition: DWARFContext.h:145
static bool isSupportedVersion(unsigned version)
Definition: DWARFContext.h:330
static DebugLoc getDebugLoc(MachineBasicBlock::instr_iterator FirstMI, MachineBasicBlock::instr_iterator LastMI)
Return the first found DebugLoc that has a DILocation, given a range of instructions.
Wraps the returned DIEs for a given address.
Definition: DWARFContext.h:311
unit_iterator_range dwo_units()
Get all units in the DWO context.
Definition: DWARFContext.h:184
DWARFUnit * getUnitAtIndex(unsigned index)
Get the unit at the specified index.
Definition: DWARFContext.h:214
uint32_t Size
Definition: Profile.cpp:46
bool isLittleEndian() const
Definition: DWARFContext.h:329
const DWARFObject & getDWARFObj() const
Definition: DWARFContext.h:116
static bool classof(const DIContext *DICtx)
Definition: DWARFContext.h:118
unsigned getNumTypesUnits() const
Returns number of units from all .debug_types[.dwo] sections.
Definition: DWARFUnit.h:149
Lightweight error class with error context and mandatory checking.
Definition: Error.h:157
This class implements an extremely fast bulk output stream that can only output to a stream...
Definition: raw_ostream.h:45
print Print MemDeps of function
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:48
const uint64_t Version
Definition: InstrProf.h:894
void setMaxVersionIfGreater(unsigned Version)
Definition: DWARFContext.h:245
unsigned getNumInfoUnits() const
Returns number of units from all .debug_info[.dwo] sections.
Definition: DWARFUnit.h:145