/Users/buildslave/jenkins/sharedspace/clang-stage2-coverage-R@2/llvm/include/llvm/DebugInfo/DWARF/DWARFContext.h
Line | Count | Source (jump to first uncovered line) |
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/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 DataExtractor; |
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 | | DWARFUnitSection<DWARFCompileUnit> CUs; |
61 | | std::deque<DWARFUnitSection<DWARFTypeUnit>> TUs; |
62 | | std::unique_ptr<DWARFUnitIndex> CUIndex; |
63 | | std::unique_ptr<DWARFGdbIndex> GdbIndex; |
64 | | std::unique_ptr<DWARFUnitIndex> TUIndex; |
65 | | std::unique_ptr<DWARFDebugAbbrev> Abbrev; |
66 | | std::unique_ptr<DWARFDebugLoc> Loc; |
67 | | std::unique_ptr<DWARFDebugAranges> Aranges; |
68 | | std::unique_ptr<DWARFDebugLine> Line; |
69 | | std::unique_ptr<DWARFDebugFrame> DebugFrame; |
70 | | std::unique_ptr<DWARFDebugFrame> EHFrame; |
71 | | std::unique_ptr<DWARFDebugMacro> Macro; |
72 | | std::unique_ptr<DWARFAcceleratorTable> AppleNames; |
73 | | |
74 | | DWARFUnitSection<DWARFCompileUnit> DWOCUs; |
75 | | std::deque<DWARFUnitSection<DWARFTypeUnit>> DWOTUs; |
76 | | std::unique_ptr<DWARFDebugAbbrev> AbbrevDWO; |
77 | | std::unique_ptr<DWARFDebugLocDWO> LocDWO; |
78 | | |
79 | | /// The maximum DWARF version of all units. |
80 | | unsigned MaxVersion = 0; |
81 | | |
82 | | struct DWOFile { |
83 | | object::OwningBinary<object::ObjectFile> File; |
84 | | std::unique_ptr<DWARFContext> Context; |
85 | | }; |
86 | | StringMap<std::weak_ptr<DWOFile>> DWOFiles; |
87 | | std::weak_ptr<DWOFile> DWP; |
88 | | bool CheckedForDWP = false; |
89 | | std::string DWPName; |
90 | | |
91 | | std::unique_ptr<MCRegisterInfo> RegInfo; |
92 | | |
93 | | /// Read compile units from the debug_info section (if necessary) |
94 | | /// and store them in CUs. |
95 | | void parseCompileUnits(); |
96 | | |
97 | | /// Read type units from the debug_types sections (if necessary) |
98 | | /// and store them in TUs. |
99 | | void parseTypeUnits(); |
100 | | |
101 | | /// Read compile units from the debug_info.dwo section (if necessary) |
102 | | /// and store them in DWOCUs. |
103 | | void parseDWOCompileUnits(); |
104 | | |
105 | | /// Read type units from the debug_types.dwo section (if necessary) |
106 | | /// and store them in DWOTUs. |
107 | | void parseDWOTypeUnits(); |
108 | | |
109 | | protected: |
110 | | std::unique_ptr<const DWARFObject> DObj; |
111 | | |
112 | | public: |
113 | | DWARFContext(std::unique_ptr<const DWARFObject> DObj, |
114 | | std::string DWPName = ""); |
115 | | ~DWARFContext(); |
116 | | |
117 | | DWARFContext(DWARFContext &) = delete; |
118 | | DWARFContext &operator=(DWARFContext &) = delete; |
119 | | |
120 | 0 | const DWARFObject &getDWARFObj() const { return *DObj; } |
121 | | |
122 | 0 | static bool classof(const DIContext *DICtx) { |
123 | 0 | return DICtx->getKind() == CK_DWARF; |
124 | 0 | } |
125 | | |
126 | | /// Dump a textual representation to \p OS. If any \p DumpOffsets are present, |
127 | | /// dump only the record at the specified offset. |
128 | | void dump(raw_ostream &OS, DIDumpOptions DumpOpts, |
129 | | std::array<Optional<uint64_t>, DIDT_ID_Count> DumpOffsets); |
130 | | |
131 | 0 | void dump(raw_ostream &OS, DIDumpOptions DumpOpts) override { |
132 | 0 | std::array<Optional<uint64_t>, DIDT_ID_Count> DumpOffsets; |
133 | 0 | dump(OS, DumpOpts, DumpOffsets); |
134 | 0 | } |
135 | | |
136 | | bool verify(raw_ostream &OS, DIDumpOptions DumpOpts = {}) override; |
137 | | |
138 | | using cu_iterator_range = DWARFUnitSection<DWARFCompileUnit>::iterator_range; |
139 | | using tu_iterator_range = DWARFUnitSection<DWARFTypeUnit>::iterator_range; |
140 | | using tu_section_iterator_range = iterator_range<decltype(TUs)::iterator>; |
141 | | |
142 | | /// Get compile units in this context. |
143 | 0 | cu_iterator_range compile_units() { |
144 | 0 | parseCompileUnits(); |
145 | 0 | return cu_iterator_range(CUs.begin(), CUs.end()); |
146 | 0 | } |
147 | | |
148 | | /// Get type units in this context. |
149 | 0 | tu_section_iterator_range type_unit_sections() { |
150 | 0 | parseTypeUnits(); |
151 | 0 | return tu_section_iterator_range(TUs.begin(), TUs.end()); |
152 | 0 | } |
153 | | |
154 | | /// Get compile units in the DWO context. |
155 | 0 | cu_iterator_range dwo_compile_units() { |
156 | 0 | parseDWOCompileUnits(); |
157 | 0 | return cu_iterator_range(DWOCUs.begin(), DWOCUs.end()); |
158 | 0 | } |
159 | | |
160 | | /// Get type units in the DWO context. |
161 | 0 | tu_section_iterator_range dwo_type_unit_sections() { |
162 | 0 | parseDWOTypeUnits(); |
163 | 0 | return tu_section_iterator_range(DWOTUs.begin(), DWOTUs.end()); |
164 | 0 | } |
165 | | |
166 | | /// Get the number of compile units in this context. |
167 | 0 | unsigned getNumCompileUnits() { |
168 | 0 | parseCompileUnits(); |
169 | 0 | return CUs.size(); |
170 | 0 | } |
171 | | |
172 | | /// Get the number of compile units in this context. |
173 | 0 | unsigned getNumTypeUnits() { |
174 | 0 | parseTypeUnits(); |
175 | 0 | return TUs.size(); |
176 | 0 | } |
177 | | |
178 | | /// Get the number of compile units in the DWO context. |
179 | 0 | unsigned getNumDWOCompileUnits() { |
180 | 0 | parseDWOCompileUnits(); |
181 | 0 | return DWOCUs.size(); |
182 | 0 | } |
183 | | |
184 | | /// Get the number of compile units in the DWO context. |
185 | 0 | unsigned getNumDWOTypeUnits() { |
186 | 0 | parseDWOTypeUnits(); |
187 | 0 | return DWOTUs.size(); |
188 | 0 | } |
189 | | |
190 | | /// Get the compile unit at the specified index for this compile unit. |
191 | 0 | DWARFCompileUnit *getCompileUnitAtIndex(unsigned index) { |
192 | 0 | parseCompileUnits(); |
193 | 0 | return CUs[index].get(); |
194 | 0 | } |
195 | | |
196 | | /// Get the compile unit at the specified index for the DWO compile units. |
197 | 0 | DWARFCompileUnit *getDWOCompileUnitAtIndex(unsigned index) { |
198 | 0 | parseDWOCompileUnits(); |
199 | 0 | return DWOCUs[index].get(); |
200 | 0 | } |
201 | | |
202 | | DWARFCompileUnit *getDWOCompileUnitForHash(uint64_t Hash); |
203 | | |
204 | | /// Get a DIE given an exact offset. |
205 | | DWARFDie getDIEForOffset(uint32_t Offset); |
206 | | |
207 | 0 | unsigned getMaxVersion() const { return MaxVersion; } |
208 | | |
209 | | void setMaxVersionIfGreater(unsigned Version) { |
210 | | if (Version > MaxVersion) |
211 | | MaxVersion = Version; |
212 | | } |
213 | | |
214 | | const DWARFUnitIndex &getCUIndex(); |
215 | | DWARFGdbIndex &getGdbIndex(); |
216 | | const DWARFUnitIndex &getTUIndex(); |
217 | | |
218 | | /// Get a pointer to the parsed DebugAbbrev object. |
219 | | const DWARFDebugAbbrev *getDebugAbbrev(); |
220 | | |
221 | | /// Get a pointer to the parsed DebugLoc object. |
222 | | const DWARFDebugLoc *getDebugLoc(); |
223 | | |
224 | | /// Get a pointer to the parsed dwo abbreviations object. |
225 | | const DWARFDebugAbbrev *getDebugAbbrevDWO(); |
226 | | |
227 | | /// Get a pointer to the parsed DebugLoc object. |
228 | | const DWARFDebugLocDWO *getDebugLocDWO(); |
229 | | |
230 | | /// Get a pointer to the parsed DebugAranges object. |
231 | | const DWARFDebugAranges *getDebugAranges(); |
232 | | |
233 | | /// Get a pointer to the parsed frame information object. |
234 | | const DWARFDebugFrame *getDebugFrame(); |
235 | | |
236 | | /// Get a pointer to the parsed eh frame information object. |
237 | | const DWARFDebugFrame *getEHFrame(); |
238 | | |
239 | | /// Get a pointer to the parsed DebugMacro object. |
240 | | const DWARFDebugMacro *getDebugMacro(); |
241 | | |
242 | | /// Get a reference to the parsed accelerator table object. |
243 | | const DWARFAcceleratorTable &getAppleNames(); |
244 | | |
245 | | /// Get a pointer to a parsed line table corresponding to a compile unit. |
246 | | const DWARFDebugLine::LineTable *getLineTableForUnit(DWARFUnit *cu); |
247 | | |
248 | | DILineInfo getLineInfoForAddress(uint64_t Address, |
249 | | DILineInfoSpecifier Specifier = DILineInfoSpecifier()) override; |
250 | | DILineInfoTable getLineInfoForAddressRange(uint64_t Address, uint64_t Size, |
251 | | DILineInfoSpecifier Specifier = DILineInfoSpecifier()) override; |
252 | | DIInliningInfo getInliningInfoForAddress(uint64_t Address, |
253 | | DILineInfoSpecifier Specifier = DILineInfoSpecifier()) override; |
254 | | |
255 | 0 | bool isLittleEndian() const { return DObj->isLittleEndian(); } |
256 | | static bool isSupportedVersion(unsigned version) { |
257 | | return version == 2 || version == 3 || version == 4 || version == 5; |
258 | | } |
259 | | |
260 | | std::shared_ptr<DWARFContext> getDWOContext(StringRef AbsolutePath); |
261 | | |
262 | 0 | const MCRegisterInfo *getRegisterInfo() const { return RegInfo.get(); } |
263 | | |
264 | | /// Function used to handle default error reporting policy. Prints a error |
265 | | /// message and returns Continue, so DWARF context ignores the error. |
266 | | static ErrorPolicy defaultErrorHandler(Error E); |
267 | | static std::unique_ptr<DWARFContext> |
268 | | create(const object::ObjectFile &Obj, const LoadedObjectInfo *L = nullptr, |
269 | | function_ref<ErrorPolicy(Error)> HandleError = defaultErrorHandler, |
270 | | std::string DWPName = ""); |
271 | | |
272 | | static std::unique_ptr<DWARFContext> |
273 | | create(const StringMap<std::unique_ptr<MemoryBuffer>> &Sections, |
274 | | uint8_t AddrSize, bool isLittleEndian = sys::IsLittleEndianHost); |
275 | | |
276 | | /// Loads register info for the architecture of the provided object file. |
277 | | /// Improves readability of dumped DWARF expressions. Requires the caller to |
278 | | /// have initialized the relevant target descriptions. |
279 | | Error loadRegisterInfo(const object::ObjectFile &Obj); |
280 | | |
281 | | private: |
282 | | /// Return the compile unit that includes an offset (relative to .debug_info). |
283 | | DWARFCompileUnit *getCompileUnitForOffset(uint32_t Offset); |
284 | | |
285 | | /// Return the compile unit which contains instruction with provided |
286 | | /// address. |
287 | | DWARFCompileUnit *getCompileUnitForAddress(uint64_t Address); |
288 | | }; |
289 | | |
290 | | } // end namespace llvm |
291 | | |
292 | | #endif // LLVM_DEBUGINFO_DWARF_DWARFCONTEXT_H |