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_LIB_DEBUGINFO_DWARFCONTEXT_H
11#define LLVM_LIB_DEBUGINFO_DWARFCONTEXT_H
12
13#include "llvm/ADT/MapVector.h"
14#include "llvm/ADT/SmallVector.h"
15#include "llvm/DebugInfo/DWARF/DIContext.h"
16#include "llvm/DebugInfo/DWARF/DWARFCompileUnit.h"
17#include "llvm/DebugInfo/DWARF/DWARFDebugAranges.h"
18#include "llvm/DebugInfo/DWARF/DWARFDebugFrame.h"
19#include "llvm/DebugInfo/DWARF/DWARFDebugLine.h"
20#include "llvm/DebugInfo/DWARF/DWARFDebugLoc.h"
21#include "llvm/DebugInfo/DWARF/DWARFDebugRangeList.h"
22#include "llvm/DebugInfo/DWARF/DWARFSection.h"
23#include "llvm/DebugInfo/DWARF/DWARFTypeUnit.h"
24#include <vector>
25
26namespace llvm {
27
28/// DWARFContext
29/// This data structure is the top level entity that deals with dwarf debug
30/// information parsing. The actual data is supplied through pure virtual
31/// methods that a concrete implementation provides.
32class DWARFContext : public DIContext {
33
34  DWARFUnitSection<DWARFCompileUnit> CUs;
35  std::vector<DWARFUnitSection<DWARFTypeUnit>> TUs;
36  std::unique_ptr<DWARFDebugAbbrev> Abbrev;
37  std::unique_ptr<DWARFDebugLoc> Loc;
38  std::unique_ptr<DWARFDebugAranges> Aranges;
39  std::unique_ptr<DWARFDebugLine> Line;
40  std::unique_ptr<DWARFDebugFrame> DebugFrame;
41
42  DWARFUnitSection<DWARFCompileUnit> DWOCUs;
43  std::vector<DWARFUnitSection<DWARFTypeUnit>> DWOTUs;
44  std::unique_ptr<DWARFDebugAbbrev> AbbrevDWO;
45  std::unique_ptr<DWARFDebugLocDWO> LocDWO;
46
47  DWARFContext(DWARFContext &) = delete;
48  DWARFContext &operator=(DWARFContext &) = delete;
49
50  /// Read compile units from the debug_info section (if necessary)
51  /// and store them in CUs.
52  void parseCompileUnits();
53
54  /// Read type units from the debug_types sections (if necessary)
55  /// and store them in TUs.
56  void parseTypeUnits();
57
58  /// Read compile units from the debug_info.dwo section (if necessary)
59  /// and store them in DWOCUs.
60  void parseDWOCompileUnits();
61
62  /// Read type units from the debug_types.dwo section (if necessary)
63  /// and store them in DWOTUs.
64  void parseDWOTypeUnits();
65
66public:
67  DWARFContext() : DIContext(CK_DWARF) {}
68
69  static bool classof(const DIContext *DICtx) {
70    return DICtx->getKind() == CK_DWARF;
71  }
72
73  void dump(raw_ostream &OS, DIDumpType DumpType = DIDT_All) override;
74
75  typedef DWARFUnitSection<DWARFCompileUnit>::iterator_range cu_iterator_range;
76  typedef DWARFUnitSection<DWARFTypeUnit>::iterator_range tu_iterator_range;
77  typedef iterator_range<std::vector<DWARFUnitSection<DWARFTypeUnit>>::iterator> tu_section_iterator_range;
78
79  /// Get compile units in this context.
80  cu_iterator_range compile_units() {
81    parseCompileUnits();
82    return cu_iterator_range(CUs.begin(), CUs.end());
83  }
84
85  /// Get type units in this context.
86  tu_section_iterator_range type_unit_sections() {
87    parseTypeUnits();
88    return tu_section_iterator_range(TUs.begin(), TUs.end());
89  }
90
91  /// Get compile units in the DWO context.
92  cu_iterator_range dwo_compile_units() {
93    parseDWOCompileUnits();
94    return cu_iterator_range(DWOCUs.begin(), DWOCUs.end());
95  }
96
97  /// Get type units in the DWO context.
98  tu_section_iterator_range dwo_type_unit_sections() {
99    parseDWOTypeUnits();
100    return tu_section_iterator_range(DWOTUs.begin(), DWOTUs.end());
101  }
102
103  /// Get the number of compile units in this context.
104  unsigned getNumCompileUnits() {
105    parseCompileUnits();
106    return CUs.size();
107  }
108
109  /// Get the number of compile units in this context.
110  unsigned getNumTypeUnits() {
111    parseTypeUnits();
112    return TUs.size();
113  }
114
115  /// Get the number of compile units in the DWO context.
116  unsigned getNumDWOCompileUnits() {
117    parseDWOCompileUnits();
118    return DWOCUs.size();
119  }
120
121  /// Get the number of compile units in the DWO context.
122  unsigned getNumDWOTypeUnits() {
123    parseDWOTypeUnits();
124    return DWOTUs.size();
125  }
126
127  /// Get the compile unit at the specified index for this compile unit.
128  DWARFCompileUnit *getCompileUnitAtIndex(unsigned index) {
129    parseCompileUnits();
130    return CUs[index].get();
131  }
132
133  /// Get the compile unit at the specified index for the DWO compile units.
134  DWARFCompileUnit *getDWOCompileUnitAtIndex(unsigned index) {
135    parseDWOCompileUnits();
136    return DWOCUs[index].get();
137  }
138
139  /// Get a pointer to the parsed DebugAbbrev object.
140  const DWARFDebugAbbrev *getDebugAbbrev();
141
142  /// Get a pointer to the parsed DebugLoc object.
143  const DWARFDebugLoc *getDebugLoc();
144
145  /// Get a pointer to the parsed dwo abbreviations object.
146  const DWARFDebugAbbrev *getDebugAbbrevDWO();
147
148  /// Get a pointer to the parsed DebugLoc object.
149  const DWARFDebugLocDWO *getDebugLocDWO();
150
151  /// Get a pointer to the parsed DebugAranges object.
152  const DWARFDebugAranges *getDebugAranges();
153
154  /// Get a pointer to the parsed frame information object.
155  const DWARFDebugFrame *getDebugFrame();
156
157  /// Get a pointer to a parsed line table corresponding to a compile unit.
158  const DWARFDebugLine::LineTable *getLineTableForUnit(DWARFUnit *cu);
159
160  DILineInfo getLineInfoForAddress(uint64_t Address,
161      DILineInfoSpecifier Specifier = DILineInfoSpecifier()) override;
162  DILineInfoTable getLineInfoForAddressRange(uint64_t Address, uint64_t Size,
163      DILineInfoSpecifier Specifier = DILineInfoSpecifier()) override;
164  DIInliningInfo getInliningInfoForAddress(uint64_t Address,
165      DILineInfoSpecifier Specifier = DILineInfoSpecifier()) override;
166
167  virtual bool isLittleEndian() const = 0;
168  virtual uint8_t getAddressSize() const = 0;
169  virtual const DWARFSection &getInfoSection() = 0;
170  typedef MapVector<object::SectionRef, DWARFSection,
171                    std::map<object::SectionRef, unsigned>> TypeSectionMap;
172  virtual const TypeSectionMap &getTypesSections() = 0;
173  virtual StringRef getAbbrevSection() = 0;
174  virtual const DWARFSection &getLocSection() = 0;
175  virtual StringRef getARangeSection() = 0;
176  virtual StringRef getDebugFrameSection() = 0;
177  virtual const DWARFSection &getLineSection() = 0;
178  virtual StringRef getStringSection() = 0;
179  virtual StringRef getRangeSection() = 0;
180  virtual StringRef getPubNamesSection() = 0;
181  virtual StringRef getPubTypesSection() = 0;
182  virtual StringRef getGnuPubNamesSection() = 0;
183  virtual StringRef getGnuPubTypesSection() = 0;
184
185  // Sections for DWARF5 split dwarf proposal.
186  virtual const DWARFSection &getInfoDWOSection() = 0;
187  virtual const TypeSectionMap &getTypesDWOSections() = 0;
188  virtual StringRef getAbbrevDWOSection() = 0;
189  virtual const DWARFSection &getLineDWOSection() = 0;
190  virtual const DWARFSection &getLocDWOSection() = 0;
191  virtual StringRef getStringDWOSection() = 0;
192  virtual StringRef getStringOffsetDWOSection() = 0;
193  virtual StringRef getRangeDWOSection() = 0;
194  virtual StringRef getAddrSection() = 0;
195  virtual const DWARFSection& getAppleNamesSection() = 0;
196  virtual const DWARFSection& getAppleTypesSection() = 0;
197  virtual const DWARFSection& getAppleNamespacesSection() = 0;
198  virtual const DWARFSection& getAppleObjCSection() = 0;
199
200  static bool isSupportedVersion(unsigned version) {
201    return version == 2 || version == 3 || version == 4;
202  }
203private:
204  /// Return the compile unit that includes an offset (relative to .debug_info).
205  DWARFCompileUnit *getCompileUnitForOffset(uint32_t Offset);
206
207  /// Return the compile unit which contains instruction with provided
208  /// address.
209  DWARFCompileUnit *getCompileUnitForAddress(uint64_t Address);
210};
211
212/// DWARFContextInMemory is the simplest possible implementation of a
213/// DWARFContext. It assumes all content is available in memory and stores
214/// pointers to it.
215class DWARFContextInMemory : public DWARFContext {
216  virtual void anchor();
217  bool IsLittleEndian;
218  uint8_t AddressSize;
219  DWARFSection InfoSection;
220  TypeSectionMap TypesSections;
221  StringRef AbbrevSection;
222  DWARFSection LocSection;
223  StringRef ARangeSection;
224  StringRef DebugFrameSection;
225  DWARFSection LineSection;
226  StringRef StringSection;
227  StringRef RangeSection;
228  StringRef PubNamesSection;
229  StringRef PubTypesSection;
230  StringRef GnuPubNamesSection;
231  StringRef GnuPubTypesSection;
232
233  // Sections for DWARF5 split dwarf proposal.
234  DWARFSection InfoDWOSection;
235  TypeSectionMap TypesDWOSections;
236  StringRef AbbrevDWOSection;
237  DWARFSection LineDWOSection;
238  DWARFSection LocDWOSection;
239  StringRef StringDWOSection;
240  StringRef StringOffsetDWOSection;
241  StringRef RangeDWOSection;
242  StringRef AddrSection;
243  DWARFSection AppleNamesSection;
244  DWARFSection AppleTypesSection;
245  DWARFSection AppleNamespacesSection;
246  DWARFSection AppleObjCSection;
247
248  SmallVector<SmallString<32>, 4> UncompressedSections;
249
250public:
251  DWARFContextInMemory(const object::ObjectFile &Obj);
252  bool isLittleEndian() const override { return IsLittleEndian; }
253  uint8_t getAddressSize() const override { return AddressSize; }
254  const DWARFSection &getInfoSection() override { return InfoSection; }
255  const TypeSectionMap &getTypesSections() override { return TypesSections; }
256  StringRef getAbbrevSection() override { return AbbrevSection; }
257  const DWARFSection &getLocSection() override { return LocSection; }
258  StringRef getARangeSection() override { return ARangeSection; }
259  StringRef getDebugFrameSection() override { return DebugFrameSection; }
260  const DWARFSection &getLineSection() override { return LineSection; }
261  StringRef getStringSection() override { return StringSection; }
262  StringRef getRangeSection() override { return RangeSection; }
263  StringRef getPubNamesSection() override { return PubNamesSection; }
264  StringRef getPubTypesSection() override { return PubTypesSection; }
265  StringRef getGnuPubNamesSection() override { return GnuPubNamesSection; }
266  StringRef getGnuPubTypesSection() override { return GnuPubTypesSection; }
267  const DWARFSection& getAppleNamesSection() override { return AppleNamesSection; }
268  const DWARFSection& getAppleTypesSection() override { return AppleTypesSection; }
269  const DWARFSection& getAppleNamespacesSection() override { return AppleNamespacesSection; }
270  const DWARFSection& getAppleObjCSection() override { return AppleObjCSection; }
271
272  // Sections for DWARF5 split dwarf proposal.
273  const DWARFSection &getInfoDWOSection() override { return InfoDWOSection; }
274  const TypeSectionMap &getTypesDWOSections() override {
275    return TypesDWOSections;
276  }
277  StringRef getAbbrevDWOSection() override { return AbbrevDWOSection; }
278  const DWARFSection &getLineDWOSection() override { return LineDWOSection; }
279  const DWARFSection &getLocDWOSection() override { return LocDWOSection; }
280  StringRef getStringDWOSection() override { return StringDWOSection; }
281  StringRef getStringOffsetDWOSection() override {
282    return StringOffsetDWOSection;
283  }
284  StringRef getRangeDWOSection() override { return RangeDWOSection; }
285  StringRef getAddrSection() override {
286    return AddrSection;
287  }
288};
289
290}
291
292#endif
293