llvm.org GIT mirror llvm / 2b9857e
[DebugInfo/DWARF] [2/4] Type units no longer in a std::deque. NFC This is patch 2 of 4 NFC refactorings to handle type units and compile units more consistently and with less concern about the object-file section that they came from. Patch 2 takes the existing std::deque<DWARFUnitSection> for type units and makes it a simple DWARFUnitSection, simplifying the handling of type units and making it more consistent with compile units. Differential Revision: https://reviews.llvm.org/D49742 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@338629 91177308-0d34-0410-b5e6-96231b3b80d8 Paul Robinson 1 year, 2 months ago
7 changed file(s) with 105 addition(s) and 102 deletion(s). Raw diff Collapse all Expand all
5757 /// information parsing. The actual data is supplied through DWARFObj.
5858 class DWARFContext : public DIContext {
5959 DWARFUnitSection CUs;
60 std::deque TUs;
60 DWARFUnitSection TUs;
6161 std::unique_ptr CUIndex;
6262 std::unique_ptr GdbIndex;
6363 std::unique_ptr TUIndex;
7575 std::unique_ptr AppleObjC;
7676
7777 DWARFUnitSection DWOCUs;
78 std::deque DWOTUs;
78 DWARFUnitSection DWOTUs;
7979 std::unique_ptr AbbrevDWO;
8080 std::unique_ptr LocDWO;
8181
140140
141141 using cu_iterator_range = DWARFUnitSection::iterator_range;
142142 using tu_iterator_range = DWARFUnitSection::iterator_range;
143 using tu_section_iterator_range = iterator_range;
144143
145144 /// Get compile units in this context.
146145 cu_iterator_range compile_units() {
149148 }
150149
151150 /// Get type units in this context.
152 tu_section_iterator_range type_unit_sections() {
151 tu_iterator_range type_units() {
153152 parseTypeUnits();
154 return tu_section_iterator_range(TUs.begin(), TUs.end());
153 return tu_iterator_range(TUs.begin(), TUs.end());
155154 }
156155
157156 /// Get compile units in the DWO context.
161160 }
162161
163162 /// Get type units in the DWO context.
164 tu_section_iterator_range dwo_type_unit_sections() {
163 tu_iterator_range dwo_type_units() {
165164 parseDWOTypeUnits();
166 return tu_section_iterator_range(DWOTUs.begin(), DWOTUs.end());
165 return tu_iterator_range(DWOTUs.begin(), DWOTUs.end());
167166 }
168167
169168 /// Get the number of compile units in this context.
278278 class SectionParser {
279279 public:
280280 using cu_range = DWARFUnitSection::iterator_range;
281 using tu_range = iterator_range::iterator>;
281 using tu_range = DWARFUnitSection::iterator_range;
282282 using LineToUnitMap = std::map;
283283
284284 SectionParser(DWARFDataExtractor &Data, const DWARFContext &C, cu_range CUs,
105105
106106 /// Describes one section's Units.
107107 class DWARFUnitSection final : public SmallVector, 1> {
108 bool Parsed = false;
109 std::function(uint32_t)> Parser;
108 std::function(uint32_t, const DWARFSection *)>
109 Parser;
110110
111111 public:
112112 using UnitVector = SmallVectorImpl>;
115115
116116 DWARFUnit *getUnitForOffset(uint32_t Offset) const;
117117 DWARFUnit *getUnitForIndexEntry(const DWARFUnitIndex::Entry &E);
118 void parse(DWARFContext &C, const DWARFSection &Section,
119 DWARFSectionKind SectionKind);
120 void parseDWO(DWARFContext &C, const DWARFSection &DWOSection,
121 DWARFSectionKind SectionKind, bool Lazy = false);
118 void addUnitsForSection(DWARFContext &C, const DWARFSection &Section,
119 DWARFSectionKind SectionKind);
120 void addUnitsForDWOSection(DWARFContext &C, const DWARFSection &DWOSection,
121 DWARFSectionKind SectionKind, bool Lazy = false);
122
122123 private:
123 void parseImpl(DWARFContext &Context, const DWARFObject &Obj,
124 const DWARFSection &Section, const DWARFDebugAbbrev *DA,
125 const DWARFSection *RS, StringRef SS, const DWARFSection &SOS,
126 const DWARFSection *AOS, const DWARFSection &LS, bool LE,
127 bool IsDWO, bool Lazy, DWARFSectionKind SectionKind);
124 void addUnitsImpl(DWARFContext &Context, const DWARFObject &Obj,
125 const DWARFSection &Section, const DWARFDebugAbbrev *DA,
126 const DWARFSection *RS, StringRef SS,
127 const DWARFSection &SOS, const DWARFSection *AOS,
128 const DWARFSection &LS, bool LE, bool IsDWO, bool Lazy,
129 DWARFSectionKind SectionKind);
128130 };
129131
130132 /// Represents base address of the CU.
9999 // sort them by their starting offsets and remove duplicates.
100100 static ContributionCollection
101101 collectContributionData(DWARFContext::cu_iterator_range CUs,
102 DWARFContext::tu_section_iterator_range TUSs) {
102 DWARFContext::tu_iterator_range TUs) {
103103 ContributionCollection Contributions;
104104 for (const auto &CU : CUs)
105105 Contributions.push_back(CU->getStringOffsetsTableContribution());
106 for (const auto &TUS : TUSs)
107 for (const auto &TU : TUS)
108 Contributions.push_back(TU->getStringOffsetsTableContribution());
109
106 for (const auto &TU : TUs)
107 Contributions.push_back(TU->getStringOffsetsTableContribution());
110108 // Sort the contributions so that any invalid ones are placed at
111109 // the start of the contributions vector. This way they are reported
112110 // first.
135133 static void dumpDWARFv5StringOffsetsSection(
136134 raw_ostream &OS, StringRef SectionName, const DWARFObject &Obj,
137135 const DWARFSection &StringOffsetsSection, StringRef StringSection,
138 DWARFContext::cu_iterator_range CUs,
139 DWARFContext::tu_section_iterator_range TUSs, bool LittleEndian) {
140 auto Contributions = collectContributionData(CUs, TUSs);
136 DWARFContext::cu_iterator_range CUs, DWARFContext::tu_iterator_range TUs,
137 bool LittleEndian) {
138 auto Contributions = collectContributionData(CUs, TUs);
141139 DWARFDataExtractor StrOffsetExt(Obj, StringOffsetsSection, LittleEndian, 0);
142140 DataExtractor StrData(StringSection, LittleEndian, 0);
143141 uint64_t SectionSize = StringOffsetsSection.Data.size();
214212 // a header containing size and version number. Alternatively, it may be a
215213 // monolithic series of string offsets, as generated by the pre-DWARF v5
216214 // implementation of split DWARF.
217 static void dumpStringOffsetsSection(
218 raw_ostream &OS, StringRef SectionName, const DWARFObject &Obj,
219 const DWARFSection &StringOffsetsSection, StringRef StringSection,
220 DWARFContext::cu_iterator_range CUs,
221 DWARFContext::tu_section_iterator_range TUSs, bool LittleEndian,
222 unsigned MaxVersion) {
215 static void dumpStringOffsetsSection(raw_ostream &OS, StringRef SectionName,
216 const DWARFObject &Obj,
217 const DWARFSection &StringOffsetsSection,
218 StringRef StringSection,
219 DWARFContext::cu_iterator_range CUs,
220 DWARFContext::tu_iterator_range TUs,
221 bool LittleEndian, unsigned MaxVersion) {
223222 // If we have at least one (compile or type) unit with DWARF v5 or greater,
224223 // we assume that the section is formatted like a DWARF v5 string offsets
225224 // section.
226225 if (MaxVersion >= 5)
227226 dumpDWARFv5StringOffsetsSection(OS, SectionName, Obj, StringOffsetsSection,
228 StringSection, CUs, TUSs, LittleEndian);
227 StringSection, CUs, TUs, LittleEndian);
229228 else {
230229 DataExtractor strOffsetExt(StringOffsetsSection.Data, LittleEndian, 0);
231230 uint32_t offset = 0;
355354 dumpDebugInfo(ExplicitDWO, ".debug_info.dwo", DObj->getInfoDWOSection(),
356355 dwo_compile_units());
357356
358 auto dumpDebugType = [&](const char *Name,
359 tu_section_iterator_range TUSections) {
357 auto dumpDebugType = [&](const char *Name, tu_iterator_range TUs) {
360358 OS << '\n' << Name << " contents:\n";
361359 DumpOffset = DumpOffsets[DIDT_ID_DebugTypes];
362 for (const auto &TUS : TUSections)
363 for (const auto &TU : TUS)
364 if (DumpOffset)
365 TU->getDIEForOffset(*DumpOffset)
366 .dump(OS, 0, DumpOpts.noImplicitRecursion());
367 else
368 TU->dump(OS, DumpOpts);
360 for (const auto &TU : TUs)
361 if (DumpOffset)
362 TU->getDIEForOffset(*DumpOffset)
363 .dump(OS, 0, DumpOpts.noImplicitRecursion());
364 else
365 TU->dump(OS, DumpOpts);
369366 };
370367 if ((DumpType & DIDT_DebugTypes)) {
371368 if (Explicit || getNumTypeUnits())
372 dumpDebugType(".debug_types", type_unit_sections());
369 dumpDebugType(".debug_types", type_units());
373370 if (ExplicitDWO || getNumDWOTypeUnits())
374 dumpDebugType(".debug_types.dwo", dwo_type_unit_sections());
371 dumpDebugType(".debug_types.dwo", dwo_type_units());
375372 }
376373
377374 if (shouldDump(Explicit, ".debug_loc", DIDT_ID_DebugLoc,
429426 DWARFDataExtractor LineData(*DObj, DObj->getLineSection(), isLittleEndian(),
430427 0);
431428 DWARFDebugLine::SectionParser Parser(LineData, *this, compile_units(),
432 type_unit_sections());
429 type_units());
433430 DumpLineSection(Parser, DumpOpts);
434431 }
435432
438435 DWARFDataExtractor LineData(*DObj, DObj->getLineDWOSection(),
439436 isLittleEndian(), 0);
440437 DWARFDebugLine::SectionParser Parser(LineData, *this, dwo_compile_units(),
441 dwo_type_unit_sections());
438 dwo_type_units());
442439 DumpLineSection(Parser, DumpOpts);
443440 }
444441
546543
547544 if (shouldDump(Explicit, ".debug_str_offsets", DIDT_ID_DebugStrOffsets,
548545 DObj->getStringOffsetSection().Data))
549 dumpStringOffsetsSection(
550 OS, "debug_str_offsets", *DObj, DObj->getStringOffsetSection(),
551 DObj->getStringSection(), compile_units(), type_unit_sections(),
552 isLittleEndian(), getMaxVersion());
546 dumpStringOffsetsSection(OS, "debug_str_offsets", *DObj,
547 DObj->getStringOffsetSection(),
548 DObj->getStringSection(), compile_units(),
549 type_units(), isLittleEndian(), getMaxVersion());
553550 if (shouldDump(ExplicitDWO, ".debug_str_offsets.dwo", DIDT_ID_DebugStrOffsets,
554551 DObj->getStringOffsetDWOSection().Data))
555552 dumpStringOffsetsSection(
556553 OS, "debug_str_offsets.dwo", *DObj, DObj->getStringOffsetDWOSection(),
557 DObj->getStringDWOSection(), dwo_compile_units(),
558 dwo_type_unit_sections(), isLittleEndian(), getMaxVersion());
554 DObj->getStringDWOSection(), dwo_compile_units(), dwo_type_units(),
555 isLittleEndian(), getMaxVersion());
559556
560557 if (shouldDump(Explicit, ".gnu_index", DIDT_ID_GdbIndex,
561558 DObj->getGdbIndexSection())) {
583580 }
584581
585582 DWARFCompileUnit *DWARFContext::getDWOCompileUnitForHash(uint64_t Hash) {
586 DWOCUs.parseDWO(*this, DObj->getInfoDWOSection(), DW_SECT_INFO, true);
583 if (DWOCUs.empty())
584 DWOCUs.addUnitsForDWOSection(*this, DObj->getInfoDWOSection(), DW_SECT_INFO,
585 true);
587586
588587 if (const auto &CUI = getCUIndex()) {
589588 if (const auto *R = CUI.getFromHash(Hash))
843842 }
844843
845844 void DWARFContext::parseCompileUnits() {
846 CUs.parse(*this, DObj->getInfoSection(), DW_SECT_INFO);
845 if (!CUs.empty())
846 return;
847 CUs.addUnitsForSection(*this, DObj->getInfoSection(), DW_SECT_INFO);
847848 }
848849
849850 void DWARFContext::parseTypeUnits() {
850851 if (!TUs.empty())
851852 return;
852853 DObj->forEachTypesSections([&](const DWARFSection &S) {
853 TUs.emplace_back();
854 TUs.back().parse(*this, S, DW_SECT_TYPES);
854 TUs.addUnitsForSection(*this, S, DW_SECT_TYPES);
855855 });
856856 }
857857
858858 void DWARFContext::parseDWOCompileUnits() {
859 DWOCUs.parseDWO(*this, DObj->getInfoDWOSection(), DW_SECT_INFO);
859 if (!DWOCUs.empty())
860 return;
861 DWOCUs.addUnitsForDWOSection(*this, DObj->getInfoDWOSection(), DW_SECT_INFO);
860862 }
861863
862864 void DWARFContext::parseDWOTypeUnits() {
863865 if (!DWOTUs.empty())
864866 return;
865867 DObj->forEachTypesDWOSections([&](const DWARFSection &S) {
866 DWOTUs.emplace_back();
867 DWOTUs.back().parseDWO(*this, S, DW_SECT_TYPES);
868 DWOTUs.addUnitsForDWOSection(*this, S, DW_SECT_TYPES);
868869 });
869870 }
870871
10461046 // line-table section.
10471047 static DWARFDebugLine::SectionParser::LineToUnitMap
10481048 buildLineToUnitMap(DWARFDebugLine::SectionParser::cu_range CUs,
1049 DWARFDebugLine::SectionParser::tu_range TUSections) {
1049 DWARFDebugLine::SectionParser::tu_range TUs) {
10501050 DWARFDebugLine::SectionParser::LineToUnitMap LineToUnit;
10511051 for (const auto &CU : CUs)
10521052 if (auto CUDIE = CU->getUnitDIE())
10531053 if (auto StmtOffset = toSectionOffset(CUDIE.find(DW_AT_stmt_list)))
10541054 LineToUnit.insert(std::make_pair(*StmtOffset, &*CU));
1055 for (const auto &TUS : TUSections)
1056 for (const auto &TU : TUS)
1057 if (auto TUDIE = TU->getUnitDIE())
1058 if (auto StmtOffset = toSectionOffset(TUDIE.find(DW_AT_stmt_list)))
1059 LineToUnit.insert(std::make_pair(*StmtOffset, &*TU));
1055 for (const auto &TU : TUs)
1056 if (auto TUDIE = TU->getUnitDIE())
1057 if (auto StmtOffset = toSectionOffset(TUDIE.find(DW_AT_stmt_list)))
1058 LineToUnit.insert(std::make_pair(*StmtOffset, &*TU));
10601059 return LineToUnit;
10611060 }
10621061
3232 using namespace llvm;
3333 using namespace dwarf;
3434
35 void DWARFUnitSection::parse(DWARFContext &C, const DWARFSection &Section,
36 DWARFSectionKind SectionKind) {
35 void DWARFUnitSection::addUnitsForSection(DWARFContext &C,
36 const DWARFSection &Section,
37 DWARFSectionKind SectionKind) {
3738 const DWARFObject &D = C.getDWARFObj();
38 parseImpl(C, D, Section, C.getDebugAbbrev(), &D.getRangeSection(),
39 D.getStringSection(), D.getStringOffsetSection(),
40 &D.getAddrSection(), D.getLineSection(), D.isLittleEndian(), false,
41 false, SectionKind);
42 }
43
44 void DWARFUnitSection::parseDWO(DWARFContext &C,
45 const DWARFSection &DWOSection,
46 DWARFSectionKind SectionKind, bool Lazy) {
39 addUnitsImpl(C, D, Section, C.getDebugAbbrev(), &D.getRangeSection(),
40 D.getStringSection(), D.getStringOffsetSection(),
41 &D.getAddrSection(), D.getLineSection(), D.isLittleEndian(),
42 false, false, SectionKind);
43 }
44
45 void DWARFUnitSection::addUnitsForDWOSection(DWARFContext &C,
46 const DWARFSection &DWOSection,
47 DWARFSectionKind SectionKind,
48 bool Lazy) {
4749 const DWARFObject &D = C.getDWARFObj();
48 parseImpl(C, D, DWOSection, C.getDebugAbbrevDWO(), &D.getRangeDWOSection(),
49 D.getStringDWOSection(), D.getStringOffsetDWOSection(),
50 &D.getAddrSection(), D.getLineDWOSection(), C.isLittleEndian(),
51 true, Lazy, SectionKind);
52 }
53
54 void DWARFUnitSection::parseImpl(DWARFContext &Context, const DWARFObject &Obj,
55 const DWARFSection &Section, const DWARFDebugAbbrev *DA,
56 const DWARFSection *RS, StringRef SS, const DWARFSection &SOS,
57 const DWARFSection *AOS, const DWARFSection &LS, bool LE,
58 bool IsDWO, bool Lazy, DWARFSectionKind SectionKind) {
59 if (Parsed)
60 return;
50 addUnitsImpl(C, D, DWOSection, C.getDebugAbbrevDWO(), &D.getRangeDWOSection(),
51 D.getStringDWOSection(), D.getStringOffsetDWOSection(),
52 &D.getAddrSection(), D.getLineDWOSection(), C.isLittleEndian(),
53 true, Lazy, SectionKind);
54 }
55
56 void DWARFUnitSection::addUnitsImpl(
57 DWARFContext &Context, const DWARFObject &Obj, const DWARFSection &Section,
58 const DWARFDebugAbbrev *DA, const DWARFSection *RS, StringRef SS,
59 const DWARFSection &SOS, const DWARFSection *AOS, const DWARFSection &LS,
60 bool LE, bool IsDWO, bool Lazy, DWARFSectionKind SectionKind) {
6161 DWARFDataExtractor Data(Obj, Section, LE, 0);
6262 // Lazy initialization of Parser, now that we have all section info.
6363 if (!Parser) {
6464 const DWARFUnitIndex *Index = nullptr;
6565 if (IsDWO)
6666 Index = &getDWARFUnitIndex(Context, SectionKind);
67 Parser = [=, &Context, &Section, &SOS,
68 &LS](uint32_t Offset) -> std::unique_ptr {
67 Parser = [=, &Context, &Obj, &Section, &SOS, &LS](
68 uint32_t Offset,
69 const DWARFSection *CurSection) -> std::unique_ptr {
70 const DWARFSection &InfoSection = CurSection ? *CurSection : Section;
71 DWARFDataExtractor Data(Obj, InfoSection, LE, 0);
6972 if (!Data.isValidOffset(Offset))
7073 return nullptr;
7174 DWARFUnitHeader Header;
7376 return nullptr;
7477 std::unique_ptr U;
7578 if (Header.isTypeUnit())
76 U = llvm::make_unique(
77 Context, Section, Header, DA, RS, SS, SOS, AOS, LS, LE, IsDWO,
78 *this);
79 U = llvm::make_unique(Context, InfoSection, Header, DA,
80 RS, SS, SOS, AOS, LS, LE, IsDWO,
81 *this);
7982 else
80 U = llvm::make_unique(
81 Context, Section, Header, DA, RS, SS, SOS, AOS, LS, LE, IsDWO,
82 *this);
83 U = llvm::make_unique(Context, InfoSection, Header,
84 DA, RS, SS, SOS, AOS, LS, LE,
85 IsDWO, *this);
8386 return U;
8487 };
8588 }
9295 ++I;
9396 continue;
9497 }
95 auto U = Parser(Offset);
98 auto U = Parser(Offset, &Section);
9699 if (!U)
97100 break;
98101 Offset = U->getNextUnitOffset();
99102 I = std::next(this->insert(I, std::move(U)));
100103 }
101 Parsed = true;
102104 }
103105
104106 DWARFUnit *DWARFUnitSection::getUnitForOffset(uint32_t Offset) const {
131133 if (!Parser)
132134 return nullptr;
133135
134 auto U = Parser(Offset);
136 auto U = Parser(Offset, nullptr);
135137 if (!U)
136138 U = nullptr;
137139
129129 std::function RecordUnrecoverable;
130130
131131 SmallVector, 2> CUs;
132 std::deque> TUs;
132 SmallVector, 2> TUs;
133133 };
134134
135135 // Fixtures must derive from "Test", but parameterised fixtures from