LLVM  10.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(uint64_t Offset);
229 
230  /// Get a DIE given an exact offset.
231  DWARFDie getDIEForOffset(uint64_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->getStrSection(), false, 0);
305  }
307  return DataExtractor(DObj->getLineStrSection(), 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  /// TODO: change input parameter from "uint64_t Address"
321  /// into "SectionedAddress Address"
322  DIEsForAddress getDIEsForAddress(uint64_t Address);
323 
324  DILineInfo getLineInfoForAddress(
325  object::SectionedAddress Address,
326  DILineInfoSpecifier Specifier = DILineInfoSpecifier()) override;
327  DILineInfoTable getLineInfoForAddressRange(
328  object::SectionedAddress Address, uint64_t Size,
329  DILineInfoSpecifier Specifier = DILineInfoSpecifier()) override;
330  DIInliningInfo getInliningInfoForAddress(
331  object::SectionedAddress Address,
332  DILineInfoSpecifier Specifier = DILineInfoSpecifier()) override;
333 
334  std::vector<DILocal>
335  getLocalsForAddress(object::SectionedAddress Address) override;
336 
337  bool isLittleEndian() const { return DObj->isLittleEndian(); }
338  static bool isSupportedVersion(unsigned version) {
339  return version == 2 || version == 3 || version == 4 || version == 5;
340  }
341 
342  std::shared_ptr<DWARFContext> getDWOContext(StringRef AbsolutePath);
343 
344  const MCRegisterInfo *getRegisterInfo() const { return RegInfo.get(); }
345 
346  /// Function used to handle default error reporting policy. Prints a error
347  /// message and returns Continue, so DWARF context ignores the error.
348  static ErrorPolicy defaultErrorHandler(Error E);
349  static std::unique_ptr<DWARFContext>
350  create(const object::ObjectFile &Obj, const LoadedObjectInfo *L = nullptr,
351  function_ref<ErrorPolicy(Error)> HandleError = defaultErrorHandler,
352  std::string DWPName = "");
353 
354  static std::unique_ptr<DWARFContext>
355  create(const StringMap<std::unique_ptr<MemoryBuffer>> &Sections,
356  uint8_t AddrSize, bool isLittleEndian = sys::IsLittleEndianHost);
357 
358  /// Loads register info for the architecture of the provided object file.
359  /// Improves readability of dumped DWARF expressions. Requires the caller to
360  /// have initialized the relevant target descriptions.
361  Error loadRegisterInfo(const object::ObjectFile &Obj);
362 
363  /// Get address size from CUs.
364  /// TODO: refactor compile_units() to make this const.
365  uint8_t getCUAddrSize();
366 
367  /// Dump Error as warning message to stderr.
368  static void dumpWarning(Error Warning);
369 
371  return getDWARFObj().getFile()->getArch();
372  }
373 
374 private:
375  /// Return the compile unit which contains instruction with provided
376  /// address.
377  /// TODO: change input parameter from "uint64_t Address"
378  /// into "SectionedAddress Address"
379  DWARFCompileUnit *getCompileUnitForAddress(uint64_t Address);
380  void addLocalsForDie(DWARFCompileUnit *CU, DWARFDie Subprogram, DWARFDie Die,
381  std::vector<DILocal> &Result);
382 };
383 
384 } // end namespace llvm
385 
386 #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:104
This class is the base class for all object file types.
Definition: ObjectFile.h:221
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:370
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: yaml2obj.h:21
const MCRegisterInfo * getRegisterInfo() const
Definition: DWARFContext.h:344
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:123
DIContextKind getKind() const
Definition: DIContext.h:214
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:171
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:135
Instrumentation for Order File
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
A format-neutral container for inlined code description.
Definition: DIContext.h:81
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
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:837
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:113
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:243
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:338
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:337
const DWARFObject & getDWARFObj() const
Definition: DWARFContext.h:116
static bool classof(const DIContext *DICtx)
Definition: DWARFContext.h:118
const MCRegisterDesc & get(MCRegister RegNo) const
Provide a get method, equivalent to [], but more useful with a pointer to this object.
unsigned getNumTypesUnits() const
Returns number of units from all .debug_types[.dwo] sections.
Definition: DWARFUnit.h:153
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:984
void setMaxVersionIfGreater(unsigned Version)
Definition: DWARFContext.h:245
unsigned getNumInfoUnits() const
Returns number of units from all .debug_info[.dwo] sections.
Definition: DWARFUnit.h:149