[Alignment][NFC] Migrate Instructions to Align
[llvm-core.git] / include / llvm / DebugInfo / DWARF / DWARFContext.h
blobfae163622edb381a796de4912b9a9d8754b3dde2
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 //===----------------------------------------------------------------------===/
9 #ifndef LLVM_DEBUGINFO_DWARF_DWARFCONTEXT_H
10 #define LLVM_DEBUGINFO_DWARF_DWARFCONTEXT_H
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>
44 namespace llvm {
46 class MCRegisterInfo;
47 class MemoryBuffer;
48 class raw_ostream;
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 };
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;
76 DWARFUnitVector DWOUnits;
77 std::unique_ptr<DWARFDebugAbbrev> AbbrevDWO;
78 std::unique_ptr<DWARFDebugLoclists> LocDWO;
80 /// The maximum DWARF version of all units.
81 unsigned MaxVersion = 0;
83 struct DWOFile {
84 object::OwningBinary<object::ObjectFile> File;
85 std::unique_ptr<DWARFContext> Context;
87 StringMap<std::weak_ptr<DWOFile>> DWOFiles;
88 std::weak_ptr<DWOFile> DWP;
89 bool CheckedForDWP = false;
90 std::string DWPName;
92 std::unique_ptr<MCRegisterInfo> RegInfo;
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();
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);
106 std::unique_ptr<const DWARFObject> DObj;
108 public:
109 DWARFContext(std::unique_ptr<const DWARFObject> DObj,
110 std::string DWPName = "");
111 ~DWARFContext();
113 DWARFContext(DWARFContext &) = delete;
114 DWARFContext &operator=(DWARFContext &) = delete;
116 const DWARFObject &getDWARFObj() const { return *DObj; }
118 static bool classof(const DIContext *DICtx) {
119 return DICtx->getKind() == CK_DWARF;
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);
127 void dump(raw_ostream &OS, DIDumpOptions DumpOpts) override {
128 std::array<Optional<uint64_t>, DIDT_ID_Count> DumpOffsets;
129 dump(OS, DumpOpts, DumpOffsets);
132 bool verify(raw_ostream &OS, DIDumpOptions DumpOpts = {}) override;
134 using unit_iterator_range = DWARFUnitVector::iterator_range;
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());
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());
151 /// Get compile units in this context.
152 unit_iterator_range compile_units() { return info_section_units(); }
154 /// Get type units in this context.
155 unit_iterator_range type_units() { return types_section_units(); }
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());
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());
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());
177 /// Get compile units in the DWO context.
178 unit_iterator_range dwo_compile_units() { return dwo_info_section_units(); }
180 /// Get type units in the DWO context.
181 unit_iterator_range dwo_type_units() { return dwo_types_section_units(); }
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());
189 /// Get the number of compile units in this context.
190 unsigned getNumCompileUnits() {
191 parseNormalUnits();
192 return NormalUnits.getNumInfoUnits();
195 /// Get the number of type units in this context.
196 unsigned getNumTypeUnits() {
197 parseNormalUnits();
198 return NormalUnits.getNumTypesUnits();
201 /// Get the number of compile units in the DWO context.
202 unsigned getNumDWOCompileUnits() {
203 parseDWOUnits();
204 return DWOUnits.getNumInfoUnits();
207 /// Get the number of type units in the DWO context.
208 unsigned getNumDWOTypeUnits() {
209 parseDWOUnits();
210 return DWOUnits.getNumTypesUnits();
213 /// Get the unit at the specified index.
214 DWARFUnit *getUnitAtIndex(unsigned index) {
215 parseNormalUnits();
216 return NormalUnits[index].get();
219 /// Get the unit at the specified index for the DWO units.
220 DWARFUnit *getDWOUnitAtIndex(unsigned index) {
221 parseDWOUnits();
222 return DWOUnits[index].get();
225 DWARFCompileUnit *getDWOCompileUnitForHash(uint64_t Hash);
227 /// Return the compile unit that includes an offset (relative to .debug_info).
228 DWARFCompileUnit *getCompileUnitForOffset(uint64_t Offset);
230 /// Get a DIE given an exact offset.
231 DWARFDie getDIEForOffset(uint64_t Offset);
233 unsigned getMaxVersion() {
234 // Ensure info units have been parsed to discover MaxVersion
235 info_section_units();
236 return MaxVersion;
239 unsigned getMaxDWOVersion() {
240 // Ensure DWO info units have been parsed to discover MaxVersion
241 dwo_info_section_units();
242 return MaxVersion;
245 void setMaxVersionIfGreater(unsigned Version) {
246 if (Version > MaxVersion)
247 MaxVersion = Version;
250 const DWARFUnitIndex &getCUIndex();
251 DWARFGdbIndex &getGdbIndex();
252 const DWARFUnitIndex &getTUIndex();
254 /// Get a pointer to the parsed DebugAbbrev object.
255 const DWARFDebugAbbrev *getDebugAbbrev();
257 /// Get a pointer to the parsed DebugLoc object.
258 const DWARFDebugLoc *getDebugLoc();
260 /// Get a pointer to the parsed dwo abbreviations object.
261 const DWARFDebugAbbrev *getDebugAbbrevDWO();
263 /// Get a pointer to the parsed DebugLoc object.
264 const DWARFDebugLoclists *getDebugLocDWO();
266 /// Get a pointer to the parsed DebugAranges object.
267 const DWARFDebugAranges *getDebugAranges();
269 /// Get a pointer to the parsed frame information object.
270 const DWARFDebugFrame *getDebugFrame();
272 /// Get a pointer to the parsed eh frame information object.
273 const DWARFDebugFrame *getEHFrame();
275 /// Get a pointer to the parsed DebugMacro object.
276 const DWARFDebugMacro *getDebugMacro();
278 /// Get a reference to the parsed accelerator table object.
279 const DWARFDebugNames &getDebugNames();
281 /// Get a reference to the parsed accelerator table object.
282 const AppleAcceleratorTable &getAppleNames();
284 /// Get a reference to the parsed accelerator table object.
285 const AppleAcceleratorTable &getAppleTypes();
287 /// Get a reference to the parsed accelerator table object.
288 const AppleAcceleratorTable &getAppleNamespaces();
290 /// Get a reference to the parsed accelerator table object.
291 const AppleAcceleratorTable &getAppleObjC();
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);
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);
303 DataExtractor getStringExtractor() const {
304 return DataExtractor(DObj->getStrSection(), false, 0);
306 DataExtractor getLineStringExtractor() const {
307 return DataExtractor(DObj->getLineStrSection(), false, 0);
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; }
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);
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;
334 std::vector<DILocal>
335 getLocalsForAddress(object::SectionedAddress Address) override;
337 bool isLittleEndian() const { return DObj->isLittleEndian(); }
338 static bool isSupportedVersion(unsigned version) {
339 return version == 2 || version == 3 || version == 4 || version == 5;
342 std::shared_ptr<DWARFContext> getDWOContext(StringRef AbsolutePath);
344 const MCRegisterInfo *getRegisterInfo() const { return RegInfo.get(); }
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 = "");
354 static std::unique_ptr<DWARFContext>
355 create(const StringMap<std::unique_ptr<MemoryBuffer>> &Sections,
356 uint8_t AddrSize, bool isLittleEndian = sys::IsLittleEndianHost);
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);
363 /// Get address size from CUs.
364 /// TODO: refactor compile_units() to make this const.
365 uint8_t getCUAddrSize();
367 /// Dump Error as warning message to stderr.
368 static void dumpWarning(Error Warning);
370 Triple::ArchType getArch() const {
371 return getDWARFObj().getFile()->getArch();
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);
384 } // end namespace llvm
386 #endif // LLVM_DEBUGINFO_DWARF_DWARFCONTEXT_H