]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm-project/llvm/include/llvm/DebugInfo/DWARF/DWARFContext.h
Merge llvm, clang, compiler-rt, libc++, libunwind, lld, lldb and openmp
[FreeBSD/FreeBSD.git] / contrib / llvm-project / llvm / include / llvm / DebugInfo / DWARF / DWARFContext.h
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"
17 #include "llvm/ADT/iterator_range.h"
18 #include "llvm/DebugInfo/DIContext.h"
19 #include "llvm/DebugInfo/DWARF/DWARFAcceleratorTable.h"
20 #include "llvm/DebugInfo/DWARF/DWARFCompileUnit.h"
21 #include "llvm/DebugInfo/DWARF/DWARFDebugAbbrev.h"
22 #include "llvm/DebugInfo/DWARF/DWARFDebugAranges.h"
23 #include "llvm/DebugInfo/DWARF/DWARFDebugFrame.h"
24 #include "llvm/DebugInfo/DWARF/DWARFDebugLine.h"
25 #include "llvm/DebugInfo/DWARF/DWARFDebugLoc.h"
26 #include "llvm/DebugInfo/DWARF/DWARFDebugMacro.h"
27 #include "llvm/DebugInfo/DWARF/DWARFDie.h"
28 #include "llvm/DebugInfo/DWARF/DWARFGdbIndex.h"
29 #include "llvm/DebugInfo/DWARF/DWARFObject.h"
30 #include "llvm/DebugInfo/DWARF/DWARFSection.h"
31 #include "llvm/DebugInfo/DWARF/DWARFTypeUnit.h"
32 #include "llvm/DebugInfo/DWARF/DWARFUnit.h"
33 #include "llvm/DebugInfo/DWARF/DWARFUnitIndex.h"
34 #include "llvm/Object/Binary.h"
35 #include "llvm/Object/ObjectFile.h"
36 #include "llvm/Support/DataExtractor.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 {
84     object::OwningBinary<object::ObjectFile> File;
85     std::unique_ptr<DWARFContext> Context;
86   };
87   StringMap<std::weak_ptr<DWOFile>> DWOFiles;
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
134   using unit_iterator_range = DWARFUnitVector::iterator_range;
135
136   /// Get units from .debug_info in this context.
137   unit_iterator_range info_section_units() {
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.
145   unit_iterator_range types_section_units() {
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.
158   unit_iterator_range normal_units() {
159     parseNormalUnits();
160     return unit_iterator_range(NormalUnits.begin(), NormalUnits.end());
161   }
162
163   /// Get units from .debug_info..dwo in the DWO context.
164   unit_iterator_range dwo_info_section_units() {
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.
171   unit_iterator_range dwo_types_section_units() {
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.
184   unit_iterator_range dwo_units() {
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.
202   unsigned getNumDWOCompileUnits() {
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
245   void setMaxVersionIfGreater(unsigned Version) {
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.
299   Expected<const DWARFDebugLine::LineTable *>
300   getLineTableForUnit(DWARFUnit *U,
301                       std::function<void(Error)> RecoverableErrorCallback);
302
303   DataExtractor getStringExtractor() const {
304     return DataExtractor(DObj->getStringSection(), false, 0);
305   }
306   DataExtractor getLineStringExtractor() const {
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;
313     DWARFDie FunctionDIE;
314     DWARFDie BlockDIE;
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
370   Triple::ArchType getArch() const {
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