Line data Source code
1 : //===- DWARFUnit.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_DWARFUNIT_H
11 : #define LLVM_DEBUGINFO_DWARF_DWARFUNIT_H
12 :
13 : #include "llvm/ADT/Optional.h"
14 : #include "llvm/ADT/STLExtras.h"
15 : #include "llvm/ADT/SmallVector.h"
16 : #include "llvm/ADT/StringRef.h"
17 : #include "llvm/ADT/iterator_range.h"
18 : #include "llvm/BinaryFormat/Dwarf.h"
19 : #include "llvm/DebugInfo/DWARF/DWARFDebugInfoEntry.h"
20 : #include "llvm/DebugInfo/DWARF/DWARFDebugRangeList.h"
21 : #include "llvm/DebugInfo/DWARF/DWARFDebugRnglists.h"
22 : #include "llvm/DebugInfo/DWARF/DWARFDie.h"
23 : #include "llvm/DebugInfo/DWARF/DWARFFormValue.h"
24 : #include "llvm/DebugInfo/DWARF/DWARFRelocMap.h"
25 : #include "llvm/DebugInfo/DWARF/DWARFSection.h"
26 : #include "llvm/DebugInfo/DWARF/DWARFUnitIndex.h"
27 : #include "llvm/Support/DataExtractor.h"
28 : #include <algorithm>
29 : #include <cassert>
30 : #include <cstddef>
31 : #include <cstdint>
32 : #include <map>
33 : #include <memory>
34 : #include <utility>
35 : #include <vector>
36 :
37 : namespace llvm {
38 :
39 : class DWARFAbbreviationDeclarationSet;
40 : class DWARFContext;
41 : class DWARFDebugAbbrev;
42 : class DWARFUnit;
43 :
44 : /// Base class describing the header of any kind of "unit." Some information
45 : /// is specific to certain unit types. We separate this class out so we can
46 : /// parse the header before deciding what specific kind of unit to construct.
47 5139 : class DWARFUnitHeader {
48 : // Offset within section.
49 : uint32_t Offset = 0;
50 : // Version, address size, and DWARF format.
51 : dwarf::FormParams FormParams;
52 : uint32_t Length = 0;
53 : uint64_t AbbrOffset = 0;
54 :
55 : // For DWO units only.
56 : const DWARFUnitIndex::Entry *IndexEntry = nullptr;
57 :
58 : // For type units only.
59 : uint64_t TypeHash = 0;
60 : uint32_t TypeOffset = 0;
61 :
62 : // For v5 split or skeleton compile units only.
63 : Optional<uint64_t> DWOId;
64 :
65 : // Unit type as parsed, or derived from the section kind.
66 : uint8_t UnitType = 0;
67 :
68 : // Size as parsed. uint8_t for compactness.
69 : uint8_t Size = 0;
70 :
71 : public:
72 : /// Parse a unit header from \p debug_info starting at \p offset_ptr.
73 : bool extract(DWARFContext &Context, const DWARFDataExtractor &debug_info,
74 : uint32_t *offset_ptr, DWARFSectionKind Kind = DW_SECT_INFO,
75 : const DWARFUnitIndex *Index = nullptr);
76 0 : uint32_t getOffset() const { return Offset; }
77 88803 : const dwarf::FormParams &getFormParams() const { return FormParams; }
78 0 : uint16_t getVersion() const { return FormParams.Version; }
79 : dwarf::DwarfFormat getFormat() const { return FormParams.Format; }
80 0 : uint8_t getAddressByteSize() const { return FormParams.AddrSize; }
81 : uint8_t getRefAddrByteSize() const { return FormParams.getRefAddrByteSize(); }
82 : uint8_t getDwarfOffsetByteSize() const {
83 12232 : return FormParams.getDwarfOffsetByteSize();
84 : }
85 0 : uint32_t getLength() const { return Length; }
86 0 : uint64_t getAbbrOffset() const { return AbbrOffset; }
87 : Optional<uint64_t> getDWOId() const { return DWOId; }
88 : void setDWOId(uint64_t Id) {
89 : assert((!DWOId || *DWOId == Id) && "setting DWOId to a different value");
90 : DWOId = Id;
91 : }
92 0 : const DWARFUnitIndex::Entry *getIndexEntry() const { return IndexEntry; }
93 0 : uint64_t getTypeHash() const { return TypeHash; }
94 0 : uint32_t getTypeOffset() const { return TypeOffset; }
95 0 : uint8_t getUnitType() const { return UnitType; }
96 0 : bool isTypeUnit() const {
97 10703 : return UnitType == dwarf::DW_UT_type || UnitType == dwarf::DW_UT_split_type;
98 : }
99 0 : uint8_t getSize() const { return Size; }
100 : // FIXME: Support DWARF64.
101 6010 : uint32_t getNextUnitOffset() const { return Offset + Length + 4; }
102 : };
103 :
104 : const DWARFUnitIndex &getDWARFUnitIndex(DWARFContext &Context,
105 : DWARFSectionKind Kind);
106 :
107 : /// Describe a collection of units. Intended to hold all units either from
108 : /// .debug_info and .debug_types, or from .debug_info.dwo and .debug_types.dwo.
109 3218 : class DWARFUnitVector final : public SmallVector<std::unique_ptr<DWARFUnit>, 1> {
110 : std::function<std::unique_ptr<DWARFUnit>(uint32_t, DWARFSectionKind,
111 : const DWARFSection *)>
112 : Parser;
113 : int NumInfoUnits = -1;
114 :
115 : public:
116 : using UnitVector = SmallVectorImpl<std::unique_ptr<DWARFUnit>>;
117 : using iterator = typename UnitVector::iterator;
118 : using iterator_range = llvm::iterator_range<typename UnitVector::iterator>;
119 :
120 : DWARFUnit *getUnitForOffset(uint32_t Offset) const;
121 : DWARFUnit *getUnitForIndexEntry(const DWARFUnitIndex::Entry &E);
122 :
123 : /// Read units from a .debug_info or .debug_types section. Calls made
124 : /// before finishedInfoUnits() are assumed to be for .debug_info sections,
125 : /// calls after finishedInfoUnits() are for .debug_types sections. Caller
126 : /// must not mix calls to addUnitsForSection and addUnitsForDWOSection.
127 : void addUnitsForSection(DWARFContext &C, const DWARFSection &Section,
128 : DWARFSectionKind SectionKind);
129 : /// Read units from a .debug_info.dwo or .debug_types.dwo section. Calls
130 : /// made before finishedInfoUnits() are assumed to be for .debug_info.dwo
131 : /// sections, calls after finishedInfoUnits() are for .debug_types.dwo
132 : /// sections. Caller must not mix calls to addUnitsForSection and
133 : /// addUnitsForDWOSection.
134 : void addUnitsForDWOSection(DWARFContext &C, const DWARFSection &DWOSection,
135 : DWARFSectionKind SectionKind, bool Lazy = false);
136 :
137 : /// Add an existing DWARFUnit to this UnitVector. This is used by the DWARF
138 : /// verifier to process unit separately.
139 : DWARFUnit *addUnit(std::unique_ptr<DWARFUnit> Unit);
140 :
141 : /// Returns number of all units held by this instance.
142 : unsigned getNumUnits() const { return size(); }
143 : /// Returns number of units from all .debug_info[.dwo] sections.
144 : unsigned getNumInfoUnits() const {
145 9125 : return NumInfoUnits == -1 ? size() : NumInfoUnits;
146 : }
147 : /// Returns number of units from all .debug_types[.dwo] sections.
148 414 : unsigned getNumTypesUnits() const { return size() - NumInfoUnits; }
149 : /// Indicate that parsing .debug_info[.dwo] is done, and remaining units
150 : /// will be from .debug_types[.dwo].
151 1860 : void finishedInfoUnits() { NumInfoUnits = size(); }
152 :
153 : private:
154 : void addUnitsImpl(DWARFContext &Context, const DWARFObject &Obj,
155 : const DWARFSection &Section, const DWARFDebugAbbrev *DA,
156 : const DWARFSection *RS, StringRef SS,
157 : const DWARFSection &SOS, const DWARFSection *AOS,
158 : const DWARFSection &LS, bool LE, bool IsDWO, bool Lazy,
159 : DWARFSectionKind SectionKind);
160 : };
161 :
162 : /// Represents base address of the CU.
163 : struct BaseAddress {
164 : uint64_t Address;
165 : uint64_t SectionIndex;
166 : };
167 :
168 : /// Represents a unit's contribution to the string offsets table.
169 : struct StrOffsetsContributionDescriptor {
170 : uint64_t Base = 0;
171 : /// The contribution size not including the header.
172 : uint64_t Size = 0;
173 : /// Format and version.
174 : dwarf::FormParams FormParams = {0, 0, dwarf::DwarfFormat::DWARF32};
175 :
176 : StrOffsetsContributionDescriptor(uint64_t Base, uint64_t Size,
177 : uint8_t Version, dwarf::DwarfFormat Format)
178 : : Base(Base), Size(Size), FormParams({Version, 0, Format}) {}
179 :
180 0 : uint8_t getVersion() const { return FormParams.Version; }
181 0 : dwarf::DwarfFormat getFormat() const { return FormParams.Format; }
182 : uint8_t getDwarfOffsetByteSize() const {
183 1396 : return FormParams.getDwarfOffsetByteSize();
184 : }
185 : /// Determine whether a contribution to the string offsets table is
186 : /// consistent with the relevant section size and that its length is
187 : /// a multiple of the size of one of its entries.
188 : Optional<StrOffsetsContributionDescriptor>
189 : validateContributionSize(DWARFDataExtractor &DA);
190 : };
191 :
192 4936 : class DWARFUnit {
193 : DWARFContext &Context;
194 : /// Section containing this DWARFUnit.
195 : const DWARFSection &InfoSection;
196 :
197 : DWARFUnitHeader Header;
198 : const DWARFDebugAbbrev *Abbrev;
199 : const DWARFSection *RangeSection;
200 : uint32_t RangeSectionBase;
201 : const DWARFSection &LineSection;
202 : StringRef StringSection;
203 : const DWARFSection &StringOffsetSection;
204 : const DWARFSection *AddrOffsetSection;
205 : uint32_t AddrOffsetSectionBase = 0;
206 : bool isLittleEndian;
207 : bool isDWO;
208 : const DWARFUnitVector &UnitVector;
209 :
210 : /// Start, length, and DWARF format of the unit's contribution to the string
211 : /// offsets table (DWARF v5).
212 : Optional<StrOffsetsContributionDescriptor> StringOffsetsTableContribution;
213 :
214 : /// A table of range lists (DWARF v5 and later).
215 : Optional<DWARFDebugRnglistTable> RngListTable;
216 :
217 : mutable const DWARFAbbreviationDeclarationSet *Abbrevs;
218 : llvm::Optional<BaseAddress> BaseAddr;
219 : /// The compile unit debug information entry items.
220 : std::vector<DWARFDebugInfoEntry> DieArray;
221 :
222 : /// Map from range's start address to end address and corresponding DIE.
223 : /// IntervalMap does not support range removal, as a result, we use the
224 : /// std::map::upper_bound for address range lookup.
225 : std::map<uint64_t, std::pair<uint64_t, DWARFDie>> AddrDieMap;
226 :
227 : using die_iterator_range =
228 : iterator_range<std::vector<DWARFDebugInfoEntry>::iterator>;
229 :
230 : std::shared_ptr<DWARFUnit> DWO;
231 :
232 : uint32_t getDIEIndex(const DWARFDebugInfoEntry *Die) {
233 51105 : auto First = DieArray.data();
234 : assert(Die >= First && Die < First + DieArray.size());
235 43982 : return Die - First;
236 : }
237 :
238 : protected:
239 : const DWARFUnitHeader &getHeader() const { return Header; }
240 :
241 : /// Size in bytes of the parsed unit header.
242 7013 : uint32_t getHeaderSize() const { return Header.getSize(); }
243 :
244 : /// Find the unit's contribution to the string offsets table and determine its
245 : /// length and form. The given offset is expected to be derived from the unit
246 : /// DIE's DW_AT_str_offsets_base attribute.
247 : Optional<StrOffsetsContributionDescriptor>
248 : determineStringOffsetsTableContribution(DWARFDataExtractor &DA,
249 : uint64_t Offset);
250 :
251 : /// Find the unit's contribution to the string offsets table and determine its
252 : /// length and form. The given offset is expected to be 0 in a dwo file or,
253 : /// in a dwp file, the start of the unit's contribution to the string offsets
254 : /// table section (as determined by the index table).
255 : Optional<StrOffsetsContributionDescriptor>
256 : determineStringOffsetsTableContributionDWO(DWARFDataExtractor &DA,
257 : uint64_t Offset);
258 :
259 : public:
260 : DWARFUnit(DWARFContext &Context, const DWARFSection &Section,
261 : const DWARFUnitHeader &Header,
262 : const DWARFDebugAbbrev *DA, const DWARFSection *RS, StringRef SS,
263 : const DWARFSection &SOS, const DWARFSection *AOS,
264 : const DWARFSection &LS, bool LE, bool IsDWO,
265 : const DWARFUnitVector &UnitVector);
266 :
267 : virtual ~DWARFUnit();
268 :
269 0 : DWARFContext& getContext() const { return Context; }
270 0 : const DWARFSection &getInfoSection() const { return InfoSection; }
271 27276 : uint32_t getOffset() const { return Header.getOffset(); }
272 : const dwarf::FormParams &getFormParams() const {
273 : return Header.getFormParams();
274 : }
275 9079 : uint16_t getVersion() const { return Header.getVersion(); }
276 10207 : uint8_t getAddressByteSize() const { return Header.getAddressByteSize(); }
277 : uint8_t getRefAddrByteSize() const { return Header.getRefAddrByteSize(); }
278 : uint8_t getDwarfOffsetByteSize() const {
279 : return Header.getDwarfOffsetByteSize();
280 : }
281 742 : uint32_t getLength() const { return Header.getLength(); }
282 223 : uint8_t getUnitType() const { return Header.getUnitType(); }
283 761 : bool isTypeUnit() const { return Header.isTypeUnit(); }
284 10635 : uint32_t getNextUnitOffset() const { return Header.getNextUnitOffset(); }
285 0 : const DWARFSection &getLineSection() const { return LineSection; }
286 : StringRef getStringSection() const { return StringSection; }
287 : const DWARFSection &getStringOffsetSection() const {
288 : return StringOffsetSection;
289 : }
290 :
291 0 : void setAddrOffsetSection(const DWARFSection *AOS, uint32_t Base) {
292 19 : AddrOffsetSection = AOS;
293 19 : AddrOffsetSectionBase = Base;
294 0 : }
295 :
296 : /// Recursively update address to Die map.
297 : void updateAddressDieMap(DWARFDie Die);
298 :
299 0 : void setRangesSection(const DWARFSection *RS, uint32_t Base) {
300 121 : RangeSection = RS;
301 121 : RangeSectionBase = Base;
302 0 : }
303 :
304 : bool getAddrOffsetSectionItem(uint32_t Index, uint64_t &Result) const;
305 : bool getStringOffsetSectionItem(uint32_t Index, uint64_t &Result) const;
306 :
307 : DWARFDataExtractor getDebugInfoExtractor() const;
308 :
309 : DataExtractor getStringExtractor() const {
310 : return DataExtractor(StringSection, false, 0);
311 : }
312 :
313 : /// Extract the range list referenced by this compile unit from the
314 : /// .debug_ranges section. If the extraction is unsuccessful, an error
315 : /// is returned. Successful extraction requires that the compile unit
316 : /// has already been extracted.
317 : Error extractRangeList(uint32_t RangeListOffset,
318 : DWARFDebugRangeList &RangeList) const;
319 : void clear();
320 :
321 : const Optional<StrOffsetsContributionDescriptor> &
322 : getStringOffsetsTableContribution() const {
323 55 : return StringOffsetsTableContribution;
324 : }
325 :
326 : uint8_t getDwarfStringOffsetsByteSize() const {
327 : assert(StringOffsetsTableContribution);
328 : return StringOffsetsTableContribution->getDwarfOffsetByteSize();
329 : }
330 :
331 : uint64_t getStringOffsetsBase() const {
332 : assert(StringOffsetsTableContribution);
333 1294 : return StringOffsetsTableContribution->Base;
334 : }
335 :
336 : const DWARFAbbreviationDeclarationSet *getAbbreviations() const;
337 :
338 92 : static bool isMatchingUnitTypeAndTag(uint8_t UnitType, dwarf::Tag Tag) {
339 92 : switch (UnitType) {
340 91 : case dwarf::DW_UT_compile:
341 91 : return Tag == dwarf::DW_TAG_compile_unit;
342 1 : case dwarf::DW_UT_type:
343 1 : return Tag == dwarf::DW_TAG_type_unit;
344 0 : case dwarf::DW_UT_partial:
345 0 : return Tag == dwarf::DW_TAG_partial_unit;
346 0 : case dwarf::DW_UT_skeleton:
347 0 : return Tag == dwarf::DW_TAG_skeleton_unit;
348 0 : case dwarf::DW_UT_split_compile:
349 : case dwarf::DW_UT_split_type:
350 : return dwarf::isUnitType(Tag);
351 : }
352 : return false;
353 : }
354 :
355 : /// Return the number of bytes for the header of a unit of
356 : /// UnitType type.
357 : ///
358 : /// This function must be called with a valid unit type which in
359 : /// DWARF5 is defined as one of the following six types.
360 : static uint32_t getDWARF5HeaderSize(uint8_t UnitType) {
361 : switch (UnitType) {
362 : case dwarf::DW_UT_compile:
363 : case dwarf::DW_UT_partial:
364 : return 12;
365 : case dwarf::DW_UT_skeleton:
366 : case dwarf::DW_UT_split_compile:
367 : return 20;
368 : case dwarf::DW_UT_type:
369 : case dwarf::DW_UT_split_type:
370 : return 24;
371 : }
372 : llvm_unreachable("Invalid UnitType.");
373 : }
374 :
375 : llvm::Optional<BaseAddress> getBaseAddress();
376 :
377 3956 : DWARFDie getUnitDIE(bool ExtractUnitDIEOnly = true) {
378 19484 : extractDIEsIfNeeded(ExtractUnitDIEOnly);
379 19484 : if (DieArray.empty())
380 0 : return DWARFDie();
381 3956 : return DWARFDie(this, &DieArray[0]);
382 : }
383 :
384 : const char *getCompilationDir();
385 : Optional<uint64_t> getDWOId() {
386 92 : extractDIEsIfNeeded(/*CUDieOnly*/ true);
387 : return getHeader().getDWOId();
388 : }
389 : void setDWOId(uint64_t NewID) { Header.setDWOId(NewID); }
390 :
391 : /// Return a vector of address ranges resulting from a (possibly encoded)
392 : /// range list starting at a given offset in the appropriate ranges section.
393 : Expected<DWARFAddressRangesVector> findRnglistFromOffset(uint32_t Offset);
394 :
395 : /// Return a vector of address ranges retrieved from an encoded range
396 : /// list whose offset is found via a table lookup given an index (DWARF v5
397 : /// and later).
398 : Expected<DWARFAddressRangesVector> findRnglistFromIndex(uint32_t Index);
399 :
400 : /// Return a rangelist's offset based on an index. The index designates
401 : /// an entry in the rangelist table's offset array and is supplied by
402 : /// DW_FORM_rnglistx.
403 : Optional<uint32_t> getRnglistOffset(uint32_t Index) {
404 8 : if (RngListTable)
405 : return RngListTable->getOffsetEntry(Index);
406 : return None;
407 : }
408 :
409 : void collectAddressRanges(DWARFAddressRangesVector &CURanges);
410 :
411 : /// Returns subprogram DIE with address range encompassing the provided
412 : /// address. The pointer is alive as long as parsed compile unit DIEs are not
413 : /// cleared.
414 : DWARFDie getSubroutineForAddress(uint64_t Address);
415 :
416 : /// getInlinedChainForAddress - fetches inlined chain for a given address.
417 : /// Returns empty chain if there is no subprogram containing address. The
418 : /// chain is valid as long as parsed compile unit DIEs are not cleared.
419 : void getInlinedChainForAddress(uint64_t Address,
420 : SmallVectorImpl<DWARFDie> &InlinedChain);
421 :
422 : /// Return the DWARFUnitVector containing this unit.
423 0 : const DWARFUnitVector &getUnitVector() const { return UnitVector; }
424 :
425 : /// Returns the number of DIEs in the unit. Parses the unit
426 : /// if necessary.
427 : unsigned getNumDIEs() {
428 1939 : extractDIEsIfNeeded(false);
429 3652 : return DieArray.size();
430 : }
431 :
432 : /// Return the index of a DIE inside the unit's DIE vector.
433 : ///
434 : /// It is illegal to call this method with a DIE that hasn't be
435 : /// created by this unit. In other word, it's illegal to call this
436 : /// method on a DIE that isn't accessible by following
437 : /// children/sibling links starting from this unit's getUnitDIE().
438 : uint32_t getDIEIndex(const DWARFDie &D) {
439 7123 : return getDIEIndex(D.getDebugInfoEntry());
440 : }
441 :
442 : /// Return the DIE object at the given index.
443 : DWARFDie getDIEAtIndex(unsigned Index) {
444 : assert(Index < DieArray.size());
445 2878 : return DWARFDie(this, &DieArray[Index]);
446 : }
447 :
448 : DWARFDie getParent(const DWARFDebugInfoEntry *Die);
449 : DWARFDie getSibling(const DWARFDebugInfoEntry *Die);
450 : DWARFDie getPreviousSibling(const DWARFDebugInfoEntry *Die);
451 : DWARFDie getFirstChild(const DWARFDebugInfoEntry *Die);
452 : DWARFDie getLastChild(const DWARFDebugInfoEntry *Die);
453 :
454 : /// Return the DIE object for a given offset inside the
455 : /// unit's DIE vector.
456 : ///
457 : /// The unit needs to have its DIEs extracted for this method to work.
458 7587 : DWARFDie getDIEForOffset(uint32_t Offset) {
459 7587 : extractDIEsIfNeeded(false);
460 : assert(!DieArray.empty());
461 : auto it = std::lower_bound(
462 : DieArray.begin(), DieArray.end(), Offset,
463 : [](const DWARFDebugInfoEntry &LHS, uint32_t Offset) {
464 32143 : return LHS.getOffset() < Offset;
465 : });
466 7587 : if (it != DieArray.end() && it->getOffset() == Offset)
467 7564 : return DWARFDie(this, &*it);
468 23 : return DWARFDie();
469 : }
470 :
471 : uint32_t getLineTableOffset() const {
472 3590 : if (auto IndexEntry = Header.getIndexEntry())
473 12 : if (const auto *Contrib = IndexEntry->getOffset(DW_SECT_LINE))
474 12 : return Contrib->Offset;
475 : return 0;
476 : }
477 :
478 : die_iterator_range dies() {
479 335 : extractDIEsIfNeeded(false);
480 : return die_iterator_range(DieArray.begin(), DieArray.end());
481 : }
482 :
483 : virtual void dump(raw_ostream &OS, DIDumpOptions DumpOpts) = 0;
484 : private:
485 : /// Size in bytes of the .debug_info data associated with this compile unit.
486 : size_t getDebugInfoSize() const {
487 2257 : return Header.getLength() + 4 - getHeaderSize();
488 : }
489 :
490 : /// extractDIEsIfNeeded - Parses a compile unit and indexes its DIEs if it
491 : /// hasn't already been done. Returns the number of DIEs parsed at this call.
492 : size_t extractDIEsIfNeeded(bool CUDieOnly);
493 :
494 : /// extractDIEsToVector - Appends all parsed DIEs to a vector.
495 : void extractDIEsToVector(bool AppendCUDie, bool AppendNonCUDIEs,
496 : std::vector<DWARFDebugInfoEntry> &DIEs) const;
497 :
498 : /// clearDIEs - Clear parsed DIEs to keep memory usage low.
499 : void clearDIEs(bool KeepCUDie);
500 :
501 : /// parseDWO - Parses .dwo file for current compile unit. Returns true if
502 : /// it was actually constructed.
503 : bool parseDWO();
504 : };
505 :
506 : } // end namespace llvm
507 :
508 : #endif // LLVM_DEBUGINFO_DWARF_DWARFUNIT_H
|