Movatterモバイル変換


[0]ホーム

URL:


LLVM 20.0.0git
DWARFUnit.cpp
Go to the documentation of this file.
1//===- DWARFUnit.cpp ------------------------------------------------------===//
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#include "llvm/DebugInfo/DWARF/DWARFUnit.h"
10#include "llvm/ADT/SmallString.h"
11#include "llvm/ADT/StringRef.h"
12#include "llvm/BinaryFormat/Dwarf.h"
13#include "llvm/DebugInfo/DWARF/DWARFAbbreviationDeclaration.h"
14#include "llvm/DebugInfo/DWARF/DWARFCompileUnit.h"
15#include "llvm/DebugInfo/DWARF/DWARFContext.h"
16#include "llvm/DebugInfo/DWARF/DWARFDebugAbbrev.h"
17#include "llvm/DebugInfo/DWARF/DWARFDebugInfoEntry.h"
18#include "llvm/DebugInfo/DWARF/DWARFDebugLoc.h"
19#include "llvm/DebugInfo/DWARF/DWARFDebugRangeList.h"
20#include "llvm/DebugInfo/DWARF/DWARFDebugRnglists.h"
21#include "llvm/DebugInfo/DWARF/DWARFDie.h"
22#include "llvm/DebugInfo/DWARF/DWARFExpression.h"
23#include "llvm/DebugInfo/DWARF/DWARFFormValue.h"
24#include "llvm/DebugInfo/DWARF/DWARFListTable.h"
25#include "llvm/DebugInfo/DWARF/DWARFObject.h"
26#include "llvm/DebugInfo/DWARF/DWARFSection.h"
27#include "llvm/DebugInfo/DWARF/DWARFTypeUnit.h"
28#include "llvm/Object/ObjectFile.h"
29#include "llvm/Support/DataExtractor.h"
30#include "llvm/Support/Errc.h"
31#include "llvm/Support/Path.h"
32#include <algorithm>
33#include <cassert>
34#include <cstddef>
35#include <cstdint>
36#include <utility>
37#include <vector>
38
39using namespacellvm;
40using namespacedwarf;
41
42voidDWARFUnitVector::addUnitsForSection(DWARFContext &C,
43constDWARFSection &Section,
44DWARFSectionKindSectionKind) {
45constDWARFObject &D =C.getDWARFObj();
46 addUnitsImpl(C,D, Section,C.getDebugAbbrev(), &D.getRangesSection(),
47 &D.getLocSection(),D.getStrSection(),
48D.getStrOffsetsSection(), &D.getAddrSection(),
49D.getLineSection(),D.isLittleEndian(),false,false,
50SectionKind);
51}
52
53voidDWARFUnitVector::addUnitsForDWOSection(DWARFContext &C,
54constDWARFSection &DWOSection,
55DWARFSectionKindSectionKind,
56bool Lazy) {
57constDWARFObject &D =C.getDWARFObj();
58 addUnitsImpl(C,D, DWOSection,C.getDebugAbbrevDWO(), &D.getRangesDWOSection(),
59 &D.getLocDWOSection(),D.getStrDWOSection(),
60D.getStrOffsetsDWOSection(), &D.getAddrSection(),
61D.getLineDWOSection(),C.isLittleEndian(),true, Lazy,
62SectionKind);
63}
64
65void DWARFUnitVector::addUnitsImpl(
66DWARFContext &Context,constDWARFObject &Obj,constDWARFSection &Section,
67constDWARFDebugAbbrev *DA,constDWARFSection *RS,
68constDWARFSection *LocSection,StringRef SS,constDWARFSection &SOS,
69constDWARFSection *AOS,constDWARFSection &LS,bool LE,bool IsDWO,
70bool Lazy,DWARFSectionKindSectionKind) {
71DWARFDataExtractorData(Obj, Section, LE, 0);
72// Lazy initialization of Parser, now that we have all section info.
73if (!Parser) {
74 Parser = [=, &Context, &Obj, &Section, &SOS,
75 &LS](uint64_tOffset,DWARFSectionKindSectionKind,
76constDWARFSection *CurSection,
77constDWARFUnitIndex::Entry *IndexEntry)
78 -> std::unique_ptr<DWARFUnit> {
79constDWARFSection &InfoSection = CurSection ? *CurSection : Section;
80DWARFDataExtractorData(Obj, InfoSection, LE, 0);
81if (!Data.isValidOffset(Offset))
82returnnullptr;
83DWARFUnitHeader Header;
84if (Error ExtractErr =
85 Header.extract(Context,Data, &Offset,SectionKind)) {
86 Context.getWarningHandler()(std::move(ExtractErr));
87returnnullptr;
88 }
89if (!IndexEntry && IsDWO) {
90constDWARFUnitIndex &Index =getDWARFUnitIndex(
91 Context, Header.isTypeUnit() ?DW_SECT_EXT_TYPES : DW_SECT_INFO);
92if (Index) {
93if (Header.isTypeUnit())
94 IndexEntry =Index.getFromHash(Header.getTypeHash());
95elseif (auto DWOId = Header.getDWOId())
96 IndexEntry =Index.getFromHash(*DWOId);
97 }
98if (!IndexEntry)
99 IndexEntry =Index.getFromOffset(Header.getOffset());
100 }
101if (IndexEntry) {
102if (Error ApplicationErr = Header.applyIndexEntry(IndexEntry)) {
103 Context.getWarningHandler()(std::move(ApplicationErr));
104returnnullptr;
105 }
106 }
107 std::unique_ptr<DWARFUnit>U;
108if (Header.isTypeUnit())
109 U = std::make_unique<DWARFTypeUnit>(Context, InfoSection, Header, DA,
110 RS, LocSection, SS, SOS, AOS, LS,
111 LE, IsDWO, *this);
112else
113U = std::make_unique<DWARFCompileUnit>(Context, InfoSection, Header,
114 DA, RS, LocSection, SS, SOS,
115 AOS, LS, LE, IsDWO, *this);
116returnU;
117 };
118 }
119if (Lazy)
120return;
121// Find a reasonable insertion point within the vector. We skip over
122// (a) units from a different section, (b) units from the same section
123// but with lower offset-within-section. This keeps units in order
124// within a section, although not necessarily within the object file,
125// even if we do lazy parsing.
126autoI = this->begin();
127uint64_tOffset = 0;
128while (Data.isValidOffset(Offset)) {
129if (I != this->end() &&
130 (&(*I)->getInfoSection() != &Section || (*I)->getOffset() ==Offset)) {
131 ++I;
132continue;
133 }
134autoU = Parser(Offset,SectionKind, &Section,nullptr);
135// If parsing failed, we're done with this section.
136if (!U)
137break;
138Offset =U->getNextUnitOffset();
139I = std::next(this->insert(I, std::move(U)));
140 }
141}
142
143DWARFUnit *DWARFUnitVector::addUnit(std::unique_ptr<DWARFUnit> Unit) {
144autoI =llvm::upper_bound(*this, Unit,
145 [](const std::unique_ptr<DWARFUnit> &LHS,
146const std::unique_ptr<DWARFUnit> &RHS) {
147returnLHS->getOffset() <RHS->getOffset();
148 });
149return this->insert(I, std::move(Unit))->get();
150}
151
152DWARFUnit *DWARFUnitVector::getUnitForOffset(uint64_tOffset) const{
153autoend =begin() +getNumInfoUnits();
154auto *CU =
155 std::upper_bound(begin(),end,Offset,
156 [](uint64_tLHS,const std::unique_ptr<DWARFUnit> &RHS) {
157returnLHS <RHS->getNextUnitOffset();
158 });
159if (CU !=end && (*CU)->getOffset() <=Offset)
160returnCU->get();
161returnnullptr;
162}
163
164DWARFUnit *
165DWARFUnitVector::getUnitForIndexEntry(constDWARFUnitIndex::Entry &E) {
166constauto *CUOff = E.getContribution(DW_SECT_INFO);
167if (!CUOff)
168returnnullptr;
169
170uint64_tOffset = CUOff->getOffset();
171autoend =begin() +getNumInfoUnits();
172
173auto *CU =
174 std::upper_bound(begin(),end, CUOff->getOffset(),
175 [](uint64_tLHS,const std::unique_ptr<DWARFUnit> &RHS) {
176 return LHS < RHS->getNextUnitOffset();
177 });
178if (CU !=end && (*CU)->getOffset() <=Offset)
179returnCU->get();
180
181if (!Parser)
182returnnullptr;
183
184auto U = Parser(Offset, DW_SECT_INFO,nullptr, &E);
185if (!U)
186returnnullptr;
187
188auto *NewCU = U.get();
189 this->insert(CU, std::move(U));
190 ++NumInfoUnits;
191return NewCU;
192}
193
194DWARFUnit::DWARFUnit(DWARFContext &DC,constDWARFSection &Section,
195constDWARFUnitHeader &Header,constDWARFDebugAbbrev *DA,
196constDWARFSection *RS,constDWARFSection *LocSection,
197StringRef SS,constDWARFSection &SOS,
198constDWARFSection *AOS,constDWARFSection &LS,bool LE,
199bool IsDWO,constDWARFUnitVector &UnitVector)
200 : Context(DC), InfoSection(Section), Header(Header), Abbrev(DA),
201 RangeSection(RS), LineSection(LS), StringSection(SS),
202 StringOffsetSection(SOS), AddrOffsetSection(AOS), IsLittleEndian(LE),
203 IsDWO(IsDWO), UnitVector(UnitVector) {
204clear();
205}
206
207DWARFUnit::~DWARFUnit() =default;
208
209DWARFDataExtractorDWARFUnit::getDebugInfoExtractor() const{
210returnDWARFDataExtractor(Context.getDWARFObj(), InfoSection, IsLittleEndian,
211getAddressByteSize());
212}
213
214std::optional<object::SectionedAddress>
215DWARFUnit::getAddrOffsetSectionItem(uint32_tIndex) const{
216if (!AddrOffsetSectionBase) {
217auto R = Context.info_section_units();
218// Surprising if a DWO file has more than one skeleton unit in it - this
219// probably shouldn't be valid, but if a use case is found, here's where to
220// support it (probably have to linearly search for the matching skeleton CU
221// here)
222if (IsDWO &&hasSingleElement(R))
223return (*R.begin())->getAddrOffsetSectionItem(Index);
224
225return std::nullopt;
226 }
227
228uint64_tOffset = *AddrOffsetSectionBase +Index *getAddressByteSize();
229if (AddrOffsetSection->Data.size() <Offset +getAddressByteSize())
230return std::nullopt;
231DWARFDataExtractor DA(Context.getDWARFObj(), *AddrOffsetSection,
232 IsLittleEndian,getAddressByteSize());
233uint64_t Section;
234uint64_tAddress = DA.getRelocatedAddress(&Offset, &Section);
235return {{Address, Section}};
236}
237
238Expected<uint64_t>DWARFUnit::getStringOffsetSectionItem(uint32_tIndex) const{
239if (!StringOffsetsTableContribution)
240return make_error<StringError>(
241"DW_FORM_strx used without a valid string offsets table",
242inconvertibleErrorCode());
243unsigned ItemSize =getDwarfStringOffsetsByteSize();
244uint64_tOffset =getStringOffsetsBase() +Index * ItemSize;
245if (StringOffsetSection.Data.size() <Offset + ItemSize)
246return make_error<StringError>("DW_FORM_strx uses index " +Twine(Index) +
247", which is too large",
248inconvertibleErrorCode());
249DWARFDataExtractor DA(Context.getDWARFObj(), StringOffsetSection,
250 IsLittleEndian, 0);
251return DA.getRelocatedValue(ItemSize, &Offset);
252}
253
254ErrorDWARFUnitHeader::extract(DWARFContext &Context,
255constDWARFDataExtractor &debug_info,
256uint64_t *offset_ptr,
257DWARFSectionKindSectionKind) {
258 Offset = *offset_ptr;
259Error Err =Error::success();
260 IndexEntry =nullptr;
261 std::tie(Length,FormParams.Format) =
262 debug_info.getInitialLength(offset_ptr, &Err);
263FormParams.Version = debug_info.getU16(offset_ptr, &Err);
264if (FormParams.Version >= 5) {
265UnitType = debug_info.getU8(offset_ptr, &Err);
266FormParams.AddrSize = debug_info.getU8(offset_ptr, &Err);
267 AbbrOffset = debug_info.getRelocatedValue(
268FormParams.getDwarfOffsetByteSize(), offset_ptr,nullptr, &Err);
269 }else {
270 AbbrOffset = debug_info.getRelocatedValue(
271FormParams.getDwarfOffsetByteSize(), offset_ptr,nullptr, &Err);
272FormParams.AddrSize = debug_info.getU8(offset_ptr, &Err);
273// Fake a unit type based on the section type. This isn't perfect,
274// but distinguishing compile and type units is generally enough.
275if (SectionKind ==DW_SECT_EXT_TYPES)
276UnitType = DW_UT_type;
277else
278UnitType = DW_UT_compile;
279 }
280if (isTypeUnit()) {
281 TypeHash = debug_info.getU64(offset_ptr, &Err);
282 TypeOffset = debug_info.getUnsigned(
283 offset_ptr,FormParams.getDwarfOffsetByteSize(), &Err);
284 }elseif (UnitType == DW_UT_split_compile ||UnitType == DW_UT_skeleton)
285 DWOId = debug_info.getU64(offset_ptr, &Err);
286
287if (Err)
288returnjoinErrors(
289createStringError(
290errc::invalid_argument,
291"DWARF unit at 0x%8.8" PRIx64" cannot be parsed:", Offset),
292 std::move(Err));
293
294// Header fields all parsed, capture the size of this unit header.
295assert(*offset_ptr - Offset <= 255 &&"unexpected header size");
296 Size =uint8_t(*offset_ptr - Offset);
297uint64_t NextCUOffset = Offset +getUnitLengthFieldByteSize() +getLength();
298
299if (!debug_info.isValidOffset(getNextUnitOffset() - 1))
300returncreateStringError(errc::invalid_argument,
301"DWARF unit from offset 0x%8.8" PRIx64" incl. "
302"to offset 0x%8.8" PRIx64" excl. "
303"extends past section size 0x%8.8zx",
304 Offset, NextCUOffset, debug_info.size());
305
306if (!DWARFContext::isSupportedVersion(getVersion()))
307returncreateStringError(
308errc::invalid_argument,
309"DWARF unit at offset 0x%8.8" PRIx64" "
310"has unsupported version %" PRIu16", supported are 2-%u",
311 Offset,getVersion(),DWARFContext::getMaxSupportedVersion());
312
313// Type offset is unit-relative; should be after the header and before
314// the end of the current unit.
315if (isTypeUnit() && TypeOffset < Size)
316returncreateStringError(errc::invalid_argument,
317"DWARF type unit at offset "
318"0x%8.8" PRIx64" "
319"has its relocated type_offset 0x%8.8" PRIx64" "
320"pointing inside the header",
321 Offset, Offset + TypeOffset);
322
323if (isTypeUnit() && TypeOffset >=getUnitLengthFieldByteSize() +getLength())
324returncreateStringError(
325errc::invalid_argument,
326"DWARF type unit from offset 0x%8.8" PRIx64" incl. "
327"to offset 0x%8.8" PRIx64" excl. has its "
328"relocated type_offset 0x%8.8" PRIx64" pointing past the unit end",
329 Offset, NextCUOffset, Offset + TypeOffset);
330
331if (Error SizeErr =DWARFContext::checkAddressSizeSupported(
332getAddressByteSize(),errc::invalid_argument,
333"DWARF unit at offset 0x%8.8" PRIx64, Offset))
334return SizeErr;
335
336// Keep track of the highest DWARF version we encounter across all units.
337 Context.setMaxVersionIfGreater(getVersion());
338returnError::success();
339}
340
341ErrorDWARFUnitHeader::applyIndexEntry(constDWARFUnitIndex::Entry *Entry) {
342assert(Entry);
343assert(!IndexEntry);
344 IndexEntry = Entry;
345if (AbbrOffset)
346returncreateStringError(errc::invalid_argument,
347"DWARF package unit at offset 0x%8.8" PRIx64
348" has a non-zero abbreviation offset",
349 Offset);
350
351auto *UnitContrib = IndexEntry->getContribution();
352if (!UnitContrib)
353returncreateStringError(errc::invalid_argument,
354"DWARF package unit at offset 0x%8.8" PRIx64
355" has no contribution index",
356 Offset);
357
358uint64_t IndexLength =getLength() +getUnitLengthFieldByteSize();
359if (UnitContrib->getLength() != IndexLength)
360returncreateStringError(errc::invalid_argument,
361"DWARF package unit at offset 0x%8.8" PRIx64
362" has an inconsistent index (expected: %" PRIu64
363", actual: %" PRIu64")",
364 Offset, UnitContrib->getLength(), IndexLength);
365
366auto *AbbrEntry = IndexEntry->getContribution(DW_SECT_ABBREV);
367if (!AbbrEntry)
368returncreateStringError(errc::invalid_argument,
369"DWARF package unit at offset 0x%8.8" PRIx64
370" missing abbreviation column",
371 Offset);
372
373 AbbrOffset = AbbrEntry->getOffset();
374returnError::success();
375}
376
377ErrorDWARFUnit::extractRangeList(uint64_t RangeListOffset,
378DWARFDebugRangeList &RangeList) const{
379// Require that compile unit is extracted.
380assert(!DieArray.empty());
381DWARFDataExtractor RangesData(Context.getDWARFObj(), *RangeSection,
382 IsLittleEndian,getAddressByteSize());
383uint64_t ActualRangeListOffset = RangeSectionBase + RangeListOffset;
384return RangeList.extract(RangesData, &ActualRangeListOffset);
385}
386
387voidDWARFUnit::clear() {
388 Abbrevs =nullptr;
389 BaseAddr.reset();
390 RangeSectionBase = 0;
391 LocSectionBase = 0;
392 AddrOffsetSectionBase = std::nullopt;
393 SU =nullptr;
394 clearDIEs(false);
395 AddrDieMap.clear();
396if (DWO)
397 DWO->clear();
398 DWO.reset();
399}
400
401constchar *DWARFUnit::getCompilationDir() {
402returndwarf::toString(getUnitDIE().find(DW_AT_comp_dir),nullptr);
403}
404
405void DWARFUnit::extractDIEsToVector(
406bool AppendCUDie,bool AppendNonCUDies,
407 std::vector<DWARFDebugInfoEntry> &Dies) const{
408if (!AppendCUDie && !AppendNonCUDies)
409return;
410
411// Set the offset to that of the first DIE and calculate the start of the
412// next compilation unit header.
413uint64_t DIEOffset =getOffset() +getHeaderSize();
414uint64_t NextCUOffset =getNextUnitOffset();
415DWARFDebugInfoEntryDIE;
416DWARFDataExtractor DebugInfoData =getDebugInfoExtractor();
417// The end offset has been already checked by DWARFUnitHeader::extract.
418assert(DebugInfoData.isValidOffset(NextCUOffset - 1));
419 std::vector<uint32_t> Parents;
420 std::vector<uint32_t> PrevSiblings;
421bool IsCUDie =true;
422
423assert(
424 ((AppendCUDie && Dies.empty()) || (!AppendCUDie && Dies.size() == 1)) &&
425"Dies array is not empty");
426
427// Fill Parents and Siblings stacks with initial value.
428 Parents.push_back(UINT32_MAX);
429if (!AppendCUDie)
430 Parents.push_back(0);
431 PrevSiblings.push_back(0);
432
433// Start to extract dies.
434do {
435assert(Parents.size() > 0 &&"Empty parents stack");
436assert((Parents.back() == UINT32_MAX || Parents.back() <= Dies.size()) &&
437"Wrong parent index");
438
439// Extract die. Stop if any error occurred.
440if (!DIE.extractFast(*this, &DIEOffset, DebugInfoData, NextCUOffset,
441 Parents.back()))
442break;
443
444// If previous sibling is remembered then update it`s SiblingIdx field.
445if (PrevSiblings.back() > 0) {
446assert(PrevSiblings.back() < Dies.size() &&
447"Previous sibling index is out of Dies boundaries");
448 Dies[PrevSiblings.back()].setSiblingIdx(Dies.size());
449 }
450
451// Store die into the Dies vector.
452if (IsCUDie) {
453if (AppendCUDie)
454 Dies.push_back(DIE);
455if (!AppendNonCUDies)
456break;
457// The average bytes per DIE entry has been seen to be
458// around 14-20 so let's pre-reserve the needed memory for
459// our DIE entries accordingly.
460 Dies.reserve(Dies.size() + getDebugInfoSize() / 14);
461 }else {
462// Remember last previous sibling.
463 PrevSiblings.back() = Dies.size();
464
465 Dies.push_back(DIE);
466 }
467
468// Check for new children scope.
469if (constDWARFAbbreviationDeclaration *AbbrDecl =
470DIE.getAbbreviationDeclarationPtr()) {
471if (AbbrDecl->hasChildren()) {
472if (AppendCUDie || !IsCUDie) {
473assert(Dies.size() > 0 &&"Dies does not contain any die");
474Parents.push_back(Dies.size() - 1);
475 PrevSiblings.push_back(0);
476 }
477 }elseif (IsCUDie)
478// Stop if we have single compile unit die w/o children.
479break;
480 }else {
481// NULL DIE: finishes current children scope.
482Parents.pop_back();
483 PrevSiblings.pop_back();
484 }
485
486if (IsCUDie)
487 IsCUDie =false;
488
489// Stop when compile unit die is removed from the parents stack.
490 }while (Parents.size() > 1);
491}
492
493void DWARFUnit::extractDIEsIfNeeded(bool CUDieOnly) {
494if (Error e =tryExtractDIEsIfNeeded(CUDieOnly))
495 Context.getRecoverableErrorHandler()(std::move(e));
496}
497
498ErrorDWARFUnit::tryExtractDIEsIfNeeded(bool CUDieOnly) {
499if ((CUDieOnly && !DieArray.empty()) ||
500 DieArray.size() > 1)
501returnError::success();// Already parsed.
502
503bool HasCUDie = !DieArray.empty();
504 extractDIEsToVector(!HasCUDie, !CUDieOnly, DieArray);
505
506if (DieArray.empty())
507returnError::success();
508
509// If CU DIE was just parsed, copy several attribute values from it.
510if (HasCUDie)
511returnError::success();
512
513DWARFDie UnitDie(this, &DieArray[0]);
514if (std::optional<uint64_t> DWOId =
515toUnsigned(UnitDie.find(DW_AT_GNU_dwo_id)))
516 Header.setDWOId(*DWOId);
517if (!IsDWO) {
518assert(AddrOffsetSectionBase == std::nullopt);
519assert(RangeSectionBase == 0);
520assert(LocSectionBase == 0);
521 AddrOffsetSectionBase =toSectionOffset(UnitDie.find(DW_AT_addr_base));
522if (!AddrOffsetSectionBase)
523 AddrOffsetSectionBase =
524toSectionOffset(UnitDie.find(DW_AT_GNU_addr_base));
525 RangeSectionBase =toSectionOffset(UnitDie.find(DW_AT_rnglists_base), 0);
526 LocSectionBase =toSectionOffset(UnitDie.find(DW_AT_loclists_base), 0);
527 }
528
529// In general, in DWARF v5 and beyond we derive the start of the unit's
530// contribution to the string offsets table from the unit DIE's
531// DW_AT_str_offsets_base attribute. Split DWARF units do not use this
532// attribute, so we assume that there is a contribution to the string
533// offsets table starting at offset 0 of the debug_str_offsets.dwo section.
534// In both cases we need to determine the format of the contribution,
535// which may differ from the unit's format.
536DWARFDataExtractor DA(Context.getDWARFObj(), StringOffsetSection,
537 IsLittleEndian, 0);
538if (IsDWO ||getVersion() >= 5) {
539auto StringOffsetOrError =
540 IsDWO ?determineStringOffsetsTableContributionDWO(DA)
541 :determineStringOffsetsTableContribution(DA);
542if (!StringOffsetOrError)
543returncreateStringError(errc::invalid_argument,
544"invalid reference to or invalid content in "
545".debug_str_offsets[.dwo]: " +
546toString(StringOffsetOrError.takeError()));
547
548 StringOffsetsTableContribution = *StringOffsetOrError;
549 }
550
551// DWARF v5 uses the .debug_rnglists and .debug_rnglists.dwo sections to
552// describe address ranges.
553if (getVersion() >= 5) {
554// In case of DWP, the base offset from the index has to be added.
555if (IsDWO) {
556uint64_t ContributionBaseOffset = 0;
557if (auto *IndexEntry = Header.getIndexEntry())
558if (auto *Contrib = IndexEntry->getContribution(DW_SECT_RNGLISTS))
559 ContributionBaseOffset = Contrib->getOffset();
560setRangesSection(
561 &Context.getDWARFObj().getRnglistsDWOSection(),
562 ContributionBaseOffset +
563DWARFListTableHeader::getHeaderSize(Header.getFormat()));
564 }else
565setRangesSection(&Context.getDWARFObj().getRnglistsSection(),
566toSectionOffset(UnitDie.find(DW_AT_rnglists_base),
567DWARFListTableHeader::getHeaderSize(
568 Header.getFormat())));
569 }
570
571if (IsDWO) {
572// If we are reading a package file, we need to adjust the location list
573// data based on the index entries.
574StringRefData = Header.getVersion() >= 5
575 ? Context.getDWARFObj().getLoclistsDWOSection().Data
576 : Context.getDWARFObj().getLocDWOSection().Data;
577if (auto *IndexEntry = Header.getIndexEntry())
578if (constauto *C = IndexEntry->getContribution(
579 Header.getVersion() >= 5 ? DW_SECT_LOCLISTS :DW_SECT_EXT_LOC))
580Data =Data.substr(C->getOffset(),C->getLength());
581
582DWARFDataExtractor DWARFData(Data, IsLittleEndian,getAddressByteSize());
583 LocTable =
584 std::make_unique<DWARFDebugLoclists>(DWARFData, Header.getVersion());
585 LocSectionBase =DWARFListTableHeader::getHeaderSize(Header.getFormat());
586 }elseif (getVersion() >= 5) {
587 LocTable = std::make_unique<DWARFDebugLoclists>(
588DWARFDataExtractor(Context.getDWARFObj(),
589 Context.getDWARFObj().getLoclistsSection(),
590 IsLittleEndian,getAddressByteSize()),
591getVersion());
592 }else {
593 LocTable = std::make_unique<DWARFDebugLoc>(DWARFDataExtractor(
594 Context.getDWARFObj(), Context.getDWARFObj().getLocSection(),
595 IsLittleEndian,getAddressByteSize()));
596 }
597
598// Don't fall back to DW_AT_GNU_ranges_base: it should be ignored for
599// skeleton CU DIE, so that DWARF users not aware of it are not broken.
600returnError::success();
601}
602
603bool DWARFUnit::parseDWO(StringRef DWOAlternativeLocation) {
604if (IsDWO)
605returnfalse;
606if (DWO)
607returnfalse;
608DWARFDie UnitDie =getUnitDIE();
609if (!UnitDie)
610returnfalse;
611auto DWOFileName =getVersion() >= 5
612 ?dwarf::toString(UnitDie.find(DW_AT_dwo_name))
613 : dwarf::toString(UnitDie.find(DW_AT_GNU_dwo_name));
614if (!DWOFileName)
615returnfalse;
616auto CompilationDir =dwarf::toString(UnitDie.find(DW_AT_comp_dir));
617SmallString<16> AbsolutePath;
618if (sys::path::is_relative(*DWOFileName) && CompilationDir &&
619 *CompilationDir) {
620sys::path::append(AbsolutePath, *CompilationDir);
621 }
622sys::path::append(AbsolutePath, *DWOFileName);
623auto DWOId =getDWOId();
624if (!DWOId)
625returnfalse;
626auto DWOContext = Context.getDWOContext(AbsolutePath);
627if (!DWOContext) {
628// Use the alternative location to get the DWARF context for the DWO object.
629if (DWOAlternativeLocation.empty())
630returnfalse;
631// If the alternative context does not correspond to the original DWO object
632// (different hashes), the below 'getDWOCompileUnitForHash' call will catch
633// the issue, with a returned null context.
634 DWOContext = Context.getDWOContext(DWOAlternativeLocation);
635if (!DWOContext)
636returnfalse;
637 }
638
639DWARFCompileUnit *DWOCU = DWOContext->getDWOCompileUnitForHash(*DWOId);
640if (!DWOCU)
641returnfalse;
642 DWO = std::shared_ptr<DWARFCompileUnit>(std::move(DWOContext), DWOCU);
643 DWO->setSkeletonUnit(this);
644// Share .debug_addr and .debug_ranges section with compile unit in .dwo
645if (AddrOffsetSectionBase)
646 DWO->setAddrOffsetSection(AddrOffsetSection, *AddrOffsetSectionBase);
647if (getVersion() == 4) {
648auto DWORangesBase = UnitDie.getRangesBaseAttribute();
649 DWO->setRangesSection(RangeSection, DWORangesBase.value_or(0));
650 }
651
652returntrue;
653}
654
655void DWARFUnit::clearDIEs(bool KeepCUDie) {
656// Do not use resize() + shrink_to_fit() to free memory occupied by dies.
657// shrink_to_fit() is a *non-binding* request to reduce capacity() to size().
658// It depends on the implementation whether the request is fulfilled.
659// Create a new vector with a small capacity and assign it to the DieArray to
660// have previous contents freed.
661 DieArray = (KeepCUDie && !DieArray.empty())
662 ? std::vector<DWARFDebugInfoEntry>({DieArray[0]})
663 : std::vector<DWARFDebugInfoEntry>();
664}
665
666Expected<DWARFAddressRangesVector>
667DWARFUnit::findRnglistFromOffset(uint64_tOffset) {
668if (getVersion() <= 4) {
669DWARFDebugRangeList RangeList;
670if (Error E =extractRangeList(Offset, RangeList))
671return std::move(E);
672return RangeList.getAbsoluteRanges(getBaseAddress());
673 }
674DWARFDataExtractor RangesData(Context.getDWARFObj(), *RangeSection,
675 IsLittleEndian, Header.getAddressByteSize());
676DWARFDebugRnglistTable RnglistTable;
677auto RangeListOrError = RnglistTable.findList(RangesData,Offset);
678if (RangeListOrError)
679return RangeListOrError.get().getAbsoluteRanges(getBaseAddress(), *this);
680return RangeListOrError.takeError();
681}
682
683Expected<DWARFAddressRangesVector>
684DWARFUnit::findRnglistFromIndex(uint32_tIndex) {
685if (autoOffset =getRnglistOffset(Index))
686returnfindRnglistFromOffset(*Offset);
687
688returncreateStringError(errc::invalid_argument,
689"invalid range list table index %d (possibly "
690"missing the entire range list table)",
691Index);
692}
693
694Expected<DWARFAddressRangesVector>DWARFUnit::collectAddressRanges() {
695DWARFDie UnitDie =getUnitDIE();
696if (!UnitDie)
697returncreateStringError(errc::invalid_argument,"No unit DIE");
698
699// First, check if unit DIE describes address ranges for the whole unit.
700auto CUDIERangesOrError = UnitDie.getAddressRanges();
701if (!CUDIERangesOrError)
702returncreateStringError(errc::invalid_argument,
703"decoding address ranges: %s",
704toString(CUDIERangesOrError.takeError()).c_str());
705return *CUDIERangesOrError;
706}
707
708Expected<DWARFLocationExpressionsVector>
709DWARFUnit::findLoclistFromOffset(uint64_tOffset) {
710DWARFLocationExpressionsVector Result;
711
712Error InterpretationError =Error::success();
713
714Error ParseError =getLocationTable().visitAbsoluteLocationList(
715Offset,getBaseAddress(),
716 [this](uint32_tIndex) {returngetAddrOffsetSectionItem(Index); },
717 [&](Expected<DWARFLocationExpression> L) {
718if (L)
719 Result.push_back(std::move(*L));
720else
721 InterpretationError =
722joinErrors(L.takeError(), std::move(InterpretationError));
723return !InterpretationError;
724 });
725
726if (ParseError || InterpretationError)
727returnjoinErrors(std::move(ParseError), std::move(InterpretationError));
728
729return Result;
730}
731
732voidDWARFUnit::updateAddressDieMap(DWARFDie Die) {
733if (Die.isSubroutineDIE()) {
734auto DIERangesOrError = Die.getAddressRanges();
735if (DIERangesOrError) {
736for (constauto &R : DIERangesOrError.get()) {
737// Ignore 0-sized ranges.
738if (R.LowPC == R.HighPC)
739continue;
740autoB = AddrDieMap.upper_bound(R.LowPC);
741if (B != AddrDieMap.begin() && R.LowPC < (--B)->second.first) {
742// The range is a sub-range of existing ranges, we need to split the
743// existing range.
744if (R.HighPC <B->second.first)
745 AddrDieMap[R.HighPC] =B->second;
746if (R.LowPC >B->first)
747 AddrDieMap[B->first].first = R.LowPC;
748 }
749 AddrDieMap[R.LowPC] = std::make_pair(R.HighPC, Die);
750 }
751 }else
752llvm::consumeError(DIERangesOrError.takeError());
753 }
754// Parent DIEs are added to the AddrDieMap prior to the Children DIEs to
755// simplify the logic to update AddrDieMap. The child's range will always
756// be equal or smaller than the parent's range. With this assumption, when
757// adding one range into the map, it will at most split a range into 3
758// sub-ranges.
759for (DWARFDie Child = Die.getFirstChild(); Child; Child = Child.getSibling())
760updateAddressDieMap(Child);
761}
762
763DWARFDieDWARFUnit::getSubroutineForAddress(uint64_tAddress) {
764 extractDIEsIfNeeded(false);
765if (AddrDieMap.empty())
766updateAddressDieMap(getUnitDIE());
767auto R = AddrDieMap.upper_bound(Address);
768if (R == AddrDieMap.begin())
769returnDWARFDie();
770// upper_bound's previous item contains Address.
771 --R;
772if (Address >= R->second.first)
773returnDWARFDie();
774return R->second.second;
775}
776
777voidDWARFUnit::updateVariableDieMap(DWARFDie Die) {
778for (DWARFDie Child : Die) {
779if (isType(Child.getTag()))
780continue;
781updateVariableDieMap(Child);
782 }
783
784if (Die.getTag() != DW_TAG_variable)
785return;
786
787Expected<DWARFLocationExpressionsVector> Locations =
788 Die.getLocations(DW_AT_location);
789if (!Locations) {
790// Missing DW_AT_location is fine here.
791consumeError(Locations.takeError());
792return;
793 }
794
795uint64_tAddress =UINT64_MAX;
796
797for (constDWARFLocationExpression &Location : *Locations) {
798uint8_t AddressSize =getAddressByteSize();
799DataExtractorData(Location.Expr,isLittleEndian(), AddressSize);
800DWARFExpression Expr(Data, AddressSize);
801auto It = Expr.begin();
802if (It == Expr.end())
803continue;
804
805// Match exactly the main sequence used to describe global variables:
806// `DW_OP_addr[x] [+ DW_OP_plus_uconst]`. Currently, this is the sequence
807// that LLVM produces for DILocalVariables and DIGlobalVariables. If, in
808// future, the DWARF producer (`DwarfCompileUnit::addLocationAttribute()` is
809// a good starting point) is extended to use further expressions, this code
810// needs to be updated.
811uint64_t LocationAddr;
812if (It->getCode() == dwarf::DW_OP_addr) {
813 LocationAddr = It->getRawOperand(0);
814 }elseif (It->getCode() == dwarf::DW_OP_addrx) {
815uint64_t DebugAddrOffset = It->getRawOperand(0);
816if (auto Pointer =getAddrOffsetSectionItem(DebugAddrOffset)) {
817 LocationAddr = Pointer->Address;
818 }
819 }else {
820continue;
821 }
822
823// Read the optional 2nd operand, a DW_OP_plus_uconst.
824if (++It != Expr.end()) {
825if (It->getCode() != dwarf::DW_OP_plus_uconst)
826continue;
827
828 LocationAddr += It->getRawOperand(0);
829
830// Probe for a 3rd operand, if it exists, bail.
831if (++It != Expr.end())
832continue;
833 }
834
835Address = LocationAddr;
836break;
837 }
838
839// Get the size of the global variable. If all else fails (i.e. the global has
840// no type), then we use a size of one to still allow symbolization of the
841// exact address.
842uint64_t GVSize = 1;
843if (Die.getAttributeValueAsReferencedDie(DW_AT_type))
844if (std::optional<uint64_t>Size = Die.getTypeSize(getAddressByteSize()))
845 GVSize = *Size;
846
847if (Address !=UINT64_MAX)
848 VariableDieMap[Address] = {Address + GVSize, Die};
849}
850
851DWARFDieDWARFUnit::getVariableForAddress(uint64_tAddress) {
852 extractDIEsIfNeeded(false);
853
854auto RootDie =getUnitDIE();
855
856auto RootLookup = RootsParsedForVariables.insert(RootDie.getOffset());
857if (RootLookup.second)
858updateVariableDieMap(RootDie);
859
860auto R = VariableDieMap.upper_bound(Address);
861if (R == VariableDieMap.begin())
862returnDWARFDie();
863
864// upper_bound's previous item contains Address.
865 --R;
866if (Address >= R->second.first)
867returnDWARFDie();
868return R->second.second;
869}
870
871void
872DWARFUnit::getInlinedChainForAddress(uint64_tAddress,
873SmallVectorImpl<DWARFDie> &InlinedChain) {
874assert(InlinedChain.empty());
875// Try to look for subprogram DIEs in the DWO file.
876 parseDWO();
877// First, find the subroutine that contains the given address (the leaf
878// of inlined chain).
879DWARFDie SubroutineDIE =
880 (DWO ? *DWO : *this).getSubroutineForAddress(Address);
881
882while (SubroutineDIE) {
883if (SubroutineDIE.isSubprogramDIE()) {
884 InlinedChain.push_back(SubroutineDIE);
885return;
886 }
887if (SubroutineDIE.getTag() == DW_TAG_inlined_subroutine)
888 InlinedChain.push_back(SubroutineDIE);
889 SubroutineDIE = SubroutineDIE.getParent();
890 }
891}
892
893constDWARFUnitIndex &llvm::getDWARFUnitIndex(DWARFContext &Context,
894DWARFSectionKind Kind) {
895if (Kind == DW_SECT_INFO)
896return Context.getCUIndex();
897assert(Kind ==DW_SECT_EXT_TYPES);
898return Context.getTUIndex();
899}
900
901DWARFDieDWARFUnit::getParent(constDWARFDebugInfoEntry *Die) {
902if (constDWARFDebugInfoEntry *Entry =getParentEntry(Die))
903returnDWARFDie(this, Entry);
904
905returnDWARFDie();
906}
907
908constDWARFDebugInfoEntry *
909DWARFUnit::getParentEntry(constDWARFDebugInfoEntry *Die) const{
910if (!Die)
911returnnullptr;
912assert(Die >= DieArray.data() && Die < DieArray.data() + DieArray.size());
913
914if (std::optional<uint32_t> ParentIdx = Die->getParentIdx()) {
915assert(*ParentIdx < DieArray.size() &&
916"ParentIdx is out of DieArray boundaries");
917returngetDebugInfoEntry(*ParentIdx);
918 }
919
920returnnullptr;
921}
922
923DWARFDieDWARFUnit::getSibling(constDWARFDebugInfoEntry *Die) {
924if (constDWARFDebugInfoEntry *Sibling =getSiblingEntry(Die))
925returnDWARFDie(this, Sibling);
926
927returnDWARFDie();
928}
929
930constDWARFDebugInfoEntry *
931DWARFUnit::getSiblingEntry(constDWARFDebugInfoEntry *Die) const{
932if (!Die)
933returnnullptr;
934assert(Die >= DieArray.data() && Die < DieArray.data() + DieArray.size());
935
936if (std::optional<uint32_t> SiblingIdx = Die->getSiblingIdx()) {
937assert(*SiblingIdx < DieArray.size() &&
938"SiblingIdx is out of DieArray boundaries");
939return &DieArray[*SiblingIdx];
940 }
941
942returnnullptr;
943}
944
945DWARFDieDWARFUnit::getPreviousSibling(constDWARFDebugInfoEntry *Die) {
946if (constDWARFDebugInfoEntry *Sibling =getPreviousSiblingEntry(Die))
947returnDWARFDie(this, Sibling);
948
949returnDWARFDie();
950}
951
952constDWARFDebugInfoEntry *
953DWARFUnit::getPreviousSiblingEntry(constDWARFDebugInfoEntry *Die) const{
954if (!Die)
955returnnullptr;
956assert(Die >= DieArray.data() && Die < DieArray.data() + DieArray.size());
957
958 std::optional<uint32_t> ParentIdx = Die->getParentIdx();
959if (!ParentIdx)
960// Die is a root die, there is no previous sibling.
961returnnullptr;
962
963assert(*ParentIdx < DieArray.size() &&
964"ParentIdx is out of DieArray boundaries");
965assert(getDIEIndex(Die) > 0 &&"Die is a root die");
966
967uint32_t PrevDieIdx =getDIEIndex(Die) - 1;
968if (PrevDieIdx == *ParentIdx)
969// Immediately previous node is parent, there is no previous sibling.
970returnnullptr;
971
972while (DieArray[PrevDieIdx].getParentIdx() != *ParentIdx) {
973 PrevDieIdx = *DieArray[PrevDieIdx].getParentIdx();
974
975assert(PrevDieIdx < DieArray.size() &&
976"PrevDieIdx is out of DieArray boundaries");
977assert(PrevDieIdx >= *ParentIdx &&
978"PrevDieIdx is not a child of parent of Die");
979 }
980
981return &DieArray[PrevDieIdx];
982}
983
984DWARFDieDWARFUnit::getFirstChild(constDWARFDebugInfoEntry *Die) {
985if (constDWARFDebugInfoEntry *Child =getFirstChildEntry(Die))
986returnDWARFDie(this, Child);
987
988returnDWARFDie();
989}
990
991constDWARFDebugInfoEntry *
992DWARFUnit::getFirstChildEntry(constDWARFDebugInfoEntry *Die) const{
993if (!Die)
994returnnullptr;
995assert(Die >= DieArray.data() && Die < DieArray.data() + DieArray.size());
996
997if (!Die->hasChildren())
998returnnullptr;
999
1000// TODO: Instead of checking here for invalid die we might reject
1001// invalid dies at parsing stage(DWARFUnit::extractDIEsToVector).
1002// We do not want access out of bounds when parsing corrupted debug data.
1003size_tI =getDIEIndex(Die) + 1;
1004if (I >= DieArray.size())
1005returnnullptr;
1006return &DieArray[I];
1007}
1008
1009DWARFDieDWARFUnit::getLastChild(constDWARFDebugInfoEntry *Die) {
1010if (constDWARFDebugInfoEntry *Child =getLastChildEntry(Die))
1011returnDWARFDie(this, Child);
1012
1013returnDWARFDie();
1014}
1015
1016constDWARFDebugInfoEntry *
1017DWARFUnit::getLastChildEntry(constDWARFDebugInfoEntry *Die) const{
1018if (!Die)
1019returnnullptr;
1020assert(Die >= DieArray.data() && Die < DieArray.data() + DieArray.size());
1021
1022if (!Die->hasChildren())
1023returnnullptr;
1024
1025if (std::optional<uint32_t> SiblingIdx = Die->getSiblingIdx()) {
1026assert(*SiblingIdx < DieArray.size() &&
1027"SiblingIdx is out of DieArray boundaries");
1028assert(DieArray[*SiblingIdx - 1].getTag() == dwarf::DW_TAG_null &&
1029"Bad end of children marker");
1030return &DieArray[*SiblingIdx - 1];
1031 }
1032
1033// If SiblingIdx is set for non-root dies we could be sure that DWARF is
1034// correct and "end of children marker" must be found. For root die we do not
1035// have such a guarantee(parsing root die might be stopped if "end of children
1036// marker" is missing, SiblingIdx is always zero for root die). That is why we
1037// do not use assertion for checking for "end of children marker" for root
1038// die.
1039
1040// TODO: Instead of checking here for invalid die we might reject
1041// invalid dies at parsing stage(DWARFUnit::extractDIEsToVector).
1042if (getDIEIndex(Die) == 0 && DieArray.size() > 1 &&
1043 DieArray.back().getTag() == dwarf::DW_TAG_null) {
1044// For the unit die we might take last item from DieArray.
1045assert(getDIEIndex(Die) ==
1046getDIEIndex(const_cast<DWARFUnit *>(this)->getUnitDIE()) &&
1047"Bad unit die");
1048return &DieArray.back();
1049 }
1050
1051returnnullptr;
1052}
1053
1054constDWARFAbbreviationDeclarationSet *DWARFUnit::getAbbreviations() const{
1055if (!Abbrevs) {
1056Expected<const DWARFAbbreviationDeclarationSet *> AbbrevsOrError =
1057 Abbrev->getAbbreviationDeclarationSet(getAbbreviationsOffset());
1058if (!AbbrevsOrError) {
1059// FIXME: We should propagate this error upwards.
1060consumeError(AbbrevsOrError.takeError());
1061returnnullptr;
1062 }
1063 Abbrevs = *AbbrevsOrError;
1064 }
1065return Abbrevs;
1066}
1067
1068std::optional<object::SectionedAddress>DWARFUnit::getBaseAddress() {
1069if (BaseAddr)
1070return BaseAddr;
1071
1072DWARFDie UnitDie = (SU ? SU :this)->getUnitDIE();
1073 std::optional<DWARFFormValue> PC =
1074 UnitDie.find({DW_AT_low_pc, DW_AT_entry_pc});
1075 BaseAddr =toSectionedAddress(PC);
1076return BaseAddr;
1077}
1078
1079Expected<StrOffsetsContributionDescriptor>
1080StrOffsetsContributionDescriptor::validateContributionSize(
1081DWARFDataExtractor &DA) {
1082uint8_t EntrySize =getDwarfOffsetByteSize();
1083// In order to ensure that we don't read a partial record at the end of
1084// the section we validate for a multiple of the entry size.
1085uint64_t ValidationSize =alignTo(Size, EntrySize);
1086// Guard against overflow.
1087if (ValidationSize >=Size)
1088if (DA.isValidOffsetForDataOfSize((uint32_t)Base, ValidationSize))
1089return *this;
1090returncreateStringError(errc::invalid_argument,"length exceeds section size");
1091}
1092
1093// Look for a DWARF64-formatted contribution to the string offsets table
1094// starting at a given offset and record it in a descriptor.
1095staticExpected<StrOffsetsContributionDescriptor>
1096parseDWARF64StringOffsetsTableHeader(DWARFDataExtractor &DA,uint64_tOffset) {
1097if (!DA.isValidOffsetForDataOfSize(Offset, 16))
1098returncreateStringError(errc::invalid_argument,"section offset exceeds section size");
1099
1100if (DA.getU32(&Offset) !=dwarf::DW_LENGTH_DWARF64)
1101returncreateStringError(errc::invalid_argument,"32 bit contribution referenced from a 64 bit unit");
1102
1103uint64_tSize = DA.getU64(&Offset);
1104uint8_tVersion = DA.getU16(&Offset);
1105 (void)DA.getU16(&Offset);// padding
1106// The encoded length includes the 2-byte version field and the 2-byte
1107// padding, so we need to subtract them out when we populate the descriptor.
1108returnStrOffsetsContributionDescriptor(Offset,Size - 4,Version,DWARF64);
1109}
1110
1111// Look for a DWARF32-formatted contribution to the string offsets table
1112// starting at a given offset and record it in a descriptor.
1113staticExpected<StrOffsetsContributionDescriptor>
1114parseDWARF32StringOffsetsTableHeader(DWARFDataExtractor &DA,uint64_tOffset) {
1115if (!DA.isValidOffsetForDataOfSize(Offset, 8))
1116returncreateStringError(errc::invalid_argument,"section offset exceeds section size");
1117
1118uint32_t ContributionSize = DA.getU32(&Offset);
1119if (ContributionSize >=dwarf::DW_LENGTH_lo_reserved)
1120returncreateStringError(errc::invalid_argument,"invalid length");
1121
1122uint8_tVersion = DA.getU16(&Offset);
1123 (void)DA.getU16(&Offset);// padding
1124// The encoded length includes the 2-byte version field and the 2-byte
1125// padding, so we need to subtract them out when we populate the descriptor.
1126returnStrOffsetsContributionDescriptor(Offset, ContributionSize - 4,Version,
1127DWARF32);
1128}
1129
1130staticExpected<StrOffsetsContributionDescriptor>
1131parseDWARFStringOffsetsTableHeader(DWARFDataExtractor &DA,
1132llvm::dwarf::DwarfFormatFormat,
1133uint64_tOffset) {
1134StrOffsetsContributionDescriptorDesc;
1135switch (Format) {
1136casedwarf::DwarfFormat::DWARF64: {
1137if (Offset < 16)
1138returncreateStringError(errc::invalid_argument,"insufficient space for 64 bit header prefix");
1139auto DescOrError =parseDWARF64StringOffsetsTableHeader(DA,Offset - 16);
1140if (!DescOrError)
1141return DescOrError.takeError();
1142Desc = *DescOrError;
1143break;
1144 }
1145casedwarf::DwarfFormat::DWARF32: {
1146if (Offset < 8)
1147returncreateStringError(errc::invalid_argument,"insufficient space for 32 bit header prefix");
1148auto DescOrError =parseDWARF32StringOffsetsTableHeader(DA,Offset - 8);
1149if (!DescOrError)
1150return DescOrError.takeError();
1151Desc = *DescOrError;
1152break;
1153 }
1154 }
1155returnDesc.validateContributionSize(DA);
1156}
1157
1158Expected<std::optional<StrOffsetsContributionDescriptor>>
1159DWARFUnit::determineStringOffsetsTableContribution(DWARFDataExtractor &DA) {
1160assert(!IsDWO);
1161auto OptOffset =toSectionOffset(getUnitDIE().find(DW_AT_str_offsets_base));
1162if (!OptOffset)
1163return std::nullopt;
1164auto DescOrError =
1165parseDWARFStringOffsetsTableHeader(DA, Header.getFormat(), *OptOffset);
1166if (!DescOrError)
1167return DescOrError.takeError();
1168return *DescOrError;
1169}
1170
1171Expected<std::optional<StrOffsetsContributionDescriptor>>
1172DWARFUnit::determineStringOffsetsTableContributionDWO(DWARFDataExtractor &DA) {
1173assert(IsDWO);
1174uint64_tOffset = 0;
1175auto IndexEntry = Header.getIndexEntry();
1176constauto *C =
1177 IndexEntry ? IndexEntry->getContribution(DW_SECT_STR_OFFSETS) :nullptr;
1178if (C)
1179Offset =C->getOffset();
1180if (getVersion() >= 5) {
1181if (DA.getData().data() ==nullptr)
1182return std::nullopt;
1183Offset += Header.getFormat() ==dwarf::DwarfFormat::DWARF32 ? 8 : 16;
1184// Look for a valid contribution at the given offset.
1185auto DescOrError =parseDWARFStringOffsetsTableHeader(DA, Header.getFormat(),Offset);
1186if (!DescOrError)
1187return DescOrError.takeError();
1188return *DescOrError;
1189 }
1190// Prior to DWARF v5, we derive the contribution size from the
1191// index table (in a package file). In a .dwo file it is simply
1192// the length of the string offsets section.
1193StrOffsetsContributionDescriptorDesc;
1194if (C)
1195Desc =StrOffsetsContributionDescriptor(C->getOffset(),C->getLength(), 4,
1196 Header.getFormat());
1197elseif (!IndexEntry && !StringOffsetSection.Data.empty())
1198Desc =StrOffsetsContributionDescriptor(0, StringOffsetSection.Data.size(),
1199 4, Header.getFormat());
1200else
1201return std::nullopt;
1202auto DescOrError =Desc.validateContributionSize(DA);
1203if (!DescOrError)
1204return DescOrError.takeError();
1205return *DescOrError;
1206}
1207
1208std::optional<uint64_t>DWARFUnit::getRnglistOffset(uint32_tIndex) {
1209DataExtractor RangesData(RangeSection->Data, IsLittleEndian,
1210getAddressByteSize());
1211DWARFDataExtractor RangesDA(Context.getDWARFObj(), *RangeSection,
1212 IsLittleEndian, 0);
1213if (std::optional<uint64_t> Off =llvm::DWARFListTableHeader::getOffsetEntry(
1214 RangesData, RangeSectionBase,getFormat(),Index))
1215return *Off + RangeSectionBase;
1216return std::nullopt;
1217}
1218
1219std::optional<uint64_t>DWARFUnit::getLoclistOffset(uint32_tIndex) {
1220if (std::optional<uint64_t> Off =llvm::DWARFListTableHeader::getOffsetEntry(
1221 LocTable->getData(), LocSectionBase,getFormat(),Index))
1222return *Off + LocSectionBase;
1223return std::nullopt;
1224}
B
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
D
static GCRegistry::Add< StatepointGC > D("statepoint-example", "an example strategy for statepoint")
DWARFAbbreviationDeclaration.h
DWARFCompileUnit.h
DWARFContext.h
DWARFDebugAbbrev.h
DWARFDebugInfoEntry.h
DWARFDebugLoc.h
DWARFDebugRangeList.h
DWARFDebugRnglists.h
DWARFDie.h
DWARFExpression.h
DWARFFormValue.h
DWARFListTable.h
DWARFObject.h
DWARFSection.h
DWARFTypeUnit.h
parseDWARF64StringOffsetsTableHeader
static Expected< StrOffsetsContributionDescriptor > parseDWARF64StringOffsetsTableHeader(DWARFDataExtractor &DA, uint64_t Offset)
Definition:DWARFUnit.cpp:1096
parseDWARF32StringOffsetsTableHeader
static Expected< StrOffsetsContributionDescriptor > parseDWARF32StringOffsetsTableHeader(DWARFDataExtractor &DA, uint64_t Offset)
Definition:DWARFUnit.cpp:1114
parseDWARFStringOffsetsTableHeader
static Expected< StrOffsetsContributionDescriptor > parseDWARFStringOffsetsTableHeader(DWARFDataExtractor &DA, llvm::dwarf::DwarfFormat Format, uint64_t Offset)
Definition:DWARFUnit.cpp:1131
DWARFUnit.h
DataExtractor.h
Dwarf.h
This file contains constants used for implementing Dwarf debug support.
Size
uint64_t Size
Definition:ELFObjHandler.cpp:81
Errc.h
I
#define I(x, y, z)
Definition:MD5.cpp:58
ObjectFile.h
Path.h
assert
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
SmallString.h
This file defines the SmallString class.
StringRef.h
RHS
Value * RHS
Definition:X86PartialReduction.cpp:74
LHS
Value * LHS
Definition:X86PartialReduction.cpp:73
llvm::DIE
A structured debug information entry.
Definition:DIE.h:819
llvm::DWARFAbbreviationDeclarationSet
Definition:DWARFDebugAbbrev.h:22
llvm::DWARFAbbreviationDeclaration
Definition:DWARFAbbreviationDeclaration.h:26
llvm::DWARFCompileUnit
Definition:DWARFCompileUnit.h:22
llvm::DWARFContext
DWARFContext This data structure is the top level entity that deals with dwarf debug information pars...
Definition:DWARFContext.h:48
llvm::DWARFContext::isSupportedVersion
static bool isSupportedVersion(unsigned version)
Definition:DWARFContext.h:406
llvm::DWARFContext::getRecoverableErrorHandler
function_ref< void(Error)> getRecoverableErrorHandler()
Definition:DWARFContext.h:436
llvm::DWARFContext::getTUIndex
const DWARFUnitIndex & getTUIndex()
Definition:DWARFContext.cpp:1417
llvm::DWARFContext::checkAddressSizeSupported
static Error checkAddressSizeSupported(unsigned AddressSize, std::error_code EC, char const *Fmt, const Ts &...Vals)
Definition:DWARFContext.h:417
llvm::DWARFContext::getWarningHandler
function_ref< void(Error)> getWarningHandler()
Definition:DWARFContext.h:440
llvm::DWARFContext::setMaxVersionIfGreater
void setMaxVersionIfGreater(unsigned Version)
Definition:DWARFContext.h:291
llvm::DWARFContext::getMaxSupportedVersion
static unsigned getMaxSupportedVersion()
Definition:DWARFContext.h:405
llvm::DWARFContext::getDWOContext
std::shared_ptr< DWARFContext > getDWOContext(StringRef AbsolutePath)
Definition:DWARFContext.cpp:1894
llvm::DWARFContext::getCUIndex
const DWARFUnitIndex & getCUIndex()
Definition:DWARFContext.cpp:1413
llvm::DWARFContext::info_section_units
unit_iterator_range info_section_units()
Get units from .debug_info in this context.
Definition:DWARFContext.h:169
llvm::DWARFContext::getDWARFObj
const DWARFObject & getDWARFObj() const
Definition:DWARFContext.h:147
llvm::DWARFDataExtractor
A DataExtractor (typically for an in-memory copy of an object-file section) plus a relocation map for...
Definition:DWARFDataExtractor.h:21
llvm::DWARFDataExtractor::getInitialLength
std::pair< uint64_t, dwarf::DwarfFormat > getInitialLength(uint64_t *Off, Error *Err=nullptr) const
Extracts the DWARF "initial length" field, which can either be a 32-bit value smaller than 0xfffffff0...
Definition:DWARFDataExtractor.cpp:17
llvm::DWARFDataExtractor::getRelocatedValue
uint64_t getRelocatedValue(uint32_t Size, uint64_t *Off, uint64_t *SectionIndex=nullptr, Error *Err=nullptr) const
Extracts a value and applies a relocation to the result if one exists for the given offset.
Definition:DWARFDataExtractor.cpp:48
llvm::DWARFDebugAbbrev
Definition:DWARFDebugAbbrev.h:58
llvm::DWARFDebugAbbrev::getAbbreviationDeclarationSet
Expected< const DWARFAbbreviationDeclarationSet * > getAbbreviationDeclarationSet(uint64_t CUAbbrOffset) const
Definition:DWARFDebugAbbrev.cpp:144
llvm::DWARFDebugInfoEntry
DWARFDebugInfoEntry - A DIE with only the minimum required data.
Definition:DWARFDebugInfoEntry.h:22
llvm::DWARFDebugInfoEntry::getSiblingIdx
std::optional< uint32_t > getSiblingIdx() const
Returns index of the sibling die.
Definition:DWARFDebugInfoEntry.h:56
llvm::DWARFDebugInfoEntry::getParentIdx
std::optional< uint32_t > getParentIdx() const
Returns index of the parent die.
Definition:DWARFDebugInfoEntry.h:48
llvm::DWARFDebugInfoEntry::hasChildren
bool hasChildren() const
Definition:DWARFDebugInfoEntry.h:70
llvm::DWARFDebugRangeList
Definition:DWARFDebugRangeList.h:24
llvm::DWARFDebugRangeList::extract
Error extract(const DWARFDataExtractor &data, uint64_t *offset_ptr)
Definition:DWARFDebugRangeList.cpp:31
llvm::DWARFDebugRangeList::getAbsoluteRanges
DWARFAddressRangesVector getAbsoluteRanges(std::optional< object::SectionedAddress > BaseAddr) const
getAbsoluteRanges - Returns absolute address ranges defined by this range list.
Definition:DWARFDebugRangeList.cpp:87
llvm::DWARFDebugRnglistTable
Definition:DWARFDebugRnglists.h:62
llvm::DWARFDie
Utility class that carries the DWARF compile/type unit and the debug info entry in an object.
Definition:DWARFDie.h:42
llvm::DWARFDie::getAddressRanges
Expected< DWARFAddressRangesVector > getAddressRanges() const
Get the address ranges for this DIE.
Definition:DWARFDie.cpp:386
llvm::DWARFDie::getAttributeValueAsReferencedDie
DWARFDie getAttributeValueAsReferencedDie(dwarf::Attribute Attr) const
Extract the specified attribute from this DIE as the referenced DIE.
Definition:DWARFDie.cpp:305
llvm::DWARFDie::getParent
DWARFDie getParent() const
Get the parent of this DIE object.
Definition:DWARFDie.cpp:654
llvm::DWARFDie::find
std::optional< DWARFFormValue > find(dwarf::Attribute Attr) const
Extract the specified attribute from this DIE.
Definition:DWARFDie.cpp:249
llvm::DWARFDie::getSibling
DWARFDie getSibling() const
Get the sibling of this DIE object.
Definition:DWARFDie.cpp:660
llvm::DWARFDie::isSubroutineDIE
bool isSubroutineDIE() const
Returns true if DIE represents a subprogram or an inlined subroutine.
Definition:DWARFDie.cpp:244
llvm::DWARFDie::isSubprogramDIE
bool isSubprogramDIE() const
Returns true if DIE represents a subprogram (not inlined).
Definition:DWARFDie.cpp:242
llvm::DWARFDie::getTypeSize
std::optional< uint64_t > getTypeSize(uint64_t PointerSize)
Gets the type size (in bytes) for this DIE.
Definition:DWARFDie.cpp:577
llvm::DWARFDie::getFirstChild
DWARFDie getFirstChild() const
Get the first child of this DIE object.
Definition:DWARFDie.cpp:672
llvm::DWARFDie::getTag
dwarf::Tag getTag() const
Definition:DWARFDie.h:72
llvm::DWARFDie::getLocations
Expected< DWARFLocationExpressionsVector > getLocations(dwarf::Attribute Attr) const
Definition:DWARFDie.cpp:426
llvm::DWARFDie::getRangesBaseAttribute
std::optional< uint64_t > getRangesBaseAttribute() const
Extract the range base attribute from this DIE as absolute section offset.
Definition:DWARFDie.cpp:346
llvm::DWARFExpression
Definition:DWARFExpression.h:23
llvm::DWARFExpression::end
iterator end() const
Definition:DWARFExpression.h:153
llvm::DWARFExpression::begin
iterator begin() const
Definition:DWARFExpression.h:152
llvm::DWARFListTableBase::findList
Expected< DWARFListType > findList(DWARFDataExtractor Data, uint64_t Offset) const
Look up a list based on a given offset.
Definition:DWARFListTable.h:282
llvm::DWARFListTableHeader::getHeaderSize
static uint8_t getHeaderSize(dwarf::DwarfFormat Format)
Return the size of the table header including the length but not including the offsets.
Definition:DWARFListTable.h:103
llvm::DWARFListTableHeader::getOffsetEntry
std::optional< uint64_t > getOffsetEntry(DataExtractor Data, uint32_t Index) const
Definition:DWARFListTable.h:115
llvm::DWARFLocationTable::visitAbsoluteLocationList
Error visitAbsoluteLocationList(uint64_t Offset, std::optional< object::SectionedAddress > BaseAddr, std::function< std::optional< object::SectionedAddress >(uint32_t)> LookupAddr, function_ref< bool(Expected< DWARFLocationExpression >)> Callback) const
Definition:DWARFDebugLoc.cpp:169
llvm::DWARFObject
Definition:DWARFObject.h:26
llvm::DWARFObject::getLoclistsSection
virtual const DWARFSection & getLoclistsSection() const
Definition:DWARFObject.h:42
llvm::DWARFObject::getLocDWOSection
virtual const DWARFSection & getLocDWOSection() const
Definition:DWARFObject.h:66
llvm::DWARFObject::getRnglistsDWOSection
virtual const DWARFSection & getRnglistsDWOSection() const
Definition:DWARFObject.h:73
llvm::DWARFObject::getLocSection
virtual const DWARFSection & getLocSection() const
Definition:DWARFObject.h:41
llvm::DWARFObject::getRnglistsSection
virtual const DWARFSection & getRnglistsSection() const
Definition:DWARFObject.h:50
llvm::DWARFObject::getLoclistsDWOSection
virtual const DWARFSection & getLoclistsDWOSection() const
Definition:DWARFObject.h:67
llvm::DWARFUnitHeader
Base class describing the header of any kind of "unit." Some information is specific to certain unit ...
Definition:DWARFUnit.h:55
llvm::DWARFUnitHeader::extract
Error extract(DWARFContext &Context, const DWARFDataExtractor &debug_info, uint64_t *offset_ptr, DWARFSectionKind SectionKind)
Parse a unit header from debug_info starting at offset_ptr.
Definition:DWARFUnit.cpp:254
llvm::DWARFUnitHeader::applyIndexEntry
Error applyIndexEntry(const DWARFUnitIndex::Entry *Entry)
Definition:DWARFUnit.cpp:341
llvm::DWARFUnitHeader::getLength
uint64_t getLength() const
Definition:DWARFUnit.h:98
llvm::DWARFUnitHeader::getVersion
uint16_t getVersion() const
Definition:DWARFUnit.h:91
llvm::DWARFUnitHeader::getAddressByteSize
uint8_t getAddressByteSize() const
Definition:DWARFUnit.h:93
llvm::DWARFUnitHeader::getNextUnitOffset
uint64_t getNextUnitOffset() const
Definition:DWARFUnit.h:116
llvm::DWARFUnitHeader::getUnitLengthFieldByteSize
uint8_t getUnitLengthFieldByteSize() const
Definition:DWARFUnit.h:113
llvm::DWARFUnitHeader::isTypeUnit
bool isTypeUnit() const
Definition:DWARFUnit.h:109
llvm::DWARFUnitIndex::Entry
Definition:DWARFUnitIndex.h:111
llvm::DWARFUnitIndex::Entry::getContribution
const SectionContribution * getContribution(DWARFSectionKind Sec) const
Definition:DWARFUnitIndex.cpp:264
llvm::DWARFUnitIndex
Definition:DWARFUnitIndex.h:99
llvm::DWARFUnitVector
Describe a collection of units.
Definition:DWARFUnit.h:128
llvm::DWARFUnitVector::addUnit
DWARFUnit * addUnit(std::unique_ptr< DWARFUnit > Unit)
Add an existing DWARFUnit to this UnitVector.
Definition:DWARFUnit.cpp:143
llvm::DWARFUnitVector::getNumInfoUnits
unsigned getNumInfoUnits() const
Returns number of units from all .debug_info[.dwo] sections.
Definition:DWARFUnit.h:167
llvm::DWARFUnitVector::addUnitsForSection
void addUnitsForSection(DWARFContext &C, const DWARFSection &Section, DWARFSectionKind SectionKind)
Read units from a .debug_info or .debug_types section.
Definition:DWARFUnit.cpp:42
llvm::DWARFUnitVector::getUnitForOffset
DWARFUnit * getUnitForOffset(uint64_t Offset) const
Definition:DWARFUnit.cpp:152
llvm::DWARFUnitVector::addUnitsForDWOSection
void addUnitsForDWOSection(DWARFContext &C, const DWARFSection &DWOSection, DWARFSectionKind SectionKind, bool Lazy=false)
Read units from a .debug_info.dwo or .debug_types.dwo section.
Definition:DWARFUnit.cpp:53
llvm::DWARFUnitVector::getUnitForIndexEntry
DWARFUnit * getUnitForIndexEntry(const DWARFUnitIndex::Entry &E)
Definition:DWARFUnit.cpp:165
llvm::DWARFUnit
Definition:DWARFUnit.h:211
llvm::DWARFUnit::getDebugInfoEntry
const DWARFDebugInfoEntry * getDebugInfoEntry(unsigned Index) const
Return DWARFDebugInfoEntry for the specified index Index.
Definition:DWARFUnit.h:276
llvm::DWARFUnit::getSiblingEntry
const DWARFDebugInfoEntry * getSiblingEntry(const DWARFDebugInfoEntry *Die) const
Definition:DWARFUnit.cpp:931
llvm::DWARFUnit::getDWOId
std::optional< uint64_t > getDWOId()
Definition:DWARFUnit.h:458
llvm::DWARFUnit::getHeaderSize
uint32_t getHeaderSize() const
Size in bytes of the parsed unit header.
Definition:DWARFUnit.h:332
llvm::DWARFUnit::getPreviousSibling
DWARFDie getPreviousSibling(const DWARFDebugInfoEntry *Die)
Definition:DWARFUnit.cpp:945
llvm::DWARFUnit::determineStringOffsetsTableContributionDWO
Expected< std::optional< StrOffsetsContributionDescriptor > > determineStringOffsetsTableContributionDWO(DWARFDataExtractor &DA)
Find the unit's contribution to the string offsets table and determine its length and form.
Definition:DWARFUnit.cpp:1172
llvm::DWARFUnit::getLocationTable
const DWARFLocationTable & getLocationTable()
Definition:DWARFUnit.h:394
llvm::DWARFUnit::getParentEntry
const DWARFDebugInfoEntry * getParentEntry(const DWARFDebugInfoEntry *Die) const
Definition:DWARFUnit.cpp:909
llvm::DWARFUnit::getFirstChild
DWARFDie getFirstChild(const DWARFDebugInfoEntry *Die)
Definition:DWARFUnit.cpp:984
llvm::DWARFUnit::getDebugInfoExtractor
DWARFDataExtractor getDebugInfoExtractor() const
Definition:DWARFUnit.cpp:209
llvm::DWARFUnit::getSibling
DWARFDie getSibling(const DWARFDebugInfoEntry *Die)
Definition:DWARFUnit.cpp:923
llvm::DWARFUnit::getRnglistOffset
std::optional< uint64_t > getRnglistOffset(uint32_t Index)
Return a rangelist's offset based on an index.
Definition:DWARFUnit.cpp:1208
llvm::DWARFUnit::tryExtractDIEsIfNeeded
Error tryExtractDIEsIfNeeded(bool CUDieOnly)
Definition:DWARFUnit.cpp:498
llvm::DWARFUnit::getUnitDIE
DWARFDie getUnitDIE(bool ExtractUnitDIEOnly=true)
Definition:DWARFUnit.h:443
llvm::DWARFUnit::~DWARFUnit
virtual ~DWARFUnit()
llvm::DWARFUnit::getAddressByteSize
uint8_t getAddressByteSize() const
Definition:DWARFUnit.h:326
llvm::DWARFUnit::getVariableForAddress
DWARFDie getVariableForAddress(uint64_t Address)
Returns variable DIE for the address provided.
Definition:DWARFUnit.cpp:851
llvm::DWARFUnit::setRangesSection
void setRangesSection(const DWARFSection *RS, uint64_t Base)
Definition:DWARFUnit.h:375
llvm::DWARFUnit::getDwarfStringOffsetsByteSize
uint8_t getDwarfStringOffsetsByteSize() const
Definition:DWARFUnit.h:410
llvm::DWARFUnit::getAbbreviations
const DWARFAbbreviationDeclarationSet * getAbbreviations() const
Definition:DWARFUnit.cpp:1054
llvm::DWARFUnit::getParent
DWARFDie getParent(const DWARFDebugInfoEntry *Die)
Definition:DWARFUnit.cpp:901
llvm::DWARFUnit::clear
void clear()
Definition:DWARFUnit.cpp:387
llvm::DWARFUnit::getLoclistOffset
std::optional< uint64_t > getLoclistOffset(uint32_t Index)
Definition:DWARFUnit.cpp:1219
llvm::DWARFUnit::getCompilationDir
const char * getCompilationDir()
Definition:DWARFUnit.cpp:401
llvm::DWARFUnit::getStringOffsetsBase
uint64_t getStringOffsetsBase() const
Definition:DWARFUnit.h:415
llvm::DWARFUnit::getFormat
dwarf::DwarfFormat getFormat() const
Definition:DWARFUnit.h:334
llvm::DWARFUnit::DWARFUnit
DWARFUnit(DWARFContext &Context, const DWARFSection &Section, const DWARFUnitHeader &Header, const DWARFDebugAbbrev *DA, const DWARFSection *RS, const DWARFSection *LocSection, StringRef SS, const DWARFSection &SOS, const DWARFSection *AOS, const DWARFSection &LS, bool LE, bool IsDWO, const DWARFUnitVector &UnitVector)
Definition:DWARFUnit.cpp:194
llvm::DWARFUnit::determineStringOffsetsTableContribution
Expected< std::optional< StrOffsetsContributionDescriptor > > determineStringOffsetsTableContribution(DWARFDataExtractor &DA)
Find the unit's contribution to the string offsets table and determine its length and form.
Definition:DWARFUnit.cpp:1159
llvm::DWARFUnit::getAbbreviationsOffset
uint64_t getAbbreviationsOffset() const
Definition:DWARFUnit.h:420
llvm::DWARFUnit::getVersion
uint16_t getVersion() const
Definition:DWARFUnit.h:325
llvm::DWARFUnit::getInlinedChainForAddress
void getInlinedChainForAddress(uint64_t Address, SmallVectorImpl< DWARFDie > &InlinedChain)
getInlinedChainForAddress - fetches inlined chain for a given address.
Definition:DWARFUnit.cpp:872
llvm::DWARFUnit::extractRangeList
Error extractRangeList(uint64_t RangeListOffset, DWARFDebugRangeList &RangeList) const
Extract the range list referenced by this compile unit from the .debug_ranges section.
Definition:DWARFUnit.cpp:377
llvm::DWARFUnit::getStringOffsetSectionItem
Expected< uint64_t > getStringOffsetSectionItem(uint32_t Index) const
Definition:DWARFUnit.cpp:238
llvm::DWARFUnit::getDIEIndex
uint32_t getDIEIndex(const DWARFDebugInfoEntry *Die) const
Return the index of a Die entry inside the unit's DIE vector.
Definition:DWARFUnit.h:269
llvm::DWARFUnit::findLoclistFromOffset
Expected< DWARFLocationExpressionsVector > findLoclistFromOffset(uint64_t Offset)
Definition:DWARFUnit.cpp:709
llvm::DWARFUnit::findRnglistFromOffset
Expected< DWARFAddressRangesVector > findRnglistFromOffset(uint64_t Offset)
Return a vector of address ranges resulting from a (possibly encoded) range list starting at a given ...
Definition:DWARFUnit.cpp:667
llvm::DWARFUnit::isLittleEndian
bool isLittleEndian() const
Definition:DWARFUnit.h:317
llvm::DWARFUnit::getPreviousSiblingEntry
const DWARFDebugInfoEntry * getPreviousSiblingEntry(const DWARFDebugInfoEntry *Die) const
Definition:DWARFUnit.cpp:953
llvm::DWARFUnit::getLastChildEntry
const DWARFDebugInfoEntry * getLastChildEntry(const DWARFDebugInfoEntry *Die) const
Definition:DWARFUnit.cpp:1017
llvm::DWARFUnit::updateVariableDieMap
void updateVariableDieMap(DWARFDie Die)
Recursively update address to variable Die map.
Definition:DWARFUnit.cpp:777
llvm::DWARFUnit::getSubroutineForAddress
DWARFDie getSubroutineForAddress(uint64_t Address)
Returns subprogram DIE with address range encompassing the provided address.
Definition:DWARFUnit.cpp:763
llvm::DWARFUnit::getFirstChildEntry
const DWARFDebugInfoEntry * getFirstChildEntry(const DWARFDebugInfoEntry *Die) const
Definition:DWARFUnit.cpp:992
llvm::DWARFUnit::findRnglistFromIndex
Expected< DWARFAddressRangesVector > findRnglistFromIndex(uint32_t Index)
Return a vector of address ranges retrieved from an encoded range list whose offset is found via a ta...
Definition:DWARFUnit.cpp:684
llvm::DWARFUnit::getNextUnitOffset
uint64_t getNextUnitOffset() const
Definition:DWARFUnit.h:338
llvm::DWARFUnit::getBaseAddress
std::optional< object::SectionedAddress > getBaseAddress()
Definition:DWARFUnit.cpp:1068
llvm::DWARFUnit::collectAddressRanges
Expected< DWARFAddressRangesVector > collectAddressRanges()
Definition:DWARFUnit.cpp:694
llvm::DWARFUnit::getAddrOffsetSectionItem
std::optional< object::SectionedAddress > getAddrOffsetSectionItem(uint32_t Index) const
Definition:DWARFUnit.cpp:215
llvm::DWARFUnit::getOffset
uint64_t getOffset() const
Definition:DWARFUnit.h:321
llvm::DWARFUnit::getLastChild
DWARFDie getLastChild(const DWARFDebugInfoEntry *Die)
Definition:DWARFUnit.cpp:1009
llvm::DWARFUnit::updateAddressDieMap
void updateAddressDieMap(DWARFDie Die)
Recursively update address to Die map.
Definition:DWARFUnit.cpp:732
llvm::DataExtractor
Definition:DataExtractor.h:41
llvm::DataExtractor::getUnsigned
uint64_t getUnsigned(uint64_t *offset_ptr, uint32_t byte_size, Error *Err=nullptr) const
Extract an unsigned integer of size byte_size from *offset_ptr.
Definition:DataExtractor.cpp:126
llvm::DataExtractor::size
size_t size() const
Return the number of bytes in the underlying buffer.
Definition:DataExtractor.h:688
llvm::DataExtractor::getU8
uint8_t getU8(uint64_t *offset_ptr, Error *Err=nullptr) const
Extract a uint8_t value from *offset_ptr.
Definition:DataExtractor.cpp:80
llvm::DataExtractor::getU16
uint16_t getU16(uint64_t *offset_ptr, Error *Err=nullptr) const
Extract a uint16_t value from *offset_ptr.
Definition:DataExtractor.cpp:93
llvm::DataExtractor::getU64
uint64_t getU64(uint64_t *offset_ptr, Error *Err=nullptr) const
Extract a uint64_t value from *offset_ptr.
Definition:DataExtractor.cpp:117
llvm::DataExtractor::isValidOffset
bool isValidOffset(uint64_t offset) const
Test the validity of offset.
Definition:DataExtractor.h:665
llvm::Error
Lightweight error class with error context and mandatory checking.
Definition:Error.h:160
llvm::Error::success
static ErrorSuccess success()
Create a success value.
Definition:Error.h:337
llvm::Expected
Tagged union holding either a T or a Error.
Definition:Error.h:481
llvm::Expected::takeError
Error takeError()
Take ownership of the stored error.
Definition:Error.h:608
llvm::SectionKind
SectionKind - This is a simple POD value that classifies the properties of a section.
Definition:SectionKind.h:22
llvm::SmallString
SmallString - A SmallString is just a SmallVector with methods and accessors that make it work better...
Definition:SmallString.h:26
llvm::SmallVectorBase::empty
bool empty() const
Definition:SmallVector.h:81
llvm::SmallVectorImpl
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
Definition:SmallVector.h:573
llvm::SmallVectorImpl::insert
iterator insert(iterator I, T &&Elt)
Definition:SmallVector.h:805
llvm::SmallVectorTemplateBase::push_back
void push_back(const T &Elt)
Definition:SmallVector.h:413
llvm::SmallVectorTemplateCommon::end
iterator end()
Definition:SmallVector.h:269
llvm::SmallVectorTemplateCommon::begin
iterator begin()
Definition:SmallVector.h:267
llvm::StringRef
StringRef - Represent a constant reference to a string, i.e.
Definition:StringRef.h:51
llvm::StringRef::empty
constexpr bool empty() const
empty - Check if the string is empty.
Definition:StringRef.h:147
llvm::StringRef::size
constexpr size_t size() const
size - Get the string size.
Definition:StringRef.h:150
llvm::Twine
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
Definition:Twine.h:81
llvm::detail::DenseSetImpl::insert
std::pair< iterator, bool > insert(const ValueT &V)
Definition:DenseSet.h:213
uint32_t
uint64_t
uint8_t
llvm::dwarf::getTag
unsigned getTag(StringRef TagString)
Definition:Dwarf.cpp:32
UINT64_MAX
#define UINT64_MAX
Definition:DataTypes.h:77
CU
Definition:AArch64AsmBackend.cpp:549
llvm::CallingConv::C
@ C
The default llvm calling convention, compatible with C.
Definition:CallingConv.h:34
llvm::M68k::MemAddrModeKind::U
@ U
llvm::dwarf::toString
std::optional< const char * > toString(const std::optional< DWARFFormValue > &V)
Take an optional DWARFFormValue and try to extract a string value from it.
Definition:DWARFFormValue.h:177
llvm::dwarf::toSectionedAddress
std::optional< object::SectionedAddress > toSectionedAddress(const std::optional< DWARFFormValue > &V)
Definition:DWARFFormValue.h:376
llvm::dwarf::Index
Index
Definition:Dwarf.h:882
llvm::dwarf::UnitType
UnitType
Constants for unit types in DWARF v5.
Definition:Dwarf.h:875
llvm::dwarf::isType
bool isType(Tag T)
Definition:Dwarf.h:111
llvm::dwarf::DwarfFormat
DwarfFormat
Constants that define the DWARF format as 32 or 64 bit.
Definition:Dwarf.h:91
llvm::dwarf::DWARF64
@ DWARF64
Definition:Dwarf.h:91
llvm::dwarf::DWARF32
@ DWARF32
Definition:Dwarf.h:91
llvm::dwarf::toSectionOffset
std::optional< uint64_t > toSectionOffset(const std::optional< DWARFFormValue > &V)
Take an optional DWARFFormValue and try to extract an section offset.
Definition:DWARFFormValue.h:399
llvm::dwarf::toUnsigned
std::optional< uint64_t > toUnsigned(const std::optional< DWARFFormValue > &V)
Take an optional DWARFFormValue and try to extract an unsigned constant.
Definition:DWARFFormValue.h:226
llvm::dwarf::DW_LENGTH_lo_reserved
@ DW_LENGTH_lo_reserved
Special values for an initial length field.
Definition:Dwarf.h:54
llvm::dwarf::DW_LENGTH_DWARF64
@ DW_LENGTH_DWARF64
Indicator of 64-bit DWARF format.
Definition:Dwarf.h:55
llvm::logicalview::LVReportKind::Parents
@ Parents
llvm::sys::path::is_relative
bool is_relative(const Twine &path, Style style=Style::native)
Is path relative?
Definition:Path.cpp:699
llvm::sys::path::append
void append(SmallVectorImpl< char > &path, const Twine &a, const Twine &b="", const Twine &c="", const Twine &d="")
Append to path.
Definition:Path.cpp:456
llvm
This is an optimization pass for GlobalISel generic memory operations.
Definition:AddressRanges.h:18
llvm::Offset
@ Offset
Definition:DWP.cpp:480
llvm::find
auto find(R &&Range, const T &Val)
Provide wrappers to std::find which take ranges instead of having to pass begin/end explicitly.
Definition:STLExtras.h:1759
llvm::getDWARFUnitIndex
const DWARFUnitIndex & getDWARFUnitIndex(DWARFContext &Context, DWARFSectionKind Kind)
Definition:DWARFUnit.cpp:893
llvm::inconvertibleErrorCode
std::error_code inconvertibleErrorCode()
The value returned by this function can be returned from convertToErrorCode for Error values where no...
Definition:Error.cpp:98
llvm::upper_bound
auto upper_bound(R &&Range, T &&Value)
Provide wrappers to std::upper_bound which take ranges instead of having to pass begin/end explicitly...
Definition:STLExtras.h:1991
llvm::createStringError
Error createStringError(std::error_code EC, char const *Fmt, const Ts &... Vals)
Create formatted StringError object.
Definition:Error.h:1291
llvm::Desc
Op::Description Desc
Definition:DWARFExpression.cpp:23
llvm::DWARFSectionKind
DWARFSectionKind
The enum of section identifiers to be used in internal interfaces.
Definition:DWARFUnitIndex.h:56
llvm::DW_SECT_EXT_LOC
@ DW_SECT_EXT_LOC
Definition:DWARFUnitIndex.h:63
llvm::DW_SECT_EXT_TYPES
@ DW_SECT_EXT_TYPES
Definition:DWARFUnitIndex.h:62
llvm::errc::invalid_argument
@ invalid_argument
llvm::DWARFLocationExpressionsVector
std::vector< DWARFLocationExpression > DWARFLocationExpressionsVector
Represents a set of absolute location expressions.
Definition:DWARFLocationExpression.h:44
llvm::joinErrors
Error joinErrors(Error E1, Error E2)
Concatenate errors.
Definition:Error.h:438
llvm::hasSingleElement
bool hasSingleElement(ContainerTy &&C)
Returns true if the given container only contains a single element.
Definition:STLExtras.h:322
llvm::CaptureComponents::Address
@ Address
llvm::alignTo
uint64_t alignTo(uint64_t Size, Align A)
Returns a multiple of A needed to store Size bytes.
Definition:Alignment.h:155
llvm::ReplacementType::Format
@ Format
llvm::toString
const char * toString(DWARFSectionKind Kind)
Definition:DWARFUnitIndex.h:67
llvm::Data
@ Data
Definition:SIMachineScheduler.h:55
llvm::consumeError
void consumeError(Error Err)
Consume a Error without doing anything.
Definition:Error.h:1069
llvm::Version
@ Version
Definition:PGOCtxProfWriter.h:22
llvm::DWARFExpression::Operation::Description
Description of the encoding of one expression Op.
Definition:DWARFExpression.h:66
llvm::DWARFLocationExpression
Represents a single DWARF expression, whose value is location-dependent.
Definition:DWARFLocationExpression.h:21
llvm::DWARFSection
Definition:DWARFSection.h:16
llvm::DWARFSection::Data
StringRef Data
Definition:DWARFSection.h:17
llvm::StrOffsetsContributionDescriptor
Represents base address of the CU.
Definition:DWARFUnit.h:187
llvm::StrOffsetsContributionDescriptor::Base
uint64_t Base
Definition:DWARFUnit.h:188
llvm::StrOffsetsContributionDescriptor::validateContributionSize
Expected< StrOffsetsContributionDescriptor > validateContributionSize(DWARFDataExtractor &DA)
Determine whether a contribution to the string offsets table is consistent with the relevant section ...
Definition:DWARFUnit.cpp:1080
llvm::StrOffsetsContributionDescriptor::Size
uint64_t Size
The contribution size not including the header.
Definition:DWARFUnit.h:190
llvm::StrOffsetsContributionDescriptor::getDwarfOffsetByteSize
uint8_t getDwarfOffsetByteSize() const
Definition:DWARFUnit.h:201
llvm::dwarf::FormParams
A helper struct providing information about the byte size of DW_FORM values that vary in size dependi...
Definition:Dwarf.h:1084
llvm::dwarf::FormParams::Format
DwarfFormat Format
Definition:Dwarf.h:1087
llvm::dwarf::FormParams::getDwarfOffsetByteSize
uint8_t getDwarfOffsetByteSize() const
The size of a reference is determined by the DWARF 32/64-bit format.
Definition:Dwarf.h:1102
llvm::dwarf::FormParams::AddrSize
uint8_t AddrSize
Definition:Dwarf.h:1086
llvm::dwarf::FormParams::Version
uint16_t Version
Definition:Dwarf.h:1085

Generated on Sun Jul 20 2025 09:09:10 for LLVM by doxygen 1.9.6
[8]ページ先頭

©2009-2025 Movatter.jp