]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm/include/llvm/DebugInfo/DWARF/DWARFContext.h
Merge llvm, clang, compiler-rt, libc++, libunwind, lld, lldb and openmp
[FreeBSD/FreeBSD.git] / contrib / llvm / include / llvm / DebugInfo / DWARF / DWARFContext.h
1 //===- DWARFContext.h -------------------------------------------*- C++ -*-===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===/
9
10 #ifndef LLVM_DEBUGINFO_DWARF_DWARFCONTEXT_H
11 #define LLVM_DEBUGINFO_DWARF_DWARFCONTEXT_H
12
13 #include "llvm/ADT/MapVector.h"
14 #include "llvm/ADT/SmallString.h"
15 #include "llvm/ADT/SmallVector.h"
16 #include "llvm/ADT/StringMap.h"
17 #include "llvm/ADT/StringRef.h"
18 #include "llvm/ADT/iterator_range.h"
19 #include "llvm/DebugInfo/DIContext.h"
20 #include "llvm/DebugInfo/DWARF/DWARFAcceleratorTable.h"
21 #include "llvm/DebugInfo/DWARF/DWARFCompileUnit.h"
22 #include "llvm/DebugInfo/DWARF/DWARFDebugAbbrev.h"
23 #include "llvm/DebugInfo/DWARF/DWARFDebugAranges.h"
24 #include "llvm/DebugInfo/DWARF/DWARFDebugFrame.h"
25 #include "llvm/DebugInfo/DWARF/DWARFDebugLine.h"
26 #include "llvm/DebugInfo/DWARF/DWARFDebugLoc.h"
27 #include "llvm/DebugInfo/DWARF/DWARFDebugMacro.h"
28 #include "llvm/DebugInfo/DWARF/DWARFDie.h"
29 #include "llvm/DebugInfo/DWARF/DWARFGdbIndex.h"
30 #include "llvm/DebugInfo/DWARF/DWARFObject.h"
31 #include "llvm/DebugInfo/DWARF/DWARFSection.h"
32 #include "llvm/DebugInfo/DWARF/DWARFTypeUnit.h"
33 #include "llvm/DebugInfo/DWARF/DWARFUnit.h"
34 #include "llvm/DebugInfo/DWARF/DWARFUnitIndex.h"
35 #include "llvm/Object/Binary.h"
36 #include "llvm/Object/ObjectFile.h"
37 #include "llvm/Support/DataExtractor.h"
38 #include "llvm/Support/Error.h"
39 #include "llvm/Support/Host.h"
40 #include <cstdint>
41 #include <deque>
42 #include <map>
43 #include <memory>
44
45 namespace llvm {
46
47 class MCRegisterInfo;
48 class MemoryBuffer;
49 class raw_ostream;
50
51 /// Used as a return value for a error callback passed to DWARF context.
52 /// Callback should return Halt if client application wants to stop
53 /// object parsing, or should return Continue otherwise.
54 enum class ErrorPolicy { Halt, Continue };
55
56 /// DWARFContext
57 /// This data structure is the top level entity that deals with dwarf debug
58 /// information parsing. The actual data is supplied through DWARFObj.
59 class DWARFContext : public DIContext {
60   DWARFUnitVector NormalUnits;
61   std::unique_ptr<DWARFUnitIndex> CUIndex;
62   std::unique_ptr<DWARFGdbIndex> GdbIndex;
63   std::unique_ptr<DWARFUnitIndex> TUIndex;
64   std::unique_ptr<DWARFDebugAbbrev> Abbrev;
65   std::unique_ptr<DWARFDebugLoc> Loc;
66   std::unique_ptr<DWARFDebugAranges> Aranges;
67   std::unique_ptr<DWARFDebugLine> Line;
68   std::unique_ptr<DWARFDebugFrame> DebugFrame;
69   std::unique_ptr<DWARFDebugFrame> EHFrame;
70   std::unique_ptr<DWARFDebugMacro> Macro;
71   std::unique_ptr<DWARFDebugNames> Names;
72   std::unique_ptr<AppleAcceleratorTable> AppleNames;
73   std::unique_ptr<AppleAcceleratorTable> AppleTypes;
74   std::unique_ptr<AppleAcceleratorTable> AppleNamespaces;
75   std::unique_ptr<AppleAcceleratorTable> AppleObjC;
76
77   DWARFUnitVector DWOUnits;
78   std::unique_ptr<DWARFDebugAbbrev> AbbrevDWO;
79   std::unique_ptr<DWARFDebugLoclists> LocDWO;
80
81   /// The maximum DWARF version of all units.
82   unsigned MaxVersion = 0;
83
84   struct DWOFile {
85     object::OwningBinary<object::ObjectFile> File;
86     std::unique_ptr<DWARFContext> Context;
87   };
88   StringMap<std::weak_ptr<DWOFile>> DWOFiles;
89   std::weak_ptr<DWOFile> DWP;
90   bool CheckedForDWP = false;
91   std::string DWPName;
92
93   std::unique_ptr<MCRegisterInfo> RegInfo;
94
95   /// Read compile units from the debug_info section (if necessary)
96   /// and type units from the debug_types sections (if necessary)
97   /// and store them in NormalUnits.
98   void parseNormalUnits();
99
100   /// Read compile units from the debug_info.dwo section (if necessary)
101   /// and type units from the debug_types.dwo section (if necessary)
102   /// and store them in DWOUnits.
103   /// If \p Lazy is true, set up to parse but don't actually parse them.
104   enum { EagerParse = false, LazyParse = true };
105   void parseDWOUnits(bool Lazy = false);
106
107   std::unique_ptr<const DWARFObject> DObj;
108
109 public:
110   DWARFContext(std::unique_ptr<const DWARFObject> DObj,
111                std::string DWPName = "");
112   ~DWARFContext();
113
114   DWARFContext(DWARFContext &) = delete;
115   DWARFContext &operator=(DWARFContext &) = delete;
116
117   const DWARFObject &getDWARFObj() const { return *DObj; }
118
119   static bool classof(const DIContext *DICtx) {
120     return DICtx->getKind() == CK_DWARF;
121   }
122
123   /// Dump a textual representation to \p OS. If any \p DumpOffsets are present,
124   /// dump only the record at the specified offset.
125   void dump(raw_ostream &OS, DIDumpOptions DumpOpts,
126             std::array<Optional<uint64_t>, DIDT_ID_Count> DumpOffsets);
127
128   void dump(raw_ostream &OS, DIDumpOptions DumpOpts) override {
129     std::array<Optional<uint64_t>, DIDT_ID_Count> DumpOffsets;
130     dump(OS, DumpOpts, DumpOffsets);
131   }
132
133   bool verify(raw_ostream &OS, DIDumpOptions DumpOpts = {}) override;
134
135   using unit_iterator_range = DWARFUnitVector::iterator_range;
136
137   /// Get units from .debug_info in this context.
138   unit_iterator_range info_section_units() {
139     parseNormalUnits();
140     return unit_iterator_range(NormalUnits.begin(),
141                                NormalUnits.begin() +
142                                    NormalUnits.getNumInfoUnits());
143   }
144
145   /// Get units from .debug_types in this context.
146   unit_iterator_range types_section_units() {
147     parseNormalUnits();
148     return unit_iterator_range(
149         NormalUnits.begin() + NormalUnits.getNumInfoUnits(), NormalUnits.end());
150   }
151
152   /// Get compile units in this context.
153   unit_iterator_range compile_units() { return info_section_units(); }
154
155   /// Get type units in this context.
156   unit_iterator_range type_units() { return types_section_units(); }
157
158   /// Get all normal compile/type units in this context.
159   unit_iterator_range normal_units() {
160     parseNormalUnits();
161     return unit_iterator_range(NormalUnits.begin(), NormalUnits.end());
162   }
163
164   /// Get units from .debug_info..dwo in the DWO context.
165   unit_iterator_range dwo_info_section_units() {
166     parseDWOUnits();
167     return unit_iterator_range(DWOUnits.begin(),
168                                DWOUnits.begin() + DWOUnits.getNumInfoUnits());
169   }
170
171   /// Get units from .debug_types.dwo in the DWO context.
172   unit_iterator_range dwo_types_section_units() {
173     parseDWOUnits();
174     return unit_iterator_range(DWOUnits.begin() + DWOUnits.getNumInfoUnits(),
175                                DWOUnits.end());
176   }
177
178   /// Get compile units in the DWO context.
179   unit_iterator_range dwo_compile_units() { return dwo_info_section_units(); }
180
181   /// Get type units in the DWO context.
182   unit_iterator_range dwo_type_units() { return dwo_types_section_units(); }
183
184   /// Get all units in the DWO context.
185   unit_iterator_range dwo_units() {
186     parseDWOUnits();
187     return unit_iterator_range(DWOUnits.begin(), DWOUnits.end());
188   }
189
190   /// Get the number of compile units in this context.
191   unsigned getNumCompileUnits() {
192     parseNormalUnits();
193     return NormalUnits.getNumInfoUnits();
194   }
195
196   /// Get the number of type units in this context.
197   unsigned getNumTypeUnits() {
198     parseNormalUnits();
199     return NormalUnits.getNumTypesUnits();
200   }
201
202   /// Get the number of compile units in the DWO context.
203   unsigned getNumDWOCompileUnits() {
204     parseDWOUnits();
205     return DWOUnits.getNumInfoUnits();
206   }
207
208   /// Get the number of type units in the DWO context.
209   unsigned getNumDWOTypeUnits() {
210     parseDWOUnits();
211     return DWOUnits.getNumTypesUnits();
212   }
213
214   /// Get the unit at the specified index.
215   DWARFUnit *getUnitAtIndex(unsigned index) {
216     parseNormalUnits();
217     return NormalUnits[index].get();
218   }
219
220   /// Get the unit at the specified index for the DWO units.
221   DWARFUnit *getDWOUnitAtIndex(unsigned index) {
222     parseDWOUnits();
223     return DWOUnits[index].get();
224   }
225
226   DWARFCompileUnit *getDWOCompileUnitForHash(uint64_t Hash);
227
228   /// Return the compile unit that includes an offset (relative to .debug_info).
229   DWARFCompileUnit *getCompileUnitForOffset(uint32_t Offset);
230
231   /// Get a DIE given an exact offset.
232   DWARFDie getDIEForOffset(uint32_t Offset);
233
234   unsigned getMaxVersion() {
235     // Ensure info units have been parsed to discover MaxVersion
236     info_section_units();
237     return MaxVersion;
238   }
239
240   unsigned getMaxDWOVersion() {
241     // Ensure DWO info units have been parsed to discover MaxVersion
242     dwo_info_section_units();
243     return MaxVersion;
244   }
245
246   void setMaxVersionIfGreater(unsigned Version) {
247     if (Version > MaxVersion)
248       MaxVersion = Version;
249   }
250
251   const DWARFUnitIndex &getCUIndex();
252   DWARFGdbIndex &getGdbIndex();
253   const DWARFUnitIndex &getTUIndex();
254
255   /// Get a pointer to the parsed DebugAbbrev object.
256   const DWARFDebugAbbrev *getDebugAbbrev();
257
258   /// Get a pointer to the parsed DebugLoc object.
259   const DWARFDebugLoc *getDebugLoc();
260
261   /// Get a pointer to the parsed dwo abbreviations object.
262   const DWARFDebugAbbrev *getDebugAbbrevDWO();
263
264   /// Get a pointer to the parsed DebugLoc object.
265   const DWARFDebugLoclists *getDebugLocDWO();
266
267   /// Get a pointer to the parsed DebugAranges object.
268   const DWARFDebugAranges *getDebugAranges();
269
270   /// Get a pointer to the parsed frame information object.
271   const DWARFDebugFrame *getDebugFrame();
272
273   /// Get a pointer to the parsed eh frame information object.
274   const DWARFDebugFrame *getEHFrame();
275
276   /// Get a pointer to the parsed DebugMacro object.
277   const DWARFDebugMacro *getDebugMacro();
278
279   /// Get a reference to the parsed accelerator table object.
280   const DWARFDebugNames &getDebugNames();
281
282   /// Get a reference to the parsed accelerator table object.
283   const AppleAcceleratorTable &getAppleNames();
284
285   /// Get a reference to the parsed accelerator table object.
286   const AppleAcceleratorTable &getAppleTypes();
287
288   /// Get a reference to the parsed accelerator table object.
289   const AppleAcceleratorTable &getAppleNamespaces();
290
291   /// Get a reference to the parsed accelerator table object.
292   const AppleAcceleratorTable &getAppleObjC();
293
294   /// Get a pointer to a parsed line table corresponding to a compile unit.
295   /// Report any parsing issues as warnings on stderr.
296   const DWARFDebugLine::LineTable *getLineTableForUnit(DWARFUnit *U);
297
298   /// Get a pointer to a parsed line table corresponding to a compile unit.
299   /// Report any recoverable parsing problems using the callback.
300   Expected<const DWARFDebugLine::LineTable *>
301   getLineTableForUnit(DWARFUnit *U,
302                       std::function<void(Error)> RecoverableErrorCallback);
303
304   DataExtractor getStringExtractor() const {
305     return DataExtractor(DObj->getStringSection(), false, 0);
306   }
307   DataExtractor getLineStringExtractor() const {
308     return DataExtractor(DObj->getLineStringSection(), false, 0);
309   }
310
311   /// Wraps the returned DIEs for a given address.
312   struct DIEsForAddress {
313     DWARFCompileUnit *CompileUnit = nullptr;
314     DWARFDie FunctionDIE;
315     DWARFDie BlockDIE;
316     explicit operator bool() const { return CompileUnit != nullptr; }
317   };
318
319   /// Get the compilation unit, the function DIE and lexical block DIE for the
320   /// given address where applicable.
321   DIEsForAddress getDIEsForAddress(uint64_t Address);
322
323   DILineInfo getLineInfoForAddress(uint64_t Address,
324       DILineInfoSpecifier Specifier = DILineInfoSpecifier()) override;
325   DILineInfoTable getLineInfoForAddressRange(uint64_t Address, uint64_t Size,
326       DILineInfoSpecifier Specifier = DILineInfoSpecifier()) override;
327   DIInliningInfo getInliningInfoForAddress(uint64_t Address,
328       DILineInfoSpecifier Specifier = DILineInfoSpecifier()) override;
329
330   bool isLittleEndian() const { return DObj->isLittleEndian(); }
331   static bool isSupportedVersion(unsigned version) {
332     return version == 2 || version == 3 || version == 4 || version == 5;
333   }
334
335   std::shared_ptr<DWARFContext> getDWOContext(StringRef AbsolutePath);
336
337   const MCRegisterInfo *getRegisterInfo() const { return RegInfo.get(); }
338
339   /// Function used to handle default error reporting policy. Prints a error
340   /// message and returns Continue, so DWARF context ignores the error.
341   static ErrorPolicy defaultErrorHandler(Error E);
342   static std::unique_ptr<DWARFContext>
343   create(const object::ObjectFile &Obj, const LoadedObjectInfo *L = nullptr,
344          function_ref<ErrorPolicy(Error)> HandleError = defaultErrorHandler,
345          std::string DWPName = "");
346
347   static std::unique_ptr<DWARFContext>
348   create(const StringMap<std::unique_ptr<MemoryBuffer>> &Sections,
349          uint8_t AddrSize, bool isLittleEndian = sys::IsLittleEndianHost);
350
351   /// Loads register info for the architecture of the provided object file.
352   /// Improves readability of dumped DWARF expressions. Requires the caller to
353   /// have initialized the relevant target descriptions.
354   Error loadRegisterInfo(const object::ObjectFile &Obj);
355
356   /// Get address size from CUs.
357   /// TODO: refactor compile_units() to make this const.
358   uint8_t getCUAddrSize();
359
360   /// Dump Error as warning message to stderr.
361   static void dumpWarning(Error Warning);
362
363   Triple::ArchType getArch() const {
364     return getDWARFObj().getFile()->getArch();
365   }
366
367 private:
368   /// Return the compile unit which contains instruction with provided
369   /// address.
370   DWARFCompileUnit *getCompileUnitForAddress(uint64_t Address);
371 };
372
373 } // end namespace llvm
374
375 #endif // LLVM_DEBUGINFO_DWARF_DWARFCONTEXT_H