llvm.org GIT mirror llvm / 0bb019f
[DWARFv5] Read and dump multiple .debug_info sections. Type units go in .debug_info comdats, not .debug_types, in v5. Differential Revision: https://reviews.llvm.org/D53907 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@346360 91177308-0d34-0410-b5e6-96231b3b80d8 Paul Robinson 10 months ago
4 changed file(s) with 104 addition(s) and 65 deletion(s). Raw diff Collapse all Expand all
3232 virtual ArrayRef getSectionNames() const { return {}; }
3333 virtual bool isLittleEndian() const = 0;
3434 virtual uint8_t getAddressSize() const { llvm_unreachable("unimplemented"); }
35 virtual const DWARFSection &getInfoSection() const { return Dummy; }
35 virtual void
36 forEachInfoSections(function_ref F) const {}
3637 virtual void
3738 forEachTypesSections(function_ref F) const {}
3839 virtual StringRef getAbbrevSection() const { return ""; }
5253 virtual StringRef getGnuPubNamesSection() const { return ""; }
5354 virtual StringRef getGnuPubTypesSection() const { return ""; }
5455 virtual const DWARFSection &getStringOffsetSection() const { return Dummy; }
55 virtual const DWARFSection &getInfoDWOSection() const { return Dummy; }
56 virtual void
57 forEachInfoDWOSections(function_ref F) const {}
5658 virtual void
5759 forEachTypesDWOSections(function_ref F) const {}
5860 virtual StringRef getAbbrevDWOSection() const { return ""; }
350350 DObj->getAbbrevDWOSection()))
351351 getDebugAbbrevDWO()->dump(OS);
352352
353 auto dumpDebugInfo = [&](unit_iterator_range Units) {
354 if (DumpOffset)
355 getDIEForOffset(DumpOffset.getValue())
356 .dump(OS, 0, DumpOpts.noImplicitRecursion());
353 auto dumpDebugInfo = [&](const char *Name, unit_iterator_range Units) {
354 OS << '\n' << Name << " contents:\n";
355 if (DumpOffset = DumpOffsets[DIDT_ID_DebugInfo])
356 for (const auto &U : Units)
357 U->getDIEForOffset(DumpOffset.getValue())
358 .dump(OS, 0, DumpOpts.noImplicitRecursion());
357359 else
358360 for (const auto &U : Units)
359361 U->dump(OS, DumpOpts);
360362 };
361 if (shouldDump(Explicit, ".debug_info", DIDT_ID_DebugInfo,
362 DObj->getInfoSection().Data))
363 dumpDebugInfo(info_section_units());
364 if (shouldDump(ExplicitDWO, ".debug_info.dwo", DIDT_ID_DebugInfo,
365 DObj->getInfoDWOSection().Data))
366 dumpDebugInfo(dwo_info_section_units());
363 if ((DumpType & DIDT_DebugInfo)) {
364 if (Explicit || getNumCompileUnits())
365 dumpDebugInfo(".debug_info", info_section_units());
366 if (ExplicitDWO || getNumDWOCompileUnits())
367 dumpDebugInfo(".debug_info.dwo", dwo_info_section_units());
368 }
367369
368370 auto dumpDebugType = [&](const char *Name, unit_iterator_range Units) {
369371 OS << '\n' << Name << " contents:\n";
871873 void DWARFContext::parseNormalUnits() {
872874 if (!NormalUnits.empty())
873875 return;
874 NormalUnits.addUnitsForSection(*this, DObj->getInfoSection(), DW_SECT_INFO);
876 DObj->forEachInfoSections([&](const DWARFSection &S) {
877 NormalUnits.addUnitsForSection(*this, S, DW_SECT_INFO);
878 });
875879 NormalUnits.finishedInfoUnits();
876880 DObj->forEachTypesSections([&](const DWARFSection &S) {
877881 NormalUnits.addUnitsForSection(*this, S, DW_SECT_TYPES);
881885 void DWARFContext::parseDWOUnits(bool Lazy) {
882886 if (!DWOUnits.empty())
883887 return;
884 DWOUnits.addUnitsForDWOSection(*this, DObj->getInfoDWOSection(), DW_SECT_INFO,
885 Lazy);
888 DObj->forEachInfoDWOSections([&](const DWARFSection &S) {
889 DWOUnits.addUnitsForDWOSection(*this, S, DW_SECT_INFO, Lazy);
890 });
886891 DWOUnits.finishedInfoUnits();
887892 DObj->forEachTypesDWOSections([&](const DWARFSection &S) {
888893 DWOUnits.addUnitsForDWOSection(*this, S, DW_SECT_TYPES, Lazy);
12341239 const object::ObjectFile *Obj = nullptr;
12351240 std::vector SectionNames;
12361241
1237 using TypeSectionMap = MapVector
1242 using InfoSectionMap = MapVector
12381243 std::map>;
12391244
1240 TypeSectionMap TypesSections;
1241 TypeSectionMap TypesDWOSections;
1242
1243 DWARFSectionMap InfoSection;
1245 InfoSectionMap InfoSections;
1246 InfoSectionMap TypesSections;
1247 InfoSectionMap InfoDWOSections;
1248 InfoSectionMap TypesDWOSections;
1249
12441250 DWARFSectionMap LocSection;
12451251 DWARFSectionMap LocListsSection;
12461252 DWARFSectionMap LineSection;
12471253 DWARFSectionMap RangeSection;
12481254 DWARFSectionMap RnglistsSection;
12491255 DWARFSectionMap StringOffsetSection;
1250 DWARFSectionMap InfoDWOSection;
12511256 DWARFSectionMap LineDWOSection;
12521257 DWARFSectionMap LocDWOSection;
12531258 DWARFSectionMap StringOffsetDWOSection;
12621267
12631268 DWARFSectionMap *mapNameToDWARFSection(StringRef Name) {
12641269 return StringSwitch(Name)
1265 .Case("debug_info", &InfoSection)
12661270 .Case("debug_loc", &LocSection)
12671271 .Case("debug_loclists", &LocListsSection)
12681272 .Case("debug_line", &LineSection)
12691273 .Case("debug_str_offsets", &StringOffsetSection)
12701274 .Case("debug_ranges", &RangeSection)
12711275 .Case("debug_rnglists", &RnglistsSection)
1272 .Case("debug_info.dwo", &InfoDWOSection)
12731276 .Case("debug_loc.dwo", &LocDWOSection)
12741277 .Case("debug_line.dwo", &LineDWOSection)
12751278 .Case("debug_names", &DebugNamesSection)
13581361 for (const auto &SecIt : Sections) {
13591362 if (StringRef *SectionData = mapSectionToMember(SecIt.first()))
13601363 *SectionData = SecIt.second->getBuffer();
1364 else if (SecIt.first() == "debug_info")
1365 // Find debug_info and debug_types data by section rather than name as
1366 // there are multiple, comdat grouped, of these sections.
1367 InfoSections[SectionRef()].Data = SecIt.second->getBuffer();
1368 else if (SecIt.first() == "debug_info.dwo")
1369 InfoDWOSections[SectionRef()].Data = SecIt.second->getBuffer();
1370 else if (SecIt.first() == "debug_types")
1371 TypesSections[SectionRef()].Data = SecIt.second->getBuffer();
1372 else if (SecIt.first() == "debug_types.dwo")
1373 TypesDWOSections[SectionRef()].Data = SecIt.second->getBuffer();
13611374 }
13621375 }
13631376 DWARFObjInMemory(const object::ObjectFile &Obj, const LoadedObjectInfo *L,
14121425 // FIXME: Use the other dwo range section when we emit it.
14131426 RangeDWOSection.Data = Data;
14141427 }
1428 } else if (Name == "debug_info") {
1429 // Find debug_info and debug_types data by section rather than name as
1430 // there are multiple, comdat grouped, of these sections.
1431 InfoSections[Section].Data = Data;
1432 } else if (Name == "debug_info.dwo") {
1433 InfoDWOSections[Section].Data = Data;
14151434 } else if (Name == "debug_types") {
1416 // Find debug_types data by section rather than name as there are
1417 // multiple, comdat grouped, debug_types sections.
14181435 TypesSections[Section].Data = Data;
14191436 } else if (Name == "debug_types.dwo") {
14201437 TypesDWOSections[Section].Data = Data;
14491466 DWARFSectionMap *Sec = mapNameToDWARFSection(RelSecName);
14501467 RelocAddrMap *Map = Sec ? &Sec->Relocs : nullptr;
14511468 if (!Map) {
1452 // Find debug_types relocs by section rather than name as there are
1453 // multiple, comdat grouped, debug_types sections.
1454 if (RelSecName == "debug_types")
1469 // Find debug_info and debug_types relocs by section rather than name
1470 // as there are multiple, comdat grouped, of these sections.
1471 if (RelSecName == "debug_info")
1472 Map = &static_cast(InfoSections[*RelocatedSection])
1473 .Relocs;
1474 else if (RelSecName == "debug_info.dwo")
1475 Map = &static_cast(
1476 InfoDWOSections[*RelocatedSection])
1477 .Relocs;
1478 else if (RelSecName == "debug_types")
14551479 Map =
14561480 &static_cast(TypesSections[*RelocatedSection])
14571481 .Relocs;
15491573 StringRef getLineStringSection() const override { return LineStringSection; }
15501574
15511575 // Sections for DWARF5 split dwarf proposal.
1552 const DWARFSection &getInfoDWOSection() const override {
1553 return InfoDWOSection;
1576 void forEachInfoDWOSections(
1577 function_ref F) const override {
1578 for (auto &P : InfoDWOSections)
1579 F(P.second);
15541580 }
15551581 void forEachTypesDWOSections(
15561582 function_ref F) const override {
15971623
15981624 StringRef getFileName() const override { return FileName; }
15991625 uint8_t getAddressSize() const override { return AddressSize; }
1600 const DWARFSection &getInfoSection() const override { return InfoSection; }
1626 void forEachInfoSections(
1627 function_ref F) const override {
1628 for (auto &P : InfoSections)
1629 F(P.second);
1630 }
16011631 void forEachTypesSections(
16021632 function_ref F) const override {
16031633 for (auto &P : TypesSections)
363363
364364 bool DWARFVerifier::handleDebugInfo() {
365365 const DWARFObject &DObj = DCtx.getDWARFObj();
366 unsigned NumErrors = 0;
366367
367368 OS << "Verifying .debug_info Unit Header Chain...\n";
368 unsigned result = verifyUnitSection(DObj.getInfoSection(), DW_SECT_INFO);
369 DObj.forEachInfoSections([&](const DWARFSection &S) {
370 NumErrors += verifyUnitSection(S, DW_SECT_INFO);
371 });
369372
370373 OS << "Verifying .debug_types Unit Header Chain...\n";
371374 DObj.forEachTypesSections([&](const DWARFSection &S) {
372 result += verifyUnitSection(S, DW_SECT_TYPES);
375 NumErrors += verifyUnitSection(S, DW_SECT_TYPES);
373376 });
374 return result == 0;
377 return NumErrors == 0;
375378 }
376379
377380 unsigned DWARFVerifier::verifyDieRanges(const DWARFDie &Die,
550553 unsigned DWARFVerifier::verifyDebugInfoForm(const DWARFDie &Die,
551554 DWARFAttribute &AttrValue) {
552555 const DWARFObject &DObj = DCtx.getDWARFObj();
556 auto DieCU = Die.getDwarfUnit();
553557 unsigned NumErrors = 0;
554558 const auto Form = AttrValue.Value.getForm();
555559 switch (Form) {
562566 Optional RefVal = AttrValue.Value.getAsReference();
563567 assert(RefVal);
564568 if (RefVal) {
565 auto DieCU = Die.getDwarfUnit();
566569 auto CUSize = DieCU->getNextUnitOffset() - DieCU->getOffset();
567570 auto CUOffset = AttrValue.Value.getRawUValue();
568571 if (CUOffset >= CUSize) {
587590 Optional RefVal = AttrValue.Value.getAsReference();
588591 assert(RefVal);
589592 if (RefVal) {
590 if (*RefVal >= DObj.getInfoSection().Data.size()) {
593 if (*RefVal >= DieCU->getInfoSection().Data.size()) {
591594 ++NumErrors;
592595 error() << "DW_FORM_ref_addr offset beyond .debug_info "
593596 "bounds:\n";
151151 # CHECK-NEXT: DW_AT_producer {{.*}} "Handmade DWO producer"
152152 # CHECK-NEXT: DW_AT_name {{.*}} "V5_dwo_compile_unit"
153153
154 .section .debug_types,"",@progbits
155 # CHECK-LABEL: .debug_types contents:
156
157 # DWARF v4 Type unit header. Normal/split are identical so we do only one.
158 TU_4_start:
159 .long TU_4_end-TU_4_version # Length of Unit
160 TU_4_version:
161 .short 4 # DWARF version number
162 .long .debug_abbrev # Offset Into Abbrev. Section
163 .byte 8 # Address Size (in bytes)
164 .quad 0x0011223344556677 # Type Signature
165 .long TU_4_type-TU_4_start # Type offset
166 # The type-unit DIE, which has a name.
167 .byte 2
168 .long str_TU_4
169 # The type DIE, which has a name.
170 TU_4_type:
171 .byte 3
172 .long str_TU_4
173 .byte 0 # NULL
174 .byte 0 # NULL
175 TU_4_end:
176
177 # CHECK: 0x00000000: Type Unit: length = 0x0000001f version = 0x0004 abbr_offset = 0x0000 addr_size = 0x08 name = 'V4_type_unit' type_signature = 0x0011223344556677 type_offset = 0x001c (next unit at 0x00000023)
178 # CHECK: 0x00000017: DW_TAG_type_unit
179
180 .section .debug_types.dwo,"",@progbits
181 # FIXME: DWARF v5 wants type units in .debug_info[.dwo] not .debug_types[.dwo].
182 # CHECK: .debug_types.dwo contents:
154 # Now a DWARF v5 type unit, which goes in a .debug_info.dwo comdat.
155 # Note there will not be another ".debug_info.dwo contents:" line, even though
156 # there is a separate ELF section header; it's dumped along with the previous
157 # unit as if they were in a single section.
158
159 .section .debug_info.dwo,"G",@progbits,5555,comdat
160 # CHECK-NOT: .debug_info.dwo
183161
184162 # DWARF v5 split type unit header.
185163 TU_split_5_start:
204182
205183 # CHECK: 0x00000000: Type Unit: length = 0x00000020 version = 0x0005 unit_type = DW_UT_split_type abbr_offset = 0x0000 addr_size = 0x08 name = 'V5_split_type_unit' type_signature = 0x8899aabbccddeeff type_offset = 0x001d (next unit at 0x00000024)
206184 # CHECK: 0x00000018: DW_TAG_type_unit
185
186 .section .debug_types,"",@progbits
187 # CHECK-LABEL: .debug_types contents:
188
189 # DWARF v4 Type unit header. Normal/split are identical so we do only one.
190 TU_4_start:
191 .long TU_4_end-TU_4_version # Length of Unit
192 TU_4_version:
193 .short 4 # DWARF version number
194 .long .debug_abbrev # Offset Into Abbrev. Section
195 .byte 8 # Address Size (in bytes)
196 .quad 0x0011223344556677 # Type Signature
197 .long TU_4_type-TU_4_start # Type offset
198 # The type-unit DIE, which has a name.
199 .byte 2
200 .long str_TU_4
201 # The type DIE, which has a name.
202 TU_4_type:
203 .byte 3
204 .long str_TU_4
205 .byte 0 # NULL
206 .byte 0 # NULL
207 TU_4_end:
208
209 # CHECK: 0x00000000: Type Unit: length = 0x0000001f version = 0x0004 abbr_offset = 0x0000 addr_size = 0x08 name = 'V4_type_unit' type_signature = 0x0011223344556677 type_offset = 0x001c (next unit at 0x00000023)
210 # CHECK: 0x00000017: DW_TAG_type_unit
207211
208212 .section .debug_line,"",@progbits
209213 # CHECK-LABEL: .debug_line contents: