From 6a046c3a67c284a6e3f1634dc92e0c528bf9409c Mon Sep 17 00:00:00 2001 From: Caroline Tice Date: Mon, 25 Mar 2024 00:00:27 -0700 Subject: [PATCH 01/37] [lld][ELF] Implement merged .debug_names section. Update LLD to be able to generate a single merged .debug_names section (rather than a set of appended sections). Option is controlled by a new flag, --debug-names. Does not handle type units yet (coming soon). --- lld/ELF/Config.h | 1 + lld/ELF/DWARF.cpp | 1 + lld/ELF/DWARF.h | 4 + lld/ELF/Driver.cpp | 3 + lld/ELF/Options.td | 4 + lld/ELF/SyntheticSections.cpp | 758 ++++++++++++++++++ lld/ELF/SyntheticSections.h | 134 ++++ lld/docs/ld.lld.1 | 4 + lld/test/ELF/Inputs/debug-names-2.s | 191 +++++ .../ELF/Inputs/debug-names-parent-idx-2.s | 347 ++++++++ lld/test/ELF/debug-names-bad-aug-string.s | 189 +++++ lld/test/ELF/debug-names-bad-die-idx-sizes.s | 151 ++++ lld/test/ELF/debug-names-bad-name-count.s | 154 ++++ lld/test/ELF/debug-names-bad-offsets-sizes.s | 153 ++++ lld/test/ELF/debug-names-bad-version.s | 173 ++++ lld/test/ELF/debug-names-invalid-attribute.s | 179 +++++ lld/test/ELF/debug-names-parent-idx.s | 549 +++++++++++++ lld/test/ELF/debug-names.s | 294 +++++++ 18 files changed, 3289 insertions(+) create mode 100644 lld/test/ELF/Inputs/debug-names-2.s create mode 100644 lld/test/ELF/Inputs/debug-names-parent-idx-2.s create mode 100644 lld/test/ELF/debug-names-bad-aug-string.s create mode 100644 lld/test/ELF/debug-names-bad-die-idx-sizes.s create mode 100644 lld/test/ELF/debug-names-bad-name-count.s create mode 100644 lld/test/ELF/debug-names-bad-offsets-sizes.s create mode 100644 lld/test/ELF/debug-names-bad-version.s create mode 100644 lld/test/ELF/debug-names-invalid-attribute.s create mode 100644 lld/test/ELF/debug-names-parent-idx.s create mode 100644 lld/test/ELF/debug-names.s diff --git a/lld/ELF/Config.h b/lld/ELF/Config.h index 83f293ab2ce57..33bfa42b0fcbf 100644 --- a/lld/ELF/Config.h +++ b/lld/ELF/Config.h @@ -229,6 +229,7 @@ struct Config { bool cref; llvm::SmallVector, 0> deadRelocInNonAlloc; + bool debugNames; bool demangle = true; bool dependentLibraries; bool disableVerify; diff --git a/lld/ELF/DWARF.cpp b/lld/ELF/DWARF.cpp index ac28aa8c7ca6e..5d58e0c60a952 100644 --- a/lld/ELF/DWARF.cpp +++ b/lld/ELF/DWARF.cpp @@ -40,6 +40,7 @@ template LLDDwarfObj::LLDDwarfObj(ObjFile *obj) { .Case(".debug_gnu_pubtypes", &gnuPubtypesSection) .Case(".debug_line", &lineSection) .Case(".debug_loclists", &loclistsSection) + .Case(".debug_names", &namesSection) .Case(".debug_ranges", &rangesSection) .Case(".debug_rnglists", &rnglistsSection) .Case(".debug_str_offsets", &strOffsetsSection) diff --git a/lld/ELF/DWARF.h b/lld/ELF/DWARF.h index ada38a043bc22..64c25c706c343 100644 --- a/lld/ELF/DWARF.h +++ b/lld/ELF/DWARF.h @@ -62,6 +62,9 @@ template class LLDDwarfObj final : public llvm::DWARFObject { const LLDDWARFSection &getGnuPubtypesSection() const override { return gnuPubtypesSection; } + const LLDDWARFSection &getNamesSection() const override { + return namesSection; + } StringRef getFileName() const override { return ""; } StringRef getAbbrevSection() const override { return abbrevSection; } @@ -87,6 +90,7 @@ template class LLDDwarfObj final : public llvm::DWARFObject { LLDDWARFSection infoSection; LLDDWARFSection lineSection; LLDDWARFSection loclistsSection; + LLDDWARFSection namesSection; LLDDWARFSection rangesSection; LLDDWARFSection rnglistsSection; LLDDWARFSection strOffsetsSection; diff --git a/lld/ELF/Driver.cpp b/lld/ELF/Driver.cpp index 86cc09621a912..5fffdc51f34dd 100644 --- a/lld/ELF/Driver.cpp +++ b/lld/ELF/Driver.cpp @@ -442,6 +442,8 @@ static void checkOptions() { error("-r and -pie may not be used together"); if (config->exportDynamic) error("-r and --export-dynamic may not be used together"); + if (config->debugNames) + error("-r and --debug-names may not be used together"); } if (config->executeOnly) { @@ -1234,6 +1236,7 @@ static void readConfigs(opt::InputArgList &args) { config->cref = args.hasArg(OPT_cref); config->optimizeBBJumps = args.hasFlag(OPT_optimize_bb_jumps, OPT_no_optimize_bb_jumps, false); + config->debugNames = args.hasFlag(OPT_debug_names, OPT_no_debug_names, false); config->demangle = args.hasFlag(OPT_demangle, OPT_no_demangle, true); config->dependencyFile = args.getLastArgValue(OPT_dependency_file); config->dependentLibraries = args.hasFlag(OPT_dependent_libraries, OPT_no_dependent_libraries, true); diff --git a/lld/ELF/Options.td b/lld/ELF/Options.td index c5e95d0d25c1a..d470646ed0eee 100644 --- a/lld/ELF/Options.td +++ b/lld/ELF/Options.td @@ -153,6 +153,10 @@ def : Flag<["--"], "no-color-diagnostics">, Alias, AliasArgs< def cref: FF<"cref">, HelpText<"Output cross reference table. If -Map is specified, print to the map file">; +defm debug_names: BB<"debug-names", + "Generate a merged .debug_names section", + "Do not generate a merged .debug_names section (default)">; + defm demangle: B<"demangle", "Demangle symbol names (default)", "Do not demangle symbol names">; diff --git a/lld/ELF/SyntheticSections.cpp b/lld/ELF/SyntheticSections.cpp index 0d7f393a9f3f4..d440410faa54f 100644 --- a/lld/ELF/SyntheticSections.cpp +++ b/lld/ELF/SyntheticSections.cpp @@ -14,6 +14,7 @@ //===----------------------------------------------------------------------===// #include "SyntheticSections.h" + #include "Config.h" #include "DWARF.h" #include "EhFrame.h" @@ -34,7 +35,9 @@ #include "llvm/ADT/StringExtras.h" #include "llvm/BinaryFormat/Dwarf.h" #include "llvm/BinaryFormat/ELF.h" +#include "llvm/DebugInfo/DWARF/DWARFAcceleratorTable.h" #include "llvm/DebugInfo/DWARF/DWARFDebugPubTable.h" +#include "llvm/Support/DJB.h" #include "llvm/Support/Endian.h" #include "llvm/Support/LEB128.h" #include "llvm/Support/Parallel.h" @@ -2711,6 +2714,759 @@ static uint32_t computeGdbHash(StringRef s) { return h; } +DebugNamesSection::DebugNamesSection() + : SyntheticSection(0, SHT_PROGBITS, 1, ".debug_names") {} + +template +void DebugNamesSection::getNameRelocsImpl( + InputSection *sec, ArrayRef rels, + llvm::DenseMap &relocs) { + for (auto &rel : rels) { + Symbol &sym = sec->getFile()->getRelocTargetSym(rel); + relocs[rel.r_offset] = sym.getVA(getAddend(rel)); + } +} + +template +void DebugNamesSection::getNameRelocs( + InputSectionBase *base, llvm::DenseMap &relocs) { + auto *sec = cast(base); + const RelsOrRelas rels = sec->template relsOrRelas(); + if (rels.areRelocsRel()) + getNameRelocsImpl(sec, rels.rels, relocs); + else + getNameRelocsImpl(sec, rels.relas, relocs); +} + +void DebugNamesSection::writeTo(uint8_t *buf) { invokeELFT(writeToImpl, buf); } + +template void DebugNamesSection::writeToImpl(uint8_t *buf) { + SmallVector mergedCuOffsets; + SmallVector mergedTuOffsets; + llvm::DenseMap strOffsets; + SmallVector, 0> chunksRelocs; + chunksRelocs.reserve(numChunks); + + for (size_t i = 0; i < numChunks; ++i) { + DebugNamesOutputChunk &chunk = outputChunks[i]; + InputSectionBase *base = inputDebugNamesSections[i]; + llvm::DenseMap relocs; + getNameRelocs(base, relocs); + chunksRelocs.push_back(std::move(relocs)); + + // Update CuOffsets list with new data + for (uint32_t cuOffset : chunk.compilationUnits) + mergedCuOffsets.push_back(chunk.sec->outSecOff + cuOffset); + + // TODO: Update TuOffsets list with new data + } + + // Update the entries with the relocated string offsets. + for (auto &stringEntry : mergedEntries) { + uint32_t oldOffset = stringEntry.stringOffsetOffset; + uint32_t idx = stringEntry.chunkIdx; + stringEntry.relocatedEntryOffset = chunksRelocs[idx][oldOffset]; + } + + // Write out bytes for merged section. + + // Write the header. + endian::write32(buf + 0, mergedHdr.UnitLength); + endian::write16(buf + 4, mergedHdr.Version); + endian::write32(buf + 8, mergedHdr.CompUnitCount); + endian::write32(buf + 12, + mergedHdr.LocalTypeUnitCount); + endian::write32(buf + 16, + mergedHdr.ForeignTypeUnitCount); + endian::write32(buf + 20, mergedHdr.BucketCount); + endian::write32(buf + 24, mergedHdr.NameCount); + endian::write32(buf + 28, mergedHdr.AbbrevTableSize); + endian::write32(buf + 32, + mergedHdr.AugmentationStringSize); + buf += 36; + memcpy(buf, mergedHdr.AugmentationString.c_str(), 8); + buf += 8; + + // Write the CU list. + for (uint32_t offset : mergedCuOffsets) { + endian::write32(buf + 0, offset); + buf += 4; + } + + // Write the local TU list. + // TODO: Fix this, once we get everything working without TUs. + if (mergedHdr.LocalTypeUnitCount != 0) + warn(".debug_names: type units are not handled in merged index"); + + // Write the foreign TU list. + // Currently LLVM does not emit foreign type units, so there should + // be nothing here to emit. + // TODO: Fix this, once we get everything working wtihout TUs. + if (mergedHdr.ForeignTypeUnitCount != 0) + warn(".debug_names: type units are not handled in merged index"); + + // Write the hash table. + // ... Write the buckets + uint32_t idx = 1; + for (const auto &bucket : bucketList) { + if (!bucket.empty()) + endian::write32(buf + 0, idx); + idx += bucket.size(); + buf += 4; + } + + // ...Write the hashes + for (const auto &bucket : bucketList) { + for (const auto &entry : bucket) { + uint32_t hashValue = entry->hashValue; + endian::write32(buf + 0, hashValue); + buf += 4; + } + } + + // Write the string offsets. + for (const auto &entry : mergedEntries) { + endian::write32(buf + 0, + entry.relocatedEntryOffset); + buf += 4; + } + + // Write the entry offsets. + for (const auto &entry : mergedEntries) { + endian::write32(buf + 0, entry.entryOffset); + buf += 4; + } + + // Write the abbrev table. + for (const auto *abbrev : mergedAbbrevTable) { + size_t uleb_size = encodeULEB128(abbrev->code, buf); + buf += uleb_size; + uleb_size = encodeULEB128(abbrev->tag, buf); + buf += uleb_size; + for (auto attr : abbrev->attributes) { + uleb_size = encodeULEB128(attr.Index, buf); + buf += uleb_size; + uleb_size = encodeULEB128(attr.Form, buf); + buf += uleb_size; + } + endian::write16(buf + 0, 0); // attribute sentinels. + buf += 2; + } + *buf++ = 0; // abbrev table sentinel + + // Write the entry pool. + for (const auto &stringEntry : mergedEntries) { + // Write all the entries for the string. + size_t uleb_size; + for (const auto &entry : stringEntry.indexEntries) { + uleb_size = encodeULEB128(entry->abbrevCode, buf); + buf += uleb_size; + for (const auto &value : entry->attrValues) { + if (value.attrSize > 0) { + endian::write32(buf + 0, value.attrValue); + buf += value.attrSize; + } + } + } + *buf++ = 0; // Entry sentinel + } +} + +bool DebugNamesSection::isNeeded() const { return numChunks > 0; } + +template +static void +readCompileUnitOffsets(struct DebugNamesSection::DebugNamesSectionData &secData, + DebugNamesSection::DebugNamesInputChunk &inputChunk, + DebugNamesSection::DebugNamesOutputChunk &outputChunk, + llvm::DWARFDataExtractor &namesExtractor) { + uint64_t offset = secData.locs.CUsBase; + uint64_t *offsetPtr = &offset; + for (size_t i = 0; i < secData.hdr.CompUnitCount; ++i) { + llvm::Error err = llvm::Error::success(); + uint32_t value = namesExtractor.getU32(offsetPtr, &err); + if (err) + errorOrWarn(toString(inputChunk.namesSection->sec) + + ": error reading CU offsets: " + toString(std::move(err))); + else + outputChunk.compilationUnits.push_back(value); + } +} + +template +static void +readEntryOffsets(struct DebugNamesSection::DebugNamesSectionData &secData, + DebugNamesSection::DebugNamesInputChunk &chunk, + llvm::DWARFDataExtractor &namesExtractor) { + secData.entryOffsets = std::make_unique(secData.hdr.NameCount); + if (secData.locs.EntryOffsetsBase >= namesExtractor.getData().size()) + errorOrWarn(toString(chunk.namesSection->sec) + + ": invalid entry offsets input"); + + uint64_t offset = secData.locs.EntryOffsetsBase; + uint64_t *offsetPtr = &offset; + for (size_t i = 0; i < secData.hdr.NameCount; ++i) { + llvm::Error err = llvm::Error::success(); + uint32_t value = namesExtractor.getU32(offsetPtr, &err); + if (err) + errorOrWarn(toString(chunk.namesSection->sec) + + ": error reading entry offsets: " + toString(std::move(err))); + else + secData.entryOffsets.get()[i] = value; + } +} + +template +static void readAttributeValues( + SmallVector &values, + DebugNamesSection::DebugNamesInputChunk &chunk, uint64_t &offset, + struct DebugNamesSection::DebugNamesSectionData &secData, + int32_t &parentOffset, llvm::DWARFDataExtractor &namesExtractor, + const llvm::DWARFDebugNames::Abbrev &abbrev) { + const LLDDWARFSection &namesSection = *chunk.namesSection; + uint64_t *offsetPtr = &offset; + DebugNamesSection::AttrValueData cuOrTuAttr = {0, 0}; + for (auto attr : abbrev.Attributes) { + llvm::Error err = llvm::Error::success(); + DebugNamesSection::AttrValueData newAttr; + uint32_t value; + switch (attr.Form) { + case DW_FORM_flag_present: { + // Currently only DW_IDX_parent attributes (in .debug_names) can + // have this form. This form does not have a real value (nothing is + // emitted for it). + break; + } + case DW_FORM_data1: + case DW_FORM_ref1: { + newAttr.attrValue = namesExtractor.getU8(offsetPtr, &err); + newAttr.attrSize = 1; + break; + } + case DW_FORM_data2: + case DW_FORM_ref2: { + value = namesExtractor.getU16(offsetPtr, &err); + newAttr.attrValue = value; + newAttr.attrSize = 2; + break; + } + case DW_FORM_data4: + case DW_FORM_ref4: { + value = namesExtractor.getU32(offsetPtr, &err); + newAttr.attrValue = value; + newAttr.attrSize = 4; + if (attr.Index == dwarf::DW_IDX_parent) + parentOffset = value + secData.locs.EntriesBase; + break; + } + case DW_FORM_data8: + case DW_FORM_ref8: + case DW_FORM_ref_sig8: { + value = namesExtractor.getU64(offsetPtr, &err); + newAttr.attrValue = value; + newAttr.attrSize = 8; + break; + } + default: { + errorOrWarn(toString(namesSection.sec) + + Twine(": unrecognized form encoding ") + Twine(attr.Form) + + " in .debug_names abbrev table"); + break; + } + } + if (err) + errorOrWarn( + toString(namesSection.sec) + + ": error while reading attributes: " + toString(std::move(err))); + if (attr.Index == DW_IDX_compile_unit || attr.Index == DW_IDX_type_unit) + // Save it to put it at the end of the attributes list. + cuOrTuAttr = newAttr; + else if (attr.Form != DW_FORM_flag_present) + values.push_back(newAttr); + } + + // Make sure the CU or TU index attribute is the last one in the list. + values.push_back(cuOrTuAttr); +} + +template +static void readEntry(DebugNamesSection::NamedEntry &stringEntry, + DebugNamesSection::DebugNamesInputChunk &chunk, + DebugNamesSection::DebugNamesSectionData &secData, + llvm::DWARFDataExtractor &namesExtractor, + const llvm::DWARFDebugNames::NameIndex &ni) { + std::unique_ptr &namesSection = chunk.namesSection; + uint64_t offset = stringEntry.entryOffset; + // Each entry ends with a zero 'sentinel' value + while (offset < namesSection->Data.size() && + namesSection->Data[offset] != 0) { + // Read & store all entries (for the same string) + auto entry = std::make_unique(); + entry->poolOffset = offset; + llvm::Error err = llvm::Error::success(); + uint64_t ulebValue = namesExtractor.getULEB128(&offset, &err); + if (err) + errorOrWarn(toString(chunk.namesSection->sec) + + ": error reading entry: " + toString(std::move(err))); + entry->abbrevCode = static_cast(ulebValue); + const auto &abbrevs = ni.getAbbrevs(); + auto abbrevIt = abbrevs.find_as(entry->abbrevCode); + if (abbrevIt != abbrevs.end()) { + const llvm::DWARFDebugNames::Abbrev &abbrev = *abbrevIt; + readAttributeValues(entry->attrValues, chunk, offset, secData, + entry->parentOffset, namesExtractor, abbrev); + stringEntry.indexEntries.push_back(std::move(entry)); + } + } + if (offset >= namesSection->Data.size()) + errorOrWarn(toString(chunk.namesSection->sec) + + ": encountered unexpected end of section while reading entry"); +} + +template +static void +readEntries(struct DebugNamesSection::DebugNamesSectionData &secData, + DebugNamesSection::DebugNamesInputChunk &chunk, + llvm::DWARFDataExtractor &namesExtractor, + llvm::DataExtractor &strExtractor, + const llvm::DWARFDebugNames::NameIndex &ni) { + // Temporary map from entry offsets to address (pointer) of entry with that + // offset; used to find parent entries quickly. + DenseMap offsetMap; + // Reserve sizes for this chunk's hashes & namedEntries. + chunk.hashValues.reserve(secData.hdr.NameCount); + secData.namedEntries.reserve(secData.hdr.NameCount); + // Calculate the Entry Offsets, create initial records. + for (uint32_t i = 0; i < secData.hdr.NameCount; ++i) { + // Get string value + DebugNamesSection::NamedEntry stringEntry; + stringEntry.entryOffset = + secData.locs.EntriesBase + secData.entryOffsets[i]; + uint64_t strOffsetOffset = + secData.locs.StringOffsetsBase + i * secData.dwarfSize; + stringEntry.stringOffsetOffset = strOffsetOffset; + uint64_t strOffset = + namesExtractor.getRelocatedValue(secData.dwarfSize, &strOffsetOffset); + StringRef name = strExtractor.getCStrRef(&strOffset); + stringEntry.name = name.data(); + // Calculate hash + stringEntry.hashValue = caseFoldingDjbHash(name); + chunk.hashValues.push_back(stringEntry.hashValue); + // Read String Entry + readEntry(stringEntry, chunk, secData, namesExtractor, ni); + // Add index entries & offsets to our temporary map + for (const auto &entry : stringEntry.indexEntries) + offsetMap[entry->poolOffset] = entry.get(); + secData.namedEntries.push_back(std::move(stringEntry)); + } + // Find/assign pointers to any 'real' parent entries (needed to find correct + // parent entry offsets in merged data). + for (auto &stringEntry : secData.namedEntries) + for (auto &entry : stringEntry.indexEntries) + if (entry->parentOffset != -1) + entry->parentEntry = offsetMap[entry->parentOffset]; +} + +static uint16_t computeDebugNamesHeaderSize() { + // Size of the .debug_names section header, in bytes, for DWARF32: + uint16_t size = /* unit length */ 4 + + /* version */ 2 + + /* padding */ 2 + + /* CU count */ 4 + + /* TU count */ 4 + + /* Foreign TU count */ 4 + + /* Bucket Count */ 4 + + /* Name Count */ 4 + + /* Abbrev table size */ 4 + + /* Augmentation string size */ 4 + + /* augmentation string */ 8; + return size; +} + +template +static void collectDebugNamesSectionData( + DebugNamesSection::DebugNamesInputChunk &chunk, + DebugNamesSection::DebugNamesOutputChunk &outputChunk, + llvm::DWARFDataExtractor &namesExtractor, + llvm::DataExtractor &strExtractor) { + for (const auto &ni : *chunk.debugNamesData) { + DebugNamesSection::DebugNamesSectionData secData; + secData.hdr = ni.getHeader(); + if (secData.hdr.Format != DwarfFormat::DWARF32) + errorOrWarn(toString(chunk.namesSection->sec) + ": unsupported DWARF64"); + secData.dwarfSize = dwarf::getDwarfOffsetByteSize(DwarfFormat::DWARF32); + secData.hdrSize = computeDebugNamesHeaderSize(); + if (secData.hdr.Version != 5) + errorOrWarn(toString(chunk.namesSection->sec) + ": unsupported version"); + secData.locs = findDebugNamesOffsets(secData.hdrSize, secData.hdr); + readCompileUnitOffsets(secData, chunk, outputChunk, namesExtractor); + readEntryOffsets(secData, chunk, namesExtractor); + readEntries(secData, chunk, namesExtractor, strExtractor, ni); + chunk.sectionsData.push_back(std::move(secData)); + } +} + +void DebugNamesSection::collectMergedCounts( + MutableArrayRef &inputChunks) { + SmallVector tmpMergedCuOffsets; + + mergedHdr.CompUnitCount = 0; + mergedHdr.LocalTypeUnitCount = 0; + mergedHdr.ForeignTypeUnitCount = 0; + mergedHdr.Version = 5; + mergedHdr.Format = DwarfFormat::DWARF32; + mergedHdr.AugmentationStringSize = 0; + + for (size_t i = 0; i < numChunks; ++i) { + DebugNamesInputChunk &inputChunk = inputChunks[i]; + DebugNamesOutputChunk &outputChunk = outputChunks[i]; + inputChunk.baseCuOffsetIdx = tmpMergedCuOffsets.size(); + for (uint32_t cuOffset : outputChunk.compilationUnits) + tmpMergedCuOffsets.push_back(outputChunk.sec->outSecOff + cuOffset); + for (const DebugNamesSectionData &data : inputChunk.sectionsData) { + mergedHdr.CompUnitCount += data.hdr.CompUnitCount; + mergedHdr.LocalTypeUnitCount += data.hdr.LocalTypeUnitCount; + mergedHdr.ForeignTypeUnitCount += data.hdr.ForeignTypeUnitCount; + // Set & check the Augmentation String. + if (mergedHdr.AugmentationStringSize == 0) { + mergedHdr.AugmentationStringSize = data.hdr.AugmentationStringSize; + mergedHdr.AugmentationString = data.hdr.AugmentationString; + } else if ((mergedHdr.AugmentationStringSize != + data.hdr.AugmentationStringSize) || + (mergedHdr.AugmentationString != + data.hdr.AugmentationString)) { + // There are conflicting augmentation strings, so it's best for the + // merged index to not use an augmentation string. + StringRef emptyString = " "; + mergedHdr.AugmentationStringSize = 8; + mergedHdr.AugmentationString = emptyString; + } + } + } +} + +void DebugNamesSection::Abbrev::Profile(llvm::FoldingSetNodeID &id) const { + id.AddInteger(tag); + for (const DWARFDebugNames::AttributeEncoding &attr : attributes) { + id.AddInteger(attr.Index); + id.AddInteger(attr.Form); + } +} + +std::pair DebugNamesSection::getMergedCuSizeData() { + // Once we've merged all the CU offsets into a single list, the original + // DWARF form/size (often 1 byte) may be too small to hold indices to all + // the offsets. Here we calculate what the right form/size needs to be for + // the merged index. + uint8_t size; + dwarf::Form form; + // TODO: Investigate possibly using llvm::DIEInteger::BestForm here + if (mergedHdr.CompUnitCount > 0xffffffff) { + form = DW_FORM_data8; + size = 8; + } else if (mergedHdr.CompUnitCount > 0xffff) { + form = DW_FORM_data4; + size = 4; + } else if (mergedHdr.CompUnitCount > 0xff) { + form = DW_FORM_data2; + size = 2; + } else { + form = DW_FORM_data1; + size = 1; + } + + return {size, form}; +} + +void DebugNamesSection::getMergedAbbrevTable( + MutableArrayRef &inputChunks) { + MapVector abbrevMap; + FoldingSet AbbreviationsSet; + + // Need to determine what size form is needed for the DW_IDX_compile_unit + // attributes in the merged index. Will need to update the abbrevs to use + // the right form. + dwarf::Form compileUnitAttrForm = getMergedCuSizeData().second; + + for (DebugNamesInputChunk &chunk : inputChunks) { + for (const auto &ni : *chunk.debugNamesData) { + const auto &abbrevs = ni.getAbbrevs(); + for (const DWARFDebugNames::Abbrev &abbrev : abbrevs) { + // Create canonicalized abbrev. + DebugNamesSection::Abbrev newAbbrev; + DWARFDebugNames::AttributeEncoding cuOrTuAttr(DW_IDX_compile_unit, + compileUnitAttrForm); + newAbbrev.code = abbrev.Code; + newAbbrev.tag = abbrev.Tag; + for (const auto attr : abbrev.Attributes) { + DWARFDebugNames::AttributeEncoding newAttr(attr.Index, attr.Form); + if (attr.Index == DW_IDX_compile_unit || + attr.Index == DW_IDX_type_unit) + // Save it, to put it at the end. + cuOrTuAttr.Index = newAttr.Index; + else + newAbbrev.attributes.push_back(newAttr); + } + // Put the CU/TU index at the end of the attributes list. + newAbbrev.attributes.push_back(cuOrTuAttr); + + // Next, check our abbreviations set to see if we've already seen the + // identical abbreviation. + uint32_t oldCode = newAbbrev.code; + uint32_t newCode; + FoldingSetNodeID id; + newAbbrev.Profile(id); + void *insertPos; + if (Abbrev *Existing = + AbbreviationsSet.FindNodeOrInsertPos(id, insertPos)) { + // Found it; we've already seen an identical abbreviation. + newCode = Existing->code; + } else { + // Didn't find it. + Abbrev *newAbbrev2 = new (Alloc) Abbrev(std::move(newAbbrev)); + AbbreviationsSet.InsertNode(newAbbrev2, insertPos); + newCode = mergedAbbrevTable.size() + 1; + newAbbrev2->code = newCode; + mergedAbbrevTable.push_back(newAbbrev2); + } + chunk.abbrevCodeMap[oldCode] = newCode; + } + } + } + + // Calculate the merged abbrev table size. + mergedHdr.AbbrevTableSize = 0; + for (Abbrev *a : mergedAbbrevTable) { + mergedHdr.AbbrevTableSize += getULEB128Size(a->code); + mergedHdr.AbbrevTableSize += getULEB128Size(a->tag); + for (const auto &attr : a->attributes) { + mergedHdr.AbbrevTableSize += getULEB128Size(attr.Index); + mergedHdr.AbbrevTableSize += getULEB128Size(attr.Form); + } + mergedHdr.AbbrevTableSize += 2; // attribute index & form sentinels + } + ++mergedHdr.AbbrevTableSize; // abbrev table sentinel +} + +void DebugNamesSection::getMergedSymbols( + MutableArrayRef &inputChunks) { + // The number of symbols (& abbrevs) we will handle is very large; will use + // multi-threading to speed it up. + constexpr size_t numShards = 32; + const size_t concurrency = + llvm::bit_floor(std::min(config->threadCount, numShards)); + const size_t shift = 32 - llvm::countr_zero(numShards); + + struct ShardData { + // Map to uniquify symbols by name + MapVector nameMap; + }; + + // Need to determine what size is needed for the DW_IDX_compile_unit + // attributes in the merged index. Will need to update the indexEntries + // to use the right size. + uint8_t compileUnitAttrSize = getMergedCuSizeData().first; + + auto shardsPtr = std::make_unique(numShards); + MutableArrayRef shards(shardsPtr.get(), numShards); + + parallelFor(0, concurrency, [&](size_t threadId) { + for (size_t i = 0; i < numChunks; ++i) { + DebugNamesInputChunk &chunk = inputChunks[i]; + for (auto &secData : chunk.sectionsData) { + // Deduplicate the NamedEntry records (based on the string/name), + // using a map from string/name to NamedEntry records. + // Note there is a twist: If there is already a record for the current + // 'string' in the nameMap, we append all the indexEntries from the + // current record to the record that's in the nameMap. I.e. we + // deduplicate the *strings* but we keep all the IndexEntry records + // (moving them to the appropriate 'kept' NamedEntry record). + for (auto &stringEntry : secData.namedEntries) { + size_t shardId = stringEntry.hashValue >> shift; + if ((shardId & (concurrency - 1)) != threadId) + continue; + + auto &shard = shards[shardId]; + stringEntry.chunkIdx = i; + for (auto &entry : stringEntry.indexEntries) { + // The DW_IDX_compile_unit is always the last attribute (we set it + // up that way when we read/created the attributes). We need to + // update the index value to use the correct merged offset, and we + // need to fix the size of the index attribute. + uint8_t endPos = entry->attrValues.size() - 1; + entry->attrValues[endPos].attrValue += chunk.baseCuOffsetIdx; + entry->attrValues[endPos].attrSize = compileUnitAttrSize; + // Update the entry's abbrev code to match the merged + // abbreviations. + entry->abbrevCode = chunk.abbrevCodeMap[entry->abbrevCode]; + } + + CachedHashStringRef cachedHashName(stringEntry.name); + auto [it, inserted] = + shard.nameMap.try_emplace(cachedHashName, std::move(stringEntry)); + if (!inserted) { + // Found the string already; don't add to map, but append + // entry/entries for it to existing map entry. + NamedEntry &found = it->second; + // Append the entries... + for (auto &entry : stringEntry.indexEntries) + found.indexEntries.push_back(std::move(entry)); + } + } + } + } + }); + + // Combined the shared symbols into mergedEntries + for (auto &shard : shards) + for (auto &mapEntry : shard.nameMap) + mergedEntries.push_back(std::move(mapEntry.second)); + mergedHdr.NameCount = mergedEntries.size(); +} + +void DebugNamesSection::computeUniqueHashes( + MutableArrayRef &chunks) { + SmallVector uniques; + for (const auto &chunk : chunks) + uniques.append(chunk.hashValues); + llvm::sort(uniques); + mergedHdr.BucketCount = dwarf::getDebugNamesBucketCount(llvm::unique(uniques) - uniques.begin()); +} + +void DebugNamesSection::generateBuckets() { + bucketList.resize(mergedHdr.BucketCount); + for (auto &entry : mergedEntries) { + uint32_t bucketIdx = entry.hashValue % mergedHdr.BucketCount; + bucketList[bucketIdx].push_back(&entry); + } + + // Sort the contents of the buckets by hash value so that the hash collisions + // end up together. + for (auto &bucket : bucketList) + llvm::stable_sort(bucket, [](NamedEntry *lhs, NamedEntry *rhs) { + return lhs->hashValue < rhs->hashValue; + }); +} + +void DebugNamesSection::calculateEntriesSizeAndOffsets() { + uint32_t offset = 0; + for (DebugNamesSection::NamedEntry &stringEntry : mergedEntries) { + stringEntry.entryOffset = offset; + for (auto &entry : stringEntry.indexEntries) { + uint32_t entrySize = 0; + entry->poolOffset = offset; + uint32_t ulebSize = getULEB128Size(entry->abbrevCode); + entrySize += ulebSize; + for (const auto &attr : entry->attrValues) + entrySize += attr.attrSize; + offset += entrySize; + } + // Add in sentinel size + ++offset; + } + mergedTotalEntriesSize = offset; +} + +void DebugNamesSection::updateParentIndexEntries() { + for (DebugNamesSection::NamedEntry &stringEntry : mergedEntries) { + for (auto &childEntry : stringEntry.indexEntries) { + if (!childEntry->parentEntry) + continue; + + // Abbrevs are indexed starting at 1; vector starts at 0. (abbrevCode + // corresponds to position in the merged table vector). + const Abbrev *abbrev = mergedAbbrevTable[childEntry->abbrevCode - 1]; + + // Found the abbrev. Find the index for the DW_IDX_parent attribute + // (in the abbrev) and update that value in the entry with the + // correct parent offset (in the merged entry pool). + for (size_t idx = 0, size = abbrev->attributes.size(); idx < size; + ++idx) { + auto attr = abbrev->attributes[idx]; + if (attr.Index == DW_IDX_parent && attr.Form == DW_FORM_ref4) + childEntry->attrValues[idx].attrValue = + childEntry->parentEntry->poolOffset; + } + } + } +} + +uint64_t DebugNamesSection::calculateMergedSectionSize() { + uint32_t hdrSize = computeDebugNamesHeaderSize(); + mergedOffsets = findDebugNamesOffsets(hdrSize, mergedHdr); + // Add in the size for all the Entries, and make it 4-byte aligned. + mergedHdr.UnitLength = + alignTo(mergedOffsets.EntriesBase + mergedTotalEntriesSize, 4); + // Add in the first 4 bytes, whichs print out the length of the section. + return mergedHdr.UnitLength + 4; +} + +template DebugNamesSection *DebugNamesSection::create() { + llvm::TimeTraceScope timeScope("Create merged .debug_names"); + SetVector files; + SmallVector sections; + for (InputSectionBase *s : ctx.inputSections) { + InputSection *isec = dyn_cast(s); + if (!isec) + continue; + // Mark original sections as dead, but save links to them for calculating + // relocations later. + if (s->name == ".debug_names") { + s->markDead(); + sections.push_back(s); + files.insert(isec->file); + } + } + auto inputChunksPtr = std::make_unique(files.size()); + MutableArrayRef inputChunks(inputChunksPtr.get(), + files.size()); + auto outputChunks = std::make_unique(files.size()); + parallelFor(0, files.size(), [&](size_t i) { + ObjFile *file = cast>(files[i]); + auto dwarfCtx = std::make_unique( + std::make_unique>(file)); + auto &dobj = + static_cast &>(dwarfCtx->getDWARFObj()); + + // Extract llvm::DWARFDebugNames data from the .debug_names section. The + // .debug_names section needs the .debug_str section, to get the actual + // symbol names. + const StringRef &strSection = dobj.getStrSection(); + const LLDDWARFSection &namesSection = dobj.getNamesSection(); + llvm::DWARFDataExtractor namesExtractor(dobj, namesSection, config->isLE, + config->wordsize); + llvm::DataExtractor strExtractor(strSection, config->isLE, + config->wordsize); + inputChunks[i].debugNamesData = + std::make_unique(namesExtractor, strExtractor); + inputChunks[i].namesSection = + std::make_unique(namesSection); + if (llvm::Error E = inputChunks[i].debugNamesData->extract()) { + // Report an error here. We were unable to extract the data. + errorOrWarn(toString(dobj.getNamesSection().sec) + ": " + + toString(std::move(E))); + } + outputChunks[i].sec = dobj.getInfoSection(); + collectDebugNamesSectionData(inputChunks[i], outputChunks[i], + namesExtractor, strExtractor); + }); + + auto *ret = make(); + ret->addSections(sections); + ret->outputChunks = std::move(outputChunks); + ret->numChunks = files.size(); + ret->collectMergedCounts(inputChunks); + ret->getMergedAbbrevTable(inputChunks); + ret->getMergedSymbols(inputChunks); + ret->computeUniqueHashes(inputChunks); + inputChunksPtr.reset(); + ret->generateBuckets(); + ret->calculateEntriesSizeAndOffsets(); + ret->updateParentIndexEntries(); + ret->sectionSize = ret->calculateMergedSectionSize(); + return ret; +} + GdbIndexSection::GdbIndexSection() : SyntheticSection(0, SHT_PROGBITS, 1, ".gdb_index") {} @@ -4272,6 +5028,8 @@ template void elf::createSyntheticSections() { if (config->andFeatures || !ctx.aarch64PauthAbiCoreInfo.empty()) add(*make()); + if (config->debugNames) + add(*DebugNamesSection::create()); if (config->gdbIndex) { in.gdbIndex = GdbIndexSection::create(); add(*in.gdbIndex); diff --git a/lld/ELF/SyntheticSections.h b/lld/ELF/SyntheticSections.h index 759b78668f546..e0b01831edaa7 100644 --- a/lld/ELF/SyntheticSections.h +++ b/lld/ELF/SyntheticSections.h @@ -21,13 +21,17 @@ #define LLD_ELF_SYNTHETIC_SECTIONS_H #include "Config.h" +#include "DWARF.h" #include "InputSection.h" #include "Symbols.h" #include "llvm/ADT/DenseSet.h" +#include "llvm/ADT/FoldingSet.h" #include "llvm/ADT/MapVector.h" #include "llvm/ADT/STLFunctionalExtras.h" #include "llvm/BinaryFormat/ELF.h" +#include "llvm/DebugInfo/DWARF/DWARFAcceleratorTable.h" #include "llvm/MC/StringTableBuilder.h" +#include "llvm/Support/Allocator.h" #include "llvm/Support/Compiler.h" #include "llvm/Support/Endian.h" #include "llvm/Support/Parallel.h" @@ -789,6 +793,136 @@ class RelroPaddingSection final : public SyntheticSection { void writeTo(uint8_t *buf) override {} }; +class DebugNamesSection final : public SyntheticSection { + // N.B. Everything in this class assumes that we are using DWARF32. + // If we move to DWARF64, most of this data will need to be re-sized, + // and the code that handles or manipulates it will need to be updated + // accordingly. + +public: + DebugNamesSection(); + template static DebugNamesSection *create(); + void writeTo(uint8_t *buf) override; + size_t getSize() const override { return sectionSize; } + bool isNeeded() const override; + + void addSections(SmallVector sec_list) { + inputDebugNamesSections = sec_list; + } + + template void writeToImpl(uint8_t *buf); + + template + void getNameRelocsImpl(InputSection *sec, ArrayRef rels, + llvm::DenseMap &relocs); + + template + void getNameRelocs(InputSectionBase *base, + llvm::DenseMap &relocs); + + template + void endianWrite(uint8_t size, uint8_t *buf_start, uint32_t offset, + uint32_t data); + + struct Abbrev : public llvm::FoldingSetNode { + uint32_t code; + uint32_t tag; + SmallVector attributes; + + void Profile(llvm::FoldingSetNodeID &id) const; + }; + + struct AttrValueData { + uint32_t attrValue; + uint8_t attrSize; + }; + + struct IndexEntry { + uint32_t abbrevCode; + uint32_t poolOffset; + union { + int32_t parentOffset = -1; + IndexEntry *parentEntry; + }; + SmallVector attrValues; + }; + + struct NamedEntry { + const char *name; + uint32_t hashValue; + uint32_t stringOffsetOffset; + uint32_t entryOffset; + uint32_t relocatedEntryOffset; + // The index of the chunk that 'name' points into, for looking up + // relocation data for this string. + uint32_t chunkIdx; + SmallVector, 0> indexEntries; + }; + + struct SectionOffsetLocs { + uint64_t stringOffsetsBase; + uint64_t entryOffsetsBase; + uint64_t entriesBase; + }; + + struct DebugNamesSectionData { + llvm::DWARFDebugNames::Header hdr; + llvm::DWARFDebugNames::DWARFDebugNamesOffsets locs; + SmallVector tuOffsets; + SmallVector abbrevTable; + std::unique_ptr entryOffsets; + SmallVector namedEntries; + uint16_t dwarfSize; + uint16_t hdrSize; + }; + + // Per-file data used, while reading in the data, to generate the merged + // section information. + struct DebugNamesInputChunk { + uint32_t baseCuOffsetIdx; + std::unique_ptr debugNamesData; + std::unique_ptr namesSection; + SmallVector sectionsData; + SmallVector hashValues; + llvm::DenseMap abbrevCodeMap; + }; + + // Per-file data needed for correctly writing out the .debug_names section. + struct DebugNamesOutputChunk { + // Pointer to .debug_info section for this chunk/file, used for + // calculating correct relocated CU offsets in the merged index. + InputSection *sec; + SmallVector compilationUnits; + SmallVector typeUnits; + }; + + void collectMergedCounts(MutableArrayRef &inputChunks); + std::pair getMergedCuSizeData(); + void getMergedAbbrevTable(MutableArrayRef &inputChunks); + void getMergedSymbols(MutableArrayRef &inputChunks); + void computeUniqueHashes(MutableArrayRef &inputChunks); + void generateBuckets(); + void calculateEntriesSizeAndOffsets(); + void updateParentIndexEntries(); + uint64_t calculateMergedSectionSize(); + + llvm::BumpPtrAllocator Alloc; + +private: + size_t sectionSize; + uint32_t mergedTotalEntriesSize; + uint32_t numChunks; + llvm::DWARFDebugNames::DWARFDebugNamesOffsets mergedOffsets; + std::unique_ptr outputChunks; + // Pointers to the original .debug_names sections; used for find the correct' + // string relocation values when writing out the merged index. + SmallVector inputDebugNamesSections; + llvm::DWARFDebugNames::Header mergedHdr; + SmallVector mergedAbbrevTable; + SmallVector mergedEntries; + SmallVector, 0> bucketList; +}; + class GdbIndexSection final : public SyntheticSection { public: struct AddressEntry { diff --git a/lld/docs/ld.lld.1 b/lld/docs/ld.lld.1 index e0316730f442e..ba8ce8f784759 100644 --- a/lld/docs/ld.lld.1 +++ b/lld/docs/ld.lld.1 @@ -172,6 +172,10 @@ This is like a generalized Output cross reference table. If .Fl Map is specified, print to the map file. +.It Fl -debug-names +Generate a merged +.Li .debug_names +section. .It Fl -defsym Ns = Ns Ar symbol Ns = Ns Ar expression Define a symbol alias. .Ar expression diff --git a/lld/test/ELF/Inputs/debug-names-2.s b/lld/test/ELF/Inputs/debug-names-2.s new file mode 100644 index 0000000000000..586788653dcc7 --- /dev/null +++ b/lld/test/ELF/Inputs/debug-names-2.s @@ -0,0 +1,191 @@ +#-- input file: debug-names-2.cpp +## Generated with: +## +## - clang++ -g -O0 -gpubnames -fdebug-compilation-dir='debug-names-test' \ +## -S debug-names-2.cpp -o debug-names-2.s +## +## debug-names-2.cpp contents: +## +## struct t1 { }; +## int main() { +## t1 v1; +## } +## + .text + .globl main # -- Begin function main + .p2align 4, 0x90 + .type main,@function +main: # @main +.Lfunc_begin0: + .cfi_startproc +# %bb.0: # %entry + pushq %rbp + .cfi_def_cfa_offset 16 + .cfi_offset %rbp, -16 + movq %rsp, %rbp + .cfi_def_cfa_register %rbp +.Ltmp0: + xorl %eax, %eax + popq %rbp + .cfi_def_cfa %rsp, 8 + retq +.Ltmp1: +.Lfunc_end0: + .size main, .Lfunc_end0-main + .cfi_endproc + # -- End function + .section .debug_abbrev,"",@progbits + .byte 0 # EOM(1) + .byte 0 # EOM(2) + .byte 0 # EOM(3) + .section .debug_info,"",@progbits +.Lcu_begin0: + .long .Ldebug_info_end0-.Ldebug_info_start0 # Length of Unit +.Ldebug_info_start0: + .short 5 # DWARF version number + .byte 1 # DWARF Unit Type + .byte 8 # Address Size (in bytes) + .long .debug_abbrev # Offset Into Abbrev. Section + .byte 1 # Abbrev [1] 0xc:0x3d DW_TAG_compile_unit + .byte 0 # DW_AT_producer + .short 33 # DW_AT_language + .byte 1 # DW_AT_name + .long .Lstr_offsets_base0 # DW_AT_str_offsets_base + .long .Lline_table_start0 # DW_AT_stmt_list + .byte 2 # DW_AT_comp_dir + .byte 0 # DW_AT_low_pc + .long .Lfunc_end0-.Lfunc_begin0 # DW_AT_high_pc + .long .Laddr_table_base0 # DW_AT_addr_base + .byte 2 # Abbrev [2] 0x23:0x1b DW_TAG_subprogram + .byte 0 # DW_AT_low_pc + .long .Lfunc_end0-.Lfunc_begin0 # DW_AT_high_pc + .byte 1 # DW_AT_frame_base + .byte 86 + .byte 3 # DW_AT_name + .byte 0 # DW_AT_decl_file + .byte 2 # DW_AT_decl_line + .long 62 # DW_AT_type + # DW_AT_external + .byte 3 # Abbrev [3] 0x32:0xb DW_TAG_variable + .byte 2 # DW_AT_location + .byte 145 + .byte 127 + .byte 5 # DW_AT_name + .byte 0 # DW_AT_decl_file + .byte 3 # DW_AT_decl_line + .long 66 # DW_AT_type + .byte 0 # End Of Children Mark + .byte 4 # Abbrev [4] 0x3e:0x4 DW_TAG_base_type + .byte 4 # DW_AT_name + .byte 5 # DW_AT_encoding + .byte 4 # DW_AT_byte_size + .byte 5 # Abbrev [5] 0x42:0x6 DW_TAG_structure_type + .byte 5 # DW_AT_calling_convention + .byte 6 # DW_AT_name + .byte 1 # DW_AT_byte_size + .byte 0 # DW_AT_decl_file + .byte 1 # DW_AT_decl_line + .byte 0 # End Of Children Mark +.Ldebug_info_end0: + .section .debug_str_offsets,"",@progbits + .long 32 # Length of String Offsets Set + .short 5 + .short 0 +.Lstr_offsets_base0: + .section .debug_str,"MS",@progbits,1 +.Linfo_string0: + .asciz "clang version 19.0.0git (git@github.com:llvm/llvm-project.git 4df364bc93af49ae413ec1ae8328f34ac70730c4)" # string offset=0 +.Linfo_string1: + .asciz "debug-names-2.cpp" # string offset=104 +.Linfo_string2: + .asciz "debug-names-test" # string offset=122 +.Linfo_string3: + .asciz "main" # string offset=139 +.Linfo_string4: + .asciz "int" # string offset=144 +.Linfo_string5: + .asciz "v1" # string offset=148 +.Linfo_string6: + .asciz "t1" # string offset=151 +.Laddr_table_base0: + .quad .Lfunc_begin0 +.Ldebug_addr_end0: + .section .debug_names,"",@progbits + .long .Lnames_end0-.Lnames_start0 # Header: unit length +.Lnames_start0: + .short 5 # Header: version + .short 0 # Header: padding + .long 1 # Header: compilation unit count + .long 0 # Header: local type unit count + .long 0 # Header: foreign type unit count + .long 3 # Header: bucket count + .long 3 # Header: name count + .long .Lnames_abbrev_end0-.Lnames_abbrev_start0 # Header: abbreviation table size + .long 8 # Header: augmentation string size + .ascii "LLVM0700" # Header: augmentation string + .long .Lcu_begin0 # Compilation unit 0 + .long 0 # Bucket 0 + .long 1 # Bucket 1 + .long 3 # Bucket 2 + .long 5863786 # Hash in Bucket 1 + .long 2090499946 # Hash in Bucket 1 + .long 193495088 # Hash in Bucket 2 + .long .Linfo_string6 # String in Bucket 1: t1 + .long .Linfo_string3 # String in Bucket 1: main + .long .Linfo_string4 # String in Bucket 2: int + .long .Lnames2-.Lnames_entries0 # Offset in Bucket 1 + .long .Lnames0-.Lnames_entries0 # Offset in Bucket 1 + .long .Lnames1-.Lnames_entries0 # Offset in Bucket 2 +.Lnames_abbrev_start0: + .byte 1 # Abbrev code + .byte 19 # DW_TAG_structure_type + .byte 3 # DW_IDX_die_offset + .byte 19 # DW_FORM_ref4 + .byte 4 # DW_IDX_parent + .byte 25 # DW_FORM_flag_present + .byte 0 # End of abbrev + .byte 0 # End of abbrev + .byte 2 # Abbrev code + .byte 46 # DW_TAG_subprogram + .byte 3 # DW_IDX_die_offset + .byte 19 # DW_FORM_ref4 + .byte 4 # DW_IDX_parent + .byte 25 # DW_FORM_flag_present + .byte 0 # End of abbrev + .byte 0 # End of abbrev + .byte 3 # Abbrev code + .byte 36 # DW_TAG_base_type + .byte 3 # DW_IDX_die_offset + .byte 19 # DW_FORM_ref4 + .byte 4 # DW_IDX_parent + .byte 25 # DW_FORM_flag_present + .byte 0 # End of abbrev + .byte 0 # End of abbrev + .byte 0 # End of abbrev list +.Lnames_abbrev_end0: +.Lnames_entries0: +.Lnames2: +.L1: + .byte 1 # Abbreviation code + .long 66 # DW_IDX_die_offset + .byte 0 # DW_IDX_parent + # End of list: t1 +.Lnames0: +.L2: + .byte 2 # Abbreviation code + .long 35 # DW_IDX_die_offset + .byte 0 # DW_IDX_parent + # End of list: main +.Lnames1: +.L0: + .byte 3 # Abbreviation code + .long 62 # DW_IDX_die_offset + .byte 0 # DW_IDX_parent + # End of list: int + .p2align 2, 0x0 +.Lnames_end0: + .ident "clang version 19.0.0git (git@github.com:llvm/llvm-project.git 4df364bc93af49ae413ec1ae8328f34ac70730c4)" + .section ".note.GNU-stack","",@progbits + .addrsig + .section .debug_line,"",@progbits +.Lline_table_start0: diff --git a/lld/test/ELF/Inputs/debug-names-parent-idx-2.s b/lld/test/ELF/Inputs/debug-names-parent-idx-2.s new file mode 100644 index 0000000000000..7eedaaee54945 --- /dev/null +++ b/lld/test/ELF/Inputs/debug-names-parent-idx-2.s @@ -0,0 +1,347 @@ +#-- input file: debug-names-parent-idx-2.cpp +## Generated with: +## +## - clang++ -g -O0 -gpubnames -fdebug-compilation-dir='parent-idx-test' \ +## -S debug-names-parent-idx-2.cpp -o debug-names-parent-idx-2.s +## +## foo.h contents: +## +## int foo(); +## +## struct foo { +## int x; +## char y; +## struct foo *foo_ptr; +## }; +## +## namespace parent_test { +## int foo(); +## } +## +## debug-names-parent-index-2.cpp contents: +## +## #include "foo.h" +## int foo () { +## struct foo struct2; +## struct2.x = 1024; +## struct2.y = 'r'; +## struct2.foo_ptr = nullptr; +## return struct2.x * (int) struct2.y; +## } +## +## namespace parent_test { +## int foo () { +## return 25; +## } +## } +## + .text + .globl _Z3foov # -- Begin function _Z3foov + .p2align 4, 0x90 + .type _Z3foov,@function +_Z3foov: # @_Z3foov +.Lfunc_begin0: + .cfi_startproc +# %bb.0: # %entry + pushq %rbp + .cfi_def_cfa_offset 16 + .cfi_offset %rbp, -16 + movq %rsp, %rbp + .cfi_def_cfa_register %rbp +.Ltmp0: + movl $1024, -16(%rbp) # imm = 0x400 + movb $114, -12(%rbp) + movq $0, -8(%rbp) + movl -16(%rbp), %eax + movsbl -12(%rbp), %ecx + imull %ecx, %eax + popq %rbp + .cfi_def_cfa %rsp, 8 + retq +.Ltmp1: +.Lfunc_end0: + .size _Z3foov, .Lfunc_end0-_Z3foov + .cfi_endproc + # -- End function + .globl _ZN11parent_test3fooEv # -- Begin function _ZN11parent_test3fooEv + .p2align 4, 0x90 + .type _ZN11parent_test3fooEv,@function +_ZN11parent_test3fooEv: # @_ZN11parent_test3fooEv +.Lfunc_begin1: + .cfi_startproc +# %bb.0: # %entry + pushq %rbp + .cfi_def_cfa_offset 16 + .cfi_offset %rbp, -16 + movq %rsp, %rbp + .cfi_def_cfa_register %rbp +.Ltmp2: + movl $25, %eax + popq %rbp + .cfi_def_cfa %rsp, 8 + retq +.Ltmp3: +.Lfunc_end1: + .size _ZN11parent_test3fooEv, .Lfunc_end1-_ZN11parent_test3fooEv + .cfi_endproc + # -- End function + .section .debug_abbrev,"",@progbits + .byte 0 # EOM(1) + .byte 0 # EOM(2) + .byte 0 # EOM(3) + .section .debug_info,"",@progbits +.Lcu_begin0: + .long .Ldebug_info_end0-.Ldebug_info_start0 # Length of Unit +.Ldebug_info_start0: + .short 5 # DWARF version number + .byte 1 # DWARF Unit Type + .byte 8 # Address Size (in bytes) + .long .debug_abbrev # Offset Into Abbrev. Section + .byte 1 # Abbrev [1] 0xc:0x76 DW_TAG_compile_unit + .byte 0 # DW_AT_producer + .short 33 # DW_AT_language + .byte 1 # DW_AT_name + .long .Lstr_offsets_base0 # DW_AT_str_offsets_base + .long .Lline_table_start0 # DW_AT_stmt_list + .byte 2 # DW_AT_comp_dir + .byte 0 # DW_AT_low_pc + .long .Lfunc_end1-.Lfunc_begin0 # DW_AT_high_pc + .long .Laddr_table_base0 # DW_AT_addr_base + .byte 2 # Abbrev [2] 0x23:0x4 DW_TAG_base_type + .byte 3 # DW_AT_name + .byte 5 # DW_AT_encoding + .byte 4 # DW_AT_byte_size + .byte 3 # Abbrev [3] 0x27:0x1c DW_TAG_subprogram + .byte 0 # DW_AT_low_pc + .long .Lfunc_end0-.Lfunc_begin0 # DW_AT_high_pc + .byte 1 # DW_AT_frame_base + .byte 86 + .byte 5 # DW_AT_linkage_name + .byte 6 # DW_AT_name + .byte 0 # DW_AT_decl_file + .byte 4 # DW_AT_decl_line + .long 35 # DW_AT_type + # DW_AT_external + .byte 4 # Abbrev [4] 0x37:0xb DW_TAG_variable + .byte 2 # DW_AT_location + .byte 145 + .byte 112 + .byte 8 # DW_AT_name + .byte 0 # DW_AT_decl_file + .byte 5 # DW_AT_decl_line + .long 86 # DW_AT_type + .byte 0 # End Of Children Mark + .byte 5 # Abbrev [5] 0x43:0x13 DW_TAG_namespace + .byte 4 # DW_AT_name + .byte 6 # Abbrev [6] 0x45:0x10 DW_TAG_subprogram + .byte 1 # DW_AT_low_pc + .long .Lfunc_end1-.Lfunc_begin1 # DW_AT_high_pc + .byte 1 # DW_AT_frame_base + .byte 86 + .byte 7 # DW_AT_linkage_name + .byte 6 # DW_AT_name + .byte 0 # DW_AT_decl_file + .byte 16 # DW_AT_decl_line + .long 35 # DW_AT_type + # DW_AT_external + .byte 0 # End Of Children Mark + .byte 7 # Abbrev [7] 0x56:0x22 DW_TAG_structure_type + .byte 5 # DW_AT_calling_convention + .byte 6 # DW_AT_name + .byte 16 # DW_AT_byte_size + .byte 1 # DW_AT_decl_file + .byte 4 # DW_AT_decl_line + .byte 8 # Abbrev [8] 0x5c:0x9 DW_TAG_member + .byte 9 # DW_AT_name + .long 35 # DW_AT_type + .byte 1 # DW_AT_decl_file + .byte 5 # DW_AT_decl_line + .byte 0 # DW_AT_data_member_location + .byte 8 # Abbrev [8] 0x65:0x9 DW_TAG_member + .byte 10 # DW_AT_name + .long 120 # DW_AT_type + .byte 1 # DW_AT_decl_file + .byte 6 # DW_AT_decl_line + .byte 4 # DW_AT_data_member_location + .byte 8 # Abbrev [8] 0x6e:0x9 DW_TAG_member + .byte 12 # DW_AT_name + .long 124 # DW_AT_type + .byte 1 # DW_AT_decl_file + .byte 7 # DW_AT_decl_line + .byte 8 # DW_AT_data_member_location + .byte 0 # End Of Children Mark + .byte 2 # Abbrev [2] 0x78:0x4 DW_TAG_base_type + .byte 11 # DW_AT_name + .byte 6 # DW_AT_encoding + .byte 1 # DW_AT_byte_size + .byte 9 # Abbrev [9] 0x7c:0x5 DW_TAG_pointer_type + .long 86 # DW_AT_type + .byte 0 # End Of Children Mark +.Ldebug_info_end0: + .section .debug_str_offsets,"",@progbits + .long 56 # Length of String Offsets Set + .short 5 + .short 0 +.Lstr_offsets_base0: + .section .debug_str,"MS",@progbits,1 +.Linfo_string0: + .asciz "clang version 19.0.0git (git@github.com:llvm/llvm-project.git 4df364bc93af49ae413ec1ae8328f34ac70730c4)" # string offset=0 +.Linfo_string1: + .asciz "debug-names-parent-idx-2.cpp" # string offset=104 +.Linfo_string2: + .asciz "parent-idx-test" # string offset=133 +.Linfo_string3: + .asciz "int" # string offset=149 +.Linfo_string4: + .asciz "foo" # string offset=153 +.Linfo_string5: + .asciz "_Z3foov" # string offset=157 +.Linfo_string6: + .asciz "parent_test" # string offset=165 +.Linfo_string7: + .asciz "_ZN11parent_test3fooEv" # string offset=177 +.Linfo_string8: + .asciz "struct2" # string offset=200 +.Linfo_string9: + .asciz "x" # string offset=208 +.Linfo_string10: + .asciz "y" # string offset=210 +.Linfo_string11: + .asciz "char" # string offset=212 +.Linfo_string12: + .asciz "foo_ptr" # string offset=217 +.Laddr_table_base0: + .quad .Lfunc_begin0 + .quad .Lfunc_begin1 +.Ldebug_addr_end0: + .section .debug_names,"",@progbits + .long .Lnames_end0-.Lnames_start0 # Header: unit length +.Lnames_start0: + .short 5 # Header: version + .short 0 # Header: padding + .long 1 # Header: compilation unit count + .long 0 # Header: local type unit count + .long 0 # Header: foreign type unit count + .long 6 # Header: bucket count + .long 6 # Header: name count + .long .Lnames_abbrev_end0-.Lnames_abbrev_start0 # Header: abbreviation table size + .long 8 # Header: augmentation string size + .ascii "LLVM0700" # Header: augmentation string + .long .Lcu_begin0 # Compilation unit 0 + .long 0 # Bucket 0 + .long 1 # Bucket 1 + .long 3 # Bucket 2 + .long 5 # Bucket 3 + .long 0 # Bucket 4 + .long 6 # Bucket 5 + .long -1451972055 # Hash in Bucket 1 + .long -1257882357 # Hash in Bucket 1 + .long 175265198 # Hash in Bucket 2 + .long 193495088 # Hash in Bucket 2 + .long 193491849 # Hash in Bucket 3 + .long 2090147939 # Hash in Bucket 5 + .long .Linfo_string7 # String in Bucket 1: _ZN11parent_test3fooEv + .long .Linfo_string5 # String in Bucket 1: _Z3foov + .long .Linfo_string6 # String in Bucket 2: parent_test + .long .Linfo_string3 # String in Bucket 2: int + .long .Linfo_string4 # String in Bucket 3: foo + .long .Linfo_string11 # String in Bucket 5: char + .long .Lnames4-.Lnames_entries0 # Offset in Bucket 1 + .long .Lnames2-.Lnames_entries0 # Offset in Bucket 1 + .long .Lnames3-.Lnames_entries0 # Offset in Bucket 2 + .long .Lnames0-.Lnames_entries0 # Offset in Bucket 2 + .long .Lnames1-.Lnames_entries0 # Offset in Bucket 3 + .long .Lnames5-.Lnames_entries0 # Offset in Bucket 5 +.Lnames_abbrev_start0: + .byte 1 # Abbrev code + .byte 46 # DW_TAG_subprogram + .byte 3 # DW_IDX_die_offset + .byte 19 # DW_FORM_ref4 + .byte 4 # DW_IDX_parent + .byte 19 # DW_FORM_ref4 + .byte 0 # End of abbrev + .byte 0 # End of abbrev + .byte 2 # Abbrev code + .byte 46 # DW_TAG_subprogram + .byte 3 # DW_IDX_die_offset + .byte 19 # DW_FORM_ref4 + .byte 4 # DW_IDX_parent + .byte 25 # DW_FORM_flag_present + .byte 0 # End of abbrev + .byte 0 # End of abbrev + .byte 3 # Abbrev code + .byte 57 # DW_TAG_namespace + .byte 3 # DW_IDX_die_offset + .byte 19 # DW_FORM_ref4 + .byte 4 # DW_IDX_parent + .byte 25 # DW_FORM_flag_present + .byte 0 # End of abbrev + .byte 0 # End of abbrev + .byte 4 # Abbrev code + .byte 36 # DW_TAG_base_type + .byte 3 # DW_IDX_die_offset + .byte 19 # DW_FORM_ref4 + .byte 4 # DW_IDX_parent + .byte 25 # DW_FORM_flag_present + .byte 0 # End of abbrev + .byte 0 # End of abbrev + .byte 5 # Abbrev code + .byte 19 # DW_TAG_structure_type + .byte 3 # DW_IDX_die_offset + .byte 19 # DW_FORM_ref4 + .byte 4 # DW_IDX_parent + .byte 25 # DW_FORM_flag_present + .byte 0 # End of abbrev + .byte 0 # End of abbrev + .byte 0 # End of abbrev list +.Lnames_abbrev_end0: +.Lnames_entries0: +.Lnames4: +.L3: + .byte 1 # Abbreviation code + .long 69 # DW_IDX_die_offset + .long .L5-.Lnames_entries0 # DW_IDX_parent + .byte 0 # End of list: _ZN11parent_test3fooEv +.Lnames2: +.L0: + .byte 2 # Abbreviation code + .long 39 # DW_IDX_die_offset + .byte 0 # DW_IDX_parent + # End of list: _Z3foov +.Lnames3: +.L5: + .byte 3 # Abbreviation code + .long 67 # DW_IDX_die_offset + .byte 0 # DW_IDX_parent + # End of list: parent_test +.Lnames0: +.L2: + .byte 4 # Abbreviation code + .long 35 # DW_IDX_die_offset + .byte 0 # DW_IDX_parent + # End of list: int +.Lnames1: + .byte 2 # Abbreviation code + .long 39 # DW_IDX_die_offset + .byte 1 # DW_IDX_parent + # Abbreviation code + .long 69 # DW_IDX_die_offset + .long .L5-.Lnames_entries0 # DW_IDX_parent +.L4: + .byte 5 # Abbreviation code + .long 86 # DW_IDX_die_offset + .byte 0 # DW_IDX_parent + # End of list: foo +.Lnames5: +.L1: + .byte 4 # Abbreviation code + .long 120 # DW_IDX_die_offset + .byte 0 # DW_IDX_parent + # End of list: char + .p2align 2, 0x0 +.Lnames_end0: + .ident "clang version 19.0.0git (git@github.com:llvm/llvm-project.git 4df364bc93af49ae413ec1ae8328f34ac70730c4)" + .section ".note.GNU-stack","",@progbits + .addrsig + .section .debug_line,"",@progbits +.Lline_table_start0: diff --git a/lld/test/ELF/debug-names-bad-aug-string.s b/lld/test/ELF/debug-names-bad-aug-string.s new file mode 100644 index 0000000000000..edf79f0fde577 --- /dev/null +++ b/lld/test/ELF/debug-names-bad-aug-string.s @@ -0,0 +1,189 @@ +# REQUIRES: x86 +# RUN: llvm-mc -filetype=obj -triple=x86_64 %s -o %t1.o +# RUN: llvm-mc -filetype=obj -triple=x86_64 %p/Inputs/debug-names-2.s -o %t2 +# RUN: ld.lld --debug-names %t1.o %t2.o -o %t + +# RUN: llvm-dwarfdump -debug-names %t | FileCheck %s --check-prefix=DWARF + +# DWARF: .debug_names contents: +# DWARF: Name Index @ 0x0 { +# DWARF-NEXT: Header { +# DWARF-NEXT: Length: 0xCC +# DWARF-NEXT: Format: DWARF32 +# DWARF-NEXT: Version: 5 +# DWARF-NEXT: CU count: 2 +# DWARF-NEXT: Local TU count: 0 +# DWARF-NEXT: Foreign TU count: 0 +# DWARF-NEXT: Bucket count: 5 +# DWARF-NEXT: Name count: 5 +# DWARF-NEXT: Abbreviations table size: 0x1F +# DWARF-NEXT: Augmentation: ' ' +# DWARF: Compilation Unit offsets [ +# DWARF-NEXT: CU[0]: 0x00000000 +# DWARF-NEXT: CU[1]: 0x00000041 + +## +## This file was generated by copying debug-names.s and manually +## editing the 'Header: augmentation string' in the .debug_names section. +## + .text + .globl _Z2f12t1 # -- Begin function _Z2f12t1 + .p2align 4, 0x90 + .type _Z2f12t1,@function +_Z2f12t1: # @_Z2f12t1 +.Lfunc_begin0: + .cfi_startproc +# %bb.0: # %entry + pushq %rbp + .cfi_def_cfa_offset 16 + .cfi_offset %rbp, -16 + movq %rsp, %rbp + .cfi_def_cfa_register %rbp +.Ltmp0: + popq %rbp + .cfi_def_cfa %rsp, 8 + retq +.Ltmp1: +.Lfunc_end0: + .size _Z2f12t1, .Lfunc_end0-_Z2f12t1 + .cfi_endproc + # -- End function + .section .debug_abbrev,"",@progbits + .byte 0 # EOM(1) + .byte 0 # EOM(2) + .byte 0 # EOM(3) + .section .debug_info,"",@progbits +.Lcu_begin0: + .long .Ldebug_info_end0-.Ldebug_info_start0 # Length of Unit +.Ldebug_info_start0: + .short 5 # DWARF version number + .byte 1 # DWARF Unit Type + .byte 8 # Address Size (in bytes) + .long .debug_abbrev # Offset Into Abbrev. Section + .byte 1 # Abbrev [1] 0xc:0x35 DW_TAG_compile_unit + .byte 0 # DW_AT_producer + .short 33 # DW_AT_language + .byte 1 # DW_AT_name + .long .Lstr_offsets_base0 # DW_AT_str_offsets_base + .long .Lline_table_start0 # DW_AT_stmt_list + .byte 2 # DW_AT_comp_dir + .byte 0 # DW_AT_low_pc + .long .Lfunc_end0-.Lfunc_begin0 # DW_AT_high_pc + .long .Laddr_table_base0 # DW_AT_addr_base + .byte 2 # Abbrev [2] 0x23:0x17 DW_TAG_subprogram + .byte 0 # DW_AT_low_pc + .long .Lfunc_end0-.Lfunc_begin0 # DW_AT_high_pc + .byte 1 # DW_AT_frame_base + .byte 86 + .byte 3 # DW_AT_linkage_name + .byte 4 # DW_AT_name + .byte 0 # DW_AT_decl_file + .byte 2 # DW_AT_decl_line + # DW_AT_external + .byte 3 # Abbrev [3] 0x2f:0xa DW_TAG_formal_parameter + .byte 2 # DW_AT_location + .byte 145 + .byte 127 + .byte 0 # DW_AT_decl_file + .byte 2 # DW_AT_decl_line + .long 58 # DW_AT_type + .byte 0 # End Of Children Mark + .byte 4 # Abbrev [4] 0x3a:0x6 DW_TAG_structure_type + .byte 5 # DW_AT_calling_convention + .byte 5 # DW_AT_name + .byte 1 # DW_AT_byte_size + .byte 0 # DW_AT_decl_file + .byte 1 # DW_AT_decl_line + .byte 0 # End Of Children Mark +.Ldebug_info_end0: + .section .debug_str_offsets,"",@progbits + .long 28 # Length of String Offsets Set + .short 5 + .short 0 +.Lstr_offsets_base0: + .section .debug_str,"MS",@progbits,1 +.Linfo_string0: + .asciz "clang version 19.0.0git (git@github.com:llvm/llvm-project.git 4df364bc93af49ae413ec1ae8328f34ac70730c4)" # string offset=0 +.Linfo_string1: + .asciz "debug-names.cpp" # string offset=104 +.Linfo_string2: + .asciz "debug-names-test" # string offset=120 +.Linfo_string3: + .asciz "f1" # string offset=137 +.Linfo_string4: + .asciz "_Z2f12t1" # string offset=140 +.Linfo_string5: + .asciz "t1" # string offset=149 +.Laddr_table_base0: + .quad .Lfunc_begin0 +.Ldebug_addr_end0: + .section .debug_names,"",@progbits + .long .Lnames_end0-.Lnames_start0 # Header: unit length +.Lnames_start0: + .short 5 # Header: version + .short 0 # Header: padding + .long 1 # Header: compilation unit count + .long 0 # Header: local type unit count + .long 0 # Header: foreign type unit count + .long 3 # Header: bucket count + .long 3 # Header: name count + .long .Lnames_abbrev_end0-.Lnames_abbrev_start0 # Header: abbreviation table size + .long 8 # Header: augmentation string size + .ascii "JUNK1234" # Header: augmentation string + .long .Lcu_begin0 # Compilation unit 0 + .long 0 # Bucket 0 + .long 1 # Bucket 1 + .long 3 # Bucket 2 + .long 5863324 # Hash in Bucket 1 + .long 5863786 # Hash in Bucket 1 + .long 1398125246 # Hash in Bucket 2 + .long .Linfo_string3 # String in Bucket 1: f1 + .long .Linfo_string5 # String in Bucket 1: t1 + .long .Linfo_string4 # String in Bucket 2: _Z2f12t1 + .long .Lnames0-.Lnames_entries0 # Offset in Bucket 1 + .long .Lnames2-.Lnames_entries0 # Offset in Bucket 1 + .long .Lnames1-.Lnames_entries0 # Offset in Bucket 2 +.Lnames_abbrev_start0: + .byte 1 # Abbrev code + .byte 46 # DW_TAG_subprogram + .byte 3 # DW_IDX_die_offset + .byte 19 # DW_FORM_ref4 + .byte 4 # DW_IDX_parent + .byte 25 # DW_FORM_flag_present + .byte 0 # End of abbrev + .byte 0 # End of abbrev + .byte 2 # Abbrev code + .byte 19 # DW_TAG_structure_type + .byte 3 # DW_IDX_die_offset + .byte 19 # DW_FORM_ref4 + .byte 4 # DW_IDX_parent + .byte 25 # DW_FORM_flag_present + .byte 0 # End of abbrev + .byte 0 # End of abbrev + .byte 0 # End of abbrev list +.Lnames_abbrev_end0: +.Lnames_entries0: +.Lnames0: +.L1: + .byte 1 # Abbreviation code + .long 35 # DW_IDX_die_offset + .byte 0 # DW_IDX_parent + # End of list: f1 +.Lnames2: +.L0: + .byte 2 # Abbreviation code + .long 58 # DW_IDX_die_offset + .byte 0 # DW_IDX_parent + # End of list: t1 +.Lnames1: + .byte 1 # Abbreviation code + .long 35 # DW_IDX_die_offset + .byte 0 # DW_IDX_parent + # End of list: _Z2f12t1 + .p2align 2, 0x0 +.Lnames_end0: + .ident "clang version 19.0.0git (git@github.com:llvm/llvm-project.git 4df364bc93af49ae413ec1ae8328f34ac70730c4)" + .section ".note.GNU-stack","",@progbits + .addrsig + .section .debug_line,"",@progbits +.Lline_table_start0: diff --git a/lld/test/ELF/debug-names-bad-die-idx-sizes.s b/lld/test/ELF/debug-names-bad-die-idx-sizes.s new file mode 100644 index 0000000000000..2da278a8dd5b7 --- /dev/null +++ b/lld/test/ELF/debug-names-bad-die-idx-sizes.s @@ -0,0 +1,151 @@ +# REQUIRES: x86 +# RUN: llvm-mc -filetype=obj -triple=x86_64 %s -o %t1.o +# +# RUN: not ld.lld --debug-names %t1.o -o /dev/null 2>&1 | FileCheck %s +# +# CHECK: error: {{.*}}:(.debug_names): encountered unexpected end of section while reading entry + +## This file was generated by first compiling main.cpp: +## clang++ -g -O0 -S -gpubnames -fdebug-compilation-dir='debug-names-test' \ +## main.cpp +## +## Then manually edit the .debug_names section. In the entries, change the +## size of the DW_IDX_die_offset from '.long' to '.byte'. +## +## main.cpp: +## int main (int argc, char **argv) { } +## + .text + .globl main # -- Begin function main + .p2align 4, 0x90 + .type main,@function +main: # @main +.Lfunc_begin0: + .cfi_startproc +# %bb.0: # %entry + pushq %rbp + .cfi_def_cfa_offset 16 + .cfi_offset %rbp, -16 + movq %rsp, %rbp + .cfi_def_cfa_register %rbp + movl %edi, -4(%rbp) + movq %rsi, -16(%rbp) +.Ltmp0: + xorl %eax, %eax + popq %rbp + .cfi_def_cfa %rsp, 8 + retq +.Ltmp1: +.Lfunc_end0: + .size main, .Lfunc_end0-main + .cfi_endproc + # -- End function + .section .debug_abbrev,"",@progbits + .byte 0 # EOM(1) + .byte 0 # EOM(2) + .byte 0 # EOM(3) + .section .debug_info,"",@progbits +.Lcu_begin0: + .long .Ldebug_info_end0-.Ldebug_info_start0 # Length of Unit +.Ldebug_info_start0: + .short 5 # DWARF version number + .byte 1 # DWARF Unit Type + .byte 8 # Address Size (in bytes) + .long .debug_abbrev # Offset Into Abbrev. Section +.Ldebug_info_end0: + .section .debug_str_offsets,"",@progbits + .long 36 # Length of String Offsets Set + .short 5 + .short 0 +.Lstr_offsets_base0: + .section .debug_str,"MS",@progbits,1 +.Linfo_string0: + .asciz "clang version 19.0.0git (git@github.com:llvm/llvm-project.git d33d5630b281debe6eabd67e323bcf767340fb6a)" # string offset=0 +.Linfo_string1: + .asciz "main.cpp" # string offset=104 +.Linfo_string2: + .asciz "debug-names-test" # string offset=113 +.Linfo_string3: + .asciz "main" # string offset=130 +.Linfo_string4: + .asciz "int" # string offset=135 +.Linfo_string5: + .asciz "argc" # string offset=139 +.Linfo_string6: + .asciz "argv" # string offset=144 +.Linfo_string7: + .asciz "char" # string offset=149 +.Laddr_table_base0: + .quad .Lfunc_begin0 +.Ldebug_addr_end0: + .section .debug_names,"",@progbits + .long .Lnames_end0-.Lnames_start0 # Header: unit length +.Lnames_start0: + .short 5 # Header: version + .short 0 # Header: padding + .long 1 # Header: compilation unit count + .long 0 # Header: local type unit count + .long 0 # Header: foreign type unit count + .long 3 # Header: bucket count + .long 3 # Header: name count + .long .Lnames_abbrev_end0-.Lnames_abbrev_start0 # Header: abbreviation table size + .long 8 # Header: augmentation string size + .ascii "LLVM0700" # Header: augmentation string + .long .Lcu_begin0 # Compilation unit 0 + .long 0 # Bucket 0 + .long 1 # Bucket 1 + .long 2 # Bucket 2 + .long 2090499946 # Hash in Bucket 1 + .long 193495088 # Hash in Bucket 2 + .long 2090147939 # Hash in Bucket 2 + .long .Linfo_string3 # String in Bucket 1: main + .long .Linfo_string4 # String in Bucket 2: int + .long .Linfo_string7 # String in Bucket 2: char + .long .Lnames0-.Lnames_entries0 # Offset in Bucket 1 + .long .Lnames1-.Lnames_entries0 # Offset in Bucket 2 + .long .Lnames2-.Lnames_entries0 # Offset in Bucket 2 +.Lnames_abbrev_start0: + .byte 1 # Abbrev code + .byte 46 # DW_TAG_subprogram + .byte 3 # DW_IDX_die_offset + .byte 19 # DW_FORM_ref4 + .byte 4 # DW_IDX_parent + .byte 25 # DW_FORM_flag_present + .byte 0 # End of abbrev + .byte 0 # End of abbrev + .byte 2 # Abbrev code + .byte 36 # DW_TAG_base_type + .byte 3 # DW_IDX_die_offset + .byte 19 # DW_FORM_ref4 + .byte 4 # DW_IDX_parent + .byte 25 # DW_FORM_flag_present + .byte 0 # End of abbrev + .byte 0 # End of abbrev + .byte 0 # End of abbrev list +.Lnames_abbrev_end0: +.Lnames_entries0: +.Lnames0: +.L1: + .byte 1 # Abbreviation code + .byte 35 # DW_IDX_die_offset + .byte 0 # DW_IDX_parent + # End of list: main +.Lnames1: +.L0: + .byte 2 # Abbreviation code + .byte 73 # DW_IDX_die_offset + .byte 0 # DW_IDX_parent + # End of list: int +.Lnames2: +.L2: + .byte 2 # Abbreviation code + .byte 87 # DW_IDX_die_offset + .byte 0 # DW_IDX_parent + # End of list: char + .p2align 2, 0x0 +.Lnames_end0: + .ident "clang version 19.0.0git (git@github.com:llvm/llvm-project.git d33d5630b281debe6eabd67e323bcf767340fb6a)" + .section ".note.GNU-stack","",@progbits + .addrsig + .section .debug_line,"",@progbits +.Lline_table_start0: diff --git a/lld/test/ELF/debug-names-bad-name-count.s b/lld/test/ELF/debug-names-bad-name-count.s new file mode 100644 index 0000000000000..4acfa182b11a9 --- /dev/null +++ b/lld/test/ELF/debug-names-bad-name-count.s @@ -0,0 +1,154 @@ +# REQUIRES: x86 +# RUN: llvm-mc -filetype=obj -triple=x86_64 %s -o %t1.o +# +# RUN: not ld.lld --debug-names %t1.o -o /dev/null 2>&1 | FileCheck %s +# +# CHECK: error: {{.*}}:(.debug_names): encountered unexpected end of section while reading entry +# CHECK: error: {{.*}}:(.debug_names): encountered unexpected end of section while reading entry +# CHECK: error: {{.*}}:(.debug_names): encountered unexpected end of section while reading entry +# CHECK: error: {{.*}}:(.debug_names): encountered unexpected end of section while reading entry + +## This file was generated by first compiling main.cpp: +## clang++ -g -O0 -S -gpubnames -fdebug-compilation-dir='debug-names-test' \ +## main.cpp +## +## Then manually edit .debug_names section: change value for +## 'Header: name count' from 3 to 4. +## +## main.cpp: +## int main (int argc, char **argv) { } +## + .text + .globl main # -- Begin function main + .p2align 4, 0x90 + .type main,@function +main: # @main +.Lfunc_begin0: + .cfi_startproc +# %bb.0: # %entry + pushq %rbp + .cfi_def_cfa_offset 16 + .cfi_offset %rbp, -16 + movq %rsp, %rbp + .cfi_def_cfa_register %rbp + movl %edi, -4(%rbp) + movq %rsi, -16(%rbp) +.Ltmp0: + xorl %eax, %eax + popq %rbp + .cfi_def_cfa %rsp, 8 + retq +.Ltmp1: +.Lfunc_end0: + .size main, .Lfunc_end0-main + .cfi_endproc + # -- End function + .section .debug_abbrev,"",@progbits + .byte 0 # EOM(1) + .byte 0 # EOM(2) + .byte 0 # EOM(3) + .section .debug_info,"",@progbits +.Lcu_begin0: + .long .Ldebug_info_end0-.Ldebug_info_start0 # Length of Unit +.Ldebug_info_start0: + .short 5 # DWARF version number + .byte 1 # DWARF Unit Type + .byte 8 # Address Size (in bytes) + .long .debug_abbrev # Offset Into Abbrev. Section +.Ldebug_info_end0: + .section .debug_str_offsets,"",@progbits + .long 36 # Length of String Offsets Set + .short 5 + .short 0 +.Lstr_offsets_base0: + .section .debug_str,"MS",@progbits,1 +.Linfo_string0: + .asciz "clang version 19.0.0git (git@github.com:llvm/llvm-project.git d33d5630b281debe6eabd67e323bcf767340fb6a)" # string offset=0 +.Linfo_string1: + .asciz "main.cpp" # string offset=104 +.Linfo_string2: + .asciz "debug-names-test" # string offset=113 +.Linfo_string3: + .asciz "main" # string offset=130 +.Linfo_string4: + .asciz "int" # string offset=135 +.Linfo_string5: + .asciz "argc" # string offset=139 +.Linfo_string6: + .asciz "argv" # string offset=144 +.Linfo_string7: + .asciz "char" # string offset=149 +.Laddr_table_base0: + .quad .Lfunc_begin0 +.Ldebug_addr_end0: + .section .debug_names,"",@progbits + .long .Lnames_end0-.Lnames_start0 # Header: unit length +.Lnames_start0: + .short 5 # Header: version + .short 0 # Header: padding + .long 1 # Header: compilation unit count + .long 0 # Header: local type unit count + .long 0 # Header: foreign type unit count + .long 3 # Header: bucket count + .long 4 # Header: name count + .long .Lnames_abbrev_end0-.Lnames_abbrev_start0 # Header: abbreviation table size + .long 8 # Header: augmentation string size + .ascii "LLVM0700" # Header: augmentation string + .long .Lcu_begin0 # Compilation unit 0 + .long 0 # Bucket 0 + .long 1 # Bucket 1 + .long 2 # Bucket 2 + .long 2090499946 # Hash in Bucket 1 + .long 193495088 # Hash in Bucket 2 + .long 2090147939 # Hash in Bucket 2 + .long .Linfo_string3 # String in Bucket 1: main + .long .Linfo_string4 # String in Bucket 2: int + .long .Linfo_string7 # String in Bucket 2: char + .long .Lnames0-.Lnames_entries0 # Offset in Bucket 1 + .long .Lnames1-.Lnames_entries0 # Offset in Bucket 2 + .long .Lnames2-.Lnames_entries0 # Offset in Bucket 2 +.Lnames_abbrev_start0: + .byte 1 # Abbrev code + .byte 46 # DW_TAG_subprogram + .byte 3 # DW_IDX_die_offset + .byte 19 # DW_FORM_ref4 + .byte 4 # DW_IDX_parent + .byte 25 # DW_FORM_flag_present + .byte 0 # End of abbrev + .byte 0 # End of abbrev + .byte 2 # Abbrev code + .byte 36 # DW_TAG_base_type + .byte 3 # DW_IDX_die_offset + .byte 19 # DW_FORM_ref4 + .byte 4 # DW_IDX_parent + .byte 25 # DW_FORM_flag_present + .byte 0 # End of abbrev + .byte 0 # End of abbrev + .byte 0 # End of abbrev list +.Lnames_abbrev_end0: +.Lnames_entries0: +.Lnames0: +.L1: + .byte 1 # Abbreviation code + .long 35 # DW_IDX_die_offset + .byte 0 # DW_IDX_parent + # End of list: main +.Lnames1: +.L0: + .byte 2 # Abbreviation code + .long 73 # DW_IDX_die_offset + .byte 0 # DW_IDX_parent + # End of list: int +.Lnames2: +.L2: + .byte 2 # Abbreviation code + .long 87 # DW_IDX_die_offset + .byte 0 # DW_IDX_parent + # End of list: char + .p2align 2, 0x0 +.Lnames_end0: + .ident "clang version 19.0.0git (git@github.com:llvm/llvm-project.git d33d5630b281debe6eabd67e323bcf767340fb6a)" + .section ".note.GNU-stack","",@progbits + .addrsig + .section .debug_line,"",@progbits +.Lline_table_start0: diff --git a/lld/test/ELF/debug-names-bad-offsets-sizes.s b/lld/test/ELF/debug-names-bad-offsets-sizes.s new file mode 100644 index 0000000000000..e11d19a9bf579 --- /dev/null +++ b/lld/test/ELF/debug-names-bad-offsets-sizes.s @@ -0,0 +1,153 @@ +# REQUIRES: x86 +# RUN: llvm-mc -filetype=obj -triple=x86_64 %s -o %t1.o +# +# RUN: not ld.lld --debug-names %t1.o -o /dev/null 2>&1 | FileCheck %s +# +# CHECK: error: {{.*}}:(.debug_names): encountered unexpected end of section while reading entry +# CHECK: error: {{.*}}:(.debug_names): encountered unexpected end of section while reading entry +# CHECK: error: {{.*}}:(.debug_names): encountered unexpected end of section while reading entry + +## This file was generated by first compiling main.cpp: +## clang++ -g -O0 -S -gpubnames -fdebug-compilation-dir='debug-names-test' \ +## main.cpp +## +## Then manually edit .debug_names section. Change the sizes of +## 'Offset in Bucket' values from '.long' to '.byte'. +## +## main.cpp: +## int main (int argc, char **argv) { } +## + .text + .globl main # -- Begin function main + .p2align 4, 0x90 + .type main,@function +main: # @main +.Lfunc_begin0: + .cfi_startproc +# %bb.0: # %entry + pushq %rbp + .cfi_def_cfa_offset 16 + .cfi_offset %rbp, -16 + movq %rsp, %rbp + .cfi_def_cfa_register %rbp + movl %edi, -4(%rbp) + movq %rsi, -16(%rbp) +.Ltmp0: + xorl %eax, %eax + popq %rbp + .cfi_def_cfa %rsp, 8 + retq +.Ltmp1: +.Lfunc_end0: + .size main, .Lfunc_end0-main + .cfi_endproc + # -- End function + .section .debug_abbrev,"",@progbits + .byte 0 # EOM(1) + .byte 0 # EOM(2) + .byte 0 # EOM(3) + .section .debug_info,"",@progbits +.Lcu_begin0: + .long .Ldebug_info_end0-.Ldebug_info_start0 # Length of Unit +.Ldebug_info_start0: + .short 5 # DWARF version number + .byte 1 # DWARF Unit Type + .byte 8 # Address Size (in bytes) + .long .debug_abbrev # Offset Into Abbrev. Section +.Ldebug_info_end0: + .section .debug_str_offsets,"",@progbits + .long 36 # Length of String Offsets Set + .short 5 + .short 0 +.Lstr_offsets_base0: + .section .debug_str,"MS",@progbits,1 +.Linfo_string0: + .asciz "clang version 19.0.0git (git@github.com:llvm/llvm-project.git d33d5630b281debe6eabd67e323bcf767340fb6a)" # string offset=0 +.Linfo_string1: + .asciz "main.cpp" # string offset=104 +.Linfo_string2: + .asciz "debug-names-test" # string offset=113 +.Linfo_string3: + .asciz "main" # string offset=130 +.Linfo_string4: + .asciz "int" # string offset=135 +.Linfo_string5: + .asciz "argc" # string offset=139 +.Linfo_string6: + .asciz "argv" # string offset=144 +.Linfo_string7: + .asciz "char" # string offset=149 +.Laddr_table_base0: + .quad .Lfunc_begin0 +.Ldebug_addr_end0: + .section .debug_names,"",@progbits + .long .Lnames_end0-.Lnames_start0 # Header: unit length +.Lnames_start0: + .short 5 # Header: version + .short 0 # Header: padding + .long 1 # Header: compilation unit count + .long 0 # Header: local type unit count + .long 0 # Header: foreign type unit count + .long 3 # Header: bucket count + .long 3 # Header: name count + .long .Lnames_abbrev_end0-.Lnames_abbrev_start0 # Header: abbreviation table size + .long 8 # Header: augmentation string size + .ascii "LLVM0700" # Header: augmentation string + .long .Lcu_begin0 # Compilation unit 0 + .long 0 # Bucket 0 + .long 1 # Bucket 1 + .long 2 # Bucket 2 + .long 2090499946 # Hash in Bucket 1 + .long 193495088 # Hash in Bucket 2 + .long 2090147939 # Hash in Bucket 2 + .long .Linfo_string3 # String in Bucket 1: main + .long .Linfo_string4 # String in Bucket 2: int + .long .Linfo_string7 # String in Bucket 2: char + .byte .Lnames0-.Lnames_entries0 # Offset in Bucket 1 + .byte .Lnames1-.Lnames_entries0 # Offset in Bucket 2 + .byte .Lnames2-.Lnames_entries0 # Offset in Bucket 2 +.Lnames_abbrev_start0: + .byte 1 # Abbrev code + .byte 46 # DW_TAG_subprogram + .byte 3 # DW_IDX_die_offset + .byte 19 # DW_FORM_ref4 + .byte 4 # DW_IDX_parent + .byte 25 # DW_FORM_flag_present + .byte 0 # End of abbrev + .byte 0 # End of abbrev + .byte 2 # Abbrev code + .byte 36 # DW_TAG_base_type + .byte 3 # DW_IDX_die_offset + .byte 19 # DW_FORM_ref4 + .byte 4 # DW_IDX_parent + .byte 25 # DW_FORM_flag_present + .byte 0 # End of abbrev + .byte 0 # End of abbrev + .byte 0 # End of abbrev list +.Lnames_abbrev_end0: +.Lnames_entries0: +.Lnames0: +.L1: + .byte 1 # Abbreviation code + .long 35 # DW_IDX_die_offset + .byte 0 # DW_IDX_parent + # End of list: main +.Lnames1: +.L0: + .byte 2 # Abbreviation code + .long 73 # DW_IDX_die_offset + .byte 0 # DW_IDX_parent + # End of list: int +.Lnames2: +.L2: + .byte 2 # Abbreviation code + .long 87 # DW_IDX_die_offset + .byte 0 # DW_IDX_parent + # End of list: char + .p2align 2, 0x0 +.Lnames_end0: + .ident "clang version 19.0.0git (git@github.com:llvm/llvm-project.git d33d5630b281debe6eabd67e323bcf767340fb6a)" + .section ".note.GNU-stack","",@progbits + .addrsig + .section .debug_line,"",@progbits +.Lline_table_start0: diff --git a/lld/test/ELF/debug-names-bad-version.s b/lld/test/ELF/debug-names-bad-version.s new file mode 100644 index 0000000000000..f3914670af94a --- /dev/null +++ b/lld/test/ELF/debug-names-bad-version.s @@ -0,0 +1,173 @@ +# REQUIRES: x86 +# RUN: llvm-mc -filetype=obj -triple=x86_64 %s -o %t1.o +# RUN: llvm-mc -filetype=obj -triple=x86_64 %p/Inputs/debug-names-2.s -o %t2 +# +# RUN: not ld.lld --debug-names %t1.o %t2.o -o /dev/null 2>&1 | FileCheck %s +# +# CHECK: error: {{.*}}:(.debug_names): unsupported version +## +## This file was generated by copying debug-names.s and manually +## editing the 'Header: version' in the .debug_names section (changed it from +## 5 to 4). + + .text + .globl _Z2f12t1 # -- Begin function _Z2f12t1 + .p2align 4, 0x90 + .type _Z2f12t1,@function +_Z2f12t1: # @_Z2f12t1 +.Lfunc_begin0: + .cfi_startproc +# %bb.0: # %entry + pushq %rbp + .cfi_def_cfa_offset 16 + .cfi_offset %rbp, -16 + movq %rsp, %rbp + .cfi_def_cfa_register %rbp +.Ltmp0: + popq %rbp + .cfi_def_cfa %rsp, 8 + retq +.Ltmp1: +.Lfunc_end0: + .size _Z2f12t1, .Lfunc_end0-_Z2f12t1 + .cfi_endproc + # -- End function + .section .debug_abbrev,"",@progbits + .byte 0 # EOM(1) + .byte 0 # EOM(2) + .byte 0 # EOM(3) + .section .debug_info,"",@progbits +.Lcu_begin0: + .long .Ldebug_info_end0-.Ldebug_info_start0 # Length of Unit +.Ldebug_info_start0: + .short 5 # DWARF version number + .byte 1 # DWARF Unit Type + .byte 8 # Address Size (in bytes) + .long .debug_abbrev # Offset Into Abbrev. Section + .byte 1 # Abbrev [1] 0xc:0x35 DW_TAG_compile_unit + .byte 0 # DW_AT_producer + .short 33 # DW_AT_language + .byte 1 # DW_AT_name + .long .Lstr_offsets_base0 # DW_AT_str_offsets_base + .long .Lline_table_start0 # DW_AT_stmt_list + .byte 2 # DW_AT_comp_dir + .byte 0 # DW_AT_low_pc + .long .Lfunc_end0-.Lfunc_begin0 # DW_AT_high_pc + .long .Laddr_table_base0 # DW_AT_addr_base + .byte 2 # Abbrev [2] 0x23:0x17 DW_TAG_subprogram + .byte 0 # DW_AT_low_pc + .long .Lfunc_end0-.Lfunc_begin0 # DW_AT_high_pc + .byte 1 # DW_AT_frame_base + .byte 86 + .byte 3 # DW_AT_linkage_name + .byte 4 # DW_AT_name + .byte 0 # DW_AT_decl_file + .byte 2 # DW_AT_decl_line + # DW_AT_external + .byte 3 # Abbrev [3] 0x2f:0xa DW_TAG_formal_parameter + .byte 2 # DW_AT_location + .byte 145 + .byte 127 + .byte 0 # DW_AT_decl_file + .byte 2 # DW_AT_decl_line + .long 58 # DW_AT_type + .byte 0 # End Of Children Mark + .byte 4 # Abbrev [4] 0x3a:0x6 DW_TAG_structure_type + .byte 5 # DW_AT_calling_convention + .byte 5 # DW_AT_name + .byte 1 # DW_AT_byte_size + .byte 0 # DW_AT_decl_file + .byte 1 # DW_AT_decl_line + .byte 0 # End Of Children Mark +.Ldebug_info_end0: + .section .debug_str_offsets,"",@progbits + .long 28 # Length of String Offsets Set + .short 5 + .short 0 +.Lstr_offsets_base0: + .section .debug_str,"MS",@progbits,1 +.Linfo_string0: + .asciz "clang version 19.0.0git (git@github.com:llvm/llvm-project.git 4df364bc93af49ae413ec1ae8328f34ac70730c4)" # string offset=0 +.Linfo_string1: + .asciz "debug-names.cpp" # string offset=104 +.Linfo_string2: + .asciz "debug-names-test" # string offset=120 +.Linfo_string3: + .asciz "f1" # string offset=137 +.Linfo_string4: + .asciz "_Z2f12t1" # string offset=140 +.Linfo_string5: + .asciz "t1" # string offset=149 +.Laddr_table_base0: + .quad .Lfunc_begin0 +.Ldebug_addr_end0: + .section .debug_names,"",@progbits + .long .Lnames_end0-.Lnames_start0 # Header: unit length +.Lnames_start0: + .short 4 # Header: version + .short 0 # Header: padding + .long 1 # Header: compilation unit count + .long 0 # Header: local type unit count + .long 0 # Header: foreign type unit count + .long 3 # Header: bucket count + .long 3 # Header: name count + .long .Lnames_abbrev_end0-.Lnames_abbrev_start0 # Header: abbreviation table size + .long 8 # Header: augmentation string size + .ascii "LLVM0700" # Header: augmentation string + .long .Lcu_begin0 # Compilation unit 0 + .long 0 # Bucket 0 + .long 1 # Bucket 1 + .long 3 # Bucket 2 + .long 5863324 # Hash in Bucket 1 + .long 5863786 # Hash in Bucket 1 + .long 1398125246 # Hash in Bucket 2 + .long .Linfo_string3 # String in Bucket 1: f1 + .long .Linfo_string5 # String in Bucket 1: t1 + .long .Linfo_string4 # String in Bucket 2: _Z2f12t1 + .long .Lnames0-.Lnames_entries0 # Offset in Bucket 1 + .long .Lnames2-.Lnames_entries0 # Offset in Bucket 1 + .long .Lnames1-.Lnames_entries0 # Offset in Bucket 2 +.Lnames_abbrev_start0: + .byte 1 # Abbrev code + .byte 46 # DW_TAG_subprogram + .byte 3 # DW_IDX_die_offset + .byte 19 # DW_FORM_ref4 + .byte 4 # DW_IDX_parent + .byte 25 # DW_FORM_flag_present + .byte 0 # End of abbrev + .byte 0 # End of abbrev + .byte 2 # Abbrev code + .byte 19 # DW_TAG_structure_type + .byte 3 # DW_IDX_die_offset + .byte 19 # DW_FORM_ref4 + .byte 4 # DW_IDX_parent + .byte 25 # DW_FORM_flag_present + .byte 0 # End of abbrev + .byte 0 # End of abbrev + .byte 0 # End of abbrev list +.Lnames_abbrev_end0: +.Lnames_entries0: +.Lnames0: +.L1: + .byte 1 # Abbreviation code + .long 35 # DW_IDX_die_offset + .byte 0 # DW_IDX_parent + # End of list: f1 +.Lnames2: +.L0: + .byte 2 # Abbreviation code + .long 58 # DW_IDX_die_offset + .byte 0 # DW_IDX_parent + # End of list: t1 +.Lnames1: + .byte 1 # Abbreviation code + .long 35 # DW_IDX_die_offset + .byte 0 # DW_IDX_parent + # End of list: _Z2f12t1 + .p2align 2, 0x0 +.Lnames_end0: + .ident "clang version 19.0.0git (git@github.com:llvm/llvm-project.git 4df364bc93af49ae413ec1ae8328f34ac70730c4)" + .section ".note.GNU-stack","",@progbits + .addrsig + .section .debug_line,"",@progbits +.Lline_table_start0: diff --git a/lld/test/ELF/debug-names-invalid-attribute.s b/lld/test/ELF/debug-names-invalid-attribute.s new file mode 100644 index 0000000000000..9b1a915d81f88 --- /dev/null +++ b/lld/test/ELF/debug-names-invalid-attribute.s @@ -0,0 +1,179 @@ +# REQUIRES: x86 +# RUN: llvm-mc -filetype=obj -triple=x86_64 %s -o %t1.o +# +# RUN: not ld.lld --debug-names %t1.o -o /dev/null 2>&1 | FileCheck %s +# +# CHECK: error: {{.*}}:(.debug_names): unrecognized form encoding 16 in .debug_names abbrev table +## +## Generated by copying debug-names.s and manually editing it to make some +## of the abbrev attributes invalid. + + .text + .globl _Z2f12t1 # -- Begin function _Z2f12t1 + .p2align 4, 0x90 + .type _Z2f12t1,@function +_Z2f12t1: # @_Z2f12t1 +.Lfunc_begin0: + .cfi_startproc +# %bb.0: # %entry + pushq %rbp + .cfi_def_cfa_offset 16 + .cfi_offset %rbp, -16 + movq %rsp, %rbp + .cfi_def_cfa_register %rbp +.Ltmp0: + popq %rbp + .cfi_def_cfa %rsp, 8 + retq +.Ltmp1: +.Lfunc_end0: + .size _Z2f12t1, .Lfunc_end0-_Z2f12t1 + .cfi_endproc + # -- End function + .section .debug_abbrev,"",@progbits + .byte 0 # EOM(1) + .byte 0 # EOM(2) + .byte 0 # EOM(3) + .section .debug_info,"",@progbits +.Lcu_begin0: + .long .Ldebug_info_end0-.Ldebug_info_start0 # Length of Unit +.Ldebug_info_start0: + .short 5 # DWARF version number + .byte 1 # DWARF Unit Type + .byte 8 # Address Size (in bytes) + .long .debug_abbrev # Offset Into Abbrev. Section + .byte 1 # Abbrev [1] 0xc:0x35 DW_TAG_compile_unit + .byte 0 # DW_AT_producer + .short 33 # DW_AT_language + .byte 1 # DW_AT_name + .long .Lstr_offsets_base0 # DW_AT_str_offsets_base + .long .Lline_table_start0 # DW_AT_stmt_list + .byte 2 # DW_AT_comp_dir + .byte 0 # DW_AT_low_pc + .long .Lfunc_end0-.Lfunc_begin0 # DW_AT_high_pc + .long .Laddr_table_base0 # DW_AT_addr_base + .byte 2 # Abbrev [2] 0x23:0x17 DW_TAG_subprogram + .byte 0 # DW_AT_low_pc + .long .Lfunc_end0-.Lfunc_begin0 # DW_AT_high_pc + .byte 1 # DW_AT_frame_base + .byte 86 + .byte 3 # DW_AT_linkage_name + .byte 4 # DW_AT_name + .byte 0 # DW_AT_decl_file + .byte 2 # DW_AT_decl_line + # DW_AT_external + .byte 3 # Abbrev [3] 0x2f:0xa DW_TAG_formal_parameter + .byte 2 # DW_AT_location + .byte 145 + .byte 127 + .byte 0 # DW_AT_decl_file + .byte 2 # DW_AT_decl_line + .long 58 # DW_AT_type + .byte 0 # End Of Children Mark + .byte 4 # Abbrev [4] 0x3a:0x6 DW_TAG_structure_type + .byte 5 # DW_AT_calling_convention + .byte 5 # DW_AT_name + .byte 1 # DW_AT_byte_size + .byte 0 # DW_AT_decl_file + .byte 1 # DW_AT_decl_line + .byte 0 # End Of Children Mark +.Ldebug_info_end0: + .section .debug_str_offsets,"",@progbits + .long 28 # Length of String Offsets Set + .short 5 + .short 0 +.Lstr_offsets_base0: + .section .debug_str,"MS",@progbits,1 +.Linfo_string0: + .asciz "clang version 19.0.0git (git@github.com:llvm/llvm-project.git 4df364bc93af49ae413ec1ae8328f34ac70730c4)" # string offset=0 +.Linfo_string1: + .asciz "debug-names.cpp" # string offset=104 +.Linfo_string2: + .asciz "debug-names-test" # string offset=120 +.Linfo_string3: + .asciz "f1" # string offset=137 +.Linfo_string4: + .asciz "_Z2f12t1" # string offset=140 +.Linfo_string5: + .asciz "t1" # string offset=149 +.Laddr_table_base0: + .quad .Lfunc_begin0 +.Ldebug_addr_end0: + .section .debug_names,"",@progbits + .long .Lnames_end0-.Lnames_start0 # Header: unit length +.Lnames_start0: + .short 5 # Header: version + .short 0 # Header: padding + .long 1 # Header: compilation unit count + .long 0 # Header: local type unit count + .long 0 # Header: foreign type unit count + .long 3 # Header: bucket count + .long 3 # Header: name count + .long .Lnames_abbrev_end0-.Lnames_abbrev_start0 # Header: abbreviation table size + .long 8 # Header: augmentation string size + .ascii "LLVM0700" # Header: augmentation string + .long .Lcu_begin0 # Compilation unit 0 + .long 0 # Bucket 0 + .long 1 # Bucket 1 + .long 3 # Bucket 2 + .long 5863324 # Hash in Bucket 1 + .long 5863786 # Hash in Bucket 1 + .long 1398125246 # Hash in Bucket 2 + .long .Linfo_string3 # String in Bucket 1: f1 + .long .Linfo_string5 # String in Bucket 1: t1 + .long .Linfo_string4 # String in Bucket 2: _Z2f12t1 + .long .Lnames0-.Lnames_entries0 # Offset in Bucket 1 + .long .Lnames2-.Lnames_entries0 # Offset in Bucket 1 + .long .Lnames1-.Lnames_entries0 # Offset in Bucket 2 +.Lnames_abbrev_start0: + .byte 1 # Abbrev code + .byte 46 # DW_TAG_subprogram + .byte 3 # DW_IDX_die_offset + .byte 19 # DW_FORM_ref4 + .byte 4 # DW_IDX_parent + .byte 25 # DW_FORM_flag_present + .byte 0 # End of abbrev + .byte 0 # End of abbrev + .byte 2 # Abbrev code + .byte 19 # DW_TAG_structure_type + .byte 3 # DW_IDX_die_offset + .byte 19 # DW_FORM_ref4 + .byte 4 # DW_IDX_parent + .byte 25 # DW_FORM_flag_present + .byte 0 # End of abbrev + .byte 0 # End of abbrev + .byte 3 # Abbrev code + .byte 19 # DW_TAG_structure_type + .byte 3 # DW_IDX_die_offset + .byte 16 # DW_FORM_ref_addr + .byte 7 # DW_IDX_unknown + .byte 25 # DW_FORM_flag_present + .byte 0 # End of abbrev + .byte 0 # End of abbrev + .byte 0 # End of abbrev list +.Lnames_abbrev_end0: +.Lnames_entries0: +.Lnames0: +.L1: + .byte 1 # Abbreviation code + .long 35 # DW_IDX_die_offset + .byte 0 # DW_IDX_parent + # End of list: f1 +.Lnames2: +.L0: + .byte 2 # Abbreviation code + .long 58 # DW_IDX_die_offset + .byte 0 # DW_IDX_parent + # End of list: t1 +.Lnames1: + .byte 3 # Abbreviation code + .long 35 # DW_IDX_die_offset + .byte 0 # DW_IDX_parent + # End of list: _Z2f12t1 + .p2align 2, 0x0 +.Lnames_end0: + .ident "clang version 19.0.0git (git@github.com:llvm/llvm-project.git 4df364bc93af49ae413ec1ae8328f34ac70730c4)" + .section ".note.GNU-stack","",@progbits + .addrsig + .section .debug_line,"",@progbits +.Lline_table_start0: diff --git a/lld/test/ELF/debug-names-parent-idx.s b/lld/test/ELF/debug-names-parent-idx.s new file mode 100644 index 0000000000000..a4e8682cd9ee5 --- /dev/null +++ b/lld/test/ELF/debug-names-parent-idx.s @@ -0,0 +1,549 @@ +# REQUIRES: x86 +# RUN: llvm-mc -filetype=obj -triple=x86_64 %s -o %t1.o +# RUN: llvm-mc -filetype=obj -triple=x86_64 %p/Inputs/debug-names-parent-idx-2.s -o %t2.o +# RUN: ld.lld --debug-names %t1.o %t2.o -o %t + +# RUN: llvm-dwarfdump -debug-names %t | FileCheck %s --check-prefix=DWARF + +# DWARF: .debug_names contents: +# DWARF: Name Index @ 0x0 { +# DWARF-NEXT: Header { +# DWARF-NEXT: Length: 0x15C +# DWARF-NEXT: Format: DWARF32 +# DWARF-NEXT: Version: 5 +# DWARF-NEXT: CU count: 2 +# DWARF-NEXT: Local TU count: 0 +# DWARF-NEXT: Foreign TU count: 0 +# DWARF-NEXT: Bucket count: 9 +# DWARF-NEXT: Name count: 9 +# DWARF-NEXT: Abbreviations table size: 0x33 +# DWARF-NEXT: Augmentation: 'LLVM0700' +# DWARF: Compilation Unit offsets [ +# DWARF-NEXT: CU[0]: 0x00000000 +# DWARF-NEXT: CU[1]: 0x000000cc +# DWARF: Abbreviations [ +# DWARF-NEXT: Abbreviation 0x1 { +# DWARF-NEXT: Tag: DW_TAG_base_type +# DWARF-NEXT: DW_IDX_die_offset: DW_FORM_ref4 +# DWARF-NEXT: DW_IDX_parent: DW_FORM_flag_present +# DWARF-NEXT: DW_IDX_compile_unit: DW_FORM_data1 +# DWARF: Abbreviation 0x2 { +# DWARF-NEXT: Tag: DW_TAG_subprogram +# DWARF-NEXT: DW_IDX_die_offset: DW_FORM_ref4 +# DWARF-NEXT: DW_IDX_parent: DW_FORM_flag_present +# DWARF-NEXT: DW_IDX_compile_unit: DW_FORM_data1 +# DWARF: Abbreviation 0x3 { +# DWARF-NEXT: Tag: DW_TAG_structure_type +# DWARF-NEXT: DW_IDX_die_offset: DW_FORM_ref4 +# DWARF-NEXT: DW_IDX_parent: DW_FORM_flag_present +# DWARF-NEXT: DW_IDX_compile_unit: DW_FORM_data1 +# DWARF: Abbreviation 0x4 { +# DWARF-NEXT: Tag: DW_TAG_subprogram +# DWARF-NEXT: DW_IDX_die_offset: DW_FORM_ref4 +# DWARF-NEXT: DW_IDX_parent: DW_FORM_ref4 +# DWARF-NEXT: DW_IDX_compile_unit: DW_FORM_data1 +# DWARF: Abbreviation 0x5 { +# DWARF-NEXT: Tag: DW_TAG_namespace +# DWARF-NEXT: DW_IDX_die_offset: DW_FORM_ref4 +# DWARF-NEXT: DW_IDX_parent: DW_FORM_flag_present +# DWARF-NEXT: DW_IDX_compile_unit: DW_FORM_data1 +# DWARF: String: 0x00000093 "bar" +# DWARF-NEXT: Entry @ 0xf7 { +# DWARF-NEXT: Abbrev: 0x2 +# DWARF-NEXT: Tag: DW_TAG_subprogram +# DWARF-NEXT: DW_IDX_die_offset: 0x00000023 +# DWARF-NEXT: DW_IDX_parent: +# DWARF-NEXT: DW_IDX_compile_unit: 0x00 +# DWARF: String: 0x000000a9 "int" +# DWARF-NEXT: Entry @ 0xfe { +# DWARF-NEXT: Abbrev: 0x1 +# DWARF-NEXT: Tag: DW_TAG_base_type +# DWARF-NEXT: DW_IDX_die_offset: 0x0000008d +# DWARF-NEXT: DW_IDX_parent: +# DWARF-NEXT: DW_IDX_compile_unit: 0x00 +# DWARF-NEXT: } +# DWARF-NEXT: Entry @ 0x104 { +# DWARF-NEXT: Abbrev: 0x1 +# DWARF-NEXT: Tag: DW_TAG_base_type +# DWARF-NEXT: DW_IDX_die_offset: 0x00000023 +# DWARF-NEXT: DW_IDX_parent: +# DWARF-NEXT: DW_IDX_compile_unit: 0x01 +# DWARF: String: 0x000000ad "foo" +# DWARF-NEXT: Entry @ 0x10b { +# DWARF-NEXT: Abbrev: 0x3 +# DWARF-NEXT: Tag: DW_TAG_structure_type +# DWARF-NEXT: DW_IDX_die_offset: 0x00000096 +# DWARF-NEXT: DW_IDX_parent: +# DWARF-NEXT: DW_IDX_compile_unit: 0x00 +# DWARF-NEXT: } +# DWARF-NEXT: Entry @ 0x111 { +# DWARF-NEXT: Abbrev: 0x2 +# DWARF-NEXT: Tag: DW_TAG_subprogram +# DWARF-NEXT: DW_IDX_die_offset: 0x00000027 +# DWARF-NEXT: DW_IDX_parent: +# DWARF-NEXT: DW_IDX_compile_unit: 0x01 +# DWARF-NEXT: } +# DWARF-NEXT: Entry @ 0x117 { +# DWARF-NEXT: Abbrev: 0x4 +# DWARF-NEXT: Tag: DW_TAG_subprogram +# DWARF-NEXT: DW_IDX_die_offset: 0x00000045 +# DWARF-NEXT: DW_IDX_parent: Entry @ 0x128 +# DWARF-NEXT: DW_IDX_compile_unit: 0x01 +# DWARF-NEXT: } +# DWARF-NEXT: Entry @ 0x121 { +# DWARF-NEXT: Abbrev: 0x3 +# DWARF-NEXT: Tag: DW_TAG_structure_type +# DWARF-NEXT: DW_IDX_die_offset: 0x00000056 +# DWARF-NEXT: DW_IDX_parent: +# DWARF-NEXT: DW_IDX_compile_unit: 0x01 +# DWARF: String: 0x00000196 "parent_test" +# DWARF-NEXT: Entry @ 0x128 { +# DWARF-NEXT: Abbrev: 0x5 +# DWARF-NEXT: Tag: DW_TAG_namespace +# DWARF-NEXT: DW_IDX_die_offset: 0x00000043 +# DWARF-NEXT: DW_IDX_parent: +# DWARF-NEXT: DW_IDX_compile_unit: 0x01 +# DWARF: String: 0x00000097 "_Z3barR3fooi" +# DWARF-NEXT: Entry @ 0x12f { +# DWARF-NEXT: Abbrev: 0x2 +# DWARF-NEXT: Tag: DW_TAG_subprogram +# DWARF-NEXT: DW_IDX_die_offset: 0x00000023 +# DWARF-NEXT: DW_IDX_parent: +# DWARF-NEXT: DW_IDX_compile_unit: 0x00 +# DWARF: String: 0x000000a4 "main" +# DWARF-NEXT: Entry @ 0x136 { +# DWARF-NEXT: Abbrev: 0x2 +# DWARF-NEXT: Tag: DW_TAG_subprogram +# DWARF-NEXT: DW_IDX_die_offset: 0x00000046 +# DWARF-NEXT: DW_IDX_parent: +# DWARF-NEXT: DW_IDX_compile_unit: 0x00 +# DWARF: String: 0x000000b5 "char" +# DWARF-NEXT: Entry @ 0x13d { +# DWARF-NEXT: Abbrev: 0x1 +# DWARF-NEXT: Tag: DW_TAG_base_type +# DWARF-NEXT: DW_IDX_die_offset: 0x000000b8 +# DWARF-NEXT: DW_IDX_parent: +# DWARF-NEXT: DW_IDX_compile_unit: 0x00 +# DWARF-NEXT: } +# DWARF-NEXT: Entry @ 0x143 { +# DWARF-NEXT: Abbrev: 0x1 +# DWARF-NEXT: Tag: DW_TAG_base_type +# DWARF-NEXT: DW_IDX_die_offset: 0x00000078 +# DWARF-NEXT: DW_IDX_parent: +# DWARF-NEXT: DW_IDX_compile_unit: 0x01 +# DWARF: String: 0x000001a2 "_ZN11parent_test3fooEv" +# DWARF-NEXT: Entry @ 0x14a { +# DWARF-NEXT: Abbrev: 0x4 +# DWARF-NEXT: Tag: DW_TAG_subprogram +# DWARF-NEXT: DW_IDX_die_offset: 0x00000045 +# DWARF-NEXT: DW_IDX_parent: Entry @ 0x128 +# DWARF-NEXT: DW_IDX_compile_unit: 0x01 +# DWARF: String: 0x0000018e "_Z3foov" +# DWARF-NEXT: Entry @ 0x155 { +# DWARF-NEXT: Abbrev: 0x2 +# DWARF-NEXT: Tag: DW_TAG_subprogram +# DWARF-NEXT: DW_IDX_die_offset: 0x00000027 +# DWARF-NEXT: DW_IDX_parent: +# DWARF-NEXT: DW_IDX_compile_unit: 0x01 + +#-- input file: debug-names-parent-idx.cpp +## Generated with: +## +## - clang++ -g -O0 -gpubnames -fdebug-compilation-dir='parent-idx-test' \ +## -S debug-names-parent-idx.cpp -o debug-names-parent-idx.s +## +## foo.h contents: +## +## int foo(); +## +## struct foo { +## int x; +## char y; +## struct foo *foo_ptr; +## }; +## +## namespace parent_test { +## int foo(); +## } +## +## debug-names-parent-idx.cpp contents: +## +## #include "foo.h" +## void bar (struct foo &foo, int junk) { +## foo.x = foo.x * junk; +## } +## int main (int argc, char** argv) { +## struct foo my_struct; +## my_struct.x = 10; +## my_struct.y = 'q'; +## my_struct.foo_ptr = nullptr; +## int junk = foo(); +## bar(my_struct, junk); +## int junk2 = parent_test::foo(); +## return 0; +## } +## + .text + .globl _Z3barR3fooi # -- Begin function _Z3barR3fooi + .p2align 4, 0x90 + .type _Z3barR3fooi,@function +_Z3barR3fooi: # @_Z3barR3fooi +.Lfunc_begin0: + .cfi_startproc +# %bb.0: # %entry + pushq %rbp + .cfi_def_cfa_offset 16 + .cfi_offset %rbp, -16 + movq %rsp, %rbp + .cfi_def_cfa_register %rbp + movq %rdi, -8(%rbp) + movl %esi, -12(%rbp) +.Ltmp0: + movq -8(%rbp), %rax + movl (%rax), %ecx + imull -12(%rbp), %ecx + movq -8(%rbp), %rax + movl %ecx, (%rax) + popq %rbp + .cfi_def_cfa %rsp, 8 + retq +.Ltmp1: +.Lfunc_end0: + .size _Z3barR3fooi, .Lfunc_end0-_Z3barR3fooi + .cfi_endproc + # -- End function + .globl main # -- Begin function main + .p2align 4, 0x90 + .type main,@function +main: # @main +.Lfunc_begin1: + .cfi_startproc +# %bb.0: # %entry + pushq %rbp + .cfi_def_cfa_offset 16 + .cfi_offset %rbp, -16 + movq %rsp, %rbp + .cfi_def_cfa_register %rbp + subq $48, %rsp + movl $0, -4(%rbp) + movl %edi, -8(%rbp) + movq %rsi, -16(%rbp) +.Ltmp2: + movl $10, -32(%rbp) + movb $113, -28(%rbp) + movq $0, -24(%rbp) + callq _Z3foov@PLT + movl %eax, -36(%rbp) + movl -36(%rbp), %esi + leaq -32(%rbp), %rdi + callq _Z3barR3fooi + callq _ZN11parent_test3fooEv@PLT + movl %eax, -40(%rbp) + xorl %eax, %eax + addq $48, %rsp + popq %rbp + .cfi_def_cfa %rsp, 8 + retq +.Ltmp3: +.Lfunc_end1: + .size main, .Lfunc_end1-main + .cfi_endproc + # -- End function + .section .debug_abbrev,"",@progbits + .byte 0 # EOM(1) + .byte 0 # EOM(2) + .byte 0 # EOM(3) + .section .debug_info,"",@progbits +.Lcu_begin0: + .long .Ldebug_info_end0-.Ldebug_info_start0 # Length of Unit +.Ldebug_info_start0: + .short 5 # DWARF version number + .byte 1 # DWARF Unit Type + .byte 8 # Address Size (in bytes) + .long .debug_abbrev # Offset Into Abbrev. Section + .byte 1 # Abbrev [1] 0xc:0xc0 DW_TAG_compile_unit + .byte 0 # DW_AT_producer + .short 33 # DW_AT_language + .byte 1 # DW_AT_name + .long .Lstr_offsets_base0 # DW_AT_str_offsets_base + .long .Lline_table_start0 # DW_AT_stmt_list + .byte 2 # DW_AT_comp_dir + .byte 0 # DW_AT_low_pc + .long .Lfunc_end1-.Lfunc_begin0 # DW_AT_high_pc + .long .Laddr_table_base0 # DW_AT_addr_base + .byte 2 # Abbrev [2] 0x23:0x23 DW_TAG_subprogram + .byte 0 # DW_AT_low_pc + .long .Lfunc_end0-.Lfunc_begin0 # DW_AT_high_pc + .byte 1 # DW_AT_frame_base + .byte 86 + .byte 3 # DW_AT_linkage_name + .byte 4 # DW_AT_name + .byte 0 # DW_AT_decl_file + .byte 3 # DW_AT_decl_line + # DW_AT_external + .byte 3 # Abbrev [3] 0x2f:0xb DW_TAG_formal_parameter + .byte 2 # DW_AT_location + .byte 145 + .byte 120 + .byte 7 # DW_AT_name + .byte 0 # DW_AT_decl_file + .byte 3 # DW_AT_decl_line + .long 145 # DW_AT_type + .byte 3 # Abbrev [3] 0x3a:0xb DW_TAG_formal_parameter + .byte 2 # DW_AT_location + .byte 145 + .byte 116 + .byte 12 # DW_AT_name + .byte 0 # DW_AT_decl_file + .byte 3 # DW_AT_decl_line + .long 141 # DW_AT_type + .byte 0 # End Of Children Mark + .byte 4 # Abbrev [4] 0x46:0x47 DW_TAG_subprogram + .byte 1 # DW_AT_low_pc + .long .Lfunc_end1-.Lfunc_begin1 # DW_AT_high_pc + .byte 1 # DW_AT_frame_base + .byte 86 + .byte 5 # DW_AT_name + .byte 0 # DW_AT_decl_file + .byte 7 # DW_AT_decl_line + .long 141 # DW_AT_type + # DW_AT_external + .byte 3 # Abbrev [3] 0x55:0xb DW_TAG_formal_parameter + .byte 2 # DW_AT_location + .byte 145 + .byte 120 + .byte 13 # DW_AT_name + .byte 0 # DW_AT_decl_file + .byte 7 # DW_AT_decl_line + .long 141 # DW_AT_type + .byte 3 # Abbrev [3] 0x60:0xb DW_TAG_formal_parameter + .byte 2 # DW_AT_location + .byte 145 + .byte 112 + .byte 14 # DW_AT_name + .byte 0 # DW_AT_decl_file + .byte 7 # DW_AT_decl_line + .long 193 # DW_AT_type + .byte 5 # Abbrev [5] 0x6b:0xb DW_TAG_variable + .byte 2 # DW_AT_location + .byte 145 + .byte 96 + .byte 15 # DW_AT_name + .byte 0 # DW_AT_decl_file + .byte 9 # DW_AT_decl_line + .long 150 # DW_AT_type + .byte 5 # Abbrev [5] 0x76:0xb DW_TAG_variable + .byte 2 # DW_AT_location + .byte 145 + .byte 92 + .byte 12 # DW_AT_name + .byte 0 # DW_AT_decl_file + .byte 14 # DW_AT_decl_line + .long 141 # DW_AT_type + .byte 5 # Abbrev [5] 0x81:0xb DW_TAG_variable + .byte 2 # DW_AT_location + .byte 145 + .byte 88 + .byte 16 # DW_AT_name + .byte 0 # DW_AT_decl_file + .byte 16 # DW_AT_decl_line + .long 141 # DW_AT_type + .byte 0 # End Of Children Mark + .byte 6 # Abbrev [6] 0x8d:0x4 DW_TAG_base_type + .byte 6 # DW_AT_name + .byte 5 # DW_AT_encoding + .byte 4 # DW_AT_byte_size + .byte 7 # Abbrev [7] 0x91:0x5 DW_TAG_reference_type + .long 150 # DW_AT_type + .byte 8 # Abbrev [8] 0x96:0x22 DW_TAG_structure_type + .byte 5 # DW_AT_calling_convention + .byte 7 # DW_AT_name + .byte 16 # DW_AT_byte_size + .byte 1 # DW_AT_decl_file + .byte 4 # DW_AT_decl_line + .byte 9 # Abbrev [9] 0x9c:0x9 DW_TAG_member + .byte 8 # DW_AT_name + .long 141 # DW_AT_type + .byte 1 # DW_AT_decl_file + .byte 5 # DW_AT_decl_line + .byte 0 # DW_AT_data_member_location + .byte 9 # Abbrev [9] 0xa5:0x9 DW_TAG_member + .byte 9 # DW_AT_name + .long 184 # DW_AT_type + .byte 1 # DW_AT_decl_file + .byte 6 # DW_AT_decl_line + .byte 4 # DW_AT_data_member_location + .byte 9 # Abbrev [9] 0xae:0x9 DW_TAG_member + .byte 11 # DW_AT_name + .long 188 # DW_AT_type + .byte 1 # DW_AT_decl_file + .byte 7 # DW_AT_decl_line + .byte 8 # DW_AT_data_member_location + .byte 0 # End Of Children Mark + .byte 6 # Abbrev [6] 0xb8:0x4 DW_TAG_base_type + .byte 10 # DW_AT_name + .byte 6 # DW_AT_encoding + .byte 1 # DW_AT_byte_size + .byte 10 # Abbrev [10] 0xbc:0x5 DW_TAG_pointer_type + .long 150 # DW_AT_type + .byte 10 # Abbrev [10] 0xc1:0x5 DW_TAG_pointer_type + .long 198 # DW_AT_type + .byte 10 # Abbrev [10] 0xc6:0x5 DW_TAG_pointer_type + .long 184 # DW_AT_type + .byte 0 # End Of Children Mark +.Ldebug_info_end0: + .section .debug_str_offsets,"",@progbits + .long 72 # Length of String Offsets Set + .short 5 + .short 0 +.Lstr_offsets_base0: + .section .debug_str,"MS",@progbits,1 +.Linfo_string0: + .asciz "clang version 19.0.0git (git@github.com:llvm/llvm-project.git 4df364bc93af49ae413ec1ae8328f34ac70730c4)" # string offset=0 +.Linfo_string1: + .asciz "debug-names-parent-idx.cpp" # string offset=104 +.Linfo_string2: + .asciz "parent-idx-test" # string offset=131 +.Linfo_string3: + .asciz "bar" # string offset=147 +.Linfo_string4: + .asciz "_Z3barR3fooi" # string offset=151 +.Linfo_string5: + .asciz "main" # string offset=164 +.Linfo_string6: + .asciz "int" # string offset=169 +.Linfo_string7: + .asciz "foo" # string offset=173 +.Linfo_string8: + .asciz "x" # string offset=177 +.Linfo_string9: + .asciz "y" # string offset=179 +.Linfo_string10: + .asciz "char" # string offset=181 +.Linfo_string11: + .asciz "foo_ptr" # string offset=186 +.Linfo_string12: + .asciz "junk" # string offset=194 +.Linfo_string13: + .asciz "argc" # string offset=199 +.Linfo_string14: + .asciz "argv" # string offset=204 +.Linfo_string15: + .asciz "my_struct" # string offset=209 +.Linfo_string16: + .asciz "junk2" # string offset=219 +.Laddr_table_base0: + .quad .Lfunc_begin0 + .quad .Lfunc_begin1 +.Ldebug_addr_end0: + .section .debug_names,"",@progbits + .long .Lnames_end0-.Lnames_start0 # Header: unit length +.Lnames_start0: + .short 5 # Header: version + .short 0 # Header: padding + .long 1 # Header: compilation unit count + .long 0 # Header: local type unit count + .long 0 # Header: foreign type unit count + .long 6 # Header: bucket count + .long 6 # Header: name count + .long .Lnames_abbrev_end0-.Lnames_abbrev_start0 # Header: abbreviation table size + .long 8 # Header: augmentation string size + .ascii "LLVM0700" # Header: augmentation string + .long .Lcu_begin0 # Compilation unit 0 + .long 1 # Bucket 0 + .long 0 # Bucket 1 + .long 2 # Bucket 2 + .long 4 # Bucket 3 + .long 5 # Bucket 4 + .long 6 # Bucket 5 + .long 193487034 # Hash in Bucket 0 + .long 193495088 # Hash in Bucket 2 + .long 1358986904 # Hash in Bucket 2 + .long 193491849 # Hash in Bucket 3 + .long 2090499946 # Hash in Bucket 4 + .long 2090147939 # Hash in Bucket 5 + .long .Linfo_string3 # String in Bucket 0: bar + .long .Linfo_string6 # String in Bucket 2: int + .long .Linfo_string4 # String in Bucket 2: _Z3barR3fooi + .long .Linfo_string7 # String in Bucket 3: foo + .long .Linfo_string5 # String in Bucket 4: main + .long .Linfo_string10 # String in Bucket 5: char + .long .Lnames0-.Lnames_entries0 # Offset in Bucket 0 + .long .Lnames3-.Lnames_entries0 # Offset in Bucket 2 + .long .Lnames1-.Lnames_entries0 # Offset in Bucket 2 + .long .Lnames4-.Lnames_entries0 # Offset in Bucket 3 + .long .Lnames2-.Lnames_entries0 # Offset in Bucket 4 + .long .Lnames5-.Lnames_entries0 # Offset in Bucket 5 +.Lnames_abbrev_start0: + .byte 1 # Abbrev code + .byte 46 # DW_TAG_subprogram + .byte 3 # DW_IDX_die_offset + .byte 19 # DW_FORM_ref4 + .byte 4 # DW_IDX_parent + .byte 25 # DW_FORM_flag_present + .byte 0 # End of abbrev + .byte 0 # End of abbrev + .byte 2 # Abbrev code + .byte 36 # DW_TAG_base_type + .byte 3 # DW_IDX_die_offset + .byte 19 # DW_FORM_ref4 + .byte 4 # DW_IDX_parent + .byte 25 # DW_FORM_flag_present + .byte 0 # End of abbrev + .byte 0 # End of abbrev + .byte 3 # Abbrev code + .byte 19 # DW_TAG_structure_type + .byte 3 # DW_IDX_die_offset + .byte 19 # DW_FORM_ref4 + .byte 4 # DW_IDX_parent + .byte 25 # DW_FORM_flag_present + .byte 0 # End of abbrev + .byte 0 # End of abbrev + .byte 0 # End of abbrev list +.Lnames_abbrev_end0: +.Lnames_entries0: +.Lnames0: +.L2: + .byte 1 # Abbreviation code + .long 35 # DW_IDX_die_offset + .byte 0 # DW_IDX_parent + # End of list: bar +.Lnames3: +.L1: + .byte 2 # Abbreviation code + .long 141 # DW_IDX_die_offset + .byte 0 # DW_IDX_parent + # End of list: int +.Lnames1: + .byte 1 # Abbreviation code + .long 35 # DW_IDX_die_offset + .byte 0 # DW_IDX_parent + # End of list: _Z3barR3fooi +.Lnames4: +.L4: + .byte 3 # Abbreviation code + .long 150 # DW_IDX_die_offset + .byte 0 # DW_IDX_parent + # End of list: foo +.Lnames2: +.L0: + .byte 1 # Abbreviation code + .long 70 # DW_IDX_die_offset + .byte 0 # DW_IDX_parent + # End of list: main +.Lnames5: +.L3: + .byte 2 # Abbreviation code + .long 184 # DW_IDX_die_offset + .byte 0 # DW_IDX_parent + # End of list: char + .p2align 2, 0x0 +.Lnames_end0: + .ident "clang version 19.0.0git (git@github.com:llvm/llvm-project.git 4df364bc93af49ae413ec1ae8328f34ac70730c4)" + .section ".note.GNU-stack","",@progbits + .addrsig + .addrsig_sym _Z3barR3fooi + .addrsig_sym _Z3foov + .addrsig_sym _ZN11parent_test3fooEv + .section .debug_line,"",@progbits +.Lline_table_start0: diff --git a/lld/test/ELF/debug-names.s b/lld/test/ELF/debug-names.s new file mode 100644 index 0000000000000..ce013303f65f6 --- /dev/null +++ b/lld/test/ELF/debug-names.s @@ -0,0 +1,294 @@ +# REQUIRES: x86 +# RUN: llvm-mc -filetype=obj -triple=x86_64 %s -o %t1.o +# RUN: llvm-mc -filetype=obj -triple=x86_64 %p/Inputs/debug-names-2.s -o %t2.o +# RUN: ld.lld --debug-names %t1.o %t2.o -o %t + +# RUN: llvm-objdump -d %t | FileCheck %s --check-prefix=DISASM +# RUN: llvm-dwarfdump -debug-names %t | FileCheck %s --check-prefix=DWARF +# RUN: llvm-readelf -SW %t | FileCheck %s --check-prefix=READELF + +# DISASM: Disassembly of section .text: +# DISASM-EMPTY: +# DISASM: <_Z2f12t1>: +# DISASM-CHECK: 201180: 55 pushq %rbp +# DISASM-CHECK: 201181: 48 89 e5 movq %rsp, %rbp +# DISASM-CHECK: 201184: 5d popq %rbp +# DISASM-CHECK: 201185: c3 retq +# DISASM-CHECK: 201186: cc int3 +# DISASM-CHECK: 201187: cc int3 +# DISASM-CHECK: 201188: cc int3 +# DISASM-CHECK: 201189: cc int3 +# DISASM-CHECK: 20118a: cc int3 +# DISASM-CHECK: 20118b: cc int3 +# DISASM-CHECK: 20118c: cc int3 +# DISASM-CHECK: 20118d: cc int3 +# DISASM-CHECK: 20118e: cc int3 +# DISASM-CHECK: 20118f: cc int3 +# DISASM:
: +# DISASM-CHECK: 201190: 55 pushq %rbp +# DISASM-CHECK: 201191: 48 89 e5 movq %rsp, %rbp +# DISASM-CHECK: 201194: 31 c0 xorl %eax, %eax +# DISASM-CHECK: 201196: 5d popq %rbp +# DISASM-CHECK: 201197: c3 retq + +# DWARF: .debug_names contents: +# DWARF: Name Index @ 0x0 { +# DWARF-NEXT: Header { +# DWARF-NEXT: Length: 0xCC +# DWARF-NEXT: Format: DWARF32 +# DWARF-NEXT: Version: 5 +# DWARF-NEXT: CU count: 2 +# DWARF-NEXT: Local TU count: 0 +# DWARF-NEXT: Foreign TU count: 0 +# DWARF-NEXT: Bucket count: 5 +# DWARF-NEXT: Name count: 5 +# DWARF-NEXT: Abbreviations table size: 0x1F +# DWARF-NEXT: Augmentation: 'LLVM0700' +# DWARF: Compilation Unit offsets [ +# DWARF-NEXT: CU[0]: 0x00000000 +# DWARF-NEXT: CU[1]: 0x00000041 +# DWARF: Abbreviations [ +# DWARF-NEXT: Abbreviation 0x1 { +# DWARF: Tag: DW_TAG_structure_type +# DWARF-NEXT: DW_IDX_die_offset: DW_FORM_ref4 +# DWARF-NEXT: DW_IDX_parent: DW_FORM_flag_present +# DWARF-NEXT: DW_IDX_compile_unit: DW_FORM_data1 +# DWARF: Abbreviation 0x2 { +# DWARF-NEXT: Tag: DW_TAG_subprogram +# DWARF-NEXT: DW_IDX_die_offset: DW_FORM_ref4 +# DWARF-NEXT: DW_IDX_parent: DW_FORM_flag_present +# DWARF-NEXT: DW_IDX_compile_unit: DW_FORM_data1 +# DWARF: Abbreviation 0x3 { +# DWARF-NEXT: Tag: DW_TAG_base_type +# DWARF-NEXT: DW_IDX_die_offset: DW_FORM_ref4 +# DWARF-NEXT: DW_IDX_parent: DW_FORM_flag_present +# DWARF-NEXT: DW_IDX_compile_unit: DW_FORM_data1 +# DWARF: Bucket 0 [ +# DWARF: Bucket 1 [ +# DWARF: String: 0x00000089 "f1" +# DWARF-NEXT: Entry @ 0xa3 { +# DWARF-NEXT: Abbrev: 0x2 +# DWARF-NEXT: Tag: DW_TAG_subprogram +# DWARF-NEXT: DW_IDX_die_offset: 0x00000023 +# DWARF-NEXT: DW_IDX_parent: +# DWARF-NEXT: DW_IDX_compile_unit: 0x00 +# DWARF: String: 0x00000095 "t1" +# DWARF-NEXT: Entry @ 0xaa { +# DWARF-NEXT: Abbrev: 0x1 +# DWARF-NEXT: Tag: DW_TAG_structure_type +# DWARF-NEXT: DW_IDX_die_offset: 0x0000003a +# DWARF-NEXT: DW_IDX_parent: +# DWARF-NEXT: DW_IDX_compile_unit: 0x00 +# DWARF-NEXT: } +# DWARF-NEXT: Entry @ 0xb0 { +# DWARF-NEXT: Abbrev: 0x1 +# DWARF-NEXT: Tag: DW_TAG_structure_type +# DWARF-NEXT: DW_IDX_die_offset: 0x00000042 +# DWARF-NEXT: DW_IDX_parent: +# DWARF-NEXT: DW_IDX_compile_unit: 0x01 +# DWARF: String: 0x00000130 "int" +# DWARF-NEXT: Entry @ 0xb7 { +# DWARF-NEXT: Abbrev: 0x3 +# DWARF-NEXT: Tag: DW_TAG_base_type +# DWARF-NEXT: DW_IDX_die_offset: 0x0000003e +# DWARF-NEXT: DW_IDX_parent: +# DWARF-NEXT: DW_IDX_compile_unit: 0x01 +# DWARF: Bucket 2 [ +# DWARF: Bucket 3 [ +# DWARF: String: 0x0000008c "_Z2f12t1" +# DWARF-NEXT: Entry @ 0xbe { +# DWARF-NEXT: Abbrev: 0x2 +# DWARF-NEXT: Tag: DW_TAG_subprogram +# DWARF-NEXT: DW_IDX_die_offset: 0x00000023 +# DWARF-NEXT: DW_IDX_parent: +# DWARF-NEXT: DW_IDX_compile_unit: 0x00 +# DWARF: Bucket 4 [ +# DWARF: String: 0x0000012b "main" +# DWARF-NEXT: Entry @ 0xc5 { +# DWARF-NEXT: Abbrev: 0x2 +# DWARF-NEXT: Tag: DW_TAG_subprogram +# DWARF-NEXT: DW_IDX_die_offset: 0x00000023 +# DWARF-NEXT: DW_IDX_parent: +# DWARF-NEXT: DW_IDX_compile_unit: 0x01 + +# READELF: .debug_names PROGBITS 0000000000000000 0003eb 0000d0 + +# RUN: ld.lld --debug-names --no-debug-names %t1.o %t2.o -o %t +# RUN: llvm-readelf -SW %t | FileCheck %s --check-prefix=NO_DBG_NAMES + + +# NO_DBG_NAMES: .debug_names PROGBITS 0000000000000000 00037c 000110 + +#-- input file: debug-names.cpp +## Generated with: +## +## - clang++ -g -O0 -gpubnames -fdebug-compilation-dir='debug-names-test' \ +## -S debug-names.cpp -o debug-names.s +## +## debug-names.cpp contents: +## +## struct t1 { }; +## void f1(t1) { } +## +## + .text + .globl _Z2f12t1 # -- Begin function _Z2f12t1 + .p2align 4, 0x90 + .type _Z2f12t1,@function +_Z2f12t1: # @_Z2f12t1 +.Lfunc_begin0: + .cfi_startproc +# %bb.0: # %entry + pushq %rbp + .cfi_def_cfa_offset 16 + .cfi_offset %rbp, -16 + movq %rsp, %rbp + .cfi_def_cfa_register %rbp +.Ltmp0: + popq %rbp + .cfi_def_cfa %rsp, 8 + retq +.Ltmp1: +.Lfunc_end0: + .size _Z2f12t1, .Lfunc_end0-_Z2f12t1 + .cfi_endproc + # -- End function + .section .debug_abbrev,"",@progbits + .byte 0 # EOM(1) + .byte 0 # EOM(2) + .byte 0 # EOM(3) + .section .debug_info,"",@progbits +.Lcu_begin0: + .long .Ldebug_info_end0-.Ldebug_info_start0 # Length of Unit +.Ldebug_info_start0: + .short 5 # DWARF version number + .byte 1 # DWARF Unit Type + .byte 8 # Address Size (in bytes) + .long .debug_abbrev # Offset Into Abbrev. Section + .byte 1 # Abbrev [1] 0xc:0x35 DW_TAG_compile_unit + .byte 0 # DW_AT_producer + .short 33 # DW_AT_language + .byte 1 # DW_AT_name + .long .Lstr_offsets_base0 # DW_AT_str_offsets_base + .long .Lline_table_start0 # DW_AT_stmt_list + .byte 2 # DW_AT_comp_dir + .byte 0 # DW_AT_low_pc + .long .Lfunc_end0-.Lfunc_begin0 # DW_AT_high_pc + .long .Laddr_table_base0 # DW_AT_addr_base + .byte 2 # Abbrev [2] 0x23:0x17 DW_TAG_subprogram + .byte 0 # DW_AT_low_pc + .long .Lfunc_end0-.Lfunc_begin0 # DW_AT_high_pc + .byte 1 # DW_AT_frame_base + .byte 86 + .byte 3 # DW_AT_linkage_name + .byte 4 # DW_AT_name + .byte 0 # DW_AT_decl_file + .byte 2 # DW_AT_decl_line + # DW_AT_external + .byte 3 # Abbrev [3] 0x2f:0xa DW_TAG_formal_parameter + .byte 2 # DW_AT_location + .byte 145 + .byte 127 + .byte 0 # DW_AT_decl_file + .byte 2 # DW_AT_decl_line + .long 58 # DW_AT_type + .byte 0 # End Of Children Mark + .byte 4 # Abbrev [4] 0x3a:0x6 DW_TAG_structure_type + .byte 5 # DW_AT_calling_convention + .byte 5 # DW_AT_name + .byte 1 # DW_AT_byte_size + .byte 0 # DW_AT_decl_file + .byte 1 # DW_AT_decl_line + .byte 0 # End Of Children Mark +.Ldebug_info_end0: + .section .debug_str_offsets,"",@progbits + .long 28 # Length of String Offsets Set + .short 5 + .short 0 +.Lstr_offsets_base0: + .section .debug_str,"MS",@progbits,1 +.Linfo_string0: + .asciz "clang version 19.0.0git (git@github.com:llvm/llvm-project.git 4df364bc93af49ae413ec1ae8328f34ac70730c4)" # string offset=0 +.Linfo_string1: + .asciz "debug-names.cpp" # string offset=104 +.Linfo_string2: + .asciz "debug-names-test" # string offset=120 +.Linfo_string3: + .asciz "f1" # string offset=137 +.Linfo_string4: + .asciz "_Z2f12t1" # string offset=140 +.Linfo_string5: + .asciz "t1" # string offset=149 +.Laddr_table_base0: + .quad .Lfunc_begin0 +.Ldebug_addr_end0: + .section .debug_names,"",@progbits + .long .Lnames_end0-.Lnames_start0 # Header: unit length +.Lnames_start0: + .short 5 # Header: version + .short 0 # Header: padding + .long 1 # Header: compilation unit count + .long 0 # Header: local type unit count + .long 0 # Header: foreign type unit count + .long 3 # Header: bucket count + .long 3 # Header: name count + .long .Lnames_abbrev_end0-.Lnames_abbrev_start0 # Header: abbreviation table size + .long 8 # Header: augmentation string size + .ascii "LLVM0700" # Header: augmentation string + .long .Lcu_begin0 # Compilation unit 0 + .long 0 # Bucket 0 + .long 1 # Bucket 1 + .long 3 # Bucket 2 + .long 5863324 # Hash in Bucket 1 + .long 5863786 # Hash in Bucket 1 + .long 1398125246 # Hash in Bucket 2 + .long .Linfo_string3 # String in Bucket 1: f1 + .long .Linfo_string5 # String in Bucket 1: t1 + .long .Linfo_string4 # String in Bucket 2: _Z2f12t1 + .long .Lnames0-.Lnames_entries0 # Offset in Bucket 1 + .long .Lnames2-.Lnames_entries0 # Offset in Bucket 1 + .long .Lnames1-.Lnames_entries0 # Offset in Bucket 2 +.Lnames_abbrev_start0: + .byte 1 # Abbrev code + .byte 46 # DW_TAG_subprogram + .byte 3 # DW_IDX_die_offset + .byte 19 # DW_FORM_ref4 + .byte 4 # DW_IDX_parent + .byte 25 # DW_FORM_flag_present + .byte 0 # End of abbrev + .byte 0 # End of abbrev + .byte 2 # Abbrev code + .byte 19 # DW_TAG_structure_type + .byte 3 # DW_IDX_die_offset + .byte 19 # DW_FORM_ref4 + .byte 4 # DW_IDX_parent + .byte 25 # DW_FORM_flag_present + .byte 0 # End of abbrev + .byte 0 # End of abbrev + .byte 0 # End of abbrev list +.Lnames_abbrev_end0: +.Lnames_entries0: +.Lnames0: +.L1: + .byte 1 # Abbreviation code + .long 35 # DW_IDX_die_offset + .byte 0 # DW_IDX_parent + # End of list: f1 +.Lnames2: +.L0: + .byte 2 # Abbreviation code + .long 58 # DW_IDX_die_offset + .byte 0 # DW_IDX_parent + # End of list: t1 +.Lnames1: + .byte 1 # Abbreviation code + .long 35 # DW_IDX_die_offset + .byte 0 # DW_IDX_parent + # End of list: _Z2f12t1 + .p2align 2, 0x0 +.Lnames_end0: + .ident "clang version 19.0.0git (git@github.com:llvm/llvm-project.git 4df364bc93af49ae413ec1ae8328f34ac70730c4)" + .section ".note.GNU-stack","",@progbits + .addrsig + .section .debug_line,"",@progbits +.Lline_table_start0: From 46339e6451baeb8d582226cfc206bbe76d597035 Mon Sep 17 00:00:00 2001 From: Caroline Tice Date: Mon, 25 Mar 2024 19:48:29 -0700 Subject: [PATCH 02/37] [lld][ELF] Implement merged .debug_names section. Fix two typos in test cases. --- lld/test/ELF/debug-names-bad-aug-string.s | 2 +- lld/test/ELF/debug-names-bad-version.s | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/lld/test/ELF/debug-names-bad-aug-string.s b/lld/test/ELF/debug-names-bad-aug-string.s index edf79f0fde577..ec1651362497e 100644 --- a/lld/test/ELF/debug-names-bad-aug-string.s +++ b/lld/test/ELF/debug-names-bad-aug-string.s @@ -1,6 +1,6 @@ # REQUIRES: x86 # RUN: llvm-mc -filetype=obj -triple=x86_64 %s -o %t1.o -# RUN: llvm-mc -filetype=obj -triple=x86_64 %p/Inputs/debug-names-2.s -o %t2 +# RUN: llvm-mc -filetype=obj -triple=x86_64 %p/Inputs/debug-names-2.s -o %t2.o # RUN: ld.lld --debug-names %t1.o %t2.o -o %t # RUN: llvm-dwarfdump -debug-names %t | FileCheck %s --check-prefix=DWARF diff --git a/lld/test/ELF/debug-names-bad-version.s b/lld/test/ELF/debug-names-bad-version.s index f3914670af94a..bf1855151c20d 100644 --- a/lld/test/ELF/debug-names-bad-version.s +++ b/lld/test/ELF/debug-names-bad-version.s @@ -1,6 +1,6 @@ # REQUIRES: x86 # RUN: llvm-mc -filetype=obj -triple=x86_64 %s -o %t1.o -# RUN: llvm-mc -filetype=obj -triple=x86_64 %p/Inputs/debug-names-2.s -o %t2 +# RUN: llvm-mc -filetype=obj -triple=x86_64 %p/Inputs/debug-names-2.s -o %t2.o # # RUN: not ld.lld --debug-names %t1.o %t2.o -o /dev/null 2>&1 | FileCheck %s # From a90417463d3819c3c7bc5b10b7fc3e36caf48dc9 Mon Sep 17 00:00:00 2001 From: Caroline Tice Date: Mon, 25 Mar 2024 23:38:38 -0700 Subject: [PATCH 03/37] [lld][ELF] Implement merged .debug_names section. Clean up some error checking and reporting, and add some new tests. --- lld/ELF/SyntheticSections.cpp | 52 +++--- lld/test/ELF/debug-names-dwarf64.s | 151 +++++++++++++++++ .../ELF/debug-names-invalid-abbrev-code.s | 151 +++++++++++++++++ .../ELF/debug-names-invalid-attribute-2.s | 150 +++++++++++++++++ .../ELF/debug-names-invalid-attribute-3.s | 154 ++++++++++++++++++ lld/test/ELF/debug-names-invalid-parent-idx.s | 153 +++++++++++++++++ 6 files changed, 788 insertions(+), 23 deletions(-) create mode 100644 lld/test/ELF/debug-names-dwarf64.s create mode 100644 lld/test/ELF/debug-names-invalid-abbrev-code.s create mode 100644 lld/test/ELF/debug-names-invalid-attribute-2.s create mode 100644 lld/test/ELF/debug-names-invalid-attribute-3.s create mode 100644 lld/test/ELF/debug-names-invalid-parent-idx.s diff --git a/lld/ELF/SyntheticSections.cpp b/lld/ELF/SyntheticSections.cpp index d440410faa54f..bc3083141f766 100644 --- a/lld/ELF/SyntheticSections.cpp +++ b/lld/ELF/SyntheticSections.cpp @@ -2877,42 +2877,36 @@ bool DebugNamesSection::isNeeded() const { return numChunks > 0; } template static void readCompileUnitOffsets(struct DebugNamesSection::DebugNamesSectionData &secData, - DebugNamesSection::DebugNamesInputChunk &inputChunk, DebugNamesSection::DebugNamesOutputChunk &outputChunk, llvm::DWARFDataExtractor &namesExtractor) { uint64_t offset = secData.locs.CUsBase; uint64_t *offsetPtr = &offset; for (size_t i = 0; i < secData.hdr.CompUnitCount; ++i) { llvm::Error err = llvm::Error::success(); + // This call to namesExtractor can't fail; if there were a problem with the + // input, it would have been caught in the call to NamesIndex::extract, in + // DebugNamesSection::create. uint32_t value = namesExtractor.getU32(offsetPtr, &err); - if (err) - errorOrWarn(toString(inputChunk.namesSection->sec) + - ": error reading CU offsets: " + toString(std::move(err))); - else - outputChunk.compilationUnits.push_back(value); + llvm::cantFail(std::move(err)); + outputChunk.compilationUnits.push_back(value); } } template static void readEntryOffsets(struct DebugNamesSection::DebugNamesSectionData &secData, - DebugNamesSection::DebugNamesInputChunk &chunk, llvm::DWARFDataExtractor &namesExtractor) { secData.entryOffsets = std::make_unique(secData.hdr.NameCount); - if (secData.locs.EntryOffsetsBase >= namesExtractor.getData().size()) - errorOrWarn(toString(chunk.namesSection->sec) + - ": invalid entry offsets input"); - uint64_t offset = secData.locs.EntryOffsetsBase; uint64_t *offsetPtr = &offset; for (size_t i = 0; i < secData.hdr.NameCount; ++i) { llvm::Error err = llvm::Error::success(); + // This call to namesExtractor can't fail; if there were a problem with the + // input, it would have been caught in the call to NamesIndex::extract, in + // DebugNamesSection::create. uint32_t value = namesExtractor.getU32(offsetPtr, &err); - if (err) - errorOrWarn(toString(chunk.namesSection->sec) + - ": error reading entry offsets: " + toString(std::move(err))); - else - secData.entryOffsets.get()[i] = value; + llvm::cantFail(std::move(err)); + secData.entryOffsets.get()[i] = value; } } @@ -2930,11 +2924,17 @@ static void readAttributeValues( llvm::Error err = llvm::Error::success(); DebugNamesSection::AttrValueData newAttr; uint32_t value; + if (attr.Index == DW_IDX_parent && + attr.Form != DW_FORM_flag_present && + attr.Form != DW_FORM_ref4) + errorOrWarn(toString(namesSection.sec) + ": invalid form for DW_IDX_parent"); switch (attr.Form) { case DW_FORM_flag_present: { // Currently only DW_IDX_parent attributes (in .debug_names) can // have this form. This form does not have a real value (nothing is // emitted for it). + if (attr.Index != DW_IDX_parent) + errorOrWarn(toString(namesSection.sec) + ": invalid form for attribute"); break; } case DW_FORM_data1: @@ -3004,10 +3004,11 @@ static void readEntry(DebugNamesSection::NamedEntry &stringEntry, auto entry = std::make_unique(); entry->poolOffset = offset; llvm::Error err = llvm::Error::success(); + // This call to namesExtractor can't fail; if there were a problem with the + // input, it would have been caught in the call to NamesIndex::extract, in + // DebugNamesSection::create. uint64_t ulebValue = namesExtractor.getULEB128(&offset, &err); - if (err) - errorOrWarn(toString(chunk.namesSection->sec) + - ": error reading entry: " + toString(std::move(err))); + llvm::cantFail(std::move(err)); entry->abbrevCode = static_cast(ulebValue); const auto &abbrevs = ni.getAbbrevs(); auto abbrevIt = abbrevs.find_as(entry->abbrevCode); @@ -3016,7 +3017,9 @@ static void readEntry(DebugNamesSection::NamedEntry &stringEntry, readAttributeValues(entry->attrValues, chunk, offset, secData, entry->parentOffset, namesExtractor, abbrev); stringEntry.indexEntries.push_back(std::move(entry)); - } + } else + errorOrWarn(toString(chunk.namesSection->sec) + + ": invalid abbrev code in entry"); } if (offset >= namesSection->Data.size()) errorOrWarn(toString(chunk.namesSection->sec) + @@ -3092,15 +3095,18 @@ static void collectDebugNamesSectionData( for (const auto &ni : *chunk.debugNamesData) { DebugNamesSection::DebugNamesSectionData secData; secData.hdr = ni.getHeader(); - if (secData.hdr.Format != DwarfFormat::DWARF32) + if (secData.hdr.Format != DwarfFormat::DWARF32) { errorOrWarn(toString(chunk.namesSection->sec) + ": unsupported DWARF64"); + // Don't try to continue; we can't parse DWARF64 at the moment. + return; + } secData.dwarfSize = dwarf::getDwarfOffsetByteSize(DwarfFormat::DWARF32); secData.hdrSize = computeDebugNamesHeaderSize(); if (secData.hdr.Version != 5) errorOrWarn(toString(chunk.namesSection->sec) + ": unsupported version"); secData.locs = findDebugNamesOffsets(secData.hdrSize, secData.hdr); - readCompileUnitOffsets(secData, chunk, outputChunk, namesExtractor); - readEntryOffsets(secData, chunk, namesExtractor); + readCompileUnitOffsets(secData, outputChunk, namesExtractor); + readEntryOffsets(secData, namesExtractor); readEntries(secData, chunk, namesExtractor, strExtractor, ni); chunk.sectionsData.push_back(std::move(secData)); } diff --git a/lld/test/ELF/debug-names-dwarf64.s b/lld/test/ELF/debug-names-dwarf64.s new file mode 100644 index 0000000000000..4391142c5558c --- /dev/null +++ b/lld/test/ELF/debug-names-dwarf64.s @@ -0,0 +1,151 @@ +# REQUIRES: x86 +# RUN: llvm-mc -filetype=obj -triple=x86_64 %s -o %t1.o +# +# RUN: not ld.lld --debug-names %t1.o -o /dev/null 2>&1 | FileCheck %s +# +# CHECK: error: {{.*}}(.debug_names): unsupported DWARF64 +## +## This file was generated by: +## clang++ -g -O0 -S -fdebug-compilation-dir='debug-names-test' \ +## -gdwarf64 -gpubnames main.cpp +## +## main.cpp +## int main (int argc, char **argv) { } +## + .text + .globl main # -- Begin function main + .p2align 4, 0x90 + .type main,@function +main: # @main +.Lfunc_begin0: + .cfi_startproc +# %bb.0: # %entry + pushq %rbp + .cfi_def_cfa_offset 16 + .cfi_offset %rbp, -16 + movq %rsp, %rbp + .cfi_def_cfa_register %rbp + movl %edi, -4(%rbp) + movq %rsi, -16(%rbp) +.Ltmp0: + xorl %eax, %eax + popq %rbp + .cfi_def_cfa %rsp, 8 + retq +.Ltmp1: +.Lfunc_end0: + .size main, .Lfunc_end0-main + .cfi_endproc + # -- End function + .section .debug_abbrev,"",@progbits + .byte 0 # EOM(1) + .byte 0 # EOM(2) + .byte 0 # EOM(3) + .section .debug_info,"",@progbits +.Lcu_begin0: + .long 4294967295 # DWARF64 Mark + .quad .Ldebug_info_end0-.Ldebug_info_start0 # Length of Unit +.Ldebug_info_start0: + .short 5 # DWARF version number + .byte 1 # DWARF Unit Type + .byte 8 # Address Size (in bytes) + .quad .debug_abbrev # Offset Into Abbrev. Section +.Ldebug_info_end0: + .section .debug_str_offsets,"",@progbits + .long 4294967295 # DWARF64 Mark + .quad 68 # Length of String Offsets Set + .short 5 + .short 0 +.Lstr_offsets_base0: + .section .debug_str,"MS",@progbits,1 +.Linfo_string0: + .asciz "clang version 19.0.0git (git@github.com:llvm/llvm-project.git 9b37e60051f362e8e22c88785239fd5dfbfdf105)" # string offset=0 +.Linfo_string1: + .asciz "main.cpp" # string offset=104 +.Linfo_string2: + .asciz "debug-names-test" # string offset=113 +.Linfo_string3: + .asciz "main" # string offset=130 +.Linfo_string4: + .asciz "int" # string offset=135 +.Linfo_string5: + .asciz "argc" # string offset=139 +.Linfo_string6: + .asciz "argv" # string offset=144 +.Linfo_string7: + .asciz "char" # string offset=149 +.Laddr_table_base0: + .quad .Lfunc_begin0 +.Ldebug_addr_end0: + .section .debug_names,"",@progbits + .long 4294967295 # DWARF64 Mark + .quad .Lnames_end0-.Lnames_start0 # Header: unit length +.Lnames_start0: + .short 5 # Header: version + .short 0 # Header: padding + .long 1 # Header: compilation unit count + .long 0 # Header: local type unit count + .long 0 # Header: foreign type unit count + .long 3 # Header: bucket count + .long 3 # Header: name count + .long .Lnames_abbrev_end0-.Lnames_abbrev_start0 # Header: abbreviation table size + .long 8 # Header: augmentation string size + .ascii "LLVM0700" # Header: augmentation string + .quad .Lcu_begin0 # Compilation unit 0 + .long 0 # Bucket 0 + .long 1 # Bucket 1 + .long 2 # Bucket 2 + .long 2090499946 # Hash in Bucket 1 + .long 193495088 # Hash in Bucket 2 + .long 2090147939 # Hash in Bucket 2 + .quad .Linfo_string3 # String in Bucket 1: main + .quad .Linfo_string4 # String in Bucket 2: int + .quad .Linfo_string7 # String in Bucket 2: char + .quad .Lnames0-.Lnames_entries0 # Offset in Bucket 1 + .quad .Lnames1-.Lnames_entries0 # Offset in Bucket 2 + .quad .Lnames2-.Lnames_entries0 # Offset in Bucket 2 +.Lnames_abbrev_start0: + .byte 1 # Abbrev code + .byte 46 # DW_TAG_subprogram + .byte 3 # DW_IDX_die_offset + .byte 19 # DW_FORM_ref4 + .byte 4 # DW_IDX_parent + .byte 25 # DW_FORM_flag_present + .byte 0 # End of abbrev + .byte 0 # End of abbrev + .byte 2 # Abbrev code + .byte 36 # DW_TAG_base_type + .byte 3 # DW_IDX_die_offset + .byte 19 # DW_FORM_ref4 + .byte 4 # DW_IDX_parent + .byte 25 # DW_FORM_flag_present + .byte 0 # End of abbrev + .byte 0 # End of abbrev + .byte 0 # End of abbrev list +.Lnames_abbrev_end0: +.Lnames_entries0: +.Lnames0: +.L2: + .byte 1 # Abbreviation code + .long 59 # DW_IDX_die_offset + .byte 0 # DW_IDX_parent + # End of list: main +.Lnames1: +.L1: + .byte 2 # Abbreviation code + .long 97 # DW_IDX_die_offset + .byte 0 # DW_IDX_parent + # End of list: int +.Lnames2: +.L0: + .byte 2 # Abbreviation code + .long 111 # DW_IDX_die_offset + .byte 0 # DW_IDX_parent + # End of list: char + .p2align 2, 0x0 +.Lnames_end0: + .ident "clang version 19.0.0git (git@github.com:llvm/llvm-project.git 9b37e60051f362e8e22c88785239fd5dfbfdf105)" + .section ".note.GNU-stack","",@progbits + .addrsig + .section .debug_line,"",@progbits +.Lline_table_start0: diff --git a/lld/test/ELF/debug-names-invalid-abbrev-code.s b/lld/test/ELF/debug-names-invalid-abbrev-code.s new file mode 100644 index 0000000000000..14970e0d10433 --- /dev/null +++ b/lld/test/ELF/debug-names-invalid-abbrev-code.s @@ -0,0 +1,151 @@ +# REQUIRES: x86 +# RUN: llvm-mc -filetype=obj -triple=x86_64 %s -o %t1.o +# +# RUN: not ld.lld --debug-names %t1.o -o /dev/null 2>&1 | FileCheck %s +# +# CHECK: error: {{.*}}(.debug_names): invalid abbrev code in entry +# CHECK: error: {{.*}}(.debug_names): invalid abbrev code in entry +## +## This file was generated by: +## clang++ -g -O0 -S -fdebug-compilation-dir='debug-names-test' \ +## -gpubnames main.cpp +## +## Then manually changing an abbrev code. +## +## main.cpp +## int main (int argc, char **argv) { } +## + .text + .globl main # -- Begin function main + .p2align 4, 0x90 + .type main,@function +main: # @main +.Lfunc_begin0: + .cfi_startproc +# %bb.0: # %entry + pushq %rbp + .cfi_def_cfa_offset 16 + .cfi_offset %rbp, -16 + movq %rsp, %rbp + .cfi_def_cfa_register %rbp + movl %edi, -4(%rbp) + movq %rsi, -16(%rbp) +.Ltmp0: + xorl %eax, %eax + popq %rbp + .cfi_def_cfa %rsp, 8 + retq +.Ltmp1: +.Lfunc_end0: + .size main, .Lfunc_end0-main + .cfi_endproc + # -- End function + .section .debug_abbrev,"",@progbits + .byte 0 # EOM(1) + .byte 0 # EOM(2) + .byte 0 # EOM(3) + .section .debug_info,"",@progbits +.Lcu_begin0: + .long .Ldebug_info_end0-.Ldebug_info_start0 # Length of Unit +.Ldebug_info_start0: + .short 5 # DWARF version number + .byte 1 # DWARF Unit Type + .byte 8 # Address Size (in bytes) + .long .debug_abbrev # Offset Into Abbrev. Section +.Ldebug_info_end0: + .section .debug_str_offsets,"",@progbits + .long 36 # Length of String Offsets Set + .short 5 + .short 0 +.Lstr_offsets_base0: + .section .debug_str,"MS",@progbits,1 +.Linfo_string0: + .asciz "clang version 19.0.0git (git@github.com:llvm/llvm-project.git d33d5630b281debe6eabd67e323bcf767340fb6a)" # string offset=0 +.Linfo_string1: + .asciz "main.cpp" # string offset=104 +.Linfo_string2: + .asciz "debug-names-test" # string offset=113 +.Linfo_string3: + .asciz "main" # string offset=130 +.Linfo_string4: + .asciz "int" # string offset=135 +.Linfo_string5: + .asciz "argc" # string offset=139 +.Linfo_string6: + .asciz "argv" # string offset=144 +.Linfo_string7: + .asciz "char" # string offset=149 +.Laddr_table_base0: + .quad .Lfunc_begin0 +.Ldebug_addr_end0: + .section .debug_names,"",@progbits + .long .Lnames_end0-.Lnames_start0 # Header: unit length +.Lnames_start0: + .short 5 # Header: version + .short 0 # Header: padding + .long 1 # Header: compilation unit count + .long 0 # Header: local type unit count + .long 0 # Header: foreign type unit count + .long 3 # Header: bucket count + .long 3 # Header: name count + .long .Lnames_abbrev_end0-.Lnames_abbrev_start0 # Header: abbreviation table size + .long 8 # Header: augmentation string size + .ascii "LLVM0700" # Header: augmentation string + .long .Lcu_begin0 # Compilation unit 0 + .long 0 # Bucket 0 + .long 1 # Bucket 1 + .long 2 # Bucket 2 + .long 2090499946 # Hash in Bucket 1 + .long 193495088 # Hash in Bucket 2 + .long 2090147939 # Hash in Bucket 2 + .long .Linfo_string3 # String in Bucket 1: main + .long .Linfo_string4 # String in Bucket 2: int + .long .Linfo_string7 # String in Bucket 2: char + .long .Lnames0-.Lnames_entries0 # Offset in Bucket 1 + .long .Lnames1-.Lnames_entries0 # Offset in Bucket 2 + .long .Lnames2-.Lnames_entries0 # Offset in Bucket 2 +.Lnames_abbrev_start0: + .byte 1 # Abbrev code + .byte 46 # DW_TAG_subprogram + .byte 3 # DW_IDX_die_offset + .byte 19 # DW_FORM_ref4 + .byte 4 # DW_IDX_parent + .byte 25 # DW_FORM_flag_present + .byte 0 # End of abbrev + .byte 0 # End of abbrev + .byte 2 # Abbrev code + .byte 36 # DW_TAG_base_type + .byte 3 # DW_IDX_die_offset + .byte 19 # DW_FORM_ref4 + .byte 4 # DW_IDX_parent + .byte 25 # DW_FORM_flag_present + .byte 0 # End of abbrev + .byte 0 # End of abbrev + .byte 0 # End of abbrev list +.Lnames_abbrev_end0: +.Lnames_entries0: +.Lnames0: +.L1: + .byte 1 # Abbreviation code + .long 35 # DW_IDX_die_offset + .byte 0 # DW_IDX_parent + # End of list: main +.Lnames1: +.L0: + .byte 3 # Abbreviation code + .long 73 # DW_IDX_die_offset + .byte 0 # DW_IDX_parent + # End of list: int +.Lnames2: +.L2: + .byte 2 # Abbreviation code + .long 87 # DW_IDX_die_offset + .byte 0 # DW_IDX_parent + # End of list: char + .p2align 2, 0x0 +.Lnames_end0: + .ident "clang version 19.0.0git (git@github.com:llvm/llvm-project.git d33d5630b281debe6eabd67e323bcf767340fb6a)" + .section ".note.GNU-stack","",@progbits + .addrsig + .section .debug_line,"",@progbits +.Lline_table_start0: diff --git a/lld/test/ELF/debug-names-invalid-attribute-2.s b/lld/test/ELF/debug-names-invalid-attribute-2.s new file mode 100644 index 0000000000000..44e74911bd035 --- /dev/null +++ b/lld/test/ELF/debug-names-invalid-attribute-2.s @@ -0,0 +1,150 @@ +# REQUIRES: x86 +# RUN: llvm-mc -filetype=obj -triple=x86_64 %s -o %t1.o +# +# RUN: not ld.lld --debug-names %t1.o -o /dev/null 2>&1 | FileCheck %s +# +# CHECK: error: {{.*}}(.debug_names): error while reading attributes: unexpected end of data at offset 0x80 while reading [0x7e, 0x82) +## +## This file was generated by: +## clang++ -g -O0 -S -fdebug-compilation-dir='debug-names-test' \ +## -gpubnames main.cpp +## +## Then manually editing .debug_names section, commenting out a +## DW_IDX_die_offset in an entry. +## +## main.cpp +## int main (int argc, char **argv) { } +## + .text + .globl main # -- Begin function main + .p2align 4, 0x90 + .type main,@function +main: # @main +.Lfunc_begin0: + .cfi_startproc +# %bb.0: # %entry + pushq %rbp + .cfi_def_cfa_offset 16 + .cfi_offset %rbp, -16 + movq %rsp, %rbp + .cfi_def_cfa_register %rbp + movl %edi, -4(%rbp) + movq %rsi, -16(%rbp) +.Ltmp0: + xorl %eax, %eax + popq %rbp + .cfi_def_cfa %rsp, 8 + retq +.Ltmp1: +.Lfunc_end0: + .size main, .Lfunc_end0-main + .cfi_endproc + # -- End function + .section .debug_abbrev,"",@progbits + .byte 0 # EOM(1) + .byte 0 # EOM(2) + .byte 0 # EOM(3) + .section .debug_info,"",@progbits +.Lcu_begin0: + .long .Ldebug_info_end0-.Ldebug_info_start0 # Length of Unit +.Ldebug_info_start0: + .short 5 # DWARF version number + .byte 1 # DWARF Unit Type + .byte 8 # Address Size (in bytes) + .long .debug_abbrev # Offset Into Abbrev. Section +.Ldebug_info_end0: + .section .debug_str_offsets,"",@progbits + .long 36 # Length of String Offsets Set + .short 5 + .short 0 +.Lstr_offsets_base0: + .section .debug_str,"MS",@progbits,1 +.Linfo_string0: + .asciz "clang version 19.0.0git (git@github.com:llvm/llvm-project.git d33d5630b281debe6eabd67e323bcf767340fb6a)" # string offset=0 +.Linfo_string1: + .asciz "main.cpp" # string offset=104 +.Linfo_string2: + .asciz "debug-names-test" # string offset=113 +.Linfo_string3: + .asciz "main" # string offset=130 +.Linfo_string4: + .asciz "int" # string offset=135 +.Linfo_string5: + .asciz "argc" # string offset=139 +.Linfo_string6: + .asciz "argv" # string offset=144 +.Linfo_string7: + .asciz "char" # string offset=149 +.Laddr_table_base0: + .quad .Lfunc_begin0 +.Ldebug_addr_end0: + .section .debug_names,"",@progbits + .long .Lnames_end0-.Lnames_start0 # Header: unit length +.Lnames_start0: + .short 5 # Header: version + .short 0 # Header: padding + .long 1 # Header: compilation unit count + .long 0 # Header: local type unit count + .long 0 # Header: foreign type unit count + .long 3 # Header: bucket count + .long 3 # Header: name count + .long .Lnames_abbrev_end0-.Lnames_abbrev_start0 # Header: abbreviation table size + .long 8 # Header: augmentation string size + .ascii "LLVM0700" # Header: augmentation string + .long .Lcu_begin0 # Compilation unit 0 + .long 0 # Bucket 0 + .long 1 # Bucket 1 + .long 2 # Bucket 2 + .long 2090499946 # Hash in Bucket 1 + .long 193495088 # Hash in Bucket 2 + .long 2090147939 # Hash in Bucket 2 + .long .Linfo_string3 # String in Bucket 1: main + .long .Linfo_string4 # String in Bucket 2: int + .long .Linfo_string7 # String in Bucket 2: char + .long .Lnames0-.Lnames_entries0 # Offset in Bucket 1 + .long .Lnames1-.Lnames_entries0 # Offset in Bucket 2 + .long .Lnames2-.Lnames_entries0 # Offset in Bucket 2 +.Lnames_abbrev_start0: + .byte 1 # Abbrev code + .byte 46 # DW_TAG_subprogram + .byte 3 # DW_IDX_die_offset + .byte 19 # DW_FORM_ref4 + .byte 4 # DW_IDX_parent + .byte 25 # DW_FORM_flag_present + .byte 0 # End of abbrev + .byte 0 # End of abbrev + .byte 2 # Abbrev code + .byte 36 # DW_TAG_base_type + .byte 3 # DW_IDX_die_offset + .byte 19 # DW_FORM_ref4 + .byte 4 # DW_IDX_parent + .byte 25 # DW_FORM_flag_present + .byte 0 # End of abbrev + .byte 0 # End of abbrev + .byte 0 # End of abbrev list +.Lnames_abbrev_end0: +.Lnames_entries0: +.Lnames0: +.L1: + .byte 1 # Abbreviation code + .long 35 # DW_IDX_die_offset + .byte 0 # DW_IDX_parent + # End of list: main +.Lnames1: +.L0: + .byte 2 # Abbreviation code + .long 73 # DW_IDX_die_offset + .byte 0 # DW_IDX_parent + # End of list: int +.Lnames2: +.L2: + .byte 2 # Abbreviation code +# .long 87 # DW_IDX_die_offset + # End of list: char + .p2align 2, 0x0 +.Lnames_end0: + .ident "clang version 19.0.0git (git@github.com:llvm/llvm-project.git d33d5630b281debe6eabd67e323bcf767340fb6a)" + .section ".note.GNU-stack","",@progbits + .addrsig + .section .debug_line,"",@progbits +.Lline_table_start0: diff --git a/lld/test/ELF/debug-names-invalid-attribute-3.s b/lld/test/ELF/debug-names-invalid-attribute-3.s new file mode 100644 index 0000000000000..1e6ea8074975f --- /dev/null +++ b/lld/test/ELF/debug-names-invalid-attribute-3.s @@ -0,0 +1,154 @@ +# REQUIRES: x86 +# RUN: llvm-mc -filetype=obj -triple=x86_64 %s -o %t1.o +# +# RUN: not ld.lld --debug-names %t1.o -o /dev/null 2>&1 | FileCheck %s +# +# CHECK: error: {{.*}}(.debug_names): invalid form for attribute +## +## This file was generated by: +## clang++ -g -O0 -S -fdebug-compilation-dir='debug-names-test' \ +## -gpubnames main.cpp +## +## +## Then manually changing the first .debug_names abbrev, so that the +## DW_IDX_die_offset uses DW_FORM_flag_present (invalid) & the DW_IDX_parent +## uses DW_FORM_ref4. Also updated the sizes of the values in the entry +## that uses the abbrev, to match the sizes of the forms. +## +## main.cpp +## int main (int argc, char **argv) { } +## + .text + .globl main # -- Begin function main + .p2align 4, 0x90 + .type main,@function +main: # @main +.Lfunc_begin0: + .cfi_startproc +# %bb.0: # %entry + pushq %rbp + .cfi_def_cfa_offset 16 + .cfi_offset %rbp, -16 + movq %rsp, %rbp + .cfi_def_cfa_register %rbp + movl %edi, -4(%rbp) + movq %rsi, -16(%rbp) +.Ltmp0: + xorl %eax, %eax + popq %rbp + .cfi_def_cfa %rsp, 8 + retq +.Ltmp1: +.Lfunc_end0: + .size main, .Lfunc_end0-main + .cfi_endproc + # -- End function + .section .debug_abbrev,"",@progbits + .byte 0 # EOM(1) + .byte 0 # EOM(2) + .byte 0 # EOM(3) + .section .debug_info,"",@progbits +.Lcu_begin0: + .long .Ldebug_info_end0-.Ldebug_info_start0 # Length of Unit +.Ldebug_info_start0: + .short 5 # DWARF version number + .byte 1 # DWARF Unit Type + .byte 8 # Address Size (in bytes) + .long .debug_abbrev # Offset Into Abbrev. Section +.Ldebug_info_end0: + .section .debug_str_offsets,"",@progbits + .long 36 # Length of String Offsets Set + .short 5 + .short 0 +.Lstr_offsets_base0: + .section .debug_str,"MS",@progbits,1 +.Linfo_string0: + .asciz "clang version 19.0.0git (git@github.com:llvm/llvm-project.git d33d5630b281debe6eabd67e323bcf767340fb6a)" # string offset=0 +.Linfo_string1: + .asciz "main.cpp" # string offset=104 +.Linfo_string2: + .asciz "debug-names-test" # string offset=113 +.Linfo_string3: + .asciz "main" # string offset=130 +.Linfo_string4: + .asciz "int" # string offset=135 +.Linfo_string5: + .asciz "argc" # string offset=139 +.Linfo_string6: + .asciz "argv" # string offset=144 +.Linfo_string7: + .asciz "char" # string offset=149 +.Laddr_table_base0: + .quad .Lfunc_begin0 +.Ldebug_addr_end0: + .section .debug_names,"",@progbits + .long .Lnames_end0-.Lnames_start0 # Header: unit length +.Lnames_start0: + .short 5 # Header: version + .short 0 # Header: padding + .long 1 # Header: compilation unit count + .long 0 # Header: local type unit count + .long 0 # Header: foreign type unit count + .long 3 # Header: bucket count + .long 3 # Header: name count + .long .Lnames_abbrev_end0-.Lnames_abbrev_start0 # Header: abbreviation table size + .long 8 # Header: augmentation string size + .ascii "LLVM0700" # Header: augmentation string + .long .Lcu_begin0 # Compilation unit 0 + .long 0 # Bucket 0 + .long 1 # Bucket 1 + .long 2 # Bucket 2 + .long 2090499946 # Hash in Bucket 1 + .long 193495088 # Hash in Bucket 2 + .long 2090147939 # Hash in Bucket 2 + .long .Linfo_string3 # String in Bucket 1: main + .long .Linfo_string4 # String in Bucket 2: int + .long .Linfo_string7 # String in Bucket 2: char + .long .Lnames0-.Lnames_entries0 # Offset in Bucket 1 + .long .Lnames1-.Lnames_entries0 # Offset in Bucket 2 + .long .Lnames2-.Lnames_entries0 # Offset in Bucket 2 +.Lnames_abbrev_start0: + .byte 1 # Abbrev code + .byte 46 # DW_TAG_subprogram + .byte 3 # DW_IDX_die_offset + .byte 25 # DW_FORM_flag_present + .byte 4 # DW_IDX_parent + .byte 19 # DW_FORM_ref4 + .byte 0 # End of abbrev + .byte 0 # End of abbrev + .byte 2 # Abbrev code + .byte 36 # DW_TAG_base_type + .byte 3 # DW_IDX_die_offset + .byte 19 # DW_FORM_ref4 + .byte 4 # DW_IDX_parent + .byte 25 # DW_FORM_flag_present + .byte 0 # End of abbrev + .byte 0 # End of abbrev + .byte 0 # End of abbrev list +.Lnames_abbrev_end0: +.Lnames_entries0: +.Lnames0: +.L1: + .byte 1 # Abbreviation code + .byte 35 # DW_IDX_die_offset + .long 0 # DW_IDX_parent + # End of list: main +.Lnames1: +.L0: + .byte 2 # Abbreviation code + .long 73 # DW_IDX_die_offset + .byte 0 # DW_IDX_parent + # End of list: int +.Lnames2: +.L2: + .byte 2 # Abbreviation code + .long 87 # DW_IDX_die_offset + .byte 0 # DW_IDX_parent + # End of list: char + .p2align 2, 0x0 +.Lnames_end0: + .ident "clang version 19.0.0git (git@github.com:llvm/llvm-project.git d33d5630b281debe6eabd67e323bcf767340fb6a)" + .section ".note.GNU-stack","",@progbits + .addrsig + .section .debug_line,"",@progbits +.Lline_table_start0: diff --git a/lld/test/ELF/debug-names-invalid-parent-idx.s b/lld/test/ELF/debug-names-invalid-parent-idx.s new file mode 100644 index 0000000000000..be5df8b155250 --- /dev/null +++ b/lld/test/ELF/debug-names-invalid-parent-idx.s @@ -0,0 +1,153 @@ +# REQUIRES: x86 +# RUN: llvm-mc -filetype=obj -triple=x86_64 %s -o %t1.o +# +# RUN: not ld.lld --debug-names %t1.o -o /dev/null 2>&1 | FileCheck %s +# +# CHECK: error: {{.*}}(.debug_names): invalid form for DW_IDX_parent +# CHECK: error: {{.*}}(.debug_names): invalid form for DW_IDX_parent +# CHECK: error: {{.*}}(.debug_names): invalid form for DW_IDX_parent +## +## This file was generated by: +## clang++ -g -O0 -S -fdebug-compilation-dir='debug-names-test' \ +## -gpubnames main.cpp +## +## Then manually editing .debug_names section, changing the form for a +## DW_IDX_parent from DW_FORM_flag_present to DW_FORM_ref1 (invalid). +## +## main.cpp +## int main (int argc, char **argv) { } +## + .text + .globl main # -- Begin function main + .p2align 4, 0x90 + .type main,@function +main: # @main +.Lfunc_begin0: + .cfi_startproc +# %bb.0: # %entry + pushq %rbp + .cfi_def_cfa_offset 16 + .cfi_offset %rbp, -16 + movq %rsp, %rbp + .cfi_def_cfa_register %rbp + movl %edi, -4(%rbp) + movq %rsi, -16(%rbp) +.Ltmp0: + xorl %eax, %eax + popq %rbp + .cfi_def_cfa %rsp, 8 + retq +.Ltmp1: +.Lfunc_end0: + .size main, .Lfunc_end0-main + .cfi_endproc + # -- End function + .section .debug_abbrev,"",@progbits + .byte 0 # EOM(1) + .byte 0 # EOM(2) + .byte 0 # EOM(3) + .section .debug_info,"",@progbits +.Lcu_begin0: + .long .Ldebug_info_end0-.Ldebug_info_start0 # Length of Unit +.Ldebug_info_start0: + .short 5 # DWARF version number + .byte 1 # DWARF Unit Type + .byte 8 # Address Size (in bytes) + .long .debug_abbrev # Offset Into Abbrev. Section +.Ldebug_info_end0: + .section .debug_str_offsets,"",@progbits + .long 36 # Length of String Offsets Set + .short 5 + .short 0 +.Lstr_offsets_base0: + .section .debug_str,"MS",@progbits,1 +.Linfo_string0: + .asciz "clang version 19.0.0git (git@github.com:llvm/llvm-project.git d33d5630b281debe6eabd67e323bcf767340fb6a)" # string offset=0 +.Linfo_string1: + .asciz "main.cpp" # string offset=104 +.Linfo_string2: + .asciz "debug-names-test" # string offset=113 +.Linfo_string3: + .asciz "main" # string offset=130 +.Linfo_string4: + .asciz "int" # string offset=135 +.Linfo_string5: + .asciz "argc" # string offset=139 +.Linfo_string6: + .asciz "argv" # string offset=144 +.Linfo_string7: + .asciz "char" # string offset=149 +.Laddr_table_base0: + .quad .Lfunc_begin0 +.Ldebug_addr_end0: + .section .debug_names,"",@progbits + .long .Lnames_end0-.Lnames_start0 # Header: unit length +.Lnames_start0: + .short 5 # Header: version + .short 0 # Header: padding + .long 1 # Header: compilation unit count + .long 0 # Header: local type unit count + .long 0 # Header: foreign type unit count + .long 3 # Header: bucket count + .long 3 # Header: name count + .long .Lnames_abbrev_end0-.Lnames_abbrev_start0 # Header: abbreviation table size + .long 8 # Header: augmentation string size + .ascii "LLVM0700" # Header: augmentation string + .long .Lcu_begin0 # Compilation unit 0 + .long 0 # Bucket 0 + .long 1 # Bucket 1 + .long 2 # Bucket 2 + .long 2090499946 # Hash in Bucket 1 + .long 193495088 # Hash in Bucket 2 + .long 2090147939 # Hash in Bucket 2 + .long .Linfo_string3 # String in Bucket 1: main + .long .Linfo_string4 # String in Bucket 2: int + .long .Linfo_string7 # String in Bucket 2: char + .long .Lnames0-.Lnames_entries0 # Offset in Bucket 1 + .long .Lnames1-.Lnames_entries0 # Offset in Bucket 2 + .long .Lnames2-.Lnames_entries0 # Offset in Bucket 2 +.Lnames_abbrev_start0: + .byte 1 # Abbrev code + .byte 46 # DW_TAG_subprogram + .byte 3 # DW_IDX_die_offset + .byte 19 # DW_FORM_ref4 + .byte 4 # DW_IDX_parent + .byte 25 # DW_FORM_flag_present + .byte 0 # End of abbrev + .byte 0 # End of abbrev + .byte 2 # Abbrev code + .byte 36 # DW_TAG_base_type + .byte 3 # DW_IDX_die_offset + .byte 19 # DW_FORM_ref4 + .byte 4 # DW_IDX_parent + .byte 17 # DW_FORM_ref1 + .byte 0 # End of abbrev + .byte 0 # End of abbrev + .byte 0 # End of abbrev list +.Lnames_abbrev_end0: +.Lnames_entries0: +.Lnames0: +.L1: + .byte 1 # Abbreviation code + .long 35 # DW_IDX_die_offset + .byte 0 # DW_IDX_parent + # End of list: main +.Lnames1: +.L0: + .byte 2 # Abbreviation code + .long 73 # DW_IDX_die_offset + .byte 0 # DW_IDX_parent + # End of list: int +.Lnames2: +.L2: + .byte 2 # Abbreviation code + .long 87 # DW_IDX_die_offset + .byte 0 # DW_IDX_parent + # End of list: char + .p2align 2, 0x0 +.Lnames_end0: + .ident "clang version 19.0.0git (git@github.com:llvm/llvm-project.git d33d5630b281debe6eabd67e323bcf767340fb6a)" + .section ".note.GNU-stack","",@progbits + .addrsig + .section .debug_line,"",@progbits +.Lline_table_start0: From 5b7ff5b5cd5c137d29d467aebfa2615ac25c00df Mon Sep 17 00:00:00 2001 From: Caroline Tice Date: Tue, 26 Mar 2024 22:48:27 -0700 Subject: [PATCH 04/37] [lld][ELF] Implement merged .debug_names section. Update and fix debug-names* tests. Make entire DebugNamesSection a template section. Fix formatting and other review comments. --- lld/ELF/SyntheticSections.cpp | 238 +++++---- lld/ELF/SyntheticSections.h | 17 +- lld/test/ELF/Inputs/debug-names-2.s | 45 +- .../ELF/Inputs/debug-names-parent-idx-2.s | 98 +--- lld/test/ELF/debug-names-bad-aug-string.s | 84 +-- lld/test/ELF/debug-names-bad-die-idx-sizes.s | 32 +- lld/test/ELF/debug-names-bad-name-count.s | 39 +- lld/test/ELF/debug-names-bad-offsets-sizes.s | 37 +- lld/test/ELF/debug-names-bad-version.s | 21 +- lld/test/ELF/debug-names-dwarf64.s | 28 +- .../ELF/debug-names-invalid-abbrev-code.s | 34 +- .../ELF/debug-names-invalid-attribute-2.s | 34 +- .../ELF/debug-names-invalid-attribute-3.s | 39 +- lld/test/ELF/debug-names-invalid-attribute.s | 53 +- lld/test/ELF/debug-names-invalid-flags.s | 148 ++++++ lld/test/ELF/debug-names-invalid-parent-idx.s | 38 +- lld/test/ELF/debug-names-parent-idx.s | 496 +++++++----------- lld/test/ELF/debug-names.s | 263 ++++------ 18 files changed, 752 insertions(+), 992 deletions(-) create mode 100644 lld/test/ELF/debug-names-invalid-flags.s diff --git a/lld/ELF/SyntheticSections.cpp b/lld/ELF/SyntheticSections.cpp index bc3083141f766..776bf719a01d7 100644 --- a/lld/ELF/SyntheticSections.cpp +++ b/lld/ELF/SyntheticSections.cpp @@ -2714,13 +2714,15 @@ static uint32_t computeGdbHash(StringRef s) { return h; } -DebugNamesSection::DebugNamesSection() +template +DebugNamesSection::DebugNamesSection() : SyntheticSection(0, SHT_PROGBITS, 1, ".debug_names") {} -template -void DebugNamesSection::getNameRelocsImpl( +template +template +void DebugNamesSection::getNameRelocsImpl( InputSection *sec, ArrayRef rels, - llvm::DenseMap &relocs) { + DenseMap &relocs) { for (auto &rel : rels) { Symbol &sym = sec->getFile()->getRelocTargetSym(rel); relocs[rel.r_offset] = sym.getVA(getAddend(rel)); @@ -2728,31 +2730,28 @@ void DebugNamesSection::getNameRelocsImpl( } template -void DebugNamesSection::getNameRelocs( - InputSectionBase *base, llvm::DenseMap &relocs) { +void DebugNamesSection::getNameRelocs( + InputSectionBase *base, DenseMap &relocs) { auto *sec = cast(base); const RelsOrRelas rels = sec->template relsOrRelas(); if (rels.areRelocsRel()) - getNameRelocsImpl(sec, rels.rels, relocs); + getNameRelocsImpl(sec, rels.rels, relocs); else - getNameRelocsImpl(sec, rels.relas, relocs); + getNameRelocsImpl(sec, rels.relas, relocs); } -void DebugNamesSection::writeTo(uint8_t *buf) { invokeELFT(writeToImpl, buf); } - -template void DebugNamesSection::writeToImpl(uint8_t *buf) { +template void DebugNamesSection::writeTo(uint8_t *buf) { SmallVector mergedCuOffsets; SmallVector mergedTuOffsets; - llvm::DenseMap strOffsets; - SmallVector, 0> chunksRelocs; + DenseMap strOffsets; + SmallVector, 0> chunksRelocs; chunksRelocs.reserve(numChunks); for (size_t i = 0; i < numChunks; ++i) { DebugNamesOutputChunk &chunk = outputChunks[i]; InputSectionBase *base = inputDebugNamesSections[i]; - llvm::DenseMap relocs; - getNameRelocs(base, relocs); - chunksRelocs.push_back(std::move(relocs)); + DenseMap &relocs = chunksRelocs.emplace_back(); + getNameRelocs(base, relocs); // Update CuOffsets list with new data for (uint32_t cuOffset : chunk.compilationUnits) @@ -2839,15 +2838,11 @@ template void DebugNamesSection::writeToImpl(uint8_t *buf) { // Write the abbrev table. for (const auto *abbrev : mergedAbbrevTable) { - size_t uleb_size = encodeULEB128(abbrev->code, buf); - buf += uleb_size; - uleb_size = encodeULEB128(abbrev->tag, buf); - buf += uleb_size; + buf += encodeULEB128(abbrev->code, buf); + buf += encodeULEB128(abbrev->tag, buf); for (auto attr : abbrev->attributes) { - uleb_size = encodeULEB128(attr.Index, buf); - buf += uleb_size; - uleb_size = encodeULEB128(attr.Form, buf); - buf += uleb_size; + buf += encodeULEB128(attr.Index, buf); + buf += encodeULEB128(attr.Form, buf); } endian::write16(buf + 0, 0); // attribute sentinels. buf += 2; @@ -2857,10 +2852,8 @@ template void DebugNamesSection::writeToImpl(uint8_t *buf) { // Write the entry pool. for (const auto &stringEntry : mergedEntries) { // Write all the entries for the string. - size_t uleb_size; for (const auto &entry : stringEntry.indexEntries) { - uleb_size = encodeULEB128(entry->abbrevCode, buf); - buf += uleb_size; + buf += encodeULEB128(entry->abbrevCode, buf); for (const auto &value : entry->attrValues) { if (value.attrSize > 0) { endian::write32(buf + 0, value.attrValue); @@ -2872,69 +2865,74 @@ template void DebugNamesSection::writeToImpl(uint8_t *buf) { } } -bool DebugNamesSection::isNeeded() const { return numChunks > 0; } +template bool DebugNamesSection::isNeeded() const { + return numChunks > 0; +} template -static void -readCompileUnitOffsets(struct DebugNamesSection::DebugNamesSectionData &secData, - DebugNamesSection::DebugNamesOutputChunk &outputChunk, - llvm::DWARFDataExtractor &namesExtractor) { +static void readCompileUnitOffsets( + typename DebugNamesSection::DebugNamesSectionData &secData, + typename DebugNamesSection::DebugNamesOutputChunk &outputChunk, + DWARFDataExtractor &namesExtractor) { uint64_t offset = secData.locs.CUsBase; uint64_t *offsetPtr = &offset; for (size_t i = 0; i < secData.hdr.CompUnitCount; ++i) { - llvm::Error err = llvm::Error::success(); + Error err = Error::success(); // This call to namesExtractor can't fail; if there were a problem with the // input, it would have been caught in the call to NamesIndex::extract, in // DebugNamesSection::create. uint32_t value = namesExtractor.getU32(offsetPtr, &err); - llvm::cantFail(std::move(err)); + cantFail(std::move(err)); outputChunk.compilationUnits.push_back(value); } } template -static void -readEntryOffsets(struct DebugNamesSection::DebugNamesSectionData &secData, - llvm::DWARFDataExtractor &namesExtractor) { +static void readEntryOffsets( + typename DebugNamesSection::DebugNamesSectionData &secData, + DWARFDataExtractor &namesExtractor) { secData.entryOffsets = std::make_unique(secData.hdr.NameCount); uint64_t offset = secData.locs.EntryOffsetsBase; uint64_t *offsetPtr = &offset; for (size_t i = 0; i < secData.hdr.NameCount; ++i) { - llvm::Error err = llvm::Error::success(); + Error err = Error::success(); // This call to namesExtractor can't fail; if there were a problem with the // input, it would have been caught in the call to NamesIndex::extract, in // DebugNamesSection::create. uint32_t value = namesExtractor.getU32(offsetPtr, &err); - llvm::cantFail(std::move(err)); + cantFail(std::move(err)); secData.entryOffsets.get()[i] = value; } } template static void readAttributeValues( - SmallVector &values, - DebugNamesSection::DebugNamesInputChunk &chunk, uint64_t &offset, - struct DebugNamesSection::DebugNamesSectionData &secData, - int32_t &parentOffset, llvm::DWARFDataExtractor &namesExtractor, - const llvm::DWARFDebugNames::Abbrev &abbrev) { + SmallVector::AttrValueData, 3> &values, + typename DebugNamesSection::DebugNamesInputChunk &chunk, + uint64_t &offset, + typename DebugNamesSection::DebugNamesSectionData &secData, + int32_t &parentOffset, DWARFDataExtractor &namesExtractor, + const DWARFDebugNames::Abbrev &abbrev) { const LLDDWARFSection &namesSection = *chunk.namesSection; uint64_t *offsetPtr = &offset; - DebugNamesSection::AttrValueData cuOrTuAttr = {0, 0}; + typename DebugNamesSection::AttrValueData cuOrTuAttr = {0, 0}; for (auto attr : abbrev.Attributes) { - llvm::Error err = llvm::Error::success(); - DebugNamesSection::AttrValueData newAttr; + Error err = Error::success(); + typename DebugNamesSection::AttrValueData newAttr; uint32_t value; if (attr.Index == DW_IDX_parent && attr.Form != DW_FORM_flag_present && attr.Form != DW_FORM_ref4) - errorOrWarn(toString(namesSection.sec) + ": invalid form for DW_IDX_parent"); + errorOrWarn(toString(namesSection.sec) + + Twine(": invalid form for DW_IDX_parent")); switch (attr.Form) { case DW_FORM_flag_present: { // Currently only DW_IDX_parent attributes (in .debug_names) can // have this form. This form does not have a real value (nothing is // emitted for it). if (attr.Index != DW_IDX_parent) - errorOrWarn(toString(namesSection.sec) + ": invalid form for attribute"); + errorOrWarn(toString(namesSection.sec) + + Twine(": invalid form for attribute")); break; } case DW_FORM_data1: @@ -2970,14 +2968,14 @@ static void readAttributeValues( default: { errorOrWarn(toString(namesSection.sec) + Twine(": unrecognized form encoding ") + Twine(attr.Form) + - " in .debug_names abbrev table"); + Twine(" in .debug_names abbrev table")); break; } } if (err) - errorOrWarn( - toString(namesSection.sec) + - ": error while reading attributes: " + toString(std::move(err))); + errorOrWarn(toString(namesSection.sec) + + Twine(": error while reading attributes: ") + + toString(std::move(err))); if (attr.Index == DW_IDX_compile_unit || attr.Index == DW_IDX_type_unit) // Save it to put it at the end of the attributes list. cuOrTuAttr = newAttr; @@ -2990,59 +2988,61 @@ static void readAttributeValues( } template -static void readEntry(DebugNamesSection::NamedEntry &stringEntry, - DebugNamesSection::DebugNamesInputChunk &chunk, - DebugNamesSection::DebugNamesSectionData &secData, - llvm::DWARFDataExtractor &namesExtractor, - const llvm::DWARFDebugNames::NameIndex &ni) { +static void +readEntry(typename DebugNamesSection::NamedEntry &stringEntry, + typename DebugNamesSection::DebugNamesInputChunk &chunk, + typename DebugNamesSection::DebugNamesSectionData &secData, + DWARFDataExtractor &namesExtractor, + const DWARFDebugNames::NameIndex &ni) { std::unique_ptr &namesSection = chunk.namesSection; uint64_t offset = stringEntry.entryOffset; // Each entry ends with a zero 'sentinel' value while (offset < namesSection->Data.size() && namesSection->Data[offset] != 0) { // Read & store all entries (for the same string) - auto entry = std::make_unique(); + auto entry = + std::make_unique::IndexEntry>(); entry->poolOffset = offset; - llvm::Error err = llvm::Error::success(); + Error err = Error::success(); // This call to namesExtractor can't fail; if there were a problem with the // input, it would have been caught in the call to NamesIndex::extract, in // DebugNamesSection::create. uint64_t ulebValue = namesExtractor.getULEB128(&offset, &err); - llvm::cantFail(std::move(err)); + cantFail(std::move(err)); entry->abbrevCode = static_cast(ulebValue); const auto &abbrevs = ni.getAbbrevs(); auto abbrevIt = abbrevs.find_as(entry->abbrevCode); if (abbrevIt != abbrevs.end()) { - const llvm::DWARFDebugNames::Abbrev &abbrev = *abbrevIt; + const DWARFDebugNames::Abbrev &abbrev = *abbrevIt; readAttributeValues(entry->attrValues, chunk, offset, secData, entry->parentOffset, namesExtractor, abbrev); stringEntry.indexEntries.push_back(std::move(entry)); } else errorOrWarn(toString(chunk.namesSection->sec) + - ": invalid abbrev code in entry"); + Twine(": invalid abbrev code in entry")); } if (offset >= namesSection->Data.size()) - errorOrWarn(toString(chunk.namesSection->sec) + - ": encountered unexpected end of section while reading entry"); + errorOrWarn( + toString(chunk.namesSection->sec) + + Twine(": encountered unexpected end of section while reading entry")); } template static void -readEntries(struct DebugNamesSection::DebugNamesSectionData &secData, - DebugNamesSection::DebugNamesInputChunk &chunk, - llvm::DWARFDataExtractor &namesExtractor, - llvm::DataExtractor &strExtractor, - const llvm::DWARFDebugNames::NameIndex &ni) { +readEntries(typename DebugNamesSection::DebugNamesSectionData &secData, + typename DebugNamesSection::DebugNamesInputChunk &chunk, + DWARFDataExtractor &namesExtractor, DataExtractor &strExtractor, + const DWARFDebugNames::NameIndex &ni) { // Temporary map from entry offsets to address (pointer) of entry with that // offset; used to find parent entries quickly. - DenseMap offsetMap; + DenseMap::IndexEntry *> offsetMap; // Reserve sizes for this chunk's hashes & namedEntries. chunk.hashValues.reserve(secData.hdr.NameCount); secData.namedEntries.reserve(secData.hdr.NameCount); // Calculate the Entry Offsets, create initial records. for (uint32_t i = 0; i < secData.hdr.NameCount; ++i) { // Get string value - DebugNamesSection::NamedEntry stringEntry; + typename DebugNamesSection::NamedEntry stringEntry; stringEntry.entryOffset = secData.locs.EntriesBase + secData.entryOffsets[i]; uint64_t strOffsetOffset = @@ -3088,22 +3088,23 @@ static uint16_t computeDebugNamesHeaderSize() { template static void collectDebugNamesSectionData( - DebugNamesSection::DebugNamesInputChunk &chunk, - DebugNamesSection::DebugNamesOutputChunk &outputChunk, - llvm::DWARFDataExtractor &namesExtractor, - llvm::DataExtractor &strExtractor) { + typename DebugNamesSection::DebugNamesInputChunk &chunk, + typename DebugNamesSection::DebugNamesOutputChunk &outputChunk, + DWARFDataExtractor &namesExtractor, DataExtractor &strExtractor) { for (const auto &ni : *chunk.debugNamesData) { - DebugNamesSection::DebugNamesSectionData secData; + typename DebugNamesSection::DebugNamesSectionData secData; secData.hdr = ni.getHeader(); if (secData.hdr.Format != DwarfFormat::DWARF32) { - errorOrWarn(toString(chunk.namesSection->sec) + ": unsupported DWARF64"); + errorOrWarn(toString(chunk.namesSection->sec) + + Twine(": unsupported DWARF64")); // Don't try to continue; we can't parse DWARF64 at the moment. return; } secData.dwarfSize = dwarf::getDwarfOffsetByteSize(DwarfFormat::DWARF32); secData.hdrSize = computeDebugNamesHeaderSize(); if (secData.hdr.Version != 5) - errorOrWarn(toString(chunk.namesSection->sec) + ": unsupported version"); + errorOrWarn(toString(chunk.namesSection->sec) + + Twine(": unsupported version")); secData.locs = findDebugNamesOffsets(secData.hdrSize, secData.hdr); readCompileUnitOffsets(secData, outputChunk, namesExtractor); readEntryOffsets(secData, namesExtractor); @@ -3112,10 +3113,10 @@ static void collectDebugNamesSectionData( } } -void DebugNamesSection::collectMergedCounts( +template +void DebugNamesSection::collectMergedCounts( MutableArrayRef &inputChunks) { SmallVector tmpMergedCuOffsets; - mergedHdr.CompUnitCount = 0; mergedHdr.LocalTypeUnitCount = 0; mergedHdr.ForeignTypeUnitCount = 0; @@ -3143,15 +3144,15 @@ void DebugNamesSection::collectMergedCounts( data.hdr.AugmentationString)) { // There are conflicting augmentation strings, so it's best for the // merged index to not use an augmentation string. - StringRef emptyString = " "; mergedHdr.AugmentationStringSize = 8; - mergedHdr.AugmentationString = emptyString; + mergedHdr.AugmentationString = " "; } } } } -void DebugNamesSection::Abbrev::Profile(llvm::FoldingSetNodeID &id) const { +template +void DebugNamesSection::Abbrev::Profile(FoldingSetNodeID &id) const { id.AddInteger(tag); for (const DWARFDebugNames::AttributeEncoding &attr : attributes) { id.AddInteger(attr.Index); @@ -3159,14 +3160,15 @@ void DebugNamesSection::Abbrev::Profile(llvm::FoldingSetNodeID &id) const { } } -std::pair DebugNamesSection::getMergedCuSizeData() { +template +std::pair DebugNamesSection::getMergedCuSizeData() { // Once we've merged all the CU offsets into a single list, the original // DWARF form/size (often 1 byte) may be too small to hold indices to all // the offsets. Here we calculate what the right form/size needs to be for // the merged index. uint8_t size; dwarf::Form form; - // TODO: Investigate possibly using llvm::DIEInteger::BestForm here + // TODO: Investigate possibly using DIEInteger::BestForm here if (mergedHdr.CompUnitCount > 0xffffffff) { form = DW_FORM_data8; size = 8; @@ -3184,10 +3186,11 @@ std::pair DebugNamesSection::getMergedCuSizeData() { return {size, form}; } -void DebugNamesSection::getMergedAbbrevTable( +template +void DebugNamesSection::getMergedAbbrevTable( MutableArrayRef &inputChunks) { MapVector abbrevMap; - FoldingSet AbbreviationsSet; + FoldingSet AbbreviationsSet; // Need to determine what size form is needed for the DW_IDX_compile_unit // attributes in the merged index. Will need to update the abbrevs to use @@ -3199,7 +3202,7 @@ void DebugNamesSection::getMergedAbbrevTable( const auto &abbrevs = ni.getAbbrevs(); for (const DWARFDebugNames::Abbrev &abbrev : abbrevs) { // Create canonicalized abbrev. - DebugNamesSection::Abbrev newAbbrev; + Abbrev newAbbrev; DWARFDebugNames::AttributeEncoding cuOrTuAttr(DW_IDX_compile_unit, compileUnitAttrForm); newAbbrev.code = abbrev.Code; @@ -3254,14 +3257,15 @@ void DebugNamesSection::getMergedAbbrevTable( ++mergedHdr.AbbrevTableSize; // abbrev table sentinel } -void DebugNamesSection::getMergedSymbols( +template +void DebugNamesSection::getMergedSymbols( MutableArrayRef &inputChunks) { // The number of symbols (& abbrevs) we will handle is very large; will use // multi-threading to speed it up. constexpr size_t numShards = 32; const size_t concurrency = - llvm::bit_floor(std::min(config->threadCount, numShards)); - const size_t shift = 32 - llvm::countr_zero(numShards); + bit_floor(std::min(config->threadCount, numShards)); + const size_t shift = 32 - countr_zero(numShards); struct ShardData { // Map to uniquify symbols by name @@ -3330,7 +3334,8 @@ void DebugNamesSection::getMergedSymbols( mergedHdr.NameCount = mergedEntries.size(); } -void DebugNamesSection::computeUniqueHashes( +template +void DebugNamesSection::computeUniqueHashes( MutableArrayRef &chunks) { SmallVector uniques; for (const auto &chunk : chunks) @@ -3339,7 +3344,7 @@ void DebugNamesSection::computeUniqueHashes( mergedHdr.BucketCount = dwarf::getDebugNamesBucketCount(llvm::unique(uniques) - uniques.begin()); } -void DebugNamesSection::generateBuckets() { +template void DebugNamesSection::generateBuckets() { bucketList.resize(mergedHdr.BucketCount); for (auto &entry : mergedEntries) { uint32_t bucketIdx = entry.hashValue % mergedHdr.BucketCount; @@ -3349,20 +3354,20 @@ void DebugNamesSection::generateBuckets() { // Sort the contents of the buckets by hash value so that the hash collisions // end up together. for (auto &bucket : bucketList) - llvm::stable_sort(bucket, [](NamedEntry *lhs, NamedEntry *rhs) { + stable_sort(bucket, [](NamedEntry *lhs, NamedEntry *rhs) { return lhs->hashValue < rhs->hashValue; }); } -void DebugNamesSection::calculateEntriesSizeAndOffsets() { +template +void DebugNamesSection::calculateEntriesSizeAndOffsets() { uint32_t offset = 0; - for (DebugNamesSection::NamedEntry &stringEntry : mergedEntries) { + for (NamedEntry &stringEntry : mergedEntries) { stringEntry.entryOffset = offset; for (auto &entry : stringEntry.indexEntries) { uint32_t entrySize = 0; entry->poolOffset = offset; - uint32_t ulebSize = getULEB128Size(entry->abbrevCode); - entrySize += ulebSize; + entrySize += getULEB128Size(entry->abbrevCode); for (const auto &attr : entry->attrValues) entrySize += attr.attrSize; offset += entrySize; @@ -3373,8 +3378,8 @@ void DebugNamesSection::calculateEntriesSizeAndOffsets() { mergedTotalEntriesSize = offset; } -void DebugNamesSection::updateParentIndexEntries() { - for (DebugNamesSection::NamedEntry &stringEntry : mergedEntries) { +template void DebugNamesSection::updateParentIndexEntries() { + for (NamedEntry &stringEntry : mergedEntries) { for (auto &childEntry : stringEntry.indexEntries) { if (!childEntry->parentEntry) continue; @@ -3397,7 +3402,8 @@ void DebugNamesSection::updateParentIndexEntries() { } } -uint64_t DebugNamesSection::calculateMergedSectionSize() { +template +uint64_t DebugNamesSection::calculateMergedSectionSize() { uint32_t hdrSize = computeDebugNamesHeaderSize(); mergedOffsets = findDebugNamesOffsets(hdrSize, mergedHdr); // Add in the size for all the Entries, and make it 4-byte aligned. @@ -3407,8 +3413,9 @@ uint64_t DebugNamesSection::calculateMergedSectionSize() { return mergedHdr.UnitLength + 4; } -template DebugNamesSection *DebugNamesSection::create() { - llvm::TimeTraceScope timeScope("Create merged .debug_names"); +template +DebugNamesSection *DebugNamesSection::create() { + TimeTraceScope timeScope("Create merged .debug_names"); SetVector files; SmallVector sections; for (InputSectionBase *s : ctx.inputSections) { @@ -3428,28 +3435,26 @@ template DebugNamesSection *DebugNamesSection::create() { files.size()); auto outputChunks = std::make_unique(files.size()); parallelFor(0, files.size(), [&](size_t i) { - ObjFile *file = cast>(files[i]); + auto *file = cast>(files[i]); auto dwarfCtx = std::make_unique( std::make_unique>(file)); auto &dobj = static_cast &>(dwarfCtx->getDWARFObj()); - // Extract llvm::DWARFDebugNames data from the .debug_names section. The + // Extract DWARFDebugNames data from the .debug_names section. The // .debug_names section needs the .debug_str section, to get the actual // symbol names. - const StringRef &strSection = dobj.getStrSection(); + const StringRef strSection = dobj.getStrSection(); const LLDDWARFSection &namesSection = dobj.getNamesSection(); - llvm::DWARFDataExtractor namesExtractor(dobj, namesSection, config->isLE, - config->wordsize); - llvm::DataExtractor strExtractor(strSection, config->isLE, - config->wordsize); + DWARFDataExtractor namesExtractor(dobj, namesSection, config->isLE, + config->wordsize); + DataExtractor strExtractor(strSection, config->isLE, config->wordsize); inputChunks[i].debugNamesData = std::make_unique(namesExtractor, strExtractor); inputChunks[i].namesSection = std::make_unique(namesSection); - if (llvm::Error E = inputChunks[i].debugNamesData->extract()) { - // Report an error here. We were unable to extract the data. - errorOrWarn(toString(dobj.getNamesSection().sec) + ": " + + if (Error E = inputChunks[i].debugNamesData->extract()) { + errorOrWarn(toString(dobj.getNamesSection().sec) + Twine(": ") + toString(std::move(E))); } outputChunks[i].sec = dobj.getInfoSection(); @@ -3458,13 +3463,14 @@ template DebugNamesSection *DebugNamesSection::create() { }); auto *ret = make(); - ret->addSections(sections); + ret->inputDebugNamesSections = sections; ret->outputChunks = std::move(outputChunks); ret->numChunks = files.size(); ret->collectMergedCounts(inputChunks); ret->getMergedAbbrevTable(inputChunks); ret->getMergedSymbols(inputChunks); ret->computeUniqueHashes(inputChunks); + // inputChunks are needed any more. Reset now to save memory. inputChunksPtr.reset(); ret->generateBuckets(); ret->calculateEntriesSizeAndOffsets(); @@ -5035,7 +5041,7 @@ template void elf::createSyntheticSections() { add(*make()); if (config->debugNames) - add(*DebugNamesSection::create()); + add(*DebugNamesSection::create()); if (config->gdbIndex) { in.gdbIndex = GdbIndexSection::create(); add(*in.gdbIndex); diff --git a/lld/ELF/SyntheticSections.h b/lld/ELF/SyntheticSections.h index e0b01831edaa7..24ffdb3db4946 100644 --- a/lld/ELF/SyntheticSections.h +++ b/lld/ELF/SyntheticSections.h @@ -793,7 +793,7 @@ class RelroPaddingSection final : public SyntheticSection { void writeTo(uint8_t *buf) override {} }; -class DebugNamesSection final : public SyntheticSection { +template class DebugNamesSection final : public SyntheticSection { // N.B. Everything in this class assumes that we are using DWARF32. // If we move to DWARF64, most of this data will need to be re-sized, // and the code that handles or manipulates it will need to be updated @@ -801,29 +801,18 @@ class DebugNamesSection final : public SyntheticSection { public: DebugNamesSection(); - template static DebugNamesSection *create(); + static DebugNamesSection *create(); void writeTo(uint8_t *buf) override; size_t getSize() const override { return sectionSize; } bool isNeeded() const override; - void addSections(SmallVector sec_list) { - inputDebugNamesSections = sec_list; - } - - template void writeToImpl(uint8_t *buf); - - template + template void getNameRelocsImpl(InputSection *sec, ArrayRef rels, llvm::DenseMap &relocs); - template void getNameRelocs(InputSectionBase *base, llvm::DenseMap &relocs); - template - void endianWrite(uint8_t size, uint8_t *buf_start, uint32_t offset, - uint32_t data); - struct Abbrev : public llvm::FoldingSetNode { uint32_t code; uint32_t tag; diff --git a/lld/test/ELF/Inputs/debug-names-2.s b/lld/test/ELF/Inputs/debug-names-2.s index 586788653dcc7..83ddbd2050d40 100644 --- a/lld/test/ELF/Inputs/debug-names-2.s +++ b/lld/test/ELF/Inputs/debug-names-2.s @@ -1,11 +1,10 @@ #-- input file: debug-names-2.cpp ## Generated with: -## ## - clang++ -g -O0 -gpubnames -fdebug-compilation-dir='debug-names-test' \ ## -S debug-names-2.cpp -o debug-names-2.s -## + ## debug-names-2.cpp contents: -## + ## struct t1 { }; ## int main() { ## t1 v1; @@ -46,46 +45,6 @@ main: # @main .byte 1 # DWARF Unit Type .byte 8 # Address Size (in bytes) .long .debug_abbrev # Offset Into Abbrev. Section - .byte 1 # Abbrev [1] 0xc:0x3d DW_TAG_compile_unit - .byte 0 # DW_AT_producer - .short 33 # DW_AT_language - .byte 1 # DW_AT_name - .long .Lstr_offsets_base0 # DW_AT_str_offsets_base - .long .Lline_table_start0 # DW_AT_stmt_list - .byte 2 # DW_AT_comp_dir - .byte 0 # DW_AT_low_pc - .long .Lfunc_end0-.Lfunc_begin0 # DW_AT_high_pc - .long .Laddr_table_base0 # DW_AT_addr_base - .byte 2 # Abbrev [2] 0x23:0x1b DW_TAG_subprogram - .byte 0 # DW_AT_low_pc - .long .Lfunc_end0-.Lfunc_begin0 # DW_AT_high_pc - .byte 1 # DW_AT_frame_base - .byte 86 - .byte 3 # DW_AT_name - .byte 0 # DW_AT_decl_file - .byte 2 # DW_AT_decl_line - .long 62 # DW_AT_type - # DW_AT_external - .byte 3 # Abbrev [3] 0x32:0xb DW_TAG_variable - .byte 2 # DW_AT_location - .byte 145 - .byte 127 - .byte 5 # DW_AT_name - .byte 0 # DW_AT_decl_file - .byte 3 # DW_AT_decl_line - .long 66 # DW_AT_type - .byte 0 # End Of Children Mark - .byte 4 # Abbrev [4] 0x3e:0x4 DW_TAG_base_type - .byte 4 # DW_AT_name - .byte 5 # DW_AT_encoding - .byte 4 # DW_AT_byte_size - .byte 5 # Abbrev [5] 0x42:0x6 DW_TAG_structure_type - .byte 5 # DW_AT_calling_convention - .byte 6 # DW_AT_name - .byte 1 # DW_AT_byte_size - .byte 0 # DW_AT_decl_file - .byte 1 # DW_AT_decl_line - .byte 0 # End Of Children Mark .Ldebug_info_end0: .section .debug_str_offsets,"",@progbits .long 32 # Length of String Offsets Set diff --git a/lld/test/ELF/Inputs/debug-names-parent-idx-2.s b/lld/test/ELF/Inputs/debug-names-parent-idx-2.s index 7eedaaee54945..ebd93c01d8518 100644 --- a/lld/test/ELF/Inputs/debug-names-parent-idx-2.s +++ b/lld/test/ELF/Inputs/debug-names-parent-idx-2.s @@ -1,25 +1,25 @@ #-- input file: debug-names-parent-idx-2.cpp ## Generated with: -## + ## - clang++ -g -O0 -gpubnames -fdebug-compilation-dir='parent-idx-test' \ ## -S debug-names-parent-idx-2.cpp -o debug-names-parent-idx-2.s -## + ## foo.h contents: -## + ## int foo(); -## + ## struct foo { ## int x; ## char y; ## struct foo *foo_ptr; ## }; -## + ## namespace parent_test { ## int foo(); ## } -## + ## debug-names-parent-index-2.cpp contents: -## + ## #include "foo.h" ## int foo () { ## struct foo struct2; @@ -28,13 +28,13 @@ ## struct2.foo_ptr = nullptr; ## return struct2.x * (int) struct2.y; ## } -## + ## namespace parent_test { ## int foo () { ## return 25; ## } ## } -## + .text .globl _Z3foov # -- Begin function _Z3foov .p2align 4, 0x90 @@ -97,86 +97,6 @@ _ZN11parent_test3fooEv: # @_ZN11parent_test3fooEv .byte 1 # DWARF Unit Type .byte 8 # Address Size (in bytes) .long .debug_abbrev # Offset Into Abbrev. Section - .byte 1 # Abbrev [1] 0xc:0x76 DW_TAG_compile_unit - .byte 0 # DW_AT_producer - .short 33 # DW_AT_language - .byte 1 # DW_AT_name - .long .Lstr_offsets_base0 # DW_AT_str_offsets_base - .long .Lline_table_start0 # DW_AT_stmt_list - .byte 2 # DW_AT_comp_dir - .byte 0 # DW_AT_low_pc - .long .Lfunc_end1-.Lfunc_begin0 # DW_AT_high_pc - .long .Laddr_table_base0 # DW_AT_addr_base - .byte 2 # Abbrev [2] 0x23:0x4 DW_TAG_base_type - .byte 3 # DW_AT_name - .byte 5 # DW_AT_encoding - .byte 4 # DW_AT_byte_size - .byte 3 # Abbrev [3] 0x27:0x1c DW_TAG_subprogram - .byte 0 # DW_AT_low_pc - .long .Lfunc_end0-.Lfunc_begin0 # DW_AT_high_pc - .byte 1 # DW_AT_frame_base - .byte 86 - .byte 5 # DW_AT_linkage_name - .byte 6 # DW_AT_name - .byte 0 # DW_AT_decl_file - .byte 4 # DW_AT_decl_line - .long 35 # DW_AT_type - # DW_AT_external - .byte 4 # Abbrev [4] 0x37:0xb DW_TAG_variable - .byte 2 # DW_AT_location - .byte 145 - .byte 112 - .byte 8 # DW_AT_name - .byte 0 # DW_AT_decl_file - .byte 5 # DW_AT_decl_line - .long 86 # DW_AT_type - .byte 0 # End Of Children Mark - .byte 5 # Abbrev [5] 0x43:0x13 DW_TAG_namespace - .byte 4 # DW_AT_name - .byte 6 # Abbrev [6] 0x45:0x10 DW_TAG_subprogram - .byte 1 # DW_AT_low_pc - .long .Lfunc_end1-.Lfunc_begin1 # DW_AT_high_pc - .byte 1 # DW_AT_frame_base - .byte 86 - .byte 7 # DW_AT_linkage_name - .byte 6 # DW_AT_name - .byte 0 # DW_AT_decl_file - .byte 16 # DW_AT_decl_line - .long 35 # DW_AT_type - # DW_AT_external - .byte 0 # End Of Children Mark - .byte 7 # Abbrev [7] 0x56:0x22 DW_TAG_structure_type - .byte 5 # DW_AT_calling_convention - .byte 6 # DW_AT_name - .byte 16 # DW_AT_byte_size - .byte 1 # DW_AT_decl_file - .byte 4 # DW_AT_decl_line - .byte 8 # Abbrev [8] 0x5c:0x9 DW_TAG_member - .byte 9 # DW_AT_name - .long 35 # DW_AT_type - .byte 1 # DW_AT_decl_file - .byte 5 # DW_AT_decl_line - .byte 0 # DW_AT_data_member_location - .byte 8 # Abbrev [8] 0x65:0x9 DW_TAG_member - .byte 10 # DW_AT_name - .long 120 # DW_AT_type - .byte 1 # DW_AT_decl_file - .byte 6 # DW_AT_decl_line - .byte 4 # DW_AT_data_member_location - .byte 8 # Abbrev [8] 0x6e:0x9 DW_TAG_member - .byte 12 # DW_AT_name - .long 124 # DW_AT_type - .byte 1 # DW_AT_decl_file - .byte 7 # DW_AT_decl_line - .byte 8 # DW_AT_data_member_location - .byte 0 # End Of Children Mark - .byte 2 # Abbrev [2] 0x78:0x4 DW_TAG_base_type - .byte 11 # DW_AT_name - .byte 6 # DW_AT_encoding - .byte 1 # DW_AT_byte_size - .byte 9 # Abbrev [9] 0x7c:0x5 DW_TAG_pointer_type - .long 86 # DW_AT_type - .byte 0 # End Of Children Mark .Ldebug_info_end0: .section .debug_str_offsets,"",@progbits .long 56 # Length of String Offsets Set diff --git a/lld/test/ELF/debug-names-bad-aug-string.s b/lld/test/ELF/debug-names-bad-aug-string.s index ec1651362497e..0c4f625fad7c1 100644 --- a/lld/test/ELF/debug-names-bad-aug-string.s +++ b/lld/test/ELF/debug-names-bad-aug-string.s @@ -1,31 +1,30 @@ -# REQUIRES: x86 -# RUN: llvm-mc -filetype=obj -triple=x86_64 %s -o %t1.o -# RUN: llvm-mc -filetype=obj -triple=x86_64 %p/Inputs/debug-names-2.s -o %t2.o -# RUN: ld.lld --debug-names %t1.o %t2.o -o %t +// This file was generated by copying debug-names.s and manually +// editing the 'Header: augmentation string' in the .debug_names section. -# RUN: llvm-dwarfdump -debug-names %t | FileCheck %s --check-prefix=DWARF +// REQUIRES: x86 +// RUN: llvm-mc -filetype=obj -triple=x86_64 %s -o %t1.o +// RUN: llvm-mc -filetype=obj -triple=x86_64 %p/Inputs/debug-names-2.s -o %t2.o +// RUN: ld.lld --debug-names %t1.o %t2.o -o %t -# DWARF: .debug_names contents: -# DWARF: Name Index @ 0x0 { -# DWARF-NEXT: Header { -# DWARF-NEXT: Length: 0xCC -# DWARF-NEXT: Format: DWARF32 -# DWARF-NEXT: Version: 5 -# DWARF-NEXT: CU count: 2 -# DWARF-NEXT: Local TU count: 0 -# DWARF-NEXT: Foreign TU count: 0 -# DWARF-NEXT: Bucket count: 5 -# DWARF-NEXT: Name count: 5 -# DWARF-NEXT: Abbreviations table size: 0x1F -# DWARF-NEXT: Augmentation: ' ' -# DWARF: Compilation Unit offsets [ -# DWARF-NEXT: CU[0]: 0x00000000 -# DWARF-NEXT: CU[1]: 0x00000041 +// RUN: llvm-dwarfdump -debug-names %t \ +// RUN: | FileCheck -DFILE=%t1.o -DFILE=%t2.o %s --check-prefix=DWARF -## -## This file was generated by copying debug-names.s and manually -## editing the 'Header: augmentation string' in the .debug_names section. -## +// DWARF: .debug_names contents: +// DWARF: Name Index @ 0x0 { +// DWARF-NEXT: Header { +// DWARF-NEXT: Length: 0xCC +// DWARF-NEXT: Format: DWARF32 +// DWARF-NEXT: Version: 5 +// DWARF-NEXT: CU count: 2 +// DWARF-NEXT: Local TU count: 0 +// DWARF-NEXT: Foreign TU count: 0 +// DWARF-NEXT: Bucket count: 5 +// DWARF-NEXT: Name count: 5 +// DWARF-NEXT: Abbreviations table size: 0x1F +// DWARF-NEXT: Augmentation: ' ' +// DWARF: Compilation Unit offsets [ +// DWARF-NEXT: CU[0]: 0x00000000 +// DWARF-NEXT: CU[1]: 0x0000000c .text .globl _Z2f12t1 # -- Begin function _Z2f12t1 .p2align 4, 0x90 @@ -60,41 +59,6 @@ _Z2f12t1: # @_Z2f12t1 .byte 1 # DWARF Unit Type .byte 8 # Address Size (in bytes) .long .debug_abbrev # Offset Into Abbrev. Section - .byte 1 # Abbrev [1] 0xc:0x35 DW_TAG_compile_unit - .byte 0 # DW_AT_producer - .short 33 # DW_AT_language - .byte 1 # DW_AT_name - .long .Lstr_offsets_base0 # DW_AT_str_offsets_base - .long .Lline_table_start0 # DW_AT_stmt_list - .byte 2 # DW_AT_comp_dir - .byte 0 # DW_AT_low_pc - .long .Lfunc_end0-.Lfunc_begin0 # DW_AT_high_pc - .long .Laddr_table_base0 # DW_AT_addr_base - .byte 2 # Abbrev [2] 0x23:0x17 DW_TAG_subprogram - .byte 0 # DW_AT_low_pc - .long .Lfunc_end0-.Lfunc_begin0 # DW_AT_high_pc - .byte 1 # DW_AT_frame_base - .byte 86 - .byte 3 # DW_AT_linkage_name - .byte 4 # DW_AT_name - .byte 0 # DW_AT_decl_file - .byte 2 # DW_AT_decl_line - # DW_AT_external - .byte 3 # Abbrev [3] 0x2f:0xa DW_TAG_formal_parameter - .byte 2 # DW_AT_location - .byte 145 - .byte 127 - .byte 0 # DW_AT_decl_file - .byte 2 # DW_AT_decl_line - .long 58 # DW_AT_type - .byte 0 # End Of Children Mark - .byte 4 # Abbrev [4] 0x3a:0x6 DW_TAG_structure_type - .byte 5 # DW_AT_calling_convention - .byte 5 # DW_AT_name - .byte 1 # DW_AT_byte_size - .byte 0 # DW_AT_decl_file - .byte 1 # DW_AT_decl_line - .byte 0 # End Of Children Mark .Ldebug_info_end0: .section .debug_str_offsets,"",@progbits .long 28 # Length of String Offsets Set diff --git a/lld/test/ELF/debug-names-bad-die-idx-sizes.s b/lld/test/ELF/debug-names-bad-die-idx-sizes.s index 2da278a8dd5b7..e73d013f3b0ed 100644 --- a/lld/test/ELF/debug-names-bad-die-idx-sizes.s +++ b/lld/test/ELF/debug-names-bad-die-idx-sizes.s @@ -1,20 +1,20 @@ -# REQUIRES: x86 -# RUN: llvm-mc -filetype=obj -triple=x86_64 %s -o %t1.o -# -# RUN: not ld.lld --debug-names %t1.o -o /dev/null 2>&1 | FileCheck %s -# -# CHECK: error: {{.*}}:(.debug_names): encountered unexpected end of section while reading entry +// This file was generated by first compiling main.cpp: +// clang++ -g -O0 -S -gpubnames -fdebug-compilation-dir='debug-names-test' \ +// main.cpp +// Then manually edit the .debug_names section. In the entries, change the +// size of the DW_IDX_die_offset from '.long' to '.byte'. + +// Contents of main.cpp: +// int main (int argc, char **argv) { } + +// REQUIRES: x86 +// RUN: llvm-mc -filetype=obj -triple=x86_64 %s -o %t1.o + +// RUN: not ld.lld --debug-names %t1.o -o /dev/null 2>&1 \ +// RUN: | FileCheck -DFILE=%t1.o %s + +// CHECK: error: {{.*}}:(.debug_names): encountered unexpected end of section while reading entry -## This file was generated by first compiling main.cpp: -## clang++ -g -O0 -S -gpubnames -fdebug-compilation-dir='debug-names-test' \ -## main.cpp -## -## Then manually edit the .debug_names section. In the entries, change the -## size of the DW_IDX_die_offset from '.long' to '.byte'. -## -## main.cpp: -## int main (int argc, char **argv) { } -## .text .globl main # -- Begin function main .p2align 4, 0x90 diff --git a/lld/test/ELF/debug-names-bad-name-count.s b/lld/test/ELF/debug-names-bad-name-count.s index 4acfa182b11a9..cda4484b0e4c6 100644 --- a/lld/test/ELF/debug-names-bad-name-count.s +++ b/lld/test/ELF/debug-names-bad-name-count.s @@ -1,23 +1,24 @@ -# REQUIRES: x86 -# RUN: llvm-mc -filetype=obj -triple=x86_64 %s -o %t1.o -# -# RUN: not ld.lld --debug-names %t1.o -o /dev/null 2>&1 | FileCheck %s -# -# CHECK: error: {{.*}}:(.debug_names): encountered unexpected end of section while reading entry -# CHECK: error: {{.*}}:(.debug_names): encountered unexpected end of section while reading entry -# CHECK: error: {{.*}}:(.debug_names): encountered unexpected end of section while reading entry -# CHECK: error: {{.*}}:(.debug_names): encountered unexpected end of section while reading entry +// REQUIRES: x86 +// RUN: llvm-mc -filetype=obj -triple=x86_64 %s -o %t1.o + +// RUN: not ld.lld --debug-names %t1.o -o /dev/null 2>&1 \ +// RUN: FileCheck -DFILE=%t1.o %s + +// CHECK: error: {{.*}}:(.debug_names): encountered unexpected end of section while reading entry +// CHECK: error: {{.*}}:(.debug_names): encountered unexpected end of section while reading entry +// CHECK: error: {{.*}}:(.debug_names): encountered unexpected end of section while reading entry +// CHECK: error: {{.*}}:(.debug_names): encountered unexpected end of section while reading entry + +// This file was generated by first compiling main.cpp: +// clang++ -g -O0 -S -gpubnames -fdebug-compilation-dir='debug-names-test' \ +// main.cpp + +// Then manually edit .debug_names section: change value for +// 'Header: name count' from 3 to 4. + +// Contents of main.cpp: +// int main (int argc, char **argv) { } -## This file was generated by first compiling main.cpp: -## clang++ -g -O0 -S -gpubnames -fdebug-compilation-dir='debug-names-test' \ -## main.cpp -## -## Then manually edit .debug_names section: change value for -## 'Header: name count' from 3 to 4. -## -## main.cpp: -## int main (int argc, char **argv) { } -## .text .globl main # -- Begin function main .p2align 4, 0x90 diff --git a/lld/test/ELF/debug-names-bad-offsets-sizes.s b/lld/test/ELF/debug-names-bad-offsets-sizes.s index e11d19a9bf579..3e7f36b2e2175 100644 --- a/lld/test/ELF/debug-names-bad-offsets-sizes.s +++ b/lld/test/ELF/debug-names-bad-offsets-sizes.s @@ -1,22 +1,23 @@ -# REQUIRES: x86 -# RUN: llvm-mc -filetype=obj -triple=x86_64 %s -o %t1.o -# -# RUN: not ld.lld --debug-names %t1.o -o /dev/null 2>&1 | FileCheck %s -# -# CHECK: error: {{.*}}:(.debug_names): encountered unexpected end of section while reading entry -# CHECK: error: {{.*}}:(.debug_names): encountered unexpected end of section while reading entry -# CHECK: error: {{.*}}:(.debug_names): encountered unexpected end of section while reading entry +// This file was generated by first compiling main.cpp: +// clang++ -g -O0 -S -gpubnames -fdebug-compilation-dir='debug-names-test' \ +// main.cpp + +// Then manually edit .debug_names section. Change the sizes of +// 'Offset in Bucket' values from '.long' to '.byte'. + +// Contentsof main.cpp: +// int main (int argc, char **argv) { } + +// REQUIRES: x86 +// RUN: llvm-mc -filetype=obj -triple=x86_64 %s -o %t1.o + +// RUN: not ld.lld --debug-names %t1.o -o /dev/null 2>&1 \ +// RUN: | FileCheck -DFILE=%t1.o %s + +// CHECK: error: {{.*}}:(.debug_names): encountered unexpected end of section while reading entry +// CHECK: error: {{.*}}:(.debug_names): encountered unexpected end of section while reading entry +// CHECK: error: {{.*}}:(.debug_names): encountered unexpected end of section while reading entry -## This file was generated by first compiling main.cpp: -## clang++ -g -O0 -S -gpubnames -fdebug-compilation-dir='debug-names-test' \ -## main.cpp -## -## Then manually edit .debug_names section. Change the sizes of -## 'Offset in Bucket' values from '.long' to '.byte'. -## -## main.cpp: -## int main (int argc, char **argv) { } -## .text .globl main # -- Begin function main .p2align 4, 0x90 diff --git a/lld/test/ELF/debug-names-bad-version.s b/lld/test/ELF/debug-names-bad-version.s index bf1855151c20d..6a299805ca090 100644 --- a/lld/test/ELF/debug-names-bad-version.s +++ b/lld/test/ELF/debug-names-bad-version.s @@ -1,15 +1,14 @@ -# REQUIRES: x86 -# RUN: llvm-mc -filetype=obj -triple=x86_64 %s -o %t1.o -# RUN: llvm-mc -filetype=obj -triple=x86_64 %p/Inputs/debug-names-2.s -o %t2.o -# -# RUN: not ld.lld --debug-names %t1.o %t2.o -o /dev/null 2>&1 | FileCheck %s -# -# CHECK: error: {{.*}}:(.debug_names): unsupported version -## -## This file was generated by copying debug-names.s and manually -## editing the 'Header: version' in the .debug_names section (changed it from -## 5 to 4). +// This file was generated by copying debug-names.s and manually +// editing the 'Header: version' in the .debug_names section (changed it from +// 5 to 4). +// REQUIRES: x86 +// RUN: llvm-mc -filetype=obj -triple=x86_64 %s -o %t1.o +// RUN: llvm-mc -filetype=obj -triple=x86_64 %p/Inputs/debug-names-2.s -o %t2.o +// RUN: not ld.lld --debug-names %t1.o %t2.o -o /dev/null 2>&1 | FileCheck %s + +// CHECK: error: {{.*}}:(.debug_names): unsupported version + .text .globl _Z2f12t1 # -- Begin function _Z2f12t1 .p2align 4, 0x90 diff --git a/lld/test/ELF/debug-names-dwarf64.s b/lld/test/ELF/debug-names-dwarf64.s index 4391142c5558c..790f2ddeba397 100644 --- a/lld/test/ELF/debug-names-dwarf64.s +++ b/lld/test/ELF/debug-names-dwarf64.s @@ -1,17 +1,17 @@ -# REQUIRES: x86 -# RUN: llvm-mc -filetype=obj -triple=x86_64 %s -o %t1.o -# -# RUN: not ld.lld --debug-names %t1.o -o /dev/null 2>&1 | FileCheck %s -# -# CHECK: error: {{.*}}(.debug_names): unsupported DWARF64 -## -## This file was generated by: -## clang++ -g -O0 -S -fdebug-compilation-dir='debug-names-test' \ -## -gdwarf64 -gpubnames main.cpp -## -## main.cpp -## int main (int argc, char **argv) { } -## +// This file was generated by: +// clang++ -g -O0 -S -fdebug-compilation-dir='debug-names-test' \ +// -gdwarf64 -gpubnames main.cpp + +// Contents of main.cpp +// int main (int argc, char **argv) { } + +// REQUIRES: x86 +// RUN: llvm-mc -filetype=obj -triple=x86_64 %s -o %t1.o +// RUN: not ld.lld --debug-names %t1.o -o /dev/null 2>&1 \ +// RUN: | FileCheck -DFILE=%t1.o %s + +// CHECK: error: {{.*}}(.debug_names): unsupported DWARF64 + .text .globl main # -- Begin function main .p2align 4, 0x90 diff --git a/lld/test/ELF/debug-names-invalid-abbrev-code.s b/lld/test/ELF/debug-names-invalid-abbrev-code.s index 14970e0d10433..54c0105ae56b5 100644 --- a/lld/test/ELF/debug-names-invalid-abbrev-code.s +++ b/lld/test/ELF/debug-names-invalid-abbrev-code.s @@ -1,20 +1,20 @@ -# REQUIRES: x86 -# RUN: llvm-mc -filetype=obj -triple=x86_64 %s -o %t1.o -# -# RUN: not ld.lld --debug-names %t1.o -o /dev/null 2>&1 | FileCheck %s -# -# CHECK: error: {{.*}}(.debug_names): invalid abbrev code in entry -# CHECK: error: {{.*}}(.debug_names): invalid abbrev code in entry -## -## This file was generated by: -## clang++ -g -O0 -S -fdebug-compilation-dir='debug-names-test' \ -## -gpubnames main.cpp -## -## Then manually changing an abbrev code. -## -## main.cpp -## int main (int argc, char **argv) { } -## +// This file was generated by: +// clang++ -g -O0 -S -fdebug-compilation-dir='debug-names-test' \ +// -gpubnames main.cpp + +// Then manually changing an abbrev code. + +// Contents of main.cpp +// int main (int argc, char **argv) { } + +// REQUIRES: x86 +// RUN: llvm-mc -filetype=obj -triple=x86_64 %s -o %t1.o +// RUN: not ld.lld --debug-names %t1.o -o /dev/null 2>&1 \ +// RUN: | FileCheck -DFILE=%t1.o %s + +// CHECK: error: {{.*}}(.debug_names): invalid abbrev code in entry +// CHECK: error: {{.*}}(.debug_names): invalid abbrev code in entry + .text .globl main # -- Begin function main .p2align 4, 0x90 diff --git a/lld/test/ELF/debug-names-invalid-attribute-2.s b/lld/test/ELF/debug-names-invalid-attribute-2.s index 44e74911bd035..16706f0054c31 100644 --- a/lld/test/ELF/debug-names-invalid-attribute-2.s +++ b/lld/test/ELF/debug-names-invalid-attribute-2.s @@ -1,20 +1,20 @@ -# REQUIRES: x86 -# RUN: llvm-mc -filetype=obj -triple=x86_64 %s -o %t1.o -# -# RUN: not ld.lld --debug-names %t1.o -o /dev/null 2>&1 | FileCheck %s -# -# CHECK: error: {{.*}}(.debug_names): error while reading attributes: unexpected end of data at offset 0x80 while reading [0x7e, 0x82) -## -## This file was generated by: -## clang++ -g -O0 -S -fdebug-compilation-dir='debug-names-test' \ -## -gpubnames main.cpp -## -## Then manually editing .debug_names section, commenting out a -## DW_IDX_die_offset in an entry. -## -## main.cpp -## int main (int argc, char **argv) { } -## +// This file was generated by: +// clang++ -g -O0 -S -fdebug-compilation-dir='debug-names-test' \ +// -gpubnames main.cpp + +// Then manually editing .debug_names section, commenting out a +// DW_IDX_die_offset in an entry. + +// Contents of main.cpp +// int main (int argc, char **argv) { } + +// REQUIRES: x86 +// RUN: llvm-mc -filetype=obj -triple=x86_64 %s -o %t1.o +// RUN: not ld.lld --debug-names %t1.o -o /dev/null 2>&1 \ +// RUN: | FileCheck -DFILE=%t1.o %s + +// CHECK: error: {{.*}}(.debug_names): error while reading attributes: unexpected end of data at offset 0x80 while reading [0x7e, 0x82) + .text .globl main # -- Begin function main .p2align 4, 0x90 diff --git a/lld/test/ELF/debug-names-invalid-attribute-3.s b/lld/test/ELF/debug-names-invalid-attribute-3.s index 1e6ea8074975f..9b99cbe87d5a0 100644 --- a/lld/test/ELF/debug-names-invalid-attribute-3.s +++ b/lld/test/ELF/debug-names-invalid-attribute-3.s @@ -1,23 +1,22 @@ -# REQUIRES: x86 -# RUN: llvm-mc -filetype=obj -triple=x86_64 %s -o %t1.o -# -# RUN: not ld.lld --debug-names %t1.o -o /dev/null 2>&1 | FileCheck %s -# -# CHECK: error: {{.*}}(.debug_names): invalid form for attribute -## -## This file was generated by: -## clang++ -g -O0 -S -fdebug-compilation-dir='debug-names-test' \ -## -gpubnames main.cpp -## -## -## Then manually changing the first .debug_names abbrev, so that the -## DW_IDX_die_offset uses DW_FORM_flag_present (invalid) & the DW_IDX_parent -## uses DW_FORM_ref4. Also updated the sizes of the values in the entry -## that uses the abbrev, to match the sizes of the forms. -## -## main.cpp -## int main (int argc, char **argv) { } -## +// This file was generated by: +// clang++ -g -O0 -S -fdebug-compilation-dir='debug-names-test' \ +// -gpubnames main.cpp + +// Then manually changing the first .debug_names abbrev, so that the +// DW_IDX_die_offset uses DW_FORM_flag_present (invalid) & the DW_IDX_parent +// uses DW_FORM_ref4. Also updated the sizes of the values in the entry +// that uses the abbrev, to match the sizes of the forms. + +// Contents of main.cpp +// int main (int argc, char **argv) { } + +// REQUIRES: x86 +// RUN: llvm-mc -filetype=obj -triple=x86_64 %s -o %t1.o +// RUN: not ld.lld --debug-names %t1.o -o /dev/null 2>&1 \ +// RUN: | FileCheck -DFILE=%t1.o %s + +// CHECK: error: {{.*}}(.debug_names): invalid form for attribute + .text .globl main # -- Begin function main .p2align 4, 0x90 diff --git a/lld/test/ELF/debug-names-invalid-attribute.s b/lld/test/ELF/debug-names-invalid-attribute.s index 9b1a915d81f88..303337c0295da 100644 --- a/lld/test/ELF/debug-names-invalid-attribute.s +++ b/lld/test/ELF/debug-names-invalid-attribute.s @@ -1,13 +1,13 @@ -# REQUIRES: x86 -# RUN: llvm-mc -filetype=obj -triple=x86_64 %s -o %t1.o -# -# RUN: not ld.lld --debug-names %t1.o -o /dev/null 2>&1 | FileCheck %s -# -# CHECK: error: {{.*}}:(.debug_names): unrecognized form encoding 16 in .debug_names abbrev table -## -## Generated by copying debug-names.s and manually editing it to make some -## of the abbrev attributes invalid. +// Generated by copying debug-names.s and manually editing it to make some +// of the abbrev attributes invalid. +// REQUIRES: x86 +// RUN: llvm-mc -filetype=obj -triple=x86_64 %s -o %t1.o +// RUN: not ld.lld --debug-names %t1.o -o /dev/null 2>&1 \ +// RUN: | FileCheck -DFILE=%t1.o %s + +// CHECK: error: {{.*}}:(.debug_names): unrecognized form encoding 16 in .debug_names abbrev table + .text .globl _Z2f12t1 # -- Begin function _Z2f12t1 .p2align 4, 0x90 @@ -42,41 +42,6 @@ _Z2f12t1: # @_Z2f12t1 .byte 1 # DWARF Unit Type .byte 8 # Address Size (in bytes) .long .debug_abbrev # Offset Into Abbrev. Section - .byte 1 # Abbrev [1] 0xc:0x35 DW_TAG_compile_unit - .byte 0 # DW_AT_producer - .short 33 # DW_AT_language - .byte 1 # DW_AT_name - .long .Lstr_offsets_base0 # DW_AT_str_offsets_base - .long .Lline_table_start0 # DW_AT_stmt_list - .byte 2 # DW_AT_comp_dir - .byte 0 # DW_AT_low_pc - .long .Lfunc_end0-.Lfunc_begin0 # DW_AT_high_pc - .long .Laddr_table_base0 # DW_AT_addr_base - .byte 2 # Abbrev [2] 0x23:0x17 DW_TAG_subprogram - .byte 0 # DW_AT_low_pc - .long .Lfunc_end0-.Lfunc_begin0 # DW_AT_high_pc - .byte 1 # DW_AT_frame_base - .byte 86 - .byte 3 # DW_AT_linkage_name - .byte 4 # DW_AT_name - .byte 0 # DW_AT_decl_file - .byte 2 # DW_AT_decl_line - # DW_AT_external - .byte 3 # Abbrev [3] 0x2f:0xa DW_TAG_formal_parameter - .byte 2 # DW_AT_location - .byte 145 - .byte 127 - .byte 0 # DW_AT_decl_file - .byte 2 # DW_AT_decl_line - .long 58 # DW_AT_type - .byte 0 # End Of Children Mark - .byte 4 # Abbrev [4] 0x3a:0x6 DW_TAG_structure_type - .byte 5 # DW_AT_calling_convention - .byte 5 # DW_AT_name - .byte 1 # DW_AT_byte_size - .byte 0 # DW_AT_decl_file - .byte 1 # DW_AT_decl_line - .byte 0 # End Of Children Mark .Ldebug_info_end0: .section .debug_str_offsets,"",@progbits .long 28 # Length of String Offsets Set diff --git a/lld/test/ELF/debug-names-invalid-flags.s b/lld/test/ELF/debug-names-invalid-flags.s new file mode 100644 index 0000000000000..96cd4da243b68 --- /dev/null +++ b/lld/test/ELF/debug-names-invalid-flags.s @@ -0,0 +1,148 @@ +// This file was generated by: +// clang++ -g -O0 -S -fdebug-compilation-dir='debug-names-test' \ +// -gpubnames main.cpp + +// Contents of main.cpp +// int main (int argc, char **argv) { } + +// REQUIRES: x86 +// RUN: llvm-mc -filetype=obj -triple=x86_64 %s -o %t1.o +// RUN: not ld.lld --debug-names -r %t1.o -o /dev/null 2>&1 \ +// RUN: | FileCheck -DFILE=%t1.o %s + +// CHECK: error: -r and --debug-names may not be used together + + .text + .globl main # -- Begin function main + .p2align 4, 0x90 + .type main,@function +main: # @main +.Lfunc_begin0: + .cfi_startproc +# %bb.0: # %entry + pushq %rbp + .cfi_def_cfa_offset 16 + .cfi_offset %rbp, -16 + movq %rsp, %rbp + .cfi_def_cfa_register %rbp + movl %edi, -4(%rbp) + movq %rsi, -16(%rbp) +.Ltmp0: + xorl %eax, %eax + popq %rbp + .cfi_def_cfa %rsp, 8 + retq +.Ltmp1: +.Lfunc_end0: + .size main, .Lfunc_end0-main + .cfi_endproc + # -- End function + .section .debug_abbrev,"",@progbits + .byte 0 # EOM(1) + .byte 0 # EOM(2) + .byte 0 # EOM(3) + .section .debug_info,"",@progbits +.Lcu_begin0: + .long .Ldebug_info_end0-.Ldebug_info_start0 # Length of Unit +.Ldebug_info_start0: + .short 5 # DWARF version number + .byte 1 # DWARF Unit Type + .byte 8 # Address Size (in bytes) + .long .debug_abbrev # Offset Into Abbrev. Section +.Ldebug_info_end0: + .section .debug_str_offsets,"",@progbits + .long 36 # Length of String Offsets Set + .short 5 + .short 0 +.Lstr_offsets_base0: + .section .debug_str,"MS",@progbits,1 +.Linfo_string0: + .asciz "clang version 19.0.0git (git@github.com:llvm/llvm-project.git d33d5630b281debe6eabd67e323bcf767340fb6a)" # string offset=0 +.Linfo_string1: + .asciz "main.cpp" # string offset=104 +.Linfo_string2: + .asciz "debug-names-test" # string offset=113 +.Linfo_string3: + .asciz "main" # string offset=130 +.Linfo_string4: + .asciz "int" # string offset=135 +.Linfo_string5: + .asciz "argc" # string offset=139 +.Linfo_string6: + .asciz "argv" # string offset=144 +.Linfo_string7: + .asciz "char" # string offset=149 +.Laddr_table_base0: + .quad .Lfunc_begin0 +.Ldebug_addr_end0: + .section .debug_names,"",@progbits + .long .Lnames_end0-.Lnames_start0 # Header: unit length +.Lnames_start0: + .short 5 # Header: version + .short 0 # Header: padding + .long 1 # Header: compilation unit count + .long 0 # Header: local type unit count + .long 0 # Header: foreign type unit count + .long 3 # Header: bucket count + .long 3 # Header: name count + .long .Lnames_abbrev_end0-.Lnames_abbrev_start0 # Header: abbreviation table size + .long 8 # Header: augmentation string size + .ascii "LLVM0700" # Header: augmentation string + .long .Lcu_begin0 # Compilation unit 0 + .long 0 # Bucket 0 + .long 1 # Bucket 1 + .long 2 # Bucket 2 + .long 2090499946 # Hash in Bucket 1 + .long 193495088 # Hash in Bucket 2 + .long 2090147939 # Hash in Bucket 2 + .long .Linfo_string3 # String in Bucket 1: main + .long .Linfo_string4 # String in Bucket 2: int + .long .Linfo_string7 # String in Bucket 2: char + .long .Lnames0-.Lnames_entries0 # Offset in Bucket 1 + .long .Lnames1-.Lnames_entries0 # Offset in Bucket 2 + .long .Lnames2-.Lnames_entries0 # Offset in Bucket 2 +.Lnames_abbrev_start0: + .byte 1 # Abbrev code + .byte 46 # DW_TAG_subprogram + .byte 3 # DW_IDX_die_offset + .byte 19 # DW_FORM_ref4 + .byte 4 # DW_IDX_parent + .byte 25 # DW_FORM_flag_present + .byte 0 # End of abbrev + .byte 0 # End of abbrev + .byte 2 # Abbrev code + .byte 36 # DW_TAG_base_type + .byte 3 # DW_IDX_die_offset + .byte 19 # DW_FORM_ref4 + .byte 4 # DW_IDX_parent + .byte 25 # DW_FORM_flag_present + .byte 0 # End of abbrev + .byte 0 # End of abbrev + .byte 0 # End of abbrev list +.Lnames_abbrev_end0: +.Lnames_entries0: +.Lnames0: +.L1: + .byte 1 # Abbreviation code + .long 35 # DW_IDX_die_offset + .byte 0 # DW_IDX_parent + # End of list: main +.Lnames1: +.L0: + .byte 2 # Abbreviation code + .long 73 # DW_IDX_die_offset + .byte 0 # DW_IDX_parent + # End of list: int +.Lnames2: +.L2: + .byte 2 # Abbreviation code + .long 87 # DW_IDX_die_offset + .byte 0 # DW_IDX_parent + # End of list: char + .p2align 2, 0x0 +.Lnames_end0: + .ident "clang version 19.0.0git (git@github.com:llvm/llvm-project.git d33d5630b281debe6eabd67e323bcf767340fb6a)" + .section ".note.GNU-stack","",@progbits + .addrsig + .section .debug_line,"",@progbits +.Lline_table_start0: diff --git a/lld/test/ELF/debug-names-invalid-parent-idx.s b/lld/test/ELF/debug-names-invalid-parent-idx.s index be5df8b155250..698183880445a 100644 --- a/lld/test/ELF/debug-names-invalid-parent-idx.s +++ b/lld/test/ELF/debug-names-invalid-parent-idx.s @@ -1,22 +1,22 @@ -# REQUIRES: x86 -# RUN: llvm-mc -filetype=obj -triple=x86_64 %s -o %t1.o -# -# RUN: not ld.lld --debug-names %t1.o -o /dev/null 2>&1 | FileCheck %s -# -# CHECK: error: {{.*}}(.debug_names): invalid form for DW_IDX_parent -# CHECK: error: {{.*}}(.debug_names): invalid form for DW_IDX_parent -# CHECK: error: {{.*}}(.debug_names): invalid form for DW_IDX_parent -## -## This file was generated by: -## clang++ -g -O0 -S -fdebug-compilation-dir='debug-names-test' \ -## -gpubnames main.cpp -## -## Then manually editing .debug_names section, changing the form for a -## DW_IDX_parent from DW_FORM_flag_present to DW_FORM_ref1 (invalid). -## -## main.cpp -## int main (int argc, char **argv) { } -## +// This file was generated by: +// clang++ -g -O0 -S -fdebug-compilation-dir='debug-names-test' \ +// -gpubnames main.cpp + +// Then manually editing .debug_names section, changing the form for a +// DW_IDX_parent from DW_FORM_flag_present to DW_FORM_ref1 (invalid). + +// Contents of main.cpp +// int main (int argc, char **argv) { } + +// REQUIRES: x86 +// RUN: llvm-mc -filetype=obj -triple=x86_64 %s -o %t1.o +// RUN: not ld.lld --debug-names %t1.o -o /dev/null 2>&1 \ +// RUN: | FileCheck -DFILE=%t1.o %s + +// CHECK: error: {{.*}}(.debug_names): invalid form for DW_IDX_parent +// CHECK: error: {{.*}}(.debug_names): invalid form for DW_IDX_parent +// CHECK: error: {{.*}}(.debug_names): invalid form for DW_IDX_parent + .text .globl main # -- Begin function main .p2align 4, 0x90 diff --git a/lld/test/ELF/debug-names-parent-idx.s b/lld/test/ELF/debug-names-parent-idx.s index a4e8682cd9ee5..cda9203fd2167 100644 --- a/lld/test/ELF/debug-names-parent-idx.s +++ b/lld/test/ELF/debug-names-parent-idx.s @@ -1,188 +1,188 @@ -# REQUIRES: x86 -# RUN: llvm-mc -filetype=obj -triple=x86_64 %s -o %t1.o -# RUN: llvm-mc -filetype=obj -triple=x86_64 %p/Inputs/debug-names-parent-idx-2.s -o %t2.o -# RUN: ld.lld --debug-names %t1.o %t2.o -o %t +// Generated with: -# RUN: llvm-dwarfdump -debug-names %t | FileCheck %s --check-prefix=DWARF +// - clang++ -g -O0 -gpubnames -fdebug-compilation-dir='parent-idx-test' \ +// -S debug-names-parent-idx.cpp -o debug-names-parent-idx.s + +// foo.h contents: + +// int foo(); + +// struct foo { +// int x; +// char y; +// struct foo *foo_ptr; +// }; + +// namespace parent_test { +// int foo(); +// } + +// debug-names-parent-idx.cpp contents: + +// #include "foo.h" +// void bar (struct foo &foo, int junk) { +// foo.x = foo.x * junk; +// } +// int main (int argc, char** argv) { +// struct foo my_struct; +// my_struct.x = 10; +// my_struct.y = 'q'; +// my_struct.foo_ptr = nullptr; +// int junk = foo(); +// bar(my_struct, junk); +// int junk2 = parent_test::foo(); +// return 0; +// } + +// REQUIRES: x86 +// RUN: llvm-mc -filetype=obj -triple=x86_64 %s -o %t1.o +// RUN: llvm-mc -filetype=obj -triple=x86_64 %p/Inputs/debug-names-parent-idx-2.s -o %t2.o +// RUN: ld.lld --debug-names %t1.o %t2.o -o %t + +// RUN: llvm-dwarfdump -debug-names %t \ +// RUN: | FileCheck -DFILE=%t1.o -DFILE=%t2.o %s --check-prefix=DWARF + +// DWARF: .debug_names contents: +// DWARF: Name Index @ 0x0 { +// DWARF-NEXT: Header { +// DWARF-NEXT: Length: 0x15C +// DWARF-NEXT: Format: DWARF32 +// DWARF-NEXT: Version: 5 +// DWARF-NEXT: CU count: 2 +// DWARF-NEXT: Local TU count: 0 +// DWARF-NEXT: Foreign TU count: 0 +// DWARF-NEXT: Bucket count: 9 +// DWARF-NEXT: Name count: 9 +// DWARF-NEXT: Abbreviations table size: 0x33 +// DWARF-NEXT: Augmentation: 'LLVM0700' +// DWARF: Compilation Unit offsets [ +// DWARF-NEXT: CU[0]: 0x00000000 +// DWARF-NEXT: CU[1]: 0x0000000c +// DWARF: Abbreviations [ +// DWARF-NEXT: Abbreviation 0x1 { +// DWARF-NEXT: Tag: DW_TAG_base_type +// DWARF-NEXT: DW_IDX_die_offset: DW_FORM_ref4 +// DWARF-NEXT: DW_IDX_parent: DW_FORM_flag_present +// DWARF-NEXT: DW_IDX_compile_unit: DW_FORM_data1 +// DWARF: Abbreviation 0x2 { +// DWARF-NEXT: Tag: DW_TAG_subprogram +// DWARF-NEXT: DW_IDX_die_offset: DW_FORM_ref4 +// DWARF-NEXT: DW_IDX_parent: DW_FORM_flag_present +// DWARF-NEXT: DW_IDX_compile_unit: DW_FORM_data1 +// DWARF: Abbreviation 0x3 { +// DWARF-NEXT: Tag: DW_TAG_structure_type +// DWARF-NEXT: DW_IDX_die_offset: DW_FORM_ref4 +// DWARF-NEXT: DW_IDX_parent: DW_FORM_flag_present +// DWARF-NEXT: DW_IDX_compile_unit: DW_FORM_data1 +// DWARF: Abbreviation 0x4 { +// DWARF-NEXT: Tag: DW_TAG_subprogram +// DWARF-NEXT: DW_IDX_die_offset: DW_FORM_ref4 +// DWARF-NEXT: DW_IDX_parent: DW_FORM_ref4 +// DWARF-NEXT: DW_IDX_compile_unit: DW_FORM_data1 +// DWARF: Abbreviation 0x5 { +// DWARF-NEXT: Tag: DW_TAG_namespace +// DWARF-NEXT: DW_IDX_die_offset: DW_FORM_ref4 +// DWARF-NEXT: DW_IDX_parent: DW_FORM_flag_present +// DWARF-NEXT: DW_IDX_compile_unit: DW_FORM_data1 +// DWARF: String: 0x00000093 "bar" +// DWARF-NEXT: Entry @ 0xf7 { +// DWARF-NEXT: Abbrev: 0x2 +// DWARF-NEXT: Tag: DW_TAG_subprogram +// DWARF-NEXT: DW_IDX_die_offset: 0x00000023 +// DWARF-NEXT: DW_IDX_parent: +// DWARF-NEXT: DW_IDX_compile_unit: 0x00 +// DWARF: String: 0x000000a9 "int" +// DWARF-NEXT: Entry @ 0xfe { +// DWARF-NEXT: Abbrev: 0x1 +// DWARF-NEXT: Tag: DW_TAG_base_type +// DWARF-NEXT: DW_IDX_die_offset: 0x0000008d +// DWARF-NEXT: DW_IDX_parent: +// DWARF-NEXT: DW_IDX_compile_unit: 0x00 +// DWARF-NEXT: } +// DWARF-NEXT: Entry @ 0x104 { +// DWARF-NEXT: Abbrev: 0x1 +// DWARF-NEXT: Tag: DW_TAG_base_type +// DWARF-NEXT: DW_IDX_die_offset: 0x00000023 +// DWARF-NEXT: DW_IDX_parent: +// DWARF-NEXT: DW_IDX_compile_unit: 0x01 +// DWARF: String: 0x000000ad "foo" +// DWARF-NEXT: Entry @ 0x10b { +// DWARF-NEXT: Abbrev: 0x3 +// DWARF-NEXT: Tag: DW_TAG_structure_type +// DWARF-NEXT: DW_IDX_die_offset: 0x00000096 +// DWARF-NEXT: DW_IDX_parent: +// DWARF-NEXT: DW_IDX_compile_unit: 0x00 +// DWARF-NEXT: } +// DWARF-NEXT: Entry @ 0x111 { +// DWARF-NEXT: Abbrev: 0x2 +// DWARF-NEXT: Tag: DW_TAG_subprogram +// DWARF-NEXT: DW_IDX_die_offset: 0x00000027 +// DWARF-NEXT: DW_IDX_parent: +// DWARF-NEXT: DW_IDX_compile_unit: 0x01 +// DWARF-NEXT: } +// DWARF-NEXT: Entry @ 0x117 { +// DWARF-NEXT: Abbrev: 0x4 +// DWARF-NEXT: Tag: DW_TAG_subprogram +// DWARF-NEXT: DW_IDX_die_offset: 0x00000045 +// DWARF-NEXT: DW_IDX_parent: Entry @ 0x128 +// DWARF-NEXT: DW_IDX_compile_unit: 0x01 +// DWARF-NEXT: } +// DWARF-NEXT: Entry @ 0x121 { +// DWARF-NEXT: Abbrev: 0x3 +// DWARF-NEXT: Tag: DW_TAG_structure_type +// DWARF-NEXT: DW_IDX_die_offset: 0x00000056 +// DWARF-NEXT: DW_IDX_parent: +// DWARF-NEXT: DW_IDX_compile_unit: 0x01 +// DWARF: String: 0x00000196 "parent_test" +// DWARF-NEXT: Entry @ 0x128 { +// DWARF-NEXT: Abbrev: 0x5 +// DWARF-NEXT: Tag: DW_TAG_namespace +// DWARF-NEXT: DW_IDX_die_offset: 0x00000043 +// DWARF-NEXT: DW_IDX_parent: +// DWARF-NEXT: DW_IDX_compile_unit: 0x01 +// DWARF: String: 0x00000097 "_Z3barR3fooi" +// DWARF-NEXT: Entry @ 0x12f { +// DWARF-NEXT: Abbrev: 0x2 +// DWARF-NEXT: Tag: DW_TAG_subprogram +// DWARF-NEXT: DW_IDX_die_offset: 0x00000023 +// DWARF-NEXT: DW_IDX_parent: +// DWARF-NEXT: DW_IDX_compile_unit: 0x00 +// DWARF: String: 0x000000a4 "main" +// DWARF-NEXT: Entry @ 0x136 { +// DWARF-NEXT: Abbrev: 0x2 +// DWARF-NEXT: Tag: DW_TAG_subprogram +// DWARF-NEXT: DW_IDX_die_offset: 0x00000046 +// DWARF-NEXT: DW_IDX_parent: +// DWARF-NEXT: DW_IDX_compile_unit: 0x00 +// DWARF: String: 0x000000b5 "char" +// DWARF-NEXT: Entry @ 0x13d { +// DWARF-NEXT: Abbrev: 0x1 +// DWARF-NEXT: Tag: DW_TAG_base_type +// DWARF-NEXT: DW_IDX_die_offset: 0x000000b8 +// DWARF-NEXT: DW_IDX_parent: +// DWARF-NEXT: DW_IDX_compile_unit: 0x00 +// DWARF-NEXT: } +// DWARF-NEXT: Entry @ 0x143 { +// DWARF-NEXT: Abbrev: 0x1 +// DWARF-NEXT: Tag: DW_TAG_base_type +// DWARF-NEXT: DW_IDX_die_offset: 0x00000078 +// DWARF-NEXT: DW_IDX_parent: +// DWARF-NEXT: DW_IDX_compile_unit: 0x01 +// DWARF: String: 0x000001a2 "_ZN11parent_test3fooEv" +// DWARF-NEXT: Entry @ 0x14a { +// DWARF-NEXT: Abbrev: 0x4 +// DWARF-NEXT: Tag: DW_TAG_subprogram +// DWARF-NEXT: DW_IDX_die_offset: 0x00000045 +// DWARF-NEXT: DW_IDX_parent: Entry @ 0x128 +// DWARF-NEXT: DW_IDX_compile_unit: 0x01 +// DWARF: String: 0x0000018e "_Z3foov" +// DWARF-NEXT: Entry @ 0x155 { +// DWARF-NEXT: Abbrev: 0x2 +// DWARF-NEXT: Tag: DW_TAG_subprogram +// DWARF-NEXT: DW_IDX_die_offset: 0x00000027 +// DWARF-NEXT: DW_IDX_parent: +// DWARF-NEXT: DW_IDX_compile_unit: 0x01 -# DWARF: .debug_names contents: -# DWARF: Name Index @ 0x0 { -# DWARF-NEXT: Header { -# DWARF-NEXT: Length: 0x15C -# DWARF-NEXT: Format: DWARF32 -# DWARF-NEXT: Version: 5 -# DWARF-NEXT: CU count: 2 -# DWARF-NEXT: Local TU count: 0 -# DWARF-NEXT: Foreign TU count: 0 -# DWARF-NEXT: Bucket count: 9 -# DWARF-NEXT: Name count: 9 -# DWARF-NEXT: Abbreviations table size: 0x33 -# DWARF-NEXT: Augmentation: 'LLVM0700' -# DWARF: Compilation Unit offsets [ -# DWARF-NEXT: CU[0]: 0x00000000 -# DWARF-NEXT: CU[1]: 0x000000cc -# DWARF: Abbreviations [ -# DWARF-NEXT: Abbreviation 0x1 { -# DWARF-NEXT: Tag: DW_TAG_base_type -# DWARF-NEXT: DW_IDX_die_offset: DW_FORM_ref4 -# DWARF-NEXT: DW_IDX_parent: DW_FORM_flag_present -# DWARF-NEXT: DW_IDX_compile_unit: DW_FORM_data1 -# DWARF: Abbreviation 0x2 { -# DWARF-NEXT: Tag: DW_TAG_subprogram -# DWARF-NEXT: DW_IDX_die_offset: DW_FORM_ref4 -# DWARF-NEXT: DW_IDX_parent: DW_FORM_flag_present -# DWARF-NEXT: DW_IDX_compile_unit: DW_FORM_data1 -# DWARF: Abbreviation 0x3 { -# DWARF-NEXT: Tag: DW_TAG_structure_type -# DWARF-NEXT: DW_IDX_die_offset: DW_FORM_ref4 -# DWARF-NEXT: DW_IDX_parent: DW_FORM_flag_present -# DWARF-NEXT: DW_IDX_compile_unit: DW_FORM_data1 -# DWARF: Abbreviation 0x4 { -# DWARF-NEXT: Tag: DW_TAG_subprogram -# DWARF-NEXT: DW_IDX_die_offset: DW_FORM_ref4 -# DWARF-NEXT: DW_IDX_parent: DW_FORM_ref4 -# DWARF-NEXT: DW_IDX_compile_unit: DW_FORM_data1 -# DWARF: Abbreviation 0x5 { -# DWARF-NEXT: Tag: DW_TAG_namespace -# DWARF-NEXT: DW_IDX_die_offset: DW_FORM_ref4 -# DWARF-NEXT: DW_IDX_parent: DW_FORM_flag_present -# DWARF-NEXT: DW_IDX_compile_unit: DW_FORM_data1 -# DWARF: String: 0x00000093 "bar" -# DWARF-NEXT: Entry @ 0xf7 { -# DWARF-NEXT: Abbrev: 0x2 -# DWARF-NEXT: Tag: DW_TAG_subprogram -# DWARF-NEXT: DW_IDX_die_offset: 0x00000023 -# DWARF-NEXT: DW_IDX_parent: -# DWARF-NEXT: DW_IDX_compile_unit: 0x00 -# DWARF: String: 0x000000a9 "int" -# DWARF-NEXT: Entry @ 0xfe { -# DWARF-NEXT: Abbrev: 0x1 -# DWARF-NEXT: Tag: DW_TAG_base_type -# DWARF-NEXT: DW_IDX_die_offset: 0x0000008d -# DWARF-NEXT: DW_IDX_parent: -# DWARF-NEXT: DW_IDX_compile_unit: 0x00 -# DWARF-NEXT: } -# DWARF-NEXT: Entry @ 0x104 { -# DWARF-NEXT: Abbrev: 0x1 -# DWARF-NEXT: Tag: DW_TAG_base_type -# DWARF-NEXT: DW_IDX_die_offset: 0x00000023 -# DWARF-NEXT: DW_IDX_parent: -# DWARF-NEXT: DW_IDX_compile_unit: 0x01 -# DWARF: String: 0x000000ad "foo" -# DWARF-NEXT: Entry @ 0x10b { -# DWARF-NEXT: Abbrev: 0x3 -# DWARF-NEXT: Tag: DW_TAG_structure_type -# DWARF-NEXT: DW_IDX_die_offset: 0x00000096 -# DWARF-NEXT: DW_IDX_parent: -# DWARF-NEXT: DW_IDX_compile_unit: 0x00 -# DWARF-NEXT: } -# DWARF-NEXT: Entry @ 0x111 { -# DWARF-NEXT: Abbrev: 0x2 -# DWARF-NEXT: Tag: DW_TAG_subprogram -# DWARF-NEXT: DW_IDX_die_offset: 0x00000027 -# DWARF-NEXT: DW_IDX_parent: -# DWARF-NEXT: DW_IDX_compile_unit: 0x01 -# DWARF-NEXT: } -# DWARF-NEXT: Entry @ 0x117 { -# DWARF-NEXT: Abbrev: 0x4 -# DWARF-NEXT: Tag: DW_TAG_subprogram -# DWARF-NEXT: DW_IDX_die_offset: 0x00000045 -# DWARF-NEXT: DW_IDX_parent: Entry @ 0x128 -# DWARF-NEXT: DW_IDX_compile_unit: 0x01 -# DWARF-NEXT: } -# DWARF-NEXT: Entry @ 0x121 { -# DWARF-NEXT: Abbrev: 0x3 -# DWARF-NEXT: Tag: DW_TAG_structure_type -# DWARF-NEXT: DW_IDX_die_offset: 0x00000056 -# DWARF-NEXT: DW_IDX_parent: -# DWARF-NEXT: DW_IDX_compile_unit: 0x01 -# DWARF: String: 0x00000196 "parent_test" -# DWARF-NEXT: Entry @ 0x128 { -# DWARF-NEXT: Abbrev: 0x5 -# DWARF-NEXT: Tag: DW_TAG_namespace -# DWARF-NEXT: DW_IDX_die_offset: 0x00000043 -# DWARF-NEXT: DW_IDX_parent: -# DWARF-NEXT: DW_IDX_compile_unit: 0x01 -# DWARF: String: 0x00000097 "_Z3barR3fooi" -# DWARF-NEXT: Entry @ 0x12f { -# DWARF-NEXT: Abbrev: 0x2 -# DWARF-NEXT: Tag: DW_TAG_subprogram -# DWARF-NEXT: DW_IDX_die_offset: 0x00000023 -# DWARF-NEXT: DW_IDX_parent: -# DWARF-NEXT: DW_IDX_compile_unit: 0x00 -# DWARF: String: 0x000000a4 "main" -# DWARF-NEXT: Entry @ 0x136 { -# DWARF-NEXT: Abbrev: 0x2 -# DWARF-NEXT: Tag: DW_TAG_subprogram -# DWARF-NEXT: DW_IDX_die_offset: 0x00000046 -# DWARF-NEXT: DW_IDX_parent: -# DWARF-NEXT: DW_IDX_compile_unit: 0x00 -# DWARF: String: 0x000000b5 "char" -# DWARF-NEXT: Entry @ 0x13d { -# DWARF-NEXT: Abbrev: 0x1 -# DWARF-NEXT: Tag: DW_TAG_base_type -# DWARF-NEXT: DW_IDX_die_offset: 0x000000b8 -# DWARF-NEXT: DW_IDX_parent: -# DWARF-NEXT: DW_IDX_compile_unit: 0x00 -# DWARF-NEXT: } -# DWARF-NEXT: Entry @ 0x143 { -# DWARF-NEXT: Abbrev: 0x1 -# DWARF-NEXT: Tag: DW_TAG_base_type -# DWARF-NEXT: DW_IDX_die_offset: 0x00000078 -# DWARF-NEXT: DW_IDX_parent: -# DWARF-NEXT: DW_IDX_compile_unit: 0x01 -# DWARF: String: 0x000001a2 "_ZN11parent_test3fooEv" -# DWARF-NEXT: Entry @ 0x14a { -# DWARF-NEXT: Abbrev: 0x4 -# DWARF-NEXT: Tag: DW_TAG_subprogram -# DWARF-NEXT: DW_IDX_die_offset: 0x00000045 -# DWARF-NEXT: DW_IDX_parent: Entry @ 0x128 -# DWARF-NEXT: DW_IDX_compile_unit: 0x01 -# DWARF: String: 0x0000018e "_Z3foov" -# DWARF-NEXT: Entry @ 0x155 { -# DWARF-NEXT: Abbrev: 0x2 -# DWARF-NEXT: Tag: DW_TAG_subprogram -# DWARF-NEXT: DW_IDX_die_offset: 0x00000027 -# DWARF-NEXT: DW_IDX_parent: -# DWARF-NEXT: DW_IDX_compile_unit: 0x01 - -#-- input file: debug-names-parent-idx.cpp -## Generated with: -## -## - clang++ -g -O0 -gpubnames -fdebug-compilation-dir='parent-idx-test' \ -## -S debug-names-parent-idx.cpp -o debug-names-parent-idx.s -## -## foo.h contents: -## -## int foo(); -## -## struct foo { -## int x; -## char y; -## struct foo *foo_ptr; -## }; -## -## namespace parent_test { -## int foo(); -## } -## -## debug-names-parent-idx.cpp contents: -## -## #include "foo.h" -## void bar (struct foo &foo, int junk) { -## foo.x = foo.x * junk; -## } -## int main (int argc, char** argv) { -## struct foo my_struct; -## my_struct.x = 10; -## my_struct.y = 'q'; -## my_struct.foo_ptr = nullptr; -## int junk = foo(); -## bar(my_struct, junk); -## int junk2 = parent_test::foo(); -## return 0; -## } -## .text .globl _Z3barR3fooi # -- Begin function _Z3barR3fooi .p2align 4, 0x90 @@ -261,136 +261,6 @@ main: # @main .byte 1 # DWARF Unit Type .byte 8 # Address Size (in bytes) .long .debug_abbrev # Offset Into Abbrev. Section - .byte 1 # Abbrev [1] 0xc:0xc0 DW_TAG_compile_unit - .byte 0 # DW_AT_producer - .short 33 # DW_AT_language - .byte 1 # DW_AT_name - .long .Lstr_offsets_base0 # DW_AT_str_offsets_base - .long .Lline_table_start0 # DW_AT_stmt_list - .byte 2 # DW_AT_comp_dir - .byte 0 # DW_AT_low_pc - .long .Lfunc_end1-.Lfunc_begin0 # DW_AT_high_pc - .long .Laddr_table_base0 # DW_AT_addr_base - .byte 2 # Abbrev [2] 0x23:0x23 DW_TAG_subprogram - .byte 0 # DW_AT_low_pc - .long .Lfunc_end0-.Lfunc_begin0 # DW_AT_high_pc - .byte 1 # DW_AT_frame_base - .byte 86 - .byte 3 # DW_AT_linkage_name - .byte 4 # DW_AT_name - .byte 0 # DW_AT_decl_file - .byte 3 # DW_AT_decl_line - # DW_AT_external - .byte 3 # Abbrev [3] 0x2f:0xb DW_TAG_formal_parameter - .byte 2 # DW_AT_location - .byte 145 - .byte 120 - .byte 7 # DW_AT_name - .byte 0 # DW_AT_decl_file - .byte 3 # DW_AT_decl_line - .long 145 # DW_AT_type - .byte 3 # Abbrev [3] 0x3a:0xb DW_TAG_formal_parameter - .byte 2 # DW_AT_location - .byte 145 - .byte 116 - .byte 12 # DW_AT_name - .byte 0 # DW_AT_decl_file - .byte 3 # DW_AT_decl_line - .long 141 # DW_AT_type - .byte 0 # End Of Children Mark - .byte 4 # Abbrev [4] 0x46:0x47 DW_TAG_subprogram - .byte 1 # DW_AT_low_pc - .long .Lfunc_end1-.Lfunc_begin1 # DW_AT_high_pc - .byte 1 # DW_AT_frame_base - .byte 86 - .byte 5 # DW_AT_name - .byte 0 # DW_AT_decl_file - .byte 7 # DW_AT_decl_line - .long 141 # DW_AT_type - # DW_AT_external - .byte 3 # Abbrev [3] 0x55:0xb DW_TAG_formal_parameter - .byte 2 # DW_AT_location - .byte 145 - .byte 120 - .byte 13 # DW_AT_name - .byte 0 # DW_AT_decl_file - .byte 7 # DW_AT_decl_line - .long 141 # DW_AT_type - .byte 3 # Abbrev [3] 0x60:0xb DW_TAG_formal_parameter - .byte 2 # DW_AT_location - .byte 145 - .byte 112 - .byte 14 # DW_AT_name - .byte 0 # DW_AT_decl_file - .byte 7 # DW_AT_decl_line - .long 193 # DW_AT_type - .byte 5 # Abbrev [5] 0x6b:0xb DW_TAG_variable - .byte 2 # DW_AT_location - .byte 145 - .byte 96 - .byte 15 # DW_AT_name - .byte 0 # DW_AT_decl_file - .byte 9 # DW_AT_decl_line - .long 150 # DW_AT_type - .byte 5 # Abbrev [5] 0x76:0xb DW_TAG_variable - .byte 2 # DW_AT_location - .byte 145 - .byte 92 - .byte 12 # DW_AT_name - .byte 0 # DW_AT_decl_file - .byte 14 # DW_AT_decl_line - .long 141 # DW_AT_type - .byte 5 # Abbrev [5] 0x81:0xb DW_TAG_variable - .byte 2 # DW_AT_location - .byte 145 - .byte 88 - .byte 16 # DW_AT_name - .byte 0 # DW_AT_decl_file - .byte 16 # DW_AT_decl_line - .long 141 # DW_AT_type - .byte 0 # End Of Children Mark - .byte 6 # Abbrev [6] 0x8d:0x4 DW_TAG_base_type - .byte 6 # DW_AT_name - .byte 5 # DW_AT_encoding - .byte 4 # DW_AT_byte_size - .byte 7 # Abbrev [7] 0x91:0x5 DW_TAG_reference_type - .long 150 # DW_AT_type - .byte 8 # Abbrev [8] 0x96:0x22 DW_TAG_structure_type - .byte 5 # DW_AT_calling_convention - .byte 7 # DW_AT_name - .byte 16 # DW_AT_byte_size - .byte 1 # DW_AT_decl_file - .byte 4 # DW_AT_decl_line - .byte 9 # Abbrev [9] 0x9c:0x9 DW_TAG_member - .byte 8 # DW_AT_name - .long 141 # DW_AT_type - .byte 1 # DW_AT_decl_file - .byte 5 # DW_AT_decl_line - .byte 0 # DW_AT_data_member_location - .byte 9 # Abbrev [9] 0xa5:0x9 DW_TAG_member - .byte 9 # DW_AT_name - .long 184 # DW_AT_type - .byte 1 # DW_AT_decl_file - .byte 6 # DW_AT_decl_line - .byte 4 # DW_AT_data_member_location - .byte 9 # Abbrev [9] 0xae:0x9 DW_TAG_member - .byte 11 # DW_AT_name - .long 188 # DW_AT_type - .byte 1 # DW_AT_decl_file - .byte 7 # DW_AT_decl_line - .byte 8 # DW_AT_data_member_location - .byte 0 # End Of Children Mark - .byte 6 # Abbrev [6] 0xb8:0x4 DW_TAG_base_type - .byte 10 # DW_AT_name - .byte 6 # DW_AT_encoding - .byte 1 # DW_AT_byte_size - .byte 10 # Abbrev [10] 0xbc:0x5 DW_TAG_pointer_type - .long 150 # DW_AT_type - .byte 10 # Abbrev [10] 0xc1:0x5 DW_TAG_pointer_type - .long 198 # DW_AT_type - .byte 10 # Abbrev [10] 0xc6:0x5 DW_TAG_pointer_type - .long 184 # DW_AT_type - .byte 0 # End Of Children Mark .Ldebug_info_end0: .section .debug_str_offsets,"",@progbits .long 72 # Length of String Offsets Set diff --git a/lld/test/ELF/debug-names.s b/lld/test/ELF/debug-names.s index ce013303f65f6..ca6d32998542b 100644 --- a/lld/test/ELF/debug-names.s +++ b/lld/test/ELF/debug-names.s @@ -1,136 +1,110 @@ -# REQUIRES: x86 -# RUN: llvm-mc -filetype=obj -triple=x86_64 %s -o %t1.o -# RUN: llvm-mc -filetype=obj -triple=x86_64 %p/Inputs/debug-names-2.s -o %t2.o -# RUN: ld.lld --debug-names %t1.o %t2.o -o %t +// Generated with: -# RUN: llvm-objdump -d %t | FileCheck %s --check-prefix=DISASM -# RUN: llvm-dwarfdump -debug-names %t | FileCheck %s --check-prefix=DWARF -# RUN: llvm-readelf -SW %t | FileCheck %s --check-prefix=READELF - -# DISASM: Disassembly of section .text: -# DISASM-EMPTY: -# DISASM: <_Z2f12t1>: -# DISASM-CHECK: 201180: 55 pushq %rbp -# DISASM-CHECK: 201181: 48 89 e5 movq %rsp, %rbp -# DISASM-CHECK: 201184: 5d popq %rbp -# DISASM-CHECK: 201185: c3 retq -# DISASM-CHECK: 201186: cc int3 -# DISASM-CHECK: 201187: cc int3 -# DISASM-CHECK: 201188: cc int3 -# DISASM-CHECK: 201189: cc int3 -# DISASM-CHECK: 20118a: cc int3 -# DISASM-CHECK: 20118b: cc int3 -# DISASM-CHECK: 20118c: cc int3 -# DISASM-CHECK: 20118d: cc int3 -# DISASM-CHECK: 20118e: cc int3 -# DISASM-CHECK: 20118f: cc int3 -# DISASM:
: -# DISASM-CHECK: 201190: 55 pushq %rbp -# DISASM-CHECK: 201191: 48 89 e5 movq %rsp, %rbp -# DISASM-CHECK: 201194: 31 c0 xorl %eax, %eax -# DISASM-CHECK: 201196: 5d popq %rbp -# DISASM-CHECK: 201197: c3 retq +// - clang++ -g -O0 -gpubnames -fdebug-compilation-dir='debug-names-test' \ +// -S debug-names.cpp -o debug-names.s -# DWARF: .debug_names contents: -# DWARF: Name Index @ 0x0 { -# DWARF-NEXT: Header { -# DWARF-NEXT: Length: 0xCC -# DWARF-NEXT: Format: DWARF32 -# DWARF-NEXT: Version: 5 -# DWARF-NEXT: CU count: 2 -# DWARF-NEXT: Local TU count: 0 -# DWARF-NEXT: Foreign TU count: 0 -# DWARF-NEXT: Bucket count: 5 -# DWARF-NEXT: Name count: 5 -# DWARF-NEXT: Abbreviations table size: 0x1F -# DWARF-NEXT: Augmentation: 'LLVM0700' -# DWARF: Compilation Unit offsets [ -# DWARF-NEXT: CU[0]: 0x00000000 -# DWARF-NEXT: CU[1]: 0x00000041 -# DWARF: Abbreviations [ -# DWARF-NEXT: Abbreviation 0x1 { -# DWARF: Tag: DW_TAG_structure_type -# DWARF-NEXT: DW_IDX_die_offset: DW_FORM_ref4 -# DWARF-NEXT: DW_IDX_parent: DW_FORM_flag_present -# DWARF-NEXT: DW_IDX_compile_unit: DW_FORM_data1 -# DWARF: Abbreviation 0x2 { -# DWARF-NEXT: Tag: DW_TAG_subprogram -# DWARF-NEXT: DW_IDX_die_offset: DW_FORM_ref4 -# DWARF-NEXT: DW_IDX_parent: DW_FORM_flag_present -# DWARF-NEXT: DW_IDX_compile_unit: DW_FORM_data1 -# DWARF: Abbreviation 0x3 { -# DWARF-NEXT: Tag: DW_TAG_base_type -# DWARF-NEXT: DW_IDX_die_offset: DW_FORM_ref4 -# DWARF-NEXT: DW_IDX_parent: DW_FORM_flag_present -# DWARF-NEXT: DW_IDX_compile_unit: DW_FORM_data1 -# DWARF: Bucket 0 [ -# DWARF: Bucket 1 [ -# DWARF: String: 0x00000089 "f1" -# DWARF-NEXT: Entry @ 0xa3 { -# DWARF-NEXT: Abbrev: 0x2 -# DWARF-NEXT: Tag: DW_TAG_subprogram -# DWARF-NEXT: DW_IDX_die_offset: 0x00000023 -# DWARF-NEXT: DW_IDX_parent: -# DWARF-NEXT: DW_IDX_compile_unit: 0x00 -# DWARF: String: 0x00000095 "t1" -# DWARF-NEXT: Entry @ 0xaa { -# DWARF-NEXT: Abbrev: 0x1 -# DWARF-NEXT: Tag: DW_TAG_structure_type -# DWARF-NEXT: DW_IDX_die_offset: 0x0000003a -# DWARF-NEXT: DW_IDX_parent: -# DWARF-NEXT: DW_IDX_compile_unit: 0x00 -# DWARF-NEXT: } -# DWARF-NEXT: Entry @ 0xb0 { -# DWARF-NEXT: Abbrev: 0x1 -# DWARF-NEXT: Tag: DW_TAG_structure_type -# DWARF-NEXT: DW_IDX_die_offset: 0x00000042 -# DWARF-NEXT: DW_IDX_parent: -# DWARF-NEXT: DW_IDX_compile_unit: 0x01 -# DWARF: String: 0x00000130 "int" -# DWARF-NEXT: Entry @ 0xb7 { -# DWARF-NEXT: Abbrev: 0x3 -# DWARF-NEXT: Tag: DW_TAG_base_type -# DWARF-NEXT: DW_IDX_die_offset: 0x0000003e -# DWARF-NEXT: DW_IDX_parent: -# DWARF-NEXT: DW_IDX_compile_unit: 0x01 -# DWARF: Bucket 2 [ -# DWARF: Bucket 3 [ -# DWARF: String: 0x0000008c "_Z2f12t1" -# DWARF-NEXT: Entry @ 0xbe { -# DWARF-NEXT: Abbrev: 0x2 -# DWARF-NEXT: Tag: DW_TAG_subprogram -# DWARF-NEXT: DW_IDX_die_offset: 0x00000023 -# DWARF-NEXT: DW_IDX_parent: -# DWARF-NEXT: DW_IDX_compile_unit: 0x00 -# DWARF: Bucket 4 [ -# DWARF: String: 0x0000012b "main" -# DWARF-NEXT: Entry @ 0xc5 { -# DWARF-NEXT: Abbrev: 0x2 -# DWARF-NEXT: Tag: DW_TAG_subprogram -# DWARF-NEXT: DW_IDX_die_offset: 0x00000023 -# DWARF-NEXT: DW_IDX_parent: -# DWARF-NEXT: DW_IDX_compile_unit: 0x01 +// debug-names.cpp contents: -# READELF: .debug_names PROGBITS 0000000000000000 0003eb 0000d0 +// struct t1 { }; +// void f1(t1) { } -# RUN: ld.lld --debug-names --no-debug-names %t1.o %t2.o -o %t -# RUN: llvm-readelf -SW %t | FileCheck %s --check-prefix=NO_DBG_NAMES - +// REQUIRES: x86 +// RUN: llvm-mc -filetype=obj -triple=x86_64 %s -o %t1.o +// RUN: llvm-mc -filetype=obj -triple=x86_64 %p/Inputs/debug-names-2.s -o %t2.o -# NO_DBG_NAMES: .debug_names PROGBITS 0000000000000000 00037c 000110 +// RUN: ld.lld --debug-names --no-debug-names %t1.o %t2.o -o %t +// RUN: llvm-readelf -SW %t | FileCheck %s --check-prefix=NO_DBG_NAMES -#-- input file: debug-names.cpp -## Generated with: -## -## - clang++ -g -O0 -gpubnames -fdebug-compilation-dir='debug-names-test' \ -## -S debug-names.cpp -o debug-names.s -## -## debug-names.cpp contents: -## -## struct t1 { }; -## void f1(t1) { } -## -## +// NO_DBG_NAMES: .debug_names PROGBITS 0000000000000000 [[#%x,]] 000110 + +// RUN: ld.lld --debug-names %t1.o %t2.o -o %t + +// RUN: llvm-dwarfdump -debug-names %t | FileCheck %s --check-prefix=DWARF +// RUN: llvm-readelf -SW %t \ +// RUN: | FileCheck -DFILE=%t1.o -DFILE=%t2.o %s --check-prefix=READELF + +// READELF: .debug_names PROGBITS 0000000000000000 [[#%x,]] 0000d0 + +// DWARF: .debug_names contents: +// DWARF: Name Index @ 0x0 { +// DWARF-NEXT: Header { +// DWARF-NEXT: Length: 0xCC +// DWARF-NEXT: Format: DWARF32 +// DWARF-NEXT: Version: 5 +// DWARF-NEXT: CU count: 2 +// DWARF-NEXT: Local TU count: 0 +// DWARF-NEXT: Foreign TU count: 0 +// DWARF-NEXT: Bucket count: 5 +// DWARF-NEXT: Name count: 5 +// DWARF-NEXT: Abbreviations table size: 0x1F +// DWARF-NEXT: Augmentation: 'LLVM0700' +// DWARF: Compilation Unit offsets [ +// DWARF-NEXT: CU[0]: 0x00000000 +// DWARF-NEXT: CU[1]: 0x0000000c +// DWARF: Abbreviations [ +// DWARF-NEXT: Abbreviation 0x1 { +// DWARF: Tag: DW_TAG_structure_type +// DWARF-NEXT: DW_IDX_die_offset: DW_FORM_ref4 +// DWARF-NEXT: DW_IDX_parent: DW_FORM_flag_present +// DWARF-NEXT: DW_IDX_compile_unit: DW_FORM_data1 +// DWARF: Abbreviation 0x2 { +// DWARF-NEXT: Tag: DW_TAG_subprogram +// DWARF-NEXT: DW_IDX_die_offset: DW_FORM_ref4 +// DWARF-NEXT: DW_IDX_parent: DW_FORM_flag_present +// DWARF-NEXT: DW_IDX_compile_unit: DW_FORM_data1 +// DWARF: Abbreviation 0x3 { +// DWARF-NEXT: Tag: DW_TAG_base_type +// DWARF-NEXT: DW_IDX_die_offset: DW_FORM_ref4 +// DWARF-NEXT: DW_IDX_parent: DW_FORM_flag_present +// DWARF-NEXT: DW_IDX_compile_unit: DW_FORM_data1 +// DWARF: Bucket 0 [ +// DWARF: Bucket 1 [ +// DWARF: String: 0x00000089 "f1" +// DWARF-NEXT: Entry @ 0xa3 { +// DWARF-NEXT: Abbrev: 0x2 +// DWARF-NEXT: Tag: DW_TAG_subprogram +// DWARF-NEXT: DW_IDX_die_offset: 0x00000023 +// DWARF-NEXT: DW_IDX_parent: +// DWARF-NEXT: DW_IDX_compile_unit: 0x00 +// DWARF: String: 0x00000095 "t1" +// DWARF-NEXT: Entry @ 0xaa { +// DWARF-NEXT: Abbrev: 0x1 +// DWARF-NEXT: Tag: DW_TAG_structure_type +// DWARF-NEXT: DW_IDX_die_offset: 0x0000003a +// DWARF-NEXT: DW_IDX_parent: +// DWARF-NEXT: DW_IDX_compile_unit: 0x00 +// DWARF-NEXT: } +// DWARF-NEXT: Entry @ 0xb0 { +// DWARF-NEXT: Abbrev: 0x1 +// DWARF-NEXT: Tag: DW_TAG_structure_type +// DWARF-NEXT: DW_IDX_die_offset: 0x00000042 +// DWARF-NEXT: DW_IDX_parent: +// DWARF-NEXT: DW_IDX_compile_unit: 0x01 +// DWARF: String: 0x00000130 "int" +// DWARF-NEXT: Entry @ 0xb7 { +// DWARF-NEXT: Abbrev: 0x3 +// DWARF-NEXT: Tag: DW_TAG_base_type +// DWARF-NEXT: DW_IDX_die_offset: 0x0000003e +// DWARF-NEXT: DW_IDX_parent: +// DWARF-NEXT: DW_IDX_compile_unit: 0x01 +// DWARF: Bucket 2 [ +// DWARF: Bucket 3 [ +// DWARF: String: 0x0000008c "_Z2f12t1" +// DWARF-NEXT: Entry @ 0xbe { +// DWARF-NEXT: Abbrev: 0x2 +// DWARF-NEXT: Tag: DW_TAG_subprogram +// DWARF-NEXT: DW_IDX_die_offset: 0x00000023 +// DWARF-NEXT: DW_IDX_parent: +// DWARF-NEXT: DW_IDX_compile_unit: 0x00 +// DWARF: Bucket 4 [ +// DWARF: String: 0x0000012b "main" +// DWARF-NEXT: Entry @ 0xc5 { +// DWARF-NEXT: Abbrev: 0x2 +// DWARF-NEXT: Tag: DW_TAG_subprogram +// DWARF-NEXT: DW_IDX_die_offset: 0x00000023 +// DWARF-NEXT: DW_IDX_parent: +// DWARF-NEXT: DW_IDX_compile_unit: 0x01 + .text .globl _Z2f12t1 # -- Begin function _Z2f12t1 .p2align 4, 0x90 @@ -165,41 +139,6 @@ _Z2f12t1: # @_Z2f12t1 .byte 1 # DWARF Unit Type .byte 8 # Address Size (in bytes) .long .debug_abbrev # Offset Into Abbrev. Section - .byte 1 # Abbrev [1] 0xc:0x35 DW_TAG_compile_unit - .byte 0 # DW_AT_producer - .short 33 # DW_AT_language - .byte 1 # DW_AT_name - .long .Lstr_offsets_base0 # DW_AT_str_offsets_base - .long .Lline_table_start0 # DW_AT_stmt_list - .byte 2 # DW_AT_comp_dir - .byte 0 # DW_AT_low_pc - .long .Lfunc_end0-.Lfunc_begin0 # DW_AT_high_pc - .long .Laddr_table_base0 # DW_AT_addr_base - .byte 2 # Abbrev [2] 0x23:0x17 DW_TAG_subprogram - .byte 0 # DW_AT_low_pc - .long .Lfunc_end0-.Lfunc_begin0 # DW_AT_high_pc - .byte 1 # DW_AT_frame_base - .byte 86 - .byte 3 # DW_AT_linkage_name - .byte 4 # DW_AT_name - .byte 0 # DW_AT_decl_file - .byte 2 # DW_AT_decl_line - # DW_AT_external - .byte 3 # Abbrev [3] 0x2f:0xa DW_TAG_formal_parameter - .byte 2 # DW_AT_location - .byte 145 - .byte 127 - .byte 0 # DW_AT_decl_file - .byte 2 # DW_AT_decl_line - .long 58 # DW_AT_type - .byte 0 # End Of Children Mark - .byte 4 # Abbrev [4] 0x3a:0x6 DW_TAG_structure_type - .byte 5 # DW_AT_calling_convention - .byte 5 # DW_AT_name - .byte 1 # DW_AT_byte_size - .byte 0 # DW_AT_decl_file - .byte 1 # DW_AT_decl_line - .byte 0 # End Of Children Mark .Ldebug_info_end0: .section .debug_str_offsets,"",@progbits .long 28 # Length of String Offsets Set From 932aa047c913d620e2eb49b9e6c94deee2b5c4c5 Mon Sep 17 00:00:00 2001 From: Caroline Tice Date: Tue, 26 Mar 2024 23:04:50 -0700 Subject: [PATCH 05/37] [lld][ELF] Implement merged .debug_names section. Fix code formatting issue. --- lld/ELF/SyntheticSections.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/lld/ELF/SyntheticSections.cpp b/lld/ELF/SyntheticSections.cpp index 776bf719a01d7..389fda9bf436b 100644 --- a/lld/ELF/SyntheticSections.cpp +++ b/lld/ELF/SyntheticSections.cpp @@ -2920,8 +2920,7 @@ static void readAttributeValues( Error err = Error::success(); typename DebugNamesSection::AttrValueData newAttr; uint32_t value; - if (attr.Index == DW_IDX_parent && - attr.Form != DW_FORM_flag_present && + if (attr.Index == DW_IDX_parent && attr.Form != DW_FORM_flag_present && attr.Form != DW_FORM_ref4) errorOrWarn(toString(namesSection.sec) + Twine(": invalid form for DW_IDX_parent")); From 2723b34681b6058be0419fb0252dcc97abbf7474 Mon Sep 17 00:00:00 2001 From: Caroline Tice Date: Wed, 27 Mar 2024 00:28:52 -0700 Subject: [PATCH 06/37] [lld][ELF] Implement merged .debug_names section Update for-loop to make sure unnecessary evaluations/calculations are not performed on condition checks. --- lld/ELF/SyntheticSections.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lld/ELF/SyntheticSections.cpp b/lld/ELF/SyntheticSections.cpp index 389fda9bf436b..28efc126df86d 100644 --- a/lld/ELF/SyntheticSections.cpp +++ b/lld/ELF/SyntheticSections.cpp @@ -3039,7 +3039,7 @@ readEntries(typename DebugNamesSection::DebugNamesSectionData &secData, chunk.hashValues.reserve(secData.hdr.NameCount); secData.namedEntries.reserve(secData.hdr.NameCount); // Calculate the Entry Offsets, create initial records. - for (uint32_t i = 0; i < secData.hdr.NameCount; ++i) { + for (uint32_t i = 0, e = secData.hdr.NameCount; i != e; ++i) { // Get string value typename DebugNamesSection::NamedEntry stringEntry; stringEntry.entryOffset = From 64e666a208b0786ef97706262177290d6e0638d7 Mon Sep 17 00:00:00 2001 From: Caroline Tice Date: Wed, 27 Mar 2024 07:52:09 -0700 Subject: [PATCH 07/37] [lld][ELF] Implement merged .debug_names section. Move '-r' and '--debug-names' test to driver.test; remove debug-names-invalid-flags.s test. --- lld/test/ELF/debug-names-invalid-flags.s | 148 ----------------------- 1 file changed, 148 deletions(-) delete mode 100644 lld/test/ELF/debug-names-invalid-flags.s diff --git a/lld/test/ELF/debug-names-invalid-flags.s b/lld/test/ELF/debug-names-invalid-flags.s deleted file mode 100644 index 96cd4da243b68..0000000000000 --- a/lld/test/ELF/debug-names-invalid-flags.s +++ /dev/null @@ -1,148 +0,0 @@ -// This file was generated by: -// clang++ -g -O0 -S -fdebug-compilation-dir='debug-names-test' \ -// -gpubnames main.cpp - -// Contents of main.cpp -// int main (int argc, char **argv) { } - -// REQUIRES: x86 -// RUN: llvm-mc -filetype=obj -triple=x86_64 %s -o %t1.o -// RUN: not ld.lld --debug-names -r %t1.o -o /dev/null 2>&1 \ -// RUN: | FileCheck -DFILE=%t1.o %s - -// CHECK: error: -r and --debug-names may not be used together - - .text - .globl main # -- Begin function main - .p2align 4, 0x90 - .type main,@function -main: # @main -.Lfunc_begin0: - .cfi_startproc -# %bb.0: # %entry - pushq %rbp - .cfi_def_cfa_offset 16 - .cfi_offset %rbp, -16 - movq %rsp, %rbp - .cfi_def_cfa_register %rbp - movl %edi, -4(%rbp) - movq %rsi, -16(%rbp) -.Ltmp0: - xorl %eax, %eax - popq %rbp - .cfi_def_cfa %rsp, 8 - retq -.Ltmp1: -.Lfunc_end0: - .size main, .Lfunc_end0-main - .cfi_endproc - # -- End function - .section .debug_abbrev,"",@progbits - .byte 0 # EOM(1) - .byte 0 # EOM(2) - .byte 0 # EOM(3) - .section .debug_info,"",@progbits -.Lcu_begin0: - .long .Ldebug_info_end0-.Ldebug_info_start0 # Length of Unit -.Ldebug_info_start0: - .short 5 # DWARF version number - .byte 1 # DWARF Unit Type - .byte 8 # Address Size (in bytes) - .long .debug_abbrev # Offset Into Abbrev. Section -.Ldebug_info_end0: - .section .debug_str_offsets,"",@progbits - .long 36 # Length of String Offsets Set - .short 5 - .short 0 -.Lstr_offsets_base0: - .section .debug_str,"MS",@progbits,1 -.Linfo_string0: - .asciz "clang version 19.0.0git (git@github.com:llvm/llvm-project.git d33d5630b281debe6eabd67e323bcf767340fb6a)" # string offset=0 -.Linfo_string1: - .asciz "main.cpp" # string offset=104 -.Linfo_string2: - .asciz "debug-names-test" # string offset=113 -.Linfo_string3: - .asciz "main" # string offset=130 -.Linfo_string4: - .asciz "int" # string offset=135 -.Linfo_string5: - .asciz "argc" # string offset=139 -.Linfo_string6: - .asciz "argv" # string offset=144 -.Linfo_string7: - .asciz "char" # string offset=149 -.Laddr_table_base0: - .quad .Lfunc_begin0 -.Ldebug_addr_end0: - .section .debug_names,"",@progbits - .long .Lnames_end0-.Lnames_start0 # Header: unit length -.Lnames_start0: - .short 5 # Header: version - .short 0 # Header: padding - .long 1 # Header: compilation unit count - .long 0 # Header: local type unit count - .long 0 # Header: foreign type unit count - .long 3 # Header: bucket count - .long 3 # Header: name count - .long .Lnames_abbrev_end0-.Lnames_abbrev_start0 # Header: abbreviation table size - .long 8 # Header: augmentation string size - .ascii "LLVM0700" # Header: augmentation string - .long .Lcu_begin0 # Compilation unit 0 - .long 0 # Bucket 0 - .long 1 # Bucket 1 - .long 2 # Bucket 2 - .long 2090499946 # Hash in Bucket 1 - .long 193495088 # Hash in Bucket 2 - .long 2090147939 # Hash in Bucket 2 - .long .Linfo_string3 # String in Bucket 1: main - .long .Linfo_string4 # String in Bucket 2: int - .long .Linfo_string7 # String in Bucket 2: char - .long .Lnames0-.Lnames_entries0 # Offset in Bucket 1 - .long .Lnames1-.Lnames_entries0 # Offset in Bucket 2 - .long .Lnames2-.Lnames_entries0 # Offset in Bucket 2 -.Lnames_abbrev_start0: - .byte 1 # Abbrev code - .byte 46 # DW_TAG_subprogram - .byte 3 # DW_IDX_die_offset - .byte 19 # DW_FORM_ref4 - .byte 4 # DW_IDX_parent - .byte 25 # DW_FORM_flag_present - .byte 0 # End of abbrev - .byte 0 # End of abbrev - .byte 2 # Abbrev code - .byte 36 # DW_TAG_base_type - .byte 3 # DW_IDX_die_offset - .byte 19 # DW_FORM_ref4 - .byte 4 # DW_IDX_parent - .byte 25 # DW_FORM_flag_present - .byte 0 # End of abbrev - .byte 0 # End of abbrev - .byte 0 # End of abbrev list -.Lnames_abbrev_end0: -.Lnames_entries0: -.Lnames0: -.L1: - .byte 1 # Abbreviation code - .long 35 # DW_IDX_die_offset - .byte 0 # DW_IDX_parent - # End of list: main -.Lnames1: -.L0: - .byte 2 # Abbreviation code - .long 73 # DW_IDX_die_offset - .byte 0 # DW_IDX_parent - # End of list: int -.Lnames2: -.L2: - .byte 2 # Abbreviation code - .long 87 # DW_IDX_die_offset - .byte 0 # DW_IDX_parent - # End of list: char - .p2align 2, 0x0 -.Lnames_end0: - .ident "clang version 19.0.0git (git@github.com:llvm/llvm-project.git d33d5630b281debe6eabd67e323bcf767340fb6a)" - .section ".note.GNU-stack","",@progbits - .addrsig - .section .debug_line,"",@progbits -.Lline_table_start0: From 28444182704374a45a3684b5e958540953cae6de Mon Sep 17 00:00:00 2001 From: Caroline Tice Date: Fri, 29 Mar 2024 07:33:14 -0700 Subject: [PATCH 08/37] [lld][ELF] Implement merged .debug_names section. Address various review comments. --- lld/ELF/SyntheticSections.cpp | 65 +++++++++++++++-------------------- lld/ELF/SyntheticSections.h | 4 +-- 2 files changed, 29 insertions(+), 40 deletions(-) diff --git a/lld/ELF/SyntheticSections.cpp b/lld/ELF/SyntheticSections.cpp index 28efc126df86d..32eb19568f615 100644 --- a/lld/ELF/SyntheticSections.cpp +++ b/lld/ELF/SyntheticSections.cpp @@ -2747,7 +2747,7 @@ template void DebugNamesSection::writeTo(uint8_t *buf) { SmallVector, 0> chunksRelocs; chunksRelocs.reserve(numChunks); - for (size_t i = 0; i < numChunks; ++i) { + for (size_t i = 0, e = numChunks; i != e; ++i) { DebugNamesOutputChunk &chunk = outputChunks[i]; InputSectionBase *base = inputDebugNamesSections[i]; DenseMap &relocs = chunksRelocs.emplace_back(); @@ -2798,9 +2798,7 @@ template void DebugNamesSection::writeTo(uint8_t *buf) { warn(".debug_names: type units are not handled in merged index"); // Write the foreign TU list. - // Currently LLVM does not emit foreign type units, so there should - // be nothing here to emit. - // TODO: Fix this, once we get everything working wtihout TUs. + // TODO: Fix this, once we get everything working without TUs. if (mergedHdr.ForeignTypeUnitCount != 0) warn(".debug_names: type units are not handled in merged index"); @@ -2855,10 +2853,8 @@ template void DebugNamesSection::writeTo(uint8_t *buf) { for (const auto &entry : stringEntry.indexEntries) { buf += encodeULEB128(entry->abbrevCode, buf); for (const auto &value : entry->attrValues) { - if (value.attrSize > 0) { - endian::write32(buf + 0, value.attrValue); - buf += value.attrSize; - } + endian::write32(buf + 0, value.attrValue); + buf += value.attrSize; } } *buf++ = 0; // Entry sentinel @@ -2876,33 +2872,26 @@ static void readCompileUnitOffsets( DWARFDataExtractor &namesExtractor) { uint64_t offset = secData.locs.CUsBase; uint64_t *offsetPtr = &offset; - for (size_t i = 0; i < secData.hdr.CompUnitCount; ++i) { - Error err = Error::success(); - // This call to namesExtractor can't fail; if there were a problem with the - // input, it would have been caught in the call to NamesIndex::extract, in - // DebugNamesSection::create. - uint32_t value = namesExtractor.getU32(offsetPtr, &err); - cantFail(std::move(err)); - outputChunk.compilationUnits.push_back(value); - } + outputChunk.compilationUnits.resize(secData.hdr.CompUnitCount); + uint32_t *bufferPtr = + namesExtractor.getU32(offsetPtr, outputChunk.compilationUnits.begin(), + secData.hdr.CompUnitCount); + if (!bufferPtr) + errorOrWarn(toString(outputChunk.sec) + + Twine(": error while reading CU offsets")); } template static void readEntryOffsets( typename DebugNamesSection::DebugNamesSectionData &secData, DWARFDataExtractor &namesExtractor) { - secData.entryOffsets = std::make_unique(secData.hdr.NameCount); + secData.entryOffsets.resize(secData.hdr.NameCount); uint64_t offset = secData.locs.EntryOffsetsBase; uint64_t *offsetPtr = &offset; - for (size_t i = 0; i < secData.hdr.NameCount; ++i) { - Error err = Error::success(); - // This call to namesExtractor can't fail; if there were a problem with the - // input, it would have been caught in the call to NamesIndex::extract, in - // DebugNamesSection::create. - uint32_t value = namesExtractor.getU32(offsetPtr, &err); - cantFail(std::move(err)); - secData.entryOffsets.get()[i] = value; - } + uint32_t *bufferPtr = namesExtractor.getU32( + offsetPtr, secData.entryOffsets.begin(), secData.hdr.NameCount); + if (!bufferPtr) + errorOrWarn(Twine(": error while reading entry offsets")); } template @@ -2975,7 +2964,7 @@ static void readAttributeValues( errorOrWarn(toString(namesSection.sec) + Twine(": error while reading attributes: ") + toString(std::move(err))); - if (attr.Index == DW_IDX_compile_unit || attr.Index == DW_IDX_type_unit) + if (attr.Index == DW_IDX_compile_unit) // Save it to put it at the end of the attributes list. cuOrTuAttr = newAttr; else if (attr.Form != DW_FORM_flag_present) @@ -3090,8 +3079,9 @@ static void collectDebugNamesSectionData( typename DebugNamesSection::DebugNamesInputChunk &chunk, typename DebugNamesSection::DebugNamesOutputChunk &outputChunk, DWARFDataExtractor &namesExtractor, DataExtractor &strExtractor) { - for (const auto &ni : *chunk.debugNamesData) { - typename DebugNamesSection::DebugNamesSectionData secData; + for (const DWARFDebugNames::NameIndex &ni : *chunk.debugNamesData) { + typename DebugNamesSection::DebugNamesSectionData &secData = + chunk.sectionsData.emplace_back(); secData.hdr = ni.getHeader(); if (secData.hdr.Format != DwarfFormat::DWARF32) { errorOrWarn(toString(chunk.namesSection->sec) + @@ -3108,7 +3098,6 @@ static void collectDebugNamesSectionData( readCompileUnitOffsets(secData, outputChunk, namesExtractor); readEntryOffsets(secData, namesExtractor); readEntries(secData, chunk, namesExtractor, strExtractor, ni); - chunk.sectionsData.push_back(std::move(secData)); } } @@ -3123,7 +3112,7 @@ void DebugNamesSection::collectMergedCounts( mergedHdr.Format = DwarfFormat::DWARF32; mergedHdr.AugmentationStringSize = 0; - for (size_t i = 0; i < numChunks; ++i) { + for (size_t i = 0, e = numChunks; i != e; ++i) { DebugNamesInputChunk &inputChunk = inputChunks[i]; DebugNamesOutputChunk &outputChunk = outputChunks[i]; inputChunk.baseCuOffsetIdx = tmpMergedCuOffsets.size(); @@ -3197,7 +3186,7 @@ void DebugNamesSection::getMergedAbbrevTable( dwarf::Form compileUnitAttrForm = getMergedCuSizeData().second; for (DebugNamesInputChunk &chunk : inputChunks) { - for (const auto &ni : *chunk.debugNamesData) { + for (const DWARFDebugNames::NameIndex &ni : *chunk.debugNamesData) { const auto &abbrevs = ni.getAbbrevs(); for (const DWARFDebugNames::Abbrev &abbrev : abbrevs) { // Create canonicalized abbrev. @@ -3208,8 +3197,7 @@ void DebugNamesSection::getMergedAbbrevTable( newAbbrev.tag = abbrev.Tag; for (const auto attr : abbrev.Attributes) { DWARFDebugNames::AttributeEncoding newAttr(attr.Index, attr.Form); - if (attr.Index == DW_IDX_compile_unit || - attr.Index == DW_IDX_type_unit) + if (attr.Index == DW_IDX_compile_unit) // Save it, to put it at the end. cuOrTuAttr.Index = newAttr.Index; else @@ -3231,7 +3219,8 @@ void DebugNamesSection::getMergedAbbrevTable( newCode = Existing->code; } else { // Didn't find it. - Abbrev *newAbbrev2 = new (Alloc) Abbrev(std::move(newAbbrev)); + Abbrev *newAbbrev2 = + new (abbrevAlloc.Allocate()) Abbrev(std::move(newAbbrev)); AbbreviationsSet.InsertNode(newAbbrev2, insertPos); newCode = mergedAbbrevTable.size() + 1; newAbbrev2->code = newCode; @@ -3280,7 +3269,7 @@ void DebugNamesSection::getMergedSymbols( MutableArrayRef shards(shardsPtr.get(), numShards); parallelFor(0, concurrency, [&](size_t threadId) { - for (size_t i = 0; i < numChunks; ++i) { + for (size_t i = 0, e = numChunks; i != e; ++i) { DebugNamesInputChunk &chunk = inputChunks[i]; for (auto &secData : chunk.sectionsData) { // Deduplicate the NamedEntry records (based on the string/name), @@ -3390,7 +3379,7 @@ template void DebugNamesSection::updateParentIndexEntries() { // Found the abbrev. Find the index for the DW_IDX_parent attribute // (in the abbrev) and update that value in the entry with the // correct parent offset (in the merged entry pool). - for (size_t idx = 0, size = abbrev->attributes.size(); idx < size; + for (size_t idx = 0, size = abbrev->attributes.size(); idx != size; ++idx) { auto attr = abbrev->attributes[idx]; if (attr.Index == DW_IDX_parent && attr.Form == DW_FORM_ref4) diff --git a/lld/ELF/SyntheticSections.h b/lld/ELF/SyntheticSections.h index 24ffdb3db4946..297f2ca6e27d8 100644 --- a/lld/ELF/SyntheticSections.h +++ b/lld/ELF/SyntheticSections.h @@ -859,7 +859,7 @@ template class DebugNamesSection final : public SyntheticSection { llvm::DWARFDebugNames::DWARFDebugNamesOffsets locs; SmallVector tuOffsets; SmallVector abbrevTable; - std::unique_ptr entryOffsets; + SmallVector entryOffsets; SmallVector namedEntries; uint16_t dwarfSize; uint16_t hdrSize; @@ -895,7 +895,7 @@ template class DebugNamesSection final : public SyntheticSection { void updateParentIndexEntries(); uint64_t calculateMergedSectionSize(); - llvm::BumpPtrAllocator Alloc; + llvm::SpecificBumpPtrAllocator abbrevAlloc; private: size_t sectionSize; From c17e68b9981182b26e7f1edf3b8d02be76110b5d Mon Sep 17 00:00:00 2001 From: Caroline Tice Date: Fri, 29 Mar 2024 07:36:10 -0700 Subject: [PATCH 09/37] [lld][ELF] Implement merged .debug_names section. Fix comment, --- lld/ELF/SyntheticSections.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lld/ELF/SyntheticSections.cpp b/lld/ELF/SyntheticSections.cpp index 32eb19568f615..7db2524597cc6 100644 --- a/lld/ELF/SyntheticSections.cpp +++ b/lld/ELF/SyntheticSections.cpp @@ -3458,7 +3458,7 @@ DebugNamesSection *DebugNamesSection::create() { ret->getMergedAbbrevTable(inputChunks); ret->getMergedSymbols(inputChunks); ret->computeUniqueHashes(inputChunks); - // inputChunks are needed any more. Reset now to save memory. + // inputChunks are not needed any more. Reset now to save memory. inputChunksPtr.reset(); ret->generateBuckets(); ret->calculateEntriesSizeAndOffsets(); From c4d7537e1a6c4e20d781a5227865f0ea7ddb8485 Mon Sep 17 00:00:00 2001 From: Caroline Tice Date: Fri, 29 Mar 2024 09:08:28 -0700 Subject: [PATCH 10/37] [lld][ELF] Implement merged .debug_names section. Replace "ELFT::TargetEndianness" with "ELFT::Endianness" --- lld/ELF/SyntheticSections.cpp | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/lld/ELF/SyntheticSections.cpp b/lld/ELF/SyntheticSections.cpp index 7db2524597cc6..3ae8e1f97c5c1 100644 --- a/lld/ELF/SyntheticSections.cpp +++ b/lld/ELF/SyntheticSections.cpp @@ -2773,15 +2773,12 @@ template void DebugNamesSection::writeTo(uint8_t *buf) { endian::write32(buf + 0, mergedHdr.UnitLength); endian::write16(buf + 4, mergedHdr.Version); endian::write32(buf + 8, mergedHdr.CompUnitCount); - endian::write32(buf + 12, - mergedHdr.LocalTypeUnitCount); - endian::write32(buf + 16, - mergedHdr.ForeignTypeUnitCount); + endian::write32(buf + 12, mergedHdr.LocalTypeUnitCount); + endian::write32(buf + 16, mergedHdr.ForeignTypeUnitCount); endian::write32(buf + 20, mergedHdr.BucketCount); endian::write32(buf + 24, mergedHdr.NameCount); endian::write32(buf + 28, mergedHdr.AbbrevTableSize); - endian::write32(buf + 32, - mergedHdr.AugmentationStringSize); + endian::write32(buf + 32, mergedHdr.AugmentationStringSize); buf += 36; memcpy(buf, mergedHdr.AugmentationString.c_str(), 8); buf += 8; @@ -2823,8 +2820,7 @@ template void DebugNamesSection::writeTo(uint8_t *buf) { // Write the string offsets. for (const auto &entry : mergedEntries) { - endian::write32(buf + 0, - entry.relocatedEntryOffset); + endian::write32(buf + 0, entry.relocatedEntryOffset); buf += 4; } From 06171a85f7e1d896f247d7f168d07308cab7bfad Mon Sep 17 00:00:00 2001 From: Caroline Tice Date: Fri, 29 Mar 2024 15:32:40 -0700 Subject: [PATCH 11/37] [lld][ELF] Implement merged .debug_names section. Set augmentation string size from the augmentation string (for error handling case). --- lld/ELF/SyntheticSections.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lld/ELF/SyntheticSections.cpp b/lld/ELF/SyntheticSections.cpp index 3ae8e1f97c5c1..0a56a6fb888f4 100644 --- a/lld/ELF/SyntheticSections.cpp +++ b/lld/ELF/SyntheticSections.cpp @@ -3128,8 +3128,8 @@ void DebugNamesSection::collectMergedCounts( data.hdr.AugmentationString)) { // There are conflicting augmentation strings, so it's best for the // merged index to not use an augmentation string. - mergedHdr.AugmentationStringSize = 8; mergedHdr.AugmentationString = " "; + mergedHdr.AugmentationStringSize = mergedHdr.AugmentationString.size(); } } } From 11898cac5255897fd94ed73b1d75c6bbe9d9bc67 Mon Sep 17 00:00:00 2001 From: Caroline Tice Date: Mon, 1 Apr 2024 21:58:31 -0700 Subject: [PATCH 12/37] [lld][ELF] Implement merged .debug_names section. Update debug-names*.s tests, to use split file format rather than multiple files. Reduce the use of 'auto' in DebugNamesSection work, replacing it with actual type names. Use UINT*_MAXINT rather than constant values. --- lld/ELF/SyntheticSections.cpp | 43 ++++++++++++++++++----------------- 1 file changed, 22 insertions(+), 21 deletions(-) diff --git a/lld/ELF/SyntheticSections.cpp b/lld/ELF/SyntheticSections.cpp index 0a56a6fb888f4..c87b29e34f69d 100644 --- a/lld/ELF/SyntheticSections.cpp +++ b/lld/ELF/SyntheticSections.cpp @@ -2761,7 +2761,7 @@ template void DebugNamesSection::writeTo(uint8_t *buf) { } // Update the entries with the relocated string offsets. - for (auto &stringEntry : mergedEntries) { + for (NamedEntry &stringEntry : mergedEntries) { uint32_t oldOffset = stringEntry.stringOffsetOffset; uint32_t idx = stringEntry.chunkIdx; stringEntry.relocatedEntryOffset = chunksRelocs[idx][oldOffset]; @@ -2802,7 +2802,7 @@ template void DebugNamesSection::writeTo(uint8_t *buf) { // Write the hash table. // ... Write the buckets uint32_t idx = 1; - for (const auto &bucket : bucketList) { + for (const SmallVector &bucket : bucketList) { if (!bucket.empty()) endian::write32(buf + 0, idx); idx += bucket.size(); @@ -2819,7 +2819,7 @@ template void DebugNamesSection::writeTo(uint8_t *buf) { } // Write the string offsets. - for (const auto &entry : mergedEntries) { + for (const NamedEntry &entry : mergedEntries) { endian::write32(buf + 0, entry.relocatedEntryOffset); buf += 4; } @@ -2831,10 +2831,10 @@ template void DebugNamesSection::writeTo(uint8_t *buf) { } // Write the abbrev table. - for (const auto *abbrev : mergedAbbrevTable) { + for (const Abbrev *abbrev : mergedAbbrevTable) { buf += encodeULEB128(abbrev->code, buf); buf += encodeULEB128(abbrev->tag, buf); - for (auto attr : abbrev->attributes) { + for (DWARFDebugNames::AttributeEncoding attr : abbrev->attributes) { buf += encodeULEB128(attr.Index, buf); buf += encodeULEB128(attr.Form, buf); } @@ -2846,7 +2846,7 @@ template void DebugNamesSection::writeTo(uint8_t *buf) { // Write the entry pool. for (const auto &stringEntry : mergedEntries) { // Write all the entries for the string. - for (const auto &entry : stringEntry.indexEntries) { + for (const std::unique_ptr &entry : stringEntry.indexEntries) { buf += encodeULEB128(entry->abbrevCode, buf); for (const auto &value : entry->attrValues) { endian::write32(buf + 0, value.attrValue); @@ -2901,7 +2901,7 @@ static void readAttributeValues( const LLDDWARFSection &namesSection = *chunk.namesSection; uint64_t *offsetPtr = &offset; typename DebugNamesSection::AttrValueData cuOrTuAttr = {0, 0}; - for (auto attr : abbrev.Attributes) { + for (DWARFDebugNames::AttributeEncoding attr : abbrev.Attributes) { Error err = Error::success(); typename DebugNamesSection::AttrValueData newAttr; uint32_t value; @@ -3153,13 +3153,13 @@ std::pair DebugNamesSection::getMergedCuSizeData() { uint8_t size; dwarf::Form form; // TODO: Investigate possibly using DIEInteger::BestForm here - if (mergedHdr.CompUnitCount > 0xffffffff) { + if (mergedHdr.CompUnitCount > UINT32_MAX) { form = DW_FORM_data8; size = 8; - } else if (mergedHdr.CompUnitCount > 0xffff) { + } else if (mergedHdr.CompUnitCount > UINT16_MAX) { form = DW_FORM_data4; size = 4; - } else if (mergedHdr.CompUnitCount > 0xff) { + } else if (mergedHdr.CompUnitCount > UINT8_MAX) { form = DW_FORM_data2; size = 2; } else { @@ -3191,7 +3191,8 @@ void DebugNamesSection::getMergedAbbrevTable( compileUnitAttrForm); newAbbrev.code = abbrev.Code; newAbbrev.tag = abbrev.Tag; - for (const auto attr : abbrev.Attributes) { + for (const DWARFDebugNames::AttributeEncoding attr : + abbrev.Attributes) { DWARFDebugNames::AttributeEncoding newAttr(attr.Index, attr.Form); if (attr.Index == DW_IDX_compile_unit) // Save it, to put it at the end. @@ -3232,7 +3233,7 @@ void DebugNamesSection::getMergedAbbrevTable( for (Abbrev *a : mergedAbbrevTable) { mergedHdr.AbbrevTableSize += getULEB128Size(a->code); mergedHdr.AbbrevTableSize += getULEB128Size(a->tag); - for (const auto &attr : a->attributes) { + for (const DWARFDebugNames::AttributeEncoding &attr : a->attributes) { mergedHdr.AbbrevTableSize += getULEB128Size(attr.Index); mergedHdr.AbbrevTableSize += getULEB128Size(attr.Form); } @@ -3267,7 +3268,7 @@ void DebugNamesSection::getMergedSymbols( parallelFor(0, concurrency, [&](size_t threadId) { for (size_t i = 0, e = numChunks; i != e; ++i) { DebugNamesInputChunk &chunk = inputChunks[i]; - for (auto &secData : chunk.sectionsData) { + for (DebugNamesSectionData &secData : chunk.sectionsData) { // Deduplicate the NamedEntry records (based on the string/name), // using a map from string/name to NamedEntry records. // Note there is a twist: If there is already a record for the current @@ -3275,14 +3276,14 @@ void DebugNamesSection::getMergedSymbols( // current record to the record that's in the nameMap. I.e. we // deduplicate the *strings* but we keep all the IndexEntry records // (moving them to the appropriate 'kept' NamedEntry record). - for (auto &stringEntry : secData.namedEntries) { + for (NamedEntry &stringEntry : secData.namedEntries) { size_t shardId = stringEntry.hashValue >> shift; if ((shardId & (concurrency - 1)) != threadId) continue; auto &shard = shards[shardId]; stringEntry.chunkIdx = i; - for (auto &entry : stringEntry.indexEntries) { + for (std::unique_ptr &entry : stringEntry.indexEntries) { // The DW_IDX_compile_unit is always the last attribute (we set it // up that way when we read/created the attributes). We need to // update the index value to use the correct merged offset, and we @@ -3312,7 +3313,7 @@ void DebugNamesSection::getMergedSymbols( }); // Combined the shared symbols into mergedEntries - for (auto &shard : shards) + for (ShardData &shard : shards) for (auto &mapEntry : shard.nameMap) mergedEntries.push_back(std::move(mapEntry.second)); mergedHdr.NameCount = mergedEntries.size(); @@ -3330,14 +3331,14 @@ void DebugNamesSection::computeUniqueHashes( template void DebugNamesSection::generateBuckets() { bucketList.resize(mergedHdr.BucketCount); - for (auto &entry : mergedEntries) { + for (NamedEntry &entry : mergedEntries) { uint32_t bucketIdx = entry.hashValue % mergedHdr.BucketCount; bucketList[bucketIdx].push_back(&entry); } // Sort the contents of the buckets by hash value so that the hash collisions // end up together. - for (auto &bucket : bucketList) + for (SmallVector &bucket : bucketList) stable_sort(bucket, [](NamedEntry *lhs, NamedEntry *rhs) { return lhs->hashValue < rhs->hashValue; }); @@ -3348,7 +3349,7 @@ void DebugNamesSection::calculateEntriesSizeAndOffsets() { uint32_t offset = 0; for (NamedEntry &stringEntry : mergedEntries) { stringEntry.entryOffset = offset; - for (auto &entry : stringEntry.indexEntries) { + for (std::unique_ptr &entry : stringEntry.indexEntries) { uint32_t entrySize = 0; entry->poolOffset = offset; entrySize += getULEB128Size(entry->abbrevCode); @@ -3364,7 +3365,7 @@ void DebugNamesSection::calculateEntriesSizeAndOffsets() { template void DebugNamesSection::updateParentIndexEntries() { for (NamedEntry &stringEntry : mergedEntries) { - for (auto &childEntry : stringEntry.indexEntries) { + for (std::unique_ptr &childEntry : stringEntry.indexEntries) { if (!childEntry->parentEntry) continue; @@ -3377,7 +3378,7 @@ template void DebugNamesSection::updateParentIndexEntries() { // correct parent offset (in the merged entry pool). for (size_t idx = 0, size = abbrev->attributes.size(); idx != size; ++idx) { - auto attr = abbrev->attributes[idx]; + DWARFDebugNames::AttributeEncoding attr = abbrev->attributes[idx]; if (attr.Index == DW_IDX_parent && attr.Form == DW_FORM_ref4) childEntry->attrValues[idx].attrValue = childEntry->parentEntry->poolOffset; From c8b69048ce6d0aa8da4756c9c86a988a8d46e385 Mon Sep 17 00:00:00 2001 From: Caroline Tice Date: Mon, 1 Apr 2024 22:19:18 -0700 Subject: [PATCH 13/37] [lld][ELF] Implement merged .debug_names section. Update tests to up split-file instead of multiple files. --- lld/test/ELF/Inputs/debug-names-2.s | 150 --------- .../ELF/Inputs/debug-names-parent-idx-2.s | 267 ---------------- lld/test/ELF/debug-names-bad-aug-string.s | 169 ++++++++++- lld/test/ELF/debug-names-bad-version.s | 165 +++++++++- lld/test/ELF/debug-names-parent-idx.s | 286 +++++++++++++++++- lld/test/ELF/debug-names.s | 178 ++++++++++- 6 files changed, 774 insertions(+), 441 deletions(-) delete mode 100644 lld/test/ELF/Inputs/debug-names-2.s delete mode 100644 lld/test/ELF/Inputs/debug-names-parent-idx-2.s diff --git a/lld/test/ELF/Inputs/debug-names-2.s b/lld/test/ELF/Inputs/debug-names-2.s deleted file mode 100644 index 83ddbd2050d40..0000000000000 --- a/lld/test/ELF/Inputs/debug-names-2.s +++ /dev/null @@ -1,150 +0,0 @@ -#-- input file: debug-names-2.cpp -## Generated with: -## - clang++ -g -O0 -gpubnames -fdebug-compilation-dir='debug-names-test' \ -## -S debug-names-2.cpp -o debug-names-2.s - -## debug-names-2.cpp contents: - -## struct t1 { }; -## int main() { -## t1 v1; -## } -## - .text - .globl main # -- Begin function main - .p2align 4, 0x90 - .type main,@function -main: # @main -.Lfunc_begin0: - .cfi_startproc -# %bb.0: # %entry - pushq %rbp - .cfi_def_cfa_offset 16 - .cfi_offset %rbp, -16 - movq %rsp, %rbp - .cfi_def_cfa_register %rbp -.Ltmp0: - xorl %eax, %eax - popq %rbp - .cfi_def_cfa %rsp, 8 - retq -.Ltmp1: -.Lfunc_end0: - .size main, .Lfunc_end0-main - .cfi_endproc - # -- End function - .section .debug_abbrev,"",@progbits - .byte 0 # EOM(1) - .byte 0 # EOM(2) - .byte 0 # EOM(3) - .section .debug_info,"",@progbits -.Lcu_begin0: - .long .Ldebug_info_end0-.Ldebug_info_start0 # Length of Unit -.Ldebug_info_start0: - .short 5 # DWARF version number - .byte 1 # DWARF Unit Type - .byte 8 # Address Size (in bytes) - .long .debug_abbrev # Offset Into Abbrev. Section -.Ldebug_info_end0: - .section .debug_str_offsets,"",@progbits - .long 32 # Length of String Offsets Set - .short 5 - .short 0 -.Lstr_offsets_base0: - .section .debug_str,"MS",@progbits,1 -.Linfo_string0: - .asciz "clang version 19.0.0git (git@github.com:llvm/llvm-project.git 4df364bc93af49ae413ec1ae8328f34ac70730c4)" # string offset=0 -.Linfo_string1: - .asciz "debug-names-2.cpp" # string offset=104 -.Linfo_string2: - .asciz "debug-names-test" # string offset=122 -.Linfo_string3: - .asciz "main" # string offset=139 -.Linfo_string4: - .asciz "int" # string offset=144 -.Linfo_string5: - .asciz "v1" # string offset=148 -.Linfo_string6: - .asciz "t1" # string offset=151 -.Laddr_table_base0: - .quad .Lfunc_begin0 -.Ldebug_addr_end0: - .section .debug_names,"",@progbits - .long .Lnames_end0-.Lnames_start0 # Header: unit length -.Lnames_start0: - .short 5 # Header: version - .short 0 # Header: padding - .long 1 # Header: compilation unit count - .long 0 # Header: local type unit count - .long 0 # Header: foreign type unit count - .long 3 # Header: bucket count - .long 3 # Header: name count - .long .Lnames_abbrev_end0-.Lnames_abbrev_start0 # Header: abbreviation table size - .long 8 # Header: augmentation string size - .ascii "LLVM0700" # Header: augmentation string - .long .Lcu_begin0 # Compilation unit 0 - .long 0 # Bucket 0 - .long 1 # Bucket 1 - .long 3 # Bucket 2 - .long 5863786 # Hash in Bucket 1 - .long 2090499946 # Hash in Bucket 1 - .long 193495088 # Hash in Bucket 2 - .long .Linfo_string6 # String in Bucket 1: t1 - .long .Linfo_string3 # String in Bucket 1: main - .long .Linfo_string4 # String in Bucket 2: int - .long .Lnames2-.Lnames_entries0 # Offset in Bucket 1 - .long .Lnames0-.Lnames_entries0 # Offset in Bucket 1 - .long .Lnames1-.Lnames_entries0 # Offset in Bucket 2 -.Lnames_abbrev_start0: - .byte 1 # Abbrev code - .byte 19 # DW_TAG_structure_type - .byte 3 # DW_IDX_die_offset - .byte 19 # DW_FORM_ref4 - .byte 4 # DW_IDX_parent - .byte 25 # DW_FORM_flag_present - .byte 0 # End of abbrev - .byte 0 # End of abbrev - .byte 2 # Abbrev code - .byte 46 # DW_TAG_subprogram - .byte 3 # DW_IDX_die_offset - .byte 19 # DW_FORM_ref4 - .byte 4 # DW_IDX_parent - .byte 25 # DW_FORM_flag_present - .byte 0 # End of abbrev - .byte 0 # End of abbrev - .byte 3 # Abbrev code - .byte 36 # DW_TAG_base_type - .byte 3 # DW_IDX_die_offset - .byte 19 # DW_FORM_ref4 - .byte 4 # DW_IDX_parent - .byte 25 # DW_FORM_flag_present - .byte 0 # End of abbrev - .byte 0 # End of abbrev - .byte 0 # End of abbrev list -.Lnames_abbrev_end0: -.Lnames_entries0: -.Lnames2: -.L1: - .byte 1 # Abbreviation code - .long 66 # DW_IDX_die_offset - .byte 0 # DW_IDX_parent - # End of list: t1 -.Lnames0: -.L2: - .byte 2 # Abbreviation code - .long 35 # DW_IDX_die_offset - .byte 0 # DW_IDX_parent - # End of list: main -.Lnames1: -.L0: - .byte 3 # Abbreviation code - .long 62 # DW_IDX_die_offset - .byte 0 # DW_IDX_parent - # End of list: int - .p2align 2, 0x0 -.Lnames_end0: - .ident "clang version 19.0.0git (git@github.com:llvm/llvm-project.git 4df364bc93af49ae413ec1ae8328f34ac70730c4)" - .section ".note.GNU-stack","",@progbits - .addrsig - .section .debug_line,"",@progbits -.Lline_table_start0: diff --git a/lld/test/ELF/Inputs/debug-names-parent-idx-2.s b/lld/test/ELF/Inputs/debug-names-parent-idx-2.s deleted file mode 100644 index ebd93c01d8518..0000000000000 --- a/lld/test/ELF/Inputs/debug-names-parent-idx-2.s +++ /dev/null @@ -1,267 +0,0 @@ -#-- input file: debug-names-parent-idx-2.cpp -## Generated with: - -## - clang++ -g -O0 -gpubnames -fdebug-compilation-dir='parent-idx-test' \ -## -S debug-names-parent-idx-2.cpp -o debug-names-parent-idx-2.s - -## foo.h contents: - -## int foo(); - -## struct foo { -## int x; -## char y; -## struct foo *foo_ptr; -## }; - -## namespace parent_test { -## int foo(); -## } - -## debug-names-parent-index-2.cpp contents: - -## #include "foo.h" -## int foo () { -## struct foo struct2; -## struct2.x = 1024; -## struct2.y = 'r'; -## struct2.foo_ptr = nullptr; -## return struct2.x * (int) struct2.y; -## } - -## namespace parent_test { -## int foo () { -## return 25; -## } -## } - - .text - .globl _Z3foov # -- Begin function _Z3foov - .p2align 4, 0x90 - .type _Z3foov,@function -_Z3foov: # @_Z3foov -.Lfunc_begin0: - .cfi_startproc -# %bb.0: # %entry - pushq %rbp - .cfi_def_cfa_offset 16 - .cfi_offset %rbp, -16 - movq %rsp, %rbp - .cfi_def_cfa_register %rbp -.Ltmp0: - movl $1024, -16(%rbp) # imm = 0x400 - movb $114, -12(%rbp) - movq $0, -8(%rbp) - movl -16(%rbp), %eax - movsbl -12(%rbp), %ecx - imull %ecx, %eax - popq %rbp - .cfi_def_cfa %rsp, 8 - retq -.Ltmp1: -.Lfunc_end0: - .size _Z3foov, .Lfunc_end0-_Z3foov - .cfi_endproc - # -- End function - .globl _ZN11parent_test3fooEv # -- Begin function _ZN11parent_test3fooEv - .p2align 4, 0x90 - .type _ZN11parent_test3fooEv,@function -_ZN11parent_test3fooEv: # @_ZN11parent_test3fooEv -.Lfunc_begin1: - .cfi_startproc -# %bb.0: # %entry - pushq %rbp - .cfi_def_cfa_offset 16 - .cfi_offset %rbp, -16 - movq %rsp, %rbp - .cfi_def_cfa_register %rbp -.Ltmp2: - movl $25, %eax - popq %rbp - .cfi_def_cfa %rsp, 8 - retq -.Ltmp3: -.Lfunc_end1: - .size _ZN11parent_test3fooEv, .Lfunc_end1-_ZN11parent_test3fooEv - .cfi_endproc - # -- End function - .section .debug_abbrev,"",@progbits - .byte 0 # EOM(1) - .byte 0 # EOM(2) - .byte 0 # EOM(3) - .section .debug_info,"",@progbits -.Lcu_begin0: - .long .Ldebug_info_end0-.Ldebug_info_start0 # Length of Unit -.Ldebug_info_start0: - .short 5 # DWARF version number - .byte 1 # DWARF Unit Type - .byte 8 # Address Size (in bytes) - .long .debug_abbrev # Offset Into Abbrev. Section -.Ldebug_info_end0: - .section .debug_str_offsets,"",@progbits - .long 56 # Length of String Offsets Set - .short 5 - .short 0 -.Lstr_offsets_base0: - .section .debug_str,"MS",@progbits,1 -.Linfo_string0: - .asciz "clang version 19.0.0git (git@github.com:llvm/llvm-project.git 4df364bc93af49ae413ec1ae8328f34ac70730c4)" # string offset=0 -.Linfo_string1: - .asciz "debug-names-parent-idx-2.cpp" # string offset=104 -.Linfo_string2: - .asciz "parent-idx-test" # string offset=133 -.Linfo_string3: - .asciz "int" # string offset=149 -.Linfo_string4: - .asciz "foo" # string offset=153 -.Linfo_string5: - .asciz "_Z3foov" # string offset=157 -.Linfo_string6: - .asciz "parent_test" # string offset=165 -.Linfo_string7: - .asciz "_ZN11parent_test3fooEv" # string offset=177 -.Linfo_string8: - .asciz "struct2" # string offset=200 -.Linfo_string9: - .asciz "x" # string offset=208 -.Linfo_string10: - .asciz "y" # string offset=210 -.Linfo_string11: - .asciz "char" # string offset=212 -.Linfo_string12: - .asciz "foo_ptr" # string offset=217 -.Laddr_table_base0: - .quad .Lfunc_begin0 - .quad .Lfunc_begin1 -.Ldebug_addr_end0: - .section .debug_names,"",@progbits - .long .Lnames_end0-.Lnames_start0 # Header: unit length -.Lnames_start0: - .short 5 # Header: version - .short 0 # Header: padding - .long 1 # Header: compilation unit count - .long 0 # Header: local type unit count - .long 0 # Header: foreign type unit count - .long 6 # Header: bucket count - .long 6 # Header: name count - .long .Lnames_abbrev_end0-.Lnames_abbrev_start0 # Header: abbreviation table size - .long 8 # Header: augmentation string size - .ascii "LLVM0700" # Header: augmentation string - .long .Lcu_begin0 # Compilation unit 0 - .long 0 # Bucket 0 - .long 1 # Bucket 1 - .long 3 # Bucket 2 - .long 5 # Bucket 3 - .long 0 # Bucket 4 - .long 6 # Bucket 5 - .long -1451972055 # Hash in Bucket 1 - .long -1257882357 # Hash in Bucket 1 - .long 175265198 # Hash in Bucket 2 - .long 193495088 # Hash in Bucket 2 - .long 193491849 # Hash in Bucket 3 - .long 2090147939 # Hash in Bucket 5 - .long .Linfo_string7 # String in Bucket 1: _ZN11parent_test3fooEv - .long .Linfo_string5 # String in Bucket 1: _Z3foov - .long .Linfo_string6 # String in Bucket 2: parent_test - .long .Linfo_string3 # String in Bucket 2: int - .long .Linfo_string4 # String in Bucket 3: foo - .long .Linfo_string11 # String in Bucket 5: char - .long .Lnames4-.Lnames_entries0 # Offset in Bucket 1 - .long .Lnames2-.Lnames_entries0 # Offset in Bucket 1 - .long .Lnames3-.Lnames_entries0 # Offset in Bucket 2 - .long .Lnames0-.Lnames_entries0 # Offset in Bucket 2 - .long .Lnames1-.Lnames_entries0 # Offset in Bucket 3 - .long .Lnames5-.Lnames_entries0 # Offset in Bucket 5 -.Lnames_abbrev_start0: - .byte 1 # Abbrev code - .byte 46 # DW_TAG_subprogram - .byte 3 # DW_IDX_die_offset - .byte 19 # DW_FORM_ref4 - .byte 4 # DW_IDX_parent - .byte 19 # DW_FORM_ref4 - .byte 0 # End of abbrev - .byte 0 # End of abbrev - .byte 2 # Abbrev code - .byte 46 # DW_TAG_subprogram - .byte 3 # DW_IDX_die_offset - .byte 19 # DW_FORM_ref4 - .byte 4 # DW_IDX_parent - .byte 25 # DW_FORM_flag_present - .byte 0 # End of abbrev - .byte 0 # End of abbrev - .byte 3 # Abbrev code - .byte 57 # DW_TAG_namespace - .byte 3 # DW_IDX_die_offset - .byte 19 # DW_FORM_ref4 - .byte 4 # DW_IDX_parent - .byte 25 # DW_FORM_flag_present - .byte 0 # End of abbrev - .byte 0 # End of abbrev - .byte 4 # Abbrev code - .byte 36 # DW_TAG_base_type - .byte 3 # DW_IDX_die_offset - .byte 19 # DW_FORM_ref4 - .byte 4 # DW_IDX_parent - .byte 25 # DW_FORM_flag_present - .byte 0 # End of abbrev - .byte 0 # End of abbrev - .byte 5 # Abbrev code - .byte 19 # DW_TAG_structure_type - .byte 3 # DW_IDX_die_offset - .byte 19 # DW_FORM_ref4 - .byte 4 # DW_IDX_parent - .byte 25 # DW_FORM_flag_present - .byte 0 # End of abbrev - .byte 0 # End of abbrev - .byte 0 # End of abbrev list -.Lnames_abbrev_end0: -.Lnames_entries0: -.Lnames4: -.L3: - .byte 1 # Abbreviation code - .long 69 # DW_IDX_die_offset - .long .L5-.Lnames_entries0 # DW_IDX_parent - .byte 0 # End of list: _ZN11parent_test3fooEv -.Lnames2: -.L0: - .byte 2 # Abbreviation code - .long 39 # DW_IDX_die_offset - .byte 0 # DW_IDX_parent - # End of list: _Z3foov -.Lnames3: -.L5: - .byte 3 # Abbreviation code - .long 67 # DW_IDX_die_offset - .byte 0 # DW_IDX_parent - # End of list: parent_test -.Lnames0: -.L2: - .byte 4 # Abbreviation code - .long 35 # DW_IDX_die_offset - .byte 0 # DW_IDX_parent - # End of list: int -.Lnames1: - .byte 2 # Abbreviation code - .long 39 # DW_IDX_die_offset - .byte 1 # DW_IDX_parent - # Abbreviation code - .long 69 # DW_IDX_die_offset - .long .L5-.Lnames_entries0 # DW_IDX_parent -.L4: - .byte 5 # Abbreviation code - .long 86 # DW_IDX_die_offset - .byte 0 # DW_IDX_parent - # End of list: foo -.Lnames5: -.L1: - .byte 4 # Abbreviation code - .long 120 # DW_IDX_die_offset - .byte 0 # DW_IDX_parent - # End of list: char - .p2align 2, 0x0 -.Lnames_end0: - .ident "clang version 19.0.0git (git@github.com:llvm/llvm-project.git 4df364bc93af49ae413ec1ae8328f34ac70730c4)" - .section ".note.GNU-stack","",@progbits - .addrsig - .section .debug_line,"",@progbits -.Lline_table_start0: diff --git a/lld/test/ELF/debug-names-bad-aug-string.s b/lld/test/ELF/debug-names-bad-aug-string.s index 0c4f625fad7c1..bf46f4ccef03d 100644 --- a/lld/test/ELF/debug-names-bad-aug-string.s +++ b/lld/test/ELF/debug-names-bad-aug-string.s @@ -2,12 +2,17 @@ // editing the 'Header: augmentation string' in the .debug_names section. // REQUIRES: x86 -// RUN: llvm-mc -filetype=obj -triple=x86_64 %s -o %t1.o -// RUN: llvm-mc -filetype=obj -triple=x86_64 %p/Inputs/debug-names-2.s -o %t2.o -// RUN: ld.lld --debug-names %t1.o %t2.o -o %t +// RUN: rm -rf %t && split-file %s %t +// RUN: llvm-mc -filetype=obj -triple=x86_64 %t/debug-names-bad-aug-string.s \ +// RUN: -o %t/debug-names-bad-aug-string.o +// RUN: llvm-mc -filetype=obj -triple=x86_64 %t/debug-names-2.s \ +// RUN: -o %t/debug-names-2.o +// RUN: ld.lld --debug-names %t/debug-names-bad-aug-string.o \ +// RUN: %t/debug-names-2.o -o %t/debug-names-bad-aug-string -// RUN: llvm-dwarfdump -debug-names %t \ -// RUN: | FileCheck -DFILE=%t1.o -DFILE=%t2.o %s --check-prefix=DWARF +// RUN: llvm-dwarfdump -debug-names %t/debug-names-bad-aug-string \ +// RUN: | FileCheck -DFILE=%t/debug-names-bad-aug-string.o \ +// RUN: -DFILE=%t/debug-names-2.o %s --check-prefix=DWARF // DWARF: .debug_names contents: // DWARF: Name Index @ 0x0 { @@ -25,6 +30,8 @@ // DWARF: Compilation Unit offsets [ // DWARF-NEXT: CU[0]: 0x00000000 // DWARF-NEXT: CU[1]: 0x0000000c + +#--- debug-names-bad-aug-string.s .text .globl _Z2f12t1 # -- Begin function _Z2f12t1 .p2align 4, 0x90 @@ -151,3 +158,155 @@ _Z2f12t1: # @_Z2f12t1 .addrsig .section .debug_line,"",@progbits .Lline_table_start0: + +#--- debug-names-2.s +// input file: debug-names-2.cpp +// Generated with: +// - clang++ -g -O0 -gpubnames -fdebug-compilation-dir='debug-names-test' \ +// -S debug-names-2.cpp -o debug-names-2.s + +// debug-names-2.cpp contents: + +// struct t1 { }; +// int main() { +// t1 v1; +// } +// + .text + .globl main # -- Begin function main + .p2align 4, 0x90 + .type main,@function +main: # @main +.Lfunc_begin0: + .cfi_startproc +# %bb.0: # %entry + pushq %rbp + .cfi_def_cfa_offset 16 + .cfi_offset %rbp, -16 + movq %rsp, %rbp + .cfi_def_cfa_register %rbp +.Ltmp0: + xorl %eax, %eax + popq %rbp + .cfi_def_cfa %rsp, 8 + retq +.Ltmp1: +.Lfunc_end0: + .size main, .Lfunc_end0-main + .cfi_endproc + # -- End function + .section .debug_abbrev,"",@progbits + .byte 0 # EOM(1) + .byte 0 # EOM(2) + .byte 0 # EOM(3) + .section .debug_info,"",@progbits +.Lcu_begin0: + .long .Ldebug_info_end0-.Ldebug_info_start0 # Length of Unit +.Ldebug_info_start0: + .short 5 # DWARF version number + .byte 1 # DWARF Unit Type + .byte 8 # Address Size (in bytes) + .long .debug_abbrev # Offset Into Abbrev. Section +.Ldebug_info_end0: + .section .debug_str_offsets,"",@progbits + .long 32 # Length of String Offsets Set + .short 5 + .short 0 +.Lstr_offsets_base0: + .section .debug_str,"MS",@progbits,1 +.Linfo_string0: + .asciz "clang version 19.0.0git (git@github.com:llvm/llvm-project.git 4df364bc93af49ae413ec1ae8328f34ac70730c4)" # string offset=0 +.Linfo_string1: + .asciz "debug-names-2.cpp" # string offset=104 +.Linfo_string2: + .asciz "debug-names-test" # string offset=122 +.Linfo_string3: + .asciz "main" # string offset=139 +.Linfo_string4: + .asciz "int" # string offset=144 +.Linfo_string5: + .asciz "v1" # string offset=148 +.Linfo_string6: + .asciz "t1" # string offset=151 +.Laddr_table_base0: + .quad .Lfunc_begin0 +.Ldebug_addr_end0: + .section .debug_names,"",@progbits + .long .Lnames_end0-.Lnames_start0 # Header: unit length +.Lnames_start0: + .short 5 # Header: version + .short 0 # Header: padding + .long 1 # Header: compilation unit count + .long 0 # Header: local type unit count + .long 0 # Header: foreign type unit count + .long 3 # Header: bucket count + .long 3 # Header: name count + .long .Lnames_abbrev_end0-.Lnames_abbrev_start0 # Header: abbreviation table size + .long 8 # Header: augmentation string size + .ascii "LLVM0700" # Header: augmentation string + .long .Lcu_begin0 # Compilation unit 0 + .long 0 # Bucket 0 + .long 1 # Bucket 1 + .long 3 # Bucket 2 + .long 5863786 # Hash in Bucket 1 + .long 2090499946 # Hash in Bucket 1 + .long 193495088 # Hash in Bucket 2 + .long .Linfo_string6 # String in Bucket 1: t1 + .long .Linfo_string3 # String in Bucket 1: main + .long .Linfo_string4 # String in Bucket 2: int + .long .Lnames2-.Lnames_entries0 # Offset in Bucket 1 + .long .Lnames0-.Lnames_entries0 # Offset in Bucket 1 + .long .Lnames1-.Lnames_entries0 # Offset in Bucket 2 +.Lnames_abbrev_start0: + .byte 1 # Abbrev code + .byte 19 # DW_TAG_structure_type + .byte 3 # DW_IDX_die_offset + .byte 19 # DW_FORM_ref4 + .byte 4 # DW_IDX_parent + .byte 25 # DW_FORM_flag_present + .byte 0 # End of abbrev + .byte 0 # End of abbrev + .byte 2 # Abbrev code + .byte 46 # DW_TAG_subprogram + .byte 3 # DW_IDX_die_offset + .byte 19 # DW_FORM_ref4 + .byte 4 # DW_IDX_parent + .byte 25 # DW_FORM_flag_present + .byte 0 # End of abbrev + .byte 0 # End of abbrev + .byte 3 # Abbrev code + .byte 36 # DW_TAG_base_type + .byte 3 # DW_IDX_die_offset + .byte 19 # DW_FORM_ref4 + .byte 4 # DW_IDX_parent + .byte 25 # DW_FORM_flag_present + .byte 0 # End of abbrev + .byte 0 # End of abbrev + .byte 0 # End of abbrev list +.Lnames_abbrev_end0: +.Lnames_entries0: +.Lnames2: +.L1: + .byte 1 # Abbreviation code + .long 66 # DW_IDX_die_offset + .byte 0 # DW_IDX_parent + # End of list: t1 +.Lnames0: +.L2: + .byte 2 # Abbreviation code + .long 35 # DW_IDX_die_offset + .byte 0 # DW_IDX_parent + # End of list: main +.Lnames1: +.L0: + .byte 3 # Abbreviation code + .long 62 # DW_IDX_die_offset + .byte 0 # DW_IDX_parent + # End of list: int + .p2align 2, 0x0 +.Lnames_end0: + .ident "clang version 19.0.0git (git@github.com:llvm/llvm-project.git 4df364bc93af49ae413ec1ae8328f34ac70730c4)" + .section ".note.GNU-stack","",@progbits + .addrsig + .section .debug_line,"",@progbits +.Lline_table_start0: diff --git a/lld/test/ELF/debug-names-bad-version.s b/lld/test/ELF/debug-names-bad-version.s index 6a299805ca090..eda1eaa03039b 100644 --- a/lld/test/ELF/debug-names-bad-version.s +++ b/lld/test/ELF/debug-names-bad-version.s @@ -3,12 +3,17 @@ // 5 to 4). // REQUIRES: x86 -// RUN: llvm-mc -filetype=obj -triple=x86_64 %s -o %t1.o -// RUN: llvm-mc -filetype=obj -triple=x86_64 %p/Inputs/debug-names-2.s -o %t2.o -// RUN: not ld.lld --debug-names %t1.o %t2.o -o /dev/null 2>&1 | FileCheck %s +// RUN: rm -rf %t && split-file %s %t +// RUN: llvm-mc -filetype=obj -triple=x86_64 %t/debug-names-bad-version.s \ +// RUN: -o %t/debug-names-bad-version.o +// RUN: llvm-mc -filetype=obj -triple=x86_64 %t/debug-names-2.s \ +// RUN: -o %t/debug-names-2.o +// RUN: not ld.lld --debug-names %t/debug-names-bad-version.o \ +// RUN: %t/debug-names-2.o -o /dev/null 2>&1 | FileCheck %s // CHECK: error: {{.*}}:(.debug_names): unsupported version - + +#--- debug-names-bad-version.s .text .globl _Z2f12t1 # -- Begin function _Z2f12t1 .p2align 4, 0x90 @@ -170,3 +175,155 @@ _Z2f12t1: # @_Z2f12t1 .addrsig .section .debug_line,"",@progbits .Lline_table_start0: + +#--- debug-names-2.s +// input file: debug-names-2.cpp +// Generated with: +// - clang++ -g -O0 -gpubnames -fdebug-compilation-dir='debug-names-test' \ +// -S debug-names-2.cpp -o debug-names-2.s + +// debug-names-2.cpp contents: + +// struct t1 { }; +// int main() { +// t1 v1; +// } +// + .text + .globl main # -- Begin function main + .p2align 4, 0x90 + .type main,@function +main: # @main +.Lfunc_begin0: + .cfi_startproc +# %bb.0: # %entry + pushq %rbp + .cfi_def_cfa_offset 16 + .cfi_offset %rbp, -16 + movq %rsp, %rbp + .cfi_def_cfa_register %rbp +.Ltmp0: + xorl %eax, %eax + popq %rbp + .cfi_def_cfa %rsp, 8 + retq +.Ltmp1: +.Lfunc_end0: + .size main, .Lfunc_end0-main + .cfi_endproc + # -- End function + .section .debug_abbrev,"",@progbits + .byte 0 # EOM(1) + .byte 0 # EOM(2) + .byte 0 # EOM(3) + .section .debug_info,"",@progbits +.Lcu_begin0: + .long .Ldebug_info_end0-.Ldebug_info_start0 # Length of Unit +.Ldebug_info_start0: + .short 5 # DWARF version number + .byte 1 # DWARF Unit Type + .byte 8 # Address Size (in bytes) + .long .debug_abbrev # Offset Into Abbrev. Section +.Ldebug_info_end0: + .section .debug_str_offsets,"",@progbits + .long 32 # Length of String Offsets Set + .short 5 + .short 0 +.Lstr_offsets_base0: + .section .debug_str,"MS",@progbits,1 +.Linfo_string0: + .asciz "clang version 19.0.0git (git@github.com:llvm/llvm-project.git 4df364bc93af49ae413ec1ae8328f34ac70730c4)" # string offset=0 +.Linfo_string1: + .asciz "debug-names-2.cpp" # string offset=104 +.Linfo_string2: + .asciz "debug-names-test" # string offset=122 +.Linfo_string3: + .asciz "main" # string offset=139 +.Linfo_string4: + .asciz "int" # string offset=144 +.Linfo_string5: + .asciz "v1" # string offset=148 +.Linfo_string6: + .asciz "t1" # string offset=151 +.Laddr_table_base0: + .quad .Lfunc_begin0 +.Ldebug_addr_end0: + .section .debug_names,"",@progbits + .long .Lnames_end0-.Lnames_start0 # Header: unit length +.Lnames_start0: + .short 5 # Header: version + .short 0 # Header: padding + .long 1 # Header: compilation unit count + .long 0 # Header: local type unit count + .long 0 # Header: foreign type unit count + .long 3 # Header: bucket count + .long 3 # Header: name count + .long .Lnames_abbrev_end0-.Lnames_abbrev_start0 # Header: abbreviation table size + .long 8 # Header: augmentation string size + .ascii "LLVM0700" # Header: augmentation string + .long .Lcu_begin0 # Compilation unit 0 + .long 0 # Bucket 0 + .long 1 # Bucket 1 + .long 3 # Bucket 2 + .long 5863786 # Hash in Bucket 1 + .long 2090499946 # Hash in Bucket 1 + .long 193495088 # Hash in Bucket 2 + .long .Linfo_string6 # String in Bucket 1: t1 + .long .Linfo_string3 # String in Bucket 1: main + .long .Linfo_string4 # String in Bucket 2: int + .long .Lnames2-.Lnames_entries0 # Offset in Bucket 1 + .long .Lnames0-.Lnames_entries0 # Offset in Bucket 1 + .long .Lnames1-.Lnames_entries0 # Offset in Bucket 2 +.Lnames_abbrev_start0: + .byte 1 # Abbrev code + .byte 19 # DW_TAG_structure_type + .byte 3 # DW_IDX_die_offset + .byte 19 # DW_FORM_ref4 + .byte 4 # DW_IDX_parent + .byte 25 # DW_FORM_flag_present + .byte 0 # End of abbrev + .byte 0 # End of abbrev + .byte 2 # Abbrev code + .byte 46 # DW_TAG_subprogram + .byte 3 # DW_IDX_die_offset + .byte 19 # DW_FORM_ref4 + .byte 4 # DW_IDX_parent + .byte 25 # DW_FORM_flag_present + .byte 0 # End of abbrev + .byte 0 # End of abbrev + .byte 3 # Abbrev code + .byte 36 # DW_TAG_base_type + .byte 3 # DW_IDX_die_offset + .byte 19 # DW_FORM_ref4 + .byte 4 # DW_IDX_parent + .byte 25 # DW_FORM_flag_present + .byte 0 # End of abbrev + .byte 0 # End of abbrev + .byte 0 # End of abbrev list +.Lnames_abbrev_end0: +.Lnames_entries0: +.Lnames2: +.L1: + .byte 1 # Abbreviation code + .long 66 # DW_IDX_die_offset + .byte 0 # DW_IDX_parent + # End of list: t1 +.Lnames0: +.L2: + .byte 2 # Abbreviation code + .long 35 # DW_IDX_die_offset + .byte 0 # DW_IDX_parent + # End of list: main +.Lnames1: +.L0: + .byte 3 # Abbreviation code + .long 62 # DW_IDX_die_offset + .byte 0 # DW_IDX_parent + # End of list: int + .p2align 2, 0x0 +.Lnames_end0: + .ident "clang version 19.0.0git (git@github.com:llvm/llvm-project.git 4df364bc93af49ae413ec1ae8328f34ac70730c4)" + .section ".note.GNU-stack","",@progbits + .addrsig + .section .debug_line,"",@progbits +.Lline_table_start0: diff --git a/lld/test/ELF/debug-names-parent-idx.s b/lld/test/ELF/debug-names-parent-idx.s index cda9203fd2167..b44455bb498ef 100644 --- a/lld/test/ELF/debug-names-parent-idx.s +++ b/lld/test/ELF/debug-names-parent-idx.s @@ -1,4 +1,4 @@ -// Generated with: +// debug-names-parent-idx.s generated with: // - clang++ -g -O0 -gpubnames -fdebug-compilation-dir='parent-idx-test' \ // -S debug-names-parent-idx.cpp -o debug-names-parent-idx.s @@ -35,12 +35,17 @@ // } // REQUIRES: x86 -// RUN: llvm-mc -filetype=obj -triple=x86_64 %s -o %t1.o -// RUN: llvm-mc -filetype=obj -triple=x86_64 %p/Inputs/debug-names-parent-idx-2.s -o %t2.o -// RUN: ld.lld --debug-names %t1.o %t2.o -o %t +// RUN: rm -rf %t && split-file %s %t +// RUN: llvm-mc -filetype=obj -triple=x86_64 %t/debug-names-parent-idx.s \ +// RUN: -o %t/debug-names-parent-idx.o +// RUN: llvm-mc -filetype=obj -triple=x86_64 %t/debug-names-parent-idx-2.s \ +// RUN: -o %t/debug-names-parent-idx-2.o +// RUN: ld.lld --debug-names %t/debug-names-parent-idx.o \ +// RUN: %t/debug-names-parent-idx-2.o -o %t/debug-names-parent-idx -// RUN: llvm-dwarfdump -debug-names %t \ -// RUN: | FileCheck -DFILE=%t1.o -DFILE=%t2.o %s --check-prefix=DWARF +// RUN: llvm-dwarfdump -debug-names %t/debug-names-parent-idx \ +// RUN: | FileCheck -DFILE=%t/debug-names-parent-idx.o \ +// RUN: -DFILE=%t/debug-names-parent-idx-2.o %s --check-prefix=DWARF // DWARF: .debug_names contents: // DWARF: Name Index @ 0x0 { @@ -183,6 +188,7 @@ // DWARF-NEXT: DW_IDX_parent: // DWARF-NEXT: DW_IDX_compile_unit: 0x01 +#--- debug-names-parent-idx.s .text .globl _Z3barR3fooi # -- Begin function _Z3barR3fooi .p2align 4, 0x90 @@ -417,3 +423,271 @@ main: # @main .addrsig_sym _ZN11parent_test3fooEv .section .debug_line,"",@progbits .Lline_table_start0: + +#--- debug-names-parent-idx-2.s +// Generated with: + +// - clang++ -g -O0 -gpubnames -fdebug-compilation-dir='parent-idx-test' \ +// -S debug-names-parent-idx-2.cpp -o debug-names-parent-idx-2.s + +// foo.h contents: + +// int foo(); + +//struct foo { +// int x; +// char y; +// struct foo *foo_ptr; +// }; + +// namespace parent_test { +// int foo(); +// } + +// debug-names-parent-index-2.cpp contents: + +// #include "foo.h" +// int foo () { +// struct foo struct2; +// struct2.x = 1024; +// struct2.y = 'r'; +// struct2.foo_ptr = nullptr; +// return struct2.x * (int) struct2.y; +// } + +// namespace parent_test { +// int foo () { +// return 25; +// } +// } + + .text + .globl _Z3foov # -- Begin function _Z3foov + .p2align 4, 0x90 + .type _Z3foov,@function +_Z3foov: # @_Z3foov +.Lfunc_begin0: + .cfi_startproc +# %bb.0: # %entry + pushq %rbp + .cfi_def_cfa_offset 16 + .cfi_offset %rbp, -16 + movq %rsp, %rbp + .cfi_def_cfa_register %rbp +.Ltmp0: + movl $1024, -16(%rbp) # imm = 0x400 + movb $114, -12(%rbp) + movq $0, -8(%rbp) + movl -16(%rbp), %eax + movsbl -12(%rbp), %ecx + imull %ecx, %eax + popq %rbp + .cfi_def_cfa %rsp, 8 + retq +.Ltmp1: +.Lfunc_end0: + .size _Z3foov, .Lfunc_end0-_Z3foov + .cfi_endproc + # -- End function + .globl _ZN11parent_test3fooEv # -- Begin function _ZN11parent_test3fooEv + .p2align 4, 0x90 + .type _ZN11parent_test3fooEv,@function +_ZN11parent_test3fooEv: # @_ZN11parent_test3fooEv +.Lfunc_begin1: + .cfi_startproc +# %bb.0: # %entry + pushq %rbp + .cfi_def_cfa_offset 16 + .cfi_offset %rbp, -16 + movq %rsp, %rbp + .cfi_def_cfa_register %rbp +.Ltmp2: + movl $25, %eax + popq %rbp + .cfi_def_cfa %rsp, 8 + retq +.Ltmp3: +.Lfunc_end1: + .size _ZN11parent_test3fooEv, .Lfunc_end1-_ZN11parent_test3fooEv + .cfi_endproc + # -- End function + .section .debug_abbrev,"",@progbits + .byte 0 # EOM(1) + .byte 0 # EOM(2) + .byte 0 # EOM(3) + .section .debug_info,"",@progbits +.Lcu_begin0: + .long .Ldebug_info_end0-.Ldebug_info_start0 # Length of Unit +.Ldebug_info_start0: + .short 5 # DWARF version number + .byte 1 # DWARF Unit Type + .byte 8 # Address Size (in bytes) + .long .debug_abbrev # Offset Into Abbrev. Section +.Ldebug_info_end0: + .section .debug_str_offsets,"",@progbits + .long 56 # Length of String Offsets Set + .short 5 + .short 0 +.Lstr_offsets_base0: + .section .debug_str,"MS",@progbits,1 +.Linfo_string0: + .asciz "clang version 19.0.0git (git@github.com:llvm/llvm-project.git 4df364bc93af49ae413ec1ae8328f34ac70730c4)" # string offset=0 +.Linfo_string1: + .asciz "debug-names-parent-idx-2.cpp" # string offset=104 +.Linfo_string2: + .asciz "parent-idx-test" # string offset=133 +.Linfo_string3: + .asciz "int" # string offset=149 +.Linfo_string4: + .asciz "foo" # string offset=153 +.Linfo_string5: + .asciz "_Z3foov" # string offset=157 +.Linfo_string6: + .asciz "parent_test" # string offset=165 +.Linfo_string7: + .asciz "_ZN11parent_test3fooEv" # string offset=177 +.Linfo_string8: + .asciz "struct2" # string offset=200 +.Linfo_string9: + .asciz "x" # string offset=208 +.Linfo_string10: + .asciz "y" # string offset=210 +.Linfo_string11: + .asciz "char" # string offset=212 +.Linfo_string12: + .asciz "foo_ptr" # string offset=217 +.Laddr_table_base0: + .quad .Lfunc_begin0 + .quad .Lfunc_begin1 +.Ldebug_addr_end0: + .section .debug_names,"",@progbits + .long .Lnames_end0-.Lnames_start0 # Header: unit length +.Lnames_start0: + .short 5 # Header: version + .short 0 # Header: padding + .long 1 # Header: compilation unit count + .long 0 # Header: local type unit count + .long 0 # Header: foreign type unit count + .long 6 # Header: bucket count + .long 6 # Header: name count + .long .Lnames_abbrev_end0-.Lnames_abbrev_start0 # Header: abbreviation table size + .long 8 # Header: augmentation string size + .ascii "LLVM0700" # Header: augmentation string + .long .Lcu_begin0 # Compilation unit 0 + .long 0 # Bucket 0 + .long 1 # Bucket 1 + .long 3 # Bucket 2 + .long 5 # Bucket 3 + .long 0 # Bucket 4 + .long 6 # Bucket 5 + .long -1451972055 # Hash in Bucket 1 + .long -1257882357 # Hash in Bucket 1 + .long 175265198 # Hash in Bucket 2 + .long 193495088 # Hash in Bucket 2 + .long 193491849 # Hash in Bucket 3 + .long 2090147939 # Hash in Bucket 5 + .long .Linfo_string7 # String in Bucket 1: _ZN11parent_test3fooEv + .long .Linfo_string5 # String in Bucket 1: _Z3foov + .long .Linfo_string6 # String in Bucket 2: parent_test + .long .Linfo_string3 # String in Bucket 2: int + .long .Linfo_string4 # String in Bucket 3: foo + .long .Linfo_string11 # String in Bucket 5: char + .long .Lnames4-.Lnames_entries0 # Offset in Bucket 1 + .long .Lnames2-.Lnames_entries0 # Offset in Bucket 1 + .long .Lnames3-.Lnames_entries0 # Offset in Bucket 2 + .long .Lnames0-.Lnames_entries0 # Offset in Bucket 2 + .long .Lnames1-.Lnames_entries0 # Offset in Bucket 3 + .long .Lnames5-.Lnames_entries0 # Offset in Bucket 5 +.Lnames_abbrev_start0: + .byte 1 # Abbrev code + .byte 46 # DW_TAG_subprogram + .byte 3 # DW_IDX_die_offset + .byte 19 # DW_FORM_ref4 + .byte 4 # DW_IDX_parent + .byte 19 # DW_FORM_ref4 + .byte 0 # End of abbrev + .byte 0 # End of abbrev + .byte 2 # Abbrev code + .byte 46 # DW_TAG_subprogram + .byte 3 # DW_IDX_die_offset + .byte 19 # DW_FORM_ref4 + .byte 4 # DW_IDX_parent + .byte 25 # DW_FORM_flag_present + .byte 0 # End of abbrev + .byte 0 # End of abbrev + .byte 3 # Abbrev code + .byte 57 # DW_TAG_namespace + .byte 3 # DW_IDX_die_offset + .byte 19 # DW_FORM_ref4 + .byte 4 # DW_IDX_parent + .byte 25 # DW_FORM_flag_present + .byte 0 # End of abbrev + .byte 0 # End of abbrev + .byte 4 # Abbrev code + .byte 36 # DW_TAG_base_type + .byte 3 # DW_IDX_die_offset + .byte 19 # DW_FORM_ref4 + .byte 4 # DW_IDX_parent + .byte 25 # DW_FORM_flag_present + .byte 0 # End of abbrev + .byte 0 # End of abbrev + .byte 5 # Abbrev code + .byte 19 # DW_TAG_structure_type + .byte 3 # DW_IDX_die_offset + .byte 19 # DW_FORM_ref4 + .byte 4 # DW_IDX_parent + .byte 25 # DW_FORM_flag_present + .byte 0 # End of abbrev + .byte 0 # End of abbrev + .byte 0 # End of abbrev list +.Lnames_abbrev_end0: +.Lnames_entries0: +.Lnames4: +.L3: + .byte 1 # Abbreviation code + .long 69 # DW_IDX_die_offset + .long .L5-.Lnames_entries0 # DW_IDX_parent + .byte 0 # End of list: _ZN11parent_test3fooEv +.Lnames2: +.L0: + .byte 2 # Abbreviation code + .long 39 # DW_IDX_die_offset + .byte 0 # DW_IDX_parent + # End of list: _Z3foov +.Lnames3: +.L5: + .byte 3 # Abbreviation code + .long 67 # DW_IDX_die_offset + .byte 0 # DW_IDX_parent + # End of list: parent_test +.Lnames0: +.L2: + .byte 4 # Abbreviation code + .long 35 # DW_IDX_die_offset + .byte 0 # DW_IDX_parent + # End of list: int +.Lnames1: + .byte 2 # Abbreviation code + .long 39 # DW_IDX_die_offset + .byte 1 # DW_IDX_parent + # Abbreviation code + .long 69 # DW_IDX_die_offset + .long .L5-.Lnames_entries0 # DW_IDX_parent +.L4: + .byte 5 # Abbreviation code + .long 86 # DW_IDX_die_offset + .byte 0 # DW_IDX_parent + # End of list: foo +.Lnames5: +.L1: + .byte 4 # Abbreviation code + .long 120 # DW_IDX_die_offset + .byte 0 # DW_IDX_parent + # End of list: char + .p2align 2, 0x0 +.Lnames_end0: + .ident "clang version 19.0.0git (git@github.com:llvm/llvm-project.git 4df364bc93af49ae413ec1ae8328f34ac70730c4)" + .section ".note.GNU-stack","",@progbits + .addrsig + .section .debug_line,"",@progbits +.Lline_table_start0: diff --git a/lld/test/ELF/debug-names.s b/lld/test/ELF/debug-names.s index ca6d32998542b..baadadd98ebf4 100644 --- a/lld/test/ELF/debug-names.s +++ b/lld/test/ELF/debug-names.s @@ -1,4 +1,4 @@ -// Generated with: +// debug_names.s was gGenerated with: // - clang++ -g -O0 -gpubnames -fdebug-compilation-dir='debug-names-test' \ // -S debug-names.cpp -o debug-names.s @@ -9,19 +9,27 @@ // void f1(t1) { } // REQUIRES: x86 -// RUN: llvm-mc -filetype=obj -triple=x86_64 %s -o %t1.o -// RUN: llvm-mc -filetype=obj -triple=x86_64 %p/Inputs/debug-names-2.s -o %t2.o +// RUN: rm -rf %t && split-file %s %t +// RUN: llvm-mc -filetype=obj -triple=x86_64 %t/debug-names.s \ +// RUN: -o %t/debug-names.o +// RUN: llvm-mc -filetype=obj -triple=x86_64 %t/debug-names-2.s \ +// RUN: -o %t/debug-names-2.o -// RUN: ld.lld --debug-names --no-debug-names %t1.o %t2.o -o %t -// RUN: llvm-readelf -SW %t | FileCheck %s --check-prefix=NO_DBG_NAMES +// RUN: ld.lld --debug-names --no-debug-names %t/debug-names.o \ +// RUN: %t/debug-names-2.o -o %t/debug-names +// RUN: llvm-readelf -SW %t/debug-names \ +// RUN: | FileCheck %s --check-prefix=NO_DBG_NAMES // NO_DBG_NAMES: .debug_names PROGBITS 0000000000000000 [[#%x,]] 000110 -// RUN: ld.lld --debug-names %t1.o %t2.o -o %t +// RUN: ld.lld --debug-names %t/debug-names.o %t/debug-names-2.o \ +// RUN: -o %t/debug-names -// RUN: llvm-dwarfdump -debug-names %t | FileCheck %s --check-prefix=DWARF -// RUN: llvm-readelf -SW %t \ -// RUN: | FileCheck -DFILE=%t1.o -DFILE=%t2.o %s --check-prefix=READELF +// RUN: llvm-dwarfdump -debug-names %t/debug-names \ +// RUN: | FileCheck %s --check-prefix=DWARF +// RUN: llvm-readelf -SW %t/debug-names \ +// RUN: | FileCheck -DFILE=%t/debug-names.o \ +// RUN: -DFILE=%t/debug-names-2.o %s --check-prefix=READELF // READELF: .debug_names PROGBITS 0000000000000000 [[#%x,]] 0000d0 @@ -105,6 +113,7 @@ // DWARF-NEXT: DW_IDX_parent: // DWARF-NEXT: DW_IDX_compile_unit: 0x01 +#--- debug-names.s .text .globl _Z2f12t1 # -- Begin function _Z2f12t1 .p2align 4, 0x90 @@ -231,3 +240,154 @@ _Z2f12t1: # @_Z2f12t1 .addrsig .section .debug_line,"",@progbits .Lline_table_start0: + +#--- debug-names-2.s +// Generated with: +// - clang++ -g -O0 -gpubnames -fdebug-compilation-dir='debug-names-test' \ +// -S debug-names-2.cpp -o debug-names-2.s + +// debug-names-2.cpp contents: + +// struct t1 { }; +// int main() { +// t1 v1; +// } +// + .text + .globl main # -- Begin function main + .p2align 4, 0x90 + .type main,@function +main: # @main +.Lfunc_begin0: + .cfi_startproc +# %bb.0: # %entry + pushq %rbp + .cfi_def_cfa_offset 16 + .cfi_offset %rbp, -16 + movq %rsp, %rbp + .cfi_def_cfa_register %rbp +.Ltmp0: + xorl %eax, %eax + popq %rbp + .cfi_def_cfa %rsp, 8 + retq +.Ltmp1: +.Lfunc_end0: + .size main, .Lfunc_end0-main + .cfi_endproc + # -- End function + .section .debug_abbrev,"",@progbits + .byte 0 # EOM(1) + .byte 0 # EOM(2) + .byte 0 # EOM(3) + .section .debug_info,"",@progbits +.Lcu_begin0: + .long .Ldebug_info_end0-.Ldebug_info_start0 # Length of Unit +.Ldebug_info_start0: + .short 5 # DWARF version number + .byte 1 # DWARF Unit Type + .byte 8 # Address Size (in bytes) + .long .debug_abbrev # Offset Into Abbrev. Section +.Ldebug_info_end0: + .section .debug_str_offsets,"",@progbits + .long 32 # Length of String Offsets Set + .short 5 + .short 0 +.Lstr_offsets_base0: + .section .debug_str,"MS",@progbits,1 +.Linfo_string0: + .asciz "clang version 19.0.0git (git@github.com:llvm/llvm-project.git 4df364bc93af49ae413ec1ae8328f34ac70730c4)" # string offset=0 +.Linfo_string1: + .asciz "debug-names-2.cpp" # string offset=104 +.Linfo_string2: + .asciz "debug-names-test" # string offset=122 +.Linfo_string3: + .asciz "main" # string offset=139 +.Linfo_string4: + .asciz "int" # string offset=144 +.Linfo_string5: + .asciz "v1" # string offset=148 +.Linfo_string6: + .asciz "t1" # string offset=151 +.Laddr_table_base0: + .quad .Lfunc_begin0 +.Ldebug_addr_end0: + .section .debug_names,"",@progbits + .long .Lnames_end0-.Lnames_start0 # Header: unit length +.Lnames_start0: + .short 5 # Header: version + .short 0 # Header: padding + .long 1 # Header: compilation unit count + .long 0 # Header: local type unit count + .long 0 # Header: foreign type unit count + .long 3 # Header: bucket count + .long 3 # Header: name count + .long .Lnames_abbrev_end0-.Lnames_abbrev_start0 # Header: abbreviation table size + .long 8 # Header: augmentation string size + .ascii "LLVM0700" # Header: augmentation string + .long .Lcu_begin0 # Compilation unit 0 + .long 0 # Bucket 0 + .long 1 # Bucket 1 + .long 3 # Bucket 2 + .long 5863786 # Hash in Bucket 1 + .long 2090499946 # Hash in Bucket 1 + .long 193495088 # Hash in Bucket 2 + .long .Linfo_string6 # String in Bucket 1: t1 + .long .Linfo_string3 # String in Bucket 1: main + .long .Linfo_string4 # String in Bucket 2: int + .long .Lnames2-.Lnames_entries0 # Offset in Bucket 1 + .long .Lnames0-.Lnames_entries0 # Offset in Bucket 1 + .long .Lnames1-.Lnames_entries0 # Offset in Bucket 2 +.Lnames_abbrev_start0: + .byte 1 # Abbrev code + .byte 19 # DW_TAG_structure_type + .byte 3 # DW_IDX_die_offset + .byte 19 # DW_FORM_ref4 + .byte 4 # DW_IDX_parent + .byte 25 # DW_FORM_flag_present + .byte 0 # End of abbrev + .byte 0 # End of abbrev + .byte 2 # Abbrev code + .byte 46 # DW_TAG_subprogram + .byte 3 # DW_IDX_die_offset + .byte 19 # DW_FORM_ref4 + .byte 4 # DW_IDX_parent + .byte 25 # DW_FORM_flag_present + .byte 0 # End of abbrev + .byte 0 # End of abbrev + .byte 3 # Abbrev code + .byte 36 # DW_TAG_base_type + .byte 3 # DW_IDX_die_offset + .byte 19 # DW_FORM_ref4 + .byte 4 # DW_IDX_parent + .byte 25 # DW_FORM_flag_present + .byte 0 # End of abbrev + .byte 0 # End of abbrev + .byte 0 # End of abbrev list +.Lnames_abbrev_end0: +.Lnames_entries0: +.Lnames2: +.L1: + .byte 1 # Abbreviation code + .long 66 # DW_IDX_die_offset + .byte 0 # DW_IDX_parent + # End of list: t1 +.Lnames0: +.L2: + .byte 2 # Abbreviation code + .long 35 # DW_IDX_die_offset + .byte 0 # DW_IDX_parent + # End of list: main +.Lnames1: +.L0: + .byte 3 # Abbreviation code + .long 62 # DW_IDX_die_offset + .byte 0 # DW_IDX_parent + # End of list: int + .p2align 2, 0x0 +.Lnames_end0: + .ident "clang version 19.0.0git (git@github.com:llvm/llvm-project.git 4df364bc93af49ae413ec1ae8328f34ac70730c4)" + .section ".note.GNU-stack","",@progbits + .addrsig + .section .debug_line,"",@progbits +.Lline_table_start0: From e4442221c8c8197e5970b92fc86c8cf7517f319b Mon Sep 17 00:00:00 2001 From: Fangrui Song Date: Sun, 7 Apr 2024 12:41:58 -0700 Subject: [PATCH 14/37] Simplify and optimize .debug_names and removed dead TU code [ELF] Add --debug-names to create merged .debug_names `clang -g -gpubnames` (with optional -gsplit-dwarf) creates the `.debug_names` section ("per-CU" index). By default lld concatenates input `.debug_names` sections into an output `.debug_names` section. LLDB can consume the concatenated section but the lookup performance is not good. This patch adds --debug-names to create a per-module index by combining the per-CU indexes into a single index that covers the entire load module. The produced `.debug_names` is a replacement for `.gdb_index`. Type units (-fdebug-types-section) are not handled yet. Co-authored-by: Fangrui Song --- lld/ELF/SyntheticSections.cpp | 1211 +++++++---------- lld/ELF/SyntheticSections.h | 160 +-- lld/ELF/Writer.cpp | 1 + lld/docs/ReleaseNotes.rst | 2 + lld/test/ELF/debug-names-bad-aug-string.s | 78 +- lld/test/ELF/debug-names-bad-die-idx-sizes.s | 25 +- lld/test/ELF/debug-names-bad-name-count.s | 30 +- lld/test/ELF/debug-names-bad-offsets-sizes.s | 28 +- lld/test/ELF/debug-names-bad-version.s | 45 +- lld/test/ELF/debug-names-dwarf64.s | 20 +- .../ELF/debug-names-invalid-abbrev-code.s | 23 +- .../ELF/debug-names-invalid-attribute-2.s | 24 +- .../ELF/debug-names-invalid-attribute-3.s | 28 +- lld/test/ELF/debug-names-invalid-attribute.s | 14 +- lld/test/ELF/debug-names-invalid-parent-idx.s | 27 +- lld/test/ELF/debug-names-parent-idx.s | 468 ++++--- lld/test/ELF/debug-names.s | 251 ++-- lld/test/ELF/driver.test | 3 +- 18 files changed, 1171 insertions(+), 1267 deletions(-) diff --git a/lld/ELF/SyntheticSections.cpp b/lld/ELF/SyntheticSections.cpp index c87b29e34f69d..be307f1b001f3 100644 --- a/lld/ELF/SyntheticSections.cpp +++ b/lld/ELF/SyntheticSections.cpp @@ -14,7 +14,6 @@ //===----------------------------------------------------------------------===// #include "SyntheticSections.h" - #include "Config.h" #include "DWARF.h" #include "EhFrame.h" @@ -31,6 +30,7 @@ #include "lld/Common/Strings.h" #include "lld/Common/Version.h" #include "llvm/ADT/STLExtras.h" +#include "llvm/ADT/Sequence.h" #include "llvm/ADT/SetOperations.h" #include "llvm/ADT/StringExtras.h" #include "llvm/BinaryFormat/Dwarf.h" @@ -2714,754 +2714,584 @@ static uint32_t computeGdbHash(StringRef s) { return h; } -template -DebugNamesSection::DebugNamesSection() - : SyntheticSection(0, SHT_PROGBITS, 1, ".debug_names") {} - -template -template -void DebugNamesSection::getNameRelocsImpl( - InputSection *sec, ArrayRef rels, - DenseMap &relocs) { - for (auto &rel : rels) { - Symbol &sym = sec->getFile()->getRelocTargetSym(rel); - relocs[rel.r_offset] = sym.getVA(getAddend(rel)); - } -} - -template -void DebugNamesSection::getNameRelocs( - InputSectionBase *base, DenseMap &relocs) { - auto *sec = cast(base); - const RelsOrRelas rels = sec->template relsOrRelas(); - if (rels.areRelocsRel()) - getNameRelocsImpl(sec, rels.rels, relocs); - else - getNameRelocsImpl(sec, rels.relas, relocs); -} - -template void DebugNamesSection::writeTo(uint8_t *buf) { - SmallVector mergedCuOffsets; - SmallVector mergedTuOffsets; - DenseMap strOffsets; - SmallVector, 0> chunksRelocs; - chunksRelocs.reserve(numChunks); - - for (size_t i = 0, e = numChunks; i != e; ++i) { - DebugNamesOutputChunk &chunk = outputChunks[i]; - InputSectionBase *base = inputDebugNamesSections[i]; - DenseMap &relocs = chunksRelocs.emplace_back(); - getNameRelocs(base, relocs); - - // Update CuOffsets list with new data - for (uint32_t cuOffset : chunk.compilationUnits) - mergedCuOffsets.push_back(chunk.sec->outSecOff + cuOffset); - - // TODO: Update TuOffsets list with new data - } - - // Update the entries with the relocated string offsets. - for (NamedEntry &stringEntry : mergedEntries) { - uint32_t oldOffset = stringEntry.stringOffsetOffset; - uint32_t idx = stringEntry.chunkIdx; - stringEntry.relocatedEntryOffset = chunksRelocs[idx][oldOffset]; - } - - // Write out bytes for merged section. - - // Write the header. - endian::write32(buf + 0, mergedHdr.UnitLength); - endian::write16(buf + 4, mergedHdr.Version); - endian::write32(buf + 8, mergedHdr.CompUnitCount); - endian::write32(buf + 12, mergedHdr.LocalTypeUnitCount); - endian::write32(buf + 16, mergedHdr.ForeignTypeUnitCount); - endian::write32(buf + 20, mergedHdr.BucketCount); - endian::write32(buf + 24, mergedHdr.NameCount); - endian::write32(buf + 28, mergedHdr.AbbrevTableSize); - endian::write32(buf + 32, mergedHdr.AugmentationStringSize); - buf += 36; - memcpy(buf, mergedHdr.AugmentationString.c_str(), 8); - buf += 8; - - // Write the CU list. - for (uint32_t offset : mergedCuOffsets) { - endian::write32(buf + 0, offset); - buf += 4; - } - - // Write the local TU list. - // TODO: Fix this, once we get everything working without TUs. - if (mergedHdr.LocalTypeUnitCount != 0) - warn(".debug_names: type units are not handled in merged index"); - - // Write the foreign TU list. - // TODO: Fix this, once we get everything working without TUs. - if (mergedHdr.ForeignTypeUnitCount != 0) - warn(".debug_names: type units are not handled in merged index"); - - // Write the hash table. - // ... Write the buckets - uint32_t idx = 1; - for (const SmallVector &bucket : bucketList) { - if (!bucket.empty()) - endian::write32(buf + 0, idx); - idx += bucket.size(); - buf += 4; - } - - // ...Write the hashes - for (const auto &bucket : bucketList) { - for (const auto &entry : bucket) { - uint32_t hashValue = entry->hashValue; - endian::write32(buf + 0, hashValue); - buf += 4; - } - } - - // Write the string offsets. - for (const NamedEntry &entry : mergedEntries) { - endian::write32(buf + 0, entry.relocatedEntryOffset); - buf += 4; - } - - // Write the entry offsets. - for (const auto &entry : mergedEntries) { - endian::write32(buf + 0, entry.entryOffset); - buf += 4; - } - - // Write the abbrev table. - for (const Abbrev *abbrev : mergedAbbrevTable) { - buf += encodeULEB128(abbrev->code, buf); - buf += encodeULEB128(abbrev->tag, buf); - for (DWARFDebugNames::AttributeEncoding attr : abbrev->attributes) { - buf += encodeULEB128(attr.Index, buf); - buf += encodeULEB128(attr.Form, buf); - } - endian::write16(buf + 0, 0); // attribute sentinels. - buf += 2; - } - *buf++ = 0; // abbrev table sentinel - - // Write the entry pool. - for (const auto &stringEntry : mergedEntries) { - // Write all the entries for the string. - for (const std::unique_ptr &entry : stringEntry.indexEntries) { - buf += encodeULEB128(entry->abbrevCode, buf); - for (const auto &value : entry->attrValues) { - endian::write32(buf + 0, value.attrValue); - buf += value.attrSize; - } - } - *buf++ = 0; // Entry sentinel - } -} - -template bool DebugNamesSection::isNeeded() const { - return numChunks > 0; -} - -template -static void readCompileUnitOffsets( - typename DebugNamesSection::DebugNamesSectionData &secData, - typename DebugNamesSection::DebugNamesOutputChunk &outputChunk, - DWARFDataExtractor &namesExtractor) { - uint64_t offset = secData.locs.CUsBase; - uint64_t *offsetPtr = &offset; - outputChunk.compilationUnits.resize(secData.hdr.CompUnitCount); - uint32_t *bufferPtr = - namesExtractor.getU32(offsetPtr, outputChunk.compilationUnits.begin(), - secData.hdr.CompUnitCount); - if (!bufferPtr) - errorOrWarn(toString(outputChunk.sec) + - Twine(": error while reading CU offsets")); -} - -template -static void readEntryOffsets( - typename DebugNamesSection::DebugNamesSectionData &secData, - DWARFDataExtractor &namesExtractor) { - secData.entryOffsets.resize(secData.hdr.NameCount); - uint64_t offset = secData.locs.EntryOffsetsBase; - uint64_t *offsetPtr = &offset; - uint32_t *bufferPtr = namesExtractor.getU32( - offsetPtr, secData.entryOffsets.begin(), secData.hdr.NameCount); - if (!bufferPtr) - errorOrWarn(Twine(": error while reading entry offsets")); -} - -template -static void readAttributeValues( - SmallVector::AttrValueData, 3> &values, - typename DebugNamesSection::DebugNamesInputChunk &chunk, - uint64_t &offset, - typename DebugNamesSection::DebugNamesSectionData &secData, - int32_t &parentOffset, DWARFDataExtractor &namesExtractor, - const DWARFDebugNames::Abbrev &abbrev) { - const LLDDWARFSection &namesSection = *chunk.namesSection; - uint64_t *offsetPtr = &offset; - typename DebugNamesSection::AttrValueData cuOrTuAttr = {0, 0}; - for (DWARFDebugNames::AttributeEncoding attr : abbrev.Attributes) { - Error err = Error::success(); - typename DebugNamesSection::AttrValueData newAttr; - uint32_t value; - if (attr.Index == DW_IDX_parent && attr.Form != DW_FORM_flag_present && - attr.Form != DW_FORM_ref4) - errorOrWarn(toString(namesSection.sec) + - Twine(": invalid form for DW_IDX_parent")); - switch (attr.Form) { - case DW_FORM_flag_present: { - // Currently only DW_IDX_parent attributes (in .debug_names) can - // have this form. This form does not have a real value (nothing is - // emitted for it). - if (attr.Index != DW_IDX_parent) - errorOrWarn(toString(namesSection.sec) + - Twine(": invalid form for attribute")); - break; - } - case DW_FORM_data1: - case DW_FORM_ref1: { - newAttr.attrValue = namesExtractor.getU8(offsetPtr, &err); - newAttr.attrSize = 1; - break; - } - case DW_FORM_data2: - case DW_FORM_ref2: { - value = namesExtractor.getU16(offsetPtr, &err); - newAttr.attrValue = value; - newAttr.attrSize = 2; - break; - } - case DW_FORM_data4: - case DW_FORM_ref4: { - value = namesExtractor.getU32(offsetPtr, &err); - newAttr.attrValue = value; - newAttr.attrSize = 4; - if (attr.Index == dwarf::DW_IDX_parent) - parentOffset = value + secData.locs.EntriesBase; - break; - } - case DW_FORM_data8: - case DW_FORM_ref8: - case DW_FORM_ref_sig8: { - value = namesExtractor.getU64(offsetPtr, &err); - newAttr.attrValue = value; - newAttr.attrSize = 8; - break; +// 4-byte alignment ensures that values in the hash lookup table and the name +// table are aligned. +DebugNamesBaseSection::DebugNamesBaseSection() + : SyntheticSection(0, SHT_PROGBITS, 4, ".debug_names") {} + +// Get the size of the .debug_names section header in bytes for DWARF32: +static uint32_t getDebugNamesHeaderSize(uint32_t augmentationStringSize) { + return /* unit length */ 4 + + /* version */ 2 + + /* padding */ 2 + + /* CU count */ 4 + + /* TU count */ 4 + + /* Foreign TU count */ 4 + + /* Bucket Count */ 4 + + /* Name Count */ 4 + + /* Abbrev table size */ 4 + + /* Augmentation string size */ 4 + + /* Augmentation string */ augmentationStringSize; +} + +void DebugNamesBaseSection::parseDebugNames( + InputChunk &inputChunk, OutputChunk &chunk, + DWARFDataExtractor &namesExtractor, DataExtractor &strExtractor, + function_ref( + const DWARFDebugNames::Header &, + const DWARFDebugNames::DWARFDebugNamesOffsets &)> + readOffsets) { + const LLDDWARFSection namesSec = inputChunk.section; + DenseMap offsetMap; + for (const DWARFDebugNames::NameIndex &ni : *inputChunk.llvmDebugNames) { + NameData &nd = inputChunk.nameData.emplace_back(); + nd.hdr = ni.getHeader(); + if (nd.hdr.Format != DwarfFormat::DWARF32) { + errorOrWarn(toString(namesSec.sec) + Twine(": unsupported DWARF64")); + return; } - default: { - errorOrWarn(toString(namesSection.sec) + - Twine(": unrecognized form encoding ") + Twine(attr.Form) + - Twine(" in .debug_names abbrev table")); - break; + if (nd.hdr.Version != 5) { + errorOrWarn(toString(namesSec.sec) + Twine(": unsupported version ") + + Twine(nd.hdr.Version)); + return; } + const uint32_t dwarfSize = + dwarf::getDwarfOffsetByteSize(DwarfFormat::DWARF32); + const uint32_t hdrSize = + getDebugNamesHeaderSize(nd.hdr.AugmentationStringSize); + auto locs = findDebugNamesOffsets(hdrSize, nd.hdr); + if (locs.EntriesBase > namesExtractor.getData().size()) { + errorOrWarn(toString(namesSec.sec) + + Twine(": index entry is out of bounds")); + return; } - if (err) - errorOrWarn(toString(namesSection.sec) + - Twine(": error while reading attributes: ") + - toString(std::move(err))); - if (attr.Index == DW_IDX_compile_unit) - // Save it to put it at the end of the attributes list. - cuOrTuAttr = newAttr; - else if (attr.Form != DW_FORM_flag_present) - values.push_back(newAttr); - } - // Make sure the CU or TU index attribute is the last one in the list. - values.push_back(cuOrTuAttr); -} + SmallVector entryOffsets = readOffsets(nd.hdr, locs); + + // Read the entry pool. + offsetMap.clear(); + nd.nameEntries.resize(nd.hdr.NameCount); + for (auto i : seq(nd.hdr.NameCount)) { + NameEntry &ne = nd.nameEntries[i]; + uint64_t strOffset = locs.StringOffsetsBase + i * dwarfSize; + ne.stringOffset = strOffset; + uint64_t strp = namesExtractor.getRelocatedValue(dwarfSize, &strOffset); + StringRef name = strExtractor.getCStrRef(&strp); + ne.name = name.data(); + ne.hashValue = caseFoldingDjbHash(name); + + // Read a series of index entries that end with abbreviation code 0. + const char *errMsg = nullptr; + uint64_t offset = locs.EntriesBase + entryOffsets[i]; + while (offset < namesSec.Data.size() && namesSec.Data[offset] != 0) { + auto ie = makeThreadLocal(); + ie->poolOffset = offset; + Error err = Error::success(); + ie->abbrevCode = + static_cast(namesExtractor.getULEB128(&offset, &err)); + if (err) { + consumeError(std::move(err)); + errMsg = ": invalid abbrev code in entry"; + break; + } + auto it = ni.getAbbrevs().find_as(ie->abbrevCode); + if (it == ni.getAbbrevs().end()) { + errMsg = ": invalid abbrev code in entry"; + break; + } -template -static void -readEntry(typename DebugNamesSection::NamedEntry &stringEntry, - typename DebugNamesSection::DebugNamesInputChunk &chunk, - typename DebugNamesSection::DebugNamesSectionData &secData, - DWARFDataExtractor &namesExtractor, - const DWARFDebugNames::NameIndex &ni) { - std::unique_ptr &namesSection = chunk.namesSection; - uint64_t offset = stringEntry.entryOffset; - // Each entry ends with a zero 'sentinel' value - while (offset < namesSection->Data.size() && - namesSection->Data[offset] != 0) { - // Read & store all entries (for the same string) - auto entry = - std::make_unique::IndexEntry>(); - entry->poolOffset = offset; - Error err = Error::success(); - // This call to namesExtractor can't fail; if there were a problem with the - // input, it would have been caught in the call to NamesIndex::extract, in - // DebugNamesSection::create. - uint64_t ulebValue = namesExtractor.getULEB128(&offset, &err); - cantFail(std::move(err)); - entry->abbrevCode = static_cast(ulebValue); - const auto &abbrevs = ni.getAbbrevs(); - auto abbrevIt = abbrevs.find_as(entry->abbrevCode); - if (abbrevIt != abbrevs.end()) { - const DWARFDebugNames::Abbrev &abbrev = *abbrevIt; - readAttributeValues(entry->attrValues, chunk, offset, secData, - entry->parentOffset, namesExtractor, abbrev); - stringEntry.indexEntries.push_back(std::move(entry)); - } else - errorOrWarn(toString(chunk.namesSection->sec) + - Twine(": invalid abbrev code in entry")); - } - if (offset >= namesSection->Data.size()) - errorOrWarn( - toString(chunk.namesSection->sec) + - Twine(": encountered unexpected end of section while reading entry")); -} + AttrValue attr, cuAttr = {0, 0}; + for (DWARFDebugNames::AttributeEncoding a : it->Attributes) { + if (a.Index == dwarf::DW_IDX_parent) { + if (a.Form == dwarf::DW_FORM_ref4) { + attr.attrValue = namesExtractor.getU32(&offset, &err); + attr.attrSize = 4; + ie->parentOffset = locs.EntriesBase + attr.attrValue; + } else if (a.Form != DW_FORM_flag_present) { + errMsg = ": invalid form for DW_IDX_parent"; + } + } else { + switch (a.Form) { + case DW_FORM_data1: + case DW_FORM_ref1: { + attr.attrValue = namesExtractor.getU8(&offset, &err); + attr.attrSize = 1; + break; + } + case DW_FORM_data2: + case DW_FORM_ref2: { + attr.attrValue = namesExtractor.getU16(&offset, &err); + attr.attrSize = 2; + break; + } + case DW_FORM_data4: + case DW_FORM_ref4: { + attr.attrValue = namesExtractor.getU32(&offset, &err); + attr.attrSize = 4; + break; + } + default: + errorOrWarn(toString(namesSec.sec) + + Twine(": unrecognized form encoding ") + + Twine(a.Form) + Twine(" in abbrev table")); + return; + } + } + if (err) { + errorOrWarn(toString(namesSec.sec) + + Twine(": error while reading attributes: ") + + toString(std::move(err))); + return; + } + if (a.Index == DW_IDX_compile_unit) + cuAttr = attr; + else if (a.Form != DW_FORM_flag_present) + ie->attrValues.push_back(attr); + } -template -static void -readEntries(typename DebugNamesSection::DebugNamesSectionData &secData, - typename DebugNamesSection::DebugNamesInputChunk &chunk, - DWARFDataExtractor &namesExtractor, DataExtractor &strExtractor, - const DWARFDebugNames::NameIndex &ni) { - // Temporary map from entry offsets to address (pointer) of entry with that - // offset; used to find parent entries quickly. - DenseMap::IndexEntry *> offsetMap; - // Reserve sizes for this chunk's hashes & namedEntries. - chunk.hashValues.reserve(secData.hdr.NameCount); - secData.namedEntries.reserve(secData.hdr.NameCount); - // Calculate the Entry Offsets, create initial records. - for (uint32_t i = 0, e = secData.hdr.NameCount; i != e; ++i) { - // Get string value - typename DebugNamesSection::NamedEntry stringEntry; - stringEntry.entryOffset = - secData.locs.EntriesBase + secData.entryOffsets[i]; - uint64_t strOffsetOffset = - secData.locs.StringOffsetsBase + i * secData.dwarfSize; - stringEntry.stringOffsetOffset = strOffsetOffset; - uint64_t strOffset = - namesExtractor.getRelocatedValue(secData.dwarfSize, &strOffsetOffset); - StringRef name = strExtractor.getCStrRef(&strOffset); - stringEntry.name = name.data(); - // Calculate hash - stringEntry.hashValue = caseFoldingDjbHash(name); - chunk.hashValues.push_back(stringEntry.hashValue); - // Read String Entry - readEntry(stringEntry, chunk, secData, namesExtractor, ni); - // Add index entries & offsets to our temporary map - for (const auto &entry : stringEntry.indexEntries) - offsetMap[entry->poolOffset] = entry.get(); - secData.namedEntries.push_back(std::move(stringEntry)); - } - // Find/assign pointers to any 'real' parent entries (needed to find correct - // parent entry offsets in merged data). - for (auto &stringEntry : secData.namedEntries) - for (auto &entry : stringEntry.indexEntries) - if (entry->parentOffset != -1) - entry->parentEntry = offsetMap[entry->parentOffset]; -} - -static uint16_t computeDebugNamesHeaderSize() { - // Size of the .debug_names section header, in bytes, for DWARF32: - uint16_t size = /* unit length */ 4 + - /* version */ 2 + - /* padding */ 2 + - /* CU count */ 4 + - /* TU count */ 4 + - /* Foreign TU count */ 4 + - /* Bucket Count */ 4 + - /* Name Count */ 4 + - /* Abbrev table size */ 4 + - /* Augmentation string size */ 4 + - /* augmentation string */ 8; - return size; -} + // Canonicalize abbrev by placing the CU/TU index at the end. + ie->attrValues.push_back(cuAttr); + ne.indexEntries.push_back(std::move(ie)); + } + if (offset >= namesSec.Data.size()) + errMsg = ": index entry is out of bounds"; + if (errMsg) + errorOrWarn(toString(namesSec.sec) + Twine(errMsg)); -template -static void collectDebugNamesSectionData( - typename DebugNamesSection::DebugNamesInputChunk &chunk, - typename DebugNamesSection::DebugNamesOutputChunk &outputChunk, - DWARFDataExtractor &namesExtractor, DataExtractor &strExtractor) { - for (const DWARFDebugNames::NameIndex &ni : *chunk.debugNamesData) { - typename DebugNamesSection::DebugNamesSectionData &secData = - chunk.sectionsData.emplace_back(); - secData.hdr = ni.getHeader(); - if (secData.hdr.Format != DwarfFormat::DWARF32) { - errorOrWarn(toString(chunk.namesSection->sec) + - Twine(": unsupported DWARF64")); - // Don't try to continue; we can't parse DWARF64 at the moment. - return; + for (IndexEntry &ie : ne.entries()) + offsetMap[ie.poolOffset] = &ie; } - secData.dwarfSize = dwarf::getDwarfOffsetByteSize(DwarfFormat::DWARF32); - secData.hdrSize = computeDebugNamesHeaderSize(); - if (secData.hdr.Version != 5) - errorOrWarn(toString(chunk.namesSection->sec) + - Twine(": unsupported version")); - secData.locs = findDebugNamesOffsets(secData.hdrSize, secData.hdr); - readCompileUnitOffsets(secData, outputChunk, namesExtractor); - readEntryOffsets(secData, namesExtractor); - readEntries(secData, chunk, namesExtractor, strExtractor, ni); - } -} -template -void DebugNamesSection::collectMergedCounts( - MutableArrayRef &inputChunks) { - SmallVector tmpMergedCuOffsets; - mergedHdr.CompUnitCount = 0; - mergedHdr.LocalTypeUnitCount = 0; - mergedHdr.ForeignTypeUnitCount = 0; - mergedHdr.Version = 5; - mergedHdr.Format = DwarfFormat::DWARF32; - mergedHdr.AugmentationStringSize = 0; - - for (size_t i = 0, e = numChunks; i != e; ++i) { - DebugNamesInputChunk &inputChunk = inputChunks[i]; - DebugNamesOutputChunk &outputChunk = outputChunks[i]; - inputChunk.baseCuOffsetIdx = tmpMergedCuOffsets.size(); - for (uint32_t cuOffset : outputChunk.compilationUnits) - tmpMergedCuOffsets.push_back(outputChunk.sec->outSecOff + cuOffset); - for (const DebugNamesSectionData &data : inputChunk.sectionsData) { - mergedHdr.CompUnitCount += data.hdr.CompUnitCount; - mergedHdr.LocalTypeUnitCount += data.hdr.LocalTypeUnitCount; - mergedHdr.ForeignTypeUnitCount += data.hdr.ForeignTypeUnitCount; - // Set & check the Augmentation String. - if (mergedHdr.AugmentationStringSize == 0) { - mergedHdr.AugmentationStringSize = data.hdr.AugmentationStringSize; - mergedHdr.AugmentationString = data.hdr.AugmentationString; - } else if ((mergedHdr.AugmentationStringSize != - data.hdr.AugmentationStringSize) || - (mergedHdr.AugmentationString != - data.hdr.AugmentationString)) { - // There are conflicting augmentation strings, so it's best for the - // merged index to not use an augmentation string. - mergedHdr.AugmentationString = " "; - mergedHdr.AugmentationStringSize = mergedHdr.AugmentationString.size(); + // Assign parent pointers, which will be used to update DW_IDX_parent index + // attributes. Note: offsetMap[0] does not exist, so parentOffset == 0 will + // get parentEntry == null as well. + for (NameEntry &ne : nd.nameEntries) + for (IndexEntry &ie : ne.entries()) + ie.parentEntry = offsetMap.lookup(ie.parentOffset); + } +} + +// Compute the form for output DW_IDX_compile_unit attributes similar to +// DIEInteger::BestForm. The input forms (often DW_FORM_data1) may not hold all +// CU indices. +std::pair static getMergedCuCountForm( + uint32_t compUnitCount) { + if (compUnitCount > UINT16_MAX) + return {4, DW_FORM_data4}; + if (compUnitCount > UINT8_MAX) + return {2, DW_FORM_data2}; + return {1, DW_FORM_data1}; +} + +void DebugNamesBaseSection::computeHdrAndAbbrevTable( + MutableArrayRef inputChunks) { + TimeTraceScope timeScope("Merge .debug_names", "hdr and abbrev table"); + size_t numCu = 0; + hdr.Format = DwarfFormat::DWARF32; + hdr.Version = 5; + hdr.CompUnitCount = 0; + hdr.LocalTypeUnitCount = 0; + hdr.ForeignTypeUnitCount = 0; + hdr.AugmentationStringSize = 0; + + // Compute CU and TU counts. + for (auto i : seq(numChunks)) { + InputChunk &inputChunk = inputChunks[i]; + inputChunk.baseCuIdx = numCu; + numCu += chunks[i].compUnits.size(); + for (const NameData &nd : inputChunk.nameData) { + hdr.CompUnitCount += nd.hdr.CompUnitCount; + hdr.LocalTypeUnitCount += nd.hdr.LocalTypeUnitCount; + hdr.ForeignTypeUnitCount += nd.hdr.ForeignTypeUnitCount; + // If augmentation strings are not identical, use an empty string. + if (i == 0) { + hdr.AugmentationStringSize = nd.hdr.AugmentationStringSize; + hdr.AugmentationString = nd.hdr.AugmentationString; + } else if (hdr.AugmentationString != nd.hdr.AugmentationString) { + hdr.AugmentationStringSize = 0; + hdr.AugmentationString.clear(); } } } -} - -template -void DebugNamesSection::Abbrev::Profile(FoldingSetNodeID &id) const { - id.AddInteger(tag); - for (const DWARFDebugNames::AttributeEncoding &attr : attributes) { - id.AddInteger(attr.Index); - id.AddInteger(attr.Form); - } -} - -template -std::pair DebugNamesSection::getMergedCuSizeData() { - // Once we've merged all the CU offsets into a single list, the original - // DWARF form/size (often 1 byte) may be too small to hold indices to all - // the offsets. Here we calculate what the right form/size needs to be for - // the merged index. - uint8_t size; - dwarf::Form form; - // TODO: Investigate possibly using DIEInteger::BestForm here - if (mergedHdr.CompUnitCount > UINT32_MAX) { - form = DW_FORM_data8; - size = 8; - } else if (mergedHdr.CompUnitCount > UINT16_MAX) { - form = DW_FORM_data4; - size = 4; - } else if (mergedHdr.CompUnitCount > UINT8_MAX) { - form = DW_FORM_data2; - size = 2; - } else { - form = DW_FORM_data1; - size = 1; - } - - return {size, form}; -} -template -void DebugNamesSection::getMergedAbbrevTable( - MutableArrayRef &inputChunks) { - MapVector abbrevMap; - FoldingSet AbbreviationsSet; - - // Need to determine what size form is needed for the DW_IDX_compile_unit - // attributes in the merged index. Will need to update the abbrevs to use - // the right form. - dwarf::Form compileUnitAttrForm = getMergedCuSizeData().second; - - for (DebugNamesInputChunk &chunk : inputChunks) { - for (const DWARFDebugNames::NameIndex &ni : *chunk.debugNamesData) { - const auto &abbrevs = ni.getAbbrevs(); - for (const DWARFDebugNames::Abbrev &abbrev : abbrevs) { - // Create canonicalized abbrev. - Abbrev newAbbrev; - DWARFDebugNames::AttributeEncoding cuOrTuAttr(DW_IDX_compile_unit, - compileUnitAttrForm); - newAbbrev.code = abbrev.Code; - newAbbrev.tag = abbrev.Tag; - for (const DWARFDebugNames::AttributeEncoding attr : - abbrev.Attributes) { - DWARFDebugNames::AttributeEncoding newAttr(attr.Index, attr.Form); - if (attr.Index == DW_IDX_compile_unit) - // Save it, to put it at the end. - cuOrTuAttr.Index = newAttr.Index; + // Uniquify input abbrev tables and compute mapping from old abbrev code to + // new abbrev code. + FoldingSet abbrevSet; + // Determine the form for the DW_IDX_compile_unit attributes in the merged + // index. The input form may not encode all possible CU indices. + const dwarf::Form cuAttrForm = getMergedCuCountForm(hdr.CompUnitCount).second; + for (InputChunk &inputChunk : inputChunks) { + for (auto [i, ni] : enumerate(*inputChunk.llvmDebugNames)) { + for (const DWARFDebugNames::Abbrev &oldAbbrev : ni.getAbbrevs()) { + // Canonicalize abbrev by placing the CU/TU index at the end, + // similar to `DebugNamesBaseSection::parse`. + Abbrev abbrev; + DWARFDebugNames::AttributeEncoding cuAttr(DW_IDX_compile_unit, + cuAttrForm); + abbrev.code = oldAbbrev.Code; + abbrev.tag = oldAbbrev.Tag; + for (DWARFDebugNames::AttributeEncoding a : oldAbbrev.Attributes) { + if (a.Index == DW_IDX_compile_unit) + cuAttr.Index = a.Index; else - newAbbrev.attributes.push_back(newAttr); + abbrev.attributes.push_back({a.Index, a.Form}); } - // Put the CU/TU index at the end of the attributes list. - newAbbrev.attributes.push_back(cuOrTuAttr); + abbrev.attributes.push_back(cuAttr); - // Next, check our abbreviations set to see if we've already seen the - // identical abbreviation. - uint32_t oldCode = newAbbrev.code; - uint32_t newCode; + // Profile the abbrev, get or assign a new code, then record the abbrev + // code mapping. FoldingSetNodeID id; - newAbbrev.Profile(id); + abbrev.Profile(id); + uint32_t newCode; void *insertPos; - if (Abbrev *Existing = - AbbreviationsSet.FindNodeOrInsertPos(id, insertPos)) { - // Found it; we've already seen an identical abbreviation. - newCode = Existing->code; + if (Abbrev *existing = abbrevSet.FindNodeOrInsertPos(id, insertPos)) { + newCode = existing->code; } else { - // Didn't find it. - Abbrev *newAbbrev2 = - new (abbrevAlloc.Allocate()) Abbrev(std::move(newAbbrev)); - AbbreviationsSet.InsertNode(newAbbrev2, insertPos); - newCode = mergedAbbrevTable.size() + 1; - newAbbrev2->code = newCode; - mergedAbbrevTable.push_back(newAbbrev2); + Abbrev *abbrev2 = + new (abbrevAlloc.Allocate()) Abbrev(std::move(abbrev)); + abbrevSet.InsertNode(abbrev2, insertPos); + abbrevTable.push_back(abbrev2); + newCode = abbrevTable.size(); + abbrev2->code = newCode; } - chunk.abbrevCodeMap[oldCode] = newCode; + inputChunk.nameData[i].abbrevCodeMap[oldAbbrev.Code] = newCode; } } } - // Calculate the merged abbrev table size. - mergedHdr.AbbrevTableSize = 0; - for (Abbrev *a : mergedAbbrevTable) { - mergedHdr.AbbrevTableSize += getULEB128Size(a->code); - mergedHdr.AbbrevTableSize += getULEB128Size(a->tag); - for (const DWARFDebugNames::AttributeEncoding &attr : a->attributes) { - mergedHdr.AbbrevTableSize += getULEB128Size(attr.Index); - mergedHdr.AbbrevTableSize += getULEB128Size(attr.Form); + // Compute the merged abbrev table. + raw_svector_ostream os(abbrevTableBuf); + for (Abbrev *abbrev : abbrevTable) { + encodeULEB128(abbrev->code, os); + encodeULEB128(abbrev->tag, os); + for (DWARFDebugNames::AttributeEncoding a : abbrev->attributes) { + encodeULEB128(a.Index, os); + encodeULEB128(a.Form, os); } - mergedHdr.AbbrevTableSize += 2; // attribute index & form sentinels + os.write("\0", 2); // attribute specification end } - ++mergedHdr.AbbrevTableSize; // abbrev table sentinel + os.write(0); // abbrev table end + hdr.AbbrevTableSize = abbrevTableBuf.size(); } -template -void DebugNamesSection::getMergedSymbols( - MutableArrayRef &inputChunks) { - // The number of symbols (& abbrevs) we will handle is very large; will use - // multi-threading to speed it up. - constexpr size_t numShards = 32; +void DebugNamesBaseSection::Abbrev::Profile(FoldingSetNodeID &id) const { + id.AddInteger(tag); + for (const DWARFDebugNames::AttributeEncoding &attr : attributes) { + id.AddInteger(attr.Index); + id.AddInteger(attr.Form); + } +} + +std::pair DebugNamesBaseSection::computeEntryPool( + MutableArrayRef inputChunks) { + TimeTraceScope timeScope("Merge .debug_names", "entry pool"); + // Collect the compilation units for each unique name. Speed it up using + // multi-threading as the number of symbols can be in the order of millions. const size_t concurrency = bit_floor(std::min(config->threadCount, numShards)); const size_t shift = 32 - countr_zero(numShards); - - struct ShardData { - // Map to uniquify symbols by name - MapVector nameMap; - }; - - // Need to determine what size is needed for the DW_IDX_compile_unit - // attributes in the merged index. Will need to update the indexEntries - // to use the right size. - uint8_t compileUnitAttrSize = getMergedCuSizeData().first; - - auto shardsPtr = std::make_unique(numShards); - MutableArrayRef shards(shardsPtr.get(), numShards); - + const uint8_t cuAttrSize = getMergedCuCountForm(hdr.CompUnitCount).first; + DenseMap maps[numShards]; parallelFor(0, concurrency, [&](size_t threadId) { - for (size_t i = 0, e = numChunks; i != e; ++i) { - DebugNamesInputChunk &chunk = inputChunks[i]; - for (DebugNamesSectionData &secData : chunk.sectionsData) { - // Deduplicate the NamedEntry records (based on the string/name), - // using a map from string/name to NamedEntry records. - // Note there is a twist: If there is already a record for the current - // 'string' in the nameMap, we append all the indexEntries from the - // current record to the record that's in the nameMap. I.e. we - // deduplicate the *strings* but we keep all the IndexEntry records - // (moving them to the appropriate 'kept' NamedEntry record). - for (NamedEntry &stringEntry : secData.namedEntries) { - size_t shardId = stringEntry.hashValue >> shift; + for (auto i : seq(numChunks)) { + InputChunk &inputChunk = inputChunks[i]; + for (NameData &nd : inputChunk.nameData) { + for (NameEntry &ne : nd.nameEntries) { + auto shardId = ne.hashValue >> shift; if ((shardId & (concurrency - 1)) != threadId) continue; - auto &shard = shards[shardId]; - stringEntry.chunkIdx = i; - for (std::unique_ptr &entry : stringEntry.indexEntries) { - // The DW_IDX_compile_unit is always the last attribute (we set it - // up that way when we read/created the attributes). We need to - // update the index value to use the correct merged offset, and we - // need to fix the size of the index attribute. - uint8_t endPos = entry->attrValues.size() - 1; - entry->attrValues[endPos].attrValue += chunk.baseCuOffsetIdx; - entry->attrValues[endPos].attrSize = compileUnitAttrSize; - // Update the entry's abbrev code to match the merged - // abbreviations. - entry->abbrevCode = chunk.abbrevCodeMap[entry->abbrevCode]; + ne.chunkIdx = i; + for (IndexEntry &ie : ne.entries()) { + ie.abbrevCode = nd.abbrevCodeMap[ie.abbrevCode]; + // Update the DW_IDX_compile_unit attribute (the last one after + // canonicalization). + auto &back = ie.attrValues.back(); + back.attrValue += inputChunk.baseCuIdx; + back.attrSize = cuAttrSize; } - CachedHashStringRef cachedHashName(stringEntry.name); - auto [it, inserted] = - shard.nameMap.try_emplace(cachedHashName, std::move(stringEntry)); - if (!inserted) { - // Found the string already; don't add to map, but append - // entry/entries for it to existing map entry. - NamedEntry &found = it->second; - // Append the entries... - for (auto &entry : stringEntry.indexEntries) - found.indexEntries.push_back(std::move(entry)); - } + auto &nameVec = nameVecs[shardId]; + auto [it, inserted] = maps[shardId].try_emplace( + CachedHashStringRef(ne.name, ne.hashValue), nameVec.size()); + if (inserted) + nameVec.push_back(std::move(ne)); + else + nameVec[it->second].indexEntries.append(ne.indexEntries); } } } }); - // Combined the shared symbols into mergedEntries - for (ShardData &shard : shards) - for (auto &mapEntry : shard.nameMap) - mergedEntries.push_back(std::move(mapEntry.second)); - mergedHdr.NameCount = mergedEntries.size(); -} - -template -void DebugNamesSection::computeUniqueHashes( - MutableArrayRef &chunks) { - SmallVector uniques; - for (const auto &chunk : chunks) - uniques.append(chunk.hashValues); - llvm::sort(uniques); - mergedHdr.BucketCount = dwarf::getDebugNamesBucketCount(llvm::unique(uniques) - uniques.begin()); -} - -template void DebugNamesSection::generateBuckets() { - bucketList.resize(mergedHdr.BucketCount); - for (NamedEntry &entry : mergedEntries) { - uint32_t bucketIdx = entry.hashValue % mergedHdr.BucketCount; - bucketList[bucketIdx].push_back(&entry); - } - - // Sort the contents of the buckets by hash value so that the hash collisions - // end up together. - for (SmallVector &bucket : bucketList) - stable_sort(bucket, [](NamedEntry *lhs, NamedEntry *rhs) { - return lhs->hashValue < rhs->hashValue; - }); -} - -template -void DebugNamesSection::calculateEntriesSizeAndOffsets() { - uint32_t offset = 0; - for (NamedEntry &stringEntry : mergedEntries) { - stringEntry.entryOffset = offset; - for (std::unique_ptr &entry : stringEntry.indexEntries) { - uint32_t entrySize = 0; - entry->poolOffset = offset; - entrySize += getULEB128Size(entry->abbrevCode); - for (const auto &attr : entry->attrValues) - entrySize += attr.attrSize; - offset += entrySize; + // Compute entry offsets parallelly. First, compute offsets relative to the + // current shard. + uint32_t offsets[numShards]; + parallelFor(0, numShards, [&](size_t shard) { + uint32_t offset = 0; + for (NameEntry &ne : nameVecs[shard]) { + ne.entryOffset = offset; + for (IndexEntry &ie : ne.entries()) { + ie.poolOffset = offset; + offset += getULEB128Size(ie.abbrevCode); + for (AttrValue value : ie.attrValues) + offset += value.attrSize; + } + ++offset; // index entry sentinel } - // Add in sentinel size - ++offset; - } - mergedTotalEntriesSize = offset; -} - -template void DebugNamesSection::updateParentIndexEntries() { - for (NamedEntry &stringEntry : mergedEntries) { - for (std::unique_ptr &childEntry : stringEntry.indexEntries) { - if (!childEntry->parentEntry) - continue; + offsets[shard] = offset; + }); + // Then add shard offsets. + std::partial_sum(offsets, std::end(offsets), offsets); + parallelFor(1, numShards, [&](size_t shard) { + uint32_t offset = offsets[shard - 1]; + for (NameEntry &ne : nameVecs[shard]) { + ne.entryOffset += offset; + for (IndexEntry &ie : ne.entries()) + ie.poolOffset += offset; + } + }); - // Abbrevs are indexed starting at 1; vector starts at 0. (abbrevCode - // corresponds to position in the merged table vector). - const Abbrev *abbrev = mergedAbbrevTable[childEntry->abbrevCode - 1]; - - // Found the abbrev. Find the index for the DW_IDX_parent attribute - // (in the abbrev) and update that value in the entry with the - // correct parent offset (in the merged entry pool). - for (size_t idx = 0, size = abbrev->attributes.size(); idx != size; - ++idx) { - DWARFDebugNames::AttributeEncoding attr = abbrev->attributes[idx]; - if (attr.Index == DW_IDX_parent && attr.Form == DW_FORM_ref4) - childEntry->attrValues[idx].attrValue = - childEntry->parentEntry->poolOffset; + // Update DW_IDX_parent attributes that use DW_FORM_ref4. + parallelFor(0, numShards, [&](size_t shard) { + for (NameEntry &ne : nameVecs[shard]) { + for (IndexEntry &ie : ne.entries()) { + if (!ie.parentEntry) + continue; + const Abbrev *abbrev = abbrevTable[ie.abbrevCode - 1]; + for (auto i : seq(abbrev->attributes.size())) { + DWARFDebugNames::AttributeEncoding a = abbrev->attributes[i]; + if (a.Index == DW_IDX_parent && a.Form == DW_FORM_ref4) + ie.attrValues[i].attrValue = ie.parentEntry->poolOffset; + } } } - } -} + }); -template -uint64_t DebugNamesSection::calculateMergedSectionSize() { - uint32_t hdrSize = computeDebugNamesHeaderSize(); - mergedOffsets = findDebugNamesOffsets(hdrSize, mergedHdr); - // Add in the size for all the Entries, and make it 4-byte aligned. - mergedHdr.UnitLength = - alignTo(mergedOffsets.EntriesBase + mergedTotalEntriesSize, 4); - // Add in the first 4 bytes, whichs print out the length of the section. - return mergedHdr.UnitLength + 4; + // Return (entry pool size, number of entries). + uint32_t num = 0; + for (auto &map : maps) + num += map.size(); + return {offsets[numShards - 1], num}; } -template -DebugNamesSection *DebugNamesSection::create() { - TimeTraceScope timeScope("Create merged .debug_names"); +void DebugNamesBaseSection::init( + function_ref parseFile) { + TimeTraceScope timeScope("Merge .debug_names"); + // Collect and remove input .debug_names sections. Save InputSection pointers + // to relocate string offsets in `writeTo`. SetVector files; - SmallVector sections; for (InputSectionBase *s : ctx.inputSections) { InputSection *isec = dyn_cast(s); if (!isec) continue; - // Mark original sections as dead, but save links to them for calculating - // relocations later. - if (s->name == ".debug_names") { + if (!(s->flags & SHF_ALLOC) && s->name == ".debug_names") { s->markDead(); - sections.push_back(s); + inputSections.push_back(isec); files.insert(isec->file); } } - auto inputChunksPtr = std::make_unique(files.size()); - MutableArrayRef inputChunks(inputChunksPtr.get(), - files.size()); - auto outputChunks = std::make_unique(files.size()); - parallelFor(0, files.size(), [&](size_t i) { - auto *file = cast>(files[i]); - auto dwarfCtx = std::make_unique( - std::make_unique>(file)); - auto &dobj = - static_cast &>(dwarfCtx->getDWARFObj()); - - // Extract DWARFDebugNames data from the .debug_names section. The - // .debug_names section needs the .debug_str section, to get the actual - // symbol names. - const StringRef strSection = dobj.getStrSection(); - const LLDDWARFSection &namesSection = dobj.getNamesSection(); - DWARFDataExtractor namesExtractor(dobj, namesSection, config->isLE, - config->wordsize); - DataExtractor strExtractor(strSection, config->isLE, config->wordsize); - inputChunks[i].debugNamesData = - std::make_unique(namesExtractor, strExtractor); - inputChunks[i].namesSection = - std::make_unique(namesSection); - if (Error E = inputChunks[i].debugNamesData->extract()) { + + // Parse input .debug_names sections and extract InputChunk and OutputChunk + // data. OutputChunk contains CU information, which will be needed by + // `writeTo`. + auto inputChunksPtr = std::make_unique(files.size()); + MutableArrayRef inputChunks(inputChunksPtr.get(), files.size()); + numChunks = files.size(); + chunks = std::make_unique(files.size()); + { + TimeTraceScope timeScope("Merge .debug_names", "parse"); + parallelFor(0, files.size(), [&](size_t i) { + parseFile(files[i], inputChunks[i], chunks[i]); + }); + } + + // Compute section header (except unit_length), abbrev table, and entry pool. + computeHdrAndAbbrevTable(inputChunks); + uint32_t entryPoolSize; + std::tie(entryPoolSize, hdr.NameCount) = computeEntryPool(inputChunks); + hdr.BucketCount = dwarf::getDebugNamesBucketCount(hdr.NameCount); + + // Compute the section size. Subtract 4 to get the unit_length for DWARF32. + uint32_t hdrSize = getDebugNamesHeaderSize(hdr.AugmentationStringSize); + size = findDebugNamesOffsets(hdrSize, hdr).EntriesBase + entryPoolSize; + hdr.UnitLength = size - 4; +} + +template DebugNamesSection::DebugNamesSection() { + init([](InputFile *f, InputChunk &inputChunk, OutputChunk &chunk) { + auto *file = cast>(f); + DWARFContext dwarf(std::make_unique>(file)); + auto &dobj = static_cast &>(dwarf.getDWARFObj()); + chunk.infoSec = dobj.getInfoSection(); + DWARFDataExtractor namesExtractor(dobj, dobj.getNamesSection(), + ELFT::Endianness == endianness::little, + ELFT::Is64Bits ? 8 : 4); + // .debug_str is needed to get symbol names from string offsets. + DataExtractor strExtractor(dobj.getStrSection(), + ELFT::Endianness == endianness::little, + ELFT::Is64Bits ? 8 : 4); + inputChunk.section = dobj.getNamesSection(); + + inputChunk.llvmDebugNames.emplace(namesExtractor, strExtractor); + if (Error e = inputChunk.llvmDebugNames->extract()) { errorOrWarn(toString(dobj.getNamesSection().sec) + Twine(": ") + - toString(std::move(E))); + toString(std::move(e))); } - outputChunks[i].sec = dobj.getInfoSection(); - collectDebugNamesSectionData(inputChunks[i], outputChunks[i], - namesExtractor, strExtractor); + parseDebugNames( + inputChunk, chunk, namesExtractor, strExtractor, + [&chunk, namesData = dobj.getNamesSection().Data.data()]( + const DWARFDebugNames::Header &hdr, + const DWARFDebugNames::DWARFDebugNamesOffsets &locs) { + // Read CU offsets. + const char *p = namesData + locs.CUsBase; + chunk.compUnits.resize_for_overwrite(hdr.CompUnitCount); + for (auto i : seq(hdr.CompUnitCount)) + chunk.compUnits[i] = + endian::readNext(p); + + // Read entry offsets. + p = namesData + locs.EntryOffsetsBase; + SmallVector entryOffsets; + entryOffsets.resize_for_overwrite(hdr.NameCount); + for (auto i : seq(hdr.NameCount)) + entryOffsets[i] = + endian::readNext(p); + return entryOffsets; + }); }); +} - auto *ret = make(); - ret->inputDebugNamesSections = sections; - ret->outputChunks = std::move(outputChunks); - ret->numChunks = files.size(); - ret->collectMergedCounts(inputChunks); - ret->getMergedAbbrevTable(inputChunks); - ret->getMergedSymbols(inputChunks); - ret->computeUniqueHashes(inputChunks); - // inputChunks are not needed any more. Reset now to save memory. - inputChunksPtr.reset(); - ret->generateBuckets(); - ret->calculateEntriesSizeAndOffsets(); - ret->updateParentIndexEntries(); - ret->sectionSize = ret->calculateMergedSectionSize(); - return ret; +template +template +void DebugNamesSection::getNameRelocs( + InputSection *sec, ArrayRef rels, + DenseMap &relocs) { + for (const RelTy &rel : rels) { + Symbol &sym = sec->file->getRelocTargetSym(rel); + relocs[rel.r_offset] = sym.getVA(getAddend(rel)); + } +} + +template void DebugNamesSection::finalizeContents() { + // Get relocations of .debug_names sections. + auto relocs = std::make_unique[]>(numChunks); + parallelFor(0, numChunks, [&](size_t i) { + InputSection *sec = inputSections[i]; + auto rels = sec->template relsOrRelas(); + if (rels.areRelocsRel()) + getNameRelocs(sec, rels.rels, relocs.get()[i]); + else + getNameRelocs(sec, rels.relas, relocs.get()[i]); + }); + + // Relocate string offsets in the name table. + parallelForEach(nameVecs, [&](auto &nameVec) { + for (NameEntry &ne : nameVec) + ne.stringOffset = relocs.get()[ne.chunkIdx][ne.stringOffset]; + }); +} + +template void DebugNamesSection::writeTo(uint8_t *buf) { + [[maybe_unused]] uint8_t *oldBuf = buf; + // Write the header. + endian::write32(buf + 0, hdr.UnitLength); + endian::write16(buf + 4, hdr.Version); + endian::write32(buf + 8, hdr.CompUnitCount); + endian::write32(buf + 12, hdr.LocalTypeUnitCount); + endian::write32(buf + 16, hdr.ForeignTypeUnitCount); + endian::write32(buf + 20, hdr.BucketCount); + endian::write32(buf + 24, hdr.NameCount); + endian::write32(buf + 28, hdr.AbbrevTableSize); + endian::write32(buf + 32, hdr.AugmentationStringSize); + buf += 36; + memcpy(buf, hdr.AugmentationString.c_str(), hdr.AugmentationString.size()); + buf += hdr.AugmentationStringSize; + + // Write the CU list. + for (auto i : seq(numChunks)) { + OutputChunk &chunk = chunks[i]; + for (uint32_t cuOffset : chunk.compUnits) { + endian::write32(buf, + chunk.infoSec->outSecOff + cuOffset); + buf += 4; + } + } + + if (hdr.LocalTypeUnitCount || hdr.ForeignTypeUnitCount) + warn(".debug_names: type units are not implemented"); + + // Write the hash lookup table. + SmallVector, 0> buckets(hdr.BucketCount); + // Symbols enter into a bucket whose index is the hash modulo bucket_count. + for (auto &nameVec : nameVecs) + for (NameEntry &ne : nameVec) + buckets[ne.hashValue % hdr.BucketCount].push_back(&ne); + + // Write buckets (accumulated bucket counts). + uint32_t bucketIdx = 1; + for (const SmallVector &bucket : buckets) { + if (!bucket.empty()) + endian::write32(buf, bucketIdx); + buf += 4; + bucketIdx += bucket.size(); + } + // Write the hashes. + for (const SmallVector &bucket : buckets) { + for (const NameEntry *e : bucket) { + endian::write32(buf, e->hashValue); + buf += 4; + } + } + + // Write the name table. The name entries are ordered by bucket_idx and + // correspond one-to-one with the hash lookup table. + // + // First, write the relocated string offsets. + for (const SmallVector &bucket : buckets) { + for (const NameEntry *ne : bucket) { + endian::write32(buf, ne->stringOffset); + buf += 4; + } + } + // Then write the entry offsets. + for (const SmallVector &bucket : buckets) { + for (const NameEntry *ne : bucket) { + endian::write32(buf, ne->entryOffset); + buf += 4; + } + } + + // Write the abbrev table. + memcpy(buf, abbrevTableBuf.data(), abbrevTableBuf.size()); + buf += abbrevTableBuf.size(); + + // Write the entry pool. Unlike the name table, the name entries follow the + // nameVecs order computed by `computeEntryPool`. + for (auto &nameVec : nameVecs) { + for (NameEntry &ne : nameVec) { + for (const IndexEntry &ie : ne.entries()) { + buf += encodeULEB128(ie.abbrevCode, buf); + for (AttrValue value : ie.attrValues) { + switch (value.attrSize) { + case 1: + *buf = value.attrValue; + break; + case 2: + endian::write16(buf, value.attrValue); + break; + case 4: + endian::write32(buf, value.attrValue); + break; + default: + llvm_unreachable("invalid attrSize"); + } + buf += value.attrSize; + } + } + ++buf; // index entry sentinel + } + } + assert(uint64_t(buf - oldBuf) == size); } GdbIndexSection::GdbIndexSection() @@ -4616,6 +4446,7 @@ void InStruct::reset() { ppc32Got2.reset(); ibtPlt.reset(); relaPlt.reset(); + debugNames.reset(); gdbIndex.reset(); shStrTab.reset(); strTab.reset(); @@ -5025,8 +4856,10 @@ template void elf::createSyntheticSections() { if (config->andFeatures || !ctx.aarch64PauthAbiCoreInfo.empty()) add(*make()); - if (config->debugNames) - add(*DebugNamesSection::create()); + if (config->debugNames) { + in.debugNames = std::make_unique>(); + add(*in.debugNames); + } if (config->gdbIndex) { in.gdbIndex = GdbIndexSection::create(); add(*in.gdbIndex); diff --git a/lld/ELF/SyntheticSections.h b/lld/ELF/SyntheticSections.h index 297f2ca6e27d8..2d37cbdefb4ad 100644 --- a/lld/ELF/SyntheticSections.h +++ b/lld/ELF/SyntheticSections.h @@ -793,27 +793,11 @@ class RelroPaddingSection final : public SyntheticSection { void writeTo(uint8_t *buf) override {} }; -template class DebugNamesSection final : public SyntheticSection { - // N.B. Everything in this class assumes that we are using DWARF32. - // If we move to DWARF64, most of this data will need to be re-sized, - // and the code that handles or manipulates it will need to be updated - // accordingly. - +// Used by the merged DWARF32 .debug_names (a per-module index). If we +// move to DWARF64, most of this data will need to be re-sized. +class DebugNamesBaseSection : public SyntheticSection { public: - DebugNamesSection(); - static DebugNamesSection *create(); - void writeTo(uint8_t *buf) override; - size_t getSize() const override { return sectionSize; } - bool isNeeded() const override; - - template - void getNameRelocsImpl(InputSection *sec, ArrayRef rels, - llvm::DenseMap &relocs); - - void getNameRelocs(InputSectionBase *base, - llvm::DenseMap &relocs); - - struct Abbrev : public llvm::FoldingSetNode { + struct Abbrev : llvm::FoldingSetNode { uint32_t code; uint32_t tag; SmallVector attributes; @@ -821,7 +805,7 @@ template class DebugNamesSection final : public SyntheticSection { void Profile(llvm::FoldingSetNodeID &id) const; }; - struct AttrValueData { + struct AttrValue { uint32_t attrValue; uint8_t attrSize; }; @@ -830,86 +814,103 @@ template class DebugNamesSection final : public SyntheticSection { uint32_t abbrevCode; uint32_t poolOffset; union { - int32_t parentOffset = -1; + uint64_t parentOffset = 0; IndexEntry *parentEntry; }; - SmallVector attrValues; + SmallVector attrValues; }; - struct NamedEntry { + struct NameEntry { const char *name; uint32_t hashValue; - uint32_t stringOffsetOffset; + uint32_t stringOffset; uint32_t entryOffset; - uint32_t relocatedEntryOffset; - // The index of the chunk that 'name' points into, for looking up - // relocation data for this string. + // Used to relocate `stringOffset` in the merged section. uint32_t chunkIdx; - SmallVector, 0> indexEntries; - }; + SmallVector indexEntries; - struct SectionOffsetLocs { - uint64_t stringOffsetsBase; - uint64_t entryOffsetsBase; - uint64_t entriesBase; + llvm::iterator_range< + llvm::pointee_iterator::iterator>> + entries() { + return llvm::make_pointee_range(indexEntries); + } }; - struct DebugNamesSectionData { + // One name index described by an input .debug_names section. An InputChunk + // typically contains one single name index. + struct NameData { llvm::DWARFDebugNames::Header hdr; - llvm::DWARFDebugNames::DWARFDebugNamesOffsets locs; - SmallVector tuOffsets; - SmallVector abbrevTable; - SmallVector entryOffsets; - SmallVector namedEntries; - uint16_t dwarfSize; - uint16_t hdrSize; + llvm::DenseMap abbrevCodeMap; + SmallVector nameEntries; }; - // Per-file data used, while reading in the data, to generate the merged - // section information. - struct DebugNamesInputChunk { - uint32_t baseCuOffsetIdx; - std::unique_ptr debugNamesData; - std::unique_ptr namesSection; - SmallVector sectionsData; - SmallVector hashValues; - llvm::DenseMap abbrevCodeMap; + // InputChunk and OutputChunk hold per-file contribution to the merged index. + // InputChunk instances will be discarded after `create` completes. + struct InputChunk { + uint32_t baseCuIdx; + LLDDWARFSection section; + SmallVector nameData; + std::optional llvmDebugNames; }; - // Per-file data needed for correctly writing out the .debug_names section. - struct DebugNamesOutputChunk { - // Pointer to .debug_info section for this chunk/file, used for - // calculating correct relocated CU offsets in the merged index. - InputSection *sec; - SmallVector compilationUnits; - SmallVector typeUnits; + struct OutputChunk { + // Pointer to the .debug_info section that contains compile units, used to + // compute the relocated CU offsets. + InputSection *infoSec; + SmallVector compUnits; }; - void collectMergedCounts(MutableArrayRef &inputChunks); - std::pair getMergedCuSizeData(); - void getMergedAbbrevTable(MutableArrayRef &inputChunks); - void getMergedSymbols(MutableArrayRef &inputChunks); - void computeUniqueHashes(MutableArrayRef &inputChunks); - void generateBuckets(); - void calculateEntriesSizeAndOffsets(); - void updateParentIndexEntries(); - uint64_t calculateMergedSectionSize(); + DebugNamesBaseSection(); + size_t getSize() const override { return size; } + bool isNeeded() const override { return numChunks > 0; } +protected: + void init(llvm::function_ref); + static void + parseDebugNames(InputChunk &inputChunk, OutputChunk &chunk, + llvm::DWARFDataExtractor &namesExtractor, + llvm::DataExtractor &strExtractor, + llvm::function_ref( + const llvm::DWARFDebugNames::Header &hdr, + const llvm::DWARFDebugNames::DWARFDebugNamesOffsets &)> + readOffsets); + void computeHdrAndAbbrevTable(MutableArrayRef); + std::pair computeEntryPool(MutableArrayRef); + + // Input .debug_names sections for relocating string offsets in the name table + // in finalizeContents. + SmallVector inputSections; + + llvm::DWARFDebugNames::Header hdr; + size_t numChunks; + std::unique_ptr chunks; llvm::SpecificBumpPtrAllocator abbrevAlloc; + SmallVector abbrevTable; + SmallVector abbrevTableBuf; + + // Sharded name entries that will be used to compute bucket_count and the + // count name table. + static constexpr size_t numShards = 32; + SmallVector nameVecs[numShards]; +}; + +// Complement DebugNamesBaseSection for ELFT-aware code: reading offsets, +// relocating string offsets, and writeTo. +template +class DebugNamesSection final : public DebugNamesBaseSection { +public: + DebugNamesSection(); + void finalizeContents() override; + void writeTo(uint8_t *buf) override; + + template + void getNameRelocs(InputSection *sec, ArrayRef rels, + llvm::DenseMap &relocs); private: - size_t sectionSize; - uint32_t mergedTotalEntriesSize; - uint32_t numChunks; - llvm::DWARFDebugNames::DWARFDebugNamesOffsets mergedOffsets; - std::unique_ptr outputChunks; - // Pointers to the original .debug_names sections; used for find the correct' - // string relocation values when writing out the merged index. - SmallVector inputDebugNamesSections; - llvm::DWARFDebugNames::Header mergedHdr; - SmallVector mergedAbbrevTable; - SmallVector mergedEntries; - SmallVector, 0> bucketList; + static void readOffsets(InputChunk &inputChunk, OutputChunk &chunk, + llvm::DWARFDataExtractor &namesExtractor, + llvm::DataExtractor &strExtractor); }; class GdbIndexSection final : public SyntheticSection { @@ -1487,6 +1488,7 @@ struct InStruct { std::unique_ptr ibtPlt; std::unique_ptr relaPlt; // Non-SHF_ALLOC sections + std::unique_ptr debugNames; std::unique_ptr gdbIndex; std::unique_ptr shStrTab; std::unique_ptr strTab; diff --git a/lld/ELF/Writer.cpp b/lld/ELF/Writer.cpp index d2a9e872dab91..240c16a4d8f69 100644 --- a/lld/ELF/Writer.cpp +++ b/lld/ELF/Writer.cpp @@ -1957,6 +1957,7 @@ template void Writer::finalizeSections() { // finalizeAddressDependentContent may have added local symbols to the // static symbol table. finalizeSynthetic(in.symTab.get()); + finalizeSynthetic(in.debugNames.get()); finalizeSynthetic(in.ppc64LongBranchTarget.get()); finalizeSynthetic(in.armCmseSGSection.get()); } diff --git a/lld/docs/ReleaseNotes.rst b/lld/docs/ReleaseNotes.rst index bf0c8e55d103e..8efe877caf6aa 100644 --- a/lld/docs/ReleaseNotes.rst +++ b/lld/docs/ReleaseNotes.rst @@ -32,6 +32,8 @@ ELF Improvements * ``GNU_PROPERTY_AARCH64_FEATURE_PAUTH`` notes, ``R_AARCH64_AUTH_ABS64`` and ``R_AARCH64_AUTH_RELATIVE`` relocations are now supported. (`#72714 `_) +* ``--debug-names`` is added to create a merged ``.debug_names`` index + from input ``.debug_names`` sections. Breaking changes ---------------- diff --git a/lld/test/ELF/debug-names-bad-aug-string.s b/lld/test/ELF/debug-names-bad-aug-string.s index bf46f4ccef03d..1cf81cfef94df 100644 --- a/lld/test/ELF/debug-names-bad-aug-string.s +++ b/lld/test/ELF/debug-names-bad-aug-string.s @@ -1,37 +1,31 @@ -// This file was generated by copying debug-names.s and manually -// editing the 'Header: augmentation string' in the .debug_names section. +# This file was generated by copying debug-names.s and manually +# editing the 'Header: augmentation string' in the .debug_names section. -// REQUIRES: x86 -// RUN: rm -rf %t && split-file %s %t -// RUN: llvm-mc -filetype=obj -triple=x86_64 %t/debug-names-bad-aug-string.s \ -// RUN: -o %t/debug-names-bad-aug-string.o -// RUN: llvm-mc -filetype=obj -triple=x86_64 %t/debug-names-2.s \ -// RUN: -o %t/debug-names-2.o -// RUN: ld.lld --debug-names %t/debug-names-bad-aug-string.o \ -// RUN: %t/debug-names-2.o -o %t/debug-names-bad-aug-string +# REQUIRES: x86 +# RUN: rm -rf %t && split-file %s %t && cd %t +# RUN: llvm-mc -filetype=obj -triple=x86_64 bad-aug-string.s -o bad-aug-string.o +# RUN: llvm-mc -filetype=obj -triple=x86_64 b.s -o b.o +# RUN: ld.lld --debug-names bad-aug-string.o b.o -o out +# RUN: llvm-dwarfdump -debug-names out | FileCheck %s --check-prefix=DWARF -// RUN: llvm-dwarfdump -debug-names %t/debug-names-bad-aug-string \ -// RUN: | FileCheck -DFILE=%t/debug-names-bad-aug-string.o \ -// RUN: -DFILE=%t/debug-names-2.o %s --check-prefix=DWARF - -// DWARF: .debug_names contents: -// DWARF: Name Index @ 0x0 { -// DWARF-NEXT: Header { -// DWARF-NEXT: Length: 0xCC -// DWARF-NEXT: Format: DWARF32 -// DWARF-NEXT: Version: 5 -// DWARF-NEXT: CU count: 2 -// DWARF-NEXT: Local TU count: 0 -// DWARF-NEXT: Foreign TU count: 0 -// DWARF-NEXT: Bucket count: 5 -// DWARF-NEXT: Name count: 5 -// DWARF-NEXT: Abbreviations table size: 0x1F -// DWARF-NEXT: Augmentation: ' ' -// DWARF: Compilation Unit offsets [ -// DWARF-NEXT: CU[0]: 0x00000000 -// DWARF-NEXT: CU[1]: 0x0000000c +# DWARF: .debug_names contents: +# DWARF: Name Index @ 0x0 { +# DWARF-NEXT: Header { +# DWARF-NEXT: Length: 0xC0 +# DWARF-NEXT: Format: DWARF32 +# DWARF-NEXT: Version: 5 +# DWARF-NEXT: CU count: 2 +# DWARF-NEXT: Local TU count: 0 +# DWARF-NEXT: Foreign TU count: 0 +# DWARF-NEXT: Bucket count: 5 +# DWARF-NEXT: Name count: 5 +# DWARF-NEXT: Abbreviations table size: 0x1F +# DWARF-NEXT: Augmentation: '' +# DWARF: Compilation Unit offsets [ +# DWARF-NEXT: CU[0]: 0x00000000 +# DWARF-NEXT: CU[1]: 0x0000000c -#--- debug-names-bad-aug-string.s +#--- bad-aug-string.s .text .globl _Z2f12t1 # -- Begin function _Z2f12t1 .p2align 4, 0x90 @@ -159,19 +153,19 @@ _Z2f12t1: # @_Z2f12t1 .section .debug_line,"",@progbits .Lline_table_start0: -#--- debug-names-2.s -// input file: debug-names-2.cpp -// Generated with: -// - clang++ -g -O0 -gpubnames -fdebug-compilation-dir='debug-names-test' \ -// -S debug-names-2.cpp -o debug-names-2.s +#--- b.s +# input file: debug-names-2.cpp +# Generated with: +# - clang++ -g -O0 -gpubnames -fdebug-compilation-dir='debug-names-test' \ +# -S debug-names-2.cpp -o b.s -// debug-names-2.cpp contents: +# debug-names-2.cpp contents: -// struct t1 { }; -// int main() { -// t1 v1; -// } -// +# struct t1 { }; +# int main() { +# t1 v1; +# } +# .text .globl main # -- Begin function main .p2align 4, 0x90 diff --git a/lld/test/ELF/debug-names-bad-die-idx-sizes.s b/lld/test/ELF/debug-names-bad-die-idx-sizes.s index e73d013f3b0ed..25a14d2e7a191 100644 --- a/lld/test/ELF/debug-names-bad-die-idx-sizes.s +++ b/lld/test/ELF/debug-names-bad-die-idx-sizes.s @@ -1,19 +1,18 @@ -// This file was generated by first compiling main.cpp: -// clang++ -g -O0 -S -gpubnames -fdebug-compilation-dir='debug-names-test' \ -// main.cpp -// Then manually edit the .debug_names section. In the entries, change the -// size of the DW_IDX_die_offset from '.long' to '.byte'. +# This file was generated by first compiling main.cpp: +# clang++ -g -O0 -S -gpubnames -fdebug-compilation-dir='debug-names-test' \ +# main.cpp +# Then manually edit the .debug_names section. In the entries, change the +# size of the DW_IDX_die_offset from '.long' to '.byte'. -// Contents of main.cpp: -// int main (int argc, char **argv) { } +# Contents of main.cpp: +# int main (int argc, char **argv) { } -// REQUIRES: x86 -// RUN: llvm-mc -filetype=obj -triple=x86_64 %s -o %t1.o +# REQUIRES: x86 +# RUN: llvm-mc -filetype=obj -triple=x86_64 %s -o %t1.o +# RUN: not ld.lld --debug-names %t1.o -o /dev/null 2>&1 \ +# RUN: | FileCheck -DFILE=%t1.o --implicit-check-not=error: %s -// RUN: not ld.lld --debug-names %t1.o -o /dev/null 2>&1 \ -// RUN: | FileCheck -DFILE=%t1.o %s - -// CHECK: error: {{.*}}:(.debug_names): encountered unexpected end of section while reading entry +# CHECK: error: [[FILE]]:(.debug_names): index entry is out of bounds .text .globl main # -- Begin function main diff --git a/lld/test/ELF/debug-names-bad-name-count.s b/lld/test/ELF/debug-names-bad-name-count.s index cda4484b0e4c6..3410949b62fcd 100644 --- a/lld/test/ELF/debug-names-bad-name-count.s +++ b/lld/test/ELF/debug-names-bad-name-count.s @@ -1,23 +1,23 @@ -// REQUIRES: x86 -// RUN: llvm-mc -filetype=obj -triple=x86_64 %s -o %t1.o +# REQUIRES: x86 +# RUN: llvm-mc -filetype=obj -triple=x86_64 %s -o %t1.o -// RUN: not ld.lld --debug-names %t1.o -o /dev/null 2>&1 \ -// RUN: FileCheck -DFILE=%t1.o %s +# RUN: not ld.lld --debug-names %t1.o -o /dev/null 2>&1 \ +# RUN: FileCheck -DFILE=%t1.o --implicit-check-not=error: %s -// CHECK: error: {{.*}}:(.debug_names): encountered unexpected end of section while reading entry -// CHECK: error: {{.*}}:(.debug_names): encountered unexpected end of section while reading entry -// CHECK: error: {{.*}}:(.debug_names): encountered unexpected end of section while reading entry -// CHECK: error: {{.*}}:(.debug_names): encountered unexpected end of section while reading entry +# CHECK: error: [[FILE]]:(.debug_names): index entry is out of bounds +# CHECK: error: [[FILE]]:(.debug_names): index entry is out of bounds +# CHECK: error: [[FILE]]:(.debug_names): index entry is out of bounds +# CHECK: error: [[FILE]]:(.debug_names): index entry is out of bounds -// This file was generated by first compiling main.cpp: -// clang++ -g -O0 -S -gpubnames -fdebug-compilation-dir='debug-names-test' \ -// main.cpp +# This file was generated by first compiling main.cpp: +# clang++ -g -O0 -S -gpubnames -fdebug-compilation-dir='debug-names-test' \ +# main.cpp -// Then manually edit .debug_names section: change value for -// 'Header: name count' from 3 to 4. +# Then manually edit .debug_names section: change value for +# 'Header: name count' from 3 to 4. -// Contents of main.cpp: -// int main (int argc, char **argv) { } +# Contents of main.cpp: +# int main (int argc, char **argv) { } .text .globl main # -- Begin function main diff --git a/lld/test/ELF/debug-names-bad-offsets-sizes.s b/lld/test/ELF/debug-names-bad-offsets-sizes.s index 3e7f36b2e2175..e5b4570b21651 100644 --- a/lld/test/ELF/debug-names-bad-offsets-sizes.s +++ b/lld/test/ELF/debug-names-bad-offsets-sizes.s @@ -1,22 +1,22 @@ -// This file was generated by first compiling main.cpp: -// clang++ -g -O0 -S -gpubnames -fdebug-compilation-dir='debug-names-test' \ -// main.cpp +# This file was generated by first compiling main.cpp: +# clang++ -g -O0 -S -gpubnames -fdebug-compilation-dir='debug-names-test' \ +# main.cpp -// Then manually edit .debug_names section. Change the sizes of -// 'Offset in Bucket' values from '.long' to '.byte'. +# Then manually edit .debug_names section. Change the sizes of +# 'Offset in Bucket' values from '.long' to '.byte'. -// Contentsof main.cpp: -// int main (int argc, char **argv) { } +# Contentsof main.cpp: +# int main (int argc, char **argv) { } -// REQUIRES: x86 -// RUN: llvm-mc -filetype=obj -triple=x86_64 %s -o %t1.o +# REQUIRES: x86 +# RUN: llvm-mc -filetype=obj -triple=x86_64 %s -o %t1.o -// RUN: not ld.lld --debug-names %t1.o -o /dev/null 2>&1 \ -// RUN: | FileCheck -DFILE=%t1.o %s +# RUN: not ld.lld --debug-names %t1.o -o /dev/null 2>&1 \ +# RUN: | FileCheck -DFILE=%t1.o --implicit-check-not=error: %s -// CHECK: error: {{.*}}:(.debug_names): encountered unexpected end of section while reading entry -// CHECK: error: {{.*}}:(.debug_names): encountered unexpected end of section while reading entry -// CHECK: error: {{.*}}:(.debug_names): encountered unexpected end of section while reading entry +# CHECK: error: [[FILE]]:(.debug_names): index entry is out of bounds +# CHECK-NEXT: error: [[FILE]]:(.debug_names): index entry is out of bounds +# CHECK-NEXT: error: [[FILE]]:(.debug_names): index entry is out of bounds .text .globl main # -- Begin function main diff --git a/lld/test/ELF/debug-names-bad-version.s b/lld/test/ELF/debug-names-bad-version.s index eda1eaa03039b..ac7d6853bfa62 100644 --- a/lld/test/ELF/debug-names-bad-version.s +++ b/lld/test/ELF/debug-names-bad-version.s @@ -1,19 +1,16 @@ -// This file was generated by copying debug-names.s and manually -// editing the 'Header: version' in the .debug_names section (changed it from -// 5 to 4). +# This file was generated by copying debug-names.s and manually +# editing the 'Header: version' in the .debug_names section (changed it from +# 5 to 4). -// REQUIRES: x86 -// RUN: rm -rf %t && split-file %s %t -// RUN: llvm-mc -filetype=obj -triple=x86_64 %t/debug-names-bad-version.s \ -// RUN: -o %t/debug-names-bad-version.o -// RUN: llvm-mc -filetype=obj -triple=x86_64 %t/debug-names-2.s \ -// RUN: -o %t/debug-names-2.o -// RUN: not ld.lld --debug-names %t/debug-names-bad-version.o \ -// RUN: %t/debug-names-2.o -o /dev/null 2>&1 | FileCheck %s +# REQUIRES: x86 +# RUN: rm -rf %t && split-file %s %t && cd %t +# RUN: llvm-mc -filetype=obj -triple=x86_64 bad-version.s -o bad-version.o +# RUN: llvm-mc -filetype=obj -triple=x86_64 b.s -o b.o +# RUN: not ld.lld --debug-names bad-version.o b.o 2>&1 | FileCheck %s --implicit-check-not=error: -// CHECK: error: {{.*}}:(.debug_names): unsupported version +# CHECK: error: bad-version.o:(.debug_names): unsupported version 4 -#--- debug-names-bad-version.s +#--- bad-version.s .text .globl _Z2f12t1 # -- Begin function _Z2f12t1 .p2align 4, 0x90 @@ -176,19 +173,19 @@ _Z2f12t1: # @_Z2f12t1 .section .debug_line,"",@progbits .Lline_table_start0: -#--- debug-names-2.s -// input file: debug-names-2.cpp -// Generated with: -// - clang++ -g -O0 -gpubnames -fdebug-compilation-dir='debug-names-test' \ -// -S debug-names-2.cpp -o debug-names-2.s +#--- b.s +# input file: debug-names-2.cpp +# Generated with: +# - clang++ -g -O0 -gpubnames -fdebug-compilation-dir='debug-names-test' \ +# -S debug-names-2.cpp -o b.s -// debug-names-2.cpp contents: +# debug-names-2.cpp contents: -// struct t1 { }; -// int main() { -// t1 v1; -// } -// +# struct t1 { }; +# int main() { +# t1 v1; +# } +# .text .globl main # -- Begin function main .p2align 4, 0x90 diff --git a/lld/test/ELF/debug-names-dwarf64.s b/lld/test/ELF/debug-names-dwarf64.s index 790f2ddeba397..515ea67945e61 100644 --- a/lld/test/ELF/debug-names-dwarf64.s +++ b/lld/test/ELF/debug-names-dwarf64.s @@ -1,16 +1,16 @@ -// This file was generated by: -// clang++ -g -O0 -S -fdebug-compilation-dir='debug-names-test' \ -// -gdwarf64 -gpubnames main.cpp +# This file was generated by: +# clang++ -g -O0 -S -fdebug-compilation-dir='debug-names-test' \ +# -gdwarf64 -gpubnames main.cpp -// Contents of main.cpp -// int main (int argc, char **argv) { } +# Contents of main.cpp +# int main (int argc, char **argv) { } -// REQUIRES: x86 -// RUN: llvm-mc -filetype=obj -triple=x86_64 %s -o %t1.o -// RUN: not ld.lld --debug-names %t1.o -o /dev/null 2>&1 \ -// RUN: | FileCheck -DFILE=%t1.o %s +# REQUIRES: x86 +# RUN: llvm-mc -filetype=obj -triple=x86_64 %s -o %t1.o +# RUN: not ld.lld --debug-names %t1.o -o /dev/null 2>&1 \ +# RUN: | FileCheck -DFILE=%t1.o --implicit-check-not=error: %s -// CHECK: error: {{.*}}(.debug_names): unsupported DWARF64 +# CHECK: error: [[FILE]]:(.debug_names): unsupported DWARF64 .text .globl main # -- Begin function main diff --git a/lld/test/ELF/debug-names-invalid-abbrev-code.s b/lld/test/ELF/debug-names-invalid-abbrev-code.s index 54c0105ae56b5..65d7f50f02d37 100644 --- a/lld/test/ELF/debug-names-invalid-abbrev-code.s +++ b/lld/test/ELF/debug-names-invalid-abbrev-code.s @@ -1,19 +1,18 @@ -// This file was generated by: -// clang++ -g -O0 -S -fdebug-compilation-dir='debug-names-test' \ -// -gpubnames main.cpp +# This file was generated by: +# clang++ -g -O0 -S -fdebug-compilation-dir='debug-names-test' \ +# -gpubnames main.cpp -// Then manually changing an abbrev code. +# Then manually changing an abbrev code. -// Contents of main.cpp -// int main (int argc, char **argv) { } +# Contents of main.cpp +# int main (int argc, char **argv) { } -// REQUIRES: x86 -// RUN: llvm-mc -filetype=obj -triple=x86_64 %s -o %t1.o -// RUN: not ld.lld --debug-names %t1.o -o /dev/null 2>&1 \ -// RUN: | FileCheck -DFILE=%t1.o %s +# REQUIRES: x86 +# RUN: llvm-mc -filetype=obj -triple=x86_64 %s -o %t1.o +# RUN: not ld.lld --debug-names %t1.o -o /dev/null 2>&1 \ +# RUN: | FileCheck -DFILE=%t1.o --implicit-check-not=error: %s -// CHECK: error: {{.*}}(.debug_names): invalid abbrev code in entry -// CHECK: error: {{.*}}(.debug_names): invalid abbrev code in entry +# CHECK: error: [[FILE]]:(.debug_names): invalid abbrev code in entry .text .globl main # -- Begin function main diff --git a/lld/test/ELF/debug-names-invalid-attribute-2.s b/lld/test/ELF/debug-names-invalid-attribute-2.s index 16706f0054c31..fbed524ef29f8 100644 --- a/lld/test/ELF/debug-names-invalid-attribute-2.s +++ b/lld/test/ELF/debug-names-invalid-attribute-2.s @@ -1,19 +1,19 @@ -// This file was generated by: -// clang++ -g -O0 -S -fdebug-compilation-dir='debug-names-test' \ -// -gpubnames main.cpp +# This file was generated by: +# clang++ -g -O0 -S -fdebug-compilation-dir='debug-names-test' \ +# -gpubnames main.cpp -// Then manually editing .debug_names section, commenting out a -// DW_IDX_die_offset in an entry. +# Then manually editing .debug_names section, commenting out a +# DW_IDX_die_offset in an entry. -// Contents of main.cpp -// int main (int argc, char **argv) { } +# Contents of main.cpp +# int main (int argc, char **argv) { } -// REQUIRES: x86 -// RUN: llvm-mc -filetype=obj -triple=x86_64 %s -o %t1.o -// RUN: not ld.lld --debug-names %t1.o -o /dev/null 2>&1 \ -// RUN: | FileCheck -DFILE=%t1.o %s +# REQUIRES: x86 +# RUN: llvm-mc -filetype=obj -triple=x86_64 %s -o %t1.o +# RUN: not ld.lld --debug-names %t1.o -o /dev/null 2>&1 \ +# RUN: | FileCheck -DFILE=%t1.o --implicit-check-not=error: %s -// CHECK: error: {{.*}}(.debug_names): error while reading attributes: unexpected end of data at offset 0x80 while reading [0x7e, 0x82) +# CHECK: error: [[FILE]]:(.debug_names): error while reading attributes: unexpected end of data at offset 0x80 while reading [0x7e, 0x82) .text .globl main # -- Begin function main diff --git a/lld/test/ELF/debug-names-invalid-attribute-3.s b/lld/test/ELF/debug-names-invalid-attribute-3.s index 9b99cbe87d5a0..465f0a92064b4 100644 --- a/lld/test/ELF/debug-names-invalid-attribute-3.s +++ b/lld/test/ELF/debug-names-invalid-attribute-3.s @@ -1,21 +1,21 @@ -// This file was generated by: -// clang++ -g -O0 -S -fdebug-compilation-dir='debug-names-test' \ -// -gpubnames main.cpp +# This file was generated by: +# clang++ -g -O0 -S -fdebug-compilation-dir='debug-names-test' \ +# -gpubnames main.cpp -// Then manually changing the first .debug_names abbrev, so that the -// DW_IDX_die_offset uses DW_FORM_flag_present (invalid) & the DW_IDX_parent -// uses DW_FORM_ref4. Also updated the sizes of the values in the entry -// that uses the abbrev, to match the sizes of the forms. +# Then manually changing the first .debug_names abbrev, so that the +# DW_IDX_die_offset uses DW_FORM_flag_present (invalid) & the DW_IDX_parent +# uses DW_FORM_ref4. Also updated the sizes of the values in the entry +# that uses the abbrev, to match the sizes of the forms. -// Contents of main.cpp -// int main (int argc, char **argv) { } +# Contents of main.cpp +# int main (int argc, char **argv) { } -// REQUIRES: x86 -// RUN: llvm-mc -filetype=obj -triple=x86_64 %s -o %t1.o -// RUN: not ld.lld --debug-names %t1.o -o /dev/null 2>&1 \ -// RUN: | FileCheck -DFILE=%t1.o %s +# REQUIRES: x86 +# RUN: llvm-mc -filetype=obj -triple=x86_64 %s -o %t1.o +# RUN: not ld.lld --debug-names %t1.o -o /dev/null 2>&1 \ +# RUN: | FileCheck -DFILE=%t1.o --implicit-check-not=error: %s -// CHECK: error: {{.*}}(.debug_names): invalid form for attribute +# CHECK: error: [[FILE]]:(.debug_names): unrecognized form encoding 25 in abbrev table .text .globl main # -- Begin function main diff --git a/lld/test/ELF/debug-names-invalid-attribute.s b/lld/test/ELF/debug-names-invalid-attribute.s index 303337c0295da..19de19c313bcf 100644 --- a/lld/test/ELF/debug-names-invalid-attribute.s +++ b/lld/test/ELF/debug-names-invalid-attribute.s @@ -1,12 +1,12 @@ -// Generated by copying debug-names.s and manually editing it to make some -// of the abbrev attributes invalid. +# Generated by copying debug-names.s and manually editing it to make some +# of the abbrev attributes invalid. -// REQUIRES: x86 -// RUN: llvm-mc -filetype=obj -triple=x86_64 %s -o %t1.o -// RUN: not ld.lld --debug-names %t1.o -o /dev/null 2>&1 \ -// RUN: | FileCheck -DFILE=%t1.o %s +# REQUIRES: x86 +# RUN: llvm-mc -filetype=obj -triple=x86_64 %s -o %t1.o +# RUN: not ld.lld --debug-names %t1.o -o /dev/null 2>&1 \ +# RUN: | FileCheck -DFILE=%t1.o --implicit-check-not=error: %s -// CHECK: error: {{.*}}:(.debug_names): unrecognized form encoding 16 in .debug_names abbrev table +# CHECK: error: [[FILE]]:(.debug_names): unrecognized form encoding 16 in abbrev table .text .globl _Z2f12t1 # -- Begin function _Z2f12t1 diff --git a/lld/test/ELF/debug-names-invalid-parent-idx.s b/lld/test/ELF/debug-names-invalid-parent-idx.s index 698183880445a..01e62fb99586a 100644 --- a/lld/test/ELF/debug-names-invalid-parent-idx.s +++ b/lld/test/ELF/debug-names-invalid-parent-idx.s @@ -1,21 +1,20 @@ -// This file was generated by: -// clang++ -g -O0 -S -fdebug-compilation-dir='debug-names-test' \ -// -gpubnames main.cpp +# This file was generated by: +# clang++ -g -O0 -S -fdebug-compilation-dir='debug-names-test' \ +# -gpubnames main.cpp -// Then manually editing .debug_names section, changing the form for a -// DW_IDX_parent from DW_FORM_flag_present to DW_FORM_ref1 (invalid). +# Then manually editing .debug_names section, changing the form for a +# DW_IDX_parent from DW_FORM_flag_present to DW_FORM_ref1 (invalid). -// Contents of main.cpp -// int main (int argc, char **argv) { } +# Contents of main.cpp +# int main (int argc, char **argv) { } -// REQUIRES: x86 -// RUN: llvm-mc -filetype=obj -triple=x86_64 %s -o %t1.o -// RUN: not ld.lld --debug-names %t1.o -o /dev/null 2>&1 \ -// RUN: | FileCheck -DFILE=%t1.o %s +# REQUIRES: x86 +# RUN: llvm-mc -filetype=obj -triple=x86_64 %s -o %t1.o +# RUN: not ld.lld --debug-names %t1.o -o /dev/null 2>&1 \ +# RUN: | FileCheck -DFILE=%t1.o --implicit-check-not=error: %s -// CHECK: error: {{.*}}(.debug_names): invalid form for DW_IDX_parent -// CHECK: error: {{.*}}(.debug_names): invalid form for DW_IDX_parent -// CHECK: error: {{.*}}(.debug_names): invalid form for DW_IDX_parent +# CHECK: error: [[FILE]]:(.debug_names): invalid form for DW_IDX_parent +# CHECK: error: [[FILE]]:(.debug_names): invalid form for DW_IDX_parent .text .globl main # -- Begin function main diff --git a/lld/test/ELF/debug-names-parent-idx.s b/lld/test/ELF/debug-names-parent-idx.s index b44455bb498ef..22e382e45c9a1 100644 --- a/lld/test/ELF/debug-names-parent-idx.s +++ b/lld/test/ELF/debug-names-parent-idx.s @@ -1,192 +1,248 @@ -// debug-names-parent-idx.s generated with: +# debug-names-parent-idx.s generated with: -// - clang++ -g -O0 -gpubnames -fdebug-compilation-dir='parent-idx-test' \ -// -S debug-names-parent-idx.cpp -o debug-names-parent-idx.s +# - clang++ -g -O0 -gpubnames -fdebug-compilation-dir='parent-idx-test' \ +# -S debug-names-parent-idx.cpp -o debug-names-parent-idx.s -// foo.h contents: +# foo.h contents: -// int foo(); +# int foo(); -// struct foo { -// int x; -// char y; -// struct foo *foo_ptr; -// }; +# struct foo { +# int x; +# char y; +# struct foo *foo_ptr; +# }; -// namespace parent_test { -// int foo(); -// } +# namespace parent_test { +# int foo(); +# } -// debug-names-parent-idx.cpp contents: +# debug-names-parent-idx.cpp contents: -// #include "foo.h" -// void bar (struct foo &foo, int junk) { -// foo.x = foo.x * junk; -// } -// int main (int argc, char** argv) { -// struct foo my_struct; -// my_struct.x = 10; -// my_struct.y = 'q'; -// my_struct.foo_ptr = nullptr; -// int junk = foo(); -// bar(my_struct, junk); -// int junk2 = parent_test::foo(); -// return 0; -// } +# #include "foo.h" +# void bar (struct foo &foo, int junk) { +# foo.x = foo.x * junk; +# } +# int main (int argc, char** argv) { +# struct foo my_struct; +# my_struct.x = 10; +# my_struct.y = 'q'; +# my_struct.foo_ptr = nullptr; +# int junk = foo(); +# bar(my_struct, junk); +# int junk2 = parent_test::foo(); +# return 0; +# } -// REQUIRES: x86 -// RUN: rm -rf %t && split-file %s %t -// RUN: llvm-mc -filetype=obj -triple=x86_64 %t/debug-names-parent-idx.s \ -// RUN: -o %t/debug-names-parent-idx.o -// RUN: llvm-mc -filetype=obj -triple=x86_64 %t/debug-names-parent-idx-2.s \ -// RUN: -o %t/debug-names-parent-idx-2.o -// RUN: ld.lld --debug-names %t/debug-names-parent-idx.o \ -// RUN: %t/debug-names-parent-idx-2.o -o %t/debug-names-parent-idx +# REQUIRES: x86 +# RUN: rm -rf %t && split-file %s %t && cd %t +# RUN: llvm-mc -filetype=obj -triple=x86_64 debug-names-parent-idx.s \ +# RUN: -o debug-names-parent-idx.o +# RUN: llvm-mc -filetype=obj -triple=x86_64 debug-names-parent-idx-2.s \ +# RUN: -o debug-names-parent-idx-2.o +# RUN: ld.lld --debug-names debug-names-parent-idx.o \ +# RUN: debug-names-parent-idx-2.o -o debug-names-parent-idx -// RUN: llvm-dwarfdump -debug-names %t/debug-names-parent-idx \ -// RUN: | FileCheck -DFILE=%t/debug-names-parent-idx.o \ -// RUN: -DFILE=%t/debug-names-parent-idx-2.o %s --check-prefix=DWARF +# RUN: llvm-dwarfdump -debug-names debug-names-parent-idx | FileCheck %s --check-prefix=DWARF -// DWARF: .debug_names contents: -// DWARF: Name Index @ 0x0 { -// DWARF-NEXT: Header { -// DWARF-NEXT: Length: 0x15C -// DWARF-NEXT: Format: DWARF32 -// DWARF-NEXT: Version: 5 -// DWARF-NEXT: CU count: 2 -// DWARF-NEXT: Local TU count: 0 -// DWARF-NEXT: Foreign TU count: 0 -// DWARF-NEXT: Bucket count: 9 -// DWARF-NEXT: Name count: 9 -// DWARF-NEXT: Abbreviations table size: 0x33 -// DWARF-NEXT: Augmentation: 'LLVM0700' -// DWARF: Compilation Unit offsets [ -// DWARF-NEXT: CU[0]: 0x00000000 -// DWARF-NEXT: CU[1]: 0x0000000c -// DWARF: Abbreviations [ -// DWARF-NEXT: Abbreviation 0x1 { -// DWARF-NEXT: Tag: DW_TAG_base_type -// DWARF-NEXT: DW_IDX_die_offset: DW_FORM_ref4 -// DWARF-NEXT: DW_IDX_parent: DW_FORM_flag_present -// DWARF-NEXT: DW_IDX_compile_unit: DW_FORM_data1 -// DWARF: Abbreviation 0x2 { -// DWARF-NEXT: Tag: DW_TAG_subprogram -// DWARF-NEXT: DW_IDX_die_offset: DW_FORM_ref4 -// DWARF-NEXT: DW_IDX_parent: DW_FORM_flag_present -// DWARF-NEXT: DW_IDX_compile_unit: DW_FORM_data1 -// DWARF: Abbreviation 0x3 { -// DWARF-NEXT: Tag: DW_TAG_structure_type -// DWARF-NEXT: DW_IDX_die_offset: DW_FORM_ref4 -// DWARF-NEXT: DW_IDX_parent: DW_FORM_flag_present -// DWARF-NEXT: DW_IDX_compile_unit: DW_FORM_data1 -// DWARF: Abbreviation 0x4 { -// DWARF-NEXT: Tag: DW_TAG_subprogram -// DWARF-NEXT: DW_IDX_die_offset: DW_FORM_ref4 -// DWARF-NEXT: DW_IDX_parent: DW_FORM_ref4 -// DWARF-NEXT: DW_IDX_compile_unit: DW_FORM_data1 -// DWARF: Abbreviation 0x5 { -// DWARF-NEXT: Tag: DW_TAG_namespace -// DWARF-NEXT: DW_IDX_die_offset: DW_FORM_ref4 -// DWARF-NEXT: DW_IDX_parent: DW_FORM_flag_present -// DWARF-NEXT: DW_IDX_compile_unit: DW_FORM_data1 -// DWARF: String: 0x00000093 "bar" -// DWARF-NEXT: Entry @ 0xf7 { -// DWARF-NEXT: Abbrev: 0x2 -// DWARF-NEXT: Tag: DW_TAG_subprogram -// DWARF-NEXT: DW_IDX_die_offset: 0x00000023 -// DWARF-NEXT: DW_IDX_parent: -// DWARF-NEXT: DW_IDX_compile_unit: 0x00 -// DWARF: String: 0x000000a9 "int" -// DWARF-NEXT: Entry @ 0xfe { -// DWARF-NEXT: Abbrev: 0x1 -// DWARF-NEXT: Tag: DW_TAG_base_type -// DWARF-NEXT: DW_IDX_die_offset: 0x0000008d -// DWARF-NEXT: DW_IDX_parent: -// DWARF-NEXT: DW_IDX_compile_unit: 0x00 -// DWARF-NEXT: } -// DWARF-NEXT: Entry @ 0x104 { -// DWARF-NEXT: Abbrev: 0x1 -// DWARF-NEXT: Tag: DW_TAG_base_type -// DWARF-NEXT: DW_IDX_die_offset: 0x00000023 -// DWARF-NEXT: DW_IDX_parent: -// DWARF-NEXT: DW_IDX_compile_unit: 0x01 -// DWARF: String: 0x000000ad "foo" -// DWARF-NEXT: Entry @ 0x10b { -// DWARF-NEXT: Abbrev: 0x3 -// DWARF-NEXT: Tag: DW_TAG_structure_type -// DWARF-NEXT: DW_IDX_die_offset: 0x00000096 -// DWARF-NEXT: DW_IDX_parent: -// DWARF-NEXT: DW_IDX_compile_unit: 0x00 -// DWARF-NEXT: } -// DWARF-NEXT: Entry @ 0x111 { -// DWARF-NEXT: Abbrev: 0x2 -// DWARF-NEXT: Tag: DW_TAG_subprogram -// DWARF-NEXT: DW_IDX_die_offset: 0x00000027 -// DWARF-NEXT: DW_IDX_parent: -// DWARF-NEXT: DW_IDX_compile_unit: 0x01 -// DWARF-NEXT: } -// DWARF-NEXT: Entry @ 0x117 { -// DWARF-NEXT: Abbrev: 0x4 -// DWARF-NEXT: Tag: DW_TAG_subprogram -// DWARF-NEXT: DW_IDX_die_offset: 0x00000045 -// DWARF-NEXT: DW_IDX_parent: Entry @ 0x128 -// DWARF-NEXT: DW_IDX_compile_unit: 0x01 -// DWARF-NEXT: } -// DWARF-NEXT: Entry @ 0x121 { -// DWARF-NEXT: Abbrev: 0x3 -// DWARF-NEXT: Tag: DW_TAG_structure_type -// DWARF-NEXT: DW_IDX_die_offset: 0x00000056 -// DWARF-NEXT: DW_IDX_parent: -// DWARF-NEXT: DW_IDX_compile_unit: 0x01 -// DWARF: String: 0x00000196 "parent_test" -// DWARF-NEXT: Entry @ 0x128 { -// DWARF-NEXT: Abbrev: 0x5 -// DWARF-NEXT: Tag: DW_TAG_namespace -// DWARF-NEXT: DW_IDX_die_offset: 0x00000043 -// DWARF-NEXT: DW_IDX_parent: -// DWARF-NEXT: DW_IDX_compile_unit: 0x01 -// DWARF: String: 0x00000097 "_Z3barR3fooi" -// DWARF-NEXT: Entry @ 0x12f { -// DWARF-NEXT: Abbrev: 0x2 -// DWARF-NEXT: Tag: DW_TAG_subprogram -// DWARF-NEXT: DW_IDX_die_offset: 0x00000023 -// DWARF-NEXT: DW_IDX_parent: -// DWARF-NEXT: DW_IDX_compile_unit: 0x00 -// DWARF: String: 0x000000a4 "main" -// DWARF-NEXT: Entry @ 0x136 { -// DWARF-NEXT: Abbrev: 0x2 -// DWARF-NEXT: Tag: DW_TAG_subprogram -// DWARF-NEXT: DW_IDX_die_offset: 0x00000046 -// DWARF-NEXT: DW_IDX_parent: -// DWARF-NEXT: DW_IDX_compile_unit: 0x00 -// DWARF: String: 0x000000b5 "char" -// DWARF-NEXT: Entry @ 0x13d { -// DWARF-NEXT: Abbrev: 0x1 -// DWARF-NEXT: Tag: DW_TAG_base_type -// DWARF-NEXT: DW_IDX_die_offset: 0x000000b8 -// DWARF-NEXT: DW_IDX_parent: -// DWARF-NEXT: DW_IDX_compile_unit: 0x00 -// DWARF-NEXT: } -// DWARF-NEXT: Entry @ 0x143 { -// DWARF-NEXT: Abbrev: 0x1 -// DWARF-NEXT: Tag: DW_TAG_base_type -// DWARF-NEXT: DW_IDX_die_offset: 0x00000078 -// DWARF-NEXT: DW_IDX_parent: -// DWARF-NEXT: DW_IDX_compile_unit: 0x01 -// DWARF: String: 0x000001a2 "_ZN11parent_test3fooEv" -// DWARF-NEXT: Entry @ 0x14a { -// DWARF-NEXT: Abbrev: 0x4 -// DWARF-NEXT: Tag: DW_TAG_subprogram -// DWARF-NEXT: DW_IDX_die_offset: 0x00000045 -// DWARF-NEXT: DW_IDX_parent: Entry @ 0x128 -// DWARF-NEXT: DW_IDX_compile_unit: 0x01 -// DWARF: String: 0x0000018e "_Z3foov" -// DWARF-NEXT: Entry @ 0x155 { -// DWARF-NEXT: Abbrev: 0x2 -// DWARF-NEXT: Tag: DW_TAG_subprogram -// DWARF-NEXT: DW_IDX_die_offset: 0x00000027 -// DWARF-NEXT: DW_IDX_parent: -// DWARF-NEXT: DW_IDX_compile_unit: 0x01 +# DWARF: .debug_names contents: +# DWARF: Name Index @ 0x0 { +# DWARF-NEXT: Header { +# DWARF-NEXT: Length: 0x158 +# DWARF-NEXT: Format: DWARF32 +# DWARF-NEXT: Version: 5 +# DWARF-NEXT: CU count: 2 +# DWARF-NEXT: Local TU count: 0 +# DWARF-NEXT: Foreign TU count: 0 +# DWARF-NEXT: Bucket count: 9 +# DWARF-NEXT: Name count: 9 +# DWARF-NEXT: Abbreviations table size: 0x33 +# DWARF-NEXT: Augmentation: 'LLVM0700' +# DWARF: Compilation Unit offsets [ +# DWARF-NEXT: CU[0]: 0x00000000 +# DWARF-NEXT: CU[1]: 0x0000000c +# DWARF: Abbreviations [ +# DWARF-NEXT: Abbreviation 0x1 { +# DWARF-NEXT: Tag: DW_TAG_base_type +# DWARF-NEXT: DW_IDX_die_offset: DW_FORM_ref4 +# DWARF-NEXT: DW_IDX_parent: DW_FORM_flag_present +# DWARF-NEXT: DW_IDX_compile_unit: DW_FORM_data1 +# DWARF: Abbreviation 0x2 { +# DWARF-NEXT: Tag: DW_TAG_subprogram +# DWARF-NEXT: DW_IDX_die_offset: DW_FORM_ref4 +# DWARF-NEXT: DW_IDX_parent: DW_FORM_flag_present +# DWARF-NEXT: DW_IDX_compile_unit: DW_FORM_data1 +# DWARF: Abbreviation 0x3 { +# DWARF-NEXT: Tag: DW_TAG_structure_type +# DWARF-NEXT: DW_IDX_die_offset: DW_FORM_ref4 +# DWARF-NEXT: DW_IDX_parent: DW_FORM_flag_present +# DWARF-NEXT: DW_IDX_compile_unit: DW_FORM_data1 +# DWARF: Abbreviation 0x4 { +# DWARF-NEXT: Tag: DW_TAG_subprogram +# DWARF-NEXT: DW_IDX_die_offset: DW_FORM_ref4 +# DWARF-NEXT: DW_IDX_parent: DW_FORM_ref4 +# DWARF-NEXT: DW_IDX_compile_unit: DW_FORM_data1 +# DWARF: Abbreviation 0x5 { +# DWARF-NEXT: Tag: DW_TAG_namespace +# DWARF-NEXT: DW_IDX_die_offset: DW_FORM_ref4 +# DWARF-NEXT: DW_IDX_parent: DW_FORM_flag_present +# DWARF-NEXT: DW_IDX_compile_unit: DW_FORM_data1 +# DWARF: Bucket 0 [ +# DWARF-NEXT: EMPTY +# DWARF-NEXT: ] +# DWARF-NEXT: Bucket 1 [ +# DWARF-NEXT: Name 1 { +# DWARF-NEXT: Hash: 0xA974AA29 +# DWARF-NEXT: String: 0x000001a2 "_ZN11parent_test3fooEv" +# DWARF-NEXT: Entry @ 0x14a { +# DWARF-NEXT: Abbrev: 0x4 +# DWARF-NEXT: Tag: DW_TAG_subprogram +# DWARF-NEXT: DW_IDX_die_offset: 0x00000045 +# DWARF-NEXT: DW_IDX_parent: Entry @ 0x128 +# DWARF-NEXT: DW_IDX_compile_unit: 0x01 +# DWARF-NEXT: } +# DWARF-NEXT: } +# DWARF-NEXT: Name 2 { +# DWARF-NEXT: Hash: 0xB5063D0B +# DWARF-NEXT: String: 0x0000018e "_Z3foov" +# DWARF-NEXT: Entry @ 0x155 { +# DWARF-NEXT: Abbrev: 0x2 +# DWARF-NEXT: Tag: DW_TAG_subprogram +# DWARF-NEXT: DW_IDX_die_offset: 0x00000027 +# DWARF-NEXT: DW_IDX_parent: +# DWARF-NEXT: DW_IDX_compile_unit: 0x01 +# DWARF-NEXT: } +# DWARF-NEXT: } +# DWARF-NEXT: ] +# DWARF-NEXT: Bucket 2 [ +# DWARF-NEXT: Name 3 { +# DWARF-NEXT: Hash: 0xB888030 +# DWARF-NEXT: String: 0x000000a9 "int" +# DWARF-NEXT: Entry @ 0xfe { +# DWARF-NEXT: Abbrev: 0x1 +# DWARF-NEXT: Tag: DW_TAG_base_type +# DWARF-NEXT: DW_IDX_die_offset: 0x0000008d +# DWARF-NEXT: DW_IDX_parent: +# DWARF-NEXT: DW_IDX_compile_unit: 0x00 +# DWARF-NEXT: } +# DWARF-NEXT: Entry @ 0x104 { +# DWARF-NEXT: Abbrev: 0x1 +# DWARF-NEXT: Tag: DW_TAG_base_type +# DWARF-NEXT: DW_IDX_die_offset: 0x00000023 +# DWARF-NEXT: DW_IDX_parent: +# DWARF-NEXT: DW_IDX_compile_unit: 0x01 +# DWARF-NEXT: } +# DWARF-NEXT: } +# DWARF-NEXT: ] +# DWARF-NEXT: Bucket 3 [ +# DWARF-NEXT: Name 4 { +# DWARF-NEXT: Hash: 0xB8860BA +# DWARF-NEXT: String: 0x00000093 "bar" +# DWARF-NEXT: Entry @ 0xf7 { +# DWARF-NEXT: Abbrev: 0x2 +# DWARF-NEXT: Tag: DW_TAG_subprogram +# DWARF-NEXT: DW_IDX_die_offset: 0x00000023 +# DWARF-NEXT: DW_IDX_parent: +# DWARF-NEXT: DW_IDX_compile_unit: 0x00 +# DWARF-NEXT: } +# DWARF-NEXT: } +# DWARF-NEXT: Name 5 { +# DWARF-NEXT: Hash: 0xB887389 +# DWARF-NEXT: String: 0x000000ad "foo" +# DWARF-NEXT: Entry @ 0x10b { +# DWARF-NEXT: Abbrev: 0x3 +# DWARF-NEXT: Tag: DW_TAG_structure_type +# DWARF-NEXT: DW_IDX_die_offset: 0x00000096 +# DWARF-NEXT: DW_IDX_parent: +# DWARF-NEXT: DW_IDX_compile_unit: 0x00 +# DWARF-NEXT: } +# DWARF-NEXT: Entry @ 0x111 { +# DWARF-NEXT: Abbrev: 0x2 +# DWARF-NEXT: Tag: DW_TAG_subprogram +# DWARF-NEXT: DW_IDX_die_offset: 0x00000027 +# DWARF-NEXT: DW_IDX_parent: +# DWARF-NEXT: DW_IDX_compile_unit: 0x01 +# DWARF-NEXT: } +# DWARF-NEXT: Entry @ 0x117 { +# DWARF-NEXT: Abbrev: 0x4 +# DWARF-NEXT: Tag: DW_TAG_subprogram +# DWARF-NEXT: DW_IDX_die_offset: 0x00000045 +# DWARF-NEXT: DW_IDX_parent: Entry @ 0x128 +# DWARF-NEXT: DW_IDX_compile_unit: 0x01 +# DWARF-NEXT: } +# DWARF-NEXT: Entry @ 0x121 { +# DWARF-NEXT: Abbrev: 0x3 +# DWARF-NEXT: Tag: DW_TAG_structure_type +# DWARF-NEXT: DW_IDX_die_offset: 0x00000056 +# DWARF-NEXT: DW_IDX_parent: +# DWARF-NEXT: DW_IDX_compile_unit: 0x01 +# DWARF-NEXT: } +# DWARF-NEXT: } +# DWARF-NEXT: ] +# DWARF-NEXT: Bucket 4 [ +# DWARF-NEXT: EMPTY +# DWARF-NEXT: ] +# DWARF-NEXT: Bucket 5 [ +# DWARF-NEXT: EMPTY +# DWARF-NEXT: ] +# DWARF-NEXT: Bucket 6 [ +# DWARF-NEXT: EMPTY +# DWARF-NEXT: ] +# DWARF-NEXT: Bucket 7 [ +# DWARF-NEXT: Name 6 { +# DWARF-NEXT: Hash: 0x7C9A7F6A +# DWARF-NEXT: String: 0x000000a4 "main" +# DWARF-NEXT: Entry @ 0x136 { +# DWARF-NEXT: Abbrev: 0x2 +# DWARF-NEXT: Tag: DW_TAG_subprogram +# DWARF-NEXT: DW_IDX_die_offset: 0x00000046 +# DWARF-NEXT: DW_IDX_parent: +# DWARF-NEXT: DW_IDX_compile_unit: 0x00 +# DWARF-NEXT: } +# DWARF-NEXT: } +# DWARF-NEXT: ] +# DWARF-NEXT: Bucket 8 [ +# DWARF-NEXT: Name 7 { +# DWARF-NEXT: Hash: 0xA7255AE +# DWARF-NEXT: String: 0x00000196 "parent_test" +# DWARF-NEXT: Entry @ 0x128 { +# DWARF-NEXT: Abbrev: 0x5 +# DWARF-NEXT: Tag: DW_TAG_namespace +# DWARF-NEXT: DW_IDX_die_offset: 0x00000043 +# DWARF-NEXT: DW_IDX_parent: +# DWARF-NEXT: DW_IDX_compile_unit: 0x01 +# DWARF-NEXT: } +# DWARF-NEXT: } +# DWARF-NEXT: Name 8 { +# DWARF-NEXT: Hash: 0x51007E98 +# DWARF-NEXT: String: 0x00000097 "_Z3barR3fooi" +# DWARF-NEXT: Entry @ 0x12f { +# DWARF-NEXT: Abbrev: 0x2 +# DWARF-NEXT: Tag: DW_TAG_subprogram +# DWARF-NEXT: DW_IDX_die_offset: 0x00000023 +# DWARF-NEXT: DW_IDX_parent: +# DWARF-NEXT: DW_IDX_compile_unit: 0x00 +# DWARF-NEXT: } +# DWARF-NEXT: } +# DWARF-NEXT: Name 9 { +# DWARF-NEXT: Hash: 0x7C952063 +# DWARF-NEXT: String: 0x000000b5 "char" +# DWARF-NEXT: Entry @ 0x13d { +# DWARF-NEXT: Abbrev: 0x1 +# DWARF-NEXT: Tag: DW_TAG_base_type +# DWARF-NEXT: DW_IDX_die_offset: 0x000000b8 +# DWARF-NEXT: DW_IDX_parent: +# DWARF-NEXT: DW_IDX_compile_unit: 0x00 +# DWARF-NEXT: } +# DWARF-NEXT: Entry @ 0x143 { +# DWARF-NEXT: Abbrev: 0x1 +# DWARF-NEXT: Tag: DW_TAG_base_type +# DWARF-NEXT: DW_IDX_die_offset: 0x00000078 +# DWARF-NEXT: DW_IDX_parent: +# DWARF-NEXT: DW_IDX_compile_unit: 0x01 +# DWARF-NEXT: } +# DWARF-NEXT: } +# DWARF-NEXT: ] #--- debug-names-parent-idx.s .text @@ -425,41 +481,41 @@ main: # @main .Lline_table_start0: #--- debug-names-parent-idx-2.s -// Generated with: +# Generated with: -// - clang++ -g -O0 -gpubnames -fdebug-compilation-dir='parent-idx-test' \ -// -S debug-names-parent-idx-2.cpp -o debug-names-parent-idx-2.s +# - clang++ -g -O0 -gpubnames -fdebug-compilation-dir='parent-idx-test' \ +# -S debug-names-parent-idx-2.cpp -o debug-names-parent-idx-2.s -// foo.h contents: +# foo.h contents: -// int foo(); +# int foo(); -//struct foo { -// int x; -// char y; -// struct foo *foo_ptr; -// }; +#struct foo { +# int x; +# char y; +# struct foo *foo_ptr; +# }; -// namespace parent_test { -// int foo(); -// } +# namespace parent_test { +# int foo(); +# } -// debug-names-parent-index-2.cpp contents: +# debug-names-parent-index-2.cpp contents: -// #include "foo.h" -// int foo () { -// struct foo struct2; -// struct2.x = 1024; -// struct2.y = 'r'; -// struct2.foo_ptr = nullptr; -// return struct2.x * (int) struct2.y; -// } +# #include "foo.h" +# int foo () { +# struct foo struct2; +# struct2.x = 1024; +# struct2.y = 'r'; +# struct2.foo_ptr = nullptr; +# return struct2.x * (int) struct2.y; +# } -// namespace parent_test { -// int foo () { -// return 25; -// } -// } +# namespace parent_test { +# int foo () { +# return 25; +# } +# } .text .globl _Z3foov # -- Begin function _Z3foov diff --git a/lld/test/ELF/debug-names.s b/lld/test/ELF/debug-names.s index baadadd98ebf4..442653386977d 100644 --- a/lld/test/ELF/debug-names.s +++ b/lld/test/ELF/debug-names.s @@ -1,119 +1,140 @@ -// debug_names.s was gGenerated with: +# debug_names.s was gGenerated with: -// - clang++ -g -O0 -gpubnames -fdebug-compilation-dir='debug-names-test' \ -// -S debug-names.cpp -o debug-names.s +# - clang++ -g -O0 -gpubnames -fdebug-compilation-dir='debug-names-test' \ +# -S debug-names.cpp -o a.s -// debug-names.cpp contents: +# debug-names.cpp contents: -// struct t1 { }; -// void f1(t1) { } +# struct t1 { }; +# void f1(t1) { } -// REQUIRES: x86 -// RUN: rm -rf %t && split-file %s %t -// RUN: llvm-mc -filetype=obj -triple=x86_64 %t/debug-names.s \ -// RUN: -o %t/debug-names.o -// RUN: llvm-mc -filetype=obj -triple=x86_64 %t/debug-names-2.s \ -// RUN: -o %t/debug-names-2.o +# REQUIRES: x86 +# RUN: rm -rf %t && split-file %s %t && cd %t +# RUN: llvm-mc -filetype=obj -triple=x86_64 a.s -o a.o +# RUN: llvm-mc -filetype=obj -triple=x86_64 b.s -o b.o -// RUN: ld.lld --debug-names --no-debug-names %t/debug-names.o \ -// RUN: %t/debug-names-2.o -o %t/debug-names -// RUN: llvm-readelf -SW %t/debug-names \ -// RUN: | FileCheck %s --check-prefix=NO_DBG_NAMES +# RUN: ld.lld --debug-names --no-debug-names a.o b.o -o out0 +# RUN: llvm-readelf -SW out0 | FileCheck %s --check-prefix=NO_MERGE -// NO_DBG_NAMES: .debug_names PROGBITS 0000000000000000 [[#%x,]] 000110 +# NO_MERGE: Name Type Address Off Size ES Flg Lk Inf Al +# NO_MERGE: .debug_names PROGBITS 0000000000000000 [[#%x,]] 000110 00 0 0 4 -// RUN: ld.lld --debug-names %t/debug-names.o %t/debug-names-2.o \ -// RUN: -o %t/debug-names +# RUN: ld.lld --debug-names a.o b.o -o out -// RUN: llvm-dwarfdump -debug-names %t/debug-names \ -// RUN: | FileCheck %s --check-prefix=DWARF -// RUN: llvm-readelf -SW %t/debug-names \ -// RUN: | FileCheck -DFILE=%t/debug-names.o \ -// RUN: -DFILE=%t/debug-names-2.o %s --check-prefix=READELF +# RUN: llvm-dwarfdump -debug-names out | FileCheck %s --check-prefix=DWARF +# RUN: llvm-readelf -SW out | FileCheck %s --check-prefix=READELF -// READELF: .debug_names PROGBITS 0000000000000000 [[#%x,]] 0000d0 +# READELF: Name Type Address Off Size ES Flg Lk Inf Al +# READELF: .debug_names PROGBITS 0000000000000000 [[#%x,]] 0000cc 00 0 0 4 -// DWARF: .debug_names contents: -// DWARF: Name Index @ 0x0 { -// DWARF-NEXT: Header { -// DWARF-NEXT: Length: 0xCC -// DWARF-NEXT: Format: DWARF32 -// DWARF-NEXT: Version: 5 -// DWARF-NEXT: CU count: 2 -// DWARF-NEXT: Local TU count: 0 -// DWARF-NEXT: Foreign TU count: 0 -// DWARF-NEXT: Bucket count: 5 -// DWARF-NEXT: Name count: 5 -// DWARF-NEXT: Abbreviations table size: 0x1F -// DWARF-NEXT: Augmentation: 'LLVM0700' -// DWARF: Compilation Unit offsets [ -// DWARF-NEXT: CU[0]: 0x00000000 -// DWARF-NEXT: CU[1]: 0x0000000c -// DWARF: Abbreviations [ -// DWARF-NEXT: Abbreviation 0x1 { -// DWARF: Tag: DW_TAG_structure_type -// DWARF-NEXT: DW_IDX_die_offset: DW_FORM_ref4 -// DWARF-NEXT: DW_IDX_parent: DW_FORM_flag_present -// DWARF-NEXT: DW_IDX_compile_unit: DW_FORM_data1 -// DWARF: Abbreviation 0x2 { -// DWARF-NEXT: Tag: DW_TAG_subprogram -// DWARF-NEXT: DW_IDX_die_offset: DW_FORM_ref4 -// DWARF-NEXT: DW_IDX_parent: DW_FORM_flag_present -// DWARF-NEXT: DW_IDX_compile_unit: DW_FORM_data1 -// DWARF: Abbreviation 0x3 { -// DWARF-NEXT: Tag: DW_TAG_base_type -// DWARF-NEXT: DW_IDX_die_offset: DW_FORM_ref4 -// DWARF-NEXT: DW_IDX_parent: DW_FORM_flag_present -// DWARF-NEXT: DW_IDX_compile_unit: DW_FORM_data1 -// DWARF: Bucket 0 [ -// DWARF: Bucket 1 [ -// DWARF: String: 0x00000089 "f1" -// DWARF-NEXT: Entry @ 0xa3 { -// DWARF-NEXT: Abbrev: 0x2 -// DWARF-NEXT: Tag: DW_TAG_subprogram -// DWARF-NEXT: DW_IDX_die_offset: 0x00000023 -// DWARF-NEXT: DW_IDX_parent: -// DWARF-NEXT: DW_IDX_compile_unit: 0x00 -// DWARF: String: 0x00000095 "t1" -// DWARF-NEXT: Entry @ 0xaa { -// DWARF-NEXT: Abbrev: 0x1 -// DWARF-NEXT: Tag: DW_TAG_structure_type -// DWARF-NEXT: DW_IDX_die_offset: 0x0000003a -// DWARF-NEXT: DW_IDX_parent: -// DWARF-NEXT: DW_IDX_compile_unit: 0x00 -// DWARF-NEXT: } -// DWARF-NEXT: Entry @ 0xb0 { -// DWARF-NEXT: Abbrev: 0x1 -// DWARF-NEXT: Tag: DW_TAG_structure_type -// DWARF-NEXT: DW_IDX_die_offset: 0x00000042 -// DWARF-NEXT: DW_IDX_parent: -// DWARF-NEXT: DW_IDX_compile_unit: 0x01 -// DWARF: String: 0x00000130 "int" -// DWARF-NEXT: Entry @ 0xb7 { -// DWARF-NEXT: Abbrev: 0x3 -// DWARF-NEXT: Tag: DW_TAG_base_type -// DWARF-NEXT: DW_IDX_die_offset: 0x0000003e -// DWARF-NEXT: DW_IDX_parent: -// DWARF-NEXT: DW_IDX_compile_unit: 0x01 -// DWARF: Bucket 2 [ -// DWARF: Bucket 3 [ -// DWARF: String: 0x0000008c "_Z2f12t1" -// DWARF-NEXT: Entry @ 0xbe { -// DWARF-NEXT: Abbrev: 0x2 -// DWARF-NEXT: Tag: DW_TAG_subprogram -// DWARF-NEXT: DW_IDX_die_offset: 0x00000023 -// DWARF-NEXT: DW_IDX_parent: -// DWARF-NEXT: DW_IDX_compile_unit: 0x00 -// DWARF: Bucket 4 [ -// DWARF: String: 0x0000012b "main" -// DWARF-NEXT: Entry @ 0xc5 { -// DWARF-NEXT: Abbrev: 0x2 -// DWARF-NEXT: Tag: DW_TAG_subprogram -// DWARF-NEXT: DW_IDX_die_offset: 0x00000023 -// DWARF-NEXT: DW_IDX_parent: -// DWARF-NEXT: DW_IDX_compile_unit: 0x01 +# DWARF: .debug_names contents: +# DWARF: Name Index @ 0x0 { +# DWARF-NEXT: Header { +# DWARF-NEXT: Length: 0xC8 +# DWARF-NEXT: Format: DWARF32 +# DWARF-NEXT: Version: 5 +# DWARF-NEXT: CU count: 2 +# DWARF-NEXT: Local TU count: 0 +# DWARF-NEXT: Foreign TU count: 0 +# DWARF-NEXT: Bucket count: 5 +# DWARF-NEXT: Name count: 5 +# DWARF-NEXT: Abbreviations table size: 0x1F +# DWARF-NEXT: Augmentation: 'LLVM0700' +# DWARF: Compilation Unit offsets [ +# DWARF-NEXT: CU[0]: 0x00000000 +# DWARF-NEXT: CU[1]: 0x0000000c +# DWARF: Abbreviations [ +# DWARF-NEXT: Abbreviation 0x1 { +# DWARF: Tag: DW_TAG_structure_type +# DWARF-NEXT: DW_IDX_die_offset: DW_FORM_ref4 +# DWARF-NEXT: DW_IDX_parent: DW_FORM_flag_present +# DWARF-NEXT: DW_IDX_compile_unit: DW_FORM_data1 +# DWARF: Abbreviation 0x2 { +# DWARF-NEXT: Tag: DW_TAG_subprogram +# DWARF-NEXT: DW_IDX_die_offset: DW_FORM_ref4 +# DWARF-NEXT: DW_IDX_parent: DW_FORM_flag_present +# DWARF-NEXT: DW_IDX_compile_unit: DW_FORM_data1 +# DWARF: Abbreviation 0x3 { +# DWARF-NEXT: Tag: DW_TAG_base_type +# DWARF-NEXT: DW_IDX_die_offset: DW_FORM_ref4 +# DWARF-NEXT: DW_IDX_parent: DW_FORM_flag_present +# DWARF-NEXT: DW_IDX_compile_unit: DW_FORM_data1 +# DWARF: Bucket 0 [ +# DWARF-NEXT: EMPTY +# DWARF-NEXT: ] +# DWARF-NEXT: Bucket 1 [ +# DWARF-NEXT: Name 1 { +# DWARF-NEXT: Hash: 0x59796A +# DWARF-NEXT: String: 0x00000095 "t1" +# DWARF-NEXT: Entry @ 0xaa { +# DWARF-NEXT: Abbrev: 0x1 +# DWARF-NEXT: Tag: DW_TAG_structure_type +# DWARF-NEXT: DW_IDX_die_offset: 0x0000003a +# DWARF-NEXT: DW_IDX_parent: +# DWARF-NEXT: DW_IDX_compile_unit: 0x00 +# DWARF-NEXT: } +# DWARF-NEXT: Entry @ 0xb0 { +# DWARF-NEXT: Abbrev: 0x1 +# DWARF-NEXT: Tag: DW_TAG_structure_type +# DWARF-NEXT: DW_IDX_die_offset: 0x00000042 +# DWARF-NEXT: DW_IDX_parent: +# DWARF-NEXT: DW_IDX_compile_unit: 0x01 +# DWARF-NEXT: } +# DWARF-NEXT: } +# DWARF-NEXT: Name 2 { +# DWARF-NEXT: Hash: 0x5355B2BE +# DWARF-NEXT: String: 0x0000008c "_Z2f12t1" +# DWARF-NEXT: Entry @ 0xbe { +# DWARF-NEXT: Abbrev: 0x2 +# DWARF-NEXT: Tag: DW_TAG_subprogram +# DWARF-NEXT: DW_IDX_die_offset: 0x00000023 +# DWARF-NEXT: DW_IDX_parent: +# DWARF-NEXT: DW_IDX_compile_unit: 0x00 +# DWARF-NEXT: } +# DWARF-NEXT: } +# DWARF-NEXT: Name 3 { +# DWARF-NEXT: Hash: 0x7C9A7F6A +# DWARF-NEXT: String: 0x0000012b "main" +# DWARF-NEXT: Entry @ 0xc5 { +# DWARF-NEXT: Abbrev: 0x2 +# DWARF-NEXT: Tag: DW_TAG_subprogram +# DWARF-NEXT: DW_IDX_die_offset: 0x00000023 +# DWARF-NEXT: DW_IDX_parent: +# DWARF-NEXT: DW_IDX_compile_unit: 0x01 +# DWARF-NEXT: } +# DWARF-NEXT: } +# DWARF-NEXT: ] +# DWARF-NEXT: Bucket 2 [ +# DWARF-NEXT: EMPTY +# DWARF-NEXT: ] +# DWARF-NEXT: Bucket 3 [ +# DWARF-NEXT: Name 4 { +# DWARF-NEXT: Hash: 0xB888030 +# DWARF-NEXT: String: 0x00000130 "int" +# DWARF-NEXT: Entry @ 0xb7 { +# DWARF-NEXT: Abbrev: 0x3 +# DWARF-NEXT: Tag: DW_TAG_base_type +# DWARF-NEXT: DW_IDX_die_offset: 0x0000003e +# DWARF-NEXT: DW_IDX_parent: +# DWARF-NEXT: DW_IDX_compile_unit: 0x01 +# DWARF-NEXT: } +# DWARF-NEXT: } +# DWARF-NEXT: ] +# DWARF-NEXT: Bucket 4 [ +# DWARF-NEXT: Name 5 { +# DWARF-NEXT: Hash: 0x59779C +# DWARF-NEXT: String: 0x00000089 "f1" +# DWARF-NEXT: Entry @ 0xa3 { +# DWARF-NEXT: Abbrev: 0x2 +# DWARF-NEXT: Tag: DW_TAG_subprogram +# DWARF-NEXT: DW_IDX_die_offset: 0x00000023 +# DWARF-NEXT: DW_IDX_parent: +# DWARF-NEXT: DW_IDX_compile_unit: 0x00 +# DWARF-NEXT: } +# DWARF-NEXT: } +# DWARF-NEXT: ] -#--- debug-names.s +#--- a.s .text .globl _Z2f12t1 # -- Begin function _Z2f12t1 .p2align 4, 0x90 @@ -241,18 +262,18 @@ _Z2f12t1: # @_Z2f12t1 .section .debug_line,"",@progbits .Lline_table_start0: -#--- debug-names-2.s -// Generated with: -// - clang++ -g -O0 -gpubnames -fdebug-compilation-dir='debug-names-test' \ -// -S debug-names-2.cpp -o debug-names-2.s +#--- b.s +# Generated with: +# - clang++ -g -O0 -gpubnames -fdebug-compilation-dir='debug-names-test' \ +# -S debug-names-2.cpp -o b.s -// debug-names-2.cpp contents: +# debug-names-2.cpp contents: -// struct t1 { }; -// int main() { -// t1 v1; -// } -// +# struct t1 { }; +# int main() { +# t1 v1; +# } +# .text .globl main # -- Begin function main .p2align 4, 0x90 diff --git a/lld/test/ELF/driver.test b/lld/test/ELF/driver.test index 49deb902aa0fd..45d73607c8ac6 100644 --- a/lld/test/ELF/driver.test +++ b/lld/test/ELF/driver.test @@ -30,9 +30,10 @@ # ERR2: error: -r and -pie may not be used together # ERR2: error: -r and --export-dynamic may not be used together -# RUN: not ld.lld -r --icf=all --gdb-index %t -o /dev/null 2>&1 | FileCheck -check-prefix=ERR4 %s +# RUN: not ld.lld -r --icf=all --gdb-index --debug-names %t -o /dev/null 2>&1 | FileCheck -check-prefix=ERR4 %s # ERR4: error: -r and --gdb-index may not be used together # ERR4: error: -r and --icf may not be used together +# ERR4: error: -r and --debug-names may not be used together # RUN: not ld.lld -shared -pie %t -o /dev/null 2>&1 | FileCheck -check-prefix=ERR7 %s # ERR7: error: -shared and -pie may not be used together From 53b14cd9ce2b57da73d173fc876d2e9e199f5640 Mon Sep 17 00:00:00 2001 From: Caroline Tice Date: Wed, 10 Apr 2024 23:33:53 -0700 Subject: [PATCH 15/37] [lld][ELF] Implement merged .debug_names section. Migrate updates & fixes from maskray's lld-debug-names branch. --- lld/ELF/SyntheticSections.cpp | 47 +++++++++++++++++++++++++---------- lld/ELF/SyntheticSections.h | 16 ++++++------ 2 files changed, 43 insertions(+), 20 deletions(-) diff --git a/lld/ELF/SyntheticSections.cpp b/lld/ELF/SyntheticSections.cpp index be307f1b001f3..3a71f8dd01cc6 100644 --- a/lld/ELF/SyntheticSections.cpp +++ b/lld/ELF/SyntheticSections.cpp @@ -2784,6 +2784,7 @@ void DebugNamesBaseSection::parseDebugNames( const char *errMsg = nullptr; uint64_t offset = locs.EntriesBase + entryOffsets[i]; while (offset < namesSec.Data.size() && namesSec.Data[offset] != 0) { + // Read & store all entries (for the same string). auto ie = makeThreadLocal(); ie->poolOffset = offset; Error err = Error::success(); @@ -2871,9 +2872,9 @@ void DebugNamesBaseSection::parseDebugNames( } } -// Compute the form for output DW_IDX_compile_unit attributes similar to -// DIEInteger::BestForm. The input forms (often DW_FORM_data1) may not hold all -// CU indices. +// Compute the form for output DW_IDX_compile_unit attributes, similar to +// DIEInteger::BestForm. The input form (often DW_FORM_data1) may not hold all +// the merged CU indices. std::pair static getMergedCuCountForm( uint32_t compUnitCount) { if (compUnitCount > UINT16_MAX) @@ -2908,23 +2909,26 @@ void DebugNamesBaseSection::computeHdrAndAbbrevTable( hdr.AugmentationStringSize = nd.hdr.AugmentationStringSize; hdr.AugmentationString = nd.hdr.AugmentationString; } else if (hdr.AugmentationString != nd.hdr.AugmentationString) { + // There are conflicting augmentation strings, so it's best for the + // merged index to not use an augmentation string. hdr.AugmentationStringSize = 0; hdr.AugmentationString.clear(); } } } - // Uniquify input abbrev tables and compute mapping from old abbrev code to - // new abbrev code. + // Create the merged abbrev table, uniquifyinng the input abbrev tables and + // computing mapping from old (per-cu) abbrev codes to new (merged) abbrev + // codes. FoldingSet abbrevSet; // Determine the form for the DW_IDX_compile_unit attributes in the merged - // index. The input form may not encode all possible CU indices. + // index. The input form may not be big enough for all CU indices. const dwarf::Form cuAttrForm = getMergedCuCountForm(hdr.CompUnitCount).second; for (InputChunk &inputChunk : inputChunks) { for (auto [i, ni] : enumerate(*inputChunk.llvmDebugNames)) { for (const DWARFDebugNames::Abbrev &oldAbbrev : ni.getAbbrevs()) { // Canonicalize abbrev by placing the CU/TU index at the end, - // similar to `DebugNamesBaseSection::parse`. + // similar to 'parseDebugNames'. Abbrev abbrev; DWARFDebugNames::AttributeEncoding cuAttr(DW_IDX_compile_unit, cuAttrForm); @@ -2936,6 +2940,7 @@ void DebugNamesBaseSection::computeHdrAndAbbrevTable( else abbrev.attributes.push_back({a.Index, a.Form}); } + // Put the CU/TU index at the end of the attributes list. abbrev.attributes.push_back(cuAttr); // Profile the abbrev, get or assign a new code, then record the abbrev @@ -2945,6 +2950,7 @@ void DebugNamesBaseSection::computeHdrAndAbbrevTable( uint32_t newCode; void *insertPos; if (Abbrev *existing = abbrevSet.FindNodeOrInsertPos(id, insertPos)) { + // Found it; we've already seen an identical abbreviation. newCode = existing->code; } else { Abbrev *abbrev2 = @@ -2985,17 +2991,22 @@ void DebugNamesBaseSection::Abbrev::Profile(FoldingSetNodeID &id) const { std::pair DebugNamesBaseSection::computeEntryPool( MutableArrayRef inputChunks) { TimeTraceScope timeScope("Merge .debug_names", "entry pool"); - // Collect the compilation units for each unique name. Speed it up using - // multi-threading as the number of symbols can be in the order of millions. + // Collect and de-duplicate all the names (preserving all the entries). + // Speed it up using multithreading, as the number of symbols can be in the + // order of millions. const size_t concurrency = bit_floor(std::min(config->threadCount, numShards)); const size_t shift = 32 - countr_zero(numShards); const uint8_t cuAttrSize = getMergedCuCountForm(hdr.CompUnitCount).first; DenseMap maps[numShards]; + parallelFor(0, concurrency, [&](size_t threadId) { for (auto i : seq(numChunks)) { InputChunk &inputChunk = inputChunks[i]; for (NameData &nd : inputChunk.nameData) { + // Deduplicate the NameEntry records (based on the string/name), + // appending all IndexEntries from duplicate NameEntry records to + // the single preserved copy. for (NameEntry &ne : nd.nameEntries) { auto shardId = ne.hashValue >> shift; if ((shardId & (concurrency - 1)) != threadId) @@ -3003,9 +3014,11 @@ std::pair DebugNamesBaseSection::computeEntryPool( ne.chunkIdx = i; for (IndexEntry &ie : ne.entries()) { + // Update the IndexEntry's abbrev code to match the merged + // abbreviations. ie.abbrevCode = nd.abbrevCodeMap[ie.abbrevCode]; // Update the DW_IDX_compile_unit attribute (the last one after - // canonicalization). + // canonicalization) to have correct merged offset value and size. auto &back = ie.attrValues.back(); back.attrValue += inputChunk.baseCuIdx; back.attrSize = cuAttrSize; @@ -3017,13 +3030,13 @@ std::pair DebugNamesBaseSection::computeEntryPool( if (inserted) nameVec.push_back(std::move(ne)); else - nameVec[it->second].indexEntries.append(ne.indexEntries); + nameVec[it->second].indexEntries.append(std::move(ne.indexEntries)); } } } }); - // Compute entry offsets parallelly. First, compute offsets relative to the + // Compute entry offsets in parallel. First, comptute offsets relative to the // current shard. uint32_t offsets[numShards]; parallelFor(0, numShards, [&](size_t shard) { @@ -3051,12 +3064,15 @@ std::pair DebugNamesBaseSection::computeEntryPool( } }); - // Update DW_IDX_parent attributes that use DW_FORM_ref4. + // Update the DW_IDX_parent entries that refer to real parents (have + // DW_FORM_ref4). parallelFor(0, numShards, [&](size_t shard) { for (NameEntry &ne : nameVecs[shard]) { for (IndexEntry &ie : ne.entries()) { if (!ie.parentEntry) continue; + // Abbrevs are indexed starting at 1; vector starts at 0. (abbrevCode + // corresponds to position in the merged table vector). const Abbrev *abbrev = abbrevTable[ie.abbrevCode - 1]; for (auto i : seq(abbrev->attributes.size())) { DWARFDebugNames::AttributeEncoding a = abbrev->attributes[i]; @@ -3217,6 +3233,8 @@ template void DebugNamesSection::writeTo(uint8_t *buf) { } } + // Write the local TU list, then the foreign TU list.. + // TODO: Fix this, once we get everything working without TUs. if (hdr.LocalTypeUnitCount || hdr.ForeignTypeUnitCount) warn(".debug_names: type units are not implemented"); @@ -3253,6 +3271,7 @@ template void DebugNamesSection::writeTo(uint8_t *buf) { buf += 4; } } + // Then write the entry offsets. for (const SmallVector &bucket : buckets) { for (const NameEntry *ne : bucket) { @@ -3269,6 +3288,7 @@ template void DebugNamesSection::writeTo(uint8_t *buf) { // nameVecs order computed by `computeEntryPool`. for (auto &nameVec : nameVecs) { for (NameEntry &ne : nameVec) { + // Write all the entries for the string. for (const IndexEntry &ie : ne.entries()) { buf += encodeULEB128(ie.abbrevCode, buf); for (AttrValue value : ie.attrValues) { @@ -4860,6 +4880,7 @@ template void elf::createSyntheticSections() { in.debugNames = std::make_unique>(); add(*in.debugNames); } + if (config->gdbIndex) { in.gdbIndex = GdbIndexSection::create(); add(*in.gdbIndex); diff --git a/lld/ELF/SyntheticSections.h b/lld/ELF/SyntheticSections.h index 2d37cbdefb4ad..3b81360072149 100644 --- a/lld/ELF/SyntheticSections.h +++ b/lld/ELF/SyntheticSections.h @@ -836,16 +836,17 @@ class DebugNamesBaseSection : public SyntheticSection { } }; - // One name index described by an input .debug_names section. An InputChunk - // typically contains one single name index. + // The contents of one input .debug_names section. An InputChunk + // typically contains one NameData, but might contain more, especially + // in LTO builds. struct NameData { llvm::DWARFDebugNames::Header hdr; llvm::DenseMap abbrevCodeMap; SmallVector nameEntries; }; - // InputChunk and OutputChunk hold per-file contribution to the merged index. - // InputChunk instances will be discarded after `create` completes. + // InputChunk and OutputChunk hold per-file contributions to the merged index. + // InputChunk instances will be discarded after `init` completes. struct InputChunk { uint32_t baseCuIdx; LLDDWARFSection section; @@ -874,11 +875,12 @@ class DebugNamesBaseSection : public SyntheticSection { const llvm::DWARFDebugNames::Header &hdr, const llvm::DWARFDebugNames::DWARFDebugNamesOffsets &)> readOffsets); - void computeHdrAndAbbrevTable(MutableArrayRef); - std::pair computeEntryPool(MutableArrayRef); + void computeHdrAndAbbrevTable(MutableArrayRef inputChunks); + std::pair + computeEntryPool(MutableArrayRef inputChunks); // Input .debug_names sections for relocating string offsets in the name table - // in finalizeContents. + // in `finalizeContents`. SmallVector inputSections; llvm::DWARFDebugNames::Header hdr; From b5732b011503f464514f01c0df9e24b351598c09 Mon Sep 17 00:00:00 2001 From: Caroline Tice Date: Sun, 14 Apr 2024 10:07:17 -0700 Subject: [PATCH 16/37] [lld][ELF] Properly handle multiple (appended) indices within single .o Current implementation does not properly handle reading multiple (appended) .debug_names sections withih the same input .o file. This updates the code that reads from the .debug_nemes section to add in the proper offset when there are multiple appended .debug_names (could be generated by LTO, e.g.). --- lld/ELF/SyntheticSections.cpp | 33 +++++++++++++++++++++++---------- lld/ELF/SyntheticSections.h | 2 ++ 2 files changed, 25 insertions(+), 10 deletions(-) diff --git a/lld/ELF/SyntheticSections.cpp b/lld/ELF/SyntheticSections.cpp index 3a71f8dd01cc6..12acbcc9a842a 100644 --- a/lld/ELF/SyntheticSections.cpp +++ b/lld/ELF/SyntheticSections.cpp @@ -2738,11 +2738,18 @@ void DebugNamesBaseSection::parseDebugNames( InputChunk &inputChunk, OutputChunk &chunk, DWARFDataExtractor &namesExtractor, DataExtractor &strExtractor, function_ref( + uint32_t numCus, + uint32_t niOffset, const DWARFDebugNames::Header &, const DWARFDebugNames::DWARFDebugNamesOffsets &)> readOffsets) { const LLDDWARFSection namesSec = inputChunk.section; DenseMap offsetMap; + // Number of CUs seen in previous NameIndex sections within current chunk. + uint32_t numCus = 0; + // Offset of current NameIndex section from start of .debug_names section in + // current chunk. + uint32_t niOffset = 0; for (const DWARFDebugNames::NameIndex &ni : *inputChunk.llvmDebugNames) { NameData &nd = inputChunk.nameData.emplace_back(); nd.hdr = ni.getHeader(); @@ -2760,20 +2767,21 @@ void DebugNamesBaseSection::parseDebugNames( const uint32_t hdrSize = getDebugNamesHeaderSize(nd.hdr.AugmentationStringSize); auto locs = findDebugNamesOffsets(hdrSize, nd.hdr); - if (locs.EntriesBase > namesExtractor.getData().size()) { + if (locs.EntriesBase + niOffset > namesExtractor.getData().size()) { errorOrWarn(toString(namesSec.sec) + Twine(": index entry is out of bounds")); return; } - SmallVector entryOffsets = readOffsets(nd.hdr, locs); + SmallVector entryOffsets = readOffsets(numCus, niOffset, + nd.hdr, locs); // Read the entry pool. offsetMap.clear(); nd.nameEntries.resize(nd.hdr.NameCount); for (auto i : seq(nd.hdr.NameCount)) { NameEntry &ne = nd.nameEntries[i]; - uint64_t strOffset = locs.StringOffsetsBase + i * dwarfSize; + uint64_t strOffset = locs.StringOffsetsBase + niOffset + i * dwarfSize; ne.stringOffset = strOffset; uint64_t strp = namesExtractor.getRelocatedValue(dwarfSize, &strOffset); StringRef name = strExtractor.getCStrRef(&strp); @@ -2782,7 +2790,7 @@ void DebugNamesBaseSection::parseDebugNames( // Read a series of index entries that end with abbreviation code 0. const char *errMsg = nullptr; - uint64_t offset = locs.EntriesBase + entryOffsets[i]; + uint64_t offset = locs.EntriesBase + niOffset + entryOffsets[i]; while (offset < namesSec.Data.size() && namesSec.Data[offset] != 0) { // Read & store all entries (for the same string). auto ie = makeThreadLocal(); @@ -2869,6 +2877,8 @@ void DebugNamesBaseSection::parseDebugNames( for (NameEntry &ne : nd.nameEntries) for (IndexEntry &ie : ne.entries()) ie.parentEntry = offsetMap.lookup(ie.parentOffset); + numCus += nd.hdr.CompUnitCount; + niOffset += nd.hdr.UnitLength + 4; } } @@ -3003,7 +3013,8 @@ std::pair DebugNamesBaseSection::computeEntryPool( parallelFor(0, concurrency, [&](size_t threadId) { for (auto i : seq(numChunks)) { InputChunk &inputChunk = inputChunks[i]; - for (NameData &nd : inputChunk.nameData) { + for (auto j : seq(inputChunk.nameData.size())) { + NameData &nd = inputChunk.nameData[j]; // Deduplicate the NameEntry records (based on the string/name), // appending all IndexEntries from duplicate NameEntry records to // the single preserved copy. @@ -3020,7 +3031,7 @@ std::pair DebugNamesBaseSection::computeEntryPool( // Update the DW_IDX_compile_unit attribute (the last one after // canonicalization) to have correct merged offset value and size. auto &back = ie.attrValues.back(); - back.attrValue += inputChunk.baseCuIdx; + back.attrValue += inputChunk.baseCuIdx + j; back.attrSize = cuAttrSize; } @@ -3156,17 +3167,19 @@ template DebugNamesSection::DebugNamesSection() { parseDebugNames( inputChunk, chunk, namesExtractor, strExtractor, [&chunk, namesData = dobj.getNamesSection().Data.data()]( + uint32_t numCus, + uint32_t niOffset, const DWARFDebugNames::Header &hdr, const DWARFDebugNames::DWARFDebugNamesOffsets &locs) { // Read CU offsets. - const char *p = namesData + locs.CUsBase; - chunk.compUnits.resize_for_overwrite(hdr.CompUnitCount); + const char *p = namesData + niOffset + locs.CUsBase; + chunk.compUnits.resize_for_overwrite(numCus + hdr.CompUnitCount); for (auto i : seq(hdr.CompUnitCount)) - chunk.compUnits[i] = + chunk.compUnits[i + numCus] = endian::readNext(p); // Read entry offsets. - p = namesData + locs.EntryOffsetsBase; + p = namesData + niOffset + locs.EntryOffsetsBase; SmallVector entryOffsets; entryOffsets.resize_for_overwrite(hdr.NameCount); for (auto i : seq(hdr.NameCount)) diff --git a/lld/ELF/SyntheticSections.h b/lld/ELF/SyntheticSections.h index 3b81360072149..f15658e779bc2 100644 --- a/lld/ELF/SyntheticSections.h +++ b/lld/ELF/SyntheticSections.h @@ -872,6 +872,8 @@ class DebugNamesBaseSection : public SyntheticSection { llvm::DWARFDataExtractor &namesExtractor, llvm::DataExtractor &strExtractor, llvm::function_ref( + uint32_t numCUs, + uint32_t niOffset, const llvm::DWARFDebugNames::Header &hdr, const llvm::DWARFDebugNames::DWARFDebugNamesOffsets &)> readOffsets); From 5b4566d6a3ca317d923647778e7a150df821be21 Mon Sep 17 00:00:00 2001 From: Caroline Tice Date: Sun, 14 Apr 2024 13:16:06 -0700 Subject: [PATCH 17/37] [lld][ELF] Add & update tests: New tests: - ppc-debug-names.s : Tests .debug_names merging for big endiamn & 32-bit - debug-names-missing-parent.s: Tests .debug_names merging works when a DW_IDX_parent attribute is missing. Updated debug-names-bad-die-idx-sizes.s & debug-names-bad-name-count.s: - Added tests with --noinhibit_execc to generate warnings & not die Fixed names of source files in debug_names.s & the new/updated tests. --- lld/test/ELF/debug-names-bad-die-idx-sizes.s | 32 +- lld/test/ELF/debug-names-bad-name-count.s | 21 +- lld/test/ELF/debug-names-missing-parent.s | 223 ++++++++++ lld/test/ELF/debug-names.s | 50 +-- lld/test/ELF/ppc32-debug-names.s | 417 +++++++++++++++++++ 5 files changed, 698 insertions(+), 45 deletions(-) create mode 100644 lld/test/ELF/debug-names-missing-parent.s create mode 100644 lld/test/ELF/ppc32-debug-names.s diff --git a/lld/test/ELF/debug-names-bad-die-idx-sizes.s b/lld/test/ELF/debug-names-bad-die-idx-sizes.s index 25a14d2e7a191..850629b308660 100644 --- a/lld/test/ELF/debug-names-bad-die-idx-sizes.s +++ b/lld/test/ELF/debug-names-bad-die-idx-sizes.s @@ -1,10 +1,10 @@ -# This file was generated by first compiling main.cpp: -# clang++ -g -O0 -S -gpubnames -fdebug-compilation-dir='debug-names-test' \ -# main.cpp +# This file was generated by first compiling a.cpp: +# clang++ -g -O0 -S -gpubnames -fdebug-compilation-dir='/proc/self/cwd' a.cpp + # Then manually edit the .debug_names section. In the entries, change the # size of the DW_IDX_die_offset from '.long' to '.byte'. -# Contents of main.cpp: +# Contents of a.cpp: # int main (int argc, char **argv) { } # REQUIRES: x86 @@ -14,6 +14,12 @@ # CHECK: error: [[FILE]]:(.debug_names): index entry is out of bounds +# RUN: llvm-mc -filetype=obj -triple=x86_64 %s -o %t1.o +# RUN: ld.lld --debug-names --noinhibit-exec %t1.o -o /dev/null 2>&1 \ +# RUN: | FileCheck -DFILE=%t1.o %s --check-prefix=WARN + +# WARN: warning: [[FILE]]:(.debug_names): index entry is out of bounds + .text .globl main # -- Begin function main .p2align 4, 0x90 @@ -59,21 +65,21 @@ main: # @main .Lstr_offsets_base0: .section .debug_str,"MS",@progbits,1 .Linfo_string0: - .asciz "clang version 19.0.0git (git@github.com:llvm/llvm-project.git d33d5630b281debe6eabd67e323bcf767340fb6a)" # string offset=0 + .asciz "clang version 19.0.0git (git@github.com:llvm/llvm-project.git 53b14cd9ce2b57da73d173fc876d2e9e199f5640)" # string offset=0 .Linfo_string1: - .asciz "main.cpp" # string offset=104 + .asciz "a.cpp" # string offset=104 .Linfo_string2: - .asciz "debug-names-test" # string offset=113 + .asciz "/proc/self/cwd" # string offset=110 .Linfo_string3: - .asciz "main" # string offset=130 + .asciz "main" # string offset=125 .Linfo_string4: - .asciz "int" # string offset=135 + .asciz "int" # string offset=130 .Linfo_string5: - .asciz "argc" # string offset=139 + .asciz "argc" # string offset=134 .Linfo_string6: - .asciz "argv" # string offset=144 + .asciz "argv" # string offset=139 .Linfo_string7: - .asciz "char" # string offset=149 + .asciz "char" # string offset=144 .Laddr_table_base0: .quad .Lfunc_begin0 .Ldebug_addr_end0: @@ -143,7 +149,7 @@ main: # @main # End of list: char .p2align 2, 0x0 .Lnames_end0: - .ident "clang version 19.0.0git (git@github.com:llvm/llvm-project.git d33d5630b281debe6eabd67e323bcf767340fb6a)" + .ident "clang version 19.0.0git (git@github.com:llvm/llvm-project.git 53b14cd9ce2b57da73d173fc876d2e9e199f5640)" .section ".note.GNU-stack","",@progbits .addrsig .section .debug_line,"",@progbits diff --git a/lld/test/ELF/debug-names-bad-name-count.s b/lld/test/ELF/debug-names-bad-name-count.s index 3410949b62fcd..f660bc0512cc6 100644 --- a/lld/test/ELF/debug-names-bad-name-count.s +++ b/lld/test/ELF/debug-names-bad-name-count.s @@ -1,22 +1,29 @@ # REQUIRES: x86 # RUN: llvm-mc -filetype=obj -triple=x86_64 %s -o %t1.o - + # RUN: not ld.lld --debug-names %t1.o -o /dev/null 2>&1 \ -# RUN: FileCheck -DFILE=%t1.o --implicit-check-not=error: %s - +# RUN: | FileCheck -DFILE=%t1.o --implicit-check-not=error: %s + # CHECK: error: [[FILE]]:(.debug_names): index entry is out of bounds # CHECK: error: [[FILE]]:(.debug_names): index entry is out of bounds # CHECK: error: [[FILE]]:(.debug_names): index entry is out of bounds # CHECK: error: [[FILE]]:(.debug_names): index entry is out of bounds -# This file was generated by first compiling main.cpp: -# clang++ -g -O0 -S -gpubnames -fdebug-compilation-dir='debug-names-test' \ -# main.cpp +# RUN: ld.lld --noinhibit-exec --debug-names %t1.o -o /dev/null 2>&1 \ +# RUN: | FileCheck -DFILE=%t1.o %s --check-prefix=WARN + +# WARN: warning: [[FILE]]:(.debug_names): index entry is out of bounds +# WARN: warning: [[FILE]]:(.debug_names): index entry is out of bounds +# WARN: warning: [[FILE]]:(.debug_names): index entry is out of bounds +# WARN: warning: [[FILE]]:(.debug_names): index entry is out of bounds + +# This file was generated by first compiling a.cpp: +# clang++ -g -O0 -S -gpubnames -fdebug-compilation-dir='/proc/self/cwd' a.cpp # Then manually edit .debug_names section: change value for # 'Header: name count' from 3 to 4. -# Contents of main.cpp: +# Contents of a.cpp: # int main (int argc, char **argv) { } .text diff --git a/lld/test/ELF/debug-names-missing-parent.s b/lld/test/ELF/debug-names-missing-parent.s new file mode 100644 index 0000000000000..5c7e0ad839a00 --- /dev/null +++ b/lld/test/ELF/debug-names-missing-parent.s @@ -0,0 +1,223 @@ +# debug-names-missing-parent was generated with + +# clang++ -g -O0 -S -fdebug-compilation-dir='debug-names-test' \ +# -gpubnames a.cpp + +# a.cpp contents: + +# int main (int argc, char **argv) { } + +# Then manually edit the .s file: +# - Remove DW_IDX_parent & DW_FORM_flag_present from DW_TAG_subprogram abbrev +# - Remove DW_IDX_parent value from entry for 'main' + +# REQUIRES: x86 +# RUN: llvm-mc -filetype=obj -triple=x86_64 %s -o %t1.o +# RUN: ld.lld --debug-names %t1.o -o %t +# RUN: llvm-dwarfdump --debug-names %t | FileCheck %s --check-prefix=DWARF + +# DWARF: .debug_names contents: +# DWARF: Name Index @ 0x0 { +# DWARF-NEXT: Header { +# DWARF-NEXT: Length: 0x8A +# DWARF-NEXT: Format: DWARF32 +# DWARF-NEXT: Version: 5 +# DWARF-NEXT: CU count: 1 +# DWARF-NEXT: Local TU count: 0 +# DWARF-NEXT: Foreign TU count: 0 +# DWARF-NEXT: Bucket count: 3 +# DWARF-NEXT: Name count: 3 +# DWARF-NEXT: Abbreviations table size: 0x13 +# DWARF-NEXT: Augmentation: 'LLVM0700' +# DWARF: Compilation Unit offsets [ +# DWARF-NEXT: CU[0]: 0x00000000 +# DWARF: Abbreviations [ +# DWARF-NEXT: Abbreviation 0x1 { +# DWARF: Tag: DW_TAG_base_type +# DWARF-NEXT: DW_IDX_die_offset: DW_FORM_ref4 +# DWARF-NEXT: DW_IDX_parent: DW_FORM_flag_present +# DWARF-NEXT: DW_IDX_compile_unit: DW_FORM_data1 +# DWARF: Abbreviation 0x2 { +# DWARF-NEXT: Tag: DW_TAG_subprogram +# DWARF-NEXT: DW_IDX_die_offset: DW_FORM_ref4 +# DWARF-NEXT: DW_IDX_compile_unit: DW_FORM_data1 +# DWARF: Bucket 0 [ +# DWARF-NEXT: EMPTY +# DWARF-NEXT: ] +# DWARF-NEXT: Bucket 1 [ +# DWARF-NEXT: Name 1 { +# DWARF-NEXT: Hash: 0x7C9A7F6A +# DWARF-NEXT: String: 0x0000007f "main" +# DWARF-NEXT: Entry @ 0x7a { +# DWARF-NEXT: Abbrev: 0x2 +# DWARF-NEXT: Tag: DW_TAG_subprogram +# DWARF-NEXT: DW_IDX_die_offset: 0x00000023 +# DWARF-NEXT: DW_IDX_compile_unit: 0x00 +# DWARF-NEXT: } +# DWARF-NEXT: Entry @ 0x80 { +# DWARF-NEXT: Abbrev: 0x1 +# DWARF-NEXT: Tag: DW_TAG_base_type +# DWARF-NEXT: DW_IDX_die_offset: 0x00000049 +# DWARF-NEXT: DW_IDX_parent: +# DWARF-NEXT: DW_IDX_compile_unit: 0x00 +# DWARF-NEXT: } +# DWARF-NEXT: } +# DWARF-NEXT: ] +# DWARF-NEXT: Bucket 2 [ +# DWARF-NEXT: Name 2 { +# DWARF-NEXT: Hash: 0xB888030 +# DWARF-NEXT: String: 0x00000084 "int" +# DWARF-NEXT: Entry @ 0x73 { +# DWARF-NEXT: Abbrev: 0x1 +# DWARF-NEXT: Tag: DW_TAG_base_type +# DWARF-NEXT: DW_IDX_die_offset: 0x00000049 +# DWARF-NEXT: DW_IDX_parent: +# DWARF-NEXT: DW_IDX_compile_unit: 0x00 +# DWARF-NEXT: } +# DWARF-NEXT: } +# DWARF-NEXT: Name 3 { +# DWARF-NEXT: Hash: 0x7C952063 +# DWARF-NEXT: String: 0x00000092 "char" +# DWARF-NEXT: Entry @ 0x87 { +# DWARF-NEXT: Abbrev: 0x1 +# DWARF-NEXT: Tag: DW_TAG_base_type +# DWARF-NEXT: DW_IDX_die_offset: 0x00000057 +# DWARF-NEXT: DW_IDX_parent: +# DWARF-NEXT: DW_IDX_compile_unit: 0x00 +# DWARF-NEXT: } +# DWARF-NEXT: } +# DWARF-NEXT: ] + +# --- a.s + + .text + .globl main # -- Begin function main + .p2align 4, 0x90 + .type main,@function +main: # @main +.Lfunc_begin0: + .cfi_startproc +# %bb.0: # %entry + pushq %rbp + .cfi_def_cfa_offset 16 + .cfi_offset %rbp, -16 + movq %rsp, %rbp + .cfi_def_cfa_register %rbp + movl %edi, -4(%rbp) + movq %rsi, -16(%rbp) +.Ltmp0: + xorl %eax, %eax + popq %rbp + .cfi_def_cfa %rsp, 8 + retq +.Ltmp1: +.Lfunc_end0: + .size main, .Lfunc_end0-main + .cfi_endproc + # -- End function + .section .debug_abbrev,"",@progbits + .byte 0 # EOM(1) + .byte 0 # EOM(2) + .byte 0 # EOM(3) + .section .debug_info,"",@progbits +.Lcu_begin0: + .long .Ldebug_info_end0-.Ldebug_info_start0 # Length of Unit +.Ldebug_info_start0: + .short 5 # DWARF version number + .byte 1 # DWARF Unit Type + .byte 8 # Address Size (in bytes) + .long .debug_abbrev # Offset Into Abbrev. Section +.Ldebug_info_end0: + .section .debug_str_offsets,"",@progbits + .long 36 # Length of String Offsets Set + .short 5 + .short 0 +.Lstr_offsets_base0: + .section .debug_str,"MS",@progbits,1 +.Linfo_string0: + .asciz "clang version 19.0.0git (git@github.com:llvm/llvm-project.git 53b14cd9ce2b57da73d173fc876d2e9e199f5640)" # string offset=0 +.Linfo_string1: + .asciz "a.cpp" # string offset=104 +.Linfo_string2: + .asciz "debug-names-test" # string offset=110 +.Linfo_string3: + .asciz "main" # string offset=127 +.Linfo_string4: + .asciz "int" # string offset=132 +.Linfo_string5: + .asciz "argc" # string offset=136 +.Linfo_string6: + .asciz "argv" # string offset=141 +.Linfo_string7: + .asciz "char" # string offset=146 +.Laddr_table_base0: + .quad .Lfunc_begin0 +.Ldebug_addr_end0: + .section .debug_names,"",@progbits + .long .Lnames_end0-.Lnames_start0 # Header: unit length +.Lnames_start0: + .short 5 # Header: version + .short 0 # Header: padding + .long 1 # Header: compilation unit count + .long 0 # Header: local type unit count + .long 0 # Header: foreign type unit count + .long 3 # Header: bucket count + .long 3 # Header: name count + .long .Lnames_abbrev_end0-.Lnames_abbrev_start0 # Header: abbreviation table size + .long 8 # Header: augmentation string size + .ascii "LLVM0700" # Header: augmentation string + .long .Lcu_begin0 # Compilation unit 0 + .long 0 # Bucket 0 + .long 1 # Bucket 1 + .long 2 # Bucket 2 + .long 2090499946 # Hash in Bucket 1 + .long 193495088 # Hash in Bucket 2 + .long 2090147939 # Hash in Bucket 2 + .long .Linfo_string3 # String in Bucket 1: main + .long .Linfo_string4 # String in Bucket 2: int + .long .Linfo_string7 # String in Bucket 2: char + .long .Lnames0-.Lnames_entries0 # Offset in Bucket 1 + .long .Lnames1-.Lnames_entries0 # Offset in Bucket 2 + .long .Lnames2-.Lnames_entries0 # Offset in Bucket 2 +.Lnames_abbrev_start0: + .byte 1 # Abbrev code + .byte 46 # DW_TAG_subprogram + .byte 3 # DW_IDX_die_offset + .byte 19 # DW_FORM_ref4 + .byte 0 # End of abbrev + .byte 0 # End of abbrev + .byte 2 # Abbrev code + .byte 36 # DW_TAG_base_type + .byte 3 # DW_IDX_die_offset + .byte 19 # DW_FORM_ref4 + .byte 4 # DW_IDX_parent + .byte 25 # DW_FORM_flag_present + .byte 0 # End of abbrev + .byte 0 # End of abbrev + .byte 0 # End of abbrev list +.Lnames_abbrev_end0: +.Lnames_entries0: +.Lnames0: +.L1: + .byte 1 # Abbreviation code + .long 35 # DW_IDX_die_offset + # End of list: main +.Lnames1: +.L0: + .byte 2 # Abbreviation code + .long 73 # DW_IDX_die_offset + .byte 0 # DW_IDX_parent + # End of list: int +.Lnames2: +.L2: + .byte 2 # Abbreviation code + .long 87 # DW_IDX_die_offset + .byte 0 # DW_IDX_parent + # End of list: char + .p2align 2, 0x0 +.Lnames_end0: + .ident "clang version 19.0.0git (git@github.com:llvm/llvm-project.git 53b14cd9ce2b57da73d173fc876d2e9e199f5640)" + .section ".note.GNU-stack","",@progbits + .addrsig + .section .debug_line,"",@progbits +.Lline_table_start0: diff --git a/lld/test/ELF/debug-names.s b/lld/test/ELF/debug-names.s index 442653386977d..eb35281a224f0 100644 --- a/lld/test/ELF/debug-names.s +++ b/lld/test/ELF/debug-names.s @@ -1,9 +1,9 @@ -# debug_names.s was gGenerated with: +# debug-names.s was generated with: # - clang++ -g -O0 -gpubnames -fdebug-compilation-dir='debug-names-test' \ -# -S debug-names.cpp -o a.s +# -S a.cpp -o a.s -# debug-names.cpp contents: +# a.cpp contents: # struct t1 { }; # void f1(t1) { } @@ -65,7 +65,7 @@ # DWARF-NEXT: Bucket 1 [ # DWARF-NEXT: Name 1 { # DWARF-NEXT: Hash: 0x59796A -# DWARF-NEXT: String: 0x00000095 "t1" +# DWARF-NEXT: String: 0x0000008b "t1" # DWARF-NEXT: Entry @ 0xaa { # DWARF-NEXT: Abbrev: 0x1 # DWARF-NEXT: Tag: DW_TAG_structure_type @@ -83,7 +83,7 @@ # DWARF-NEXT: } # DWARF-NEXT: Name 2 { # DWARF-NEXT: Hash: 0x5355B2BE -# DWARF-NEXT: String: 0x0000008c "_Z2f12t1" +# DWARF-NEXT: String: 0x00000082 "_Z2f12t1" # DWARF-NEXT: Entry @ 0xbe { # DWARF-NEXT: Abbrev: 0x2 # DWARF-NEXT: Tag: DW_TAG_subprogram @@ -94,7 +94,7 @@ # DWARF-NEXT: } # DWARF-NEXT: Name 3 { # DWARF-NEXT: Hash: 0x7C9A7F6A -# DWARF-NEXT: String: 0x0000012b "main" +# DWARF-NEXT: String: 0x00000115 "main" # DWARF-NEXT: Entry @ 0xc5 { # DWARF-NEXT: Abbrev: 0x2 # DWARF-NEXT: Tag: DW_TAG_subprogram @@ -110,7 +110,7 @@ # DWARF-NEXT: Bucket 3 [ # DWARF-NEXT: Name 4 { # DWARF-NEXT: Hash: 0xB888030 -# DWARF-NEXT: String: 0x00000130 "int" +# DWARF-NEXT: String: 0x0000011a "int" # DWARF-NEXT: Entry @ 0xb7 { # DWARF-NEXT: Abbrev: 0x3 # DWARF-NEXT: Tag: DW_TAG_base_type @@ -123,7 +123,7 @@ # DWARF-NEXT: Bucket 4 [ # DWARF-NEXT: Name 5 { # DWARF-NEXT: Hash: 0x59779C -# DWARF-NEXT: String: 0x00000089 "f1" +# DWARF-NEXT: String: 0x0000007f "f1" # DWARF-NEXT: Entry @ 0xa3 { # DWARF-NEXT: Abbrev: 0x2 # DWARF-NEXT: Tag: DW_TAG_subprogram @@ -177,17 +177,17 @@ _Z2f12t1: # @_Z2f12t1 .Lstr_offsets_base0: .section .debug_str,"MS",@progbits,1 .Linfo_string0: - .asciz "clang version 19.0.0git (git@github.com:llvm/llvm-project.git 4df364bc93af49ae413ec1ae8328f34ac70730c4)" # string offset=0 + .asciz "clang version 19.0.0git (git@github.com:llvm/llvm-project.git 53b14cd9ce2b57da73d173fc876d2e9e199f5640)" # string offset=0 .Linfo_string1: - .asciz "debug-names.cpp" # string offset=104 + .asciz "a.cpp" # string offset=104 .Linfo_string2: - .asciz "debug-names-test" # string offset=120 + .asciz "debug-names-test" # string offset=110 .Linfo_string3: - .asciz "f1" # string offset=137 + .asciz "f1" # string offset=127 .Linfo_string4: - .asciz "_Z2f12t1" # string offset=140 + .asciz "_Z2f12t1" # string offset=130 .Linfo_string5: - .asciz "t1" # string offset=149 + .asciz "t1" # string offset=139 .Laddr_table_base0: .quad .Lfunc_begin0 .Ldebug_addr_end0: @@ -256,7 +256,7 @@ _Z2f12t1: # @_Z2f12t1 # End of list: _Z2f12t1 .p2align 2, 0x0 .Lnames_end0: - .ident "clang version 19.0.0git (git@github.com:llvm/llvm-project.git 4df364bc93af49ae413ec1ae8328f34ac70730c4)" + .ident "clang version 19.0.0git (git@github.com:llvm/llvm-project.git 53b14cd9ce2b57da73d173fc876d2e9e199f5640)" .section ".note.GNU-stack","",@progbits .addrsig .section .debug_line,"",@progbits @@ -265,9 +265,9 @@ _Z2f12t1: # @_Z2f12t1 #--- b.s # Generated with: # - clang++ -g -O0 -gpubnames -fdebug-compilation-dir='debug-names-test' \ -# -S debug-names-2.cpp -o b.s +# -S b.cpp -o b.s -# debug-names-2.cpp contents: +# b.cpp contents: # struct t1 { }; # int main() { @@ -317,19 +317,19 @@ main: # @main .Lstr_offsets_base0: .section .debug_str,"MS",@progbits,1 .Linfo_string0: - .asciz "clang version 19.0.0git (git@github.com:llvm/llvm-project.git 4df364bc93af49ae413ec1ae8328f34ac70730c4)" # string offset=0 + .asciz "clang version 19.0.0git (git@github.com:llvm/llvm-project.git 53b14cd9ce2b57da73d173fc876d2e9e199f5640)" # string offset=0 .Linfo_string1: - .asciz "debug-names-2.cpp" # string offset=104 + .asciz "b.cpp" # string offset=104 .Linfo_string2: - .asciz "debug-names-test" # string offset=122 + .asciz "debug-names-test" # string offset=110 .Linfo_string3: - .asciz "main" # string offset=139 + .asciz "main" # string offset=127 .Linfo_string4: - .asciz "int" # string offset=144 + .asciz "int" # string offset=132 .Linfo_string5: - .asciz "v1" # string offset=148 + .asciz "v1" # string offset=136 .Linfo_string6: - .asciz "t1" # string offset=151 + .asciz "t1" # string offset=139 .Laddr_table_base0: .quad .Lfunc_begin0 .Ldebug_addr_end0: @@ -407,7 +407,7 @@ main: # @main # End of list: int .p2align 2, 0x0 .Lnames_end0: - .ident "clang version 19.0.0git (git@github.com:llvm/llvm-project.git 4df364bc93af49ae413ec1ae8328f34ac70730c4)" + .ident "clang version 19.0.0git (git@github.com:llvm/llvm-project.git 53b14cd9ce2b57da73d173fc876d2e9e199f5640)" .section ".note.GNU-stack","",@progbits .addrsig .section .debug_line,"",@progbits diff --git a/lld/test/ELF/ppc32-debug-names.s b/lld/test/ELF/ppc32-debug-names.s new file mode 100644 index 0000000000000..40d7cc5b4fa2f --- /dev/null +++ b/lld/test/ELF/ppc32-debug-names.s @@ -0,0 +1,417 @@ +# ppc-debug-names.s was generated with: + +# - clang++ --target=powerpc -g -O0 -gpubnames \ +# -fdebug-compilation-dir='debug-names-test' -S a.cpp -o a.s + +# a.cpp contents: + +# struct t1 { }; +# void f1(t1) { } + +# REQUIRES: ppc +# RUN: rm -rf %t && split-file %s %t && cd %t +# RUN: llvm-mc -filetype=obj -triple=powerpc a.s -o a.o +# RUN: llvm-mc -filetype=obj -triple=powerpc b.s -o b.o + +# RUN: ld.lld --debug-names --no-debug-names a.o b.o -o out0 +# RUN: llvm-readelf -SW out0 | FileCheck %s --check-prefix=NO_MERGE + +# NO_MERGE: Name Type Address Off Size ES Flg Lk Inf Al +# NO_MERGE: .debug_names PROGBITS 00000000 [[#%x,]] 000110 00 0 0 4 + +# RUN: ld.lld --debug-names a.o b.o -o out + +# RUN: llvm-dwarfdump -debug-names out | FileCheck %s --check-prefix=DWARF +# RUN: llvm-readelf -SW out | FileCheck %s --check-prefix=READELF + +# READELF: Name Type Address Off Size ES Flg Lk Inf Al +# READELF: .debug_names PROGBITS 00000000 [[#%x,]] 0000cc 00 0 0 4 + +# DWARF: file format elf32-powerpc +# DWARF: .debug_names contents: +# DWARF: Name Index @ 0x0 { +# DWARF-NEXT: Header { +# DWARF-NEXT: Length: 0xC8 +# DWARF-NEXT: Format: DWARF32 +# DWARF-NEXT: Version: 5 +# DWARF-NEXT: CU count: 2 +# DWARF-NEXT: Local TU count: 0 +# DWARF-NEXT: Foreign TU count: 0 +# DWARF-NEXT: Bucket count: 5 +# DWARF-NEXT: Name count: 5 +# DWARF-NEXT: Abbreviations table size: 0x1F +# DWARF-NEXT: Augmentation: 'LLVM0700' +# DWARF: Compilation Unit offsets [ +# DWARF-NEXT: CU[0]: 0x00000000 +# DWARF-NEXT: CU[1]: 0x0000000c +# DWARF: Abbreviations [ +# DWARF-NEXT: Abbreviation 0x1 { +# DWARF: Tag: DW_TAG_structure_type +# DWARF-NEXT: DW_IDX_die_offset: DW_FORM_ref4 +# DWARF-NEXT: DW_IDX_parent: DW_FORM_flag_present +# DWARF-NEXT: DW_IDX_compile_unit: DW_FORM_data1 +# DWARF: Abbreviation 0x2 { +# DWARF-NEXT: Tag: DW_TAG_subprogram +# DWARF-NEXT: DW_IDX_die_offset: DW_FORM_ref4 +# DWARF-NEXT: DW_IDX_parent: DW_FORM_flag_present +# DWARF-NEXT: DW_IDX_compile_unit: DW_FORM_data1 +# DWARF: Abbreviation 0x3 { +# DWARF-NEXT: Tag: DW_TAG_base_type +# DWARF-NEXT: DW_IDX_die_offset: DW_FORM_ref4 +# DWARF-NEXT: DW_IDX_parent: DW_FORM_flag_present +# DWARF-NEXT: DW_IDX_compile_unit: DW_FORM_data1 +# DWARF: Bucket 0 [ +# DWARF-NEXT: EMPTY +# DWARF-NEXT: ] +# DWARF-NEXT: Bucket 1 [ +# DWARF-NEXT: Name 1 { +# DWARF-NEXT: Hash: 0x59796A +# DWARF-NEXT: String: 0x0000008b "t1" +# DWARF-NEXT: Entry @ 0xaa { +# DWARF-NEXT: Abbrev: 0x1 +# DWARF-NEXT: Tag: DW_TAG_structure_type +# DWARF-NEXT: DW_IDX_die_offset: 0x0000003a +# DWARF-NEXT: DW_IDX_parent: +# DWARF-NEXT: DW_IDX_compile_unit: 0x00 +# DWARF-NEXT: } +# DWARF-NEXT: Entry @ 0xb0 { +# DWARF-NEXT: Abbrev: 0x1 +# DWARF-NEXT: Tag: DW_TAG_structure_type +# DWARF-NEXT: DW_IDX_die_offset: 0x00000042 +# DWARF-NEXT: DW_IDX_parent: +# DWARF-NEXT: DW_IDX_compile_unit: 0x01 +# DWARF-NEXT: } +# DWARF-NEXT: } +# DWARF-NEXT: Name 2 { +# DWARF-NEXT: Hash: 0x5355B2BE +# DWARF-NEXT: String: 0x00000082 "_Z2f12t1" +# DWARF-NEXT: Entry @ 0xbe { +# DWARF-NEXT: Abbrev: 0x2 +# DWARF-NEXT: Tag: DW_TAG_subprogram +# DWARF-NEXT: DW_IDX_die_offset: 0x00000023 +# DWARF-NEXT: DW_IDX_parent: +# DWARF-NEXT: DW_IDX_compile_unit: 0x00 +# DWARF-NEXT: } +# DWARF-NEXT: } +# DWARF-NEXT: Name 3 { +# DWARF-NEXT: Hash: 0x7C9A7F6A +# DWARF-NEXT: String: 0x00000111 "main" +# DWARF-NEXT: Entry @ 0xc5 { +# DWARF-NEXT: Abbrev: 0x2 +# DWARF-NEXT: Tag: DW_TAG_subprogram +# DWARF-NEXT: DW_IDX_die_offset: 0x00000023 +# DWARF-NEXT: DW_IDX_parent: +# DWARF-NEXT: DW_IDX_compile_unit: 0x01 +# DWARF-NEXT: } +# DWARF-NEXT: } +# DWARF-NEXT: ] +# DWARF-NEXT: Bucket 2 [ +# DWARF-NEXT: EMPTY +# DWARF-NEXT: ] +# DWARF-NEXT: Bucket 3 [ +# DWARF-NEXT: Name 4 { +# DWARF-NEXT: Hash: 0xB888030 +# DWARF-NEXT: String: 0x00000116 "int" +# DWARF-NEXT: Entry @ 0xb7 { +# DWARF-NEXT: Abbrev: 0x3 +# DWARF-NEXT: Tag: DW_TAG_base_type +# DWARF-NEXT: DW_IDX_die_offset: 0x0000003e +# DWARF-NEXT: DW_IDX_parent: +# DWARF-NEXT: DW_IDX_compile_unit: 0x01 +# DWARF-NEXT: } +# DWARF-NEXT: } +# DWARF-NEXT: ] +# DWARF-NEXT: Bucket 4 [ +# DWARF-NEXT: Name 5 { +# DWARF-NEXT: Hash: 0x59779C +# DWARF-NEXT: String: 0x0000007f "f1" +# DWARF-NEXT: Entry @ 0xa3 { +# DWARF-NEXT: Abbrev: 0x2 +# DWARF-NEXT: Tag: DW_TAG_subprogram +# DWARF-NEXT: DW_IDX_die_offset: 0x00000023 +# DWARF-NEXT: DW_IDX_parent: +# DWARF-NEXT: DW_IDX_compile_unit: 0x00 +# DWARF-NEXT: } +# DWARF-NEXT: } +# DWARF-NEXT: ] + +#--- a.s + .text + .globl _Z2f12t1 # -- Begin function _Z2f12t1 + .p2align 2 + .type _Z2f12t1,@function +_Z2f12t1: # @_Z2f12t1 +.Lfunc_begin0: + .cfi_startproc +# %bb.0: # %entry + stwu 1, -16(1) + stw 31, 12(1) + .cfi_def_cfa_offset 16 + .cfi_offset r31, -4 + mr 31, 1 + .cfi_def_cfa_register r31 +.Ltmp0: + lwz 31, 12(1) + addi 1, 1, 16 + blr +.Ltmp1: +.Lfunc_end0: + .size _Z2f12t1, .Lfunc_end0-.Lfunc_begin0 + .cfi_endproc + # -- End function + .section .debug_abbrev,"",@progbits + .byte 0 # EOM(1) + .byte 0 # EOM(2) + .byte 0 # EOM(3) + .section .debug_info,"",@progbits +.Lcu_begin0: + .long .Ldebug_info_end0-.Ldebug_info_start0 # Length of Unit +.Ldebug_info_start0: + .short 5 # DWARF version number + .byte 1 # DWARF Unit Type + .byte 4 # Address Size (in bytes) + .long .debug_abbrev # Offset Into Abbrev. Section +.Ldebug_info_end0: + .section .debug_str_offsets,"",@progbits + .long 28 # Length of String Offsets Set + .short 5 + .short 0 +.Lstr_offsets_base0: + .section .debug_str,"MS",@progbits,1 +.Linfo_string0: + .asciz "clang version 19.0.0git (git@github.com:llvm/llvm-project.git 53b14cd9ce2b57da73d173fc876d2e9e199f5640)" # string offset=0 +.Linfo_string1: + .asciz "a.cpp" # string offset=104 +.Linfo_string2: + .asciz "debug-names-test" # string offset=110 +.Linfo_string3: + .asciz "f1" # string offset=127 +.Linfo_string4: + .asciz "_Z2f12t1" # string offset=130 +.Linfo_string5: + .asciz "t1" # string offset=139 +.Laddr_table_base0: + .long .Lfunc_begin0 +.Ldebug_addr_end0: + .section .debug_names,"",@progbits + .long .Lnames_end0-.Lnames_start0 # Header: unit length +.Lnames_start0: + .short 5 # Header: version + .short 0 # Header: padding + .long 1 # Header: compilation unit count + .long 0 # Header: local type unit count + .long 0 # Header: foreign type unit count + .long 3 # Header: bucket count + .long 3 # Header: name count + .long .Lnames_abbrev_end0-.Lnames_abbrev_start0 # Header: abbreviation table size + .long 8 # Header: augmentation string size + .ascii "LLVM0700" # Header: augmentation string + .long .Lcu_begin0 # Compilation unit 0 + .long 0 # Bucket 0 + .long 1 # Bucket 1 + .long 3 # Bucket 2 + .long 5863324 # Hash in Bucket 1 + .long 5863786 # Hash in Bucket 1 + .long 1398125246 # Hash in Bucket 2 + .long .Linfo_string3 # String in Bucket 1: f1 + .long .Linfo_string5 # String in Bucket 1: t1 + .long .Linfo_string4 # String in Bucket 2: _Z2f12t1 + .long .Lnames0-.Lnames_entries0 # Offset in Bucket 1 + .long .Lnames2-.Lnames_entries0 # Offset in Bucket 1 + .long .Lnames1-.Lnames_entries0 # Offset in Bucket 2 +.Lnames_abbrev_start0: + .byte 1 # Abbrev code + .byte 46 # DW_TAG_subprogram + .byte 3 # DW_IDX_die_offset + .byte 19 # DW_FORM_ref4 + .byte 4 # DW_IDX_parent + .byte 25 # DW_FORM_flag_present + .byte 0 # End of abbrev + .byte 0 # End of abbrev + .byte 2 # Abbrev code + .byte 19 # DW_TAG_structure_type + .byte 3 # DW_IDX_die_offset + .byte 19 # DW_FORM_ref4 + .byte 4 # DW_IDX_parent + .byte 25 # DW_FORM_flag_present + .byte 0 # End of abbrev + .byte 0 # End of abbrev + .byte 0 # End of abbrev list +.Lnames_abbrev_end0: +.Lnames_entries0: +.Lnames0: +.L1: + .byte 1 # Abbreviation code + .long 35 # DW_IDX_die_offset + .byte 0 # DW_IDX_parent + # End of list: f1 +.Lnames2: +.L0: + .byte 2 # Abbreviation code + .long 58 # DW_IDX_die_offset + .byte 0 # DW_IDX_parent + # End of list: t1 +.Lnames1: + .byte 1 # Abbreviation code + .long 35 # DW_IDX_die_offset + .byte 0 # DW_IDX_parent + # End of list: _Z2f12t1 + .p2align 2, 0x0 +.Lnames_end0: + .ident "clang version 19.0.0git (git@github.com:llvm/llvm-project.git 53b14cd9ce2b57da73d173fc876d2e9e199f5640)" + .section ".note.GNU-stack","",@progbits + .addrsig + .section .debug_line,"",@progbits +.Lline_table_start0: + +#--- b.s +# Generated with: +# - clang++ --target=powerpc -g -O0 -gpubnames \ +# -fdebug-compilation-dir='debug-names-test' -S b.cpp -o b.s + +# b.cpp contents: + +# struct t1 { }; +# int main() { +# t1 v1; +# } +# + .text + .globl main # -- Begin function main + .p2align 2 + .type main,@function +main: # @main +.Lfunc_begin0: + .cfi_startproc +# %bb.0: # %entry + stwu 1, -16(1) + stw 31, 12(1) + .cfi_def_cfa_offset 16 + .cfi_offset r31, -4 + mr 31, 1 + .cfi_def_cfa_register r31 + li 3, 0 +.Ltmp0: + lwz 31, 12(1) + addi 1, 1, 16 + blr +.Ltmp1: +.Lfunc_end0: + .size main, .Lfunc_end0-.Lfunc_begin0 + .cfi_endproc + # -- End function + .section .debug_abbrev,"",@progbits + .byte 0 # EOM(1) + .byte 0 # EOM(2) + .byte 0 # EOM(3) + .section .debug_info,"",@progbits +.Lcu_begin0: + .long .Ldebug_info_end0-.Ldebug_info_start0 # Length of Unit +.Ldebug_info_start0: + .short 5 # DWARF version number + .byte 1 # DWARF Unit Type + .byte 4 # Address Size (in bytes) + .long .debug_abbrev # Offset Into Abbrev. Section +.Ldebug_info_end0: + .section .debug_str_offsets,"",@progbits + .long 32 # Length of String Offsets Set + .short 5 + .short 0 +.Lstr_offsets_base0: + .section .debug_str,"MS",@progbits,1 +.Linfo_string0: + .asciz "clang version 19.0.0git (git@github.com:llvm/llvm-project.git 53b14cd9ce2b57da73d173fc876d2e9e199f5640)" # string offset=0 +.Linfo_string1: + .asciz "b.cpp" # string offset=104 +.Linfo_string2: + .asciz "debug-names-test" # string offset=110 +.Linfo_string3: + .asciz "main" # string offset=127 +.Linfo_string4: + .asciz "int" # string offset=132 +.Linfo_string5: + .asciz "v1" # string offset=136 +.Linfo_string6: + .asciz "t1" # string offset=139 +.Laddr_table_base0: + .long .Lfunc_begin0 +.Ldebug_addr_end0: + .section .debug_names,"",@progbits + .long .Lnames_end0-.Lnames_start0 # Header: unit length +.Lnames_start0: + .short 5 # Header: version + .short 0 # Header: padding + .long 1 # Header: compilation unit count + .long 0 # Header: local type unit count + .long 0 # Header: foreign type unit count + .long 3 # Header: bucket count + .long 3 # Header: name count + .long .Lnames_abbrev_end0-.Lnames_abbrev_start0 # Header: abbreviation table size + .long 8 # Header: augmentation string size + .ascii "LLVM0700" # Header: augmentation string + .long .Lcu_begin0 # Compilation unit 0 + .long 0 # Bucket 0 + .long 1 # Bucket 1 + .long 3 # Bucket 2 + .long 5863786 # Hash in Bucket 1 + .long 2090499946 # Hash in Bucket 1 + .long 193495088 # Hash in Bucket 2 + .long .Linfo_string6 # String in Bucket 1: t1 + .long .Linfo_string3 # String in Bucket 1: main + .long .Linfo_string4 # String in Bucket 2: int + .long .Lnames2-.Lnames_entries0 # Offset in Bucket 1 + .long .Lnames0-.Lnames_entries0 # Offset in Bucket 1 + .long .Lnames1-.Lnames_entries0 # Offset in Bucket 2 +.Lnames_abbrev_start0: + .byte 1 # Abbrev code + .byte 19 # DW_TAG_structure_type + .byte 3 # DW_IDX_die_offset + .byte 19 # DW_FORM_ref4 + .byte 4 # DW_IDX_parent + .byte 25 # DW_FORM_flag_present + .byte 0 # End of abbrev + .byte 0 # End of abbrev + .byte 2 # Abbrev code + .byte 46 # DW_TAG_subprogram + .byte 3 # DW_IDX_die_offset + .byte 19 # DW_FORM_ref4 + .byte 4 # DW_IDX_parent + .byte 25 # DW_FORM_flag_present + .byte 0 # End of abbrev + .byte 0 # End of abbrev + .byte 3 # Abbrev code + .byte 36 # DW_TAG_base_type + .byte 3 # DW_IDX_die_offset + .byte 19 # DW_FORM_ref4 + .byte 4 # DW_IDX_parent + .byte 25 # DW_FORM_flag_present + .byte 0 # End of abbrev + .byte 0 # End of abbrev + .byte 0 # End of abbrev list +.Lnames_abbrev_end0: +.Lnames_entries0: +.Lnames2: +.L1: + .byte 1 # Abbreviation code + .long 66 # DW_IDX_die_offset + .byte 0 # DW_IDX_parent + # End of list: t1 +.Lnames0: +.L2: + .byte 2 # Abbreviation code + .long 35 # DW_IDX_die_offset + .byte 0 # DW_IDX_parent + # End of list: main +.Lnames1: +.L0: + .byte 3 # Abbreviation code + .long 62 # DW_IDX_die_offset + .byte 0 # DW_IDX_parent + # End of list: int + .p2align 2, 0x0 +.Lnames_end0: + .ident "clang version 19.0.0git (git@github.com:llvm/llvm-project.git 53b14cd9ce2b57da73d173fc876d2e9e199f5640)" + .section ".note.GNU-stack","",@progbits + .addrsig + .section .debug_line,"",@progbits +.Lline_table_start0: From 8d712883000fef2d21832c1d600e64da4fc19548 Mon Sep 17 00:00:00 2001 From: Caroline Tice Date: Sun, 14 Apr 2024 13:37:38 -0700 Subject: [PATCH 18/37] [lld][ELF] Fix clang-format issues. Fix clang-format issues. --- lld/ELF/SyntheticSections.cpp | 11 ++++------- lld/ELF/SyntheticSections.h | 3 +-- 2 files changed, 5 insertions(+), 9 deletions(-) diff --git a/lld/ELF/SyntheticSections.cpp b/lld/ELF/SyntheticSections.cpp index 12acbcc9a842a..910ace1c757b4 100644 --- a/lld/ELF/SyntheticSections.cpp +++ b/lld/ELF/SyntheticSections.cpp @@ -2738,9 +2738,7 @@ void DebugNamesBaseSection::parseDebugNames( InputChunk &inputChunk, OutputChunk &chunk, DWARFDataExtractor &namesExtractor, DataExtractor &strExtractor, function_ref( - uint32_t numCus, - uint32_t niOffset, - const DWARFDebugNames::Header &, + uint32_t numCus, uint32_t niOffset, const DWARFDebugNames::Header &, const DWARFDebugNames::DWARFDebugNamesOffsets &)> readOffsets) { const LLDDWARFSection namesSec = inputChunk.section; @@ -2773,8 +2771,8 @@ void DebugNamesBaseSection::parseDebugNames( return; } - SmallVector entryOffsets = readOffsets(numCus, niOffset, - nd.hdr, locs); + SmallVector entryOffsets = + readOffsets(numCus, niOffset, nd.hdr, locs); // Read the entry pool. offsetMap.clear(); @@ -3167,8 +3165,7 @@ template DebugNamesSection::DebugNamesSection() { parseDebugNames( inputChunk, chunk, namesExtractor, strExtractor, [&chunk, namesData = dobj.getNamesSection().Data.data()]( - uint32_t numCus, - uint32_t niOffset, + uint32_t numCus, uint32_t niOffset, const DWARFDebugNames::Header &hdr, const DWARFDebugNames::DWARFDebugNamesOffsets &locs) { // Read CU offsets. diff --git a/lld/ELF/SyntheticSections.h b/lld/ELF/SyntheticSections.h index f15658e779bc2..534fac005e0b8 100644 --- a/lld/ELF/SyntheticSections.h +++ b/lld/ELF/SyntheticSections.h @@ -872,8 +872,7 @@ class DebugNamesBaseSection : public SyntheticSection { llvm::DWARFDataExtractor &namesExtractor, llvm::DataExtractor &strExtractor, llvm::function_ref( - uint32_t numCUs, - uint32_t niOffset, + uint32_t numCUs, uint32_t niOffset, const llvm::DWARFDebugNames::Header &hdr, const llvm::DWARFDebugNames::DWARFDebugNamesOffsets &)> readOffsets); From 7607c4d40149128f848055613edf9c3cf9ae890d Mon Sep 17 00:00:00 2001 From: Caroline Tice Date: Sun, 14 Apr 2024 16:29:47 -0700 Subject: [PATCH 19/37] [lld][ELF] Clean up file & directory names in tests. Shorten file names to a.cpp, b.cpp, etc. Replace debug-names-test directory with /proc/self/cwd. --- lld/test/ELF/debug-names-bad-aug-string.s | 45 ++++---- lld/test/ELF/debug-names-bad-name-count.s | 18 +-- lld/test/ELF/debug-names-bad-offsets-sizes.s | 25 ++-- lld/test/ELF/debug-names-bad-version.s | 85 ++++---------- lld/test/ELF/debug-names-dwarf64.s | 24 ++-- .../ELF/debug-names-invalid-abbrev-code.s | 23 ++-- .../ELF/debug-names-invalid-attribute-2.s | 23 ++-- .../ELF/debug-names-invalid-attribute-3.s | 23 ++-- lld/test/ELF/debug-names-invalid-attribute.s | 16 +-- lld/test/ELF/debug-names-invalid-parent-idx.s | 25 ++-- lld/test/ELF/debug-names-missing-parent.s | 21 ++-- lld/test/ELF/debug-names-parent-idx.s | 109 +++++++++--------- lld/test/ELF/debug-names.s | 35 +++--- lld/test/ELF/ppc32-debug-names.s | 33 +++--- 14 files changed, 233 insertions(+), 272 deletions(-) diff --git a/lld/test/ELF/debug-names-bad-aug-string.s b/lld/test/ELF/debug-names-bad-aug-string.s index 1cf81cfef94df..62ed64aa5b570 100644 --- a/lld/test/ELF/debug-names-bad-aug-string.s +++ b/lld/test/ELF/debug-names-bad-aug-string.s @@ -3,9 +3,9 @@ # REQUIRES: x86 # RUN: rm -rf %t && split-file %s %t && cd %t -# RUN: llvm-mc -filetype=obj -triple=x86_64 bad-aug-string.s -o bad-aug-string.o +# RUN: llvm-mc -filetype=obj -triple=x86_64 a.s -o a.o # RUN: llvm-mc -filetype=obj -triple=x86_64 b.s -o b.o -# RUN: ld.lld --debug-names bad-aug-string.o b.o -o out +# RUN: ld.lld --debug-names a.o b.o -o out # RUN: llvm-dwarfdump -debug-names out | FileCheck %s --check-prefix=DWARF # DWARF: .debug_names contents: @@ -24,8 +24,8 @@ # DWARF: Compilation Unit offsets [ # DWARF-NEXT: CU[0]: 0x00000000 # DWARF-NEXT: CU[1]: 0x0000000c - -#--- bad-aug-string.s + +#--- a.s .text .globl _Z2f12t1 # -- Begin function _Z2f12t1 .p2align 4, 0x90 @@ -68,17 +68,17 @@ _Z2f12t1: # @_Z2f12t1 .Lstr_offsets_base0: .section .debug_str,"MS",@progbits,1 .Linfo_string0: - .asciz "clang version 19.0.0git (git@github.com:llvm/llvm-project.git 4df364bc93af49ae413ec1ae8328f34ac70730c4)" # string offset=0 + .asciz "clang version 19.0.0git (git@github.com:llvm/llvm-project.git 53b14cd9ce2b57da73d173fc876d2e9e199f5640)" # string offset=0 .Linfo_string1: - .asciz "debug-names.cpp" # string offset=104 + .asciz "a.cpp" # string offset=104 .Linfo_string2: - .asciz "debug-names-test" # string offset=120 + .asciz "/proc/self/cwd" # string offset=110 .Linfo_string3: - .asciz "f1" # string offset=137 + .asciz "f1" # string offset=125 .Linfo_string4: - .asciz "_Z2f12t1" # string offset=140 + .asciz "_Z2f12t1" # string offset=128 .Linfo_string5: - .asciz "t1" # string offset=149 + .asciz "t1" # string offset=137 .Laddr_table_base0: .quad .Lfunc_begin0 .Ldebug_addr_end0: @@ -147,19 +147,18 @@ _Z2f12t1: # @_Z2f12t1 # End of list: _Z2f12t1 .p2align 2, 0x0 .Lnames_end0: - .ident "clang version 19.0.0git (git@github.com:llvm/llvm-project.git 4df364bc93af49ae413ec1ae8328f34ac70730c4)" + .ident "clang version 19.0.0git (git@github.com:llvm/llvm-project.git 53b14cd9ce2b57da73d173fc876d2e9e199f5640)" .section ".note.GNU-stack","",@progbits .addrsig .section .debug_line,"",@progbits .Lline_table_start0: #--- b.s -# input file: debug-names-2.cpp # Generated with: -# - clang++ -g -O0 -gpubnames -fdebug-compilation-dir='debug-names-test' \ -# -S debug-names-2.cpp -o b.s +# - clang++ -g -O0 -gpubnames -fdebug-compilation-dir='/proc/self/cwdt' \ +# -S b.cpp -o b.s -# debug-names-2.cpp contents: +# b.cpp contents: # struct t1 { }; # int main() { @@ -209,19 +208,19 @@ main: # @main .Lstr_offsets_base0: .section .debug_str,"MS",@progbits,1 .Linfo_string0: - .asciz "clang version 19.0.0git (git@github.com:llvm/llvm-project.git 4df364bc93af49ae413ec1ae8328f34ac70730c4)" # string offset=0 + .asciz "clang version 19.0.0git (git@github.com:llvm/llvm-project.git 53b14cd9ce2b57da73d173fc876d2e9e199f5640)" # string offset=0 .Linfo_string1: - .asciz "debug-names-2.cpp" # string offset=104 + .asciz "b.cpp" # string offset=104 .Linfo_string2: - .asciz "debug-names-test" # string offset=122 + .asciz "/proc/self/cwd" # string offset=110 .Linfo_string3: - .asciz "main" # string offset=139 + .asciz "main" # string offset=125 .Linfo_string4: - .asciz "int" # string offset=144 + .asciz "int" # string offset=130 .Linfo_string5: - .asciz "v1" # string offset=148 + .asciz "v1" # string offset=134 .Linfo_string6: - .asciz "t1" # string offset=151 + .asciz "t1" # string offset=137 .Laddr_table_base0: .quad .Lfunc_begin0 .Ldebug_addr_end0: @@ -299,7 +298,7 @@ main: # @main # End of list: int .p2align 2, 0x0 .Lnames_end0: - .ident "clang version 19.0.0git (git@github.com:llvm/llvm-project.git 4df364bc93af49ae413ec1ae8328f34ac70730c4)" + .ident "clang version 19.0.0git (git@github.com:llvm/llvm-project.git 53b14cd9ce2b57da73d173fc876d2e9e199f5640)" .section ".note.GNU-stack","",@progbits .addrsig .section .debug_line,"",@progbits diff --git a/lld/test/ELF/debug-names-bad-name-count.s b/lld/test/ELF/debug-names-bad-name-count.s index f660bc0512cc6..11a418177e1c1 100644 --- a/lld/test/ELF/debug-names-bad-name-count.s +++ b/lld/test/ELF/debug-names-bad-name-count.s @@ -71,21 +71,21 @@ main: # @main .Lstr_offsets_base0: .section .debug_str,"MS",@progbits,1 .Linfo_string0: - .asciz "clang version 19.0.0git (git@github.com:llvm/llvm-project.git d33d5630b281debe6eabd67e323bcf767340fb6a)" # string offset=0 + .asciz "clang version 19.0.0git (git@github.com:llvm/llvm-project.git 53b14cd9ce2b57da73d173fc876d2e9e199f5640)" # string offset=0 .Linfo_string1: - .asciz "main.cpp" # string offset=104 + .asciz "a.cpp" # string offset=104 .Linfo_string2: - .asciz "debug-names-test" # string offset=113 + .asciz "/proc/self/cwd" # string offset=110 .Linfo_string3: - .asciz "main" # string offset=130 + .asciz "main" # string offset=125 .Linfo_string4: - .asciz "int" # string offset=135 + .asciz "int" # string offset=130 .Linfo_string5: - .asciz "argc" # string offset=139 + .asciz "argc" # string offset=134 .Linfo_string6: - .asciz "argv" # string offset=144 + .asciz "argv" # string offset=139 .Linfo_string7: - .asciz "char" # string offset=149 + .asciz "char" # string offset=144 .Laddr_table_base0: .quad .Lfunc_begin0 .Ldebug_addr_end0: @@ -155,7 +155,7 @@ main: # @main # End of list: char .p2align 2, 0x0 .Lnames_end0: - .ident "clang version 19.0.0git (git@github.com:llvm/llvm-project.git d33d5630b281debe6eabd67e323bcf767340fb6a)" + .ident "clang version 19.0.0git (git@github.com:llvm/llvm-project.git 53b14cd9ce2b57da73d173fc876d2e9e199f5640)" .section ".note.GNU-stack","",@progbits .addrsig .section .debug_line,"",@progbits diff --git a/lld/test/ELF/debug-names-bad-offsets-sizes.s b/lld/test/ELF/debug-names-bad-offsets-sizes.s index e5b4570b21651..e70a6215f3c87 100644 --- a/lld/test/ELF/debug-names-bad-offsets-sizes.s +++ b/lld/test/ELF/debug-names-bad-offsets-sizes.s @@ -1,11 +1,10 @@ -# This file was generated by first compiling main.cpp: -# clang++ -g -O0 -S -gpubnames -fdebug-compilation-dir='debug-names-test' \ -# main.cpp +# This file was generated by first compiling a.cpp: +# clang++ -g -O0 -S -gpubnames -fdebug-compilation-dir='/proc/self/cwd' a.cpp # Then manually edit .debug_names section. Change the sizes of # 'Offset in Bucket' values from '.long' to '.byte'. -# Contentsof main.cpp: +# Contents of a.cpp: # int main (int argc, char **argv) { } # REQUIRES: x86 @@ -63,21 +62,21 @@ main: # @main .Lstr_offsets_base0: .section .debug_str,"MS",@progbits,1 .Linfo_string0: - .asciz "clang version 19.0.0git (git@github.com:llvm/llvm-project.git d33d5630b281debe6eabd67e323bcf767340fb6a)" # string offset=0 + .asciz "clang version 19.0.0git (git@github.com:llvm/llvm-project.git 53b14cd9ce2b57da73d173fc876d2e9e199f5640)" # string offset=0 .Linfo_string1: - .asciz "main.cpp" # string offset=104 + .asciz "a.cpp" # string offset=104 .Linfo_string2: - .asciz "debug-names-test" # string offset=113 + .asciz "/proc/self/cwd" # string offset=110 .Linfo_string3: - .asciz "main" # string offset=130 + .asciz "main" # string offset=125 .Linfo_string4: - .asciz "int" # string offset=135 + .asciz "int" # string offset=130 .Linfo_string5: - .asciz "argc" # string offset=139 + .asciz "argc" # string offset=134 .Linfo_string6: - .asciz "argv" # string offset=144 + .asciz "argv" # string offset=139 .Linfo_string7: - .asciz "char" # string offset=149 + .asciz "char" # string offset=144 .Laddr_table_base0: .quad .Lfunc_begin0 .Ldebug_addr_end0: @@ -147,7 +146,7 @@ main: # @main # End of list: char .p2align 2, 0x0 .Lnames_end0: - .ident "clang version 19.0.0git (git@github.com:llvm/llvm-project.git d33d5630b281debe6eabd67e323bcf767340fb6a)" + .ident "clang version 19.0.0git (git@github.com:llvm/llvm-project.git 53b14cd9ce2b57da73d173fc876d2e9e199f5640)" .section ".note.GNU-stack","",@progbits .addrsig .section .debug_line,"",@progbits diff --git a/lld/test/ELF/debug-names-bad-version.s b/lld/test/ELF/debug-names-bad-version.s index ac7d6853bfa62..6f6ff2d507a9b 100644 --- a/lld/test/ELF/debug-names-bad-version.s +++ b/lld/test/ELF/debug-names-bad-version.s @@ -4,13 +4,14 @@ # REQUIRES: x86 # RUN: rm -rf %t && split-file %s %t && cd %t -# RUN: llvm-mc -filetype=obj -triple=x86_64 bad-version.s -o bad-version.o +# RUN: llvm-mc -filetype=obj -triple=x86_64 a.s -o a.o # RUN: llvm-mc -filetype=obj -triple=x86_64 b.s -o b.o -# RUN: not ld.lld --debug-names bad-version.o b.o 2>&1 | FileCheck %s --implicit-check-not=error: +# RUN: not ld.lld --debug-names a.o b.o 2>&1 \ +# RUN: | FileCheck -DFILE=a.o %s --implicit-check-not=error: -# CHECK: error: bad-version.o:(.debug_names): unsupported version 4 - -#--- bad-version.s +# CHECK: error: [[FILE]]:(.debug_names): unsupported version 4 + +#--- a.s .text .globl _Z2f12t1 # -- Begin function _Z2f12t1 .p2align 4, 0x90 @@ -45,41 +46,6 @@ _Z2f12t1: # @_Z2f12t1 .byte 1 # DWARF Unit Type .byte 8 # Address Size (in bytes) .long .debug_abbrev # Offset Into Abbrev. Section - .byte 1 # Abbrev [1] 0xc:0x35 DW_TAG_compile_unit - .byte 0 # DW_AT_producer - .short 33 # DW_AT_language - .byte 1 # DW_AT_name - .long .Lstr_offsets_base0 # DW_AT_str_offsets_base - .long .Lline_table_start0 # DW_AT_stmt_list - .byte 2 # DW_AT_comp_dir - .byte 0 # DW_AT_low_pc - .long .Lfunc_end0-.Lfunc_begin0 # DW_AT_high_pc - .long .Laddr_table_base0 # DW_AT_addr_base - .byte 2 # Abbrev [2] 0x23:0x17 DW_TAG_subprogram - .byte 0 # DW_AT_low_pc - .long .Lfunc_end0-.Lfunc_begin0 # DW_AT_high_pc - .byte 1 # DW_AT_frame_base - .byte 86 - .byte 3 # DW_AT_linkage_name - .byte 4 # DW_AT_name - .byte 0 # DW_AT_decl_file - .byte 2 # DW_AT_decl_line - # DW_AT_external - .byte 3 # Abbrev [3] 0x2f:0xa DW_TAG_formal_parameter - .byte 2 # DW_AT_location - .byte 145 - .byte 127 - .byte 0 # DW_AT_decl_file - .byte 2 # DW_AT_decl_line - .long 58 # DW_AT_type - .byte 0 # End Of Children Mark - .byte 4 # Abbrev [4] 0x3a:0x6 DW_TAG_structure_type - .byte 5 # DW_AT_calling_convention - .byte 5 # DW_AT_name - .byte 1 # DW_AT_byte_size - .byte 0 # DW_AT_decl_file - .byte 1 # DW_AT_decl_line - .byte 0 # End Of Children Mark .Ldebug_info_end0: .section .debug_str_offsets,"",@progbits .long 28 # Length of String Offsets Set @@ -88,17 +54,17 @@ _Z2f12t1: # @_Z2f12t1 .Lstr_offsets_base0: .section .debug_str,"MS",@progbits,1 .Linfo_string0: - .asciz "clang version 19.0.0git (git@github.com:llvm/llvm-project.git 4df364bc93af49ae413ec1ae8328f34ac70730c4)" # string offset=0 + .asciz "clang version 19.0.0git (git@github.com:llvm/llvm-project.git 53b14cd9ce2b57da73d173fc876d2e9e199f5640)" # string offset=0 .Linfo_string1: - .asciz "debug-names.cpp" # string offset=104 + .asciz "a.cpp" # string offset=104 .Linfo_string2: - .asciz "debug-names-test" # string offset=120 + .asciz "/proc/self/cwd" # string offset=110 .Linfo_string3: - .asciz "f1" # string offset=137 + .asciz "f1" # string offset=125 .Linfo_string4: - .asciz "_Z2f12t1" # string offset=140 + .asciz "_Z2f12t1" # string offset=128 .Linfo_string5: - .asciz "t1" # string offset=149 + .asciz "t1" # string offset=137 .Laddr_table_base0: .quad .Lfunc_begin0 .Ldebug_addr_end0: @@ -167,19 +133,18 @@ _Z2f12t1: # @_Z2f12t1 # End of list: _Z2f12t1 .p2align 2, 0x0 .Lnames_end0: - .ident "clang version 19.0.0git (git@github.com:llvm/llvm-project.git 4df364bc93af49ae413ec1ae8328f34ac70730c4)" + .ident "clang version 19.0.0git (git@github.com:llvm/llvm-project.git 53b14cd9ce2b57da73d173fc876d2e9e199f5640)" .section ".note.GNU-stack","",@progbits .addrsig .section .debug_line,"",@progbits .Lline_table_start0: #--- b.s -# input file: debug-names-2.cpp # Generated with: -# - clang++ -g -O0 -gpubnames -fdebug-compilation-dir='debug-names-test' \ -# -S debug-names-2.cpp -o b.s +# - clang++ -g -O0 -gpubnames -fdebug-compilation-dir='/proc/self/cwd' \ +# -S b.cpp -o b.s -# debug-names-2.cpp contents: +# b.cpp contents: # struct t1 { }; # int main() { @@ -217,7 +182,7 @@ main: # @main .Lcu_begin0: .long .Ldebug_info_end0-.Ldebug_info_start0 # Length of Unit .Ldebug_info_start0: - .short 5 # DWARF version number + .short 4 # DWARF version number .byte 1 # DWARF Unit Type .byte 8 # Address Size (in bytes) .long .debug_abbrev # Offset Into Abbrev. Section @@ -229,19 +194,19 @@ main: # @main .Lstr_offsets_base0: .section .debug_str,"MS",@progbits,1 .Linfo_string0: - .asciz "clang version 19.0.0git (git@github.com:llvm/llvm-project.git 4df364bc93af49ae413ec1ae8328f34ac70730c4)" # string offset=0 + .asciz "clang version 19.0.0git (git@github.com:llvm/llvm-project.git 53b14cd9ce2b57da73d173fc876d2e9e199f5640)" # string offset=0 .Linfo_string1: - .asciz "debug-names-2.cpp" # string offset=104 + .asciz "b.cpp" # string offset=104 .Linfo_string2: - .asciz "debug-names-test" # string offset=122 + .asciz "/proc/self/cwd" # string offset=110 .Linfo_string3: - .asciz "main" # string offset=139 + .asciz "main" # string offset=125 .Linfo_string4: - .asciz "int" # string offset=144 + .asciz "int" # string offset=130 .Linfo_string5: - .asciz "v1" # string offset=148 + .asciz "v1" # string offset=134 .Linfo_string6: - .asciz "t1" # string offset=151 + .asciz "t1" # string offset=137 .Laddr_table_base0: .quad .Lfunc_begin0 .Ldebug_addr_end0: @@ -319,7 +284,7 @@ main: # @main # End of list: int .p2align 2, 0x0 .Lnames_end0: - .ident "clang version 19.0.0git (git@github.com:llvm/llvm-project.git 4df364bc93af49ae413ec1ae8328f34ac70730c4)" + .ident "clang version 19.0.0git (git@github.com:llvm/llvm-project.git 53b14cd9ce2b57da73d173fc876d2e9e199f5640)" .section ".note.GNU-stack","",@progbits .addrsig .section .debug_line,"",@progbits diff --git a/lld/test/ELF/debug-names-dwarf64.s b/lld/test/ELF/debug-names-dwarf64.s index 515ea67945e61..310e9379bf9ae 100644 --- a/lld/test/ELF/debug-names-dwarf64.s +++ b/lld/test/ELF/debug-names-dwarf64.s @@ -1,8 +1,8 @@ # This file was generated by: -# clang++ -g -O0 -S -fdebug-compilation-dir='debug-names-test' \ -# -gdwarf64 -gpubnames main.cpp +# clang++ -g -O0 -S -fdebug-compilation-dir='/proc/self/cwd' \ +# -gdwarf64 -gpubnames a.cpp -# Contents of main.cpp +# Contents of a.cpp # int main (int argc, char **argv) { } # REQUIRES: x86 @@ -59,21 +59,21 @@ main: # @main .Lstr_offsets_base0: .section .debug_str,"MS",@progbits,1 .Linfo_string0: - .asciz "clang version 19.0.0git (git@github.com:llvm/llvm-project.git 9b37e60051f362e8e22c88785239fd5dfbfdf105)" # string offset=0 + .asciz "clang version 19.0.0git (git@github.com:llvm/llvm-project.git 53b14cd9ce2b57da73d173fc876d2e9e199f5640)" # string offset=0 .Linfo_string1: - .asciz "main.cpp" # string offset=104 + .asciz "a.cpp" # string offset=104 .Linfo_string2: - .asciz "debug-names-test" # string offset=113 + .asciz "/proc/self/cwd" # string offset=110 .Linfo_string3: - .asciz "main" # string offset=130 + .asciz "main" # string offset=125 .Linfo_string4: - .asciz "int" # string offset=135 + .asciz "int" # string offset=130 .Linfo_string5: - .asciz "argc" # string offset=139 + .asciz "argc" # string offset=134 .Linfo_string6: - .asciz "argv" # string offset=144 + .asciz "argv" # string offset=139 .Linfo_string7: - .asciz "char" # string offset=149 + .asciz "char" # string offset=144 .Laddr_table_base0: .quad .Lfunc_begin0 .Ldebug_addr_end0: @@ -144,7 +144,7 @@ main: # @main # End of list: char .p2align 2, 0x0 .Lnames_end0: - .ident "clang version 19.0.0git (git@github.com:llvm/llvm-project.git 9b37e60051f362e8e22c88785239fd5dfbfdf105)" + .ident "clang version 19.0.0git (git@github.com:llvm/llvm-project.git 53b14cd9ce2b57da73d173fc876d2e9e199f5640)" .section ".note.GNU-stack","",@progbits .addrsig .section .debug_line,"",@progbits diff --git a/lld/test/ELF/debug-names-invalid-abbrev-code.s b/lld/test/ELF/debug-names-invalid-abbrev-code.s index 65d7f50f02d37..5290eb86e276d 100644 --- a/lld/test/ELF/debug-names-invalid-abbrev-code.s +++ b/lld/test/ELF/debug-names-invalid-abbrev-code.s @@ -1,10 +1,9 @@ # This file was generated by: -# clang++ -g -O0 -S -fdebug-compilation-dir='debug-names-test' \ -# -gpubnames main.cpp +# clang++ -g -O0 -S -fdebug-compilation-dir='/proc/self/cwd' -gpubnames a.cpp # Then manually changing an abbrev code. -# Contents of main.cpp +# Contents of a.cpp # int main (int argc, char **argv) { } # REQUIRES: x86 @@ -59,21 +58,21 @@ main: # @main .Lstr_offsets_base0: .section .debug_str,"MS",@progbits,1 .Linfo_string0: - .asciz "clang version 19.0.0git (git@github.com:llvm/llvm-project.git d33d5630b281debe6eabd67e323bcf767340fb6a)" # string offset=0 + .asciz "clang version 19.0.0git (git@github.com:llvm/llvm-project.git 53b14cd9ce2b57da73d173fc876d2e9e199f5640)" # string offset=0 .Linfo_string1: - .asciz "main.cpp" # string offset=104 + .asciz "a.cpp" # string offset=104 .Linfo_string2: - .asciz "debug-names-test" # string offset=113 + .asciz "/proc/self/cwd" # string offset=110 .Linfo_string3: - .asciz "main" # string offset=130 + .asciz "main" # string offset=125 .Linfo_string4: - .asciz "int" # string offset=135 + .asciz "int" # string offset=130 .Linfo_string5: - .asciz "argc" # string offset=139 + .asciz "argc" # string offset=134 .Linfo_string6: - .asciz "argv" # string offset=144 + .asciz "argv" # string offset=139 .Linfo_string7: - .asciz "char" # string offset=149 + .asciz "char" # string offset=144 .Laddr_table_base0: .quad .Lfunc_begin0 .Ldebug_addr_end0: @@ -143,7 +142,7 @@ main: # @main # End of list: char .p2align 2, 0x0 .Lnames_end0: - .ident "clang version 19.0.0git (git@github.com:llvm/llvm-project.git d33d5630b281debe6eabd67e323bcf767340fb6a)" + .ident "clang version 19.0.0git (git@github.com:llvm/llvm-project.git 53b14cd9ce2b57da73d173fc876d2e9e199f5640)" .section ".note.GNU-stack","",@progbits .addrsig .section .debug_line,"",@progbits diff --git a/lld/test/ELF/debug-names-invalid-attribute-2.s b/lld/test/ELF/debug-names-invalid-attribute-2.s index fbed524ef29f8..6ea8c5e1e3f69 100644 --- a/lld/test/ELF/debug-names-invalid-attribute-2.s +++ b/lld/test/ELF/debug-names-invalid-attribute-2.s @@ -1,11 +1,10 @@ # This file was generated by: -# clang++ -g -O0 -S -fdebug-compilation-dir='debug-names-test' \ -# -gpubnames main.cpp +# clang++ -g -O0 -S -fdebug-compilation-dir='/proc/self/cwd' -gpubnames a.cpp # Then manually editing .debug_names section, commenting out a # DW_IDX_die_offset in an entry. -# Contents of main.cpp +# Contents of a.cpp # int main (int argc, char **argv) { } # REQUIRES: x86 @@ -60,21 +59,21 @@ main: # @main .Lstr_offsets_base0: .section .debug_str,"MS",@progbits,1 .Linfo_string0: - .asciz "clang version 19.0.0git (git@github.com:llvm/llvm-project.git d33d5630b281debe6eabd67e323bcf767340fb6a)" # string offset=0 + .asciz "clang version 19.0.0git (git@github.com:llvm/llvm-project.git 53b14cd9ce2b57da73d173fc876d2e9e199f5640)" # string offset=0 .Linfo_string1: - .asciz "main.cpp" # string offset=104 + .asciz "a.cpp" # string offset=104 .Linfo_string2: - .asciz "debug-names-test" # string offset=113 + .asciz "/proc/self/cwd" # string offset=110 .Linfo_string3: - .asciz "main" # string offset=130 + .asciz "main" # string offset=125 .Linfo_string4: - .asciz "int" # string offset=135 + .asciz "int" # string offset=130 .Linfo_string5: - .asciz "argc" # string offset=139 + .asciz "argc" # string offset=134 .Linfo_string6: - .asciz "argv" # string offset=144 + .asciz "argv" # string offset=139 .Linfo_string7: - .asciz "char" # string offset=149 + .asciz "char" # string offset=144 .Laddr_table_base0: .quad .Lfunc_begin0 .Ldebug_addr_end0: @@ -143,7 +142,7 @@ main: # @main # End of list: char .p2align 2, 0x0 .Lnames_end0: - .ident "clang version 19.0.0git (git@github.com:llvm/llvm-project.git d33d5630b281debe6eabd67e323bcf767340fb6a)" + .ident "clang version 19.0.0git (git@github.com:llvm/llvm-project.git 53b14cd9ce2b57da73d173fc876d2e9e199f5640)" .section ".note.GNU-stack","",@progbits .addrsig .section .debug_line,"",@progbits diff --git a/lld/test/ELF/debug-names-invalid-attribute-3.s b/lld/test/ELF/debug-names-invalid-attribute-3.s index 465f0a92064b4..1674498df7e30 100644 --- a/lld/test/ELF/debug-names-invalid-attribute-3.s +++ b/lld/test/ELF/debug-names-invalid-attribute-3.s @@ -1,13 +1,12 @@ # This file was generated by: -# clang++ -g -O0 -S -fdebug-compilation-dir='debug-names-test' \ -# -gpubnames main.cpp +# clang++ -g -O0 -S -fdebug-compilation-dir='/proc/self/cwd' -gpubnames a.cpp # Then manually changing the first .debug_names abbrev, so that the # DW_IDX_die_offset uses DW_FORM_flag_present (invalid) & the DW_IDX_parent # uses DW_FORM_ref4. Also updated the sizes of the values in the entry # that uses the abbrev, to match the sizes of the forms. -# Contents of main.cpp +# Contents of a.cpp # int main (int argc, char **argv) { } # REQUIRES: x86 @@ -62,21 +61,21 @@ main: # @main .Lstr_offsets_base0: .section .debug_str,"MS",@progbits,1 .Linfo_string0: - .asciz "clang version 19.0.0git (git@github.com:llvm/llvm-project.git d33d5630b281debe6eabd67e323bcf767340fb6a)" # string offset=0 + .asciz "clang version 19.0.0git (git@github.com:llvm/llvm-project.git 53b14cd9ce2b57da73d173fc876d2e9e199f5640)" # string offset=0 .Linfo_string1: - .asciz "main.cpp" # string offset=104 + .asciz "a.cpp" # string offset=104 .Linfo_string2: - .asciz "debug-names-test" # string offset=113 + .asciz "/proc/self/cwd" # string offset=110 .Linfo_string3: - .asciz "main" # string offset=130 + .asciz "main" # string offset=125 .Linfo_string4: - .asciz "int" # string offset=135 + .asciz "int" # string offset=130 .Linfo_string5: - .asciz "argc" # string offset=139 + .asciz "argc" # string offset=134 .Linfo_string6: - .asciz "argv" # string offset=144 + .asciz "argv" # string offset=139 .Linfo_string7: - .asciz "char" # string offset=149 + .asciz "char" # string offset=144 .Laddr_table_base0: .quad .Lfunc_begin0 .Ldebug_addr_end0: @@ -146,7 +145,7 @@ main: # @main # End of list: char .p2align 2, 0x0 .Lnames_end0: - .ident "clang version 19.0.0git (git@github.com:llvm/llvm-project.git d33d5630b281debe6eabd67e323bcf767340fb6a)" + .ident "clang version 19.0.0git (git@github.com:llvm/llvm-project.git 53b14cd9ce2b57da73d173fc876d2e9e199f5640)" .section ".note.GNU-stack","",@progbits .addrsig .section .debug_line,"",@progbits diff --git a/lld/test/ELF/debug-names-invalid-attribute.s b/lld/test/ELF/debug-names-invalid-attribute.s index 19de19c313bcf..52b9c6f7ade95 100644 --- a/lld/test/ELF/debug-names-invalid-attribute.s +++ b/lld/test/ELF/debug-names-invalid-attribute.s @@ -1,4 +1,4 @@ -# Generated by copying debug-names.s and manually editing it to make some +# Generated by copying a.s from debug-names.s and manually editing it to make some # of the abbrev attributes invalid. # REQUIRES: x86 @@ -50,17 +50,17 @@ _Z2f12t1: # @_Z2f12t1 .Lstr_offsets_base0: .section .debug_str,"MS",@progbits,1 .Linfo_string0: - .asciz "clang version 19.0.0git (git@github.com:llvm/llvm-project.git 4df364bc93af49ae413ec1ae8328f34ac70730c4)" # string offset=0 + .asciz "clang version 19.0.0git (git@github.com:llvm/llvm-project.git 53b14cd9ce2b57da73d173fc876d2e9e199f5640)" # string offset=0 .Linfo_string1: - .asciz "debug-names.cpp" # string offset=104 + .asciz "a.cpp" # string offset=104 .Linfo_string2: - .asciz "debug-names-test" # string offset=120 + .asciz "/proc/self/cwd" # string offset=110 .Linfo_string3: - .asciz "f1" # string offset=137 + .asciz "f1" # string offset=125 .Linfo_string4: - .asciz "_Z2f12t1" # string offset=140 + .asciz "_Z2f12t1" # string offset=128 .Linfo_string5: - .asciz "t1" # string offset=149 + .asciz "t1" # string offset=137 .Laddr_table_base0: .quad .Lfunc_begin0 .Ldebug_addr_end0: @@ -137,7 +137,7 @@ _Z2f12t1: # @_Z2f12t1 # End of list: _Z2f12t1 .p2align 2, 0x0 .Lnames_end0: - .ident "clang version 19.0.0git (git@github.com:llvm/llvm-project.git 4df364bc93af49ae413ec1ae8328f34ac70730c4)" + .ident "clang version 19.0.0git (git@github.com:llvm/llvm-project.git 53b14cd9ce2b57da73d173fc876d2e9e199f5640)" .section ".note.GNU-stack","",@progbits .addrsig .section .debug_line,"",@progbits diff --git a/lld/test/ELF/debug-names-invalid-parent-idx.s b/lld/test/ELF/debug-names-invalid-parent-idx.s index 01e62fb99586a..5db11ee10b32e 100644 --- a/lld/test/ELF/debug-names-invalid-parent-idx.s +++ b/lld/test/ELF/debug-names-invalid-parent-idx.s @@ -1,11 +1,11 @@ # This file was generated by: -# clang++ -g -O0 -S -fdebug-compilation-dir='debug-names-test' \ -# -gpubnames main.cpp +# clang++ -g -O0 -S -fdebug-compilation-dir='/proc/self/cwd' \ +# -gpubnames a.cpp # Then manually editing .debug_names section, changing the form for a # DW_IDX_parent from DW_FORM_flag_present to DW_FORM_ref1 (invalid). -# Contents of main.cpp +# Contents of a.cpp # int main (int argc, char **argv) { } # REQUIRES: x86 @@ -22,6 +22,7 @@ .type main,@function main: # @main .Lfunc_begin0: + .file 0 "/proc/self/cwd" "a.cpp" md5 0xb5f4ba9cf33ca376f9981b3284aa785f .cfi_startproc # %bb.0: # %entry pushq %rbp @@ -61,21 +62,21 @@ main: # @main .Lstr_offsets_base0: .section .debug_str,"MS",@progbits,1 .Linfo_string0: - .asciz "clang version 19.0.0git (git@github.com:llvm/llvm-project.git d33d5630b281debe6eabd67e323bcf767340fb6a)" # string offset=0 + .asciz "clang version 19.0.0git (git@github.com:llvm/llvm-project.git 53b14cd9ce2b57da73d173fc876d2e9e199f5640)" # string offset=0 .Linfo_string1: - .asciz "main.cpp" # string offset=104 + .asciz "a.cpp" # string offset=104 .Linfo_string2: - .asciz "debug-names-test" # string offset=113 + .asciz "/proc/self/cwd" # string offset=110 .Linfo_string3: - .asciz "main" # string offset=130 + .asciz "main" # string offset=125 .Linfo_string4: - .asciz "int" # string offset=135 + .asciz "int" # string offset=130 .Linfo_string5: - .asciz "argc" # string offset=139 + .asciz "argc" # string offset=134 .Linfo_string6: - .asciz "argv" # string offset=144 + .asciz "argv" # string offset=139 .Linfo_string7: - .asciz "char" # string offset=149 + .asciz "char" # string offset=144 .Laddr_table_base0: .quad .Lfunc_begin0 .Ldebug_addr_end0: @@ -145,7 +146,7 @@ main: # @main # End of list: char .p2align 2, 0x0 .Lnames_end0: - .ident "clang version 19.0.0git (git@github.com:llvm/llvm-project.git d33d5630b281debe6eabd67e323bcf767340fb6a)" + .ident "clang version 19.0.0git (git@github.com:llvm/llvm-project.git 53b14cd9ce2b57da73d173fc876d2e9e199f5640)" .section ".note.GNU-stack","",@progbits .addrsig .section .debug_line,"",@progbits diff --git a/lld/test/ELF/debug-names-missing-parent.s b/lld/test/ELF/debug-names-missing-parent.s index 5c7e0ad839a00..480d047504934 100644 --- a/lld/test/ELF/debug-names-missing-parent.s +++ b/lld/test/ELF/debug-names-missing-parent.s @@ -1,6 +1,6 @@ # debug-names-missing-parent was generated with -# clang++ -g -O0 -S -fdebug-compilation-dir='debug-names-test' \ +# clang++ -g -O0 -S -fdebug-compilation-dir='/proc/self/cwd' \ # -gpubnames a.cpp # a.cpp contents: @@ -47,7 +47,7 @@ # DWARF-NEXT: Bucket 1 [ # DWARF-NEXT: Name 1 { # DWARF-NEXT: Hash: 0x7C9A7F6A -# DWARF-NEXT: String: 0x0000007f "main" +# DWARF-NEXT: String: 0x0000007d "main" # DWARF-NEXT: Entry @ 0x7a { # DWARF-NEXT: Abbrev: 0x2 # DWARF-NEXT: Tag: DW_TAG_subprogram @@ -66,7 +66,7 @@ # DWARF-NEXT: Bucket 2 [ # DWARF-NEXT: Name 2 { # DWARF-NEXT: Hash: 0xB888030 -# DWARF-NEXT: String: 0x00000084 "int" +# DWARF-NEXT: String: 0x00000082 "int" # DWARF-NEXT: Entry @ 0x73 { # DWARF-NEXT: Abbrev: 0x1 # DWARF-NEXT: Tag: DW_TAG_base_type @@ -77,7 +77,7 @@ # DWARF-NEXT: } # DWARF-NEXT: Name 3 { # DWARF-NEXT: Hash: 0x7C952063 -# DWARF-NEXT: String: 0x00000092 "char" +# DWARF-NEXT: String: 0x0000008b "char" # DWARF-NEXT: Entry @ 0x87 { # DWARF-NEXT: Abbrev: 0x1 # DWARF-NEXT: Tag: DW_TAG_base_type @@ -139,17 +139,18 @@ main: # @main .Linfo_string1: .asciz "a.cpp" # string offset=104 .Linfo_string2: - .asciz "debug-names-test" # string offset=110 + .asciz "/proc/self/cwd" # string offset=110 .Linfo_string3: - .asciz "main" # string offset=127 + .asciz "main" # string offset=125 .Linfo_string4: - .asciz "int" # string offset=132 + .asciz "int" # string offset=130 .Linfo_string5: - .asciz "argc" # string offset=136 + .asciz "argc" # string offset=134 .Linfo_string6: - .asciz "argv" # string offset=141 + .asciz "argv" # string offset=139 .Linfo_string7: - .asciz "char" # string offset=146 + .asciz "char" # string offset=144 + .section .debug_str_offsets,"",@progbits .Laddr_table_base0: .quad .Lfunc_begin0 .Ldebug_addr_end0: diff --git a/lld/test/ELF/debug-names-parent-idx.s b/lld/test/ELF/debug-names-parent-idx.s index 22e382e45c9a1..64551aa02e59f 100644 --- a/lld/test/ELF/debug-names-parent-idx.s +++ b/lld/test/ELF/debug-names-parent-idx.s @@ -1,7 +1,7 @@ # debug-names-parent-idx.s generated with: -# - clang++ -g -O0 -gpubnames -fdebug-compilation-dir='parent-idx-test' \ -# -S debug-names-parent-idx.cpp -o debug-names-parent-idx.s +# clang++ -g -O0 -gpubnames -fdebug-compilation-dir='/proc/self/cwd' -S \ +# a.cpp -o a.s # foo.h contents: @@ -17,7 +17,7 @@ # int foo(); # } -# debug-names-parent-idx.cpp contents: +# a.cpp contents: # #include "foo.h" # void bar (struct foo &foo, int junk) { @@ -36,14 +36,11 @@ # REQUIRES: x86 # RUN: rm -rf %t && split-file %s %t && cd %t -# RUN: llvm-mc -filetype=obj -triple=x86_64 debug-names-parent-idx.s \ -# RUN: -o debug-names-parent-idx.o -# RUN: llvm-mc -filetype=obj -triple=x86_64 debug-names-parent-idx-2.s \ -# RUN: -o debug-names-parent-idx-2.o -# RUN: ld.lld --debug-names debug-names-parent-idx.o \ -# RUN: debug-names-parent-idx-2.o -o debug-names-parent-idx +# RUN: llvm-mc -filetype=obj -triple=x86_64 a.s -o a.o +# RUN: llvm-mc -filetype=obj -triple=x86_64 b.s -o b.o +# RUN: ld.lld --debug-names a.o b.o -o out -# RUN: llvm-dwarfdump -debug-names debug-names-parent-idx | FileCheck %s --check-prefix=DWARF +# RUN: llvm-dwarfdump -debug-names out | FileCheck %s --check-prefix=DWARF # DWARF: .debug_names contents: # DWARF: Name Index @ 0x0 { @@ -93,7 +90,7 @@ # DWARF-NEXT: Bucket 1 [ # DWARF-NEXT: Name 1 { # DWARF-NEXT: Hash: 0xA974AA29 -# DWARF-NEXT: String: 0x000001a2 "_ZN11parent_test3fooEv" +# DWARF-NEXT: String: 0x00000174 "_ZN11parent_test3fooEv" # DWARF-NEXT: Entry @ 0x14a { # DWARF-NEXT: Abbrev: 0x4 # DWARF-NEXT: Tag: DW_TAG_subprogram @@ -104,7 +101,7 @@ # DWARF-NEXT: } # DWARF-NEXT: Name 2 { # DWARF-NEXT: Hash: 0xB5063D0B -# DWARF-NEXT: String: 0x0000018e "_Z3foov" +# DWARF-NEXT: String: 0x00000160 "_Z3foov" # DWARF-NEXT: Entry @ 0x155 { # DWARF-NEXT: Abbrev: 0x2 # DWARF-NEXT: Tag: DW_TAG_subprogram @@ -117,7 +114,7 @@ # DWARF-NEXT: Bucket 2 [ # DWARF-NEXT: Name 3 { # DWARF-NEXT: Hash: 0xB888030 -# DWARF-NEXT: String: 0x000000a9 "int" +# DWARF-NEXT: String: 0x00000093 "int" # DWARF-NEXT: Entry @ 0xfe { # DWARF-NEXT: Abbrev: 0x1 # DWARF-NEXT: Tag: DW_TAG_base_type @@ -137,7 +134,7 @@ # DWARF-NEXT: Bucket 3 [ # DWARF-NEXT: Name 4 { # DWARF-NEXT: Hash: 0xB8860BA -# DWARF-NEXT: String: 0x00000093 "bar" +# DWARF-NEXT: String: 0x0000007d "bar" # DWARF-NEXT: Entry @ 0xf7 { # DWARF-NEXT: Abbrev: 0x2 # DWARF-NEXT: Tag: DW_TAG_subprogram @@ -148,7 +145,7 @@ # DWARF-NEXT: } # DWARF-NEXT: Name 5 { # DWARF-NEXT: Hash: 0xB887389 -# DWARF-NEXT: String: 0x000000ad "foo" +# DWARF-NEXT: String: 0x00000097 "foo" # DWARF-NEXT: Entry @ 0x10b { # DWARF-NEXT: Abbrev: 0x3 # DWARF-NEXT: Tag: DW_TAG_structure_type @@ -191,7 +188,7 @@ # DWARF-NEXT: Bucket 7 [ # DWARF-NEXT: Name 6 { # DWARF-NEXT: Hash: 0x7C9A7F6A -# DWARF-NEXT: String: 0x000000a4 "main" +# DWARF-NEXT: String: 0x0000008e "main" # DWARF-NEXT: Entry @ 0x136 { # DWARF-NEXT: Abbrev: 0x2 # DWARF-NEXT: Tag: DW_TAG_subprogram @@ -204,7 +201,7 @@ # DWARF-NEXT: Bucket 8 [ # DWARF-NEXT: Name 7 { # DWARF-NEXT: Hash: 0xA7255AE -# DWARF-NEXT: String: 0x00000196 "parent_test" +# DWARF-NEXT: String: 0x00000168 "parent_test" # DWARF-NEXT: Entry @ 0x128 { # DWARF-NEXT: Abbrev: 0x5 # DWARF-NEXT: Tag: DW_TAG_namespace @@ -215,7 +212,7 @@ # DWARF-NEXT: } # DWARF-NEXT: Name 8 { # DWARF-NEXT: Hash: 0x51007E98 -# DWARF-NEXT: String: 0x00000097 "_Z3barR3fooi" +# DWARF-NEXT: String: 0x00000081 "_Z3barR3fooi" # DWARF-NEXT: Entry @ 0x12f { # DWARF-NEXT: Abbrev: 0x2 # DWARF-NEXT: Tag: DW_TAG_subprogram @@ -226,7 +223,7 @@ # DWARF-NEXT: } # DWARF-NEXT: Name 9 { # DWARF-NEXT: Hash: 0x7C952063 -# DWARF-NEXT: String: 0x000000b5 "char" +# DWARF-NEXT: String: 0x0000009f "char" # DWARF-NEXT: Entry @ 0x13d { # DWARF-NEXT: Abbrev: 0x1 # DWARF-NEXT: Tag: DW_TAG_base_type @@ -244,7 +241,7 @@ # DWARF-NEXT: } # DWARF-NEXT: ] -#--- debug-names-parent-idx.s +#--- a.s .text .globl _Z3barR3fooi # -- Begin function _Z3barR3fooi .p2align 4, 0x90 @@ -331,39 +328,39 @@ main: # @main .Lstr_offsets_base0: .section .debug_str,"MS",@progbits,1 .Linfo_string0: - .asciz "clang version 19.0.0git (git@github.com:llvm/llvm-project.git 4df364bc93af49ae413ec1ae8328f34ac70730c4)" # string offset=0 + .asciz "clang version 19.0.0git (git@github.com:llvm/llvm-project.git 53b14cd9ce2b57da73d173fc876d2e9e199f5640)" # string offset=0 .Linfo_string1: - .asciz "debug-names-parent-idx.cpp" # string offset=104 + .asciz "a.cpp" # string offset=104 .Linfo_string2: - .asciz "parent-idx-test" # string offset=131 + .asciz "/proc/self/cwd" # string offset=110 .Linfo_string3: - .asciz "bar" # string offset=147 + .asciz "bar" # string offset=125 .Linfo_string4: - .asciz "_Z3barR3fooi" # string offset=151 + .asciz "_Z3barR3fooi" # string offset=129 .Linfo_string5: - .asciz "main" # string offset=164 + .asciz "main" # string offset=142 .Linfo_string6: - .asciz "int" # string offset=169 + .asciz "int" # string offset=147 .Linfo_string7: - .asciz "foo" # string offset=173 + .asciz "foo" # string offset=151 .Linfo_string8: - .asciz "x" # string offset=177 + .asciz "x" # string offset=155 .Linfo_string9: - .asciz "y" # string offset=179 + .asciz "y" # string offset=157 .Linfo_string10: - .asciz "char" # string offset=181 + .asciz "char" # string offset=159 .Linfo_string11: - .asciz "foo_ptr" # string offset=186 + .asciz "foo_ptr" # string offset=164 .Linfo_string12: - .asciz "junk" # string offset=194 + .asciz "junk" # string offset=172 .Linfo_string13: - .asciz "argc" # string offset=199 + .asciz "argc" # string offset=177 .Linfo_string14: - .asciz "argv" # string offset=204 + .asciz "argv" # string offset=182 .Linfo_string15: - .asciz "my_struct" # string offset=209 + .asciz "my_struct" # string offset=187 .Linfo_string16: - .asciz "junk2" # string offset=219 + .asciz "junk2" # string offset=197 .Laddr_table_base0: .quad .Lfunc_begin0 .quad .Lfunc_begin1 @@ -471,7 +468,7 @@ main: # @main # End of list: char .p2align 2, 0x0 .Lnames_end0: - .ident "clang version 19.0.0git (git@github.com:llvm/llvm-project.git 4df364bc93af49ae413ec1ae8328f34ac70730c4)" + .ident "clang version 19.0.0git (git@github.com:llvm/llvm-project.git 53b14cd9ce2b57da73d173fc876d2e9e199f5640)" .section ".note.GNU-stack","",@progbits .addrsig .addrsig_sym _Z3barR3fooi @@ -480,11 +477,11 @@ main: # @main .section .debug_line,"",@progbits .Lline_table_start0: -#--- debug-names-parent-idx-2.s +#--- b.s # Generated with: -# - clang++ -g -O0 -gpubnames -fdebug-compilation-dir='parent-idx-test' \ -# -S debug-names-parent-idx-2.cpp -o debug-names-parent-idx-2.s +# clang++ -g -O0 -gpubnames -fdebug-compilation-dir='/proc/self/cwd' -S \ +# b.cpp -o b.s # foo.h contents: @@ -500,7 +497,7 @@ main: # @main # int foo(); # } -# debug-names-parent-index-2.cpp contents: +# b.cpp contents: # #include "foo.h" # int foo () { @@ -587,31 +584,31 @@ _ZN11parent_test3fooEv: # @_ZN11parent_test3fooEv .Lstr_offsets_base0: .section .debug_str,"MS",@progbits,1 .Linfo_string0: - .asciz "clang version 19.0.0git (git@github.com:llvm/llvm-project.git 4df364bc93af49ae413ec1ae8328f34ac70730c4)" # string offset=0 + .asciz "clang version 19.0.0git (git@github.com:llvm/llvm-project.git 53b14cd9ce2b57da73d173fc876d2e9e199f5640)" # string offset=0 .Linfo_string1: - .asciz "debug-names-parent-idx-2.cpp" # string offset=104 + .asciz "b.cpp" # string offset=104 .Linfo_string2: - .asciz "parent-idx-test" # string offset=133 + .asciz "/proc/self/cwd" # string offset=110 .Linfo_string3: - .asciz "int" # string offset=149 + .asciz "int" # string offset=125 .Linfo_string4: - .asciz "foo" # string offset=153 + .asciz "foo" # string offset=129 .Linfo_string5: - .asciz "_Z3foov" # string offset=157 + .asciz "_Z3foov" # string offset=133 .Linfo_string6: - .asciz "parent_test" # string offset=165 + .asciz "parent_test" # string offset=141 .Linfo_string7: - .asciz "_ZN11parent_test3fooEv" # string offset=177 + .asciz "_ZN11parent_test3fooEv" # string offset=153 .Linfo_string8: - .asciz "struct2" # string offset=200 + .asciz "struct2" # string offset=176 .Linfo_string9: - .asciz "x" # string offset=208 + .asciz "x" # string offset=184 .Linfo_string10: - .asciz "y" # string offset=210 + .asciz "y" # string offset=186 .Linfo_string11: - .asciz "char" # string offset=212 + .asciz "char" # string offset=188 .Linfo_string12: - .asciz "foo_ptr" # string offset=217 + .asciz "foo_ptr" # string offset=193 .Laddr_table_base0: .quad .Lfunc_begin0 .quad .Lfunc_begin1 @@ -742,7 +739,7 @@ _ZN11parent_test3fooEv: # @_ZN11parent_test3fooEv # End of list: char .p2align 2, 0x0 .Lnames_end0: - .ident "clang version 19.0.0git (git@github.com:llvm/llvm-project.git 4df364bc93af49ae413ec1ae8328f34ac70730c4)" + .ident "clang version 19.0.0git (git@github.com:llvm/llvm-project.git 53b14cd9ce2b57da73d173fc876d2e9e199f5640)" .section ".note.GNU-stack","",@progbits .addrsig .section .debug_line,"",@progbits diff --git a/lld/test/ELF/debug-names.s b/lld/test/ELF/debug-names.s index eb35281a224f0..4ca2cb1eabefa 100644 --- a/lld/test/ELF/debug-names.s +++ b/lld/test/ELF/debug-names.s @@ -1,7 +1,7 @@ # debug-names.s was generated with: -# - clang++ -g -O0 -gpubnames -fdebug-compilation-dir='debug-names-test' \ -# -S a.cpp -o a.s +# - clang++ -g -O0 -gpubnames -fdebug-compilation-dir='/proc/self/cwd' \ +# -S a.cpp -o a.s # a.cpp contents: @@ -65,7 +65,7 @@ # DWARF-NEXT: Bucket 1 [ # DWARF-NEXT: Name 1 { # DWARF-NEXT: Hash: 0x59796A -# DWARF-NEXT: String: 0x0000008b "t1" +# DWARF-NEXT: String: 0x00000089 "t1" # DWARF-NEXT: Entry @ 0xaa { # DWARF-NEXT: Abbrev: 0x1 # DWARF-NEXT: Tag: DW_TAG_structure_type @@ -83,7 +83,7 @@ # DWARF-NEXT: } # DWARF-NEXT: Name 2 { # DWARF-NEXT: Hash: 0x5355B2BE -# DWARF-NEXT: String: 0x00000082 "_Z2f12t1" +# DWARF-NEXT: String: 0x00000080 "_Z2f12t1" # DWARF-NEXT: Entry @ 0xbe { # DWARF-NEXT: Abbrev: 0x2 # DWARF-NEXT: Tag: DW_TAG_subprogram @@ -94,7 +94,7 @@ # DWARF-NEXT: } # DWARF-NEXT: Name 3 { # DWARF-NEXT: Hash: 0x7C9A7F6A -# DWARF-NEXT: String: 0x00000115 "main" +# DWARF-NEXT: String: 0x00000111 "main" # DWARF-NEXT: Entry @ 0xc5 { # DWARF-NEXT: Abbrev: 0x2 # DWARF-NEXT: Tag: DW_TAG_subprogram @@ -110,7 +110,7 @@ # DWARF-NEXT: Bucket 3 [ # DWARF-NEXT: Name 4 { # DWARF-NEXT: Hash: 0xB888030 -# DWARF-NEXT: String: 0x0000011a "int" +# DWARF-NEXT: String: 0x00000116 "int" # DWARF-NEXT: Entry @ 0xb7 { # DWARF-NEXT: Abbrev: 0x3 # DWARF-NEXT: Tag: DW_TAG_base_type @@ -123,7 +123,7 @@ # DWARF-NEXT: Bucket 4 [ # DWARF-NEXT: Name 5 { # DWARF-NEXT: Hash: 0x59779C -# DWARF-NEXT: String: 0x0000007f "f1" +# DWARF-NEXT: String: 0x0000007d "f1" # DWARF-NEXT: Entry @ 0xa3 { # DWARF-NEXT: Abbrev: 0x2 # DWARF-NEXT: Tag: DW_TAG_subprogram @@ -181,13 +181,13 @@ _Z2f12t1: # @_Z2f12t1 .Linfo_string1: .asciz "a.cpp" # string offset=104 .Linfo_string2: - .asciz "debug-names-test" # string offset=110 + .asciz "/proc/self/cwd" # string offset=110 .Linfo_string3: - .asciz "f1" # string offset=127 + .asciz "f1" # string offset=125 .Linfo_string4: - .asciz "_Z2f12t1" # string offset=130 + .asciz "_Z2f12t1" # string offset=128 .Linfo_string5: - .asciz "t1" # string offset=139 + .asciz "t1" # string offset=137 .Laddr_table_base0: .quad .Lfunc_begin0 .Ldebug_addr_end0: @@ -264,7 +264,7 @@ _Z2f12t1: # @_Z2f12t1 #--- b.s # Generated with: -# - clang++ -g -O0 -gpubnames -fdebug-compilation-dir='debug-names-test' \ +# - clang++ -g -O0 -gpubnames -fdebug-compilation-dir='/proc/self/cwd' \ # -S b.cpp -o b.s # b.cpp contents: @@ -274,6 +274,7 @@ _Z2f12t1: # @_Z2f12t1 # t1 v1; # } # + .text .globl main # -- Begin function main .p2align 4, 0x90 @@ -321,15 +322,15 @@ main: # @main .Linfo_string1: .asciz "b.cpp" # string offset=104 .Linfo_string2: - .asciz "debug-names-test" # string offset=110 + .asciz "/proc/self/cwd" # string offset=110 .Linfo_string3: - .asciz "main" # string offset=127 + .asciz "main" # string offset=125 .Linfo_string4: - .asciz "int" # string offset=132 + .asciz "int" # string offset=130 .Linfo_string5: - .asciz "v1" # string offset=136 + .asciz "v1" # string offset=134 .Linfo_string6: - .asciz "t1" # string offset=139 + .asciz "t1" # string offset=137 .Laddr_table_base0: .quad .Lfunc_begin0 .Ldebug_addr_end0: diff --git a/lld/test/ELF/ppc32-debug-names.s b/lld/test/ELF/ppc32-debug-names.s index 40d7cc5b4fa2f..f091f961588d0 100644 --- a/lld/test/ELF/ppc32-debug-names.s +++ b/lld/test/ELF/ppc32-debug-names.s @@ -1,7 +1,7 @@ # ppc-debug-names.s was generated with: # - clang++ --target=powerpc -g -O0 -gpubnames \ -# -fdebug-compilation-dir='debug-names-test' -S a.cpp -o a.s +# -fdebug-compilation-dir='/self/proc/cwd' -S a.cpp -o a.s # a.cpp contents: @@ -66,7 +66,7 @@ # DWARF-NEXT: Bucket 1 [ # DWARF-NEXT: Name 1 { # DWARF-NEXT: Hash: 0x59796A -# DWARF-NEXT: String: 0x0000008b "t1" +# DWARF-NEXT: String: 0x00000089 "t1" # DWARF-NEXT: Entry @ 0xaa { # DWARF-NEXT: Abbrev: 0x1 # DWARF-NEXT: Tag: DW_TAG_structure_type @@ -84,7 +84,7 @@ # DWARF-NEXT: } # DWARF-NEXT: Name 2 { # DWARF-NEXT: Hash: 0x5355B2BE -# DWARF-NEXT: String: 0x00000082 "_Z2f12t1" +# DWARF-NEXT: String: 0x00000080 "_Z2f12t1" # DWARF-NEXT: Entry @ 0xbe { # DWARF-NEXT: Abbrev: 0x2 # DWARF-NEXT: Tag: DW_TAG_subprogram @@ -95,7 +95,7 @@ # DWARF-NEXT: } # DWARF-NEXT: Name 3 { # DWARF-NEXT: Hash: 0x7C9A7F6A -# DWARF-NEXT: String: 0x00000111 "main" +# DWARF-NEXT: String: 0x0000010d "main" # DWARF-NEXT: Entry @ 0xc5 { # DWARF-NEXT: Abbrev: 0x2 # DWARF-NEXT: Tag: DW_TAG_subprogram @@ -111,7 +111,7 @@ # DWARF-NEXT: Bucket 3 [ # DWARF-NEXT: Name 4 { # DWARF-NEXT: Hash: 0xB888030 -# DWARF-NEXT: String: 0x00000116 "int" +# DWARF-NEXT: String: 0x00000112 "int" # DWARF-NEXT: Entry @ 0xb7 { # DWARF-NEXT: Abbrev: 0x3 # DWARF-NEXT: Tag: DW_TAG_base_type @@ -124,7 +124,7 @@ # DWARF-NEXT: Bucket 4 [ # DWARF-NEXT: Name 5 { # DWARF-NEXT: Hash: 0x59779C -# DWARF-NEXT: String: 0x0000007f "f1" +# DWARF-NEXT: String: 0x0000007d "f1" # DWARF-NEXT: Entry @ 0xa3 { # DWARF-NEXT: Abbrev: 0x2 # DWARF-NEXT: Tag: DW_TAG_subprogram @@ -144,6 +144,7 @@ _Z2f12t1: # @_Z2f12t1 .Lfunc_begin0: .cfi_startproc # %bb.0: # %entry + #DEBUG_VALUE: f1: <- [$r3+0] stwu 1, -16(1) stw 31, 12(1) .cfi_def_cfa_offset 16 @@ -183,13 +184,13 @@ _Z2f12t1: # @_Z2f12t1 .Linfo_string1: .asciz "a.cpp" # string offset=104 .Linfo_string2: - .asciz "debug-names-test" # string offset=110 + .asciz "/proc/self/cwd" # string offset=110 .Linfo_string3: - .asciz "f1" # string offset=127 + .asciz "f1" # string offset=125 .Linfo_string4: - .asciz "_Z2f12t1" # string offset=130 + .asciz "_Z2f12t1" # string offset=128 .Linfo_string5: - .asciz "t1" # string offset=139 + .asciz "t1" # string offset=137 .Laddr_table_base0: .long .Lfunc_begin0 .Ldebug_addr_end0: @@ -267,7 +268,7 @@ _Z2f12t1: # @_Z2f12t1 #--- b.s # Generated with: # - clang++ --target=powerpc -g -O0 -gpubnames \ -# -fdebug-compilation-dir='debug-names-test' -S b.cpp -o b.s +# -fdebug-compilation-dir='/self/proc/cwd' -S b.cpp -o b.s # b.cpp contents: @@ -324,15 +325,15 @@ main: # @main .Linfo_string1: .asciz "b.cpp" # string offset=104 .Linfo_string2: - .asciz "debug-names-test" # string offset=110 + .asciz "/proc/self/cwd" # string offset=110 .Linfo_string3: - .asciz "main" # string offset=127 + .asciz "main" # string offset=125 .Linfo_string4: - .asciz "int" # string offset=132 + .asciz "int" # string offset=130 .Linfo_string5: - .asciz "v1" # string offset=136 + .asciz "v1" # string offset=134 .Linfo_string6: - .asciz "t1" # string offset=139 + .asciz "t1" # string offset=137 .Laddr_table_base0: .long .Lfunc_begin0 .Ldebug_addr_end0: From 3721df40d983e3a9ba8bdd35796e556001461290 Mon Sep 17 00:00:00 2001 From: Caroline Tice Date: Mon, 15 Apr 2024 00:54:03 -0700 Subject: [PATCH 20/37] [lld][ELF] Add test for CompUnit > 1 Add code to update CU offsets correctly when there are multiple CUs within one .o file. Also add test for this. --- lld/ELF/SyntheticSections.cpp | 34 ++ lld/ELF/SyntheticSections.h | 2 + lld/test/ELF/debug-names-multi-cus.s | 645 +++++++++++++++++++++++++++ 3 files changed, 681 insertions(+) create mode 100644 lld/test/ELF/debug-names-multi-cus.s diff --git a/lld/ELF/SyntheticSections.cpp b/lld/ELF/SyntheticSections.cpp index 910ace1c757b4..b69cc4cd967d5 100644 --- a/lld/ELF/SyntheticSections.cpp +++ b/lld/ELF/SyntheticSections.cpp @@ -3217,6 +3217,38 @@ template void DebugNamesSection::finalizeContents() { }); } +template +void DebugNamesSection::updateMultiCuOffsets(OutputChunk &chunk) { + // Find the .debug_info section data for this chunk. + auto *file = cast>(chunk.infoSec->file); + DWARFContext dwarf(std::make_unique>(file)); + auto &dobj = static_cast &>(dwarf.getDWARFObj()); + InputSection *infoSec = dobj.getInfoSection(); + auto infoData = toStringRef(infoSec->contentMaybeDecompress()); + const char *p = infoData.data(); + + // Skim through the CUs reading the unit lengths & types to find correct + // starting offsets for CUs (before relocation). + uint32_t nextCu = 0; + for (size_t i = 1, end = chunk.compUnits.size(); i < end; ++i) { + // First CU offset for each new (appended) .debug_names section starts at + // zero. + if (chunk.compUnits[i] == 0) { + // Skip to start of next CU and read the type & size. + p = infoData.data() + nextCu; + uint32_t unit_length = + endian::readNext(p); + [[maybe_unused]] uint16_t version = + endian::readNext(p); + uint8_t unitType = + endian::readNext(p); + if (unitType == dwarf::DW_UT_compile) + nextCu += unit_length + 4; + } + chunk.compUnits[i] += nextCu; + } +} + template void DebugNamesSection::writeTo(uint8_t *buf) { [[maybe_unused]] uint8_t *oldBuf = buf; // Write the header. @@ -3236,6 +3268,8 @@ template void DebugNamesSection::writeTo(uint8_t *buf) { // Write the CU list. for (auto i : seq(numChunks)) { OutputChunk &chunk = chunks[i]; + if (chunk.compUnits.size() > 1) + updateMultiCuOffsets(chunk); for (uint32_t cuOffset : chunk.compUnits) { endian::write32(buf, chunk.infoSec->outSecOff + cuOffset); diff --git a/lld/ELF/SyntheticSections.h b/lld/ELF/SyntheticSections.h index 534fac005e0b8..cbf16c4011388 100644 --- a/lld/ELF/SyntheticSections.h +++ b/lld/ELF/SyntheticSections.h @@ -910,6 +910,8 @@ class DebugNamesSection final : public DebugNamesBaseSection { void getNameRelocs(InputSection *sec, ArrayRef rels, llvm::DenseMap &relocs); + void updateMultiCuOffsets(OutputChunk &chunk); + private: static void readOffsets(InputChunk &inputChunk, OutputChunk &chunk, llvm::DWARFDataExtractor &namesExtractor, diff --git a/lld/test/ELF/debug-names-multi-cus.s b/lld/test/ELF/debug-names-multi-cus.s new file mode 100644 index 0000000000000..bc79a783f61dd --- /dev/null +++ b/lld/test/ELF/debug-names-multi-cus.s @@ -0,0 +1,645 @@ +# ab.s was generated by: + +# clang++ a.cpp -gpubnames a.cpp -g -emit-llvm -c \ +# -fdebug-compilation-dir='/proc/self/cwd +# clang++ b.cpp -gpubnames b.cpp -g -emit-llvm -c \ +# -fdebug-compilation-dir='/proc/self/cwd +# llvm-link a.bc b.bc -o ab.bc +# clang++ ab.bc -S -o ab.s + +# a.cpp contains: +# struct t1 { }; +# void f1(t1) { } + +# b.cpp contains: +# struct t1 { }; +# int main() { +# t1 v1; +# } + + +# REQUIRES: x86 +# RUN: rm -rf %t && split-file %s %t && cd %t +# RUN: llvm-mc -filetype=obj -triple=x86_64 ab.s -o ab.o +# RUN: llvm-mc -filetype=obj -triple=x86_64 c.s -o c.o +# RUN: ld.lld --debug-names ab.o c.o -o out +# RUN: llvm-dwarfdump --debug-names out \ +# RUN: | FileCheck -DFILE=a.o %s --check-prefix=DWARF + +# DWARF: Compilation Unit offsets [ +# DWARF-NEXT: CU[0]: 0x00000000 +# DWARF-NEXT: CU[1]: 0x00000041 +# DWARF-NEXT: CU[2]: 0x00000084 +# DWARF-NEXT: ] + +# RUN: ld.lld --debug-names c.o ab.o -o out2 +# RUN: llvm-dwarfdump --debug-names out2 \ +# RUN: | FileCheck -DFILE=a.o %s --check-prefix=DWARF2 + +# DWARF2: Compilation Unit offsets [ +# DWARF2-NEXT: CU[0]: 0x00000000 +# DWARF2-NEXT: CU[1]: 0x00000030 +# DWARF2-NEXT: CU[2]: 0x00000071 +# DWARF2-NEXT: ] + +#--- ab.s + .text + .globl _Z2f12t1 # -- Begin function _Z2f12t1 + .p2align 4, 0x90 + .type _Z2f12t1,@function +_Z2f12t1: # @_Z2f12t1 +.Lfunc_begin0: + .cfi_startproc +# %bb.0: # %entry + pushq %rbp + .cfi_def_cfa_offset 16 + .cfi_offset %rbp, -16 + movq %rsp, %rbp + .cfi_def_cfa_register %rbp +.Ltmp0: + popq %rbp + .cfi_def_cfa %rsp, 8 + retq +.Ltmp1: +.Lfunc_end0: + .size _Z2f12t1, .Lfunc_end0-_Z2f12t1 + .cfi_endproc + # -- End function + .globl main # -- Begin function main + .p2align 4, 0x90 + .type main,@function +main: # @main +.Lfunc_begin1: + .cfi_startproc +# %bb.0: # %entry + pushq %rbp + .cfi_def_cfa_offset 16 + .cfi_offset %rbp, -16 + movq %rsp, %rbp + .cfi_def_cfa_register %rbp +.Ltmp2: + xorl %eax, %eax + popq %rbp + .cfi_def_cfa %rsp, 8 + retq +.Ltmp3: +.Lfunc_end1: + .size main, .Lfunc_end1-main + .cfi_endproc + # -- End function + .section .debug_abbrev,"",@progbits + .byte 1 # Abbreviation Code + .byte 17 # DW_TAG_compile_unit + .byte 1 # DW_CHILDREN_yes + .byte 37 # DW_AT_producer + .byte 37 # DW_FORM_strx1 + .byte 19 # DW_AT_language + .byte 5 # DW_FORM_data2 + .byte 3 # DW_AT_name + .byte 37 # DW_FORM_strx1 + .byte 114 # DW_AT_str_offsets_base + .byte 23 # DW_FORM_sec_offset + .byte 16 # DW_AT_stmt_list + .byte 23 # DW_FORM_sec_offset + .byte 27 # DW_AT_comp_dir + .byte 37 # DW_FORM_strx1 + .byte 17 # DW_AT_low_pc + .byte 27 # DW_FORM_addrx + .byte 18 # DW_AT_high_pc + .byte 6 # DW_FORM_data4 + .byte 115 # DW_AT_addr_base + .byte 23 # DW_FORM_sec_offset + .byte 0 # EOM(1) + .byte 0 # EOM(2) + .byte 2 # Abbreviation Code + .byte 46 # DW_TAG_subprogram + .byte 1 # DW_CHILDREN_yes + .byte 17 # DW_AT_low_pc + .byte 27 # DW_FORM_addrx + .byte 18 # DW_AT_high_pc + .byte 6 # DW_FORM_data4 + .byte 64 # DW_AT_frame_base + .byte 24 # DW_FORM_exprloc + .byte 110 # DW_AT_linkage_name + .byte 37 # DW_FORM_strx1 + .byte 3 # DW_AT_name + .byte 37 # DW_FORM_strx1 + .byte 58 # DW_AT_decl_file + .byte 11 # DW_FORM_data1 + .byte 59 # DW_AT_decl_line + .byte 11 # DW_FORM_data1 + .byte 63 # DW_AT_external + .byte 25 # DW_FORM_flag_present + .byte 0 # EOM(1) + .byte 0 # EOM(2) + .byte 3 # Abbreviation Code + .byte 5 # DW_TAG_formal_parameter + .byte 0 # DW_CHILDREN_no + .byte 2 # DW_AT_location + .byte 24 # DW_FORM_exprloc + .byte 58 # DW_AT_decl_file + .byte 11 # DW_FORM_data1 + .byte 59 # DW_AT_decl_line + .byte 11 # DW_FORM_data1 + .byte 73 # DW_AT_type + .byte 19 # DW_FORM_ref4 + .byte 0 # EOM(1) + .byte 0 # EOM(2) + .byte 4 # Abbreviation Code + .byte 19 # DW_TAG_structure_type + .byte 0 # DW_CHILDREN_no + .byte 54 # DW_AT_calling_convention + .byte 11 # DW_FORM_data1 + .byte 3 # DW_AT_name + .byte 37 # DW_FORM_strx1 + .byte 11 # DW_AT_byte_size + .byte 11 # DW_FORM_data1 + .byte 58 # DW_AT_decl_file + .byte 11 # DW_FORM_data1 + .byte 59 # DW_AT_decl_line + .byte 11 # DW_FORM_data1 + .byte 0 # EOM(1) + .byte 0 # EOM(2) + .byte 5 # Abbreviation Code + .byte 46 # DW_TAG_subprogram + .byte 1 # DW_CHILDREN_yes + .byte 17 # DW_AT_low_pc + .byte 27 # DW_FORM_addrx + .byte 18 # DW_AT_high_pc + .byte 6 # DW_FORM_data4 + .byte 64 # DW_AT_frame_base + .byte 24 # DW_FORM_exprloc + .byte 3 # DW_AT_name + .byte 37 # DW_FORM_strx1 + .byte 58 # DW_AT_decl_file + .byte 11 # DW_FORM_data1 + .byte 59 # DW_AT_decl_line + .byte 11 # DW_FORM_data1 + .byte 73 # DW_AT_type + .byte 19 # DW_FORM_ref4 + .byte 63 # DW_AT_external + .byte 25 # DW_FORM_flag_present + .byte 0 # EOM(1) + .byte 0 # EOM(2) + .byte 6 # Abbreviation Code + .byte 52 # DW_TAG_variable + .byte 0 # DW_CHILDREN_no + .byte 2 # DW_AT_location + .byte 24 # DW_FORM_exprloc + .byte 3 # DW_AT_name + .byte 37 # DW_FORM_strx1 + .byte 58 # DW_AT_decl_file + .byte 11 # DW_FORM_data1 + .byte 59 # DW_AT_decl_line + .byte 11 # DW_FORM_data1 + .byte 73 # DW_AT_type + .byte 16 # DW_FORM_ref_addr + .byte 0 # EOM(1) + .byte 0 # EOM(2) + .byte 7 # Abbreviation Code + .byte 36 # DW_TAG_base_type + .byte 0 # DW_CHILDREN_no + .byte 3 # DW_AT_name + .byte 37 # DW_FORM_strx1 + .byte 62 # DW_AT_encoding + .byte 11 # DW_FORM_data1 + .byte 11 # DW_AT_byte_size + .byte 11 # DW_FORM_data1 + .byte 0 # EOM(1) + .byte 0 # EOM(2) + .byte 0 # EOM(3) + .section .debug_info,"",@progbits +.Lcu_begin0: + .long .Ldebug_info_end0-.Ldebug_info_start0 # Length of Unit +.Ldebug_info_start0: + .short 5 # DWARF version number + .byte 1 # DWARF Unit Type + .byte 8 # Address Size (in bytes) + .long .debug_abbrev # Offset Into Abbrev. Section + .byte 1 # Abbrev [1] 0xc:0x35 DW_TAG_compile_unit + .byte 0 # DW_AT_producer + .short 33 # DW_AT_language + .byte 1 # DW_AT_name + .long .Lstr_offsets_base0 # DW_AT_str_offsets_base + .long .Lline_table_start0 # DW_AT_stmt_list + .byte 2 # DW_AT_comp_dir + .byte 0 # DW_AT_low_pc + .long .Lfunc_end0-.Lfunc_begin0 # DW_AT_high_pc + .long .Laddr_table_base0 # DW_AT_addr_base + .byte 2 # Abbrev [2] 0x23:0x17 DW_TAG_subprogram + .byte 0 # DW_AT_low_pc + .long .Lfunc_end0-.Lfunc_begin0 # DW_AT_high_pc + .byte 1 # DW_AT_frame_base + .byte 86 + .byte 4 # DW_AT_linkage_name + .byte 5 # DW_AT_name + .byte 1 # DW_AT_decl_file + .byte 2 # DW_AT_decl_line + # DW_AT_external + .byte 3 # Abbrev [3] 0x2f:0xa DW_TAG_formal_parameter + .byte 2 # DW_AT_location + .byte 145 + .byte 127 + .byte 1 # DW_AT_decl_file + .byte 2 # DW_AT_decl_line + .long 58 # DW_AT_type + .byte 0 # End Of Children Mark + .byte 4 # Abbrev [4] 0x3a:0x6 DW_TAG_structure_type + .byte 5 # DW_AT_calling_convention + .byte 8 # DW_AT_name + .byte 1 # DW_AT_byte_size + .byte 1 # DW_AT_decl_file + .byte 1 # DW_AT_decl_line + .byte 0 # End Of Children Mark +.Ldebug_info_end0: +.Lcu_begin1: + .long .Ldebug_info_end1-.Ldebug_info_start1 # Length of Unit +.Ldebug_info_start1: + .short 5 # DWARF version number + .byte 1 # DWARF Unit Type + .byte 8 # Address Size (in bytes) + .long .debug_abbrev # Offset Into Abbrev. Section + .byte 1 # Abbrev [1] 0xc:0x37 DW_TAG_compile_unit + .byte 0 # DW_AT_producer + .short 33 # DW_AT_language + .byte 3 # DW_AT_name + .long .Lstr_offsets_base0 # DW_AT_str_offsets_base + .long .Lline_table_start0 # DW_AT_stmt_list + .byte 2 # DW_AT_comp_dir + .byte 1 # DW_AT_low_pc + .long .Lfunc_end1-.Lfunc_begin1 # DW_AT_high_pc + .long .Laddr_table_base0 # DW_AT_addr_base + .byte 5 # Abbrev [5] 0x23:0x1b DW_TAG_subprogram + .byte 1 # DW_AT_low_pc + .long .Lfunc_end1-.Lfunc_begin1 # DW_AT_high_pc + .byte 1 # DW_AT_frame_base + .byte 86 + .byte 6 # DW_AT_name + .byte 2 # DW_AT_decl_file + .byte 2 # DW_AT_decl_line + .long 62 # DW_AT_type + # DW_AT_external + .byte 6 # Abbrev [6] 0x32:0xb DW_TAG_variable + .byte 2 # DW_AT_location + .byte 145 + .byte 127 + .byte 9 # DW_AT_name + .byte 2 # DW_AT_decl_file + .byte 3 # DW_AT_decl_line + .long .debug_info+58 # DW_AT_type + .byte 0 # End Of Children Mark + .byte 7 # Abbrev [7] 0x3e:0x4 DW_TAG_base_type + .byte 7 # DW_AT_name + .byte 5 # DW_AT_encoding + .byte 4 # DW_AT_byte_size + .byte 0 # End Of Children Mark +.Ldebug_info_end1: + .section .debug_str_offsets,"",@progbits + .long 44 # Length of String Offsets Set + .short 5 + .short 0 +.Lstr_offsets_base0: + .section .debug_str,"MS",@progbits,1 +.Linfo_string0: + .asciz "clang version 19.0.0git (git@github.com:llvm/llvm-project.git 7607c4d40149128f848055613edf9c3cf9ae890d)" # string offset=0 +.Linfo_string1: + .asciz "a.cpp" # string offset=104 +.Linfo_string2: + .asciz "/proc/self/cwd" # string offset=110 +.Linfo_string3: + .asciz "f1" # string offset=125 +.Linfo_string4: + .asciz "_Z2f12t1" # string offset=128 +.Linfo_string5: + .asciz "b.cpp" # string offset=137 +.Linfo_string6: + .asciz "main" # string offset=143 +.Linfo_string7: + .asciz "int" # string offset=148 +.Linfo_string8: + .asciz "t1" # string offset=152 +.Linfo_string9: + .asciz "v1" # string offset=155 + .section .debug_str_offsets,"",@progbits + .long .Linfo_string0 + .long .Linfo_string1 + .long .Linfo_string2 + .long .Linfo_string5 + .long .Linfo_string4 + .long .Linfo_string3 + .long .Linfo_string6 + .long .Linfo_string7 + .long .Linfo_string8 + .long .Linfo_string9 + .section .debug_addr,"",@progbits + .long .Ldebug_addr_end0-.Ldebug_addr_start0 # Length of contribution +.Ldebug_addr_start0: + .short 5 # DWARF version number + .byte 8 # Address size + .byte 0 # Segment selector size +.Laddr_table_base0: + .quad .Lfunc_begin0 + .quad .Lfunc_begin1 +.Ldebug_addr_end0: + .section .debug_names,"",@progbits + .long .Lnames_end0-.Lnames_start0 # Header: unit length +.Lnames_start0: + .short 5 # Header: version + .short 0 # Header: padding + .long 2 # Header: compilation unit count + .long 0 # Header: local type unit count + .long 0 # Header: foreign type unit count + .long 5 # Header: bucket count + .long 5 # Header: name count + .long .Lnames_abbrev_end0-.Lnames_abbrev_start0 # Header: abbreviation table size + .long 8 # Header: augmentation string size + .ascii "LLVM0700" # Header: augmentation string + .long .Lcu_begin0 # Compilation unit 0 + .long .Lcu_begin1 # Compilation unit 1 + .long 0 # Bucket 0 + .long 1 # Bucket 1 + .long 0 # Bucket 2 + .long 4 # Bucket 3 + .long 5 # Bucket 4 + .long 5863786 # Hash in Bucket 1 + .long 1398125246 # Hash in Bucket 1 + .long 2090499946 # Hash in Bucket 1 + .long 193495088 # Hash in Bucket 3 + .long 5863324 # Hash in Bucket 4 + .long .Linfo_string8 # String in Bucket 1: t1 + .long .Linfo_string4 # String in Bucket 1: _Z2f12t1 + .long .Linfo_string6 # String in Bucket 1: main + .long .Linfo_string7 # String in Bucket 3: int + .long .Linfo_string3 # String in Bucket 4: f1 + .long .Lnames4-.Lnames_entries0 # Offset in Bucket 1 + .long .Lnames1-.Lnames_entries0 # Offset in Bucket 1 + .long .Lnames2-.Lnames_entries0 # Offset in Bucket 1 + .long .Lnames3-.Lnames_entries0 # Offset in Bucket 3 + .long .Lnames0-.Lnames_entries0 # Offset in Bucket 4 +.Lnames_abbrev_start0: + .byte 1 # Abbrev code + .byte 19 # DW_TAG_structure_type + .byte 1 # DW_IDX_compile_unit + .byte 11 # DW_FORM_data1 + .byte 3 # DW_IDX_die_offset + .byte 19 # DW_FORM_ref4 + .byte 4 # DW_IDX_parent + .byte 25 # DW_FORM_flag_present + .byte 0 # End of abbrev + .byte 0 # End of abbrev + .byte 2 # Abbrev code + .byte 46 # DW_TAG_subprogram + .byte 1 # DW_IDX_compile_unit + .byte 11 # DW_FORM_data1 + .byte 3 # DW_IDX_die_offset + .byte 19 # DW_FORM_ref4 + .byte 4 # DW_IDX_parent + .byte 25 # DW_FORM_flag_present + .byte 0 # End of abbrev + .byte 0 # End of abbrev + .byte 3 # Abbrev code + .byte 36 # DW_TAG_base_type + .byte 1 # DW_IDX_compile_unit + .byte 11 # DW_FORM_data1 + .byte 3 # DW_IDX_die_offset + .byte 19 # DW_FORM_ref4 + .byte 4 # DW_IDX_parent + .byte 25 # DW_FORM_flag_present + .byte 0 # End of abbrev + .byte 0 # End of abbrev + .byte 0 # End of abbrev list +.Lnames_abbrev_end0: +.Lnames_entries0: +.Lnames4: +.L0: + .byte 1 # Abbreviation code + .byte 0 # DW_IDX_compile_unit + .long 58 # DW_IDX_die_offset + .byte 0 # DW_IDX_parent + # End of list: t1 +.Lnames1: +.L3: + .byte 2 # Abbreviation code + .byte 0 # DW_IDX_compile_unit + .long 35 # DW_IDX_die_offset + .byte 0 # DW_IDX_parent + # End of list: _Z2f12t1 +.Lnames2: +.L2: + .byte 2 # Abbreviation code + .byte 1 # DW_IDX_compile_unit + .long 35 # DW_IDX_die_offset + .byte 0 # DW_IDX_parent + # End of list: main +.Lnames3: +.L1: + .byte 3 # Abbreviation code + .byte 1 # DW_IDX_compile_unit + .long 62 # DW_IDX_die_offset + .byte 0 # DW_IDX_parent + # End of list: int +.Lnames0: + .byte 2 # Abbreviation code + .byte 0 # DW_IDX_compile_unit + .long 35 # DW_IDX_die_offset + .byte 0 # DW_IDX_parent + # End of list: f1 + .p2align 2, 0x0 +.Lnames_end0: + .ident "clang version 19.0.0git (git@github.com:llvm/llvm-project.git 7607c4d40149128f848055613edf9c3cf9ae890d)" + .ident "clang version 19.0.0git (git@github.com:llvm/llvm-project.git 7607c4d40149128f848055613edf9c3cf9ae890d)" + .section ".note.GNU-stack","",@progbits + .addrsig + .section .debug_line,"",@progbits +.Lline_table_start0: + +#--- c.s +# Generated with: +# - clang++ -g -gpubnames -fdebug-compilation-dir='/proc/self/cwd' \ +# -S c.cpp -o c.s + +# c.cpp contents: + +# void null() { } + + .text + .globl _Z4nullv # -- Begin function _Z4nullv + .p2align 4, 0x90 + .type _Z4nullv,@function +_Z4nullv: # @_Z4nullv +.Lfunc_begin0: + .cfi_startproc +# %bb.0: # %entry + pushq %rbp + .cfi_def_cfa_offset 16 + .cfi_offset %rbp, -16 + movq %rsp, %rbp + .cfi_def_cfa_register %rbp +.Ltmp0: + popq %rbp + .cfi_def_cfa %rsp, 8 + retq +.Ltmp1: +.Lfunc_end0: + .size _Z4nullv, .Lfunc_end0-_Z4nullv + .cfi_endproc + # -- End function + .section .debug_abbrev,"",@progbits + .byte 1 # Abbreviation Code + .byte 17 # DW_TAG_compile_unit + .byte 1 # DW_CHILDREN_yes + .byte 37 # DW_AT_producer + .byte 37 # DW_FORM_strx1 + .byte 19 # DW_AT_language + .byte 5 # DW_FORM_data2 + .byte 3 # DW_AT_name + .byte 37 # DW_FORM_strx1 + .byte 114 # DW_AT_str_offsets_base + .byte 23 # DW_FORM_sec_offset + .byte 16 # DW_AT_stmt_list + .byte 23 # DW_FORM_sec_offset + .byte 27 # DW_AT_comp_dir + .byte 37 # DW_FORM_strx1 + .byte 17 # DW_AT_low_pc + .byte 27 # DW_FORM_addrx + .byte 18 # DW_AT_high_pc + .byte 6 # DW_FORM_data4 + .byte 115 # DW_AT_addr_base + .byte 23 # DW_FORM_sec_offset + .byte 0 # EOM(1) + .byte 0 # EOM(2) + .byte 2 # Abbreviation Code + .byte 46 # DW_TAG_subprogram + .byte 0 # DW_CHILDREN_no + .byte 17 # DW_AT_low_pc + .byte 27 # DW_FORM_addrx + .byte 18 # DW_AT_high_pc + .byte 6 # DW_FORM_data4 + .byte 64 # DW_AT_frame_base + .byte 24 # DW_FORM_exprloc + .byte 110 # DW_AT_linkage_name + .byte 37 # DW_FORM_strx1 + .byte 3 # DW_AT_name + .byte 37 # DW_FORM_strx1 + .byte 58 # DW_AT_decl_file + .byte 11 # DW_FORM_data1 + .byte 59 # DW_AT_decl_line + .byte 11 # DW_FORM_data1 + .byte 63 # DW_AT_external + .byte 25 # DW_FORM_flag_present + .byte 0 # EOM(1) + .byte 0 # EOM(2) + .byte 0 # EOM(3) + .section .debug_info,"",@progbits +.Lcu_begin0: + .long .Ldebug_info_end0-.Ldebug_info_start0 # Length of Unit +.Ldebug_info_start0: + .short 5 # DWARF version number + .byte 1 # DWARF Unit Type + .byte 8 # Address Size (in bytes) + .long .debug_abbrev # Offset Into Abbrev. Section + .byte 1 # Abbrev [1] 0xc:0x24 DW_TAG_compile_unit + .byte 0 # DW_AT_producer + .short 33 # DW_AT_language + .byte 1 # DW_AT_name + .long .Lstr_offsets_base0 # DW_AT_str_offsets_base + .long .Lline_table_start0 # DW_AT_stmt_list + .byte 2 # DW_AT_comp_dir + .byte 0 # DW_AT_low_pc + .long .Lfunc_end0-.Lfunc_begin0 # DW_AT_high_pc + .long .Laddr_table_base0 # DW_AT_addr_base + .byte 2 # Abbrev [2] 0x23:0xc DW_TAG_subprogram + .byte 0 # DW_AT_low_pc + .long .Lfunc_end0-.Lfunc_begin0 # DW_AT_high_pc + .byte 1 # DW_AT_frame_base + .byte 86 + .byte 3 # DW_AT_linkage_name + .byte 4 # DW_AT_name + .byte 0 # DW_AT_decl_file + .byte 1 # DW_AT_decl_line + # DW_AT_external + .byte 0 # End Of Children Mark +.Ldebug_info_end0: + .section .debug_str_offsets,"",@progbits + .long 24 # Length of String Offsets Set + .short 5 + .short 0 +.Lstr_offsets_base0: + .section .debug_str,"MS",@progbits,1 +.Linfo_string0: + .asciz "clang version 19.0.0git (git@github.com:llvm/llvm-project.git 7607c4d40149128f848055613edf9c3cf9ae890d)" # string offset=0 +.Linfo_string1: + .asciz "c.cpp" # string offset=104 +.Linfo_string2: + .asciz "/proc/self/cwd" # string offset=110 +.Linfo_string3: + .asciz "null" # string offset=125 +.Linfo_string4: + .asciz "_Z4nullv" # string offset=130 + .section .debug_str_offsets,"",@progbits + .long .Linfo_string0 + .long .Linfo_string1 + .long .Linfo_string2 + .long .Linfo_string4 + .long .Linfo_string3 + .section .debug_addr,"",@progbits + .long .Ldebug_addr_end0-.Ldebug_addr_start0 # Length of contribution +.Ldebug_addr_start0: + .short 5 # DWARF version number + .byte 8 # Address size + .byte 0 # Segment selector size +.Laddr_table_base0: + .quad .Lfunc_begin0 +.Ldebug_addr_end0: + .section .debug_names,"",@progbits + .long .Lnames_end0-.Lnames_start0 # Header: unit length +.Lnames_start0: + .short 5 # Header: version + .short 0 # Header: padding + .long 1 # Header: compilation unit count + .long 0 # Header: local type unit count + .long 0 # Header: foreign type unit count + .long 2 # Header: bucket count + .long 2 # Header: name count + .long .Lnames_abbrev_end0-.Lnames_abbrev_start0 # Header: abbreviation table size + .long 8 # Header: augmentation string size + .ascii "LLVM0700" # Header: augmentation string + .long .Lcu_begin0 # Compilation unit 0 + .long 1 # Bucket 0 + .long 2 # Bucket 1 + .long 2090557760 # Hash in Bucket 0 + .long 1488390083 # Hash in Bucket 1 + .long .Linfo_string3 # String in Bucket 0: null + .long .Linfo_string4 # String in Bucket 1: _Z4nullv + .long .Lnames0-.Lnames_entries0 # Offset in Bucket 0 + .long .Lnames1-.Lnames_entries0 # Offset in Bucket 1 +.Lnames_abbrev_start0: + .byte 1 # Abbrev code + .byte 46 # DW_TAG_subprogram + .byte 3 # DW_IDX_die_offset + .byte 19 # DW_FORM_ref4 + .byte 4 # DW_IDX_parent + .byte 25 # DW_FORM_flag_present + .byte 0 # End of abbrev + .byte 0 # End of abbrev + .byte 0 # End of abbrev list +.Lnames_abbrev_end0: +.Lnames_entries0: +.Lnames0: +.L0: + .byte 1 # Abbreviation code + .long 35 # DW_IDX_die_offset + .byte 0 # DW_IDX_parent + # End of list: null +.Lnames1: + .byte 1 # Abbreviation code + .long 35 # DW_IDX_die_offset + .byte 0 # DW_IDX_parent + # End of list: _Z4nullv + .p2align 2, 0x0 +.Lnames_end0: + .ident "clang version 19.0.0git (git@github.com:llvm/llvm-project.git 7607c4d40149128f848055613edf9c3cf9ae890d)" + .section ".note.GNU-stack","",@progbits + .addrsig + .section .debug_line,"",@progbits +.Lline_table_start0: From 174fa5bef6ea85dc68ce75da927c5ef723d1566d Mon Sep 17 00:00:00 2001 From: Caroline Tice Date: Mon, 15 Apr 2024 10:33:31 -0700 Subject: [PATCH 21/37] [lld][ELF] Clean up updateMultiCuOffset. Use the existing .debug_info section pointer in chunk, rather than rebuilding it. --- lld/ELF/SyntheticSections.cpp | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/lld/ELF/SyntheticSections.cpp b/lld/ELF/SyntheticSections.cpp index b69cc4cd967d5..3f7931c4d2486 100644 --- a/lld/ELF/SyntheticSections.cpp +++ b/lld/ELF/SyntheticSections.cpp @@ -3219,20 +3219,13 @@ template void DebugNamesSection::finalizeContents() { template void DebugNamesSection::updateMultiCuOffsets(OutputChunk &chunk) { - // Find the .debug_info section data for this chunk. - auto *file = cast>(chunk.infoSec->file); - DWARFContext dwarf(std::make_unique>(file)); - auto &dobj = static_cast &>(dwarf.getDWARFObj()); - InputSection *infoSec = dobj.getInfoSection(); - auto infoData = toStringRef(infoSec->contentMaybeDecompress()); + auto infoData = toStringRef(chunk.infoSec->contentMaybeDecompress()); const char *p = infoData.data(); // Skim through the CUs reading the unit lengths & types to find correct // starting offsets for CUs (before relocation). uint32_t nextCu = 0; for (size_t i = 1, end = chunk.compUnits.size(); i < end; ++i) { - // First CU offset for each new (appended) .debug_names section starts at - // zero. if (chunk.compUnits[i] == 0) { // Skip to start of next CU and read the type & size. p = infoData.data() + nextCu; From d81d3598e589b24443eca55e53b140040e67862d Mon Sep 17 00:00:00 2001 From: Fangrui Song Date: Mon, 15 Apr 2024 13:03:30 -0700 Subject: [PATCH 22/37] writeTo: Use endian::writeNext and rename oldBuf --- lld/ELF/SyntheticSections.cpp | 64 +++++++++++++++-------------------- 1 file changed, 27 insertions(+), 37 deletions(-) diff --git a/lld/ELF/SyntheticSections.cpp b/lld/ELF/SyntheticSections.cpp index 3f7931c4d2486..dd07236aef29f 100644 --- a/lld/ELF/SyntheticSections.cpp +++ b/lld/ELF/SyntheticSections.cpp @@ -3243,18 +3243,19 @@ void DebugNamesSection::updateMultiCuOffsets(OutputChunk &chunk) { } template void DebugNamesSection::writeTo(uint8_t *buf) { - [[maybe_unused]] uint8_t *oldBuf = buf; + [[maybe_unused]] const uint8_t *const beginBuf = buf; // Write the header. - endian::write32(buf + 0, hdr.UnitLength); - endian::write16(buf + 4, hdr.Version); - endian::write32(buf + 8, hdr.CompUnitCount); - endian::write32(buf + 12, hdr.LocalTypeUnitCount); - endian::write32(buf + 16, hdr.ForeignTypeUnitCount); - endian::write32(buf + 20, hdr.BucketCount); - endian::write32(buf + 24, hdr.NameCount); - endian::write32(buf + 28, hdr.AbbrevTableSize); - endian::write32(buf + 32, hdr.AugmentationStringSize); - buf += 36; + endian::writeNext(buf, hdr.UnitLength); + endian::writeNext(buf, hdr.Version); + buf += 2; // padding + endian::writeNext(buf, hdr.CompUnitCount); + endian::writeNext(buf, hdr.LocalTypeUnitCount); + endian::writeNext(buf, hdr.ForeignTypeUnitCount); + endian::writeNext(buf, hdr.BucketCount); + endian::writeNext(buf, hdr.NameCount); + endian::writeNext(buf, hdr.AbbrevTableSize); + endian::writeNext(buf, + hdr.AugmentationStringSize); memcpy(buf, hdr.AugmentationString.c_str(), hdr.AugmentationString.size()); buf += hdr.AugmentationStringSize; @@ -3264,9 +3265,8 @@ template void DebugNamesSection::writeTo(uint8_t *buf) { if (chunk.compUnits.size() > 1) updateMultiCuOffsets(chunk); for (uint32_t cuOffset : chunk.compUnits) { - endian::write32(buf, - chunk.infoSec->outSecOff + cuOffset); - buf += 4; + endian::writeNext( + buf, chunk.infoSec->outSecOff + cuOffset); } } @@ -3291,31 +3291,22 @@ template void DebugNamesSection::writeTo(uint8_t *buf) { bucketIdx += bucket.size(); } // Write the hashes. - for (const SmallVector &bucket : buckets) { - for (const NameEntry *e : bucket) { - endian::write32(buf, e->hashValue); - buf += 4; - } - } + for (const SmallVector &bucket : buckets) + for (const NameEntry *e : bucket) + endian::writeNext(buf, e->hashValue); // Write the name table. The name entries are ordered by bucket_idx and // correspond one-to-one with the hash lookup table. // // First, write the relocated string offsets. - for (const SmallVector &bucket : buckets) { - for (const NameEntry *ne : bucket) { - endian::write32(buf, ne->stringOffset); - buf += 4; - } - } + for (const SmallVector &bucket : buckets) + for (const NameEntry *ne : bucket) + endian::writeNext(buf, ne->stringOffset); // Then write the entry offsets. - for (const SmallVector &bucket : buckets) { - for (const NameEntry *ne : bucket) { - endian::write32(buf, ne->entryOffset); - buf += 4; - } - } + for (const SmallVector &bucket : buckets) + for (const NameEntry *ne : bucket) + endian::writeNext(buf, ne->entryOffset); // Write the abbrev table. memcpy(buf, abbrevTableBuf.data(), abbrevTableBuf.size()); @@ -3331,24 +3322,23 @@ template void DebugNamesSection::writeTo(uint8_t *buf) { for (AttrValue value : ie.attrValues) { switch (value.attrSize) { case 1: - *buf = value.attrValue; + *buf++ = value.attrValue; break; case 2: - endian::write16(buf, value.attrValue); + endian::writeNext(buf, value.attrValue); break; case 4: - endian::write32(buf, value.attrValue); + endian::writeNext(buf, value.attrValue); break; default: llvm_unreachable("invalid attrSize"); } - buf += value.attrSize; } } ++buf; // index entry sentinel } } - assert(uint64_t(buf - oldBuf) == size); + assert(uint64_t(buf - beginBuf) == size); } GdbIndexSection::GdbIndexSection() From 1660c19aa319e8cbb0251fff9da963de33eac8c8 Mon Sep 17 00:00:00 2001 From: Fangrui Song Date: Mon, 15 Apr 2024 13:28:31 -0700 Subject: [PATCH 23/37] Simplify updateMultiCuOffsets --- lld/ELF/SyntheticSections.cpp | 20 +++++++------------- 1 file changed, 7 insertions(+), 13 deletions(-) diff --git a/lld/ELF/SyntheticSections.cpp b/lld/ELF/SyntheticSections.cpp index dd07236aef29f..5e4d9c8e6cac7 100644 --- a/lld/ELF/SyntheticSections.cpp +++ b/lld/ELF/SyntheticSections.cpp @@ -3217,26 +3217,20 @@ template void DebugNamesSection::finalizeContents() { }); } +// Skim through the CUs reading the unit lengths & types to find correct +// starting offsets for CUs (before relocation). template void DebugNamesSection::updateMultiCuOffsets(OutputChunk &chunk) { - auto infoData = toStringRef(chunk.infoSec->contentMaybeDecompress()); - const char *p = infoData.data(); - - // Skim through the CUs reading the unit lengths & types to find correct - // starting offsets for CUs (before relocation). + ArrayRef infoData = chunk.infoSec->contentMaybeDecompress(); uint32_t nextCu = 0; for (size_t i = 1, end = chunk.compUnits.size(); i < end; ++i) { if (chunk.compUnits[i] == 0) { // Skip to start of next CU and read the type & size. - p = infoData.data() + nextCu; - uint32_t unit_length = - endian::readNext(p); - [[maybe_unused]] uint16_t version = - endian::readNext(p); - uint8_t unitType = - endian::readNext(p); + auto *p = infoData.data() + nextCu; + uint32_t unitLength = endian::read32(p); + uint8_t unitType = p[6]; if (unitType == dwarf::DW_UT_compile) - nextCu += unit_length + 4; + nextCu += unitLength + 4; } chunk.compUnits[i] += nextCu; } From 129c09ea88de26248ad95c78250e4a6fde0b2586 Mon Sep 17 00:00:00 2001 From: Caroline Tice Date: Mon, 15 Apr 2024 14:29:01 -0700 Subject: [PATCH 24/37] [lld][ELF] Minor fixes. Fix some error strings & adjust tests that test for them. Fix comments at top of ppc32-debug-names.s test. Fix for-loop syntax and call NameIndex::getOffsets. --- lld/ELF/SyntheticSections.cpp | 17 ++++++++--------- lld/test/ELF/debug-names-bad-version.s | 2 +- lld/test/ELF/debug-names-dwarf64.s | 2 +- lld/test/ELF/ppc32-debug-names.s | 6 +++--- 4 files changed, 13 insertions(+), 14 deletions(-) diff --git a/lld/ELF/SyntheticSections.cpp b/lld/ELF/SyntheticSections.cpp index 5e4d9c8e6cac7..844fac57710dd 100644 --- a/lld/ELF/SyntheticSections.cpp +++ b/lld/ELF/SyntheticSections.cpp @@ -2752,22 +2752,21 @@ void DebugNamesBaseSection::parseDebugNames( NameData &nd = inputChunk.nameData.emplace_back(); nd.hdr = ni.getHeader(); if (nd.hdr.Format != DwarfFormat::DWARF32) { - errorOrWarn(toString(namesSec.sec) + Twine(": unsupported DWARF64")); + errorOrWarn(toString(namesSec.sec) + + Twine(": found DWARF64, which is currently unsupported")); return; } if (nd.hdr.Version != 5) { - errorOrWarn(toString(namesSec.sec) + Twine(": unsupported version ") + + errorOrWarn(toString(namesSec.sec) + Twine(": unsupported version: ") + Twine(nd.hdr.Version)); return; } const uint32_t dwarfSize = dwarf::getDwarfOffsetByteSize(DwarfFormat::DWARF32); - const uint32_t hdrSize = - getDebugNamesHeaderSize(nd.hdr.AugmentationStringSize); - auto locs = findDebugNamesOffsets(hdrSize, nd.hdr); + DWARFDebugNames::DWARFDebugNamesOffsets locs = ni.getOffsets(); if (locs.EntriesBase + niOffset > namesExtractor.getData().size()) { errorOrWarn(toString(namesSec.sec) + - Twine(": index entry is out of bounds")); + Twine(": entry pool start is beyond end of section")); return; } @@ -3179,9 +3178,9 @@ template DebugNamesSection::DebugNamesSection() { p = namesData + niOffset + locs.EntryOffsetsBase; SmallVector entryOffsets; entryOffsets.resize_for_overwrite(hdr.NameCount); - for (auto i : seq(hdr.NameCount)) - entryOffsets[i] = - endian::readNext(p); + + for (auto &offset : entryOffsets) + offset = endian::readNext(p); return entryOffsets; }); }); diff --git a/lld/test/ELF/debug-names-bad-version.s b/lld/test/ELF/debug-names-bad-version.s index 6f6ff2d507a9b..4835c4a3fa742 100644 --- a/lld/test/ELF/debug-names-bad-version.s +++ b/lld/test/ELF/debug-names-bad-version.s @@ -9,7 +9,7 @@ # RUN: not ld.lld --debug-names a.o b.o 2>&1 \ # RUN: | FileCheck -DFILE=a.o %s --implicit-check-not=error: -# CHECK: error: [[FILE]]:(.debug_names): unsupported version 4 +# CHECK: error: [[FILE]]:(.debug_names): unsupported version: 4 #--- a.s .text diff --git a/lld/test/ELF/debug-names-dwarf64.s b/lld/test/ELF/debug-names-dwarf64.s index 310e9379bf9ae..d5ba3b69255a2 100644 --- a/lld/test/ELF/debug-names-dwarf64.s +++ b/lld/test/ELF/debug-names-dwarf64.s @@ -10,7 +10,7 @@ # RUN: not ld.lld --debug-names %t1.o -o /dev/null 2>&1 \ # RUN: | FileCheck -DFILE=%t1.o --implicit-check-not=error: %s -# CHECK: error: [[FILE]]:(.debug_names): unsupported DWARF64 +# CHECK: error: [[FILE]]:(.debug_names): found DWARF64, which is currently unsupported .text .globl main # -- Begin function main diff --git a/lld/test/ELF/ppc32-debug-names.s b/lld/test/ELF/ppc32-debug-names.s index f091f961588d0..3fc93ec86693f 100644 --- a/lld/test/ELF/ppc32-debug-names.s +++ b/lld/test/ELF/ppc32-debug-names.s @@ -1,7 +1,7 @@ -# ppc-debug-names.s was generated with: +# ppc32-debug-names.s was generated with: -# - clang++ --target=powerpc -g -O0 -gpubnames \ -# -fdebug-compilation-dir='/self/proc/cwd' -S a.cpp -o a.s +# clang++ --target=powerpc -g -gpubnames \ +# -fdebug-compilation-dir='/self/proc/cwd' -S a.cpp -o a.s # a.cpp contents: From 932a5c9b7244731a7597a91402db8c664175ccc5 Mon Sep 17 00:00:00 2001 From: Fangrui Song Date: Mon, 15 Apr 2024 15:29:09 -0700 Subject: [PATCH 25/37] Fix when there are more than one name indices in an input .debug_names --- lld/ELF/SyntheticSections.cpp | 22 ++++++++-------------- lld/ELF/SyntheticSections.h | 2 +- lld/test/ELF/debug-names.s | 5 +++++ 3 files changed, 14 insertions(+), 15 deletions(-) diff --git a/lld/ELF/SyntheticSections.cpp b/lld/ELF/SyntheticSections.cpp index 844fac57710dd..891e1b244e49d 100644 --- a/lld/ELF/SyntheticSections.cpp +++ b/lld/ELF/SyntheticSections.cpp @@ -2738,16 +2738,13 @@ void DebugNamesBaseSection::parseDebugNames( InputChunk &inputChunk, OutputChunk &chunk, DWARFDataExtractor &namesExtractor, DataExtractor &strExtractor, function_ref( - uint32_t numCus, uint32_t niOffset, const DWARFDebugNames::Header &, + uint32_t numCus, const DWARFDebugNames::Header &, const DWARFDebugNames::DWARFDebugNamesOffsets &)> readOffsets) { const LLDDWARFSection namesSec = inputChunk.section; DenseMap offsetMap; // Number of CUs seen in previous NameIndex sections within current chunk. uint32_t numCus = 0; - // Offset of current NameIndex section from start of .debug_names section in - // current chunk. - uint32_t niOffset = 0; for (const DWARFDebugNames::NameIndex &ni : *inputChunk.llvmDebugNames) { NameData &nd = inputChunk.nameData.emplace_back(); nd.hdr = ni.getHeader(); @@ -2764,21 +2761,20 @@ void DebugNamesBaseSection::parseDebugNames( const uint32_t dwarfSize = dwarf::getDwarfOffsetByteSize(DwarfFormat::DWARF32); DWARFDebugNames::DWARFDebugNamesOffsets locs = ni.getOffsets(); - if (locs.EntriesBase + niOffset > namesExtractor.getData().size()) { + if (locs.EntriesBase > namesExtractor.getData().size()) { errorOrWarn(toString(namesSec.sec) + Twine(": entry pool start is beyond end of section")); return; } - SmallVector entryOffsets = - readOffsets(numCus, niOffset, nd.hdr, locs); + SmallVector entryOffsets = readOffsets(numCus, nd.hdr, locs); // Read the entry pool. offsetMap.clear(); nd.nameEntries.resize(nd.hdr.NameCount); for (auto i : seq(nd.hdr.NameCount)) { NameEntry &ne = nd.nameEntries[i]; - uint64_t strOffset = locs.StringOffsetsBase + niOffset + i * dwarfSize; + uint64_t strOffset = locs.StringOffsetsBase + i * dwarfSize; ne.stringOffset = strOffset; uint64_t strp = namesExtractor.getRelocatedValue(dwarfSize, &strOffset); StringRef name = strExtractor.getCStrRef(&strp); @@ -2787,7 +2783,7 @@ void DebugNamesBaseSection::parseDebugNames( // Read a series of index entries that end with abbreviation code 0. const char *errMsg = nullptr; - uint64_t offset = locs.EntriesBase + niOffset + entryOffsets[i]; + uint64_t offset = locs.EntriesBase + entryOffsets[i]; while (offset < namesSec.Data.size() && namesSec.Data[offset] != 0) { // Read & store all entries (for the same string). auto ie = makeThreadLocal(); @@ -2875,7 +2871,6 @@ void DebugNamesBaseSection::parseDebugNames( for (IndexEntry &ie : ne.entries()) ie.parentEntry = offsetMap.lookup(ie.parentOffset); numCus += nd.hdr.CompUnitCount; - niOffset += nd.hdr.UnitLength + 4; } } @@ -3164,18 +3159,17 @@ template DebugNamesSection::DebugNamesSection() { parseDebugNames( inputChunk, chunk, namesExtractor, strExtractor, [&chunk, namesData = dobj.getNamesSection().Data.data()]( - uint32_t numCus, uint32_t niOffset, - const DWARFDebugNames::Header &hdr, + uint32_t numCus, const DWARFDebugNames::Header &hdr, const DWARFDebugNames::DWARFDebugNamesOffsets &locs) { // Read CU offsets. - const char *p = namesData + niOffset + locs.CUsBase; + const char *p = namesData + locs.CUsBase; chunk.compUnits.resize_for_overwrite(numCus + hdr.CompUnitCount); for (auto i : seq(hdr.CompUnitCount)) chunk.compUnits[i + numCus] = endian::readNext(p); // Read entry offsets. - p = namesData + niOffset + locs.EntryOffsetsBase; + p = namesData + locs.EntryOffsetsBase; SmallVector entryOffsets; entryOffsets.resize_for_overwrite(hdr.NameCount); diff --git a/lld/ELF/SyntheticSections.h b/lld/ELF/SyntheticSections.h index cbf16c4011388..c0d90fd915301 100644 --- a/lld/ELF/SyntheticSections.h +++ b/lld/ELF/SyntheticSections.h @@ -872,7 +872,7 @@ class DebugNamesBaseSection : public SyntheticSection { llvm::DWARFDataExtractor &namesExtractor, llvm::DataExtractor &strExtractor, llvm::function_ref( - uint32_t numCUs, uint32_t niOffset, + uint32_t numCUs, const llvm::DWARFDebugNames::Header &hdr, const llvm::DWARFDebugNames::DWARFDebugNamesOffsets &)> readOffsets); diff --git a/lld/test/ELF/debug-names.s b/lld/test/ELF/debug-names.s index 4ca2cb1eabefa..a36c7e6898870 100644 --- a/lld/test/ELF/debug-names.s +++ b/lld/test/ELF/debug-names.s @@ -24,6 +24,11 @@ # RUN: llvm-dwarfdump -debug-names out | FileCheck %s --check-prefix=DWARF # RUN: llvm-readelf -SW out | FileCheck %s --check-prefix=READELF +## Test we can handle concatenated .debug_names. +# RUN: ld.lld -r a.o b.o -o ab.o +# RUN: ld.lld --debug-names ab.o -o out1 +# RUN: llvm-dwarfdump -debug-names out1 | FileCheck %s --check-prefix=DWARF + # READELF: Name Type Address Off Size ES Flg Lk Inf Al # READELF: .debug_names PROGBITS 0000000000000000 [[#%x,]] 0000cc 00 0 0 4 From 18da913700ea70981504e1a8f0fee773b62d7d8a Mon Sep 17 00:00:00 2001 From: Fangrui Song Date: Mon, 15 Apr 2024 13:28:31 -0700 Subject: [PATCH 26/37] Fix CU list offsets when there are 3+ CUs in one name index Untested yet. https://github.com/llvm/llvm-project/pull/86508#issuecomment-2057815004 contains instructions to test this scenario. --- lld/ELF/SyntheticSections.cpp | 53 +++++++++++------------------------ lld/ELF/SyntheticSections.h | 9 +++--- 2 files changed, 21 insertions(+), 41 deletions(-) diff --git a/lld/ELF/SyntheticSections.cpp b/lld/ELF/SyntheticSections.cpp index 891e1b244e49d..8ce4ef6e36852 100644 --- a/lld/ELF/SyntheticSections.cpp +++ b/lld/ELF/SyntheticSections.cpp @@ -3161,19 +3161,18 @@ template DebugNamesSection::DebugNamesSection() { [&chunk, namesData = dobj.getNamesSection().Data.data()]( uint32_t numCus, const DWARFDebugNames::Header &hdr, const DWARFDebugNames::DWARFDebugNamesOffsets &locs) { - // Read CU offsets. - const char *p = namesData + locs.CUsBase; + // Read CU offsets, which are relocated by .debug_info + X + // relocations. Record the section offset to be relocated by + // `finalizeContents`. chunk.compUnits.resize_for_overwrite(numCus + hdr.CompUnitCount); for (auto i : seq(hdr.CompUnitCount)) - chunk.compUnits[i + numCus] = - endian::readNext(p); + chunk.compUnits[numCus + i] = locs.CUsBase + i * 4; // Read entry offsets. - p = namesData + locs.EntryOffsetsBase; + const char *p = namesData + locs.EntryOffsetsBase; SmallVector entryOffsets; entryOffsets.resize_for_overwrite(hdr.NameCount); - - for (auto &offset : entryOffsets) + for (uint32_t &offset : entryOffsets) offset = endian::readNext(p); return entryOffsets; }); @@ -3201,34 +3200,20 @@ template void DebugNamesSection::finalizeContents() { getNameRelocs(sec, rels.rels, relocs.get()[i]); else getNameRelocs(sec, rels.relas, relocs.get()[i]); + + // Relocate CU offsets with .debug_info + X relocations. + OutputChunk &chunk = chunks.get()[i]; + for (auto [j, cuOffset] : enumerate(chunk.compUnits)) + cuOffset = relocs.get()[i].lookup(cuOffset); }); - // Relocate string offsets in the name table. + // Relocate string offsets in the name table with .debug_str + X relocations. parallelForEach(nameVecs, [&](auto &nameVec) { for (NameEntry &ne : nameVec) - ne.stringOffset = relocs.get()[ne.chunkIdx][ne.stringOffset]; + ne.stringOffset = relocs.get()[ne.chunkIdx].lookup(ne.stringOffset); }); } -// Skim through the CUs reading the unit lengths & types to find correct -// starting offsets for CUs (before relocation). -template -void DebugNamesSection::updateMultiCuOffsets(OutputChunk &chunk) { - ArrayRef infoData = chunk.infoSec->contentMaybeDecompress(); - uint32_t nextCu = 0; - for (size_t i = 1, end = chunk.compUnits.size(); i < end; ++i) { - if (chunk.compUnits[i] == 0) { - // Skip to start of next CU and read the type & size. - auto *p = infoData.data() + nextCu; - uint32_t unitLength = endian::read32(p); - uint8_t unitType = p[6]; - if (unitType == dwarf::DW_UT_compile) - nextCu += unitLength + 4; - } - chunk.compUnits[i] += nextCu; - } -} - template void DebugNamesSection::writeTo(uint8_t *buf) { [[maybe_unused]] const uint8_t *const beginBuf = buf; // Write the header. @@ -3247,15 +3232,9 @@ template void DebugNamesSection::writeTo(uint8_t *buf) { buf += hdr.AugmentationStringSize; // Write the CU list. - for (auto i : seq(numChunks)) { - OutputChunk &chunk = chunks[i]; - if (chunk.compUnits.size() > 1) - updateMultiCuOffsets(chunk); - for (uint32_t cuOffset : chunk.compUnits) { - endian::writeNext( - buf, chunk.infoSec->outSecOff + cuOffset); - } - } + for (auto i : seq(numChunks)) + for (uint32_t cuOffset : chunks[i].compUnits) + endian::writeNext(buf, cuOffset); // Write the local TU list, then the foreign TU list.. // TODO: Fix this, once we get everything working without TUs. diff --git a/lld/ELF/SyntheticSections.h b/lld/ELF/SyntheticSections.h index c0d90fd915301..497ff3a62b61a 100644 --- a/lld/ELF/SyntheticSections.h +++ b/lld/ELF/SyntheticSections.h @@ -858,6 +858,10 @@ class DebugNamesBaseSection : public SyntheticSection { // Pointer to the .debug_info section that contains compile units, used to // compute the relocated CU offsets. InputSection *infoSec; + // This initially holds section offsets, which may not be consecutive if + // there are multiple name indices in an input .debug_names section. After + // relocation, the section offsets are changed to CU offsets relative to the + // output section. SmallVector compUnits; }; @@ -872,8 +876,7 @@ class DebugNamesBaseSection : public SyntheticSection { llvm::DWARFDataExtractor &namesExtractor, llvm::DataExtractor &strExtractor, llvm::function_ref( - uint32_t numCUs, - const llvm::DWARFDebugNames::Header &hdr, + uint32_t numCUs, const llvm::DWARFDebugNames::Header &hdr, const llvm::DWARFDebugNames::DWARFDebugNamesOffsets &)> readOffsets); void computeHdrAndAbbrevTable(MutableArrayRef inputChunks); @@ -910,8 +913,6 @@ class DebugNamesSection final : public DebugNamesBaseSection { void getNameRelocs(InputSection *sec, ArrayRef rels, llvm::DenseMap &relocs); - void updateMultiCuOffsets(OutputChunk &chunk); - private: static void readOffsets(InputChunk &inputChunk, OutputChunk &chunk, llvm::DWARFDataExtractor &namesExtractor, From dfe787af70e11666a8e43ca73a86d1841d364dfc Mon Sep 17 00:00:00 2001 From: Fangrui Song Date: Mon, 15 Apr 2024 17:06:22 -0700 Subject: [PATCH 27/37] Test compressed input and output --- lld/test/ELF/debug-names.s | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/lld/test/ELF/debug-names.s b/lld/test/ELF/debug-names.s index a36c7e6898870..888dd9007ed12 100644 --- a/lld/test/ELF/debug-names.s +++ b/lld/test/ELF/debug-names.s @@ -32,6 +32,16 @@ # READELF: Name Type Address Off Size ES Flg Lk Inf Al # READELF: .debug_names PROGBITS 0000000000000000 [[#%x,]] 0000cc 00 0 0 4 +## Test we can handle compressed input and --compress-debug-sections compresses output .debug_names. +# RUN: %if zlib %{ llvm-objcopy --compress-debug-sections=zlib a.o a.zlib.o %} +# RUN: %if zlib %{ ld.lld --debug-names --compress-debug-sections=zlib a.zlib.o b.o -o out.zlib %} +# RUN: %if zlib %{ llvm-readelf -S out.zlib | FileCheck %s --check-prefix=READELF-ZLIB %} +# RUN: %if zlib %{ llvm-objcopy --decompress-debug-sections out.zlib out.zlib.de %} +# RUN: %if zlib %{ llvm-dwarfdump -debug-names out.zlib.de | FileCheck %s --check-prefix=DWARF %} + +# READELF-ZLIB: Name Type Address Off Size ES Flg Lk Inf Al +# READELF-ZLIB: .debug_names PROGBITS 0000000000000000 [[#%x,]] [[#%x,]] 00 C 0 0 1 + # DWARF: .debug_names contents: # DWARF: Name Index @ 0x0 { # DWARF-NEXT: Header { From 133c19a5aec145b6615ace3cb51677c5d9626c53 Mon Sep 17 00:00:00 2001 From: Caroline Tice Date: Tue, 16 Apr 2024 11:40:44 -0700 Subject: [PATCH 28/37] [lld][ELF] Add more tests for debug_names. Add multiple variations of test for having multiple CUs in a single .o file. Add tests for using --debug_names when one or all of the input files do not have a .debug_names section. --- lld/test/ELF/debug-names-multi-cus-2.s | 460 ++++++++++++++++ lld/test/ELF/debug-names-multi-cus-append.s | 459 ++++++++++++++++ lld/test/ELF/debug-names-multi-cus-long.s | 563 ++++++++++++++++++++ lld/test/ELF/debug-names-nonames.s | 228 ++++++++ 4 files changed, 1710 insertions(+) create mode 100644 lld/test/ELF/debug-names-multi-cus-2.s create mode 100644 lld/test/ELF/debug-names-multi-cus-append.s create mode 100644 lld/test/ELF/debug-names-multi-cus-long.s create mode 100644 lld/test/ELF/debug-names-nonames.s diff --git a/lld/test/ELF/debug-names-multi-cus-2.s b/lld/test/ELF/debug-names-multi-cus-2.s new file mode 100644 index 0000000000000..1d8bcdc56d43f --- /dev/null +++ b/lld/test/ELF/debug-names-multi-cus-2.s @@ -0,0 +1,460 @@ +# abc.s was generated by: + +# clang++ a.cpp -gpubnames a.cpp -g -emit-llvm -c \ +# -fdebug-compilation-dir='/proc/self/cwd +# clang++ b.cpp -gpubnames b.cpp -g -emit-llvm -c \ +# -fdebug-compilation-dir='/proc/self/cwd +1# clang++ c.cpp -gpubnames c.cpp -g -emit-llvm -c \ +# -fdebug-compilation-dir='/proc/self/cwd' +# llvm-link a.bc b.bc c.bc -o abc.bc +# clang++ abc.bc -S -o abc.s + +# a.cpp contains: +# struct t1 { }; +# void f1(t1) { } + +# b.cpp contains: +# struct t1 { }; +# int main() { +# t1 v1; +# } + +# c.cpp contains: +# +# void null() { } + + +# REQUIRES: x86 +# RUN: rm -rf %t && split-file %s %t && cd %t +# RUN: llvm-mc -filetype=obj -triple=x86_64 abc.s -o abc.o +# RUN: llvm-mc -filetype=obj -triple=x86_64 d.s -o d.o +# RUN: ld.lld --debug-names abc.o d.o -o out +# RUN: llvm-dwarfdump --debug-names out \ +# RUN: | FileCheck -DFILE=a.o %s --check-prefix=DWARF + +# DWARF: Compilation Unit offsets [ +# DWARF-NEXT: CU[0]: 0x00000000 +# DWARF-NEXT: CU[1]: 0x0000000c +# DWARF-NEXT: CU[2]: 0x00000018 +# DWARF-NEXT: CU[3]: 0x00000024 +# DWARF-NEXT: ] + +# RUN: ld.lld --debug-names d.o abc.o -o out2 +# RUN: llvm-dwarfdump --debug-names out2 \ +# RUN: | FileCheck -DFILE=a.o %s --check-prefix=DWARF2 + +# DWARF2: Compilation Unit offsets [ +# DWARF2-NEXT: CU[0]: 0x00000000 +# DWARF2-NEXT: CU[1]: 0x0000000c +# DWARF2-NEXT: CU[2]: 0x00000018 +# DWARF2-NEXT: CU[3]: 0x00000024 +# DWARF2-NEXT: ] + +#--- abc.s + + .text + .globl _Z2f12t1 # -- Begin function _Z2f12t1 + .p2align 4, 0x90 + .type _Z2f12t1,@function +_Z2f12t1: # @_Z2f12t1 +.Lfunc_begin0: + .cfi_startproc +# %bb.0: # %entry + pushq %rbp + .cfi_def_cfa_offset 16 + .cfi_offset %rbp, -16 + movq %rsp, %rbp + .cfi_def_cfa_register %rbp +.Ltmp0: + popq %rbp + .cfi_def_cfa %rsp, 8 + retq +.Ltmp1: +.Lfunc_end0: + .size _Z2f12t1, .Lfunc_end0-_Z2f12t1 + .cfi_endproc + # -- End function + .globl main # -- Begin function main + .p2align 4, 0x90 + .type main,@function +main: # @main +.Lfunc_begin1: + .cfi_startproc +# %bb.0: # %entry + pushq %rbp + .cfi_def_cfa_offset 16 + .cfi_offset %rbp, -16 + movq %rsp, %rbp + .cfi_def_cfa_register %rbp +.Ltmp2: + xorl %eax, %eax + popq %rbp + .cfi_def_cfa %rsp, 8 + retq +.Ltmp3: +.Lfunc_end1: + .size main, .Lfunc_end1-main + .cfi_endproc + # -- End function + .globl _Z4nullv # -- Begin function _Z4nullv + .p2align 4, 0x90 + .type _Z4nullv,@function +_Z4nullv: # @_Z4nullv +.Lfunc_begin2: + .cfi_startproc +# %bb.0: # %entry + pushq %rbp + .cfi_def_cfa_offset 16 + .cfi_offset %rbp, -16 + movq %rsp, %rbp + .cfi_def_cfa_register %rbp +.Ltmp4: + popq %rbp + .cfi_def_cfa %rsp, 8 + retq +.Ltmp5: +.Lfunc_end2: + .size _Z4nullv, .Lfunc_end2-_Z4nullv + .cfi_endproc + # -- End function + .section .debug_abbrev,"",@progbits + .byte 0 # EOM(1) + .byte 0 # EOM(2) + .byte 0 # EOM(3) + .section .debug_info,"",@progbits +.Lcu_begin0: + .long .Ldebug_info_end0-.Ldebug_info_start0 # Length of Unit +.Ldebug_info_start0: + .short 5 # DWARF version number + .byte 1 # DWARF Unit Type + .byte 8 # Address Size (in bytes) + .long .debug_abbrev # Offset Into Abbrev. Section +.Ldebug_info_end0: +.Lcu_begin1: + .long .Ldebug_info_end1-.Ldebug_info_start1 # Length of Unit +.Ldebug_info_start1: + .short 5 # DWARF version number + .byte 1 # DWARF Unit Type + .byte 8 # Address Size (in bytes) + .long .debug_abbrev # Offset Into Abbrev. Section +.Ldebug_info_end1: +.Lcu_begin2: + .long .Ldebug_info_end2-.Ldebug_info_start2 # Length of Unit +.Ldebug_info_start2: + .short 5 # DWARF version number + .byte 1 # DWARF Unit Type + .byte 8 # Address Size (in bytes) + .long .debug_abbrev # Offset Into Abbrev. Section +.Ldebug_info_end2: + .section .debug_str_offsets,"",@progbits + .long 56 # Length of String Offsets Set + .short 5 + .short 0 +.Lstr_offsets_base0: + .section .debug_str,"MS",@progbits,1 +.Linfo_string0: + .asciz "clang version 19.0.0git (git@github.com:llvm/llvm-project.git 58e50c2a7b0a8a63e038dbfc4cb12d81aef1a32d)" # string offset=0 +.Linfo_string1: + .asciz "a.cpp" # string offset=104 +.Linfo_string2: + .asciz "/proc/self/cwd" # string offset=110 +.Linfo_string3: + .asciz "f1" # string offset=125 +.Linfo_string4: + .asciz "_Z2f12t1" # string offset=128 +.Linfo_string5: + .asciz "b.cpp" # string offset=137 +.Linfo_string6: + .asciz "main" # string offset=143 +.Linfo_string7: + .asciz "c.cpp" # string offset=148 +.Linfo_string8: + .asciz "null" # string offset=154 +.Linfo_string9: + .asciz "_Z4nullv" # string offset=159 +.Linfo_string10: + .asciz "int" # string offset=168 +.Linfo_string11: + .asciz "t1" # string offset=172 +.Linfo_string12: + .asciz "v1" # string offset=175 + .section .debug_str_offsets,"",@progbits +.Laddr_table_base0: + .quad .Lfunc_begin0 + .quad .Lfunc_begin1 + .quad .Lfunc_begin2 +.Ldebug_addr_end0: + .section .debug_names,"",@progbits + .long .Lnames_end0-.Lnames_start0 # Header: unit length +.Lnames_start0: + .short 5 # Header: version + .short 0 # Header: padding + .long 3 # Header: compilation unit count + .long 0 # Header: local type unit count + .long 0 # Header: foreign type unit count + .long 7 # Header: bucket count + .long 7 # Header: name count + .long .Lnames_abbrev_end0-.Lnames_abbrev_start0 # Header: abbreviation table size + .long 8 # Header: augmentation string size + .ascii "LLVM0700" # Header: augmentation string + .long .Lcu_begin0 # Compilation unit 0 + .long .Lcu_begin1 # Compilation unit 1 + .long .Lcu_begin2 # Compilation unit 2 + .long 1 # Bucket 0 + .long 0 # Bucket 1 + .long 0 # Bucket 2 + .long 2 # Bucket 3 + .long 4 # Bucket 4 + .long 5 # Bucket 5 + .long 0 # Bucket 6 + .long 1398125246 # Hash in Bucket 0 + .long 193495088 # Hash in Bucket 3 + .long 2090499946 # Hash in Bucket 3 + .long 2090557760 # Hash in Bucket 4 + .long 5863324 # Hash in Bucket 5 + .long 5863786 # Hash in Bucket 5 + .long 1488390083 # Hash in Bucket 5 + .long .Linfo_string4 # String in Bucket 0: _Z2f12t1 + .long .Linfo_string10 # String in Bucket 3: int + .long .Linfo_string6 # String in Bucket 3: main + .long .Linfo_string8 # String in Bucket 4: null + .long .Linfo_string3 # String in Bucket 5: f1 + .long .Linfo_string11 # String in Bucket 5: t1 + .long .Linfo_string9 # String in Bucket 5: _Z4nullv + .long .Lnames1-.Lnames_entries0 # Offset in Bucket 0 + .long .Lnames5-.Lnames_entries0 # Offset in Bucket 3 + .long .Lnames2-.Lnames_entries0 # Offset in Bucket 3 + .long .Lnames3-.Lnames_entries0 # Offset in Bucket 4 + .long .Lnames0-.Lnames_entries0 # Offset in Bucket 5 + .long .Lnames6-.Lnames_entries0 # Offset in Bucket 5 + .long .Lnames4-.Lnames_entries0 # Offset in Bucket 5 +.Lnames_abbrev_start0: + .byte 1 # Abbrev code + .byte 46 # DW_TAG_subprogram + .byte 1 # DW_IDX_compile_unit + .byte 11 # DW_FORM_data1 + .byte 3 # DW_IDX_die_offset + .byte 19 # DW_FORM_ref4 + .byte 4 # DW_IDX_parent + .byte 25 # DW_FORM_flag_present + .byte 0 # End of abbrev + .byte 0 # End of abbrev + .byte 2 # Abbrev code + .byte 36 # DW_TAG_base_type + .byte 1 # DW_IDX_compile_unit + .byte 11 # DW_FORM_data1 + .byte 3 # DW_IDX_die_offset + .byte 19 # DW_FORM_ref4 + .byte 4 # DW_IDX_parent + .byte 25 # DW_FORM_flag_present + .byte 0 # End of abbrev + .byte 0 # End of abbrev + .byte 3 # Abbrev code + .byte 19 # DW_TAG_structure_type + .byte 1 # DW_IDX_compile_unit + .byte 11 # DW_FORM_data1 + .byte 3 # DW_IDX_die_offset + .byte 19 # DW_FORM_ref4 + .byte 4 # DW_IDX_parent + .byte 25 # DW_FORM_flag_present + .byte 0 # End of abbrev + .byte 0 # End of abbrev + .byte 0 # End of abbrev list +.Lnames_abbrev_end0: +.Lnames_entries0: +.Lnames1: +.L3: + .byte 1 # Abbreviation code + .byte 0 # DW_IDX_compile_unit + .long 35 # DW_IDX_die_offset + .byte 0 # DW_IDX_parent + # End of list: _Z2f12t1 +.Lnames5: +.L1: + .byte 2 # Abbreviation code + .byte 1 # DW_IDX_compile_unit + .long 62 # DW_IDX_die_offset + .byte 0 # DW_IDX_parent + # End of list: int +.Lnames2: +.L2: + .byte 1 # Abbreviation code + .byte 1 # DW_IDX_compile_unit + .long 35 # DW_IDX_die_offset + .byte 0 # DW_IDX_parent + # End of list: main +.Lnames3: +.L4: + .byte 1 # Abbreviation code + .byte 2 # DW_IDX_compile_unit + .long 35 # DW_IDX_die_offset + .byte 0 # DW_IDX_parent + # End of list: null +.Lnames0: + .byte 1 # Abbreviation code + .byte 0 # DW_IDX_compile_unit + .long 35 # DW_IDX_die_offset + .byte 0 # DW_IDX_parent + # End of list: f1 +.Lnames6: +.L0: + .byte 3 # Abbreviation code + .byte 0 # DW_IDX_compile_unit + .long 58 # DW_IDX_die_offset + .byte 0 # DW_IDX_parent + # End of list: t1 +.Lnames4: + .byte 1 # Abbreviation code + .byte 2 # DW_IDX_compile_unit + .long 35 # DW_IDX_die_offset + .byte 0 # DW_IDX_parent + # End of list: _Z4nullv + .p2align 2, 0x0 +.Lnames_end0: + .ident "clang version 19.0.0git (git@github.com:llvm/llvm-project.git 58e50c2a7b0a8a63e038dbfc4cb12d81aef1a32d)" + .ident "clang version 19.0.0git (git@github.com:llvm/llvm-project.git 58e50c2a7b0a8a63e038dbfc4cb12d81aef1a32d)" + .ident "clang version 19.0.0git (git@github.com:llvm/llvm-project.git 58e50c2a7b0a8a63e038dbfc4cb12d81aef1a32d)" + .section ".note.GNU-stack","",@progbits + .addrsig + .section .debug_line,"",@progbits +.Lline_table_start0: + +#--- d.s +# Generated with: +# - clang++ -g -gpubnames -fdebug-compilation-dir='/proc/self/cwd' \ +# -S d.cpp -o d.s + +# d.cpp contents: + +# int foo(int x) { return 4; } + + .text + .globl _Z3fooi # -- Begin function _Z3fooi + .p2align 4, 0x90 + .type _Z3fooi,@function +_Z3fooi: # @_Z3fooi +.Lfunc_begin0: + .cfi_startproc +# %bb.0: # %entry + pushq %rbp + .cfi_def_cfa_offset 16 + .cfi_offset %rbp, -16 + movq %rsp, %rbp + .cfi_def_cfa_register %rbp + movl %edi, -4(%rbp) +.Ltmp0: + movl $4, %eax + popq %rbp + .cfi_def_cfa %rsp, 8 + retq +.Ltmp1: +.Lfunc_end0: + .size _Z3fooi, .Lfunc_end0-_Z3fooi + .cfi_endproc + # -- End function + .section .debug_abbrev,"",@progbits + .byte 0 # EOM(1) + .byte 0 # EOM(2) + .byte 0 # EOM(3) + .section .debug_info,"",@progbits +.Lcu_begin0: + .long .Ldebug_info_end0-.Ldebug_info_start0 # Length of Unit +.Ldebug_info_start0: + .short 5 # DWARF version number + .byte 1 # DWARF Unit Type + .byte 8 # Address Size (in bytes) + .long .debug_abbrev # Offset Into Abbrev. Section +.Ldebug_info_end0: + .section .debug_str_offsets,"",@progbits + .long 32 # Length of String Offsets Set + .short 5 + .short 0 +.Lstr_offsets_base0: + .section .debug_str,"MS",@progbits,1 +.Linfo_string0: + .asciz "clang version 19.0.0git (git@github.com:llvm/llvm-project.git 58e50c2a7b0a8a63e038dbfc4cb12d81aef1a32d)" # string offset=0 +.Linfo_string1: + .asciz "d.cpp" # string offset=104 +.Linfo_string2: + .asciz "/proc/self/cwd" # string offset=110 +.Linfo_string3: + .asciz "foo" # string offset=125 +.Linfo_string4: + .asciz "_Z3fooi" # string offset=129 +.Linfo_string5: + .asciz "int" # string offset=137 +.Linfo_string6: + .asciz "x" # string offset=141 +.Laddr_table_base0: + .quad .Lfunc_begin0 +.Ldebug_addr_end0: + .section .debug_names,"",@progbits + .long .Lnames_end0-.Lnames_start0 # Header: unit length +.Lnames_start0: + .short 5 # Header: version + .short 0 # Header: padding + .long 1 # Header: compilation unit count + .long 0 # Header: local type unit count + .long 0 # Header: foreign type unit count + .long 3 # Header: bucket count + .long 3 # Header: name count + .long .Lnames_abbrev_end0-.Lnames_abbrev_start0 # Header: abbreviation table size + .long 8 # Header: augmentation string size + .ascii "LLVM0700" # Header: augmentation string + .long .Lcu_begin0 # Compilation unit 0 + .long 1 # Bucket 0 + .long 0 # Bucket 1 + .long 3 # Bucket 2 + .long 193491849 # Hash in Bucket 0 + .long -1257882370 # Hash in Bucket 0 + .long 193495088 # Hash in Bucket 2 + .long .Linfo_string3 # String in Bucket 0: foo + .long .Linfo_string4 # String in Bucket 0: _Z3fooi + .long .Linfo_string5 # String in Bucket 2: int + .long .Lnames0-.Lnames_entries0 # Offset in Bucket 0 + .long .Lnames1-.Lnames_entries0 # Offset in Bucket 0 + .long .Lnames2-.Lnames_entries0 # Offset in Bucket 2 +.Lnames_abbrev_start0: + .byte 1 # Abbrev code + .byte 46 # DW_TAG_subprogram + .byte 3 # DW_IDX_die_offset + .byte 19 # DW_FORM_ref4 + .byte 4 # DW_IDX_parent + .byte 25 # DW_FORM_flag_present + .byte 0 # End of abbrev + .byte 0 # End of abbrev + .byte 2 # Abbrev code + .byte 36 # DW_TAG_base_type + .byte 3 # DW_IDX_die_offset + .byte 19 # DW_FORM_ref4 + .byte 4 # DW_IDX_parent + .byte 25 # DW_FORM_flag_present + .byte 0 # End of abbrev + .byte 0 # End of abbrev + .byte 0 # End of abbrev list +.Lnames_abbrev_end0: +.Lnames_entries0: +.Lnames0: +.L1: + .byte 1 # Abbreviation code + .long 35 # DW_IDX_die_offset + .byte 0 # DW_IDX_parent + # End of list: foo +.Lnames1: + .byte 1 # Abbreviation code + .long 35 # DW_IDX_die_offset + .byte 0 # DW_IDX_parent + # End of list: _Z3fooi +.Lnames2: +.L0: + .byte 2 # Abbreviation code + .long 63 # DW_IDX_die_offset + .byte 0 # DW_IDX_parent + # End of list: int + .p2align 2, 0x0 +.Lnames_end0: + .ident "clang version 19.0.0git (git@github.com:llvm/llvm-project.git 58e50c2a7b0a8a63e038dbfc4cb12d81aef1a32d)" + .section ".note.GNU-stack","",@progbits + .addrsig + .section .debug_line,"",@progbits +.Lline_table_start0: diff --git a/lld/test/ELF/debug-names-multi-cus-append.s b/lld/test/ELF/debug-names-multi-cus-append.s new file mode 100644 index 0000000000000..de8bd0f939f42 --- /dev/null +++ b/lld/test/ELF/debug-names-multi-cus-append.s @@ -0,0 +1,459 @@ +# This .s files were generated by: + +# clang++ b.cpp -gpubnames b.cpp -g -emit-llvm -c \ +# -fdebug-compilation-dir='/proc/self/cwd +# clang++ c.cpp -gpubnames c.cpp -g -emit-llvm -c \ +# -fdebug-compilation-dir='/proc/self/cwd +# llvm-link b.bc c.bc -o bc.bc +# clang++ bc.bc -S -o bc.s +# clang++ -g -O0 -gpubnames a.cpp -S -o a.s \ +# -fdebug-compilation-dir='/proc/self/cwd +# clang++ -g -O0 -gpubnames d.cpp -S -o d.s \ +# -fdebug-compilation-dir='/proc/self/cwd + +# a.cpp contains: +# struct t1 { }; +# void f1(t1) { } + +# b.cpp contains: +# struct t1 { }; +# int main() { +# t1 v1; +# } + +# c.cpp contains: +# void null() { } + +# d.cpp contains: +# int foo(int x) { return 4; } + +# REQUIRES: x86 +# RUN: rm -rf %t && split-file %s %t && cd %t +# RUN: llvm-mc -filetype=obj -triple=x86_64 a.s -o a.o +# RUN: llvm-mc -filetype=obj -triple=x86_64 bc.s -o bc.o +# RUN: llvm-mc -filetype=obj -triple=x86_64 d.s -o d.o +# RUN: ld.lld -r a.o bc.o -o abc.o +# RUN: ld.lld --debug-names d.o abc.o -o out +# RUN: llvm-dwarfdump --debug-names out \ +# RUN: | FileCheck -DFILE=a.o %s --check-prefix=DWARF + +# DWARF: Compilation Unit offsets [ +# DWARF-NEXT: CU[0]: 0x00000000 +# DWARF-NEXT: CU[1]: 0x00000001 +# DWARF-NEXT: CU[2]: 0x00000002 +# DWARF-NEXT: CU[3]: 0x00000003 +# DWARF-NEXT: ] + +#--- a.s + + .text + .globl _Z2f12t1 # -- Begin function _Z2f12t1 + .p2align 4, 0x90 + .type _Z2f12t1,@function +_Z2f12t1: # @_Z2f12t1 +.Lfunc_begin0: + .cfi_startproc +# %bb.0: # %entry + pushq %rbp + .cfi_def_cfa_offset 16 + .cfi_offset %rbp, -16 + movq %rsp, %rbp + .cfi_def_cfa_register %rbp +.Ltmp0: + popq %rbp + .cfi_def_cfa %rsp, 8 + retq +.Ltmp1: +.Lfunc_end0: + .size _Z2f12t1, .Lfunc_end0-_Z2f12t1 + .cfi_endproc + # -- End function + .section .debug_info,"",@progbits +.Lcu_begin0: + .byte 0 + .section .debug_str,"MS",@progbits,1 +.Linfo_string0: + .asciz "clang version 19.0.0git (git@github.com:llvm/llvm-project.git dfe787af70e11666a8e43ca73a86d1841d364dfc)" # string offset=0 +.Linfo_string1: + .asciz "a.cpp" # string offset=104 +.Linfo_string2: + .asciz "/proc/self/cwd" # string offset=110 +.Linfo_string3: + .asciz "f1" # string offset=125 +.Linfo_string4: + .asciz "_Z2f12t1" # string offset=128 +.Linfo_string5: + .asciz "t1" # string offset=137 + .section .debug_names,"",@progbits + .long .Lnames_end0-.Lnames_start0 # Header: unit length +.Lnames_start0: + .short 5 # Header: version + .short 0 # Header: padding + .long 1 # Header: compilation unit count + .long 0 # Header: local type unit count + .long 0 # Header: foreign type unit count + .long 3 # Header: bucket count + .long 3 # Header: name count + .long .Lnames_abbrev_end0-.Lnames_abbrev_start0 # Header: abbreviation table size + .long 8 # Header: augmentation string size + .ascii "LLVM0700" # Header: augmentation string + .long .Lcu_begin0 # Compilation unit 0 + .long 0 # Bucket 0 + .long 1 # Bucket 1 + .long 3 # Bucket 2 + .long 5863324 # Hash in Bucket 1 + .long 5863786 # Hash in Bucket 1 + .long 1398125246 # Hash in Bucket 2 + .long .Linfo_string3 # String in Bucket 1: f1 + .long .Linfo_string5 # String in Bucket 1: t1 + .long .Linfo_string4 # String in Bucket 2: _Z2f12t1 + .long .Lnames0-.Lnames_entries0 # Offset in Bucket 1 + .long .Lnames2-.Lnames_entries0 # Offset in Bucket 1 + .long .Lnames1-.Lnames_entries0 # Offset in Bucket 2 +.Lnames_abbrev_start0: + .byte 1 # Abbrev code + .byte 46 # DW_TAG_subprogram + .byte 3 # DW_IDX_die_offset + .byte 19 # DW_FORM_ref4 + .byte 4 # DW_IDX_parent + .byte 25 # DW_FORM_flag_present + .byte 0 # End of abbrev + .byte 0 # End of abbrev + .byte 2 # Abbrev code + .byte 19 # DW_TAG_structure_type + .byte 3 # DW_IDX_die_offset + .byte 19 # DW_FORM_ref4 + .byte 4 # DW_IDX_parent + .byte 25 # DW_FORM_flag_present + .byte 0 # End of abbrev + .byte 0 # End of abbrev + .byte 0 # End of abbrev list +.Lnames_abbrev_end0: +.Lnames_entries0: +.Lnames0: +.L1: + .byte 1 # Abbreviation code + .long 35 # DW_IDX_die_offset + .byte 0 # DW_IDX_parent + # End of list: f1 +.Lnames2: +.L0: + .byte 2 # Abbreviation code + .long 58 # DW_IDX_die_offset + .byte 0 # DW_IDX_parent + # End of list: t1 +.Lnames1: + .byte 1 # Abbreviation code + .long 35 # DW_IDX_die_offset + .byte 0 # DW_IDX_parent + # End of list: _Z2f12t1 + .p2align 2, 0x0 +.Lnames_end0: + .ident "clang version 19.0.0git (git@github.com:llvm/llvm-project.git dfe787af70e11666a8e43ca73a86d1841d364dfc)" + .section ".note.GNU-stack","",@progbits + .addrsig + .section .debug_line,"",@progbits +.Lline_table_start0: + +#--- bc.s + + .text + .globl main # -- Begin function main + .p2align 4, 0x90 + .type main,@function +main: # @main +.Lfunc_begin0: + .cfi_startproc +# %bb.0: # %entry + pushq %rbp + .cfi_def_cfa_offset 16 + .cfi_offset %rbp, -16 + movq %rsp, %rbp + .cfi_def_cfa_register %rbp +.Ltmp0: + xorl %eax, %eax + popq %rbp + .cfi_def_cfa %rsp, 8 + retq +.Ltmp1: +.Lfunc_end0: + .size main, .Lfunc_end0-main + .cfi_endproc + # -- End function + .globl _Z4nullv # -- Begin function _Z4nullv + .p2align 4, 0x90 + .type _Z4nullv,@function +_Z4nullv: # @_Z4nullv +.Lfunc_begin1: + .cfi_startproc +# %bb.0: # %entry + pushq %rbp + .cfi_def_cfa_offset 16 + .cfi_offset %rbp, -16 + movq %rsp, %rbp + .cfi_def_cfa_register %rbp +.Ltmp2: + popq %rbp + .cfi_def_cfa %rsp, 8 + retq +.Ltmp3: +.Lfunc_end1: + .size _Z4nullv, .Lfunc_end1-_Z4nullv + .cfi_endproc + # -- End function + .section .debug_info,"",@progbits +.Lcu_begin0: + .byte 0 +.Lcu_begin1: + .byte 0 + .section .debug_str,"MS",@progbits,1 +.Linfo_string0: + .asciz "clang version 19.0.0git (git@github.com:llvm/llvm-project.git dfe787af70e11666a8e43ca73a86d1841d364dfc)" # string offset=0 +.Linfo_string1: + .asciz "b.cpp" # string offset=104 +.Linfo_string2: + .asciz "/proc/self/cwd" # string offset=110 +.Linfo_string3: + .asciz "main" # string offset=125 +.Linfo_string4: + .asciz "c.cpp" # string offset=130 +.Linfo_string5: + .asciz "null" # string offset=136 +.Linfo_string6: + .asciz "_Z4nullv" # string offset=141 +.Linfo_string7: + .asciz "int" # string offset=150 +.Linfo_string8: + .asciz "v1" # string offset=154 +.Linfo_string9: + .asciz "t1" # string offset=157 +.Laddr_table_base0: + .quad .Lfunc_begin0 + .quad .Lfunc_begin1 +.Ldebug_addr_end0: + .section .debug_names,"",@progbits + .long .Lnames_end0-.Lnames_start0 # Header: unit length +.Lnames_start0: + .short 5 # Header: version + .short 0 # Header: padding + .long 2 # Header: compilation unit count + .long 0 # Header: local type unit count + .long 0 # Header: foreign type unit count + .long 5 # Header: bucket count + .long 5 # Header: name count + .long .Lnames_abbrev_end0-.Lnames_abbrev_start0 # Header: abbreviation table size + .long 8 # Header: augmentation string size + .ascii "LLVM0700" # Header: augmentation string + .long .Lcu_begin0 # Compilation unit 0 + .long .Lcu_begin1 # Compilation unit 1 + .long 1 # Bucket 0 + .long 2 # Bucket 1 + .long 0 # Bucket 2 + .long 4 # Bucket 3 + .long 0 # Bucket 4 + .long 2090557760 # Hash in Bucket 0 + .long 5863786 # Hash in Bucket 1 + .long 2090499946 # Hash in Bucket 1 + .long 193495088 # Hash in Bucket 3 + .long 1488390083 # Hash in Bucket 3 + .long .Linfo_string5 # String in Bucket 0: null + .long .Linfo_string9 # String in Bucket 1: t1 + .long .Linfo_string3 # String in Bucket 1: main + .long .Linfo_string7 # String in Bucket 3: int + .long .Linfo_string6 # String in Bucket 3: _Z4nullv + .long .Lnames1-.Lnames_entries0 # Offset in Bucket 0 + .long .Lnames4-.Lnames_entries0 # Offset in Bucket 1 + .long .Lnames0-.Lnames_entries0 # Offset in Bucket 1 + .long .Lnames3-.Lnames_entries0 # Offset in Bucket 3 + .long .Lnames2-.Lnames_entries0 # Offset in Bucket 3 +.Lnames_abbrev_start0: + .byte 1 # Abbrev code + .byte 46 # DW_TAG_subprogram + .byte 1 # DW_IDX_compile_unit + .byte 11 # DW_FORM_data1 + .byte 3 # DW_IDX_die_offset + .byte 19 # DW_FORM_ref4 + .byte 4 # DW_IDX_parent + .byte 25 # DW_FORM_flag_present + .byte 0 # End of abbrev + .byte 0 # End of abbrev + .byte 2 # Abbrev code + .byte 19 # DW_TAG_structure_type + .byte 1 # DW_IDX_compile_unit + .byte 11 # DW_FORM_data1 + .byte 3 # DW_IDX_die_offset + .byte 19 # DW_FORM_ref4 + .byte 4 # DW_IDX_parent + .byte 25 # DW_FORM_flag_present + .byte 0 # End of abbrev + .byte 0 # End of abbrev + .byte 3 # Abbrev code + .byte 36 # DW_TAG_base_type + .byte 1 # DW_IDX_compile_unit + .byte 11 # DW_FORM_data1 + .byte 3 # DW_IDX_die_offset + .byte 19 # DW_FORM_ref4 + .byte 4 # DW_IDX_parent + .byte 25 # DW_FORM_flag_present + .byte 0 # End of abbrev + .byte 0 # End of abbrev + .byte 0 # End of abbrev list +.Lnames_abbrev_end0: +.Lnames_entries0: +.Lnames1: +.L2: + .byte 1 # Abbreviation code + .byte 1 # DW_IDX_compile_unit + .long 35 # DW_IDX_die_offset + .byte 0 # DW_IDX_parent + # End of list: null +.Lnames4: +.L1: + .byte 2 # Abbreviation code + .byte 0 # DW_IDX_compile_unit + .long 66 # DW_IDX_die_offset + .byte 0 # DW_IDX_parent + # End of list: t1 +.Lnames0: +.L3: + .byte 1 # Abbreviation code + .byte 0 # DW_IDX_compile_unit + .long 35 # DW_IDX_die_offset + .byte 0 # DW_IDX_parent + # End of list: main +.Lnames3: +.L0: + .byte 3 # Abbreviation code + .byte 0 # DW_IDX_compile_unit + .long 62 # DW_IDX_die_offset + .byte 0 # DW_IDX_parent + # End of list: int +.Lnames2: + .byte 1 # Abbreviation code + .byte 1 # DW_IDX_compile_unit + .long 35 # DW_IDX_die_offset + .byte 0 # DW_IDX_parent + # End of list: _Z4nullv + .p2align 2, 0x0 +.Lnames_end0: + .ident "clang version 19.0.0git (git@github.com:llvm/llvm-project.git dfe787af70e11666a8e43ca73a86d1841d364dfc)" + .ident "clang version 19.0.0git (git@github.com:llvm/llvm-project.git dfe787af70e11666a8e43ca73a86d1841d364dfc)" + .section ".note.GNU-stack","",@progbits + .addrsig + .section .debug_line,"",@progbits +.Lline_table_start0: + +#--- d.s + + .text + .globl _Z3fooi # -- Begin function _Z3fooi + .p2align 4, 0x90 + .type _Z3fooi,@function +_Z3fooi: # @_Z3fooi +.Lfunc_begin0: + .cfi_startproc +# %bb.0: # %entry + pushq %rbp + .cfi_def_cfa_offset 16 + .cfi_offset %rbp, -16 + movq %rsp, %rbp + .cfi_def_cfa_register %rbp + movl %edi, -4(%rbp) +.Ltmp0: + movl $4, %eax + popq %rbp + .cfi_def_cfa %rsp, 8 + retq +.Ltmp1: +.Lfunc_end0: + .size _Z3fooi, .Lfunc_end0-_Z3fooi + .cfi_endproc + # -- End function + .section .debug_info,"",@progbits +.Lcu_begin0: + .byte 0 + .section .debug_str,"MS",@progbits,1 +.Linfo_string0: + .asciz "clang version 19.0.0git (git@github.com:llvm/llvm-project.git 58e50c2a7b0a8a63e038dbfc4cb12d81aef1a32d)" # string offset=0 +.Linfo_string1: + .asciz "d.cpp" # string offset=104 +.Linfo_string2: + .asciz "/proc/self/cwd" # string offset=110 +.Linfo_string3: + .asciz "foo" # string offset=125 +.Linfo_string4: + .asciz "_Z3fooi" # string offset=129 +.Linfo_string5: + .asciz "int" # string offset=137 +.Linfo_string6: + .asciz "x" # string offset=141 + .section .debug_names,"",@progbits + .long .Lnames_end0-.Lnames_start0 # Header: unit length +.Lnames_start0: + .short 5 # Header: version + .short 0 # Header: padding + .long 1 # Header: compilation unit count + .long 0 # Header: local type unit count + .long 0 # Header: foreign type unit count + .long 3 # Header: bucket count + .long 3 # Header: name count + .long .Lnames_abbrev_end0-.Lnames_abbrev_start0 # Header: abbreviation table size + .long 8 # Header: augmentation string size + .ascii "LLVM0700" # Header: augmentation string + .long .Lcu_begin0 # Compilation unit 0 + .long 1 # Bucket 0 + .long 0 # Bucket 1 + .long 3 # Bucket 2 + .long 193491849 # Hash in Bucket 0 + .long -1257882370 # Hash in Bucket 0 + .long 193495088 # Hash in Bucket 2 + .long .Linfo_string3 # String in Bucket 0: foo + .long .Linfo_string4 # String in Bucket 0: _Z3fooi + .long .Linfo_string5 # String in Bucket 2: int + .long .Lnames0-.Lnames_entries0 # Offset in Bucket 0 + .long .Lnames1-.Lnames_entries0 # Offset in Bucket 0 + .long .Lnames2-.Lnames_entries0 # Offset in Bucket 2 +.Lnames_abbrev_start0: + .byte 1 # Abbrev code + .byte 46 # DW_TAG_subprogram + .byte 3 # DW_IDX_die_offset + .byte 19 # DW_FORM_ref4 + .byte 4 # DW_IDX_parent + .byte 25 # DW_FORM_flag_present + .byte 0 # End of abbrev + .byte 0 # End of abbrev + .byte 2 # Abbrev code + .byte 36 # DW_TAG_base_type + .byte 3 # DW_IDX_die_offset + .byte 19 # DW_FORM_ref4 + .byte 4 # DW_IDX_parent + .byte 25 # DW_FORM_flag_present + .byte 0 # End of abbrev + .byte 0 # End of abbrev + .byte 0 # End of abbrev list +.Lnames_abbrev_end0: +.Lnames_entries0: +.Lnames0: +.L1: + .byte 1 # Abbreviation code + .long 35 # DW_IDX_die_offset + .byte 0 # DW_IDX_parent + # End of list: foo +.Lnames1: + .byte 1 # Abbreviation code + .long 35 # DW_IDX_die_offset + .byte 0 # DW_IDX_parent + # End of list: _Z3fooi +.Lnames2: +.L0: + .byte 2 # Abbreviation code + .long 63 # DW_IDX_die_offset + .byte 0 # DW_IDX_parent + # End of list: int + .p2align 2, 0x0 +.Lnames_end0: + .ident "clang version 19.0.0git (git@github.com:llvm/llvm-project.git 58e50c2a7b0a8a63e038dbfc4cb12d81aef1a32d)" + .section ".note.GNU-stack","",@progbits + .addrsig + .section .debug_line,"",@progbits +.Lline_table_start0: diff --git a/lld/test/ELF/debug-names-multi-cus-long.s b/lld/test/ELF/debug-names-multi-cus-long.s new file mode 100644 index 0000000000000..563e1ee2c17a6 --- /dev/null +++ b/lld/test/ELF/debug-names-multi-cus-long.s @@ -0,0 +1,563 @@ +# The .s files were generated by: + +# clang++ a.cpp -gpubnames a.cpp -g -emit-llvm -c \ +# -fdebug-compilation-dir='/proc/self/cwd +# clang++ b.cpp -gpubnames b.cpp -g -emit-llvm -c \ +# -fdebug-compilation-dir='/proc/self/cwd +1# clang++ c.cpp -gpubnames c.cpp -g -emit-llvm -c \ +# -fdebug-compilation-dir='/proc/self/cwd' +# llvm-link a.bc b.bc c.bc -o abc.bc +# clang++ abc.bc -S -o abc.s + +# clang++ d.cpp -gpubnames d.cpp -g -emit-llvm -c \ +# -fdebug-compilation-dir='/proc/self/cwd +# clang++ e.cpp -gpubnames e.cpp -g -emit-llvm -c \ +# -fdebug-compilation-dir='/proc/self/cwd +# llvm-link d.bc e.bc -o de.bc +# clang++ de.bc -S -o de.s + +# clang++ -g -gpubnames -fdebug-compilation-dir='/proc/self/cwd' \ +# -S f.cpp -o f.s + +# a.cpp contains: +# struct t1 { }; +# void f1(t1) { } + +# b.cpp contains: +# struct t1 { }; +# int main() { +# t1 v1; +# } + +# c.cpp contains: +# void null() { } + +# d.cpp contents: +# int foo(int x) { return 4; } + +# e.cpp contains: +# void bar(void *) {} + +# f.cpp contains +# void baz() { } + +# REQUIRES: x86 +# RUN: rm -rf %t && split-file %s %t && cd %t +# RUN: llvm-mc -filetype=obj -triple=x86_64 abc.s -o abc.o +# RUN: llvm-mc -filetype=obj -triple=x86_64 de.s -o de.o +# RUN: llvm-mc -filetype=obj -triple=x86_64 f.s -o f.o +# RUN: ld.lld --debug-names abc.o de.o f.o -o out +# RUN: llvm-dwarfdump --debug-names out \ +# RUN: | FileCheck %s --check-prefix=DWARF + +# DWARF: Compilation Unit offsets [ +# DWARF-NEXT: CU[0]: 0x00000000 +# DWARF-NEXT: CU[1]: 0x00000001 +# DWARF-NEXT: CU[2]: 0x00000002 +# DWARF-NEXT: CU[3]: 0x00000003 +# DWARF-NEXT: CU[4]: 0x00000004 +# DWARF-NEXT: CU[5]: 0x00000005 +# DWARF-NEXT: ] + +#--- abc.s + + .text + .globl _Z2f12t1 # -- Begin function _Z2f12t1 + .p2align 4, 0x90 + .type _Z2f12t1,@function +_Z2f12t1: # @_Z2f12t1 +.Lfunc_begin0: + .cfi_startproc +# %bb.0: # %entry + pushq %rbp + .cfi_def_cfa_offset 16 + .cfi_offset %rbp, -16 + movq %rsp, %rbp + .cfi_def_cfa_register %rbp +.Ltmp0: + popq %rbp + .cfi_def_cfa %rsp, 8 + retq +.Ltmp1: +.Lfunc_end0: + .size _Z2f12t1, .Lfunc_end0-_Z2f12t1 + .cfi_endproc + # -- End function + .globl main # -- Begin function main + .p2align 4, 0x90 + .type main,@function +main: # @main +.Lfunc_begin1: + .cfi_startproc +# %bb.0: # %entry + pushq %rbp + .cfi_def_cfa_offset 16 + .cfi_offset %rbp, -16 + movq %rsp, %rbp + .cfi_def_cfa_register %rbp +.Ltmp2: + xorl %eax, %eax + popq %rbp + .cfi_def_cfa %rsp, 8 + retq +.Ltmp3: +.Lfunc_end1: + .size main, .Lfunc_end1-main + .cfi_endproc + # -- End function + .globl _Z4nullv # -- Begin function _Z4nullv + .p2align 4, 0x90 + .type _Z4nullv,@function +_Z4nullv: # @_Z4nullv +.Lfunc_begin2: + .cfi_startproc +# %bb.0: # %entry + pushq %rbp + .cfi_def_cfa_offset 16 + .cfi_offset %rbp, -16 + movq %rsp, %rbp + .cfi_def_cfa_register %rbp +.Ltmp4: + popq %rbp + .cfi_def_cfa %rsp, 8 + retq +.Ltmp5: +.Lfunc_end2: + .size _Z4nullv, .Lfunc_end2-_Z4nullv + .cfi_endproc + # -- End function + .section .debug_info,"",@progbits +.Lcu_begin0: + .byte 0 +.Lcu_begin1: + .byte 0 +.Lcu_begin2: + .byte 0 + .section .debug_str,"MS",@progbits,1 +.Linfo_string0: + .asciz "clang version 19.0.0git (git@github.com:llvm/llvm-project.git dfe787af70e11666a8e43ca73a86d1841d364dfc)" # string offset=0 +.Linfo_string1: + .asciz "a.cpp" # string offset=104 +.Linfo_string2: + .asciz "/proc/self/cwd" # string offset=110 +.Linfo_string3: + .asciz "f1" # string offset=125 +.Linfo_string4: + .asciz "_Z2f12t1" # string offset=128 +.Linfo_string5: + .asciz "b.cpp" # string offset=137 +.Linfo_string6: + .asciz "main" # string offset=143 +.Linfo_string7: + .asciz "c.cpp" # string offset=148 +.Linfo_string8: + .asciz "null" # string offset=154 +.Linfo_string9: + .asciz "_Z4nullv" # string offset=159 +.Linfo_string10: + .asciz "int" # string offset=168 +.Linfo_string11: + .asciz "t1" # string offset=172 +.Linfo_string12: + .asciz "v1" # string offset=175 + .section .debug_names,"",@progbits + .long .Lnames_end0-.Lnames_start0 # Header: unit length +.Lnames_start0: + .short 5 # Header: version + .short 0 # Header: padding + .long 3 # Header: compilation unit count + .long 0 # Header: local type unit count + .long 0 # Header: foreign type unit count + .long 7 # Header: bucket count + .long 7 # Header: name count + .long .Lnames_abbrev_end0-.Lnames_abbrev_start0 # Header: abbreviation table size + .long 8 # Header: augmentation string size + .ascii "LLVM0700" # Header: augmentation string + .long .Lcu_begin0 # Compilation unit 0 + .long .Lcu_begin1 # Compilation unit 1 + .long .Lcu_begin2 # Compilation unit 2 + .long 1 # Bucket 0 + .long 0 # Bucket 1 + .long 0 # Bucket 2 + .long 2 # Bucket 3 + .long 4 # Bucket 4 + .long 5 # Bucket 5 + .long 0 # Bucket 6 + .long 1398125246 # Hash in Bucket 0 + .long 193495088 # Hash in Bucket 3 + .long 2090499946 # Hash in Bucket 3 + .long 2090557760 # Hash in Bucket 4 + .long 5863324 # Hash in Bucket 5 + .long 5863786 # Hash in Bucket 5 + .long 1488390083 # Hash in Bucket 5 + .long .Linfo_string4 # String in Bucket 0: _Z2f12t1 + .long .Linfo_string10 # String in Bucket 3: int + .long .Linfo_string6 # String in Bucket 3: main + .long .Linfo_string8 # String in Bucket 4: null + .long .Linfo_string3 # String in Bucket 5: f1 + .long .Linfo_string11 # String in Bucket 5: t1 + .long .Linfo_string9 # String in Bucket 5: _Z4nullv + .long .Lnames1-.Lnames_entries0 # Offset in Bucket 0 + .long .Lnames5-.Lnames_entries0 # Offset in Bucket 3 + .long .Lnames2-.Lnames_entries0 # Offset in Bucket 3 + .long .Lnames3-.Lnames_entries0 # Offset in Bucket 4 + .long .Lnames0-.Lnames_entries0 # Offset in Bucket 5 + .long .Lnames6-.Lnames_entries0 # Offset in Bucket 5 + .long .Lnames4-.Lnames_entries0 # Offset in Bucket 5 +.Lnames_abbrev_start0: + .byte 1 # Abbrev code + .byte 46 # DW_TAG_subprogram + .byte 1 # DW_IDX_compile_unit + .byte 11 # DW_FORM_data1 + .byte 3 # DW_IDX_die_offset + .byte 19 # DW_FORM_ref4 + .byte 4 # DW_IDX_parent + .byte 25 # DW_FORM_flag_present + .byte 0 # End of abbrev + .byte 0 # End of abbrev + .byte 2 # Abbrev code + .byte 36 # DW_TAG_base_type + .byte 1 # DW_IDX_compile_unit + .byte 11 # DW_FORM_data1 + .byte 3 # DW_IDX_die_offset + .byte 19 # DW_FORM_ref4 + .byte 4 # DW_IDX_parent + .byte 25 # DW_FORM_flag_present + .byte 0 # End of abbrev + .byte 0 # End of abbrev + .byte 3 # Abbrev code + .byte 19 # DW_TAG_structure_type + .byte 1 # DW_IDX_compile_unit + .byte 11 # DW_FORM_data1 + .byte 3 # DW_IDX_die_offset + .byte 19 # DW_FORM_ref4 + .byte 4 # DW_IDX_parent + .byte 25 # DW_FORM_flag_present + .byte 0 # End of abbrev + .byte 0 # End of abbrev + .byte 0 # End of abbrev list +.Lnames_abbrev_end0: +.Lnames_entries0: +.Lnames1: +.L3: + .byte 1 # Abbreviation code + .byte 0 # DW_IDX_compile_unit + .long 35 # DW_IDX_die_offset + .byte 0 # DW_IDX_parent + # End of list: _Z2f12t1 +.Lnames5: +.L1: + .byte 2 # Abbreviation code + .byte 1 # DW_IDX_compile_unit + .long 62 # DW_IDX_die_offset + .byte 0 # DW_IDX_parent + # End of list: int +.Lnames2: +.L2: + .byte 1 # Abbreviation code + .byte 1 # DW_IDX_compile_unit + .long 35 # DW_IDX_die_offset + .byte 0 # DW_IDX_parent + # End of list: main +.Lnames3: +.L4: + .byte 1 # Abbreviation code + .byte 2 # DW_IDX_compile_unit + .long 35 # DW_IDX_die_offset + .byte 0 # DW_IDX_parent + # End of list: null +.Lnames0: + .byte 1 # Abbreviation code + .byte 0 # DW_IDX_compile_unit + .long 35 # DW_IDX_die_offset + .byte 0 # DW_IDX_parent + # End of list: f1 +.Lnames6: +.L0: + .byte 3 # Abbreviation code + .byte 0 # DW_IDX_compile_unit + .long 58 # DW_IDX_die_offset + .byte 0 # DW_IDX_parent + # End of list: t1 +.Lnames4: + .byte 1 # Abbreviation code + .byte 2 # DW_IDX_compile_unit + .long 35 # DW_IDX_die_offset + .byte 0 # DW_IDX_parent + # End of list: _Z4nullv + .p2align 2, 0x0 +.Lnames_end0: + .ident "clang version 19.0.0git (git@github.com:llvm/llvm-project.git dfe787af70e11666a8e43ca73a86d1841d364dfc)" + .ident "clang version 19.0.0git (git@github.com:llvm/llvm-project.git dfe787af70e11666a8e43ca73a86d1841d364dfc)" + .ident "clang version 19.0.0git (git@github.com:llvm/llvm-project.git dfe787af70e11666a8e43ca73a86d1841d364dfc)" + .section ".note.GNU-stack","",@progbits + .addrsig + .section .debug_line,"",@progbits +.Lline_table_start0: + +#--- de.s + + .text + .globl _Z3fooi # -- Begin function _Z3fooi + .p2align 4, 0x90 + .type _Z3fooi,@function +_Z3fooi: # @_Z3fooi +.Lfunc_begin0: + .cfi_startproc +# %bb.0: # %entry + pushq %rbp + .cfi_def_cfa_offset 16 + .cfi_offset %rbp, -16 + movq %rsp, %rbp + .cfi_def_cfa_register %rbp + movl %edi, -4(%rbp) +.Ltmp0: + movl $4, %eax + popq %rbp + .cfi_def_cfa %rsp, 8 + retq +.Ltmp1: +.Lfunc_end0: + .size _Z3fooi, .Lfunc_end0-_Z3fooi + .cfi_endproc + # -- End function + .globl _Z3barPv # -- Begin function _Z3barPv + .p2align 4, 0x90 + .type _Z3barPv,@function +_Z3barPv: # @_Z3barPv +.Lfunc_begin1: + .cfi_startproc +# %bb.0: # %entry + pushq %rbp + .cfi_def_cfa_offset 16 + .cfi_offset %rbp, -16 + movq %rsp, %rbp + .cfi_def_cfa_register %rbp + movq %rdi, -8(%rbp) +.Ltmp2: + popq %rbp + .cfi_def_cfa %rsp, 8 + retq +.Ltmp3: +.Lfunc_end1: + .size _Z3barPv, .Lfunc_end1-_Z3barPv + .cfi_endproc + # -- End function + .section .debug_info,"",@progbits +.Lcu_begin0: + .byte 0 +.Lcu_begin1: + .byte 0 + .section .debug_str,"MS",@progbits,1 +.Linfo_string0: + .asciz "clang version 19.0.0git (git@github.com:llvm/llvm-project.git dfe787af70e11666a8e43ca73a86d1841d364dfc)" # string offset=0 +.Linfo_string1: + .asciz "d.cpp" # string offset=104 +.Linfo_string2: + .asciz "/proc/self/cwd" # string offset=110 +.Linfo_string3: + .asciz "foo" # string offset=125 +.Linfo_string4: + .asciz "_Z3fooi" # string offset=129 +.Linfo_string5: + .asciz "e.cpp" # string offset=137 +.Linfo_string6: + .asciz "bar" # string offset=143 +.Linfo_string7: + .asciz "_Z3barPv" # string offset=147 +.Linfo_string8: + .asciz "int" # string offset=156 +.Linfo_string9: + .asciz "x" # string offset=160 + .section .debug_names,"",@progbits + .long .Lnames_end0-.Lnames_start0 # Header: unit length +.Lnames_start0: + .short 5 # Header: version + .short 0 # Header: padding + .long 2 # Header: compilation unit count + .long 0 # Header: local type unit count + .long 0 # Header: foreign type unit count + .long 5 # Header: bucket count + .long 5 # Header: name count + .long .Lnames_abbrev_end0-.Lnames_abbrev_start0 # Header: abbreviation table size + .long 8 # Header: augmentation string size + .ascii "LLVM0700" # Header: augmentation string + .long .Lcu_begin0 # Compilation unit 0 + .long .Lcu_begin1 # Compilation unit 1 + .long 0 # Bucket 0 + .long 1 # Bucket 1 + .long 0 # Bucket 2 + .long 2 # Bucket 3 + .long 3 # Bucket 4 + .long -1257882370 # Hash in Bucket 1 + .long 193495088 # Hash in Bucket 3 + .long 193487034 # Hash in Bucket 4 + .long 193491849 # Hash in Bucket 4 + .long 1434311564 # Hash in Bucket 4 + .long .Linfo_string4 # String in Bucket 1: _Z3fooi + .long .Linfo_string8 # String in Bucket 3: int + .long .Linfo_string6 # String in Bucket 4: bar + .long .Linfo_string3 # String in Bucket 4: foo + .long .Linfo_string7 # String in Bucket 4: _Z3barPv + .long .Lnames1-.Lnames_entries0 # Offset in Bucket 1 + .long .Lnames4-.Lnames_entries0 # Offset in Bucket 3 + .long .Lnames2-.Lnames_entries0 # Offset in Bucket 4 + .long .Lnames0-.Lnames_entries0 # Offset in Bucket 4 + .long .Lnames3-.Lnames_entries0 # Offset in Bucket 4 +.Lnames_abbrev_start0: + .byte 1 # Abbrev code + .byte 46 # DW_TAG_subprogram + .byte 1 # DW_IDX_compile_unit + .byte 11 # DW_FORM_data1 + .byte 3 # DW_IDX_die_offset + .byte 19 # DW_FORM_ref4 + .byte 4 # DW_IDX_parent + .byte 25 # DW_FORM_flag_present + .byte 0 # End of abbrev + .byte 0 # End of abbrev + .byte 2 # Abbrev code + .byte 36 # DW_TAG_base_type + .byte 1 # DW_IDX_compile_unit + .byte 11 # DW_FORM_data1 + .byte 3 # DW_IDX_die_offset + .byte 19 # DW_FORM_ref4 + .byte 4 # DW_IDX_parent + .byte 25 # DW_FORM_flag_present + .byte 0 # End of abbrev + .byte 0 # End of abbrev + .byte 0 # End of abbrev list +.Lnames_abbrev_end0: +.Lnames_entries0: +.Lnames1: +.L2: + .byte 1 # Abbreviation code + .byte 0 # DW_IDX_compile_unit + .long 35 # DW_IDX_die_offset + .byte 0 # DW_IDX_parent + # End of list: _Z3fooi +.Lnames4: +.L0: + .byte 2 # Abbreviation code + .byte 0 # DW_IDX_compile_unit + .long 63 # DW_IDX_die_offset + .byte 0 # DW_IDX_parent + # End of list: int +.Lnames2: +.L1: + .byte 1 # Abbreviation code + .byte 1 # DW_IDX_compile_unit + .long 35 # DW_IDX_die_offset + .byte 0 # DW_IDX_parent + # End of list: bar +.Lnames0: + .byte 1 # Abbreviation code + .byte 0 # DW_IDX_compile_unit + .long 35 # DW_IDX_die_offset + .byte 0 # DW_IDX_parent + # End of list: foo +.Lnames3: + .byte 1 # Abbreviation code + .byte 1 # DW_IDX_compile_unit + .long 35 # DW_IDX_die_offset + .byte 0 # DW_IDX_parent + # End of list: _Z3barPv + .p2align 2, 0x0 +.Lnames_end0: + .ident "clang version 19.0.0git (git@github.com:llvm/llvm-project.git dfe787af70e11666a8e43ca73a86d1841d364dfc)" + .ident "clang version 19.0.0git (git@github.com:llvm/llvm-project.git dfe787af70e11666a8e43ca73a86d1841d364dfc)" + .section ".note.GNU-stack","",@progbits + .addrsig + .section .debug_line,"",@progbits +.Lline_table_start0: + +#--- f.s + + .text + .globl _Z3bazv # -- Begin function _Z3bazv + .p2align 4, 0x90 + .type _Z3bazv,@function +_Z3bazv: # @_Z3bazv +.Lfunc_begin0: + .cfi_startproc +# %bb.0: # %entry + pushq %rbp + .cfi_def_cfa_offset 16 + .cfi_offset %rbp, -16 + movq %rsp, %rbp + .cfi_def_cfa_register %rbp +.Ltmp0: + popq %rbp + .cfi_def_cfa %rsp, 8 + retq +.Ltmp1: +.Lfunc_end0: + .size _Z3bazv, .Lfunc_end0-_Z3bazv + .cfi_endproc + # -- End function + .section .debug_info,"",@progbits +.Lcu_begin0: + .byte 0 + .section .debug_str,"MS",@progbits,1 +.Linfo_string0: + .asciz "clang version 19.0.0git (git@github.com:llvm/llvm-project.git dfe787af70e11666a8e43ca73a86d1841d364dfc)" # string offset=0 +.Linfo_string1: + .asciz "f.cpp" # string offset=104 +.Linfo_string2: + .asciz "/proc/self/cwd" # string offset=110 +.Linfo_string3: + .asciz "baz" # string offset=125 +.Linfo_string4: + .asciz "_Z3bazv" # string offset=129 + .section .debug_names,"",@progbits + .long .Lnames_end0-.Lnames_start0 # Header: unit length +.Lnames_start0: + .short 5 # Header: version + .short 0 # Header: padding + .long 1 # Header: compilation unit count + .long 0 # Header: local type unit count + .long 0 # Header: foreign type unit count + .long 2 # Header: bucket count + .long 2 # Header: name count + .long .Lnames_abbrev_end0-.Lnames_abbrev_start0 # Header: abbreviation table size + .long 8 # Header: augmentation string size + .ascii "LLVM0700" # Header: augmentation string + .long .Lcu_begin0 # Compilation unit 0 + .long 1 # Bucket 0 + .long 0 # Bucket 1 + .long 193487042 # Hash in Bucket 0 + .long -1258040988 # Hash in Bucket 0 + .long .Linfo_string3 # String in Bucket 0: baz + .long .Linfo_string4 # String in Bucket 0: _Z3bazv + .long .Lnames0-.Lnames_entries0 # Offset in Bucket 0 + .long .Lnames1-.Lnames_entries0 # Offset in Bucket 0 +.Lnames_abbrev_start0: + .byte 1 # Abbrev code + .byte 46 # DW_TAG_subprogram + .byte 3 # DW_IDX_die_offset + .byte 19 # DW_FORM_ref4 + .byte 4 # DW_IDX_parent + .byte 25 # DW_FORM_flag_present + .byte 0 # End of abbrev + .byte 0 # End of abbrev + .byte 0 # End of abbrev list +.Lnames_abbrev_end0: +.Lnames_entries0: +.Lnames0: +.L0: + .byte 1 # Abbreviation code + .long 35 # DW_IDX_die_offset + .byte 0 # DW_IDX_parent + # End of list: baz +.Lnames1: + .byte 1 # Abbreviation code + .long 35 # DW_IDX_die_offset + .byte 0 # DW_IDX_parent + # End of list: _Z3bazv + .p2align 2, 0x0 +.Lnames_end0: + .ident "clang version 19.0.0git (git@github.com:llvm/llvm-project.git dfe787af70e11666a8e43ca73a86d1841d364dfc)" + .section ".note.GNU-stack","",@progbits + .addrsig + .section .debug_line,"",@progbits +.Lline_table_start0: + diff --git a/lld/test/ELF/debug-names-nonames.s b/lld/test/ELF/debug-names-nonames.s new file mode 100644 index 0000000000000..be658ae761496 --- /dev/null +++ b/lld/test/ELF/debug-names-nonames.s @@ -0,0 +1,228 @@ +# The .s files were generated with: + +# - clang++ -g -gpubnames -fdebug-compilation-dir='/proc/self/cwd' \ +# -S a.cpp -o a.names.s + +# - clang++ -O0 -S a.cpp -o a.nonames.s + +# - clang++ -O0 -S b.cpp -o b.s + +# a.cpp contents: + +# struct t1 { }; +# void f1(t1) { } + +# b.cpp contents: +# struct t1 { }; +# int main() { +# t1 v1; +# } +# + +# REQUIRES: x86 +# RUN: rm -rf %t && split-file %s %t && cd %t +# RUN: llvm-mc -filetype=obj -triple=x86_64 a.names.s -o a.names.o +# RUN: llvm-mc -filetype=obj -triple=x86_64 a.nonames.s -o a.nonames.o +# RUN: llvm-mc -filetype=obj -triple=x86_64 b.s -o b.o + +# Test one file with .debug_names and one file without. +# RUN: ld.lld --debug-names a.names.o b.o -o out0 +# RUN: llvm-readelf -SW out0 | FileCheck %s --check-prefix=ELF1 +# RUN: llvm-dwarfdump -debug-names out0 | FileCheck %s --check-prefix=DWARF + +# DWARF: .debug_names contents: +# DWARF-NEXT: Name Index @ 0x0 { +# DWARF-NEXT: Header { +# DWARF-NEXT: Length: 0x86 +# DWARF-NEXT: Format: DWARF32 +# DWARF-NEXT: Version: 5 +# DWARF-NEXT: CU count: 1 +# DWARF-NEXT: Local TU count: 0 +# DWARF-NEXT: Foreign TU count: 0 +# DWARF-NEXT: Bucket count: 3 +# DWARF-NEXT: Name count: 3 +# DWARF-NEXT: Abbreviations table size: 0x15 +# DWARF-NEXT: Augmentation: 'LLVM0700' +# DWARF-NEXT: } +# DWARF-NEXT: Compilation Unit offsets [ +# DWARF-NEXT: CU[0]: 0x00000000 +# DWARF-NEXT: ] + +# ELF1: Name Type Address Off Size ES Flg Lk Inf Al +# ELF1: .debug_names PROGBITS 0000000000000000 [[#%x,]] 00008a 00 0 0 4 + +# Test both files without .debug_names. +# RUN: ld.lld --debug-names a.nonames.o b.o -o out +# RUN: llvm-readelf -SW out | FileCheck %s --check-prefix=ELF2 + +# Verify that there not a .debug_names section in the ELF file. +# ELF2: Name Type Address Off Size ES Flg Lk Inf Al +# ELF2: [ 1] .eh_frame PROGBITS 0000000000200120 000120 00005c 00 A 0 0 8 +# ELF2-NEXT: [ 2] .text PROGBITS 0000000000201180 000180 000018 00 AX 0 0 16 +# ELF2-NEXT: [ 3] .comment PROGBITS 0000000000000000 000198 000071 01 MS 0 0 1 +# ELF2-NEXT: [ 4] .symtab SYMTAB 0000000000000000 000210 000048 18 6 1 8 +# ELF2-NEXT: [ 5] .shstrtab STRTAB 0000000000000000 000258 000034 00 0 0 1 +# ELF2-NEXT: [ 6] .strtab STRTAB 0000000000000000 00028c 00000f 00 0 0 1 +# ELF2-NEXT:Key to Flags: + +#--- a.names.s + + .text + .globl _Z2f12t1 # -- Begin function _Z2f12t1 + .p2align 4, 0x90 + .type _Z2f12t1,@function +_Z2f12t1: # @_Z2f12t1 +.Lfunc_begin0: + .cfi_startproc +# %bb.0: # %entry + pushq %rbp + .cfi_def_cfa_offset 16 + .cfi_offset %rbp, -16 + movq %rsp, %rbp + .cfi_def_cfa_register %rbp +.Ltmp0: + popq %rbp + .cfi_def_cfa %rsp, 8 + retq +.Ltmp1: +.Lfunc_end0: + .size _Z2f12t1, .Lfunc_end0-_Z2f12t1 + .cfi_endproc + # -- End function + .section .debug_info,"",@progbits +.Lcu_begin0: + .byte 0 + .section .debug_str,"MS",@progbits,1 +.Linfo_string0: + .asciz "clang version 19.0.0git (git@github.com:llvm/llvm-project.git dfe787af70e11666a8e43ca73a86d1841d364dfc)" # string offset=0 +.Linfo_string1: + .asciz "a.cpp" # string offset=104 +.Linfo_string2: + .asciz "/proc/self/cwd" # string offset=110 +.Linfo_string3: + .asciz "f1" # string offset=125 +.Linfo_string4: + .asciz "_Z2f12t1" # string offset=128 +.Linfo_string5: + .asciz "t1" # string offset=137 + .section .debug_names,"",@progbits + .long .Lnames_end0-.Lnames_start0 # Header: unit length +.Lnames_start0: + .short 5 # Header: version + .short 0 # Header: padding + .long 1 # Header: compilation unit count + .long 0 # Header: local type unit count + .long 0 # Header: foreign type unit count + .long 3 # Header: bucket count + .long 3 # Header: name count + .long .Lnames_abbrev_end0-.Lnames_abbrev_start0 # Header: abbreviation table size + .long 8 # Header: augmentation string size + .ascii "LLVM0700" # Header: augmentation string + .long .Lcu_begin0 # Compilation unit 0 + .long 0 # Bucket 0 + .long 1 # Bucket 1 + .long 3 # Bucket 2 + .long 5863324 # Hash in Bucket 1 + .long 5863786 # Hash in Bucket 1 + .long 1398125246 # Hash in Bucket 2 + .long .Linfo_string3 # String in Bucket 1: f1 + .long .Linfo_string5 # String in Bucket 1: t1 + .long .Linfo_string4 # String in Bucket 2: _Z2f12t1 + .long .Lnames0-.Lnames_entries0 # Offset in Bucket 1 + .long .Lnames2-.Lnames_entries0 # Offset in Bucket 1 + .long .Lnames1-.Lnames_entries0 # Offset in Bucket 2 +.Lnames_abbrev_start0: + .byte 1 # Abbrev code + .byte 46 # DW_TAG_subprogram + .byte 3 # DW_IDX_die_offset + .byte 19 # DW_FORM_ref4 + .byte 4 # DW_IDX_parent + .byte 25 # DW_FORM_flag_present + .byte 0 # End of abbrev + .byte 0 # End of abbrev + .byte 2 # Abbrev code + .byte 19 # DW_TAG_structure_type + .byte 3 # DW_IDX_die_offset + .byte 19 # DW_FORM_ref4 + .byte 4 # DW_IDX_parent + .byte 25 # DW_FORM_flag_present + .byte 0 # End of abbrev + .byte 0 # End of abbrev + .byte 0 # End of abbrev list +.Lnames_abbrev_end0: +.Lnames_entries0: +.Lnames0: +.L1: + .byte 1 # Abbreviation code + .long 35 # DW_IDX_die_offset + .byte 0 # DW_IDX_parent + # End of list: f1 +.Lnames2: +.L0: + .byte 2 # Abbreviation code + .long 58 # DW_IDX_die_offset + .byte 0 # DW_IDX_parent + # End of list: t1 +.Lnames1: + .byte 1 # Abbreviation code + .long 35 # DW_IDX_die_offset + .byte 0 # DW_IDX_parent + # End of list: _Z2f12t1 + .p2align 2, 0x0 +.Lnames_end0: + .ident "clang version 19.0.0git (git@github.com:llvm/llvm-project.git dfe787af70e11666a8e43ca73a86d1841d364dfc)" + .section ".note.GNU-stack","",@progbits + .addrsig + .section .debug_line,"",@progbits +.Lline_table_start0: + +#--- a.nonames.s + + .text + .globl _Z2f12t1 # -- Begin function _Z2f12t1 + .p2align 4, 0x90 + .type _Z2f12t1,@function +_Z2f12t1: # @_Z2f12t1 + .cfi_startproc +# %bb.0: # %entry + pushq %rbp + .cfi_def_cfa_offset 16 + .cfi_offset %rbp, -16 + movq %rsp, %rbp + .cfi_def_cfa_register %rbp + popq %rbp + .cfi_def_cfa %rsp, 8 + retq +.Lfunc_end0: + .size _Z2f12t1, .Lfunc_end0-_Z2f12t1 + .cfi_endproc + # -- End function + .ident "clang version 19.0.0git (git@github.com:llvm/llvm-project.git dfe787af70e11666a8e43ca73a86d1841d364dfc)" + .section ".note.GNU-stack","",@progbits + .addrsig + +#--- b.s + + .text + .globl main # -- Begin function main + .p2align 4, 0x90 + .type main,@function +main: # @main + .cfi_startproc +# %bb.0: # %entry + pushq %rbp + .cfi_def_cfa_offset 16 + .cfi_offset %rbp, -16 + movq %rsp, %rbp + .cfi_def_cfa_register %rbp + xorl %eax, %eax + popq %rbp + .cfi_def_cfa %rsp, 8 + retq +.Lfunc_end0: + .size main, .Lfunc_end0-main + .cfi_endproc + # -- End function + .ident "clang version 19.0.0git (git@github.com:llvm/llvm-project.git dfe787af70e11666a8e43ca73a86d1841d364dfc)" + .section ".note.GNU-stack","",@progbits + .addrsig From d12762cdb6357915e0f6f6dbfc09c2c75d746ee7 Mon Sep 17 00:00:00 2001 From: Fangrui Song Date: Tue, 16 Apr 2024 13:52:49 -0700 Subject: [PATCH 29/37] Deduplicate tests Add Inputs/debug-names-[ab].s which can be easily regenerated Update some negative tests to use Inputs/debug-names-[ab].s or apply straightforward transformation with sed --- lld/test/ELF/Inputs/debug-names-a.s | 239 ++++++ lld/test/ELF/Inputs/debug-names-b.s | 358 +++++++++ lld/test/ELF/Inputs/debug-names-bcd.s | 406 ++++++++++ lld/test/ELF/Inputs/debug-names-ef.s | 332 +++++++++ lld/test/ELF/debug-names-bad-aug-string.s | 305 -------- lld/test/ELF/debug-names-bad-offsets-sizes.s | 153 ---- lld/test/ELF/debug-names-bad-version.s | 291 -------- lld/test/ELF/debug-names-bad.s | 91 +++ ...ebug-names-die-offset-form-flag-present.s} | 0 .../ELF/debug-names-different-aug-string.s | 14 + lld/test/ELF/debug-names-dwarf64.s | 215 ++++-- .../ELF/debug-names-invalid-abbrev-code.s | 149 ---- .../ELF/debug-names-invalid-attribute-2.s | 149 ---- lld/test/ELF/debug-names-invalid-attribute.s | 144 ---- lld/test/ELF/debug-names-multi-cus-2.s | 460 ------------ lld/test/ELF/debug-names-multi-cus-append.s | 459 ------------ lld/test/ELF/debug-names-multi-cus-long.s | 563 -------------- lld/test/ELF/debug-names-multi-cus.s | 691 ++---------------- lld/test/ELF/debug-names-nonames.s | 221 +----- lld/test/ELF/tools/generate-content.py | 82 +++ 20 files changed, 1739 insertions(+), 3583 deletions(-) create mode 100644 lld/test/ELF/Inputs/debug-names-a.s create mode 100644 lld/test/ELF/Inputs/debug-names-b.s create mode 100644 lld/test/ELF/Inputs/debug-names-bcd.s create mode 100644 lld/test/ELF/Inputs/debug-names-ef.s delete mode 100644 lld/test/ELF/debug-names-bad-aug-string.s delete mode 100644 lld/test/ELF/debug-names-bad-offsets-sizes.s delete mode 100644 lld/test/ELF/debug-names-bad-version.s create mode 100644 lld/test/ELF/debug-names-bad.s rename lld/test/ELF/{debug-names-invalid-attribute-3.s => debug-names-die-offset-form-flag-present.s} (100%) create mode 100644 lld/test/ELF/debug-names-different-aug-string.s delete mode 100644 lld/test/ELF/debug-names-invalid-abbrev-code.s delete mode 100644 lld/test/ELF/debug-names-invalid-attribute-2.s delete mode 100644 lld/test/ELF/debug-names-invalid-attribute.s delete mode 100644 lld/test/ELF/debug-names-multi-cus-2.s delete mode 100644 lld/test/ELF/debug-names-multi-cus-append.s delete mode 100644 lld/test/ELF/debug-names-multi-cus-long.s create mode 100755 lld/test/ELF/tools/generate-content.py diff --git a/lld/test/ELF/Inputs/debug-names-a.s b/lld/test/ELF/Inputs/debug-names-a.s new file mode 100644 index 0000000000000..32fe3b88b0433 --- /dev/null +++ b/lld/test/ELF/Inputs/debug-names-a.s @@ -0,0 +1,239 @@ +.ifdef GEN +#--- a.cc +struct t1 {}; +extern "C" void _start(t1) {} +#--- gen +clang -S -g -gpubnames a.cc -o - +.endif + .text + .file "a.cc" + .globl _start # -- Begin function _start + .p2align 4, 0x90 + .type _start,@function +_start: # @_start +.Lfunc_begin0: + .file 0 "/proc/self/cwd" "a.cc" md5 0x6835f89a7d36054002b51e54e47d852e + .loc 0 2 0 # a.cc:2:0 + .cfi_startproc +# %bb.0: # %entry + pushq %rbp + .cfi_def_cfa_offset 16 + .cfi_offset %rbp, -16 + movq %rsp, %rbp + .cfi_def_cfa_register %rbp +.Ltmp0: + .loc 0 2 29 prologue_end epilogue_begin # a.cc:2:29 + popq %rbp + .cfi_def_cfa %rsp, 8 + retq +.Ltmp1: +.Lfunc_end0: + .size _start, .Lfunc_end0-_start + .cfi_endproc + # -- End function + .section .debug_abbrev,"",@progbits + .byte 1 # Abbreviation Code + .byte 17 # DW_TAG_compile_unit + .byte 1 # DW_CHILDREN_yes + .byte 37 # DW_AT_producer + .byte 37 # DW_FORM_strx1 + .byte 19 # DW_AT_language + .byte 5 # DW_FORM_data2 + .byte 3 # DW_AT_name + .byte 37 # DW_FORM_strx1 + .byte 114 # DW_AT_str_offsets_base + .byte 23 # DW_FORM_sec_offset + .byte 16 # DW_AT_stmt_list + .byte 23 # DW_FORM_sec_offset + .byte 27 # DW_AT_comp_dir + .byte 37 # DW_FORM_strx1 + .byte 17 # DW_AT_low_pc + .byte 27 # DW_FORM_addrx + .byte 18 # DW_AT_high_pc + .byte 6 # DW_FORM_data4 + .byte 115 # DW_AT_addr_base + .byte 23 # DW_FORM_sec_offset + .byte 0 # EOM(1) + .byte 0 # EOM(2) + .byte 2 # Abbreviation Code + .byte 46 # DW_TAG_subprogram + .byte 1 # DW_CHILDREN_yes + .byte 17 # DW_AT_low_pc + .byte 27 # DW_FORM_addrx + .byte 18 # DW_AT_high_pc + .byte 6 # DW_FORM_data4 + .byte 64 # DW_AT_frame_base + .byte 24 # DW_FORM_exprloc + .byte 3 # DW_AT_name + .byte 37 # DW_FORM_strx1 + .byte 58 # DW_AT_decl_file + .byte 11 # DW_FORM_data1 + .byte 59 # DW_AT_decl_line + .byte 11 # DW_FORM_data1 + .byte 63 # DW_AT_external + .byte 25 # DW_FORM_flag_present + .byte 0 # EOM(1) + .byte 0 # EOM(2) + .byte 3 # Abbreviation Code + .byte 5 # DW_TAG_formal_parameter + .byte 0 # DW_CHILDREN_no + .byte 2 # DW_AT_location + .byte 24 # DW_FORM_exprloc + .byte 58 # DW_AT_decl_file + .byte 11 # DW_FORM_data1 + .byte 59 # DW_AT_decl_line + .byte 11 # DW_FORM_data1 + .byte 73 # DW_AT_type + .byte 19 # DW_FORM_ref4 + .byte 0 # EOM(1) + .byte 0 # EOM(2) + .byte 4 # Abbreviation Code + .byte 19 # DW_TAG_structure_type + .byte 0 # DW_CHILDREN_no + .byte 54 # DW_AT_calling_convention + .byte 11 # DW_FORM_data1 + .byte 3 # DW_AT_name + .byte 37 # DW_FORM_strx1 + .byte 11 # DW_AT_byte_size + .byte 11 # DW_FORM_data1 + .byte 58 # DW_AT_decl_file + .byte 11 # DW_FORM_data1 + .byte 59 # DW_AT_decl_line + .byte 11 # DW_FORM_data1 + .byte 0 # EOM(1) + .byte 0 # EOM(2) + .byte 0 # EOM(3) + .section .debug_info,"",@progbits +.Lcu_begin0: + .long .Ldebug_info_end0-.Ldebug_info_start0 # Length of Unit +.Ldebug_info_start0: + .short 5 # DWARF version number + .byte 1 # DWARF Unit Type + .byte 8 # Address Size (in bytes) + .long .debug_abbrev # Offset Into Abbrev. Section + .byte 1 # Abbrev [1] 0xc:0x34 DW_TAG_compile_unit + .byte 0 # DW_AT_producer + .short 33 # DW_AT_language + .byte 1 # DW_AT_name + .long .Lstr_offsets_base0 # DW_AT_str_offsets_base + .long .Lline_table_start0 # DW_AT_stmt_list + .byte 2 # DW_AT_comp_dir + .byte 0 # DW_AT_low_pc + .long .Lfunc_end0-.Lfunc_begin0 # DW_AT_high_pc + .long .Laddr_table_base0 # DW_AT_addr_base + .byte 2 # Abbrev [2] 0x23:0x16 DW_TAG_subprogram + .byte 0 # DW_AT_low_pc + .long .Lfunc_end0-.Lfunc_begin0 # DW_AT_high_pc + .byte 1 # DW_AT_frame_base + .byte 86 + .byte 3 # DW_AT_name + .byte 0 # DW_AT_decl_file + .byte 2 # DW_AT_decl_line + # DW_AT_external + .byte 3 # Abbrev [3] 0x2e:0xa DW_TAG_formal_parameter + .byte 2 # DW_AT_location + .byte 145 + .byte 127 + .byte 0 # DW_AT_decl_file + .byte 2 # DW_AT_decl_line + .long 57 # DW_AT_type + .byte 0 # End Of Children Mark + .byte 4 # Abbrev [4] 0x39:0x6 DW_TAG_structure_type + .byte 5 # DW_AT_calling_convention + .byte 4 # DW_AT_name + .byte 1 # DW_AT_byte_size + .byte 0 # DW_AT_decl_file + .byte 1 # DW_AT_decl_line + .byte 0 # End Of Children Mark +.Ldebug_info_end0: + .section .debug_str_offsets,"",@progbits + .long 24 # Length of String Offsets Set + .short 5 + .short 0 +.Lstr_offsets_base0: + .section .debug_str,"MS",@progbits,1 +.Linfo_string0: + .byte 0 # string offset=0 +.Linfo_string1: + .asciz "a.cc" # string offset=1 +.Linfo_string2: + .asciz "/proc/self/cwd" # string offset=6 +.Linfo_string3: + .asciz "_start" # string offset=21 +.Linfo_string4: + .asciz "t1" # string offset=28 + .section .debug_str_offsets,"",@progbits + .long .Linfo_string0 + .long .Linfo_string1 + .long .Linfo_string2 + .long .Linfo_string3 + .long .Linfo_string4 + .section .debug_addr,"",@progbits + .long .Ldebug_addr_end0-.Ldebug_addr_start0 # Length of contribution +.Ldebug_addr_start0: + .short 5 # DWARF version number + .byte 8 # Address size + .byte 0 # Segment selector size +.Laddr_table_base0: + .quad .Lfunc_begin0 +.Ldebug_addr_end0: + .section .debug_names,"",@progbits + .long .Lnames_end0-.Lnames_start0 # Header: unit length +.Lnames_start0: + .short 5 # Header: version + .short 0 # Header: padding + .long 1 # Header: compilation unit count + .long 0 # Header: local type unit count + .long 0 # Header: foreign type unit count + .long 2 # Header: bucket count + .long 2 # Header: name count + .long .Lnames_abbrev_end0-.Lnames_abbrev_start0 # Header: abbreviation table size + .long 8 # Header: augmentation string size + .ascii "LLVM0700" # Header: augmentation string + .long .Lcu_begin0 # Compilation unit 0 + .long 1 # Bucket 0 + .long 0 # Bucket 1 + .long 5863786 # Hash in Bucket 0 + .long -304389582 # Hash in Bucket 0 + .long .Linfo_string4 # String in Bucket 0: t1 + .long .Linfo_string3 # String in Bucket 0: _start + .long .Lnames1-.Lnames_entries0 # Offset in Bucket 0 + .long .Lnames0-.Lnames_entries0 # Offset in Bucket 0 +.Lnames_abbrev_start0: + .byte 1 # Abbrev code + .byte 19 # DW_TAG_structure_type + .byte 3 # DW_IDX_die_offset + .byte 19 # DW_FORM_ref4 + .byte 4 # DW_IDX_parent + .byte 25 # DW_FORM_flag_present + .byte 0 # End of abbrev + .byte 0 # End of abbrev + .byte 2 # Abbrev code + .byte 46 # DW_TAG_subprogram + .byte 3 # DW_IDX_die_offset + .byte 19 # DW_FORM_ref4 + .byte 4 # DW_IDX_parent + .byte 25 # DW_FORM_flag_present + .byte 0 # End of abbrev + .byte 0 # End of abbrev + .byte 0 # End of abbrev list +.Lnames_abbrev_end0: +.Lnames_entries0: +.Lnames1: +.L1: + .byte 1 # Abbreviation code + .long 57 # DW_IDX_die_offset + .byte 0 # DW_IDX_parent + # End of list: t1 +.Lnames0: +.L0: + .byte 2 # Abbreviation code + .long 35 # DW_IDX_die_offset + .byte 0 # DW_IDX_parent + # End of list: _start + .p2align 2, 0x0 +.Lnames_end0: + .section ".note.GNU-stack","",@progbits + .addrsig + .section .debug_line,"",@progbits +.Lline_table_start0: diff --git a/lld/test/ELF/Inputs/debug-names-b.s b/lld/test/ELF/Inputs/debug-names-b.s new file mode 100644 index 0000000000000..938a44690ee91 --- /dev/null +++ b/lld/test/ELF/Inputs/debug-names-b.s @@ -0,0 +1,358 @@ +.ifdef GEN +#--- b.cc +struct t1 { }; +namespace ns { +struct t2 {}; +} +int main() { t1 v1; ns::t2 v2; } +#--- gen +clang -S -g -gpubnames b.cc -o - +.endif + .text + .file "b.cc" + .globl main # -- Begin function main + .p2align 4, 0x90 + .type main,@function +main: # @main +.Lfunc_begin0: + .file 0 "/proc/self/cwd" "b.cc" md5 0xcb70125759dcd65dfed077164397a2f4 + .loc 0 5 0 # b.cc:5:0 + .cfi_startproc +# %bb.0: # %entry + pushq %rbp + .cfi_def_cfa_offset 16 + .cfi_offset %rbp, -16 + movq %rsp, %rbp + .cfi_def_cfa_register %rbp +.Ltmp0: + .loc 0 5 32 prologue_end # b.cc:5:32 + xorl %eax, %eax + .loc 0 5 32 epilogue_begin is_stmt 0 # b.cc:5:32 + popq %rbp + .cfi_def_cfa %rsp, 8 + retq +.Ltmp1: +.Lfunc_end0: + .size main, .Lfunc_end0-main + .cfi_endproc + # -- End function + .section .debug_abbrev,"",@progbits + .byte 1 # Abbreviation Code + .byte 17 # DW_TAG_compile_unit + .byte 1 # DW_CHILDREN_yes + .byte 37 # DW_AT_producer + .byte 37 # DW_FORM_strx1 + .byte 19 # DW_AT_language + .byte 5 # DW_FORM_data2 + .byte 3 # DW_AT_name + .byte 37 # DW_FORM_strx1 + .byte 114 # DW_AT_str_offsets_base + .byte 23 # DW_FORM_sec_offset + .byte 16 # DW_AT_stmt_list + .byte 23 # DW_FORM_sec_offset + .byte 27 # DW_AT_comp_dir + .byte 37 # DW_FORM_strx1 + .byte 17 # DW_AT_low_pc + .byte 27 # DW_FORM_addrx + .byte 18 # DW_AT_high_pc + .byte 6 # DW_FORM_data4 + .byte 115 # DW_AT_addr_base + .byte 23 # DW_FORM_sec_offset + .byte 0 # EOM(1) + .byte 0 # EOM(2) + .byte 2 # Abbreviation Code + .byte 46 # DW_TAG_subprogram + .byte 1 # DW_CHILDREN_yes + .byte 17 # DW_AT_low_pc + .byte 27 # DW_FORM_addrx + .byte 18 # DW_AT_high_pc + .byte 6 # DW_FORM_data4 + .byte 64 # DW_AT_frame_base + .byte 24 # DW_FORM_exprloc + .byte 3 # DW_AT_name + .byte 37 # DW_FORM_strx1 + .byte 58 # DW_AT_decl_file + .byte 11 # DW_FORM_data1 + .byte 59 # DW_AT_decl_line + .byte 11 # DW_FORM_data1 + .byte 73 # DW_AT_type + .byte 19 # DW_FORM_ref4 + .byte 63 # DW_AT_external + .byte 25 # DW_FORM_flag_present + .byte 0 # EOM(1) + .byte 0 # EOM(2) + .byte 3 # Abbreviation Code + .byte 52 # DW_TAG_variable + .byte 0 # DW_CHILDREN_no + .byte 2 # DW_AT_location + .byte 24 # DW_FORM_exprloc + .byte 3 # DW_AT_name + .byte 37 # DW_FORM_strx1 + .byte 58 # DW_AT_decl_file + .byte 11 # DW_FORM_data1 + .byte 59 # DW_AT_decl_line + .byte 11 # DW_FORM_data1 + .byte 73 # DW_AT_type + .byte 19 # DW_FORM_ref4 + .byte 0 # EOM(1) + .byte 0 # EOM(2) + .byte 4 # Abbreviation Code + .byte 36 # DW_TAG_base_type + .byte 0 # DW_CHILDREN_no + .byte 3 # DW_AT_name + .byte 37 # DW_FORM_strx1 + .byte 62 # DW_AT_encoding + .byte 11 # DW_FORM_data1 + .byte 11 # DW_AT_byte_size + .byte 11 # DW_FORM_data1 + .byte 0 # EOM(1) + .byte 0 # EOM(2) + .byte 5 # Abbreviation Code + .byte 19 # DW_TAG_structure_type + .byte 0 # DW_CHILDREN_no + .byte 54 # DW_AT_calling_convention + .byte 11 # DW_FORM_data1 + .byte 3 # DW_AT_name + .byte 37 # DW_FORM_strx1 + .byte 11 # DW_AT_byte_size + .byte 11 # DW_FORM_data1 + .byte 58 # DW_AT_decl_file + .byte 11 # DW_FORM_data1 + .byte 59 # DW_AT_decl_line + .byte 11 # DW_FORM_data1 + .byte 0 # EOM(1) + .byte 0 # EOM(2) + .byte 6 # Abbreviation Code + .byte 57 # DW_TAG_namespace + .byte 1 # DW_CHILDREN_yes + .byte 3 # DW_AT_name + .byte 37 # DW_FORM_strx1 + .byte 0 # EOM(1) + .byte 0 # EOM(2) + .byte 0 # EOM(3) + .section .debug_info,"",@progbits +.Lcu_begin0: + .long .Ldebug_info_end0-.Ldebug_info_start0 # Length of Unit +.Ldebug_info_start0: + .short 5 # DWARF version number + .byte 1 # DWARF Unit Type + .byte 8 # Address Size (in bytes) + .long .debug_abbrev # Offset Into Abbrev. Section + .byte 1 # Abbrev [1] 0xc:0x51 DW_TAG_compile_unit + .byte 0 # DW_AT_producer + .short 33 # DW_AT_language + .byte 1 # DW_AT_name + .long .Lstr_offsets_base0 # DW_AT_str_offsets_base + .long .Lline_table_start0 # DW_AT_stmt_list + .byte 2 # DW_AT_comp_dir + .byte 0 # DW_AT_low_pc + .long .Lfunc_end0-.Lfunc_begin0 # DW_AT_high_pc + .long .Laddr_table_base0 # DW_AT_addr_base + .byte 2 # Abbrev [2] 0x23:0x26 DW_TAG_subprogram + .byte 0 # DW_AT_low_pc + .long .Lfunc_end0-.Lfunc_begin0 # DW_AT_high_pc + .byte 1 # DW_AT_frame_base + .byte 86 + .byte 3 # DW_AT_name + .byte 0 # DW_AT_decl_file + .byte 5 # DW_AT_decl_line + .long 73 # DW_AT_type + # DW_AT_external + .byte 3 # Abbrev [3] 0x32:0xb DW_TAG_variable + .byte 2 # DW_AT_location + .byte 145 + .byte 127 + .byte 5 # DW_AT_name + .byte 0 # DW_AT_decl_file + .byte 5 # DW_AT_decl_line + .long 77 # DW_AT_type + .byte 3 # Abbrev [3] 0x3d:0xb DW_TAG_variable + .byte 2 # DW_AT_location + .byte 145 + .byte 126 + .byte 7 # DW_AT_name + .byte 0 # DW_AT_decl_file + .byte 5 # DW_AT_decl_line + .long 85 # DW_AT_type + .byte 0 # End Of Children Mark + .byte 4 # Abbrev [4] 0x49:0x4 DW_TAG_base_type + .byte 4 # DW_AT_name + .byte 5 # DW_AT_encoding + .byte 4 # DW_AT_byte_size + .byte 5 # Abbrev [5] 0x4d:0x6 DW_TAG_structure_type + .byte 5 # DW_AT_calling_convention + .byte 6 # DW_AT_name + .byte 1 # DW_AT_byte_size + .byte 0 # DW_AT_decl_file + .byte 1 # DW_AT_decl_line + .byte 6 # Abbrev [6] 0x53:0x9 DW_TAG_namespace + .byte 8 # DW_AT_name + .byte 5 # Abbrev [5] 0x55:0x6 DW_TAG_structure_type + .byte 5 # DW_AT_calling_convention + .byte 9 # DW_AT_name + .byte 1 # DW_AT_byte_size + .byte 0 # DW_AT_decl_file + .byte 3 # DW_AT_decl_line + .byte 0 # End Of Children Mark + .byte 0 # End Of Children Mark +.Ldebug_info_end0: + .section .debug_str_offsets,"",@progbits + .long 44 # Length of String Offsets Set + .short 5 + .short 0 +.Lstr_offsets_base0: + .section .debug_str,"MS",@progbits,1 +.Linfo_string0: + .byte 0 # string offset=0 +.Linfo_string1: + .asciz "b.cc" # string offset=1 +.Linfo_string2: + .asciz "/proc/self/cwd" # string offset=6 +.Linfo_string3: + .asciz "main" # string offset=21 +.Linfo_string4: + .asciz "int" # string offset=26 +.Linfo_string5: + .asciz "v1" # string offset=30 +.Linfo_string6: + .asciz "t1" # string offset=33 +.Linfo_string7: + .asciz "v2" # string offset=36 +.Linfo_string8: + .asciz "ns" # string offset=39 +.Linfo_string9: + .asciz "t2" # string offset=42 + .section .debug_str_offsets,"",@progbits + .long .Linfo_string0 + .long .Linfo_string1 + .long .Linfo_string2 + .long .Linfo_string3 + .long .Linfo_string4 + .long .Linfo_string5 + .long .Linfo_string6 + .long .Linfo_string7 + .long .Linfo_string8 + .long .Linfo_string9 + .section .debug_addr,"",@progbits + .long .Ldebug_addr_end0-.Ldebug_addr_start0 # Length of contribution +.Ldebug_addr_start0: + .short 5 # DWARF version number + .byte 8 # Address size + .byte 0 # Segment selector size +.Laddr_table_base0: + .quad .Lfunc_begin0 +.Ldebug_addr_end0: + .section .debug_names,"",@progbits + .long .Lnames_end0-.Lnames_start0 # Header: unit length +.Lnames_start0: + .short 5 # Header: version + .short 0 # Header: padding + .long 1 # Header: compilation unit count + .long 0 # Header: local type unit count + .long 0 # Header: foreign type unit count + .long 5 # Header: bucket count + .long 5 # Header: name count + .long .Lnames_abbrev_end0-.Lnames_abbrev_start0 # Header: abbreviation table size + .long 8 # Header: augmentation string size + .ascii "LLVM0700" # Header: augmentation string + .long .Lcu_begin0 # Compilation unit 0 + .long 0 # Bucket 0 + .long 1 # Bucket 1 + .long 3 # Bucket 2 + .long 4 # Bucket 3 + .long 5 # Bucket 4 + .long 5863786 # Hash in Bucket 1 + .long 2090499946 # Hash in Bucket 1 + .long 5863787 # Hash in Bucket 2 + .long 193495088 # Hash in Bucket 3 + .long 5863654 # Hash in Bucket 4 + .long .Linfo_string6 # String in Bucket 1: t1 + .long .Linfo_string3 # String in Bucket 1: main + .long .Linfo_string9 # String in Bucket 2: t2 + .long .Linfo_string4 # String in Bucket 3: int + .long .Linfo_string8 # String in Bucket 4: ns + .long .Lnames2-.Lnames_entries0 # Offset in Bucket 1 + .long .Lnames0-.Lnames_entries0 # Offset in Bucket 1 + .long .Lnames4-.Lnames_entries0 # Offset in Bucket 2 + .long .Lnames1-.Lnames_entries0 # Offset in Bucket 3 + .long .Lnames3-.Lnames_entries0 # Offset in Bucket 4 +.Lnames_abbrev_start0: + .byte 1 # Abbrev code + .byte 19 # DW_TAG_structure_type + .byte 3 # DW_IDX_die_offset + .byte 19 # DW_FORM_ref4 + .byte 4 # DW_IDX_parent + .byte 25 # DW_FORM_flag_present + .byte 0 # End of abbrev + .byte 0 # End of abbrev + .byte 2 # Abbrev code + .byte 46 # DW_TAG_subprogram + .byte 3 # DW_IDX_die_offset + .byte 19 # DW_FORM_ref4 + .byte 4 # DW_IDX_parent + .byte 25 # DW_FORM_flag_present + .byte 0 # End of abbrev + .byte 0 # End of abbrev + .byte 3 # Abbrev code + .byte 19 # DW_TAG_structure_type + .byte 3 # DW_IDX_die_offset + .byte 19 # DW_FORM_ref4 + .byte 4 # DW_IDX_parent + .byte 19 # DW_FORM_ref4 + .byte 0 # End of abbrev + .byte 0 # End of abbrev + .byte 4 # Abbrev code + .byte 36 # DW_TAG_base_type + .byte 3 # DW_IDX_die_offset + .byte 19 # DW_FORM_ref4 + .byte 4 # DW_IDX_parent + .byte 25 # DW_FORM_flag_present + .byte 0 # End of abbrev + .byte 0 # End of abbrev + .byte 5 # Abbrev code + .byte 57 # DW_TAG_namespace + .byte 3 # DW_IDX_die_offset + .byte 19 # DW_FORM_ref4 + .byte 4 # DW_IDX_parent + .byte 25 # DW_FORM_flag_present + .byte 0 # End of abbrev + .byte 0 # End of abbrev + .byte 0 # End of abbrev list +.Lnames_abbrev_end0: +.Lnames_entries0: +.Lnames2: +.L4: + .byte 1 # Abbreviation code + .long 77 # DW_IDX_die_offset + .byte 0 # DW_IDX_parent + # End of list: t1 +.Lnames0: +.L2: + .byte 2 # Abbreviation code + .long 35 # DW_IDX_die_offset + .byte 0 # DW_IDX_parent + # End of list: main +.Lnames4: +.L3: + .byte 3 # Abbreviation code + .long 85 # DW_IDX_die_offset + .long .L1-.Lnames_entries0 # DW_IDX_parent + .byte 0 # End of list: t2 +.Lnames1: +.L0: + .byte 4 # Abbreviation code + .long 73 # DW_IDX_die_offset + .byte 0 # DW_IDX_parent + # End of list: int +.Lnames3: +.L1: + .byte 5 # Abbreviation code + .long 83 # DW_IDX_die_offset + .byte 0 # DW_IDX_parent + # End of list: ns + .p2align 2, 0x0 +.Lnames_end0: + .section ".note.GNU-stack","",@progbits + .addrsig + .section .debug_line,"",@progbits +.Lline_table_start0: diff --git a/lld/test/ELF/Inputs/debug-names-bcd.s b/lld/test/ELF/Inputs/debug-names-bcd.s new file mode 100644 index 0000000000000..690485515b6c0 --- /dev/null +++ b/lld/test/ELF/Inputs/debug-names-bcd.s @@ -0,0 +1,406 @@ +.ifdef GEN +//--- b.cc +[[gnu::used]] int vb; +//--- c.cc +[[gnu::used]] int vc; +//--- d.cc +namespace ns { +[[gnu::used]] int vd; +} +//--- gen +clang -O1 -g -gpubnames -flto b.cc c.cc d.cc -nostdlib -fuse-ld=lld -Wl,--lto-emit-asm +cat a.out.lto.s +.endif + .text + .file "ld-temp.o" + .file 1 "/proc/self/cwd" "b.cc" md5 0x78dad32a49063326a4de543198e54944 + .file 2 "/proc/self/cwd" "c.cc" md5 0x7a0f7bf2cb0ec8c297f794908d91ab1b + .file 3 "/proc/self/cwd" "d.cc" md5 0x035bb8b2da82db6f75693f2a941c3294 + .type vb,@object # @vb + .section .bss.vb,"aw",@nobits + .globl vb + .p2align 2, 0x0 +vb: + .long 0 # 0x0 + .size vb, 4 + + .type vc,@object # @vc + .section .bss.vc,"aw",@nobits + .globl vc + .p2align 2, 0x0 +vc: + .long 0 # 0x0 + .size vc, 4 + + .type _ZN2ns2vdE,@object # @_ZN2ns2vdE + .section .bss._ZN2ns2vdE,"aw",@nobits + .globl _ZN2ns2vdE + .p2align 2, 0x0 +_ZN2ns2vdE: + .long 0 # 0x0 + .size _ZN2ns2vdE, 4 + + .section .debug_abbrev,"",@progbits + .byte 1 # Abbreviation Code + .byte 17 # DW_TAG_compile_unit + .byte 1 # DW_CHILDREN_yes + .byte 37 # DW_AT_producer + .byte 37 # DW_FORM_strx1 + .byte 19 # DW_AT_language + .byte 5 # DW_FORM_data2 + .byte 3 # DW_AT_name + .byte 37 # DW_FORM_strx1 + .byte 114 # DW_AT_str_offsets_base + .byte 23 # DW_FORM_sec_offset + .byte 16 # DW_AT_stmt_list + .byte 23 # DW_FORM_sec_offset + .byte 27 # DW_AT_comp_dir + .byte 37 # DW_FORM_strx1 + .byte 115 # DW_AT_addr_base + .byte 23 # DW_FORM_sec_offset + .byte 0 # EOM(1) + .byte 0 # EOM(2) + .byte 2 # Abbreviation Code + .byte 52 # DW_TAG_variable + .byte 0 # DW_CHILDREN_no + .byte 3 # DW_AT_name + .byte 37 # DW_FORM_strx1 + .byte 73 # DW_AT_type + .byte 19 # DW_FORM_ref4 + .byte 63 # DW_AT_external + .byte 25 # DW_FORM_flag_present + .byte 58 # DW_AT_decl_file + .byte 11 # DW_FORM_data1 + .byte 59 # DW_AT_decl_line + .byte 11 # DW_FORM_data1 + .byte 2 # DW_AT_location + .byte 24 # DW_FORM_exprloc + .byte 0 # EOM(1) + .byte 0 # EOM(2) + .byte 3 # Abbreviation Code + .byte 36 # DW_TAG_base_type + .byte 0 # DW_CHILDREN_no + .byte 3 # DW_AT_name + .byte 37 # DW_FORM_strx1 + .byte 62 # DW_AT_encoding + .byte 11 # DW_FORM_data1 + .byte 11 # DW_AT_byte_size + .byte 11 # DW_FORM_data1 + .byte 0 # EOM(1) + .byte 0 # EOM(2) + .byte 4 # Abbreviation Code + .byte 52 # DW_TAG_variable + .byte 0 # DW_CHILDREN_no + .byte 3 # DW_AT_name + .byte 37 # DW_FORM_strx1 + .byte 73 # DW_AT_type + .byte 16 # DW_FORM_ref_addr + .byte 63 # DW_AT_external + .byte 25 # DW_FORM_flag_present + .byte 58 # DW_AT_decl_file + .byte 11 # DW_FORM_data1 + .byte 59 # DW_AT_decl_line + .byte 11 # DW_FORM_data1 + .byte 2 # DW_AT_location + .byte 24 # DW_FORM_exprloc + .byte 0 # EOM(1) + .byte 0 # EOM(2) + .byte 5 # Abbreviation Code + .byte 57 # DW_TAG_namespace + .byte 1 # DW_CHILDREN_yes + .byte 3 # DW_AT_name + .byte 37 # DW_FORM_strx1 + .byte 0 # EOM(1) + .byte 0 # EOM(2) + .byte 6 # Abbreviation Code + .byte 52 # DW_TAG_variable + .byte 0 # DW_CHILDREN_no + .byte 3 # DW_AT_name + .byte 37 # DW_FORM_strx1 + .byte 73 # DW_AT_type + .byte 16 # DW_FORM_ref_addr + .byte 63 # DW_AT_external + .byte 25 # DW_FORM_flag_present + .byte 58 # DW_AT_decl_file + .byte 11 # DW_FORM_data1 + .byte 59 # DW_AT_decl_line + .byte 11 # DW_FORM_data1 + .byte 2 # DW_AT_location + .byte 24 # DW_FORM_exprloc + .byte 110 # DW_AT_linkage_name + .byte 37 # DW_FORM_strx1 + .byte 0 # EOM(1) + .byte 0 # EOM(2) + .byte 0 # EOM(3) + .section .debug_info,"",@progbits +.Lcu_begin0: + .long .Ldebug_info_end0-.Ldebug_info_start0 # Length of Unit +.Ldebug_info_start0: + .short 5 # DWARF version number + .byte 1 # DWARF Unit Type + .byte 8 # Address Size (in bytes) + .long .debug_abbrev # Offset Into Abbrev. Section + .byte 1 # Abbrev [1] 0xc:0x22 DW_TAG_compile_unit + .byte 0 # DW_AT_producer + .short 33 # DW_AT_language + .byte 1 # DW_AT_name + .long .Lstr_offsets_base0 # DW_AT_str_offsets_base + .long .Lline_table_start0 # DW_AT_stmt_list + .byte 2 # DW_AT_comp_dir + .long .Laddr_table_base0 # DW_AT_addr_base + .byte 2 # Abbrev [2] 0x1e:0xb DW_TAG_variable + .byte 3 # DW_AT_name + .long 41 # DW_AT_type + # DW_AT_external + .byte 1 # DW_AT_decl_file + .byte 1 # DW_AT_decl_line + .byte 2 # DW_AT_location + .byte 161 + .byte 0 + .byte 3 # Abbrev [3] 0x29:0x4 DW_TAG_base_type + .byte 4 # DW_AT_name + .byte 5 # DW_AT_encoding + .byte 4 # DW_AT_byte_size + .byte 0 # End Of Children Mark +.Ldebug_info_end0: +.Lcu_begin1: + .long .Ldebug_info_end1-.Ldebug_info_start1 # Length of Unit +.Ldebug_info_start1: + .short 5 # DWARF version number + .byte 1 # DWARF Unit Type + .byte 8 # Address Size (in bytes) + .long .debug_abbrev # Offset Into Abbrev. Section + .byte 1 # Abbrev [1] 0xc:0x1e DW_TAG_compile_unit + .byte 0 # DW_AT_producer + .short 33 # DW_AT_language + .byte 5 # DW_AT_name + .long .Lstr_offsets_base0 # DW_AT_str_offsets_base + .long .Lline_table_start0 # DW_AT_stmt_list + .byte 2 # DW_AT_comp_dir + .long .Laddr_table_base0 # DW_AT_addr_base + .byte 4 # Abbrev [4] 0x1e:0xb DW_TAG_variable + .byte 6 # DW_AT_name + .long .debug_info+41 # DW_AT_type + # DW_AT_external + .byte 2 # DW_AT_decl_file + .byte 1 # DW_AT_decl_line + .byte 2 # DW_AT_location + .byte 161 + .byte 1 + .byte 0 # End Of Children Mark +.Ldebug_info_end1: +.Lcu_begin2: + .long .Ldebug_info_end2-.Ldebug_info_start2 # Length of Unit +.Ldebug_info_start2: + .short 5 # DWARF version number + .byte 1 # DWARF Unit Type + .byte 8 # Address Size (in bytes) + .long .debug_abbrev # Offset Into Abbrev. Section + .byte 1 # Abbrev [1] 0xc:0x22 DW_TAG_compile_unit + .byte 0 # DW_AT_producer + .short 33 # DW_AT_language + .byte 7 # DW_AT_name + .long .Lstr_offsets_base0 # DW_AT_str_offsets_base + .long .Lline_table_start0 # DW_AT_stmt_list + .byte 2 # DW_AT_comp_dir + .long .Laddr_table_base0 # DW_AT_addr_base + .byte 5 # Abbrev [5] 0x1e:0xf DW_TAG_namespace + .byte 8 # DW_AT_name + .byte 6 # Abbrev [6] 0x20:0xc DW_TAG_variable + .byte 9 # DW_AT_name + .long .debug_info+41 # DW_AT_type + # DW_AT_external + .byte 3 # DW_AT_decl_file + .byte 2 # DW_AT_decl_line + .byte 2 # DW_AT_location + .byte 161 + .byte 2 + .byte 10 # DW_AT_linkage_name + .byte 0 # End Of Children Mark + .byte 0 # End Of Children Mark +.Ldebug_info_end2: + .section .debug_str_offsets,"",@progbits + .long 48 # Length of String Offsets Set + .short 5 + .short 0 +.Lstr_offsets_base0: + .section .debug_str,"MS",@progbits,1 +.Linfo_string0: + .byte 0 # string offset=0 +.Linfo_string1: + .asciz "b.cc" # string offset=1 +.Linfo_string2: + .asciz "/proc/self/cwd" # string offset=6 +.Linfo_string3: + .asciz "vb" # string offset=21 +.Linfo_string4: + .asciz "int" # string offset=24 +.Linfo_string5: + .asciz "c.cc" # string offset=28 +.Linfo_string6: + .asciz "vc" # string offset=33 +.Linfo_string7: + .asciz "d.cc" # string offset=36 +.Linfo_string8: + .asciz "ns" # string offset=41 +.Linfo_string9: + .asciz "vd" # string offset=44 +.Linfo_string10: + .asciz "_ZN2ns2vdE" # string offset=47 + .section .debug_str_offsets,"",@progbits + .long .Linfo_string0 + .long .Linfo_string1 + .long .Linfo_string2 + .long .Linfo_string3 + .long .Linfo_string4 + .long .Linfo_string5 + .long .Linfo_string6 + .long .Linfo_string7 + .long .Linfo_string8 + .long .Linfo_string9 + .long .Linfo_string10 + .section .debug_addr,"",@progbits + .long .Ldebug_addr_end0-.Ldebug_addr_start0 # Length of contribution +.Ldebug_addr_start0: + .short 5 # DWARF version number + .byte 8 # Address size + .byte 0 # Segment selector size +.Laddr_table_base0: + .quad vb + .quad vc + .quad _ZN2ns2vdE +.Ldebug_addr_end0: + .section .debug_names,"",@progbits + .long .Lnames_end0-.Lnames_start0 # Header: unit length +.Lnames_start0: + .short 5 # Header: version + .short 0 # Header: padding + .long 3 # Header: compilation unit count + .long 0 # Header: local type unit count + .long 0 # Header: foreign type unit count + .long 6 # Header: bucket count + .long 6 # Header: name count + .long .Lnames_abbrev_end0-.Lnames_abbrev_start0 # Header: abbreviation table size + .long 8 # Header: augmentation string size + .ascii "LLVM0700" # Header: augmentation string + .long .Lcu_begin0 # Compilation unit 0 + .long .Lcu_begin1 # Compilation unit 1 + .long .Lcu_begin2 # Compilation unit 2 + .long 1 # Bucket 0 + .long 2 # Bucket 1 + .long 3 # Bucket 2 + .long 0 # Bucket 3 + .long 4 # Bucket 4 + .long 6 # Bucket 5 + .long 5863902 # Hash in Bucket 0 + .long 5863903 # Hash in Bucket 1 + .long 193495088 # Hash in Bucket 2 + .long 5863654 # Hash in Bucket 4 + .long -823734096 # Hash in Bucket 4 + .long 5863901 # Hash in Bucket 5 + .long .Linfo_string6 # String in Bucket 0: vc + .long .Linfo_string9 # String in Bucket 1: vd + .long .Linfo_string4 # String in Bucket 2: int + .long .Linfo_string8 # String in Bucket 4: ns + .long .Linfo_string10 # String in Bucket 4: _ZN2ns2vdE + .long .Linfo_string3 # String in Bucket 5: vb + .long .Lnames2-.Lnames_entries0 # Offset in Bucket 0 + .long .Lnames4-.Lnames_entries0 # Offset in Bucket 1 + .long .Lnames0-.Lnames_entries0 # Offset in Bucket 2 + .long .Lnames3-.Lnames_entries0 # Offset in Bucket 4 + .long .Lnames5-.Lnames_entries0 # Offset in Bucket 4 + .long .Lnames1-.Lnames_entries0 # Offset in Bucket 5 +.Lnames_abbrev_start0: + .byte 1 # Abbrev code + .byte 52 # DW_TAG_variable + .byte 1 # DW_IDX_compile_unit + .byte 11 # DW_FORM_data1 + .byte 3 # DW_IDX_die_offset + .byte 19 # DW_FORM_ref4 + .byte 4 # DW_IDX_parent + .byte 25 # DW_FORM_flag_present + .byte 0 # End of abbrev + .byte 0 # End of abbrev + .byte 2 # Abbrev code + .byte 52 # DW_TAG_variable + .byte 1 # DW_IDX_compile_unit + .byte 11 # DW_FORM_data1 + .byte 3 # DW_IDX_die_offset + .byte 19 # DW_FORM_ref4 + .byte 4 # DW_IDX_parent + .byte 19 # DW_FORM_ref4 + .byte 0 # End of abbrev + .byte 0 # End of abbrev + .byte 3 # Abbrev code + .byte 36 # DW_TAG_base_type + .byte 1 # DW_IDX_compile_unit + .byte 11 # DW_FORM_data1 + .byte 3 # DW_IDX_die_offset + .byte 19 # DW_FORM_ref4 + .byte 4 # DW_IDX_parent + .byte 25 # DW_FORM_flag_present + .byte 0 # End of abbrev + .byte 0 # End of abbrev + .byte 4 # Abbrev code + .byte 57 # DW_TAG_namespace + .byte 1 # DW_IDX_compile_unit + .byte 11 # DW_FORM_data1 + .byte 3 # DW_IDX_die_offset + .byte 19 # DW_FORM_ref4 + .byte 4 # DW_IDX_parent + .byte 25 # DW_FORM_flag_present + .byte 0 # End of abbrev + .byte 0 # End of abbrev + .byte 0 # End of abbrev list +.Lnames_abbrev_end0: +.Lnames_entries0: +.Lnames2: +.L0: + .byte 1 # Abbreviation code + .byte 1 # DW_IDX_compile_unit + .long 30 # DW_IDX_die_offset + .byte 0 # DW_IDX_parent + # End of list: vc +.Lnames4: +.L4: + .byte 2 # Abbreviation code + .byte 2 # DW_IDX_compile_unit + .long 32 # DW_IDX_die_offset + .long .L2-.Lnames_entries0 # DW_IDX_parent + .byte 0 # End of list: vd +.Lnames0: +.L3: + .byte 3 # Abbreviation code + .byte 0 # DW_IDX_compile_unit + .long 41 # DW_IDX_die_offset + .byte 0 # DW_IDX_parent + # End of list: int +.Lnames3: +.L2: + .byte 4 # Abbreviation code + .byte 2 # DW_IDX_compile_unit + .long 30 # DW_IDX_die_offset + .byte 0 # DW_IDX_parent + # End of list: ns +.Lnames5: + .byte 2 # Abbreviation code + .byte 2 # DW_IDX_compile_unit + .long 32 # DW_IDX_die_offset + .long .L2-.Lnames_entries0 # DW_IDX_parent + .byte 0 # End of list: _ZN2ns2vdE +.Lnames1: +.L1: + .byte 1 # Abbreviation code + .byte 0 # DW_IDX_compile_unit + .long 30 # DW_IDX_die_offset + .byte 0 # DW_IDX_parent + # End of list: vb + .p2align 2, 0x0 +.Lnames_end0: + .section ".note.GNU-stack","",@progbits + .addrsig + .addrsig_sym vb + .addrsig_sym vc + .addrsig_sym _ZN2ns2vdE + .section .debug_line,"",@progbits +.Lline_table_start0: diff --git a/lld/test/ELF/Inputs/debug-names-ef.s b/lld/test/ELF/Inputs/debug-names-ef.s new file mode 100644 index 0000000000000..d50f3b131e5f6 --- /dev/null +++ b/lld/test/ELF/Inputs/debug-names-ef.s @@ -0,0 +1,332 @@ +.ifdef GEN +//--- e.cc +[[gnu::used]] int ve; +//--- f.cc +namespace ns { +[[gnu::used]] int vf; +} +//--- gen +clang -O1 -g -gpubnames -flto e.cc f.cc -nostdlib -fuse-ld=lld -Wl,--lto-emit-asm +cat a.out.lto.s +.endif + .text + .file "ld-temp.o" + .file 1 "/proc/self/cwd" "e.cc" md5 0xa8d6c645998197bd15436f2a351ebd6a + .file 2 "/proc/self/cwd" "f.cc" md5 0x6bf8b64f7d7116a3398f9522a92447f9 + .type ve,@object # @ve + .section .bss.ve,"aw",@nobits + .globl ve + .p2align 2, 0x0 +ve: + .long 0 # 0x0 + .size ve, 4 + + .type _ZN2ns2vfE,@object # @_ZN2ns2vfE + .section .bss._ZN2ns2vfE,"aw",@nobits + .globl _ZN2ns2vfE + .p2align 2, 0x0 +_ZN2ns2vfE: + .long 0 # 0x0 + .size _ZN2ns2vfE, 4 + + .section .debug_abbrev,"",@progbits + .byte 1 # Abbreviation Code + .byte 17 # DW_TAG_compile_unit + .byte 1 # DW_CHILDREN_yes + .byte 37 # DW_AT_producer + .byte 37 # DW_FORM_strx1 + .byte 19 # DW_AT_language + .byte 5 # DW_FORM_data2 + .byte 3 # DW_AT_name + .byte 37 # DW_FORM_strx1 + .byte 114 # DW_AT_str_offsets_base + .byte 23 # DW_FORM_sec_offset + .byte 16 # DW_AT_stmt_list + .byte 23 # DW_FORM_sec_offset + .byte 27 # DW_AT_comp_dir + .byte 37 # DW_FORM_strx1 + .byte 115 # DW_AT_addr_base + .byte 23 # DW_FORM_sec_offset + .byte 0 # EOM(1) + .byte 0 # EOM(2) + .byte 2 # Abbreviation Code + .byte 52 # DW_TAG_variable + .byte 0 # DW_CHILDREN_no + .byte 3 # DW_AT_name + .byte 37 # DW_FORM_strx1 + .byte 73 # DW_AT_type + .byte 19 # DW_FORM_ref4 + .byte 63 # DW_AT_external + .byte 25 # DW_FORM_flag_present + .byte 58 # DW_AT_decl_file + .byte 11 # DW_FORM_data1 + .byte 59 # DW_AT_decl_line + .byte 11 # DW_FORM_data1 + .byte 2 # DW_AT_location + .byte 24 # DW_FORM_exprloc + .byte 0 # EOM(1) + .byte 0 # EOM(2) + .byte 3 # Abbreviation Code + .byte 36 # DW_TAG_base_type + .byte 0 # DW_CHILDREN_no + .byte 3 # DW_AT_name + .byte 37 # DW_FORM_strx1 + .byte 62 # DW_AT_encoding + .byte 11 # DW_FORM_data1 + .byte 11 # DW_AT_byte_size + .byte 11 # DW_FORM_data1 + .byte 0 # EOM(1) + .byte 0 # EOM(2) + .byte 4 # Abbreviation Code + .byte 57 # DW_TAG_namespace + .byte 1 # DW_CHILDREN_yes + .byte 3 # DW_AT_name + .byte 37 # DW_FORM_strx1 + .byte 0 # EOM(1) + .byte 0 # EOM(2) + .byte 5 # Abbreviation Code + .byte 52 # DW_TAG_variable + .byte 0 # DW_CHILDREN_no + .byte 3 # DW_AT_name + .byte 37 # DW_FORM_strx1 + .byte 73 # DW_AT_type + .byte 16 # DW_FORM_ref_addr + .byte 63 # DW_AT_external + .byte 25 # DW_FORM_flag_present + .byte 58 # DW_AT_decl_file + .byte 11 # DW_FORM_data1 + .byte 59 # DW_AT_decl_line + .byte 11 # DW_FORM_data1 + .byte 2 # DW_AT_location + .byte 24 # DW_FORM_exprloc + .byte 110 # DW_AT_linkage_name + .byte 37 # DW_FORM_strx1 + .byte 0 # EOM(1) + .byte 0 # EOM(2) + .byte 0 # EOM(3) + .section .debug_info,"",@progbits +.Lcu_begin0: + .long .Ldebug_info_end0-.Ldebug_info_start0 # Length of Unit +.Ldebug_info_start0: + .short 5 # DWARF version number + .byte 1 # DWARF Unit Type + .byte 8 # Address Size (in bytes) + .long .debug_abbrev # Offset Into Abbrev. Section + .byte 1 # Abbrev [1] 0xc:0x22 DW_TAG_compile_unit + .byte 0 # DW_AT_producer + .short 33 # DW_AT_language + .byte 1 # DW_AT_name + .long .Lstr_offsets_base0 # DW_AT_str_offsets_base + .long .Lline_table_start0 # DW_AT_stmt_list + .byte 2 # DW_AT_comp_dir + .long .Laddr_table_base0 # DW_AT_addr_base + .byte 2 # Abbrev [2] 0x1e:0xb DW_TAG_variable + .byte 3 # DW_AT_name + .long 41 # DW_AT_type + # DW_AT_external + .byte 1 # DW_AT_decl_file + .byte 1 # DW_AT_decl_line + .byte 2 # DW_AT_location + .byte 161 + .byte 0 + .byte 3 # Abbrev [3] 0x29:0x4 DW_TAG_base_type + .byte 4 # DW_AT_name + .byte 5 # DW_AT_encoding + .byte 4 # DW_AT_byte_size + .byte 0 # End Of Children Mark +.Ldebug_info_end0: +.Lcu_begin1: + .long .Ldebug_info_end1-.Ldebug_info_start1 # Length of Unit +.Ldebug_info_start1: + .short 5 # DWARF version number + .byte 1 # DWARF Unit Type + .byte 8 # Address Size (in bytes) + .long .debug_abbrev # Offset Into Abbrev. Section + .byte 1 # Abbrev [1] 0xc:0x22 DW_TAG_compile_unit + .byte 0 # DW_AT_producer + .short 33 # DW_AT_language + .byte 5 # DW_AT_name + .long .Lstr_offsets_base0 # DW_AT_str_offsets_base + .long .Lline_table_start0 # DW_AT_stmt_list + .byte 2 # DW_AT_comp_dir + .long .Laddr_table_base0 # DW_AT_addr_base + .byte 4 # Abbrev [4] 0x1e:0xf DW_TAG_namespace + .byte 6 # DW_AT_name + .byte 5 # Abbrev [5] 0x20:0xc DW_TAG_variable + .byte 7 # DW_AT_name + .long .debug_info+41 # DW_AT_type + # DW_AT_external + .byte 2 # DW_AT_decl_file + .byte 2 # DW_AT_decl_line + .byte 2 # DW_AT_location + .byte 161 + .byte 1 + .byte 8 # DW_AT_linkage_name + .byte 0 # End Of Children Mark + .byte 0 # End Of Children Mark +.Ldebug_info_end1: + .section .debug_str_offsets,"",@progbits + .long 40 # Length of String Offsets Set + .short 5 + .short 0 +.Lstr_offsets_base0: + .section .debug_str,"MS",@progbits,1 +.Linfo_string0: + .byte 0 # string offset=0 +.Linfo_string1: + .asciz "e.cc" # string offset=1 +.Linfo_string2: + .asciz "/proc/self/cwd" # string offset=6 +.Linfo_string3: + .asciz "ve" # string offset=21 +.Linfo_string4: + .asciz "int" # string offset=24 +.Linfo_string5: + .asciz "f.cc" # string offset=28 +.Linfo_string6: + .asciz "ns" # string offset=33 +.Linfo_string7: + .asciz "vf" # string offset=36 +.Linfo_string8: + .asciz "_ZN2ns2vfE" # string offset=39 + .section .debug_str_offsets,"",@progbits + .long .Linfo_string0 + .long .Linfo_string1 + .long .Linfo_string2 + .long .Linfo_string3 + .long .Linfo_string4 + .long .Linfo_string5 + .long .Linfo_string6 + .long .Linfo_string7 + .long .Linfo_string8 + .section .debug_addr,"",@progbits + .long .Ldebug_addr_end0-.Ldebug_addr_start0 # Length of contribution +.Ldebug_addr_start0: + .short 5 # DWARF version number + .byte 8 # Address size + .byte 0 # Segment selector size +.Laddr_table_base0: + .quad ve + .quad _ZN2ns2vfE +.Ldebug_addr_end0: + .section .debug_names,"",@progbits + .long .Lnames_end0-.Lnames_start0 # Header: unit length +.Lnames_start0: + .short 5 # Header: version + .short 0 # Header: padding + .long 2 # Header: compilation unit count + .long 0 # Header: local type unit count + .long 0 # Header: foreign type unit count + .long 5 # Header: bucket count + .long 5 # Header: name count + .long .Lnames_abbrev_end0-.Lnames_abbrev_start0 # Header: abbreviation table size + .long 8 # Header: augmentation string size + .ascii "LLVM0700" # Header: augmentation string + .long .Lcu_begin0 # Compilation unit 0 + .long .Lcu_begin1 # Compilation unit 1 + .long 1 # Bucket 0 + .long 2 # Bucket 1 + .long 0 # Bucket 2 + .long 3 # Bucket 3 + .long 4 # Bucket 4 + .long 5863905 # Hash in Bucket 0 + .long -823734030 # Hash in Bucket 1 + .long 193495088 # Hash in Bucket 3 + .long 5863654 # Hash in Bucket 4 + .long 5863904 # Hash in Bucket 4 + .long .Linfo_string7 # String in Bucket 0: vf + .long .Linfo_string8 # String in Bucket 1: _ZN2ns2vfE + .long .Linfo_string4 # String in Bucket 3: int + .long .Linfo_string6 # String in Bucket 4: ns + .long .Linfo_string3 # String in Bucket 4: ve + .long .Lnames3-.Lnames_entries0 # Offset in Bucket 0 + .long .Lnames4-.Lnames_entries0 # Offset in Bucket 1 + .long .Lnames0-.Lnames_entries0 # Offset in Bucket 3 + .long .Lnames2-.Lnames_entries0 # Offset in Bucket 4 + .long .Lnames1-.Lnames_entries0 # Offset in Bucket 4 +.Lnames_abbrev_start0: + .byte 1 # Abbrev code + .byte 52 # DW_TAG_variable + .byte 1 # DW_IDX_compile_unit + .byte 11 # DW_FORM_data1 + .byte 3 # DW_IDX_die_offset + .byte 19 # DW_FORM_ref4 + .byte 4 # DW_IDX_parent + .byte 19 # DW_FORM_ref4 + .byte 0 # End of abbrev + .byte 0 # End of abbrev + .byte 2 # Abbrev code + .byte 36 # DW_TAG_base_type + .byte 1 # DW_IDX_compile_unit + .byte 11 # DW_FORM_data1 + .byte 3 # DW_IDX_die_offset + .byte 19 # DW_FORM_ref4 + .byte 4 # DW_IDX_parent + .byte 25 # DW_FORM_flag_present + .byte 0 # End of abbrev + .byte 0 # End of abbrev + .byte 3 # Abbrev code + .byte 57 # DW_TAG_namespace + .byte 1 # DW_IDX_compile_unit + .byte 11 # DW_FORM_data1 + .byte 3 # DW_IDX_die_offset + .byte 19 # DW_FORM_ref4 + .byte 4 # DW_IDX_parent + .byte 25 # DW_FORM_flag_present + .byte 0 # End of abbrev + .byte 0 # End of abbrev + .byte 4 # Abbrev code + .byte 52 # DW_TAG_variable + .byte 1 # DW_IDX_compile_unit + .byte 11 # DW_FORM_data1 + .byte 3 # DW_IDX_die_offset + .byte 19 # DW_FORM_ref4 + .byte 4 # DW_IDX_parent + .byte 25 # DW_FORM_flag_present + .byte 0 # End of abbrev + .byte 0 # End of abbrev + .byte 0 # End of abbrev list +.Lnames_abbrev_end0: +.Lnames_entries0: +.Lnames3: +.L2: + .byte 1 # Abbreviation code + .byte 1 # DW_IDX_compile_unit + .long 32 # DW_IDX_die_offset + .long .L0-.Lnames_entries0 # DW_IDX_parent + .byte 0 # End of list: vf +.Lnames4: + .byte 1 # Abbreviation code + .byte 1 # DW_IDX_compile_unit + .long 32 # DW_IDX_die_offset + .long .L0-.Lnames_entries0 # DW_IDX_parent + .byte 0 # End of list: _ZN2ns2vfE +.Lnames0: +.L3: + .byte 2 # Abbreviation code + .byte 0 # DW_IDX_compile_unit + .long 41 # DW_IDX_die_offset + .byte 0 # DW_IDX_parent + # End of list: int +.Lnames2: +.L0: + .byte 3 # Abbreviation code + .byte 1 # DW_IDX_compile_unit + .long 30 # DW_IDX_die_offset + .byte 0 # DW_IDX_parent + # End of list: ns +.Lnames1: +.L1: + .byte 4 # Abbreviation code + .byte 0 # DW_IDX_compile_unit + .long 30 # DW_IDX_die_offset + .byte 0 # DW_IDX_parent + # End of list: ve + .p2align 2, 0x0 +.Lnames_end0: + .section ".note.GNU-stack","",@progbits + .addrsig + .addrsig_sym ve + .addrsig_sym _ZN2ns2vfE + .section .debug_line,"",@progbits +.Lline_table_start0: diff --git a/lld/test/ELF/debug-names-bad-aug-string.s b/lld/test/ELF/debug-names-bad-aug-string.s deleted file mode 100644 index 62ed64aa5b570..0000000000000 --- a/lld/test/ELF/debug-names-bad-aug-string.s +++ /dev/null @@ -1,305 +0,0 @@ -# This file was generated by copying debug-names.s and manually -# editing the 'Header: augmentation string' in the .debug_names section. - -# REQUIRES: x86 -# RUN: rm -rf %t && split-file %s %t && cd %t -# RUN: llvm-mc -filetype=obj -triple=x86_64 a.s -o a.o -# RUN: llvm-mc -filetype=obj -triple=x86_64 b.s -o b.o -# RUN: ld.lld --debug-names a.o b.o -o out -# RUN: llvm-dwarfdump -debug-names out | FileCheck %s --check-prefix=DWARF - -# DWARF: .debug_names contents: -# DWARF: Name Index @ 0x0 { -# DWARF-NEXT: Header { -# DWARF-NEXT: Length: 0xC0 -# DWARF-NEXT: Format: DWARF32 -# DWARF-NEXT: Version: 5 -# DWARF-NEXT: CU count: 2 -# DWARF-NEXT: Local TU count: 0 -# DWARF-NEXT: Foreign TU count: 0 -# DWARF-NEXT: Bucket count: 5 -# DWARF-NEXT: Name count: 5 -# DWARF-NEXT: Abbreviations table size: 0x1F -# DWARF-NEXT: Augmentation: '' -# DWARF: Compilation Unit offsets [ -# DWARF-NEXT: CU[0]: 0x00000000 -# DWARF-NEXT: CU[1]: 0x0000000c - -#--- a.s - .text - .globl _Z2f12t1 # -- Begin function _Z2f12t1 - .p2align 4, 0x90 - .type _Z2f12t1,@function -_Z2f12t1: # @_Z2f12t1 -.Lfunc_begin0: - .cfi_startproc -# %bb.0: # %entry - pushq %rbp - .cfi_def_cfa_offset 16 - .cfi_offset %rbp, -16 - movq %rsp, %rbp - .cfi_def_cfa_register %rbp -.Ltmp0: - popq %rbp - .cfi_def_cfa %rsp, 8 - retq -.Ltmp1: -.Lfunc_end0: - .size _Z2f12t1, .Lfunc_end0-_Z2f12t1 - .cfi_endproc - # -- End function - .section .debug_abbrev,"",@progbits - .byte 0 # EOM(1) - .byte 0 # EOM(2) - .byte 0 # EOM(3) - .section .debug_info,"",@progbits -.Lcu_begin0: - .long .Ldebug_info_end0-.Ldebug_info_start0 # Length of Unit -.Ldebug_info_start0: - .short 5 # DWARF version number - .byte 1 # DWARF Unit Type - .byte 8 # Address Size (in bytes) - .long .debug_abbrev # Offset Into Abbrev. Section -.Ldebug_info_end0: - .section .debug_str_offsets,"",@progbits - .long 28 # Length of String Offsets Set - .short 5 - .short 0 -.Lstr_offsets_base0: - .section .debug_str,"MS",@progbits,1 -.Linfo_string0: - .asciz "clang version 19.0.0git (git@github.com:llvm/llvm-project.git 53b14cd9ce2b57da73d173fc876d2e9e199f5640)" # string offset=0 -.Linfo_string1: - .asciz "a.cpp" # string offset=104 -.Linfo_string2: - .asciz "/proc/self/cwd" # string offset=110 -.Linfo_string3: - .asciz "f1" # string offset=125 -.Linfo_string4: - .asciz "_Z2f12t1" # string offset=128 -.Linfo_string5: - .asciz "t1" # string offset=137 -.Laddr_table_base0: - .quad .Lfunc_begin0 -.Ldebug_addr_end0: - .section .debug_names,"",@progbits - .long .Lnames_end0-.Lnames_start0 # Header: unit length -.Lnames_start0: - .short 5 # Header: version - .short 0 # Header: padding - .long 1 # Header: compilation unit count - .long 0 # Header: local type unit count - .long 0 # Header: foreign type unit count - .long 3 # Header: bucket count - .long 3 # Header: name count - .long .Lnames_abbrev_end0-.Lnames_abbrev_start0 # Header: abbreviation table size - .long 8 # Header: augmentation string size - .ascii "JUNK1234" # Header: augmentation string - .long .Lcu_begin0 # Compilation unit 0 - .long 0 # Bucket 0 - .long 1 # Bucket 1 - .long 3 # Bucket 2 - .long 5863324 # Hash in Bucket 1 - .long 5863786 # Hash in Bucket 1 - .long 1398125246 # Hash in Bucket 2 - .long .Linfo_string3 # String in Bucket 1: f1 - .long .Linfo_string5 # String in Bucket 1: t1 - .long .Linfo_string4 # String in Bucket 2: _Z2f12t1 - .long .Lnames0-.Lnames_entries0 # Offset in Bucket 1 - .long .Lnames2-.Lnames_entries0 # Offset in Bucket 1 - .long .Lnames1-.Lnames_entries0 # Offset in Bucket 2 -.Lnames_abbrev_start0: - .byte 1 # Abbrev code - .byte 46 # DW_TAG_subprogram - .byte 3 # DW_IDX_die_offset - .byte 19 # DW_FORM_ref4 - .byte 4 # DW_IDX_parent - .byte 25 # DW_FORM_flag_present - .byte 0 # End of abbrev - .byte 0 # End of abbrev - .byte 2 # Abbrev code - .byte 19 # DW_TAG_structure_type - .byte 3 # DW_IDX_die_offset - .byte 19 # DW_FORM_ref4 - .byte 4 # DW_IDX_parent - .byte 25 # DW_FORM_flag_present - .byte 0 # End of abbrev - .byte 0 # End of abbrev - .byte 0 # End of abbrev list -.Lnames_abbrev_end0: -.Lnames_entries0: -.Lnames0: -.L1: - .byte 1 # Abbreviation code - .long 35 # DW_IDX_die_offset - .byte 0 # DW_IDX_parent - # End of list: f1 -.Lnames2: -.L0: - .byte 2 # Abbreviation code - .long 58 # DW_IDX_die_offset - .byte 0 # DW_IDX_parent - # End of list: t1 -.Lnames1: - .byte 1 # Abbreviation code - .long 35 # DW_IDX_die_offset - .byte 0 # DW_IDX_parent - # End of list: _Z2f12t1 - .p2align 2, 0x0 -.Lnames_end0: - .ident "clang version 19.0.0git (git@github.com:llvm/llvm-project.git 53b14cd9ce2b57da73d173fc876d2e9e199f5640)" - .section ".note.GNU-stack","",@progbits - .addrsig - .section .debug_line,"",@progbits -.Lline_table_start0: - -#--- b.s -# Generated with: -# - clang++ -g -O0 -gpubnames -fdebug-compilation-dir='/proc/self/cwdt' \ -# -S b.cpp -o b.s - -# b.cpp contents: - -# struct t1 { }; -# int main() { -# t1 v1; -# } -# - .text - .globl main # -- Begin function main - .p2align 4, 0x90 - .type main,@function -main: # @main -.Lfunc_begin0: - .cfi_startproc -# %bb.0: # %entry - pushq %rbp - .cfi_def_cfa_offset 16 - .cfi_offset %rbp, -16 - movq %rsp, %rbp - .cfi_def_cfa_register %rbp -.Ltmp0: - xorl %eax, %eax - popq %rbp - .cfi_def_cfa %rsp, 8 - retq -.Ltmp1: -.Lfunc_end0: - .size main, .Lfunc_end0-main - .cfi_endproc - # -- End function - .section .debug_abbrev,"",@progbits - .byte 0 # EOM(1) - .byte 0 # EOM(2) - .byte 0 # EOM(3) - .section .debug_info,"",@progbits -.Lcu_begin0: - .long .Ldebug_info_end0-.Ldebug_info_start0 # Length of Unit -.Ldebug_info_start0: - .short 5 # DWARF version number - .byte 1 # DWARF Unit Type - .byte 8 # Address Size (in bytes) - .long .debug_abbrev # Offset Into Abbrev. Section -.Ldebug_info_end0: - .section .debug_str_offsets,"",@progbits - .long 32 # Length of String Offsets Set - .short 5 - .short 0 -.Lstr_offsets_base0: - .section .debug_str,"MS",@progbits,1 -.Linfo_string0: - .asciz "clang version 19.0.0git (git@github.com:llvm/llvm-project.git 53b14cd9ce2b57da73d173fc876d2e9e199f5640)" # string offset=0 -.Linfo_string1: - .asciz "b.cpp" # string offset=104 -.Linfo_string2: - .asciz "/proc/self/cwd" # string offset=110 -.Linfo_string3: - .asciz "main" # string offset=125 -.Linfo_string4: - .asciz "int" # string offset=130 -.Linfo_string5: - .asciz "v1" # string offset=134 -.Linfo_string6: - .asciz "t1" # string offset=137 -.Laddr_table_base0: - .quad .Lfunc_begin0 -.Ldebug_addr_end0: - .section .debug_names,"",@progbits - .long .Lnames_end0-.Lnames_start0 # Header: unit length -.Lnames_start0: - .short 5 # Header: version - .short 0 # Header: padding - .long 1 # Header: compilation unit count - .long 0 # Header: local type unit count - .long 0 # Header: foreign type unit count - .long 3 # Header: bucket count - .long 3 # Header: name count - .long .Lnames_abbrev_end0-.Lnames_abbrev_start0 # Header: abbreviation table size - .long 8 # Header: augmentation string size - .ascii "LLVM0700" # Header: augmentation string - .long .Lcu_begin0 # Compilation unit 0 - .long 0 # Bucket 0 - .long 1 # Bucket 1 - .long 3 # Bucket 2 - .long 5863786 # Hash in Bucket 1 - .long 2090499946 # Hash in Bucket 1 - .long 193495088 # Hash in Bucket 2 - .long .Linfo_string6 # String in Bucket 1: t1 - .long .Linfo_string3 # String in Bucket 1: main - .long .Linfo_string4 # String in Bucket 2: int - .long .Lnames2-.Lnames_entries0 # Offset in Bucket 1 - .long .Lnames0-.Lnames_entries0 # Offset in Bucket 1 - .long .Lnames1-.Lnames_entries0 # Offset in Bucket 2 -.Lnames_abbrev_start0: - .byte 1 # Abbrev code - .byte 19 # DW_TAG_structure_type - .byte 3 # DW_IDX_die_offset - .byte 19 # DW_FORM_ref4 - .byte 4 # DW_IDX_parent - .byte 25 # DW_FORM_flag_present - .byte 0 # End of abbrev - .byte 0 # End of abbrev - .byte 2 # Abbrev code - .byte 46 # DW_TAG_subprogram - .byte 3 # DW_IDX_die_offset - .byte 19 # DW_FORM_ref4 - .byte 4 # DW_IDX_parent - .byte 25 # DW_FORM_flag_present - .byte 0 # End of abbrev - .byte 0 # End of abbrev - .byte 3 # Abbrev code - .byte 36 # DW_TAG_base_type - .byte 3 # DW_IDX_die_offset - .byte 19 # DW_FORM_ref4 - .byte 4 # DW_IDX_parent - .byte 25 # DW_FORM_flag_present - .byte 0 # End of abbrev - .byte 0 # End of abbrev - .byte 0 # End of abbrev list -.Lnames_abbrev_end0: -.Lnames_entries0: -.Lnames2: -.L1: - .byte 1 # Abbreviation code - .long 66 # DW_IDX_die_offset - .byte 0 # DW_IDX_parent - # End of list: t1 -.Lnames0: -.L2: - .byte 2 # Abbreviation code - .long 35 # DW_IDX_die_offset - .byte 0 # DW_IDX_parent - # End of list: main -.Lnames1: -.L0: - .byte 3 # Abbreviation code - .long 62 # DW_IDX_die_offset - .byte 0 # DW_IDX_parent - # End of list: int - .p2align 2, 0x0 -.Lnames_end0: - .ident "clang version 19.0.0git (git@github.com:llvm/llvm-project.git 53b14cd9ce2b57da73d173fc876d2e9e199f5640)" - .section ".note.GNU-stack","",@progbits - .addrsig - .section .debug_line,"",@progbits -.Lline_table_start0: diff --git a/lld/test/ELF/debug-names-bad-offsets-sizes.s b/lld/test/ELF/debug-names-bad-offsets-sizes.s deleted file mode 100644 index e70a6215f3c87..0000000000000 --- a/lld/test/ELF/debug-names-bad-offsets-sizes.s +++ /dev/null @@ -1,153 +0,0 @@ -# This file was generated by first compiling a.cpp: -# clang++ -g -O0 -S -gpubnames -fdebug-compilation-dir='/proc/self/cwd' a.cpp - -# Then manually edit .debug_names section. Change the sizes of -# 'Offset in Bucket' values from '.long' to '.byte'. - -# Contents of a.cpp: -# int main (int argc, char **argv) { } - -# REQUIRES: x86 -# RUN: llvm-mc -filetype=obj -triple=x86_64 %s -o %t1.o - -# RUN: not ld.lld --debug-names %t1.o -o /dev/null 2>&1 \ -# RUN: | FileCheck -DFILE=%t1.o --implicit-check-not=error: %s - -# CHECK: error: [[FILE]]:(.debug_names): index entry is out of bounds -# CHECK-NEXT: error: [[FILE]]:(.debug_names): index entry is out of bounds -# CHECK-NEXT: error: [[FILE]]:(.debug_names): index entry is out of bounds - - .text - .globl main # -- Begin function main - .p2align 4, 0x90 - .type main,@function -main: # @main -.Lfunc_begin0: - .cfi_startproc -# %bb.0: # %entry - pushq %rbp - .cfi_def_cfa_offset 16 - .cfi_offset %rbp, -16 - movq %rsp, %rbp - .cfi_def_cfa_register %rbp - movl %edi, -4(%rbp) - movq %rsi, -16(%rbp) -.Ltmp0: - xorl %eax, %eax - popq %rbp - .cfi_def_cfa %rsp, 8 - retq -.Ltmp1: -.Lfunc_end0: - .size main, .Lfunc_end0-main - .cfi_endproc - # -- End function - .section .debug_abbrev,"",@progbits - .byte 0 # EOM(1) - .byte 0 # EOM(2) - .byte 0 # EOM(3) - .section .debug_info,"",@progbits -.Lcu_begin0: - .long .Ldebug_info_end0-.Ldebug_info_start0 # Length of Unit -.Ldebug_info_start0: - .short 5 # DWARF version number - .byte 1 # DWARF Unit Type - .byte 8 # Address Size (in bytes) - .long .debug_abbrev # Offset Into Abbrev. Section -.Ldebug_info_end0: - .section .debug_str_offsets,"",@progbits - .long 36 # Length of String Offsets Set - .short 5 - .short 0 -.Lstr_offsets_base0: - .section .debug_str,"MS",@progbits,1 -.Linfo_string0: - .asciz "clang version 19.0.0git (git@github.com:llvm/llvm-project.git 53b14cd9ce2b57da73d173fc876d2e9e199f5640)" # string offset=0 -.Linfo_string1: - .asciz "a.cpp" # string offset=104 -.Linfo_string2: - .asciz "/proc/self/cwd" # string offset=110 -.Linfo_string3: - .asciz "main" # string offset=125 -.Linfo_string4: - .asciz "int" # string offset=130 -.Linfo_string5: - .asciz "argc" # string offset=134 -.Linfo_string6: - .asciz "argv" # string offset=139 -.Linfo_string7: - .asciz "char" # string offset=144 -.Laddr_table_base0: - .quad .Lfunc_begin0 -.Ldebug_addr_end0: - .section .debug_names,"",@progbits - .long .Lnames_end0-.Lnames_start0 # Header: unit length -.Lnames_start0: - .short 5 # Header: version - .short 0 # Header: padding - .long 1 # Header: compilation unit count - .long 0 # Header: local type unit count - .long 0 # Header: foreign type unit count - .long 3 # Header: bucket count - .long 3 # Header: name count - .long .Lnames_abbrev_end0-.Lnames_abbrev_start0 # Header: abbreviation table size - .long 8 # Header: augmentation string size - .ascii "LLVM0700" # Header: augmentation string - .long .Lcu_begin0 # Compilation unit 0 - .long 0 # Bucket 0 - .long 1 # Bucket 1 - .long 2 # Bucket 2 - .long 2090499946 # Hash in Bucket 1 - .long 193495088 # Hash in Bucket 2 - .long 2090147939 # Hash in Bucket 2 - .long .Linfo_string3 # String in Bucket 1: main - .long .Linfo_string4 # String in Bucket 2: int - .long .Linfo_string7 # String in Bucket 2: char - .byte .Lnames0-.Lnames_entries0 # Offset in Bucket 1 - .byte .Lnames1-.Lnames_entries0 # Offset in Bucket 2 - .byte .Lnames2-.Lnames_entries0 # Offset in Bucket 2 -.Lnames_abbrev_start0: - .byte 1 # Abbrev code - .byte 46 # DW_TAG_subprogram - .byte 3 # DW_IDX_die_offset - .byte 19 # DW_FORM_ref4 - .byte 4 # DW_IDX_parent - .byte 25 # DW_FORM_flag_present - .byte 0 # End of abbrev - .byte 0 # End of abbrev - .byte 2 # Abbrev code - .byte 36 # DW_TAG_base_type - .byte 3 # DW_IDX_die_offset - .byte 19 # DW_FORM_ref4 - .byte 4 # DW_IDX_parent - .byte 25 # DW_FORM_flag_present - .byte 0 # End of abbrev - .byte 0 # End of abbrev - .byte 0 # End of abbrev list -.Lnames_abbrev_end0: -.Lnames_entries0: -.Lnames0: -.L1: - .byte 1 # Abbreviation code - .long 35 # DW_IDX_die_offset - .byte 0 # DW_IDX_parent - # End of list: main -.Lnames1: -.L0: - .byte 2 # Abbreviation code - .long 73 # DW_IDX_die_offset - .byte 0 # DW_IDX_parent - # End of list: int -.Lnames2: -.L2: - .byte 2 # Abbreviation code - .long 87 # DW_IDX_die_offset - .byte 0 # DW_IDX_parent - # End of list: char - .p2align 2, 0x0 -.Lnames_end0: - .ident "clang version 19.0.0git (git@github.com:llvm/llvm-project.git 53b14cd9ce2b57da73d173fc876d2e9e199f5640)" - .section ".note.GNU-stack","",@progbits - .addrsig - .section .debug_line,"",@progbits -.Lline_table_start0: diff --git a/lld/test/ELF/debug-names-bad-version.s b/lld/test/ELF/debug-names-bad-version.s deleted file mode 100644 index 4835c4a3fa742..0000000000000 --- a/lld/test/ELF/debug-names-bad-version.s +++ /dev/null @@ -1,291 +0,0 @@ -# This file was generated by copying debug-names.s and manually -# editing the 'Header: version' in the .debug_names section (changed it from -# 5 to 4). - -# REQUIRES: x86 -# RUN: rm -rf %t && split-file %s %t && cd %t -# RUN: llvm-mc -filetype=obj -triple=x86_64 a.s -o a.o -# RUN: llvm-mc -filetype=obj -triple=x86_64 b.s -o b.o -# RUN: not ld.lld --debug-names a.o b.o 2>&1 \ -# RUN: | FileCheck -DFILE=a.o %s --implicit-check-not=error: - -# CHECK: error: [[FILE]]:(.debug_names): unsupported version: 4 - -#--- a.s - .text - .globl _Z2f12t1 # -- Begin function _Z2f12t1 - .p2align 4, 0x90 - .type _Z2f12t1,@function -_Z2f12t1: # @_Z2f12t1 -.Lfunc_begin0: - .cfi_startproc -# %bb.0: # %entry - pushq %rbp - .cfi_def_cfa_offset 16 - .cfi_offset %rbp, -16 - movq %rsp, %rbp - .cfi_def_cfa_register %rbp -.Ltmp0: - popq %rbp - .cfi_def_cfa %rsp, 8 - retq -.Ltmp1: -.Lfunc_end0: - .size _Z2f12t1, .Lfunc_end0-_Z2f12t1 - .cfi_endproc - # -- End function - .section .debug_abbrev,"",@progbits - .byte 0 # EOM(1) - .byte 0 # EOM(2) - .byte 0 # EOM(3) - .section .debug_info,"",@progbits -.Lcu_begin0: - .long .Ldebug_info_end0-.Ldebug_info_start0 # Length of Unit -.Ldebug_info_start0: - .short 5 # DWARF version number - .byte 1 # DWARF Unit Type - .byte 8 # Address Size (in bytes) - .long .debug_abbrev # Offset Into Abbrev. Section -.Ldebug_info_end0: - .section .debug_str_offsets,"",@progbits - .long 28 # Length of String Offsets Set - .short 5 - .short 0 -.Lstr_offsets_base0: - .section .debug_str,"MS",@progbits,1 -.Linfo_string0: - .asciz "clang version 19.0.0git (git@github.com:llvm/llvm-project.git 53b14cd9ce2b57da73d173fc876d2e9e199f5640)" # string offset=0 -.Linfo_string1: - .asciz "a.cpp" # string offset=104 -.Linfo_string2: - .asciz "/proc/self/cwd" # string offset=110 -.Linfo_string3: - .asciz "f1" # string offset=125 -.Linfo_string4: - .asciz "_Z2f12t1" # string offset=128 -.Linfo_string5: - .asciz "t1" # string offset=137 -.Laddr_table_base0: - .quad .Lfunc_begin0 -.Ldebug_addr_end0: - .section .debug_names,"",@progbits - .long .Lnames_end0-.Lnames_start0 # Header: unit length -.Lnames_start0: - .short 4 # Header: version - .short 0 # Header: padding - .long 1 # Header: compilation unit count - .long 0 # Header: local type unit count - .long 0 # Header: foreign type unit count - .long 3 # Header: bucket count - .long 3 # Header: name count - .long .Lnames_abbrev_end0-.Lnames_abbrev_start0 # Header: abbreviation table size - .long 8 # Header: augmentation string size - .ascii "LLVM0700" # Header: augmentation string - .long .Lcu_begin0 # Compilation unit 0 - .long 0 # Bucket 0 - .long 1 # Bucket 1 - .long 3 # Bucket 2 - .long 5863324 # Hash in Bucket 1 - .long 5863786 # Hash in Bucket 1 - .long 1398125246 # Hash in Bucket 2 - .long .Linfo_string3 # String in Bucket 1: f1 - .long .Linfo_string5 # String in Bucket 1: t1 - .long .Linfo_string4 # String in Bucket 2: _Z2f12t1 - .long .Lnames0-.Lnames_entries0 # Offset in Bucket 1 - .long .Lnames2-.Lnames_entries0 # Offset in Bucket 1 - .long .Lnames1-.Lnames_entries0 # Offset in Bucket 2 -.Lnames_abbrev_start0: - .byte 1 # Abbrev code - .byte 46 # DW_TAG_subprogram - .byte 3 # DW_IDX_die_offset - .byte 19 # DW_FORM_ref4 - .byte 4 # DW_IDX_parent - .byte 25 # DW_FORM_flag_present - .byte 0 # End of abbrev - .byte 0 # End of abbrev - .byte 2 # Abbrev code - .byte 19 # DW_TAG_structure_type - .byte 3 # DW_IDX_die_offset - .byte 19 # DW_FORM_ref4 - .byte 4 # DW_IDX_parent - .byte 25 # DW_FORM_flag_present - .byte 0 # End of abbrev - .byte 0 # End of abbrev - .byte 0 # End of abbrev list -.Lnames_abbrev_end0: -.Lnames_entries0: -.Lnames0: -.L1: - .byte 1 # Abbreviation code - .long 35 # DW_IDX_die_offset - .byte 0 # DW_IDX_parent - # End of list: f1 -.Lnames2: -.L0: - .byte 2 # Abbreviation code - .long 58 # DW_IDX_die_offset - .byte 0 # DW_IDX_parent - # End of list: t1 -.Lnames1: - .byte 1 # Abbreviation code - .long 35 # DW_IDX_die_offset - .byte 0 # DW_IDX_parent - # End of list: _Z2f12t1 - .p2align 2, 0x0 -.Lnames_end0: - .ident "clang version 19.0.0git (git@github.com:llvm/llvm-project.git 53b14cd9ce2b57da73d173fc876d2e9e199f5640)" - .section ".note.GNU-stack","",@progbits - .addrsig - .section .debug_line,"",@progbits -.Lline_table_start0: - -#--- b.s -# Generated with: -# - clang++ -g -O0 -gpubnames -fdebug-compilation-dir='/proc/self/cwd' \ -# -S b.cpp -o b.s - -# b.cpp contents: - -# struct t1 { }; -# int main() { -# t1 v1; -# } -# - .text - .globl main # -- Begin function main - .p2align 4, 0x90 - .type main,@function -main: # @main -.Lfunc_begin0: - .cfi_startproc -# %bb.0: # %entry - pushq %rbp - .cfi_def_cfa_offset 16 - .cfi_offset %rbp, -16 - movq %rsp, %rbp - .cfi_def_cfa_register %rbp -.Ltmp0: - xorl %eax, %eax - popq %rbp - .cfi_def_cfa %rsp, 8 - retq -.Ltmp1: -.Lfunc_end0: - .size main, .Lfunc_end0-main - .cfi_endproc - # -- End function - .section .debug_abbrev,"",@progbits - .byte 0 # EOM(1) - .byte 0 # EOM(2) - .byte 0 # EOM(3) - .section .debug_info,"",@progbits -.Lcu_begin0: - .long .Ldebug_info_end0-.Ldebug_info_start0 # Length of Unit -.Ldebug_info_start0: - .short 4 # DWARF version number - .byte 1 # DWARF Unit Type - .byte 8 # Address Size (in bytes) - .long .debug_abbrev # Offset Into Abbrev. Section -.Ldebug_info_end0: - .section .debug_str_offsets,"",@progbits - .long 32 # Length of String Offsets Set - .short 5 - .short 0 -.Lstr_offsets_base0: - .section .debug_str,"MS",@progbits,1 -.Linfo_string0: - .asciz "clang version 19.0.0git (git@github.com:llvm/llvm-project.git 53b14cd9ce2b57da73d173fc876d2e9e199f5640)" # string offset=0 -.Linfo_string1: - .asciz "b.cpp" # string offset=104 -.Linfo_string2: - .asciz "/proc/self/cwd" # string offset=110 -.Linfo_string3: - .asciz "main" # string offset=125 -.Linfo_string4: - .asciz "int" # string offset=130 -.Linfo_string5: - .asciz "v1" # string offset=134 -.Linfo_string6: - .asciz "t1" # string offset=137 -.Laddr_table_base0: - .quad .Lfunc_begin0 -.Ldebug_addr_end0: - .section .debug_names,"",@progbits - .long .Lnames_end0-.Lnames_start0 # Header: unit length -.Lnames_start0: - .short 5 # Header: version - .short 0 # Header: padding - .long 1 # Header: compilation unit count - .long 0 # Header: local type unit count - .long 0 # Header: foreign type unit count - .long 3 # Header: bucket count - .long 3 # Header: name count - .long .Lnames_abbrev_end0-.Lnames_abbrev_start0 # Header: abbreviation table size - .long 8 # Header: augmentation string size - .ascii "LLVM0700" # Header: augmentation string - .long .Lcu_begin0 # Compilation unit 0 - .long 0 # Bucket 0 - .long 1 # Bucket 1 - .long 3 # Bucket 2 - .long 5863786 # Hash in Bucket 1 - .long 2090499946 # Hash in Bucket 1 - .long 193495088 # Hash in Bucket 2 - .long .Linfo_string6 # String in Bucket 1: t1 - .long .Linfo_string3 # String in Bucket 1: main - .long .Linfo_string4 # String in Bucket 2: int - .long .Lnames2-.Lnames_entries0 # Offset in Bucket 1 - .long .Lnames0-.Lnames_entries0 # Offset in Bucket 1 - .long .Lnames1-.Lnames_entries0 # Offset in Bucket 2 -.Lnames_abbrev_start0: - .byte 1 # Abbrev code - .byte 19 # DW_TAG_structure_type - .byte 3 # DW_IDX_die_offset - .byte 19 # DW_FORM_ref4 - .byte 4 # DW_IDX_parent - .byte 25 # DW_FORM_flag_present - .byte 0 # End of abbrev - .byte 0 # End of abbrev - .byte 2 # Abbrev code - .byte 46 # DW_TAG_subprogram - .byte 3 # DW_IDX_die_offset - .byte 19 # DW_FORM_ref4 - .byte 4 # DW_IDX_parent - .byte 25 # DW_FORM_flag_present - .byte 0 # End of abbrev - .byte 0 # End of abbrev - .byte 3 # Abbrev code - .byte 36 # DW_TAG_base_type - .byte 3 # DW_IDX_die_offset - .byte 19 # DW_FORM_ref4 - .byte 4 # DW_IDX_parent - .byte 25 # DW_FORM_flag_present - .byte 0 # End of abbrev - .byte 0 # End of abbrev - .byte 0 # End of abbrev list -.Lnames_abbrev_end0: -.Lnames_entries0: -.Lnames2: -.L1: - .byte 1 # Abbreviation code - .long 66 # DW_IDX_die_offset - .byte 0 # DW_IDX_parent - # End of list: t1 -.Lnames0: -.L2: - .byte 2 # Abbreviation code - .long 35 # DW_IDX_die_offset - .byte 0 # DW_IDX_parent - # End of list: main -.Lnames1: -.L0: - .byte 3 # Abbreviation code - .long 62 # DW_IDX_die_offset - .byte 0 # DW_IDX_parent - # End of list: int - .p2align 2, 0x0 -.Lnames_end0: - .ident "clang version 19.0.0git (git@github.com:llvm/llvm-project.git 53b14cd9ce2b57da73d173fc876d2e9e199f5640)" - .section ".note.GNU-stack","",@progbits - .addrsig - .section .debug_line,"",@progbits -.Lline_table_start0: diff --git a/lld/test/ELF/debug-names-bad.s b/lld/test/ELF/debug-names-bad.s new file mode 100644 index 0000000000000..4b0c0b9bbf4e4 --- /dev/null +++ b/lld/test/ELF/debug-names-bad.s @@ -0,0 +1,91 @@ +# REQUIRES: x86 +# RUN: rm -rf %t && mkdir %t && cd %t + +## Test errors in the header. +# RUN: sed '/Header: version/s/5/4/' %S/Inputs/debug-names-a.s > bad-version.s +# RUN: llvm-mc -filetype=obj -triple=x86_64 bad-version.s -o bad-version.o +# RUN: not ld.lld --debug-names bad-version.o 2>&1 | FileCheck %s --check-prefix=BAD-VERSION --implicit-check-not=error: + +# BAD-VERSION: error: bad-version.o:(.debug_names): unsupported version: 4 + +# RUN: sed '/Header: name count/s/[0-9]/4/' %S/Inputs/debug-names-a.s > bad-name-count.s +# RUN: llvm-mc -filetype=obj -triple=x86_64 bad-name-count.s -o bad-name-count.o +# RUN: not ld.lld --debug-names bad-name-count.o 2>&1 | FileCheck %s --check-prefix=BAD-NAME-COUNT --implicit-check-not=error: + +## Test errors in offsets. +# BAD-NAME-COUNT: error: bad-name-count.o:(.debug_names): Section too small: cannot read abbreviations. + +# RUN: sed '/Offset in Bucket/s/long/byte/' %S/Inputs/debug-names-a.s > entry-offset-in-byte.s +# RUN: llvm-mc -filetype=obj -triple=x86_64 entry-offset-in-byte.s -o entry-offset-in-byte.o +# RUN: not ld.lld --debug-names entry-offset-in-byte.o 2>&1 | FileCheck %s --check-prefix=ENTRY-OFFSET-IN-BYTE --implicit-check-not=error: + +# ENTRY-OFFSET-IN-BYTE-COUNT-2: error: entry-offset-in-byte.o:(.debug_names): index entry is out of bounds + +## Test errors in the abbrev table. +# RUN: sed -E '/DW_IDX_die_offset/{n;s/[0-9]+.*DW_FORM_ref4/16/}' %S/Inputs/debug-names-a.s > bad-die-form.s +# RUN: llvm-mc -filetype=obj -triple=x86_64 bad-die-form.s -o bad-die-form.o +# RUN: not ld.lld --debug-names bad-die-form.o 2>&1 | FileCheck %s --check-prefix=BAD-DIE-FORM --implicit-check-not=error: + +# BAD-DIE-FORM: error: bad-die-form.o:(.debug_names): unrecognized form encoding 16 in abbrev table + +## Test errors in the entry pool. +# RUN: sed -E '/Lnames.:/{n;n;s/[0-9]+/3/}' %S/Inputs/debug-names-a.s > bad-abbrev-code.s +# RUN: llvm-mc -filetype=obj -triple=x86_64 bad-abbrev-code.s -o bad-abbrev-code.o +# RUN: not ld.lld --debug-names bad-abbrev-code.o 2>&1 | FileCheck %s --check-prefix=BAD-ABBREV-CODE --implicit-check-not=error: +# RUN: ld.lld --debug-names bad-abbrev-code.o -o bad-abbrev-code --noinhibit-exec +# RUN: llvm-dwarfdump --debug-names bad-abbrev-code | FileCheck %s --check-prefix=BAD-ABBREV-CODE-DWARF + +# BAD-ABBREV-CODE-COUNT-2: error: bad-abbrev-code.o:(.debug_names): invalid abbrev code in entry + +# BAD-ABBREV-CODE-DWARF: Abbreviations [ +# BAD-ABBREV-CODE-DWARF-NEXT: Abbreviation 0x1 { +# BAD-ABBREV-CODE-DWARF-NEXT: Tag: DW_TAG_subprogram +# BAD-ABBREV-CODE-DWARF-NEXT: DW_IDX_die_offset: DW_FORM_ref4 +# BAD-ABBREV-CODE-DWARF-NEXT: DW_IDX_parent: DW_FORM_flag_present +# BAD-ABBREV-CODE-DWARF-NEXT: DW_IDX_compile_unit: DW_FORM_data1 +# BAD-ABBREV-CODE-DWARF-NEXT: } +# BAD-ABBREV-CODE-DWARF-NEXT: Abbreviation 0x2 { +# BAD-ABBREV-CODE-DWARF-NEXT: Tag: DW_TAG_structure_type +# BAD-ABBREV-CODE-DWARF-NEXT: DW_IDX_die_offset: DW_FORM_ref4 +# BAD-ABBREV-CODE-DWARF-NEXT: DW_IDX_parent: DW_FORM_flag_present +# BAD-ABBREV-CODE-DWARF-NEXT: DW_IDX_compile_unit: DW_FORM_data1 +# BAD-ABBREV-CODE-DWARF-NEXT: } +# BAD-ABBREV-CODE-DWARF-NEXT: ] +# BAD-ABBREV-CODE-DWARF: Bucket 0 +# BAD-ABBREV-CODE-DWARF-NOT: Entry + +# RUN: sed -E '/Lnames0:/{n;n;n;s/.*DW_IDX_die_offset.*//}' %S/Inputs/debug-names-a.s > missing-die-offset0.s +# RUN: llvm-mc -filetype=obj -triple=x86_64 missing-die-offset0.s -o missing-die-offset0.o +# RUN: ld.lld --debug-names missing-die-offset0.o --noinhibit-exec -o missing-die-offset0 2>&1 | FileCheck %s --check-prefix=MISSING-DIE-OFFSET0 + +# MISSING-DIE-OFFSET0: warning: missing-die-offset0.o:(.debug_names): index entry is out of bounds + +# RUN: sed -E '/Lnames1:/{n;n;n;s/.*DW_IDX_die_offset.*//}' %S/Inputs/debug-names-a.s > missing-die-offset1.s +# RUN: llvm-mc -filetype=obj -triple=x86_64 missing-die-offset1.s -o missing-die-offset1.o +# RUN: ld.lld --debug-names missing-die-offset1.o -o missing-die-offset1 +# RUN: llvm-dwarfdump --debug-names missing-die-offset1 | FileCheck %s --check-prefix=MISSING-DIE-OFFSET1 + +# MISSING-DIE-OFFSET1: Bucket 0 [ +# MISSING-DIE-OFFSET1-NEXT: Name 1 { +# MISSING-DIE-OFFSET1-NEXT: Hash: 0x59796A +# MISSING-DIE-OFFSET1-NEXT: String: {{.*}} "t1" +# MISSING-DIE-OFFSET1-NEXT: Entry @ 0x65 { +# MISSING-DIE-OFFSET1-NEXT: Abbrev: 0x2 +# MISSING-DIE-OFFSET1-NEXT: Tag: DW_TAG_structure_type +# MISSING-DIE-OFFSET1-NEXT: DW_IDX_die_offset: 0x00230200 +# MISSING-DIE-OFFSET1-NEXT: DW_IDX_parent: +# MISSING-DIE-OFFSET1-NEXT: DW_IDX_compile_unit: 0x00 +# MISSING-DIE-OFFSET1-NEXT: } +# MISSING-DIE-OFFSET1-NEXT: } +# MISSING-DIE-OFFSET1-NEXT: Name 2 { +# MISSING-DIE-OFFSET1-NEXT: Hash: 0xEDDB6232 +# MISSING-DIE-OFFSET1-NEXT: String: {{.*}} "_start" +# MISSING-DIE-OFFSET1-NEXT: Entry @ 0x6c { +# MISSING-DIE-OFFSET1-NEXT: Abbrev: 0x1 +# MISSING-DIE-OFFSET1-NEXT: Tag: DW_TAG_subprogram +# MISSING-DIE-OFFSET1-NEXT: DW_IDX_die_offset: 0x00000023 +# MISSING-DIE-OFFSET1-NEXT: DW_IDX_parent: +# MISSING-DIE-OFFSET1-NEXT: DW_IDX_compile_unit: 0x00 +# MISSING-DIE-OFFSET1-NEXT: } +# MISSING-DIE-OFFSET1-NEXT: } +# MISSING-DIE-OFFSET1-NEXT: ] diff --git a/lld/test/ELF/debug-names-invalid-attribute-3.s b/lld/test/ELF/debug-names-die-offset-form-flag-present.s similarity index 100% rename from lld/test/ELF/debug-names-invalid-attribute-3.s rename to lld/test/ELF/debug-names-die-offset-form-flag-present.s diff --git a/lld/test/ELF/debug-names-different-aug-string.s b/lld/test/ELF/debug-names-different-aug-string.s new file mode 100644 index 0000000000000..eb0c3fadf8a30 --- /dev/null +++ b/lld/test/ELF/debug-names-different-aug-string.s @@ -0,0 +1,14 @@ +# REQUIRES: x86 +# RUN: rm -rf %t && mkdir %t && cd %t +# RUN: sed 's/LLVM0700/LLVM9999/' %S/Inputs/debug-names-a.s | llvm-mc -filetype=obj -triple=x86_64 -o a.o +# RUN: llvm-mc -filetype=obj -triple=x86_64 %S/Inputs/debug-names-b.s -o b.o +# RUN: ld.lld --debug-names a.o b.o -o out +# RUN: llvm-dwarfdump -debug-names out | FileCheck %s --check-prefix=DWARF + +# DWARF: .debug_names contents: +# DWARF: Name Index @ 0x0 { +# DWARF-NEXT: Header { +# DWARF-NEXT: Length: +# DWARF-NEXT: Format: DWARF32 +# DWARF-NEXT: Version: 5 +# DWARF: Augmentation: '' diff --git a/lld/test/ELF/debug-names-dwarf64.s b/lld/test/ELF/debug-names-dwarf64.s index d5ba3b69255a2..0bbceff8cb0ce 100644 --- a/lld/test/ELF/debug-names-dwarf64.s +++ b/lld/test/ELF/debug-names-dwarf64.s @@ -1,23 +1,26 @@ -# This file was generated by: -# clang++ -g -O0 -S -fdebug-compilation-dir='/proc/self/cwd' \ -# -gdwarf64 -gpubnames a.cpp - -# Contents of a.cpp -# int main (int argc, char **argv) { } - # REQUIRES: x86 -# RUN: llvm-mc -filetype=obj -triple=x86_64 %s -o %t1.o -# RUN: not ld.lld --debug-names %t1.o -o /dev/null 2>&1 \ -# RUN: | FileCheck -DFILE=%t1.o --implicit-check-not=error: %s +# RUN: llvm-mc -filetype=obj -triple=x86_64 %s -o %t.o +# RUN: not ld.lld --debug-names %t.o -o /dev/null 2>&1 | \ +# RUN: FileCheck -DFILE=%t.o --implicit-check-not=error: %s # CHECK: error: [[FILE]]:(.debug_names): found DWARF64, which is currently unsupported +.ifdef GEN +//--- a.cc +struct t1 {}; +extern "C" void _start(t1) {} +//--- gen +clang -S -g -gpubnames -gdwarf64 a.cc -o - +.endif .text - .globl main # -- Begin function main + .file "a.cc" + .globl _start # -- Begin function _start .p2align 4, 0x90 - .type main,@function -main: # @main + .type _start,@function +_start: # @_start .Lfunc_begin0: + .file 0 "/proc/self/cwd" "a.cc" md5 0x6835f89a7d36054002b51e54e47d852e + .loc 0 2 0 # a.cc:2:0 .cfi_startproc # %bb.0: # %entry pushq %rbp @@ -25,19 +28,85 @@ main: # @main .cfi_offset %rbp, -16 movq %rsp, %rbp .cfi_def_cfa_register %rbp - movl %edi, -4(%rbp) - movq %rsi, -16(%rbp) .Ltmp0: - xorl %eax, %eax + .loc 0 2 29 prologue_end epilogue_begin # a.cc:2:29 popq %rbp .cfi_def_cfa %rsp, 8 retq .Ltmp1: .Lfunc_end0: - .size main, .Lfunc_end0-main + .size _start, .Lfunc_end0-_start .cfi_endproc # -- End function .section .debug_abbrev,"",@progbits + .byte 1 # Abbreviation Code + .byte 17 # DW_TAG_compile_unit + .byte 1 # DW_CHILDREN_yes + .byte 37 # DW_AT_producer + .byte 37 # DW_FORM_strx1 + .byte 19 # DW_AT_language + .byte 5 # DW_FORM_data2 + .byte 3 # DW_AT_name + .byte 37 # DW_FORM_strx1 + .byte 114 # DW_AT_str_offsets_base + .byte 23 # DW_FORM_sec_offset + .byte 16 # DW_AT_stmt_list + .byte 23 # DW_FORM_sec_offset + .byte 27 # DW_AT_comp_dir + .byte 37 # DW_FORM_strx1 + .byte 17 # DW_AT_low_pc + .byte 27 # DW_FORM_addrx + .byte 18 # DW_AT_high_pc + .byte 6 # DW_FORM_data4 + .byte 115 # DW_AT_addr_base + .byte 23 # DW_FORM_sec_offset + .byte 0 # EOM(1) + .byte 0 # EOM(2) + .byte 2 # Abbreviation Code + .byte 46 # DW_TAG_subprogram + .byte 1 # DW_CHILDREN_yes + .byte 17 # DW_AT_low_pc + .byte 27 # DW_FORM_addrx + .byte 18 # DW_AT_high_pc + .byte 6 # DW_FORM_data4 + .byte 64 # DW_AT_frame_base + .byte 24 # DW_FORM_exprloc + .byte 3 # DW_AT_name + .byte 37 # DW_FORM_strx1 + .byte 58 # DW_AT_decl_file + .byte 11 # DW_FORM_data1 + .byte 59 # DW_AT_decl_line + .byte 11 # DW_FORM_data1 + .byte 63 # DW_AT_external + .byte 25 # DW_FORM_flag_present + .byte 0 # EOM(1) + .byte 0 # EOM(2) + .byte 3 # Abbreviation Code + .byte 5 # DW_TAG_formal_parameter + .byte 0 # DW_CHILDREN_no + .byte 2 # DW_AT_location + .byte 24 # DW_FORM_exprloc + .byte 58 # DW_AT_decl_file + .byte 11 # DW_FORM_data1 + .byte 59 # DW_AT_decl_line + .byte 11 # DW_FORM_data1 + .byte 73 # DW_AT_type + .byte 19 # DW_FORM_ref4 + .byte 0 # EOM(1) + .byte 0 # EOM(2) + .byte 4 # Abbreviation Code + .byte 19 # DW_TAG_structure_type + .byte 0 # DW_CHILDREN_no + .byte 54 # DW_AT_calling_convention + .byte 11 # DW_FORM_data1 + .byte 3 # DW_AT_name + .byte 37 # DW_FORM_strx1 + .byte 11 # DW_AT_byte_size + .byte 11 # DW_FORM_data1 + .byte 58 # DW_AT_decl_file + .byte 11 # DW_FORM_data1 + .byte 59 # DW_AT_decl_line + .byte 11 # DW_FORM_data1 .byte 0 # EOM(1) .byte 0 # EOM(2) .byte 0 # EOM(3) @@ -50,30 +119,71 @@ main: # @main .byte 1 # DWARF Unit Type .byte 8 # Address Size (in bytes) .quad .debug_abbrev # Offset Into Abbrev. Section + .byte 1 # Abbrev [1] 0x18:0x40 DW_TAG_compile_unit + .byte 0 # DW_AT_producer + .short 33 # DW_AT_language + .byte 1 # DW_AT_name + .quad .Lstr_offsets_base0 # DW_AT_str_offsets_base + .quad .Lline_table_start0 # DW_AT_stmt_list + .byte 2 # DW_AT_comp_dir + .byte 0 # DW_AT_low_pc + .long .Lfunc_end0-.Lfunc_begin0 # DW_AT_high_pc + .quad .Laddr_table_base0 # DW_AT_addr_base + .byte 2 # Abbrev [2] 0x3b:0x16 DW_TAG_subprogram + .byte 0 # DW_AT_low_pc + .long .Lfunc_end0-.Lfunc_begin0 # DW_AT_high_pc + .byte 1 # DW_AT_frame_base + .byte 86 + .byte 3 # DW_AT_name + .byte 0 # DW_AT_decl_file + .byte 2 # DW_AT_decl_line + # DW_AT_external + .byte 3 # Abbrev [3] 0x46:0xa DW_TAG_formal_parameter + .byte 2 # DW_AT_location + .byte 145 + .byte 127 + .byte 0 # DW_AT_decl_file + .byte 2 # DW_AT_decl_line + .long 81 # DW_AT_type + .byte 0 # End Of Children Mark + .byte 4 # Abbrev [4] 0x51:0x6 DW_TAG_structure_type + .byte 5 # DW_AT_calling_convention + .byte 4 # DW_AT_name + .byte 1 # DW_AT_byte_size + .byte 0 # DW_AT_decl_file + .byte 1 # DW_AT_decl_line + .byte 0 # End Of Children Mark .Ldebug_info_end0: .section .debug_str_offsets,"",@progbits .long 4294967295 # DWARF64 Mark - .quad 68 # Length of String Offsets Set + .quad 44 # Length of String Offsets Set .short 5 .short 0 .Lstr_offsets_base0: .section .debug_str,"MS",@progbits,1 .Linfo_string0: - .asciz "clang version 19.0.0git (git@github.com:llvm/llvm-project.git 53b14cd9ce2b57da73d173fc876d2e9e199f5640)" # string offset=0 + .byte 0 # string offset=0 .Linfo_string1: - .asciz "a.cpp" # string offset=104 + .asciz "a.cc" # string offset=1 .Linfo_string2: - .asciz "/proc/self/cwd" # string offset=110 + .asciz "/proc/self/cwd" # string offset=6 .Linfo_string3: - .asciz "main" # string offset=125 + .asciz "_start" # string offset=21 .Linfo_string4: - .asciz "int" # string offset=130 -.Linfo_string5: - .asciz "argc" # string offset=134 -.Linfo_string6: - .asciz "argv" # string offset=139 -.Linfo_string7: - .asciz "char" # string offset=144 + .asciz "t1" # string offset=28 + .section .debug_str_offsets,"",@progbits + .quad .Linfo_string0 + .quad .Linfo_string1 + .quad .Linfo_string2 + .quad .Linfo_string3 + .quad .Linfo_string4 + .section .debug_addr,"",@progbits + .long 4294967295 # DWARF64 Mark + .quad .Ldebug_addr_end0-.Ldebug_addr_start0 # Length of contribution +.Ldebug_addr_start0: + .short 5 # DWARF version number + .byte 8 # Address size + .byte 0 # Segment selector size .Laddr_table_base0: .quad .Lfunc_begin0 .Ldebug_addr_end0: @@ -86,27 +196,23 @@ main: # @main .long 1 # Header: compilation unit count .long 0 # Header: local type unit count .long 0 # Header: foreign type unit count - .long 3 # Header: bucket count - .long 3 # Header: name count + .long 2 # Header: bucket count + .long 2 # Header: name count .long .Lnames_abbrev_end0-.Lnames_abbrev_start0 # Header: abbreviation table size .long 8 # Header: augmentation string size .ascii "LLVM0700" # Header: augmentation string .quad .Lcu_begin0 # Compilation unit 0 - .long 0 # Bucket 0 - .long 1 # Bucket 1 - .long 2 # Bucket 2 - .long 2090499946 # Hash in Bucket 1 - .long 193495088 # Hash in Bucket 2 - .long 2090147939 # Hash in Bucket 2 - .quad .Linfo_string3 # String in Bucket 1: main - .quad .Linfo_string4 # String in Bucket 2: int - .quad .Linfo_string7 # String in Bucket 2: char - .quad .Lnames0-.Lnames_entries0 # Offset in Bucket 1 - .quad .Lnames1-.Lnames_entries0 # Offset in Bucket 2 - .quad .Lnames2-.Lnames_entries0 # Offset in Bucket 2 + .long 1 # Bucket 0 + .long 0 # Bucket 1 + .long 5863786 # Hash in Bucket 0 + .long -304389582 # Hash in Bucket 0 + .quad .Linfo_string4 # String in Bucket 0: t1 + .quad .Linfo_string3 # String in Bucket 0: _start + .quad .Lnames1-.Lnames_entries0 # Offset in Bucket 0 + .quad .Lnames0-.Lnames_entries0 # Offset in Bucket 0 .Lnames_abbrev_start0: .byte 1 # Abbrev code - .byte 46 # DW_TAG_subprogram + .byte 19 # DW_TAG_structure_type .byte 3 # DW_IDX_die_offset .byte 19 # DW_FORM_ref4 .byte 4 # DW_IDX_parent @@ -114,7 +220,7 @@ main: # @main .byte 0 # End of abbrev .byte 0 # End of abbrev .byte 2 # Abbrev code - .byte 36 # DW_TAG_base_type + .byte 46 # DW_TAG_subprogram .byte 3 # DW_IDX_die_offset .byte 19 # DW_FORM_ref4 .byte 4 # DW_IDX_parent @@ -124,27 +230,20 @@ main: # @main .byte 0 # End of abbrev list .Lnames_abbrev_end0: .Lnames_entries0: -.Lnames0: -.L2: - .byte 1 # Abbreviation code - .long 59 # DW_IDX_die_offset - .byte 0 # DW_IDX_parent - # End of list: main .Lnames1: .L1: - .byte 2 # Abbreviation code - .long 97 # DW_IDX_die_offset + .byte 1 # Abbreviation code + .long 81 # DW_IDX_die_offset .byte 0 # DW_IDX_parent - # End of list: int -.Lnames2: + # End of list: t1 +.Lnames0: .L0: .byte 2 # Abbreviation code - .long 111 # DW_IDX_die_offset + .long 59 # DW_IDX_die_offset .byte 0 # DW_IDX_parent - # End of list: char + # End of list: _start .p2align 2, 0x0 .Lnames_end0: - .ident "clang version 19.0.0git (git@github.com:llvm/llvm-project.git 53b14cd9ce2b57da73d173fc876d2e9e199f5640)" .section ".note.GNU-stack","",@progbits .addrsig .section .debug_line,"",@progbits diff --git a/lld/test/ELF/debug-names-invalid-abbrev-code.s b/lld/test/ELF/debug-names-invalid-abbrev-code.s deleted file mode 100644 index 5290eb86e276d..0000000000000 --- a/lld/test/ELF/debug-names-invalid-abbrev-code.s +++ /dev/null @@ -1,149 +0,0 @@ -# This file was generated by: -# clang++ -g -O0 -S -fdebug-compilation-dir='/proc/self/cwd' -gpubnames a.cpp - -# Then manually changing an abbrev code. - -# Contents of a.cpp -# int main (int argc, char **argv) { } - -# REQUIRES: x86 -# RUN: llvm-mc -filetype=obj -triple=x86_64 %s -o %t1.o -# RUN: not ld.lld --debug-names %t1.o -o /dev/null 2>&1 \ -# RUN: | FileCheck -DFILE=%t1.o --implicit-check-not=error: %s - -# CHECK: error: [[FILE]]:(.debug_names): invalid abbrev code in entry - - .text - .globl main # -- Begin function main - .p2align 4, 0x90 - .type main,@function -main: # @main -.Lfunc_begin0: - .cfi_startproc -# %bb.0: # %entry - pushq %rbp - .cfi_def_cfa_offset 16 - .cfi_offset %rbp, -16 - movq %rsp, %rbp - .cfi_def_cfa_register %rbp - movl %edi, -4(%rbp) - movq %rsi, -16(%rbp) -.Ltmp0: - xorl %eax, %eax - popq %rbp - .cfi_def_cfa %rsp, 8 - retq -.Ltmp1: -.Lfunc_end0: - .size main, .Lfunc_end0-main - .cfi_endproc - # -- End function - .section .debug_abbrev,"",@progbits - .byte 0 # EOM(1) - .byte 0 # EOM(2) - .byte 0 # EOM(3) - .section .debug_info,"",@progbits -.Lcu_begin0: - .long .Ldebug_info_end0-.Ldebug_info_start0 # Length of Unit -.Ldebug_info_start0: - .short 5 # DWARF version number - .byte 1 # DWARF Unit Type - .byte 8 # Address Size (in bytes) - .long .debug_abbrev # Offset Into Abbrev. Section -.Ldebug_info_end0: - .section .debug_str_offsets,"",@progbits - .long 36 # Length of String Offsets Set - .short 5 - .short 0 -.Lstr_offsets_base0: - .section .debug_str,"MS",@progbits,1 -.Linfo_string0: - .asciz "clang version 19.0.0git (git@github.com:llvm/llvm-project.git 53b14cd9ce2b57da73d173fc876d2e9e199f5640)" # string offset=0 -.Linfo_string1: - .asciz "a.cpp" # string offset=104 -.Linfo_string2: - .asciz "/proc/self/cwd" # string offset=110 -.Linfo_string3: - .asciz "main" # string offset=125 -.Linfo_string4: - .asciz "int" # string offset=130 -.Linfo_string5: - .asciz "argc" # string offset=134 -.Linfo_string6: - .asciz "argv" # string offset=139 -.Linfo_string7: - .asciz "char" # string offset=144 -.Laddr_table_base0: - .quad .Lfunc_begin0 -.Ldebug_addr_end0: - .section .debug_names,"",@progbits - .long .Lnames_end0-.Lnames_start0 # Header: unit length -.Lnames_start0: - .short 5 # Header: version - .short 0 # Header: padding - .long 1 # Header: compilation unit count - .long 0 # Header: local type unit count - .long 0 # Header: foreign type unit count - .long 3 # Header: bucket count - .long 3 # Header: name count - .long .Lnames_abbrev_end0-.Lnames_abbrev_start0 # Header: abbreviation table size - .long 8 # Header: augmentation string size - .ascii "LLVM0700" # Header: augmentation string - .long .Lcu_begin0 # Compilation unit 0 - .long 0 # Bucket 0 - .long 1 # Bucket 1 - .long 2 # Bucket 2 - .long 2090499946 # Hash in Bucket 1 - .long 193495088 # Hash in Bucket 2 - .long 2090147939 # Hash in Bucket 2 - .long .Linfo_string3 # String in Bucket 1: main - .long .Linfo_string4 # String in Bucket 2: int - .long .Linfo_string7 # String in Bucket 2: char - .long .Lnames0-.Lnames_entries0 # Offset in Bucket 1 - .long .Lnames1-.Lnames_entries0 # Offset in Bucket 2 - .long .Lnames2-.Lnames_entries0 # Offset in Bucket 2 -.Lnames_abbrev_start0: - .byte 1 # Abbrev code - .byte 46 # DW_TAG_subprogram - .byte 3 # DW_IDX_die_offset - .byte 19 # DW_FORM_ref4 - .byte 4 # DW_IDX_parent - .byte 25 # DW_FORM_flag_present - .byte 0 # End of abbrev - .byte 0 # End of abbrev - .byte 2 # Abbrev code - .byte 36 # DW_TAG_base_type - .byte 3 # DW_IDX_die_offset - .byte 19 # DW_FORM_ref4 - .byte 4 # DW_IDX_parent - .byte 25 # DW_FORM_flag_present - .byte 0 # End of abbrev - .byte 0 # End of abbrev - .byte 0 # End of abbrev list -.Lnames_abbrev_end0: -.Lnames_entries0: -.Lnames0: -.L1: - .byte 1 # Abbreviation code - .long 35 # DW_IDX_die_offset - .byte 0 # DW_IDX_parent - # End of list: main -.Lnames1: -.L0: - .byte 3 # Abbreviation code - .long 73 # DW_IDX_die_offset - .byte 0 # DW_IDX_parent - # End of list: int -.Lnames2: -.L2: - .byte 2 # Abbreviation code - .long 87 # DW_IDX_die_offset - .byte 0 # DW_IDX_parent - # End of list: char - .p2align 2, 0x0 -.Lnames_end0: - .ident "clang version 19.0.0git (git@github.com:llvm/llvm-project.git 53b14cd9ce2b57da73d173fc876d2e9e199f5640)" - .section ".note.GNU-stack","",@progbits - .addrsig - .section .debug_line,"",@progbits -.Lline_table_start0: diff --git a/lld/test/ELF/debug-names-invalid-attribute-2.s b/lld/test/ELF/debug-names-invalid-attribute-2.s deleted file mode 100644 index 6ea8c5e1e3f69..0000000000000 --- a/lld/test/ELF/debug-names-invalid-attribute-2.s +++ /dev/null @@ -1,149 +0,0 @@ -# This file was generated by: -# clang++ -g -O0 -S -fdebug-compilation-dir='/proc/self/cwd' -gpubnames a.cpp - -# Then manually editing .debug_names section, commenting out a -# DW_IDX_die_offset in an entry. - -# Contents of a.cpp -# int main (int argc, char **argv) { } - -# REQUIRES: x86 -# RUN: llvm-mc -filetype=obj -triple=x86_64 %s -o %t1.o -# RUN: not ld.lld --debug-names %t1.o -o /dev/null 2>&1 \ -# RUN: | FileCheck -DFILE=%t1.o --implicit-check-not=error: %s - -# CHECK: error: [[FILE]]:(.debug_names): error while reading attributes: unexpected end of data at offset 0x80 while reading [0x7e, 0x82) - - .text - .globl main # -- Begin function main - .p2align 4, 0x90 - .type main,@function -main: # @main -.Lfunc_begin0: - .cfi_startproc -# %bb.0: # %entry - pushq %rbp - .cfi_def_cfa_offset 16 - .cfi_offset %rbp, -16 - movq %rsp, %rbp - .cfi_def_cfa_register %rbp - movl %edi, -4(%rbp) - movq %rsi, -16(%rbp) -.Ltmp0: - xorl %eax, %eax - popq %rbp - .cfi_def_cfa %rsp, 8 - retq -.Ltmp1: -.Lfunc_end0: - .size main, .Lfunc_end0-main - .cfi_endproc - # -- End function - .section .debug_abbrev,"",@progbits - .byte 0 # EOM(1) - .byte 0 # EOM(2) - .byte 0 # EOM(3) - .section .debug_info,"",@progbits -.Lcu_begin0: - .long .Ldebug_info_end0-.Ldebug_info_start0 # Length of Unit -.Ldebug_info_start0: - .short 5 # DWARF version number - .byte 1 # DWARF Unit Type - .byte 8 # Address Size (in bytes) - .long .debug_abbrev # Offset Into Abbrev. Section -.Ldebug_info_end0: - .section .debug_str_offsets,"",@progbits - .long 36 # Length of String Offsets Set - .short 5 - .short 0 -.Lstr_offsets_base0: - .section .debug_str,"MS",@progbits,1 -.Linfo_string0: - .asciz "clang version 19.0.0git (git@github.com:llvm/llvm-project.git 53b14cd9ce2b57da73d173fc876d2e9e199f5640)" # string offset=0 -.Linfo_string1: - .asciz "a.cpp" # string offset=104 -.Linfo_string2: - .asciz "/proc/self/cwd" # string offset=110 -.Linfo_string3: - .asciz "main" # string offset=125 -.Linfo_string4: - .asciz "int" # string offset=130 -.Linfo_string5: - .asciz "argc" # string offset=134 -.Linfo_string6: - .asciz "argv" # string offset=139 -.Linfo_string7: - .asciz "char" # string offset=144 -.Laddr_table_base0: - .quad .Lfunc_begin0 -.Ldebug_addr_end0: - .section .debug_names,"",@progbits - .long .Lnames_end0-.Lnames_start0 # Header: unit length -.Lnames_start0: - .short 5 # Header: version - .short 0 # Header: padding - .long 1 # Header: compilation unit count - .long 0 # Header: local type unit count - .long 0 # Header: foreign type unit count - .long 3 # Header: bucket count - .long 3 # Header: name count - .long .Lnames_abbrev_end0-.Lnames_abbrev_start0 # Header: abbreviation table size - .long 8 # Header: augmentation string size - .ascii "LLVM0700" # Header: augmentation string - .long .Lcu_begin0 # Compilation unit 0 - .long 0 # Bucket 0 - .long 1 # Bucket 1 - .long 2 # Bucket 2 - .long 2090499946 # Hash in Bucket 1 - .long 193495088 # Hash in Bucket 2 - .long 2090147939 # Hash in Bucket 2 - .long .Linfo_string3 # String in Bucket 1: main - .long .Linfo_string4 # String in Bucket 2: int - .long .Linfo_string7 # String in Bucket 2: char - .long .Lnames0-.Lnames_entries0 # Offset in Bucket 1 - .long .Lnames1-.Lnames_entries0 # Offset in Bucket 2 - .long .Lnames2-.Lnames_entries0 # Offset in Bucket 2 -.Lnames_abbrev_start0: - .byte 1 # Abbrev code - .byte 46 # DW_TAG_subprogram - .byte 3 # DW_IDX_die_offset - .byte 19 # DW_FORM_ref4 - .byte 4 # DW_IDX_parent - .byte 25 # DW_FORM_flag_present - .byte 0 # End of abbrev - .byte 0 # End of abbrev - .byte 2 # Abbrev code - .byte 36 # DW_TAG_base_type - .byte 3 # DW_IDX_die_offset - .byte 19 # DW_FORM_ref4 - .byte 4 # DW_IDX_parent - .byte 25 # DW_FORM_flag_present - .byte 0 # End of abbrev - .byte 0 # End of abbrev - .byte 0 # End of abbrev list -.Lnames_abbrev_end0: -.Lnames_entries0: -.Lnames0: -.L1: - .byte 1 # Abbreviation code - .long 35 # DW_IDX_die_offset - .byte 0 # DW_IDX_parent - # End of list: main -.Lnames1: -.L0: - .byte 2 # Abbreviation code - .long 73 # DW_IDX_die_offset - .byte 0 # DW_IDX_parent - # End of list: int -.Lnames2: -.L2: - .byte 2 # Abbreviation code -# .long 87 # DW_IDX_die_offset - # End of list: char - .p2align 2, 0x0 -.Lnames_end0: - .ident "clang version 19.0.0git (git@github.com:llvm/llvm-project.git 53b14cd9ce2b57da73d173fc876d2e9e199f5640)" - .section ".note.GNU-stack","",@progbits - .addrsig - .section .debug_line,"",@progbits -.Lline_table_start0: diff --git a/lld/test/ELF/debug-names-invalid-attribute.s b/lld/test/ELF/debug-names-invalid-attribute.s deleted file mode 100644 index 52b9c6f7ade95..0000000000000 --- a/lld/test/ELF/debug-names-invalid-attribute.s +++ /dev/null @@ -1,144 +0,0 @@ -# Generated by copying a.s from debug-names.s and manually editing it to make some -# of the abbrev attributes invalid. - -# REQUIRES: x86 -# RUN: llvm-mc -filetype=obj -triple=x86_64 %s -o %t1.o -# RUN: not ld.lld --debug-names %t1.o -o /dev/null 2>&1 \ -# RUN: | FileCheck -DFILE=%t1.o --implicit-check-not=error: %s - -# CHECK: error: [[FILE]]:(.debug_names): unrecognized form encoding 16 in abbrev table - - .text - .globl _Z2f12t1 # -- Begin function _Z2f12t1 - .p2align 4, 0x90 - .type _Z2f12t1,@function -_Z2f12t1: # @_Z2f12t1 -.Lfunc_begin0: - .cfi_startproc -# %bb.0: # %entry - pushq %rbp - .cfi_def_cfa_offset 16 - .cfi_offset %rbp, -16 - movq %rsp, %rbp - .cfi_def_cfa_register %rbp -.Ltmp0: - popq %rbp - .cfi_def_cfa %rsp, 8 - retq -.Ltmp1: -.Lfunc_end0: - .size _Z2f12t1, .Lfunc_end0-_Z2f12t1 - .cfi_endproc - # -- End function - .section .debug_abbrev,"",@progbits - .byte 0 # EOM(1) - .byte 0 # EOM(2) - .byte 0 # EOM(3) - .section .debug_info,"",@progbits -.Lcu_begin0: - .long .Ldebug_info_end0-.Ldebug_info_start0 # Length of Unit -.Ldebug_info_start0: - .short 5 # DWARF version number - .byte 1 # DWARF Unit Type - .byte 8 # Address Size (in bytes) - .long .debug_abbrev # Offset Into Abbrev. Section -.Ldebug_info_end0: - .section .debug_str_offsets,"",@progbits - .long 28 # Length of String Offsets Set - .short 5 - .short 0 -.Lstr_offsets_base0: - .section .debug_str,"MS",@progbits,1 -.Linfo_string0: - .asciz "clang version 19.0.0git (git@github.com:llvm/llvm-project.git 53b14cd9ce2b57da73d173fc876d2e9e199f5640)" # string offset=0 -.Linfo_string1: - .asciz "a.cpp" # string offset=104 -.Linfo_string2: - .asciz "/proc/self/cwd" # string offset=110 -.Linfo_string3: - .asciz "f1" # string offset=125 -.Linfo_string4: - .asciz "_Z2f12t1" # string offset=128 -.Linfo_string5: - .asciz "t1" # string offset=137 -.Laddr_table_base0: - .quad .Lfunc_begin0 -.Ldebug_addr_end0: - .section .debug_names,"",@progbits - .long .Lnames_end0-.Lnames_start0 # Header: unit length -.Lnames_start0: - .short 5 # Header: version - .short 0 # Header: padding - .long 1 # Header: compilation unit count - .long 0 # Header: local type unit count - .long 0 # Header: foreign type unit count - .long 3 # Header: bucket count - .long 3 # Header: name count - .long .Lnames_abbrev_end0-.Lnames_abbrev_start0 # Header: abbreviation table size - .long 8 # Header: augmentation string size - .ascii "LLVM0700" # Header: augmentation string - .long .Lcu_begin0 # Compilation unit 0 - .long 0 # Bucket 0 - .long 1 # Bucket 1 - .long 3 # Bucket 2 - .long 5863324 # Hash in Bucket 1 - .long 5863786 # Hash in Bucket 1 - .long 1398125246 # Hash in Bucket 2 - .long .Linfo_string3 # String in Bucket 1: f1 - .long .Linfo_string5 # String in Bucket 1: t1 - .long .Linfo_string4 # String in Bucket 2: _Z2f12t1 - .long .Lnames0-.Lnames_entries0 # Offset in Bucket 1 - .long .Lnames2-.Lnames_entries0 # Offset in Bucket 1 - .long .Lnames1-.Lnames_entries0 # Offset in Bucket 2 -.Lnames_abbrev_start0: - .byte 1 # Abbrev code - .byte 46 # DW_TAG_subprogram - .byte 3 # DW_IDX_die_offset - .byte 19 # DW_FORM_ref4 - .byte 4 # DW_IDX_parent - .byte 25 # DW_FORM_flag_present - .byte 0 # End of abbrev - .byte 0 # End of abbrev - .byte 2 # Abbrev code - .byte 19 # DW_TAG_structure_type - .byte 3 # DW_IDX_die_offset - .byte 19 # DW_FORM_ref4 - .byte 4 # DW_IDX_parent - .byte 25 # DW_FORM_flag_present - .byte 0 # End of abbrev - .byte 0 # End of abbrev - .byte 3 # Abbrev code - .byte 19 # DW_TAG_structure_type - .byte 3 # DW_IDX_die_offset - .byte 16 # DW_FORM_ref_addr - .byte 7 # DW_IDX_unknown - .byte 25 # DW_FORM_flag_present - .byte 0 # End of abbrev - .byte 0 # End of abbrev - .byte 0 # End of abbrev list -.Lnames_abbrev_end0: -.Lnames_entries0: -.Lnames0: -.L1: - .byte 1 # Abbreviation code - .long 35 # DW_IDX_die_offset - .byte 0 # DW_IDX_parent - # End of list: f1 -.Lnames2: -.L0: - .byte 2 # Abbreviation code - .long 58 # DW_IDX_die_offset - .byte 0 # DW_IDX_parent - # End of list: t1 -.Lnames1: - .byte 3 # Abbreviation code - .long 35 # DW_IDX_die_offset - .byte 0 # DW_IDX_parent - # End of list: _Z2f12t1 - .p2align 2, 0x0 -.Lnames_end0: - .ident "clang version 19.0.0git (git@github.com:llvm/llvm-project.git 53b14cd9ce2b57da73d173fc876d2e9e199f5640)" - .section ".note.GNU-stack","",@progbits - .addrsig - .section .debug_line,"",@progbits -.Lline_table_start0: diff --git a/lld/test/ELF/debug-names-multi-cus-2.s b/lld/test/ELF/debug-names-multi-cus-2.s deleted file mode 100644 index 1d8bcdc56d43f..0000000000000 --- a/lld/test/ELF/debug-names-multi-cus-2.s +++ /dev/null @@ -1,460 +0,0 @@ -# abc.s was generated by: - -# clang++ a.cpp -gpubnames a.cpp -g -emit-llvm -c \ -# -fdebug-compilation-dir='/proc/self/cwd -# clang++ b.cpp -gpubnames b.cpp -g -emit-llvm -c \ -# -fdebug-compilation-dir='/proc/self/cwd -1# clang++ c.cpp -gpubnames c.cpp -g -emit-llvm -c \ -# -fdebug-compilation-dir='/proc/self/cwd' -# llvm-link a.bc b.bc c.bc -o abc.bc -# clang++ abc.bc -S -o abc.s - -# a.cpp contains: -# struct t1 { }; -# void f1(t1) { } - -# b.cpp contains: -# struct t1 { }; -# int main() { -# t1 v1; -# } - -# c.cpp contains: -# -# void null() { } - - -# REQUIRES: x86 -# RUN: rm -rf %t && split-file %s %t && cd %t -# RUN: llvm-mc -filetype=obj -triple=x86_64 abc.s -o abc.o -# RUN: llvm-mc -filetype=obj -triple=x86_64 d.s -o d.o -# RUN: ld.lld --debug-names abc.o d.o -o out -# RUN: llvm-dwarfdump --debug-names out \ -# RUN: | FileCheck -DFILE=a.o %s --check-prefix=DWARF - -# DWARF: Compilation Unit offsets [ -# DWARF-NEXT: CU[0]: 0x00000000 -# DWARF-NEXT: CU[1]: 0x0000000c -# DWARF-NEXT: CU[2]: 0x00000018 -# DWARF-NEXT: CU[3]: 0x00000024 -# DWARF-NEXT: ] - -# RUN: ld.lld --debug-names d.o abc.o -o out2 -# RUN: llvm-dwarfdump --debug-names out2 \ -# RUN: | FileCheck -DFILE=a.o %s --check-prefix=DWARF2 - -# DWARF2: Compilation Unit offsets [ -# DWARF2-NEXT: CU[0]: 0x00000000 -# DWARF2-NEXT: CU[1]: 0x0000000c -# DWARF2-NEXT: CU[2]: 0x00000018 -# DWARF2-NEXT: CU[3]: 0x00000024 -# DWARF2-NEXT: ] - -#--- abc.s - - .text - .globl _Z2f12t1 # -- Begin function _Z2f12t1 - .p2align 4, 0x90 - .type _Z2f12t1,@function -_Z2f12t1: # @_Z2f12t1 -.Lfunc_begin0: - .cfi_startproc -# %bb.0: # %entry - pushq %rbp - .cfi_def_cfa_offset 16 - .cfi_offset %rbp, -16 - movq %rsp, %rbp - .cfi_def_cfa_register %rbp -.Ltmp0: - popq %rbp - .cfi_def_cfa %rsp, 8 - retq -.Ltmp1: -.Lfunc_end0: - .size _Z2f12t1, .Lfunc_end0-_Z2f12t1 - .cfi_endproc - # -- End function - .globl main # -- Begin function main - .p2align 4, 0x90 - .type main,@function -main: # @main -.Lfunc_begin1: - .cfi_startproc -# %bb.0: # %entry - pushq %rbp - .cfi_def_cfa_offset 16 - .cfi_offset %rbp, -16 - movq %rsp, %rbp - .cfi_def_cfa_register %rbp -.Ltmp2: - xorl %eax, %eax - popq %rbp - .cfi_def_cfa %rsp, 8 - retq -.Ltmp3: -.Lfunc_end1: - .size main, .Lfunc_end1-main - .cfi_endproc - # -- End function - .globl _Z4nullv # -- Begin function _Z4nullv - .p2align 4, 0x90 - .type _Z4nullv,@function -_Z4nullv: # @_Z4nullv -.Lfunc_begin2: - .cfi_startproc -# %bb.0: # %entry - pushq %rbp - .cfi_def_cfa_offset 16 - .cfi_offset %rbp, -16 - movq %rsp, %rbp - .cfi_def_cfa_register %rbp -.Ltmp4: - popq %rbp - .cfi_def_cfa %rsp, 8 - retq -.Ltmp5: -.Lfunc_end2: - .size _Z4nullv, .Lfunc_end2-_Z4nullv - .cfi_endproc - # -- End function - .section .debug_abbrev,"",@progbits - .byte 0 # EOM(1) - .byte 0 # EOM(2) - .byte 0 # EOM(3) - .section .debug_info,"",@progbits -.Lcu_begin0: - .long .Ldebug_info_end0-.Ldebug_info_start0 # Length of Unit -.Ldebug_info_start0: - .short 5 # DWARF version number - .byte 1 # DWARF Unit Type - .byte 8 # Address Size (in bytes) - .long .debug_abbrev # Offset Into Abbrev. Section -.Ldebug_info_end0: -.Lcu_begin1: - .long .Ldebug_info_end1-.Ldebug_info_start1 # Length of Unit -.Ldebug_info_start1: - .short 5 # DWARF version number - .byte 1 # DWARF Unit Type - .byte 8 # Address Size (in bytes) - .long .debug_abbrev # Offset Into Abbrev. Section -.Ldebug_info_end1: -.Lcu_begin2: - .long .Ldebug_info_end2-.Ldebug_info_start2 # Length of Unit -.Ldebug_info_start2: - .short 5 # DWARF version number - .byte 1 # DWARF Unit Type - .byte 8 # Address Size (in bytes) - .long .debug_abbrev # Offset Into Abbrev. Section -.Ldebug_info_end2: - .section .debug_str_offsets,"",@progbits - .long 56 # Length of String Offsets Set - .short 5 - .short 0 -.Lstr_offsets_base0: - .section .debug_str,"MS",@progbits,1 -.Linfo_string0: - .asciz "clang version 19.0.0git (git@github.com:llvm/llvm-project.git 58e50c2a7b0a8a63e038dbfc4cb12d81aef1a32d)" # string offset=0 -.Linfo_string1: - .asciz "a.cpp" # string offset=104 -.Linfo_string2: - .asciz "/proc/self/cwd" # string offset=110 -.Linfo_string3: - .asciz "f1" # string offset=125 -.Linfo_string4: - .asciz "_Z2f12t1" # string offset=128 -.Linfo_string5: - .asciz "b.cpp" # string offset=137 -.Linfo_string6: - .asciz "main" # string offset=143 -.Linfo_string7: - .asciz "c.cpp" # string offset=148 -.Linfo_string8: - .asciz "null" # string offset=154 -.Linfo_string9: - .asciz "_Z4nullv" # string offset=159 -.Linfo_string10: - .asciz "int" # string offset=168 -.Linfo_string11: - .asciz "t1" # string offset=172 -.Linfo_string12: - .asciz "v1" # string offset=175 - .section .debug_str_offsets,"",@progbits -.Laddr_table_base0: - .quad .Lfunc_begin0 - .quad .Lfunc_begin1 - .quad .Lfunc_begin2 -.Ldebug_addr_end0: - .section .debug_names,"",@progbits - .long .Lnames_end0-.Lnames_start0 # Header: unit length -.Lnames_start0: - .short 5 # Header: version - .short 0 # Header: padding - .long 3 # Header: compilation unit count - .long 0 # Header: local type unit count - .long 0 # Header: foreign type unit count - .long 7 # Header: bucket count - .long 7 # Header: name count - .long .Lnames_abbrev_end0-.Lnames_abbrev_start0 # Header: abbreviation table size - .long 8 # Header: augmentation string size - .ascii "LLVM0700" # Header: augmentation string - .long .Lcu_begin0 # Compilation unit 0 - .long .Lcu_begin1 # Compilation unit 1 - .long .Lcu_begin2 # Compilation unit 2 - .long 1 # Bucket 0 - .long 0 # Bucket 1 - .long 0 # Bucket 2 - .long 2 # Bucket 3 - .long 4 # Bucket 4 - .long 5 # Bucket 5 - .long 0 # Bucket 6 - .long 1398125246 # Hash in Bucket 0 - .long 193495088 # Hash in Bucket 3 - .long 2090499946 # Hash in Bucket 3 - .long 2090557760 # Hash in Bucket 4 - .long 5863324 # Hash in Bucket 5 - .long 5863786 # Hash in Bucket 5 - .long 1488390083 # Hash in Bucket 5 - .long .Linfo_string4 # String in Bucket 0: _Z2f12t1 - .long .Linfo_string10 # String in Bucket 3: int - .long .Linfo_string6 # String in Bucket 3: main - .long .Linfo_string8 # String in Bucket 4: null - .long .Linfo_string3 # String in Bucket 5: f1 - .long .Linfo_string11 # String in Bucket 5: t1 - .long .Linfo_string9 # String in Bucket 5: _Z4nullv - .long .Lnames1-.Lnames_entries0 # Offset in Bucket 0 - .long .Lnames5-.Lnames_entries0 # Offset in Bucket 3 - .long .Lnames2-.Lnames_entries0 # Offset in Bucket 3 - .long .Lnames3-.Lnames_entries0 # Offset in Bucket 4 - .long .Lnames0-.Lnames_entries0 # Offset in Bucket 5 - .long .Lnames6-.Lnames_entries0 # Offset in Bucket 5 - .long .Lnames4-.Lnames_entries0 # Offset in Bucket 5 -.Lnames_abbrev_start0: - .byte 1 # Abbrev code - .byte 46 # DW_TAG_subprogram - .byte 1 # DW_IDX_compile_unit - .byte 11 # DW_FORM_data1 - .byte 3 # DW_IDX_die_offset - .byte 19 # DW_FORM_ref4 - .byte 4 # DW_IDX_parent - .byte 25 # DW_FORM_flag_present - .byte 0 # End of abbrev - .byte 0 # End of abbrev - .byte 2 # Abbrev code - .byte 36 # DW_TAG_base_type - .byte 1 # DW_IDX_compile_unit - .byte 11 # DW_FORM_data1 - .byte 3 # DW_IDX_die_offset - .byte 19 # DW_FORM_ref4 - .byte 4 # DW_IDX_parent - .byte 25 # DW_FORM_flag_present - .byte 0 # End of abbrev - .byte 0 # End of abbrev - .byte 3 # Abbrev code - .byte 19 # DW_TAG_structure_type - .byte 1 # DW_IDX_compile_unit - .byte 11 # DW_FORM_data1 - .byte 3 # DW_IDX_die_offset - .byte 19 # DW_FORM_ref4 - .byte 4 # DW_IDX_parent - .byte 25 # DW_FORM_flag_present - .byte 0 # End of abbrev - .byte 0 # End of abbrev - .byte 0 # End of abbrev list -.Lnames_abbrev_end0: -.Lnames_entries0: -.Lnames1: -.L3: - .byte 1 # Abbreviation code - .byte 0 # DW_IDX_compile_unit - .long 35 # DW_IDX_die_offset - .byte 0 # DW_IDX_parent - # End of list: _Z2f12t1 -.Lnames5: -.L1: - .byte 2 # Abbreviation code - .byte 1 # DW_IDX_compile_unit - .long 62 # DW_IDX_die_offset - .byte 0 # DW_IDX_parent - # End of list: int -.Lnames2: -.L2: - .byte 1 # Abbreviation code - .byte 1 # DW_IDX_compile_unit - .long 35 # DW_IDX_die_offset - .byte 0 # DW_IDX_parent - # End of list: main -.Lnames3: -.L4: - .byte 1 # Abbreviation code - .byte 2 # DW_IDX_compile_unit - .long 35 # DW_IDX_die_offset - .byte 0 # DW_IDX_parent - # End of list: null -.Lnames0: - .byte 1 # Abbreviation code - .byte 0 # DW_IDX_compile_unit - .long 35 # DW_IDX_die_offset - .byte 0 # DW_IDX_parent - # End of list: f1 -.Lnames6: -.L0: - .byte 3 # Abbreviation code - .byte 0 # DW_IDX_compile_unit - .long 58 # DW_IDX_die_offset - .byte 0 # DW_IDX_parent - # End of list: t1 -.Lnames4: - .byte 1 # Abbreviation code - .byte 2 # DW_IDX_compile_unit - .long 35 # DW_IDX_die_offset - .byte 0 # DW_IDX_parent - # End of list: _Z4nullv - .p2align 2, 0x0 -.Lnames_end0: - .ident "clang version 19.0.0git (git@github.com:llvm/llvm-project.git 58e50c2a7b0a8a63e038dbfc4cb12d81aef1a32d)" - .ident "clang version 19.0.0git (git@github.com:llvm/llvm-project.git 58e50c2a7b0a8a63e038dbfc4cb12d81aef1a32d)" - .ident "clang version 19.0.0git (git@github.com:llvm/llvm-project.git 58e50c2a7b0a8a63e038dbfc4cb12d81aef1a32d)" - .section ".note.GNU-stack","",@progbits - .addrsig - .section .debug_line,"",@progbits -.Lline_table_start0: - -#--- d.s -# Generated with: -# - clang++ -g -gpubnames -fdebug-compilation-dir='/proc/self/cwd' \ -# -S d.cpp -o d.s - -# d.cpp contents: - -# int foo(int x) { return 4; } - - .text - .globl _Z3fooi # -- Begin function _Z3fooi - .p2align 4, 0x90 - .type _Z3fooi,@function -_Z3fooi: # @_Z3fooi -.Lfunc_begin0: - .cfi_startproc -# %bb.0: # %entry - pushq %rbp - .cfi_def_cfa_offset 16 - .cfi_offset %rbp, -16 - movq %rsp, %rbp - .cfi_def_cfa_register %rbp - movl %edi, -4(%rbp) -.Ltmp0: - movl $4, %eax - popq %rbp - .cfi_def_cfa %rsp, 8 - retq -.Ltmp1: -.Lfunc_end0: - .size _Z3fooi, .Lfunc_end0-_Z3fooi - .cfi_endproc - # -- End function - .section .debug_abbrev,"",@progbits - .byte 0 # EOM(1) - .byte 0 # EOM(2) - .byte 0 # EOM(3) - .section .debug_info,"",@progbits -.Lcu_begin0: - .long .Ldebug_info_end0-.Ldebug_info_start0 # Length of Unit -.Ldebug_info_start0: - .short 5 # DWARF version number - .byte 1 # DWARF Unit Type - .byte 8 # Address Size (in bytes) - .long .debug_abbrev # Offset Into Abbrev. Section -.Ldebug_info_end0: - .section .debug_str_offsets,"",@progbits - .long 32 # Length of String Offsets Set - .short 5 - .short 0 -.Lstr_offsets_base0: - .section .debug_str,"MS",@progbits,1 -.Linfo_string0: - .asciz "clang version 19.0.0git (git@github.com:llvm/llvm-project.git 58e50c2a7b0a8a63e038dbfc4cb12d81aef1a32d)" # string offset=0 -.Linfo_string1: - .asciz "d.cpp" # string offset=104 -.Linfo_string2: - .asciz "/proc/self/cwd" # string offset=110 -.Linfo_string3: - .asciz "foo" # string offset=125 -.Linfo_string4: - .asciz "_Z3fooi" # string offset=129 -.Linfo_string5: - .asciz "int" # string offset=137 -.Linfo_string6: - .asciz "x" # string offset=141 -.Laddr_table_base0: - .quad .Lfunc_begin0 -.Ldebug_addr_end0: - .section .debug_names,"",@progbits - .long .Lnames_end0-.Lnames_start0 # Header: unit length -.Lnames_start0: - .short 5 # Header: version - .short 0 # Header: padding - .long 1 # Header: compilation unit count - .long 0 # Header: local type unit count - .long 0 # Header: foreign type unit count - .long 3 # Header: bucket count - .long 3 # Header: name count - .long .Lnames_abbrev_end0-.Lnames_abbrev_start0 # Header: abbreviation table size - .long 8 # Header: augmentation string size - .ascii "LLVM0700" # Header: augmentation string - .long .Lcu_begin0 # Compilation unit 0 - .long 1 # Bucket 0 - .long 0 # Bucket 1 - .long 3 # Bucket 2 - .long 193491849 # Hash in Bucket 0 - .long -1257882370 # Hash in Bucket 0 - .long 193495088 # Hash in Bucket 2 - .long .Linfo_string3 # String in Bucket 0: foo - .long .Linfo_string4 # String in Bucket 0: _Z3fooi - .long .Linfo_string5 # String in Bucket 2: int - .long .Lnames0-.Lnames_entries0 # Offset in Bucket 0 - .long .Lnames1-.Lnames_entries0 # Offset in Bucket 0 - .long .Lnames2-.Lnames_entries0 # Offset in Bucket 2 -.Lnames_abbrev_start0: - .byte 1 # Abbrev code - .byte 46 # DW_TAG_subprogram - .byte 3 # DW_IDX_die_offset - .byte 19 # DW_FORM_ref4 - .byte 4 # DW_IDX_parent - .byte 25 # DW_FORM_flag_present - .byte 0 # End of abbrev - .byte 0 # End of abbrev - .byte 2 # Abbrev code - .byte 36 # DW_TAG_base_type - .byte 3 # DW_IDX_die_offset - .byte 19 # DW_FORM_ref4 - .byte 4 # DW_IDX_parent - .byte 25 # DW_FORM_flag_present - .byte 0 # End of abbrev - .byte 0 # End of abbrev - .byte 0 # End of abbrev list -.Lnames_abbrev_end0: -.Lnames_entries0: -.Lnames0: -.L1: - .byte 1 # Abbreviation code - .long 35 # DW_IDX_die_offset - .byte 0 # DW_IDX_parent - # End of list: foo -.Lnames1: - .byte 1 # Abbreviation code - .long 35 # DW_IDX_die_offset - .byte 0 # DW_IDX_parent - # End of list: _Z3fooi -.Lnames2: -.L0: - .byte 2 # Abbreviation code - .long 63 # DW_IDX_die_offset - .byte 0 # DW_IDX_parent - # End of list: int - .p2align 2, 0x0 -.Lnames_end0: - .ident "clang version 19.0.0git (git@github.com:llvm/llvm-project.git 58e50c2a7b0a8a63e038dbfc4cb12d81aef1a32d)" - .section ".note.GNU-stack","",@progbits - .addrsig - .section .debug_line,"",@progbits -.Lline_table_start0: diff --git a/lld/test/ELF/debug-names-multi-cus-append.s b/lld/test/ELF/debug-names-multi-cus-append.s deleted file mode 100644 index de8bd0f939f42..0000000000000 --- a/lld/test/ELF/debug-names-multi-cus-append.s +++ /dev/null @@ -1,459 +0,0 @@ -# This .s files were generated by: - -# clang++ b.cpp -gpubnames b.cpp -g -emit-llvm -c \ -# -fdebug-compilation-dir='/proc/self/cwd -# clang++ c.cpp -gpubnames c.cpp -g -emit-llvm -c \ -# -fdebug-compilation-dir='/proc/self/cwd -# llvm-link b.bc c.bc -o bc.bc -# clang++ bc.bc -S -o bc.s -# clang++ -g -O0 -gpubnames a.cpp -S -o a.s \ -# -fdebug-compilation-dir='/proc/self/cwd -# clang++ -g -O0 -gpubnames d.cpp -S -o d.s \ -# -fdebug-compilation-dir='/proc/self/cwd - -# a.cpp contains: -# struct t1 { }; -# void f1(t1) { } - -# b.cpp contains: -# struct t1 { }; -# int main() { -# t1 v1; -# } - -# c.cpp contains: -# void null() { } - -# d.cpp contains: -# int foo(int x) { return 4; } - -# REQUIRES: x86 -# RUN: rm -rf %t && split-file %s %t && cd %t -# RUN: llvm-mc -filetype=obj -triple=x86_64 a.s -o a.o -# RUN: llvm-mc -filetype=obj -triple=x86_64 bc.s -o bc.o -# RUN: llvm-mc -filetype=obj -triple=x86_64 d.s -o d.o -# RUN: ld.lld -r a.o bc.o -o abc.o -# RUN: ld.lld --debug-names d.o abc.o -o out -# RUN: llvm-dwarfdump --debug-names out \ -# RUN: | FileCheck -DFILE=a.o %s --check-prefix=DWARF - -# DWARF: Compilation Unit offsets [ -# DWARF-NEXT: CU[0]: 0x00000000 -# DWARF-NEXT: CU[1]: 0x00000001 -# DWARF-NEXT: CU[2]: 0x00000002 -# DWARF-NEXT: CU[3]: 0x00000003 -# DWARF-NEXT: ] - -#--- a.s - - .text - .globl _Z2f12t1 # -- Begin function _Z2f12t1 - .p2align 4, 0x90 - .type _Z2f12t1,@function -_Z2f12t1: # @_Z2f12t1 -.Lfunc_begin0: - .cfi_startproc -# %bb.0: # %entry - pushq %rbp - .cfi_def_cfa_offset 16 - .cfi_offset %rbp, -16 - movq %rsp, %rbp - .cfi_def_cfa_register %rbp -.Ltmp0: - popq %rbp - .cfi_def_cfa %rsp, 8 - retq -.Ltmp1: -.Lfunc_end0: - .size _Z2f12t1, .Lfunc_end0-_Z2f12t1 - .cfi_endproc - # -- End function - .section .debug_info,"",@progbits -.Lcu_begin0: - .byte 0 - .section .debug_str,"MS",@progbits,1 -.Linfo_string0: - .asciz "clang version 19.0.0git (git@github.com:llvm/llvm-project.git dfe787af70e11666a8e43ca73a86d1841d364dfc)" # string offset=0 -.Linfo_string1: - .asciz "a.cpp" # string offset=104 -.Linfo_string2: - .asciz "/proc/self/cwd" # string offset=110 -.Linfo_string3: - .asciz "f1" # string offset=125 -.Linfo_string4: - .asciz "_Z2f12t1" # string offset=128 -.Linfo_string5: - .asciz "t1" # string offset=137 - .section .debug_names,"",@progbits - .long .Lnames_end0-.Lnames_start0 # Header: unit length -.Lnames_start0: - .short 5 # Header: version - .short 0 # Header: padding - .long 1 # Header: compilation unit count - .long 0 # Header: local type unit count - .long 0 # Header: foreign type unit count - .long 3 # Header: bucket count - .long 3 # Header: name count - .long .Lnames_abbrev_end0-.Lnames_abbrev_start0 # Header: abbreviation table size - .long 8 # Header: augmentation string size - .ascii "LLVM0700" # Header: augmentation string - .long .Lcu_begin0 # Compilation unit 0 - .long 0 # Bucket 0 - .long 1 # Bucket 1 - .long 3 # Bucket 2 - .long 5863324 # Hash in Bucket 1 - .long 5863786 # Hash in Bucket 1 - .long 1398125246 # Hash in Bucket 2 - .long .Linfo_string3 # String in Bucket 1: f1 - .long .Linfo_string5 # String in Bucket 1: t1 - .long .Linfo_string4 # String in Bucket 2: _Z2f12t1 - .long .Lnames0-.Lnames_entries0 # Offset in Bucket 1 - .long .Lnames2-.Lnames_entries0 # Offset in Bucket 1 - .long .Lnames1-.Lnames_entries0 # Offset in Bucket 2 -.Lnames_abbrev_start0: - .byte 1 # Abbrev code - .byte 46 # DW_TAG_subprogram - .byte 3 # DW_IDX_die_offset - .byte 19 # DW_FORM_ref4 - .byte 4 # DW_IDX_parent - .byte 25 # DW_FORM_flag_present - .byte 0 # End of abbrev - .byte 0 # End of abbrev - .byte 2 # Abbrev code - .byte 19 # DW_TAG_structure_type - .byte 3 # DW_IDX_die_offset - .byte 19 # DW_FORM_ref4 - .byte 4 # DW_IDX_parent - .byte 25 # DW_FORM_flag_present - .byte 0 # End of abbrev - .byte 0 # End of abbrev - .byte 0 # End of abbrev list -.Lnames_abbrev_end0: -.Lnames_entries0: -.Lnames0: -.L1: - .byte 1 # Abbreviation code - .long 35 # DW_IDX_die_offset - .byte 0 # DW_IDX_parent - # End of list: f1 -.Lnames2: -.L0: - .byte 2 # Abbreviation code - .long 58 # DW_IDX_die_offset - .byte 0 # DW_IDX_parent - # End of list: t1 -.Lnames1: - .byte 1 # Abbreviation code - .long 35 # DW_IDX_die_offset - .byte 0 # DW_IDX_parent - # End of list: _Z2f12t1 - .p2align 2, 0x0 -.Lnames_end0: - .ident "clang version 19.0.0git (git@github.com:llvm/llvm-project.git dfe787af70e11666a8e43ca73a86d1841d364dfc)" - .section ".note.GNU-stack","",@progbits - .addrsig - .section .debug_line,"",@progbits -.Lline_table_start0: - -#--- bc.s - - .text - .globl main # -- Begin function main - .p2align 4, 0x90 - .type main,@function -main: # @main -.Lfunc_begin0: - .cfi_startproc -# %bb.0: # %entry - pushq %rbp - .cfi_def_cfa_offset 16 - .cfi_offset %rbp, -16 - movq %rsp, %rbp - .cfi_def_cfa_register %rbp -.Ltmp0: - xorl %eax, %eax - popq %rbp - .cfi_def_cfa %rsp, 8 - retq -.Ltmp1: -.Lfunc_end0: - .size main, .Lfunc_end0-main - .cfi_endproc - # -- End function - .globl _Z4nullv # -- Begin function _Z4nullv - .p2align 4, 0x90 - .type _Z4nullv,@function -_Z4nullv: # @_Z4nullv -.Lfunc_begin1: - .cfi_startproc -# %bb.0: # %entry - pushq %rbp - .cfi_def_cfa_offset 16 - .cfi_offset %rbp, -16 - movq %rsp, %rbp - .cfi_def_cfa_register %rbp -.Ltmp2: - popq %rbp - .cfi_def_cfa %rsp, 8 - retq -.Ltmp3: -.Lfunc_end1: - .size _Z4nullv, .Lfunc_end1-_Z4nullv - .cfi_endproc - # -- End function - .section .debug_info,"",@progbits -.Lcu_begin0: - .byte 0 -.Lcu_begin1: - .byte 0 - .section .debug_str,"MS",@progbits,1 -.Linfo_string0: - .asciz "clang version 19.0.0git (git@github.com:llvm/llvm-project.git dfe787af70e11666a8e43ca73a86d1841d364dfc)" # string offset=0 -.Linfo_string1: - .asciz "b.cpp" # string offset=104 -.Linfo_string2: - .asciz "/proc/self/cwd" # string offset=110 -.Linfo_string3: - .asciz "main" # string offset=125 -.Linfo_string4: - .asciz "c.cpp" # string offset=130 -.Linfo_string5: - .asciz "null" # string offset=136 -.Linfo_string6: - .asciz "_Z4nullv" # string offset=141 -.Linfo_string7: - .asciz "int" # string offset=150 -.Linfo_string8: - .asciz "v1" # string offset=154 -.Linfo_string9: - .asciz "t1" # string offset=157 -.Laddr_table_base0: - .quad .Lfunc_begin0 - .quad .Lfunc_begin1 -.Ldebug_addr_end0: - .section .debug_names,"",@progbits - .long .Lnames_end0-.Lnames_start0 # Header: unit length -.Lnames_start0: - .short 5 # Header: version - .short 0 # Header: padding - .long 2 # Header: compilation unit count - .long 0 # Header: local type unit count - .long 0 # Header: foreign type unit count - .long 5 # Header: bucket count - .long 5 # Header: name count - .long .Lnames_abbrev_end0-.Lnames_abbrev_start0 # Header: abbreviation table size - .long 8 # Header: augmentation string size - .ascii "LLVM0700" # Header: augmentation string - .long .Lcu_begin0 # Compilation unit 0 - .long .Lcu_begin1 # Compilation unit 1 - .long 1 # Bucket 0 - .long 2 # Bucket 1 - .long 0 # Bucket 2 - .long 4 # Bucket 3 - .long 0 # Bucket 4 - .long 2090557760 # Hash in Bucket 0 - .long 5863786 # Hash in Bucket 1 - .long 2090499946 # Hash in Bucket 1 - .long 193495088 # Hash in Bucket 3 - .long 1488390083 # Hash in Bucket 3 - .long .Linfo_string5 # String in Bucket 0: null - .long .Linfo_string9 # String in Bucket 1: t1 - .long .Linfo_string3 # String in Bucket 1: main - .long .Linfo_string7 # String in Bucket 3: int - .long .Linfo_string6 # String in Bucket 3: _Z4nullv - .long .Lnames1-.Lnames_entries0 # Offset in Bucket 0 - .long .Lnames4-.Lnames_entries0 # Offset in Bucket 1 - .long .Lnames0-.Lnames_entries0 # Offset in Bucket 1 - .long .Lnames3-.Lnames_entries0 # Offset in Bucket 3 - .long .Lnames2-.Lnames_entries0 # Offset in Bucket 3 -.Lnames_abbrev_start0: - .byte 1 # Abbrev code - .byte 46 # DW_TAG_subprogram - .byte 1 # DW_IDX_compile_unit - .byte 11 # DW_FORM_data1 - .byte 3 # DW_IDX_die_offset - .byte 19 # DW_FORM_ref4 - .byte 4 # DW_IDX_parent - .byte 25 # DW_FORM_flag_present - .byte 0 # End of abbrev - .byte 0 # End of abbrev - .byte 2 # Abbrev code - .byte 19 # DW_TAG_structure_type - .byte 1 # DW_IDX_compile_unit - .byte 11 # DW_FORM_data1 - .byte 3 # DW_IDX_die_offset - .byte 19 # DW_FORM_ref4 - .byte 4 # DW_IDX_parent - .byte 25 # DW_FORM_flag_present - .byte 0 # End of abbrev - .byte 0 # End of abbrev - .byte 3 # Abbrev code - .byte 36 # DW_TAG_base_type - .byte 1 # DW_IDX_compile_unit - .byte 11 # DW_FORM_data1 - .byte 3 # DW_IDX_die_offset - .byte 19 # DW_FORM_ref4 - .byte 4 # DW_IDX_parent - .byte 25 # DW_FORM_flag_present - .byte 0 # End of abbrev - .byte 0 # End of abbrev - .byte 0 # End of abbrev list -.Lnames_abbrev_end0: -.Lnames_entries0: -.Lnames1: -.L2: - .byte 1 # Abbreviation code - .byte 1 # DW_IDX_compile_unit - .long 35 # DW_IDX_die_offset - .byte 0 # DW_IDX_parent - # End of list: null -.Lnames4: -.L1: - .byte 2 # Abbreviation code - .byte 0 # DW_IDX_compile_unit - .long 66 # DW_IDX_die_offset - .byte 0 # DW_IDX_parent - # End of list: t1 -.Lnames0: -.L3: - .byte 1 # Abbreviation code - .byte 0 # DW_IDX_compile_unit - .long 35 # DW_IDX_die_offset - .byte 0 # DW_IDX_parent - # End of list: main -.Lnames3: -.L0: - .byte 3 # Abbreviation code - .byte 0 # DW_IDX_compile_unit - .long 62 # DW_IDX_die_offset - .byte 0 # DW_IDX_parent - # End of list: int -.Lnames2: - .byte 1 # Abbreviation code - .byte 1 # DW_IDX_compile_unit - .long 35 # DW_IDX_die_offset - .byte 0 # DW_IDX_parent - # End of list: _Z4nullv - .p2align 2, 0x0 -.Lnames_end0: - .ident "clang version 19.0.0git (git@github.com:llvm/llvm-project.git dfe787af70e11666a8e43ca73a86d1841d364dfc)" - .ident "clang version 19.0.0git (git@github.com:llvm/llvm-project.git dfe787af70e11666a8e43ca73a86d1841d364dfc)" - .section ".note.GNU-stack","",@progbits - .addrsig - .section .debug_line,"",@progbits -.Lline_table_start0: - -#--- d.s - - .text - .globl _Z3fooi # -- Begin function _Z3fooi - .p2align 4, 0x90 - .type _Z3fooi,@function -_Z3fooi: # @_Z3fooi -.Lfunc_begin0: - .cfi_startproc -# %bb.0: # %entry - pushq %rbp - .cfi_def_cfa_offset 16 - .cfi_offset %rbp, -16 - movq %rsp, %rbp - .cfi_def_cfa_register %rbp - movl %edi, -4(%rbp) -.Ltmp0: - movl $4, %eax - popq %rbp - .cfi_def_cfa %rsp, 8 - retq -.Ltmp1: -.Lfunc_end0: - .size _Z3fooi, .Lfunc_end0-_Z3fooi - .cfi_endproc - # -- End function - .section .debug_info,"",@progbits -.Lcu_begin0: - .byte 0 - .section .debug_str,"MS",@progbits,1 -.Linfo_string0: - .asciz "clang version 19.0.0git (git@github.com:llvm/llvm-project.git 58e50c2a7b0a8a63e038dbfc4cb12d81aef1a32d)" # string offset=0 -.Linfo_string1: - .asciz "d.cpp" # string offset=104 -.Linfo_string2: - .asciz "/proc/self/cwd" # string offset=110 -.Linfo_string3: - .asciz "foo" # string offset=125 -.Linfo_string4: - .asciz "_Z3fooi" # string offset=129 -.Linfo_string5: - .asciz "int" # string offset=137 -.Linfo_string6: - .asciz "x" # string offset=141 - .section .debug_names,"",@progbits - .long .Lnames_end0-.Lnames_start0 # Header: unit length -.Lnames_start0: - .short 5 # Header: version - .short 0 # Header: padding - .long 1 # Header: compilation unit count - .long 0 # Header: local type unit count - .long 0 # Header: foreign type unit count - .long 3 # Header: bucket count - .long 3 # Header: name count - .long .Lnames_abbrev_end0-.Lnames_abbrev_start0 # Header: abbreviation table size - .long 8 # Header: augmentation string size - .ascii "LLVM0700" # Header: augmentation string - .long .Lcu_begin0 # Compilation unit 0 - .long 1 # Bucket 0 - .long 0 # Bucket 1 - .long 3 # Bucket 2 - .long 193491849 # Hash in Bucket 0 - .long -1257882370 # Hash in Bucket 0 - .long 193495088 # Hash in Bucket 2 - .long .Linfo_string3 # String in Bucket 0: foo - .long .Linfo_string4 # String in Bucket 0: _Z3fooi - .long .Linfo_string5 # String in Bucket 2: int - .long .Lnames0-.Lnames_entries0 # Offset in Bucket 0 - .long .Lnames1-.Lnames_entries0 # Offset in Bucket 0 - .long .Lnames2-.Lnames_entries0 # Offset in Bucket 2 -.Lnames_abbrev_start0: - .byte 1 # Abbrev code - .byte 46 # DW_TAG_subprogram - .byte 3 # DW_IDX_die_offset - .byte 19 # DW_FORM_ref4 - .byte 4 # DW_IDX_parent - .byte 25 # DW_FORM_flag_present - .byte 0 # End of abbrev - .byte 0 # End of abbrev - .byte 2 # Abbrev code - .byte 36 # DW_TAG_base_type - .byte 3 # DW_IDX_die_offset - .byte 19 # DW_FORM_ref4 - .byte 4 # DW_IDX_parent - .byte 25 # DW_FORM_flag_present - .byte 0 # End of abbrev - .byte 0 # End of abbrev - .byte 0 # End of abbrev list -.Lnames_abbrev_end0: -.Lnames_entries0: -.Lnames0: -.L1: - .byte 1 # Abbreviation code - .long 35 # DW_IDX_die_offset - .byte 0 # DW_IDX_parent - # End of list: foo -.Lnames1: - .byte 1 # Abbreviation code - .long 35 # DW_IDX_die_offset - .byte 0 # DW_IDX_parent - # End of list: _Z3fooi -.Lnames2: -.L0: - .byte 2 # Abbreviation code - .long 63 # DW_IDX_die_offset - .byte 0 # DW_IDX_parent - # End of list: int - .p2align 2, 0x0 -.Lnames_end0: - .ident "clang version 19.0.0git (git@github.com:llvm/llvm-project.git 58e50c2a7b0a8a63e038dbfc4cb12d81aef1a32d)" - .section ".note.GNU-stack","",@progbits - .addrsig - .section .debug_line,"",@progbits -.Lline_table_start0: diff --git a/lld/test/ELF/debug-names-multi-cus-long.s b/lld/test/ELF/debug-names-multi-cus-long.s deleted file mode 100644 index 563e1ee2c17a6..0000000000000 --- a/lld/test/ELF/debug-names-multi-cus-long.s +++ /dev/null @@ -1,563 +0,0 @@ -# The .s files were generated by: - -# clang++ a.cpp -gpubnames a.cpp -g -emit-llvm -c \ -# -fdebug-compilation-dir='/proc/self/cwd -# clang++ b.cpp -gpubnames b.cpp -g -emit-llvm -c \ -# -fdebug-compilation-dir='/proc/self/cwd -1# clang++ c.cpp -gpubnames c.cpp -g -emit-llvm -c \ -# -fdebug-compilation-dir='/proc/self/cwd' -# llvm-link a.bc b.bc c.bc -o abc.bc -# clang++ abc.bc -S -o abc.s - -# clang++ d.cpp -gpubnames d.cpp -g -emit-llvm -c \ -# -fdebug-compilation-dir='/proc/self/cwd -# clang++ e.cpp -gpubnames e.cpp -g -emit-llvm -c \ -# -fdebug-compilation-dir='/proc/self/cwd -# llvm-link d.bc e.bc -o de.bc -# clang++ de.bc -S -o de.s - -# clang++ -g -gpubnames -fdebug-compilation-dir='/proc/self/cwd' \ -# -S f.cpp -o f.s - -# a.cpp contains: -# struct t1 { }; -# void f1(t1) { } - -# b.cpp contains: -# struct t1 { }; -# int main() { -# t1 v1; -# } - -# c.cpp contains: -# void null() { } - -# d.cpp contents: -# int foo(int x) { return 4; } - -# e.cpp contains: -# void bar(void *) {} - -# f.cpp contains -# void baz() { } - -# REQUIRES: x86 -# RUN: rm -rf %t && split-file %s %t && cd %t -# RUN: llvm-mc -filetype=obj -triple=x86_64 abc.s -o abc.o -# RUN: llvm-mc -filetype=obj -triple=x86_64 de.s -o de.o -# RUN: llvm-mc -filetype=obj -triple=x86_64 f.s -o f.o -# RUN: ld.lld --debug-names abc.o de.o f.o -o out -# RUN: llvm-dwarfdump --debug-names out \ -# RUN: | FileCheck %s --check-prefix=DWARF - -# DWARF: Compilation Unit offsets [ -# DWARF-NEXT: CU[0]: 0x00000000 -# DWARF-NEXT: CU[1]: 0x00000001 -# DWARF-NEXT: CU[2]: 0x00000002 -# DWARF-NEXT: CU[3]: 0x00000003 -# DWARF-NEXT: CU[4]: 0x00000004 -# DWARF-NEXT: CU[5]: 0x00000005 -# DWARF-NEXT: ] - -#--- abc.s - - .text - .globl _Z2f12t1 # -- Begin function _Z2f12t1 - .p2align 4, 0x90 - .type _Z2f12t1,@function -_Z2f12t1: # @_Z2f12t1 -.Lfunc_begin0: - .cfi_startproc -# %bb.0: # %entry - pushq %rbp - .cfi_def_cfa_offset 16 - .cfi_offset %rbp, -16 - movq %rsp, %rbp - .cfi_def_cfa_register %rbp -.Ltmp0: - popq %rbp - .cfi_def_cfa %rsp, 8 - retq -.Ltmp1: -.Lfunc_end0: - .size _Z2f12t1, .Lfunc_end0-_Z2f12t1 - .cfi_endproc - # -- End function - .globl main # -- Begin function main - .p2align 4, 0x90 - .type main,@function -main: # @main -.Lfunc_begin1: - .cfi_startproc -# %bb.0: # %entry - pushq %rbp - .cfi_def_cfa_offset 16 - .cfi_offset %rbp, -16 - movq %rsp, %rbp - .cfi_def_cfa_register %rbp -.Ltmp2: - xorl %eax, %eax - popq %rbp - .cfi_def_cfa %rsp, 8 - retq -.Ltmp3: -.Lfunc_end1: - .size main, .Lfunc_end1-main - .cfi_endproc - # -- End function - .globl _Z4nullv # -- Begin function _Z4nullv - .p2align 4, 0x90 - .type _Z4nullv,@function -_Z4nullv: # @_Z4nullv -.Lfunc_begin2: - .cfi_startproc -# %bb.0: # %entry - pushq %rbp - .cfi_def_cfa_offset 16 - .cfi_offset %rbp, -16 - movq %rsp, %rbp - .cfi_def_cfa_register %rbp -.Ltmp4: - popq %rbp - .cfi_def_cfa %rsp, 8 - retq -.Ltmp5: -.Lfunc_end2: - .size _Z4nullv, .Lfunc_end2-_Z4nullv - .cfi_endproc - # -- End function - .section .debug_info,"",@progbits -.Lcu_begin0: - .byte 0 -.Lcu_begin1: - .byte 0 -.Lcu_begin2: - .byte 0 - .section .debug_str,"MS",@progbits,1 -.Linfo_string0: - .asciz "clang version 19.0.0git (git@github.com:llvm/llvm-project.git dfe787af70e11666a8e43ca73a86d1841d364dfc)" # string offset=0 -.Linfo_string1: - .asciz "a.cpp" # string offset=104 -.Linfo_string2: - .asciz "/proc/self/cwd" # string offset=110 -.Linfo_string3: - .asciz "f1" # string offset=125 -.Linfo_string4: - .asciz "_Z2f12t1" # string offset=128 -.Linfo_string5: - .asciz "b.cpp" # string offset=137 -.Linfo_string6: - .asciz "main" # string offset=143 -.Linfo_string7: - .asciz "c.cpp" # string offset=148 -.Linfo_string8: - .asciz "null" # string offset=154 -.Linfo_string9: - .asciz "_Z4nullv" # string offset=159 -.Linfo_string10: - .asciz "int" # string offset=168 -.Linfo_string11: - .asciz "t1" # string offset=172 -.Linfo_string12: - .asciz "v1" # string offset=175 - .section .debug_names,"",@progbits - .long .Lnames_end0-.Lnames_start0 # Header: unit length -.Lnames_start0: - .short 5 # Header: version - .short 0 # Header: padding - .long 3 # Header: compilation unit count - .long 0 # Header: local type unit count - .long 0 # Header: foreign type unit count - .long 7 # Header: bucket count - .long 7 # Header: name count - .long .Lnames_abbrev_end0-.Lnames_abbrev_start0 # Header: abbreviation table size - .long 8 # Header: augmentation string size - .ascii "LLVM0700" # Header: augmentation string - .long .Lcu_begin0 # Compilation unit 0 - .long .Lcu_begin1 # Compilation unit 1 - .long .Lcu_begin2 # Compilation unit 2 - .long 1 # Bucket 0 - .long 0 # Bucket 1 - .long 0 # Bucket 2 - .long 2 # Bucket 3 - .long 4 # Bucket 4 - .long 5 # Bucket 5 - .long 0 # Bucket 6 - .long 1398125246 # Hash in Bucket 0 - .long 193495088 # Hash in Bucket 3 - .long 2090499946 # Hash in Bucket 3 - .long 2090557760 # Hash in Bucket 4 - .long 5863324 # Hash in Bucket 5 - .long 5863786 # Hash in Bucket 5 - .long 1488390083 # Hash in Bucket 5 - .long .Linfo_string4 # String in Bucket 0: _Z2f12t1 - .long .Linfo_string10 # String in Bucket 3: int - .long .Linfo_string6 # String in Bucket 3: main - .long .Linfo_string8 # String in Bucket 4: null - .long .Linfo_string3 # String in Bucket 5: f1 - .long .Linfo_string11 # String in Bucket 5: t1 - .long .Linfo_string9 # String in Bucket 5: _Z4nullv - .long .Lnames1-.Lnames_entries0 # Offset in Bucket 0 - .long .Lnames5-.Lnames_entries0 # Offset in Bucket 3 - .long .Lnames2-.Lnames_entries0 # Offset in Bucket 3 - .long .Lnames3-.Lnames_entries0 # Offset in Bucket 4 - .long .Lnames0-.Lnames_entries0 # Offset in Bucket 5 - .long .Lnames6-.Lnames_entries0 # Offset in Bucket 5 - .long .Lnames4-.Lnames_entries0 # Offset in Bucket 5 -.Lnames_abbrev_start0: - .byte 1 # Abbrev code - .byte 46 # DW_TAG_subprogram - .byte 1 # DW_IDX_compile_unit - .byte 11 # DW_FORM_data1 - .byte 3 # DW_IDX_die_offset - .byte 19 # DW_FORM_ref4 - .byte 4 # DW_IDX_parent - .byte 25 # DW_FORM_flag_present - .byte 0 # End of abbrev - .byte 0 # End of abbrev - .byte 2 # Abbrev code - .byte 36 # DW_TAG_base_type - .byte 1 # DW_IDX_compile_unit - .byte 11 # DW_FORM_data1 - .byte 3 # DW_IDX_die_offset - .byte 19 # DW_FORM_ref4 - .byte 4 # DW_IDX_parent - .byte 25 # DW_FORM_flag_present - .byte 0 # End of abbrev - .byte 0 # End of abbrev - .byte 3 # Abbrev code - .byte 19 # DW_TAG_structure_type - .byte 1 # DW_IDX_compile_unit - .byte 11 # DW_FORM_data1 - .byte 3 # DW_IDX_die_offset - .byte 19 # DW_FORM_ref4 - .byte 4 # DW_IDX_parent - .byte 25 # DW_FORM_flag_present - .byte 0 # End of abbrev - .byte 0 # End of abbrev - .byte 0 # End of abbrev list -.Lnames_abbrev_end0: -.Lnames_entries0: -.Lnames1: -.L3: - .byte 1 # Abbreviation code - .byte 0 # DW_IDX_compile_unit - .long 35 # DW_IDX_die_offset - .byte 0 # DW_IDX_parent - # End of list: _Z2f12t1 -.Lnames5: -.L1: - .byte 2 # Abbreviation code - .byte 1 # DW_IDX_compile_unit - .long 62 # DW_IDX_die_offset - .byte 0 # DW_IDX_parent - # End of list: int -.Lnames2: -.L2: - .byte 1 # Abbreviation code - .byte 1 # DW_IDX_compile_unit - .long 35 # DW_IDX_die_offset - .byte 0 # DW_IDX_parent - # End of list: main -.Lnames3: -.L4: - .byte 1 # Abbreviation code - .byte 2 # DW_IDX_compile_unit - .long 35 # DW_IDX_die_offset - .byte 0 # DW_IDX_parent - # End of list: null -.Lnames0: - .byte 1 # Abbreviation code - .byte 0 # DW_IDX_compile_unit - .long 35 # DW_IDX_die_offset - .byte 0 # DW_IDX_parent - # End of list: f1 -.Lnames6: -.L0: - .byte 3 # Abbreviation code - .byte 0 # DW_IDX_compile_unit - .long 58 # DW_IDX_die_offset - .byte 0 # DW_IDX_parent - # End of list: t1 -.Lnames4: - .byte 1 # Abbreviation code - .byte 2 # DW_IDX_compile_unit - .long 35 # DW_IDX_die_offset - .byte 0 # DW_IDX_parent - # End of list: _Z4nullv - .p2align 2, 0x0 -.Lnames_end0: - .ident "clang version 19.0.0git (git@github.com:llvm/llvm-project.git dfe787af70e11666a8e43ca73a86d1841d364dfc)" - .ident "clang version 19.0.0git (git@github.com:llvm/llvm-project.git dfe787af70e11666a8e43ca73a86d1841d364dfc)" - .ident "clang version 19.0.0git (git@github.com:llvm/llvm-project.git dfe787af70e11666a8e43ca73a86d1841d364dfc)" - .section ".note.GNU-stack","",@progbits - .addrsig - .section .debug_line,"",@progbits -.Lline_table_start0: - -#--- de.s - - .text - .globl _Z3fooi # -- Begin function _Z3fooi - .p2align 4, 0x90 - .type _Z3fooi,@function -_Z3fooi: # @_Z3fooi -.Lfunc_begin0: - .cfi_startproc -# %bb.0: # %entry - pushq %rbp - .cfi_def_cfa_offset 16 - .cfi_offset %rbp, -16 - movq %rsp, %rbp - .cfi_def_cfa_register %rbp - movl %edi, -4(%rbp) -.Ltmp0: - movl $4, %eax - popq %rbp - .cfi_def_cfa %rsp, 8 - retq -.Ltmp1: -.Lfunc_end0: - .size _Z3fooi, .Lfunc_end0-_Z3fooi - .cfi_endproc - # -- End function - .globl _Z3barPv # -- Begin function _Z3barPv - .p2align 4, 0x90 - .type _Z3barPv,@function -_Z3barPv: # @_Z3barPv -.Lfunc_begin1: - .cfi_startproc -# %bb.0: # %entry - pushq %rbp - .cfi_def_cfa_offset 16 - .cfi_offset %rbp, -16 - movq %rsp, %rbp - .cfi_def_cfa_register %rbp - movq %rdi, -8(%rbp) -.Ltmp2: - popq %rbp - .cfi_def_cfa %rsp, 8 - retq -.Ltmp3: -.Lfunc_end1: - .size _Z3barPv, .Lfunc_end1-_Z3barPv - .cfi_endproc - # -- End function - .section .debug_info,"",@progbits -.Lcu_begin0: - .byte 0 -.Lcu_begin1: - .byte 0 - .section .debug_str,"MS",@progbits,1 -.Linfo_string0: - .asciz "clang version 19.0.0git (git@github.com:llvm/llvm-project.git dfe787af70e11666a8e43ca73a86d1841d364dfc)" # string offset=0 -.Linfo_string1: - .asciz "d.cpp" # string offset=104 -.Linfo_string2: - .asciz "/proc/self/cwd" # string offset=110 -.Linfo_string3: - .asciz "foo" # string offset=125 -.Linfo_string4: - .asciz "_Z3fooi" # string offset=129 -.Linfo_string5: - .asciz "e.cpp" # string offset=137 -.Linfo_string6: - .asciz "bar" # string offset=143 -.Linfo_string7: - .asciz "_Z3barPv" # string offset=147 -.Linfo_string8: - .asciz "int" # string offset=156 -.Linfo_string9: - .asciz "x" # string offset=160 - .section .debug_names,"",@progbits - .long .Lnames_end0-.Lnames_start0 # Header: unit length -.Lnames_start0: - .short 5 # Header: version - .short 0 # Header: padding - .long 2 # Header: compilation unit count - .long 0 # Header: local type unit count - .long 0 # Header: foreign type unit count - .long 5 # Header: bucket count - .long 5 # Header: name count - .long .Lnames_abbrev_end0-.Lnames_abbrev_start0 # Header: abbreviation table size - .long 8 # Header: augmentation string size - .ascii "LLVM0700" # Header: augmentation string - .long .Lcu_begin0 # Compilation unit 0 - .long .Lcu_begin1 # Compilation unit 1 - .long 0 # Bucket 0 - .long 1 # Bucket 1 - .long 0 # Bucket 2 - .long 2 # Bucket 3 - .long 3 # Bucket 4 - .long -1257882370 # Hash in Bucket 1 - .long 193495088 # Hash in Bucket 3 - .long 193487034 # Hash in Bucket 4 - .long 193491849 # Hash in Bucket 4 - .long 1434311564 # Hash in Bucket 4 - .long .Linfo_string4 # String in Bucket 1: _Z3fooi - .long .Linfo_string8 # String in Bucket 3: int - .long .Linfo_string6 # String in Bucket 4: bar - .long .Linfo_string3 # String in Bucket 4: foo - .long .Linfo_string7 # String in Bucket 4: _Z3barPv - .long .Lnames1-.Lnames_entries0 # Offset in Bucket 1 - .long .Lnames4-.Lnames_entries0 # Offset in Bucket 3 - .long .Lnames2-.Lnames_entries0 # Offset in Bucket 4 - .long .Lnames0-.Lnames_entries0 # Offset in Bucket 4 - .long .Lnames3-.Lnames_entries0 # Offset in Bucket 4 -.Lnames_abbrev_start0: - .byte 1 # Abbrev code - .byte 46 # DW_TAG_subprogram - .byte 1 # DW_IDX_compile_unit - .byte 11 # DW_FORM_data1 - .byte 3 # DW_IDX_die_offset - .byte 19 # DW_FORM_ref4 - .byte 4 # DW_IDX_parent - .byte 25 # DW_FORM_flag_present - .byte 0 # End of abbrev - .byte 0 # End of abbrev - .byte 2 # Abbrev code - .byte 36 # DW_TAG_base_type - .byte 1 # DW_IDX_compile_unit - .byte 11 # DW_FORM_data1 - .byte 3 # DW_IDX_die_offset - .byte 19 # DW_FORM_ref4 - .byte 4 # DW_IDX_parent - .byte 25 # DW_FORM_flag_present - .byte 0 # End of abbrev - .byte 0 # End of abbrev - .byte 0 # End of abbrev list -.Lnames_abbrev_end0: -.Lnames_entries0: -.Lnames1: -.L2: - .byte 1 # Abbreviation code - .byte 0 # DW_IDX_compile_unit - .long 35 # DW_IDX_die_offset - .byte 0 # DW_IDX_parent - # End of list: _Z3fooi -.Lnames4: -.L0: - .byte 2 # Abbreviation code - .byte 0 # DW_IDX_compile_unit - .long 63 # DW_IDX_die_offset - .byte 0 # DW_IDX_parent - # End of list: int -.Lnames2: -.L1: - .byte 1 # Abbreviation code - .byte 1 # DW_IDX_compile_unit - .long 35 # DW_IDX_die_offset - .byte 0 # DW_IDX_parent - # End of list: bar -.Lnames0: - .byte 1 # Abbreviation code - .byte 0 # DW_IDX_compile_unit - .long 35 # DW_IDX_die_offset - .byte 0 # DW_IDX_parent - # End of list: foo -.Lnames3: - .byte 1 # Abbreviation code - .byte 1 # DW_IDX_compile_unit - .long 35 # DW_IDX_die_offset - .byte 0 # DW_IDX_parent - # End of list: _Z3barPv - .p2align 2, 0x0 -.Lnames_end0: - .ident "clang version 19.0.0git (git@github.com:llvm/llvm-project.git dfe787af70e11666a8e43ca73a86d1841d364dfc)" - .ident "clang version 19.0.0git (git@github.com:llvm/llvm-project.git dfe787af70e11666a8e43ca73a86d1841d364dfc)" - .section ".note.GNU-stack","",@progbits - .addrsig - .section .debug_line,"",@progbits -.Lline_table_start0: - -#--- f.s - - .text - .globl _Z3bazv # -- Begin function _Z3bazv - .p2align 4, 0x90 - .type _Z3bazv,@function -_Z3bazv: # @_Z3bazv -.Lfunc_begin0: - .cfi_startproc -# %bb.0: # %entry - pushq %rbp - .cfi_def_cfa_offset 16 - .cfi_offset %rbp, -16 - movq %rsp, %rbp - .cfi_def_cfa_register %rbp -.Ltmp0: - popq %rbp - .cfi_def_cfa %rsp, 8 - retq -.Ltmp1: -.Lfunc_end0: - .size _Z3bazv, .Lfunc_end0-_Z3bazv - .cfi_endproc - # -- End function - .section .debug_info,"",@progbits -.Lcu_begin0: - .byte 0 - .section .debug_str,"MS",@progbits,1 -.Linfo_string0: - .asciz "clang version 19.0.0git (git@github.com:llvm/llvm-project.git dfe787af70e11666a8e43ca73a86d1841d364dfc)" # string offset=0 -.Linfo_string1: - .asciz "f.cpp" # string offset=104 -.Linfo_string2: - .asciz "/proc/self/cwd" # string offset=110 -.Linfo_string3: - .asciz "baz" # string offset=125 -.Linfo_string4: - .asciz "_Z3bazv" # string offset=129 - .section .debug_names,"",@progbits - .long .Lnames_end0-.Lnames_start0 # Header: unit length -.Lnames_start0: - .short 5 # Header: version - .short 0 # Header: padding - .long 1 # Header: compilation unit count - .long 0 # Header: local type unit count - .long 0 # Header: foreign type unit count - .long 2 # Header: bucket count - .long 2 # Header: name count - .long .Lnames_abbrev_end0-.Lnames_abbrev_start0 # Header: abbreviation table size - .long 8 # Header: augmentation string size - .ascii "LLVM0700" # Header: augmentation string - .long .Lcu_begin0 # Compilation unit 0 - .long 1 # Bucket 0 - .long 0 # Bucket 1 - .long 193487042 # Hash in Bucket 0 - .long -1258040988 # Hash in Bucket 0 - .long .Linfo_string3 # String in Bucket 0: baz - .long .Linfo_string4 # String in Bucket 0: _Z3bazv - .long .Lnames0-.Lnames_entries0 # Offset in Bucket 0 - .long .Lnames1-.Lnames_entries0 # Offset in Bucket 0 -.Lnames_abbrev_start0: - .byte 1 # Abbrev code - .byte 46 # DW_TAG_subprogram - .byte 3 # DW_IDX_die_offset - .byte 19 # DW_FORM_ref4 - .byte 4 # DW_IDX_parent - .byte 25 # DW_FORM_flag_present - .byte 0 # End of abbrev - .byte 0 # End of abbrev - .byte 0 # End of abbrev list -.Lnames_abbrev_end0: -.Lnames_entries0: -.Lnames0: -.L0: - .byte 1 # Abbreviation code - .long 35 # DW_IDX_die_offset - .byte 0 # DW_IDX_parent - # End of list: baz -.Lnames1: - .byte 1 # Abbreviation code - .long 35 # DW_IDX_die_offset - .byte 0 # DW_IDX_parent - # End of list: _Z3bazv - .p2align 2, 0x0 -.Lnames_end0: - .ident "clang version 19.0.0git (git@github.com:llvm/llvm-project.git dfe787af70e11666a8e43ca73a86d1841d364dfc)" - .section ".note.GNU-stack","",@progbits - .addrsig - .section .debug_line,"",@progbits -.Lline_table_start0: - diff --git a/lld/test/ELF/debug-names-multi-cus.s b/lld/test/ELF/debug-names-multi-cus.s index bc79a783f61dd..19e99be58e701 100644 --- a/lld/test/ELF/debug-names-multi-cus.s +++ b/lld/test/ELF/debug-names-multi-cus.s @@ -1,645 +1,48 @@ -# ab.s was generated by: - -# clang++ a.cpp -gpubnames a.cpp -g -emit-llvm -c \ -# -fdebug-compilation-dir='/proc/self/cwd -# clang++ b.cpp -gpubnames b.cpp -g -emit-llvm -c \ -# -fdebug-compilation-dir='/proc/self/cwd -# llvm-link a.bc b.bc -o ab.bc -# clang++ ab.bc -S -o ab.s - -# a.cpp contains: -# struct t1 { }; -# void f1(t1) { } - -# b.cpp contains: -# struct t1 { }; -# int main() { -# t1 v1; -# } - - # REQUIRES: x86 -# RUN: rm -rf %t && split-file %s %t && cd %t -# RUN: llvm-mc -filetype=obj -triple=x86_64 ab.s -o ab.o -# RUN: llvm-mc -filetype=obj -triple=x86_64 c.s -o c.o -# RUN: ld.lld --debug-names ab.o c.o -o out -# RUN: llvm-dwarfdump --debug-names out \ -# RUN: | FileCheck -DFILE=a.o %s --check-prefix=DWARF - -# DWARF: Compilation Unit offsets [ -# DWARF-NEXT: CU[0]: 0x00000000 -# DWARF-NEXT: CU[1]: 0x00000041 -# DWARF-NEXT: CU[2]: 0x00000084 -# DWARF-NEXT: ] - -# RUN: ld.lld --debug-names c.o ab.o -o out2 -# RUN: llvm-dwarfdump --debug-names out2 \ -# RUN: | FileCheck -DFILE=a.o %s --check-prefix=DWARF2 - -# DWARF2: Compilation Unit offsets [ -# DWARF2-NEXT: CU[0]: 0x00000000 -# DWARF2-NEXT: CU[1]: 0x00000030 -# DWARF2-NEXT: CU[2]: 0x00000071 -# DWARF2-NEXT: ] - -#--- ab.s - .text - .globl _Z2f12t1 # -- Begin function _Z2f12t1 - .p2align 4, 0x90 - .type _Z2f12t1,@function -_Z2f12t1: # @_Z2f12t1 -.Lfunc_begin0: - .cfi_startproc -# %bb.0: # %entry - pushq %rbp - .cfi_def_cfa_offset 16 - .cfi_offset %rbp, -16 - movq %rsp, %rbp - .cfi_def_cfa_register %rbp -.Ltmp0: - popq %rbp - .cfi_def_cfa %rsp, 8 - retq -.Ltmp1: -.Lfunc_end0: - .size _Z2f12t1, .Lfunc_end0-_Z2f12t1 - .cfi_endproc - # -- End function - .globl main # -- Begin function main - .p2align 4, 0x90 - .type main,@function -main: # @main -.Lfunc_begin1: - .cfi_startproc -# %bb.0: # %entry - pushq %rbp - .cfi_def_cfa_offset 16 - .cfi_offset %rbp, -16 - movq %rsp, %rbp - .cfi_def_cfa_register %rbp -.Ltmp2: - xorl %eax, %eax - popq %rbp - .cfi_def_cfa %rsp, 8 - retq -.Ltmp3: -.Lfunc_end1: - .size main, .Lfunc_end1-main - .cfi_endproc - # -- End function - .section .debug_abbrev,"",@progbits - .byte 1 # Abbreviation Code - .byte 17 # DW_TAG_compile_unit - .byte 1 # DW_CHILDREN_yes - .byte 37 # DW_AT_producer - .byte 37 # DW_FORM_strx1 - .byte 19 # DW_AT_language - .byte 5 # DW_FORM_data2 - .byte 3 # DW_AT_name - .byte 37 # DW_FORM_strx1 - .byte 114 # DW_AT_str_offsets_base - .byte 23 # DW_FORM_sec_offset - .byte 16 # DW_AT_stmt_list - .byte 23 # DW_FORM_sec_offset - .byte 27 # DW_AT_comp_dir - .byte 37 # DW_FORM_strx1 - .byte 17 # DW_AT_low_pc - .byte 27 # DW_FORM_addrx - .byte 18 # DW_AT_high_pc - .byte 6 # DW_FORM_data4 - .byte 115 # DW_AT_addr_base - .byte 23 # DW_FORM_sec_offset - .byte 0 # EOM(1) - .byte 0 # EOM(2) - .byte 2 # Abbreviation Code - .byte 46 # DW_TAG_subprogram - .byte 1 # DW_CHILDREN_yes - .byte 17 # DW_AT_low_pc - .byte 27 # DW_FORM_addrx - .byte 18 # DW_AT_high_pc - .byte 6 # DW_FORM_data4 - .byte 64 # DW_AT_frame_base - .byte 24 # DW_FORM_exprloc - .byte 110 # DW_AT_linkage_name - .byte 37 # DW_FORM_strx1 - .byte 3 # DW_AT_name - .byte 37 # DW_FORM_strx1 - .byte 58 # DW_AT_decl_file - .byte 11 # DW_FORM_data1 - .byte 59 # DW_AT_decl_line - .byte 11 # DW_FORM_data1 - .byte 63 # DW_AT_external - .byte 25 # DW_FORM_flag_present - .byte 0 # EOM(1) - .byte 0 # EOM(2) - .byte 3 # Abbreviation Code - .byte 5 # DW_TAG_formal_parameter - .byte 0 # DW_CHILDREN_no - .byte 2 # DW_AT_location - .byte 24 # DW_FORM_exprloc - .byte 58 # DW_AT_decl_file - .byte 11 # DW_FORM_data1 - .byte 59 # DW_AT_decl_line - .byte 11 # DW_FORM_data1 - .byte 73 # DW_AT_type - .byte 19 # DW_FORM_ref4 - .byte 0 # EOM(1) - .byte 0 # EOM(2) - .byte 4 # Abbreviation Code - .byte 19 # DW_TAG_structure_type - .byte 0 # DW_CHILDREN_no - .byte 54 # DW_AT_calling_convention - .byte 11 # DW_FORM_data1 - .byte 3 # DW_AT_name - .byte 37 # DW_FORM_strx1 - .byte 11 # DW_AT_byte_size - .byte 11 # DW_FORM_data1 - .byte 58 # DW_AT_decl_file - .byte 11 # DW_FORM_data1 - .byte 59 # DW_AT_decl_line - .byte 11 # DW_FORM_data1 - .byte 0 # EOM(1) - .byte 0 # EOM(2) - .byte 5 # Abbreviation Code - .byte 46 # DW_TAG_subprogram - .byte 1 # DW_CHILDREN_yes - .byte 17 # DW_AT_low_pc - .byte 27 # DW_FORM_addrx - .byte 18 # DW_AT_high_pc - .byte 6 # DW_FORM_data4 - .byte 64 # DW_AT_frame_base - .byte 24 # DW_FORM_exprloc - .byte 3 # DW_AT_name - .byte 37 # DW_FORM_strx1 - .byte 58 # DW_AT_decl_file - .byte 11 # DW_FORM_data1 - .byte 59 # DW_AT_decl_line - .byte 11 # DW_FORM_data1 - .byte 73 # DW_AT_type - .byte 19 # DW_FORM_ref4 - .byte 63 # DW_AT_external - .byte 25 # DW_FORM_flag_present - .byte 0 # EOM(1) - .byte 0 # EOM(2) - .byte 6 # Abbreviation Code - .byte 52 # DW_TAG_variable - .byte 0 # DW_CHILDREN_no - .byte 2 # DW_AT_location - .byte 24 # DW_FORM_exprloc - .byte 3 # DW_AT_name - .byte 37 # DW_FORM_strx1 - .byte 58 # DW_AT_decl_file - .byte 11 # DW_FORM_data1 - .byte 59 # DW_AT_decl_line - .byte 11 # DW_FORM_data1 - .byte 73 # DW_AT_type - .byte 16 # DW_FORM_ref_addr - .byte 0 # EOM(1) - .byte 0 # EOM(2) - .byte 7 # Abbreviation Code - .byte 36 # DW_TAG_base_type - .byte 0 # DW_CHILDREN_no - .byte 3 # DW_AT_name - .byte 37 # DW_FORM_strx1 - .byte 62 # DW_AT_encoding - .byte 11 # DW_FORM_data1 - .byte 11 # DW_AT_byte_size - .byte 11 # DW_FORM_data1 - .byte 0 # EOM(1) - .byte 0 # EOM(2) - .byte 0 # EOM(3) - .section .debug_info,"",@progbits -.Lcu_begin0: - .long .Ldebug_info_end0-.Ldebug_info_start0 # Length of Unit -.Ldebug_info_start0: - .short 5 # DWARF version number - .byte 1 # DWARF Unit Type - .byte 8 # Address Size (in bytes) - .long .debug_abbrev # Offset Into Abbrev. Section - .byte 1 # Abbrev [1] 0xc:0x35 DW_TAG_compile_unit - .byte 0 # DW_AT_producer - .short 33 # DW_AT_language - .byte 1 # DW_AT_name - .long .Lstr_offsets_base0 # DW_AT_str_offsets_base - .long .Lline_table_start0 # DW_AT_stmt_list - .byte 2 # DW_AT_comp_dir - .byte 0 # DW_AT_low_pc - .long .Lfunc_end0-.Lfunc_begin0 # DW_AT_high_pc - .long .Laddr_table_base0 # DW_AT_addr_base - .byte 2 # Abbrev [2] 0x23:0x17 DW_TAG_subprogram - .byte 0 # DW_AT_low_pc - .long .Lfunc_end0-.Lfunc_begin0 # DW_AT_high_pc - .byte 1 # DW_AT_frame_base - .byte 86 - .byte 4 # DW_AT_linkage_name - .byte 5 # DW_AT_name - .byte 1 # DW_AT_decl_file - .byte 2 # DW_AT_decl_line - # DW_AT_external - .byte 3 # Abbrev [3] 0x2f:0xa DW_TAG_formal_parameter - .byte 2 # DW_AT_location - .byte 145 - .byte 127 - .byte 1 # DW_AT_decl_file - .byte 2 # DW_AT_decl_line - .long 58 # DW_AT_type - .byte 0 # End Of Children Mark - .byte 4 # Abbrev [4] 0x3a:0x6 DW_TAG_structure_type - .byte 5 # DW_AT_calling_convention - .byte 8 # DW_AT_name - .byte 1 # DW_AT_byte_size - .byte 1 # DW_AT_decl_file - .byte 1 # DW_AT_decl_line - .byte 0 # End Of Children Mark -.Ldebug_info_end0: -.Lcu_begin1: - .long .Ldebug_info_end1-.Ldebug_info_start1 # Length of Unit -.Ldebug_info_start1: - .short 5 # DWARF version number - .byte 1 # DWARF Unit Type - .byte 8 # Address Size (in bytes) - .long .debug_abbrev # Offset Into Abbrev. Section - .byte 1 # Abbrev [1] 0xc:0x37 DW_TAG_compile_unit - .byte 0 # DW_AT_producer - .short 33 # DW_AT_language - .byte 3 # DW_AT_name - .long .Lstr_offsets_base0 # DW_AT_str_offsets_base - .long .Lline_table_start0 # DW_AT_stmt_list - .byte 2 # DW_AT_comp_dir - .byte 1 # DW_AT_low_pc - .long .Lfunc_end1-.Lfunc_begin1 # DW_AT_high_pc - .long .Laddr_table_base0 # DW_AT_addr_base - .byte 5 # Abbrev [5] 0x23:0x1b DW_TAG_subprogram - .byte 1 # DW_AT_low_pc - .long .Lfunc_end1-.Lfunc_begin1 # DW_AT_high_pc - .byte 1 # DW_AT_frame_base - .byte 86 - .byte 6 # DW_AT_name - .byte 2 # DW_AT_decl_file - .byte 2 # DW_AT_decl_line - .long 62 # DW_AT_type - # DW_AT_external - .byte 6 # Abbrev [6] 0x32:0xb DW_TAG_variable - .byte 2 # DW_AT_location - .byte 145 - .byte 127 - .byte 9 # DW_AT_name - .byte 2 # DW_AT_decl_file - .byte 3 # DW_AT_decl_line - .long .debug_info+58 # DW_AT_type - .byte 0 # End Of Children Mark - .byte 7 # Abbrev [7] 0x3e:0x4 DW_TAG_base_type - .byte 7 # DW_AT_name - .byte 5 # DW_AT_encoding - .byte 4 # DW_AT_byte_size - .byte 0 # End Of Children Mark -.Ldebug_info_end1: - .section .debug_str_offsets,"",@progbits - .long 44 # Length of String Offsets Set - .short 5 - .short 0 -.Lstr_offsets_base0: - .section .debug_str,"MS",@progbits,1 -.Linfo_string0: - .asciz "clang version 19.0.0git (git@github.com:llvm/llvm-project.git 7607c4d40149128f848055613edf9c3cf9ae890d)" # string offset=0 -.Linfo_string1: - .asciz "a.cpp" # string offset=104 -.Linfo_string2: - .asciz "/proc/self/cwd" # string offset=110 -.Linfo_string3: - .asciz "f1" # string offset=125 -.Linfo_string4: - .asciz "_Z2f12t1" # string offset=128 -.Linfo_string5: - .asciz "b.cpp" # string offset=137 -.Linfo_string6: - .asciz "main" # string offset=143 -.Linfo_string7: - .asciz "int" # string offset=148 -.Linfo_string8: - .asciz "t1" # string offset=152 -.Linfo_string9: - .asciz "v1" # string offset=155 - .section .debug_str_offsets,"",@progbits - .long .Linfo_string0 - .long .Linfo_string1 - .long .Linfo_string2 - .long .Linfo_string5 - .long .Linfo_string4 - .long .Linfo_string3 - .long .Linfo_string6 - .long .Linfo_string7 - .long .Linfo_string8 - .long .Linfo_string9 - .section .debug_addr,"",@progbits - .long .Ldebug_addr_end0-.Ldebug_addr_start0 # Length of contribution -.Ldebug_addr_start0: - .short 5 # DWARF version number - .byte 8 # Address size - .byte 0 # Segment selector size -.Laddr_table_base0: - .quad .Lfunc_begin0 - .quad .Lfunc_begin1 -.Ldebug_addr_end0: - .section .debug_names,"",@progbits - .long .Lnames_end0-.Lnames_start0 # Header: unit length -.Lnames_start0: - .short 5 # Header: version - .short 0 # Header: padding - .long 2 # Header: compilation unit count - .long 0 # Header: local type unit count - .long 0 # Header: foreign type unit count - .long 5 # Header: bucket count - .long 5 # Header: name count - .long .Lnames_abbrev_end0-.Lnames_abbrev_start0 # Header: abbreviation table size - .long 8 # Header: augmentation string size - .ascii "LLVM0700" # Header: augmentation string - .long .Lcu_begin0 # Compilation unit 0 - .long .Lcu_begin1 # Compilation unit 1 - .long 0 # Bucket 0 - .long 1 # Bucket 1 - .long 0 # Bucket 2 - .long 4 # Bucket 3 - .long 5 # Bucket 4 - .long 5863786 # Hash in Bucket 1 - .long 1398125246 # Hash in Bucket 1 - .long 2090499946 # Hash in Bucket 1 - .long 193495088 # Hash in Bucket 3 - .long 5863324 # Hash in Bucket 4 - .long .Linfo_string8 # String in Bucket 1: t1 - .long .Linfo_string4 # String in Bucket 1: _Z2f12t1 - .long .Linfo_string6 # String in Bucket 1: main - .long .Linfo_string7 # String in Bucket 3: int - .long .Linfo_string3 # String in Bucket 4: f1 - .long .Lnames4-.Lnames_entries0 # Offset in Bucket 1 - .long .Lnames1-.Lnames_entries0 # Offset in Bucket 1 - .long .Lnames2-.Lnames_entries0 # Offset in Bucket 1 - .long .Lnames3-.Lnames_entries0 # Offset in Bucket 3 - .long .Lnames0-.Lnames_entries0 # Offset in Bucket 4 -.Lnames_abbrev_start0: - .byte 1 # Abbrev code - .byte 19 # DW_TAG_structure_type - .byte 1 # DW_IDX_compile_unit - .byte 11 # DW_FORM_data1 - .byte 3 # DW_IDX_die_offset - .byte 19 # DW_FORM_ref4 - .byte 4 # DW_IDX_parent - .byte 25 # DW_FORM_flag_present - .byte 0 # End of abbrev - .byte 0 # End of abbrev - .byte 2 # Abbrev code - .byte 46 # DW_TAG_subprogram - .byte 1 # DW_IDX_compile_unit - .byte 11 # DW_FORM_data1 - .byte 3 # DW_IDX_die_offset - .byte 19 # DW_FORM_ref4 - .byte 4 # DW_IDX_parent - .byte 25 # DW_FORM_flag_present - .byte 0 # End of abbrev - .byte 0 # End of abbrev - .byte 3 # Abbrev code - .byte 36 # DW_TAG_base_type - .byte 1 # DW_IDX_compile_unit - .byte 11 # DW_FORM_data1 - .byte 3 # DW_IDX_die_offset - .byte 19 # DW_FORM_ref4 - .byte 4 # DW_IDX_parent - .byte 25 # DW_FORM_flag_present - .byte 0 # End of abbrev - .byte 0 # End of abbrev - .byte 0 # End of abbrev list -.Lnames_abbrev_end0: -.Lnames_entries0: -.Lnames4: -.L0: - .byte 1 # Abbreviation code - .byte 0 # DW_IDX_compile_unit - .long 58 # DW_IDX_die_offset - .byte 0 # DW_IDX_parent - # End of list: t1 -.Lnames1: -.L3: - .byte 2 # Abbreviation code - .byte 0 # DW_IDX_compile_unit - .long 35 # DW_IDX_die_offset - .byte 0 # DW_IDX_parent - # End of list: _Z2f12t1 -.Lnames2: -.L2: - .byte 2 # Abbreviation code - .byte 1 # DW_IDX_compile_unit - .long 35 # DW_IDX_die_offset - .byte 0 # DW_IDX_parent - # End of list: main -.Lnames3: -.L1: - .byte 3 # Abbreviation code - .byte 1 # DW_IDX_compile_unit - .long 62 # DW_IDX_die_offset - .byte 0 # DW_IDX_parent - # End of list: int -.Lnames0: - .byte 2 # Abbreviation code - .byte 0 # DW_IDX_compile_unit - .long 35 # DW_IDX_die_offset - .byte 0 # DW_IDX_parent - # End of list: f1 - .p2align 2, 0x0 -.Lnames_end0: - .ident "clang version 19.0.0git (git@github.com:llvm/llvm-project.git 7607c4d40149128f848055613edf9c3cf9ae890d)" - .ident "clang version 19.0.0git (git@github.com:llvm/llvm-project.git 7607c4d40149128f848055613edf9c3cf9ae890d)" - .section ".note.GNU-stack","",@progbits - .addrsig - .section .debug_line,"",@progbits -.Lline_table_start0: - -#--- c.s -# Generated with: -# - clang++ -g -gpubnames -fdebug-compilation-dir='/proc/self/cwd' \ -# -S c.cpp -o c.s - -# c.cpp contents: - -# void null() { } - - .text - .globl _Z4nullv # -- Begin function _Z4nullv - .p2align 4, 0x90 - .type _Z4nullv,@function -_Z4nullv: # @_Z4nullv -.Lfunc_begin0: - .cfi_startproc -# %bb.0: # %entry - pushq %rbp - .cfi_def_cfa_offset 16 - .cfi_offset %rbp, -16 - movq %rsp, %rbp - .cfi_def_cfa_register %rbp -.Ltmp0: - popq %rbp - .cfi_def_cfa %rsp, 8 - retq -.Ltmp1: -.Lfunc_end0: - .size _Z4nullv, .Lfunc_end0-_Z4nullv - .cfi_endproc - # -- End function - .section .debug_abbrev,"",@progbits - .byte 1 # Abbreviation Code - .byte 17 # DW_TAG_compile_unit - .byte 1 # DW_CHILDREN_yes - .byte 37 # DW_AT_producer - .byte 37 # DW_FORM_strx1 - .byte 19 # DW_AT_language - .byte 5 # DW_FORM_data2 - .byte 3 # DW_AT_name - .byte 37 # DW_FORM_strx1 - .byte 114 # DW_AT_str_offsets_base - .byte 23 # DW_FORM_sec_offset - .byte 16 # DW_AT_stmt_list - .byte 23 # DW_FORM_sec_offset - .byte 27 # DW_AT_comp_dir - .byte 37 # DW_FORM_strx1 - .byte 17 # DW_AT_low_pc - .byte 27 # DW_FORM_addrx - .byte 18 # DW_AT_high_pc - .byte 6 # DW_FORM_data4 - .byte 115 # DW_AT_addr_base - .byte 23 # DW_FORM_sec_offset - .byte 0 # EOM(1) - .byte 0 # EOM(2) - .byte 2 # Abbreviation Code - .byte 46 # DW_TAG_subprogram - .byte 0 # DW_CHILDREN_no - .byte 17 # DW_AT_low_pc - .byte 27 # DW_FORM_addrx - .byte 18 # DW_AT_high_pc - .byte 6 # DW_FORM_data4 - .byte 64 # DW_AT_frame_base - .byte 24 # DW_FORM_exprloc - .byte 110 # DW_AT_linkage_name - .byte 37 # DW_FORM_strx1 - .byte 3 # DW_AT_name - .byte 37 # DW_FORM_strx1 - .byte 58 # DW_AT_decl_file - .byte 11 # DW_FORM_data1 - .byte 59 # DW_AT_decl_line - .byte 11 # DW_FORM_data1 - .byte 63 # DW_AT_external - .byte 25 # DW_FORM_flag_present - .byte 0 # EOM(1) - .byte 0 # EOM(2) - .byte 0 # EOM(3) - .section .debug_info,"",@progbits -.Lcu_begin0: - .long .Ldebug_info_end0-.Ldebug_info_start0 # Length of Unit -.Ldebug_info_start0: - .short 5 # DWARF version number - .byte 1 # DWARF Unit Type - .byte 8 # Address Size (in bytes) - .long .debug_abbrev # Offset Into Abbrev. Section - .byte 1 # Abbrev [1] 0xc:0x24 DW_TAG_compile_unit - .byte 0 # DW_AT_producer - .short 33 # DW_AT_language - .byte 1 # DW_AT_name - .long .Lstr_offsets_base0 # DW_AT_str_offsets_base - .long .Lline_table_start0 # DW_AT_stmt_list - .byte 2 # DW_AT_comp_dir - .byte 0 # DW_AT_low_pc - .long .Lfunc_end0-.Lfunc_begin0 # DW_AT_high_pc - .long .Laddr_table_base0 # DW_AT_addr_base - .byte 2 # Abbrev [2] 0x23:0xc DW_TAG_subprogram - .byte 0 # DW_AT_low_pc - .long .Lfunc_end0-.Lfunc_begin0 # DW_AT_high_pc - .byte 1 # DW_AT_frame_base - .byte 86 - .byte 3 # DW_AT_linkage_name - .byte 4 # DW_AT_name - .byte 0 # DW_AT_decl_file - .byte 1 # DW_AT_decl_line - # DW_AT_external - .byte 0 # End Of Children Mark -.Ldebug_info_end0: - .section .debug_str_offsets,"",@progbits - .long 24 # Length of String Offsets Set - .short 5 - .short 0 -.Lstr_offsets_base0: - .section .debug_str,"MS",@progbits,1 -.Linfo_string0: - .asciz "clang version 19.0.0git (git@github.com:llvm/llvm-project.git 7607c4d40149128f848055613edf9c3cf9ae890d)" # string offset=0 -.Linfo_string1: - .asciz "c.cpp" # string offset=104 -.Linfo_string2: - .asciz "/proc/self/cwd" # string offset=110 -.Linfo_string3: - .asciz "null" # string offset=125 -.Linfo_string4: - .asciz "_Z4nullv" # string offset=130 - .section .debug_str_offsets,"",@progbits - .long .Linfo_string0 - .long .Linfo_string1 - .long .Linfo_string2 - .long .Linfo_string4 - .long .Linfo_string3 - .section .debug_addr,"",@progbits - .long .Ldebug_addr_end0-.Ldebug_addr_start0 # Length of contribution -.Ldebug_addr_start0: - .short 5 # DWARF version number - .byte 8 # Address size - .byte 0 # Segment selector size -.Laddr_table_base0: - .quad .Lfunc_begin0 -.Ldebug_addr_end0: - .section .debug_names,"",@progbits - .long .Lnames_end0-.Lnames_start0 # Header: unit length -.Lnames_start0: - .short 5 # Header: version - .short 0 # Header: padding - .long 1 # Header: compilation unit count - .long 0 # Header: local type unit count - .long 0 # Header: foreign type unit count - .long 2 # Header: bucket count - .long 2 # Header: name count - .long .Lnames_abbrev_end0-.Lnames_abbrev_start0 # Header: abbreviation table size - .long 8 # Header: augmentation string size - .ascii "LLVM0700" # Header: augmentation string - .long .Lcu_begin0 # Compilation unit 0 - .long 1 # Bucket 0 - .long 2 # Bucket 1 - .long 2090557760 # Hash in Bucket 0 - .long 1488390083 # Hash in Bucket 1 - .long .Linfo_string3 # String in Bucket 0: null - .long .Linfo_string4 # String in Bucket 1: _Z4nullv - .long .Lnames0-.Lnames_entries0 # Offset in Bucket 0 - .long .Lnames1-.Lnames_entries0 # Offset in Bucket 1 -.Lnames_abbrev_start0: - .byte 1 # Abbrev code - .byte 46 # DW_TAG_subprogram - .byte 3 # DW_IDX_die_offset - .byte 19 # DW_FORM_ref4 - .byte 4 # DW_IDX_parent - .byte 25 # DW_FORM_flag_present - .byte 0 # End of abbrev - .byte 0 # End of abbrev - .byte 0 # End of abbrev list -.Lnames_abbrev_end0: -.Lnames_entries0: -.Lnames0: -.L0: - .byte 1 # Abbreviation code - .long 35 # DW_IDX_die_offset - .byte 0 # DW_IDX_parent - # End of list: null -.Lnames1: - .byte 1 # Abbreviation code - .long 35 # DW_IDX_die_offset - .byte 0 # DW_IDX_parent - # End of list: _Z4nullv - .p2align 2, 0x0 -.Lnames_end0: - .ident "clang version 19.0.0git (git@github.com:llvm/llvm-project.git 7607c4d40149128f848055613edf9c3cf9ae890d)" - .section ".note.GNU-stack","",@progbits - .addrsig - .section .debug_line,"",@progbits -.Lline_table_start0: +## Test name indexes that contain multiple CU offsets due to LTO. + +# RUN: rm -rf %t && mkdir %t && cd %t +# RUN: llvm-mc -filetype=obj -triple=x86_64 %S/Inputs/debug-names-a.s -o a.o +# RUN: llvm-mc -filetype=obj -triple=x86_64 %S/Inputs/debug-names-bcd.s -o bcd.o +# RUN: llvm-mc -filetype=obj -triple=x86_64 %S/Inputs/debug-names-ef.s -o ef.o +# RUN: ld.lld --debug-names a.o bcd.o ef.o -o out +# RUN: llvm-dwarfdump --debug-info --debug-names out | FileCheck %s --check-prefix=DWARF + +## Place the multiple CU offsets in the second name index in an input file. +# RUN: ld.lld -r a.o bcd.o -o abcd.o +# RUN: ld.lld --debug-names abcd.o ef.o -o out +# RUN: llvm-dwarfdump --debug-info --debug-names out | FileCheck %s --check-prefix=DWARF + +# DWARF: 0x00000000: Compile Unit +# DWARF: 0x00000040: Compile Unit +# DWARF: 0x0000006e: Compile Unit +# DWARF: 0x00000098: Compile Unit +# DWARF: 0x000000c6: Compile Unit +# DWARF: 0x000000f4: Compile Unit + +# DWARF: Compilation Unit offsets [ +# DWARF-NEXT: CU[0]: 0x00000000 +# DWARF-NEXT: CU[1]: 0x00000040 +# DWARF-NEXT: CU[2]: 0x0000006e +# DWARF-NEXT: CU[3]: 0x00000098 +# DWARF-NEXT: CU[4]: 0x000000c6 +# DWARF-NEXT: CU[5]: 0x000000f4 +# DWARF-NEXT: ] +# DWARF: String: {{.*}} "vc" +# DWARF: DW_IDX_compile_unit: 0x02 +# DWARF: String: {{.*}} "vd" +# DWARF: DW_IDX_die_offset: +# DWARF-SAME: 0x00000020 +# DWARF: DW_IDX_compile_unit: +# DWARF-SAME: 0x03 +# DWARF: String: {{.*}} "ve" +# DWARF: DW_IDX_die_offset: +# DWARF-SAME: 0x0000001e +# DWARF: DW_IDX_compile_unit: +# DWARF-SAME: 0x04 +# DWARF: String: {{.*}} "vf" +# DWARF: DW_IDX_compile_unit: +# DWARF-SAME: 0x05 +# DWARF: String: {{.*}} "vb" +# DWARF: DW_IDX_compile_unit: +# DWARF-SAME: 0x01 diff --git a/lld/test/ELF/debug-names-nonames.s b/lld/test/ELF/debug-names-nonames.s index be658ae761496..54b7c864fa825 100644 --- a/lld/test/ELF/debug-names-nonames.s +++ b/lld/test/ELF/debug-names-nonames.s @@ -1,228 +1,33 @@ -# The .s files were generated with: - -# - clang++ -g -gpubnames -fdebug-compilation-dir='/proc/self/cwd' \ -# -S a.cpp -o a.names.s - -# - clang++ -O0 -S a.cpp -o a.nonames.s - -# - clang++ -O0 -S b.cpp -o b.s - -# a.cpp contents: - -# struct t1 { }; -# void f1(t1) { } - -# b.cpp contents: -# struct t1 { }; -# int main() { -# t1 v1; -# } -# - # REQUIRES: x86 -# RUN: rm -rf %t && split-file %s %t && cd %t -# RUN: llvm-mc -filetype=obj -triple=x86_64 a.names.s -o a.names.o -# RUN: llvm-mc -filetype=obj -triple=x86_64 a.nonames.s -o a.nonames.o -# RUN: llvm-mc -filetype=obj -triple=x86_64 b.s -o b.o +# RUN: rm -rf %t && mkdir %t && cd %t +# RUN: llvm-mc -filetype=obj -triple=x86_64 %S/Inputs/debug-names-a.s -o a.o +# RUN: echo '.globl foo; foo:' | llvm-mc -filetype=obj -triple=x86_64 - -o b0.o -# Test one file with .debug_names and one file without. -# RUN: ld.lld --debug-names a.names.o b.o -o out0 -# RUN: llvm-readelf -SW out0 | FileCheck %s --check-prefix=ELF1 +# RUN: ld.lld --debug-names a.o b0.o -o out0 # RUN: llvm-dwarfdump -debug-names out0 | FileCheck %s --check-prefix=DWARF # DWARF: .debug_names contents: # DWARF-NEXT: Name Index @ 0x0 { # DWARF-NEXT: Header { -# DWARF-NEXT: Length: 0x86 +# DWARF-NEXT: Length: 0x6F # DWARF-NEXT: Format: DWARF32 # DWARF-NEXT: Version: 5 # DWARF-NEXT: CU count: 1 # DWARF-NEXT: Local TU count: 0 # DWARF-NEXT: Foreign TU count: 0 -# DWARF-NEXT: Bucket count: 3 -# DWARF-NEXT: Name count: 3 +# DWARF-NEXT: Bucket count: 2 +# DWARF-NEXT: Name count: 2 # DWARF-NEXT: Abbreviations table size: 0x15 # DWARF-NEXT: Augmentation: 'LLVM0700' # DWARF-NEXT: } # DWARF-NEXT: Compilation Unit offsets [ # DWARF-NEXT: CU[0]: 0x00000000 # DWARF-NEXT: ] - -# ELF1: Name Type Address Off Size ES Flg Lk Inf Al -# ELF1: .debug_names PROGBITS 0000000000000000 [[#%x,]] 00008a 00 0 0 4 - -# Test both files without .debug_names. -# RUN: ld.lld --debug-names a.nonames.o b.o -o out -# RUN: llvm-readelf -SW out | FileCheck %s --check-prefix=ELF2 - -# Verify that there not a .debug_names section in the ELF file. -# ELF2: Name Type Address Off Size ES Flg Lk Inf Al -# ELF2: [ 1] .eh_frame PROGBITS 0000000000200120 000120 00005c 00 A 0 0 8 -# ELF2-NEXT: [ 2] .text PROGBITS 0000000000201180 000180 000018 00 AX 0 0 16 -# ELF2-NEXT: [ 3] .comment PROGBITS 0000000000000000 000198 000071 01 MS 0 0 1 -# ELF2-NEXT: [ 4] .symtab SYMTAB 0000000000000000 000210 000048 18 6 1 8 -# ELF2-NEXT: [ 5] .shstrtab STRTAB 0000000000000000 000258 000034 00 0 0 1 -# ELF2-NEXT: [ 6] .strtab STRTAB 0000000000000000 00028c 00000f 00 0 0 1 -# ELF2-NEXT:Key to Flags: - -#--- a.names.s - - .text - .globl _Z2f12t1 # -- Begin function _Z2f12t1 - .p2align 4, 0x90 - .type _Z2f12t1,@function -_Z2f12t1: # @_Z2f12t1 -.Lfunc_begin0: - .cfi_startproc -# %bb.0: # %entry - pushq %rbp - .cfi_def_cfa_offset 16 - .cfi_offset %rbp, -16 - movq %rsp, %rbp - .cfi_def_cfa_register %rbp -.Ltmp0: - popq %rbp - .cfi_def_cfa %rsp, 8 - retq -.Ltmp1: -.Lfunc_end0: - .size _Z2f12t1, .Lfunc_end0-_Z2f12t1 - .cfi_endproc - # -- End function - .section .debug_info,"",@progbits -.Lcu_begin0: - .byte 0 - .section .debug_str,"MS",@progbits,1 -.Linfo_string0: - .asciz "clang version 19.0.0git (git@github.com:llvm/llvm-project.git dfe787af70e11666a8e43ca73a86d1841d364dfc)" # string offset=0 -.Linfo_string1: - .asciz "a.cpp" # string offset=104 -.Linfo_string2: - .asciz "/proc/self/cwd" # string offset=110 -.Linfo_string3: - .asciz "f1" # string offset=125 -.Linfo_string4: - .asciz "_Z2f12t1" # string offset=128 -.Linfo_string5: - .asciz "t1" # string offset=137 - .section .debug_names,"",@progbits - .long .Lnames_end0-.Lnames_start0 # Header: unit length -.Lnames_start0: - .short 5 # Header: version - .short 0 # Header: padding - .long 1 # Header: compilation unit count - .long 0 # Header: local type unit count - .long 0 # Header: foreign type unit count - .long 3 # Header: bucket count - .long 3 # Header: name count - .long .Lnames_abbrev_end0-.Lnames_abbrev_start0 # Header: abbreviation table size - .long 8 # Header: augmentation string size - .ascii "LLVM0700" # Header: augmentation string - .long .Lcu_begin0 # Compilation unit 0 - .long 0 # Bucket 0 - .long 1 # Bucket 1 - .long 3 # Bucket 2 - .long 5863324 # Hash in Bucket 1 - .long 5863786 # Hash in Bucket 1 - .long 1398125246 # Hash in Bucket 2 - .long .Linfo_string3 # String in Bucket 1: f1 - .long .Linfo_string5 # String in Bucket 1: t1 - .long .Linfo_string4 # String in Bucket 2: _Z2f12t1 - .long .Lnames0-.Lnames_entries0 # Offset in Bucket 1 - .long .Lnames2-.Lnames_entries0 # Offset in Bucket 1 - .long .Lnames1-.Lnames_entries0 # Offset in Bucket 2 -.Lnames_abbrev_start0: - .byte 1 # Abbrev code - .byte 46 # DW_TAG_subprogram - .byte 3 # DW_IDX_die_offset - .byte 19 # DW_FORM_ref4 - .byte 4 # DW_IDX_parent - .byte 25 # DW_FORM_flag_present - .byte 0 # End of abbrev - .byte 0 # End of abbrev - .byte 2 # Abbrev code - .byte 19 # DW_TAG_structure_type - .byte 3 # DW_IDX_die_offset - .byte 19 # DW_FORM_ref4 - .byte 4 # DW_IDX_parent - .byte 25 # DW_FORM_flag_present - .byte 0 # End of abbrev - .byte 0 # End of abbrev - .byte 0 # End of abbrev list -.Lnames_abbrev_end0: -.Lnames_entries0: -.Lnames0: -.L1: - .byte 1 # Abbreviation code - .long 35 # DW_IDX_die_offset - .byte 0 # DW_IDX_parent - # End of list: f1 -.Lnames2: -.L0: - .byte 2 # Abbreviation code - .long 58 # DW_IDX_die_offset - .byte 0 # DW_IDX_parent - # End of list: t1 -.Lnames1: - .byte 1 # Abbreviation code - .long 35 # DW_IDX_die_offset - .byte 0 # DW_IDX_parent - # End of list: _Z2f12t1 - .p2align 2, 0x0 -.Lnames_end0: - .ident "clang version 19.0.0git (git@github.com:llvm/llvm-project.git dfe787af70e11666a8e43ca73a86d1841d364dfc)" - .section ".note.GNU-stack","",@progbits - .addrsig - .section .debug_line,"",@progbits -.Lline_table_start0: - -#--- a.nonames.s - - .text - .globl _Z2f12t1 # -- Begin function _Z2f12t1 - .p2align 4, 0x90 - .type _Z2f12t1,@function -_Z2f12t1: # @_Z2f12t1 - .cfi_startproc -# %bb.0: # %entry - pushq %rbp - .cfi_def_cfa_offset 16 - .cfi_offset %rbp, -16 - movq %rsp, %rbp - .cfi_def_cfa_register %rbp - popq %rbp - .cfi_def_cfa %rsp, 8 - retq -.Lfunc_end0: - .size _Z2f12t1, .Lfunc_end0-_Z2f12t1 - .cfi_endproc - # -- End function - .ident "clang version 19.0.0git (git@github.com:llvm/llvm-project.git dfe787af70e11666a8e43ca73a86d1841d364dfc)" - .section ".note.GNU-stack","",@progbits - .addrsig -#--- b.s +## Test both files without .debug_names. +# RUN: echo '.globl _start; _start:' | llvm-mc -filetype=obj -triple=x86_64 - -o a0.o +# RUN: ld.lld --debug-names a0.o b0.o -o out1 +# RUN: llvm-readelf -SW out1 | FileCheck %s --check-prefix=ELF - .text - .globl main # -- Begin function main - .p2align 4, 0x90 - .type main,@function -main: # @main - .cfi_startproc -# %bb.0: # %entry - pushq %rbp - .cfi_def_cfa_offset 16 - .cfi_offset %rbp, -16 - movq %rsp, %rbp - .cfi_def_cfa_register %rbp - xorl %eax, %eax - popq %rbp - .cfi_def_cfa %rsp, 8 - retq -.Lfunc_end0: - .size main, .Lfunc_end0-main - .cfi_endproc - # -- End function - .ident "clang version 19.0.0git (git@github.com:llvm/llvm-project.git dfe787af70e11666a8e43ca73a86d1841d364dfc)" - .section ".note.GNU-stack","",@progbits - .addrsig +# ELF: Name Type Address Off Size ES Flg Lk Inf Al +# ELF-NOT: .debug_names diff --git a/lld/test/ELF/tools/generate-content.py b/lld/test/ELF/tools/generate-content.py new file mode 100755 index 0000000000000..3665865a257a4 --- /dev/null +++ b/lld/test/ELF/tools/generate-content.py @@ -0,0 +1,82 @@ +#!/usr/bin/env python +"""Given a test file with the following content: + + .ifdef GEN + #--- a.cc + int va; + #--- gen + clang -S -g a.cc -o - + .endif + # content + +The script will replace the content after 'endif' with the stdout of 'gen'. +The extra files are generated in a temporary directory with split-file. + +Example: +PATH=/path/to/clang_build/bin:$PATH tools/generate-debug-names.py debug-names-*.s Inputs/debug-names*.s +""" +import contextlib, os, subprocess, sys, tempfile + + +@contextlib.contextmanager +def cd(dir): + cwd = os.getcwd() + os.chdir(dir) + try: + yield + finally: + os.chdir(cwd) + + +def process(path): + split_file_input = [] + prolog = [] + is_cc = False + is_prolog = True + with open(path) as f: + for line in f.readlines(): + line = line.rstrip() + if is_prolog: + prolog.append(line) + if line.startswith(".endif"): + is_cc = is_prolog = False + if is_cc: + split_file_input.append(line) + if line.startswith(".ifdef GEN"): + is_cc = True + + if not split_file_input: + print("no .ifdef GEN, bail out", file=sys.stderr) + return + with tempfile.TemporaryDirectory() as dir: + sub = subprocess.run( + ["split-file", "-", dir], + input="\n".join(split_file_input).encode(), + capture_output=True, + ) + if sub.returncode != 0: + sys.stderr.write(f"split-file failed\n{sub.stderr.decode()}") + return + with cd(dir): + if not os.path.exists("gen"): + print("'gen' not found", file=sys.stderr) + return + + env = dict( + os.environ, CCC_OVERRIDE_OPTIONS="+-fno-ident", PWD="/proc/self/cwd" + ) + sub = subprocess.run(["zsh", "gen"], capture_output=True, env=env) + if sub.returncode != 0: + sys.stderr.write(f"'gen' failed\n{sub.stderr.decode()}") + return + content = sub.stdout.decode() + + with open(path, "w") as f: + # Print lines up to '.endif'. + print("\n".join(prolog), file=f) + # Then print the stdout of 'gen'. + f.write(content) + + +for path in sys.argv[1:]: + process(path) From fe196b7e40401f818872e9768e840d87066a3ee4 Mon Sep 17 00:00:00 2001 From: Caroline Tice Date: Tue, 16 Apr 2024 23:04:35 -0700 Subject: [PATCH 30/37] [lld][ELF] Minor fixes addressing review comments. - Update comment about CompUnits in OutputChunk. - Replace two uses of 'seq' in for-loops. - Replace use of memcpy with llvm::copy. --- lld/ELF/SyntheticSections.cpp | 13 +++++-------- lld/ELF/SyntheticSections.h | 6 ++---- 2 files changed, 7 insertions(+), 12 deletions(-) diff --git a/lld/ELF/SyntheticSections.cpp b/lld/ELF/SyntheticSections.cpp index 8ce4ef6e36852..33e292f5d4792 100644 --- a/lld/ELF/SyntheticSections.cpp +++ b/lld/ELF/SyntheticSections.cpp @@ -3077,11 +3077,9 @@ std::pair DebugNamesBaseSection::computeEntryPool( // Abbrevs are indexed starting at 1; vector starts at 0. (abbrevCode // corresponds to position in the merged table vector). const Abbrev *abbrev = abbrevTable[ie.abbrevCode - 1]; - for (auto i : seq(abbrev->attributes.size())) { - DWARFDebugNames::AttributeEncoding a = abbrev->attributes[i]; + for (auto &[a, v] : zip_equal(abbrev->attributes, ie.attrValues)) if (a.Index == DW_IDX_parent && a.Form == DW_FORM_ref4) - ie.attrValues[i].attrValue = ie.parentEntry->poolOffset; - } + v.attrValue = ie.parentEntry->poolOfset; } } }); @@ -3232,8 +3230,8 @@ template void DebugNamesSection::writeTo(uint8_t *buf) { buf += hdr.AugmentationStringSize; // Write the CU list. - for (auto i : seq(numChunks)) - for (uint32_t cuOffset : chunks[i].compUnits) + for (OutputChunk &chunk : chunks) + for (uint32_t cuOffset : chunk.compUnits) endian::writeNext(buf, cuOffset); // Write the local TU list, then the foreign TU list.. @@ -3275,8 +3273,7 @@ template void DebugNamesSection::writeTo(uint8_t *buf) { endian::writeNext(buf, ne->entryOffset); // Write the abbrev table. - memcpy(buf, abbrevTableBuf.data(), abbrevTableBuf.size()); - buf += abbrevTableBuf.size(); + buf = llvm::copy(abbrevTableBuf, buf); // Write the entry pool. Unlike the name table, the name entries follow the // nameVecs order computed by `computeEntryPool`. diff --git a/lld/ELF/SyntheticSections.h b/lld/ELF/SyntheticSections.h index 497ff3a62b61a..91babfb92da61 100644 --- a/lld/ELF/SyntheticSections.h +++ b/lld/ELF/SyntheticSections.h @@ -858,10 +858,8 @@ class DebugNamesBaseSection : public SyntheticSection { // Pointer to the .debug_info section that contains compile units, used to // compute the relocated CU offsets. InputSection *infoSec; - // This initially holds section offsets, which may not be consecutive if - // there are multiple name indices in an input .debug_names section. After - // relocation, the section offsets are changed to CU offsets relative to the - // output section. + // This initially holds section offsets. After relocation, the section + // offsets are changed to CU offsets relative the the output section. SmallVector compUnits; }; From cee8c29b25861c7eaf223bf9eceac0b7be81b394 Mon Sep 17 00:00:00 2001 From: Caroline Tice Date: Tue, 16 Apr 2024 23:46:47 -0700 Subject: [PATCH 31/37] [lld][ELF] Fixes to previous fixes. Fix typo, add 'const', replace one use of 'seq'/ --- lld/ELF/SyntheticSections.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/lld/ELF/SyntheticSections.cpp b/lld/ELF/SyntheticSections.cpp index 33e292f5d4792..98f1f68d05c41 100644 --- a/lld/ELF/SyntheticSections.cpp +++ b/lld/ELF/SyntheticSections.cpp @@ -3077,9 +3077,9 @@ std::pair DebugNamesBaseSection::computeEntryPool( // Abbrevs are indexed starting at 1; vector starts at 0. (abbrevCode // corresponds to position in the merged table vector). const Abbrev *abbrev = abbrevTable[ie.abbrevCode - 1]; - for (auto &[a, v] : zip_equal(abbrev->attributes, ie.attrValues)) + for (const auto &[a, v] : zip_equal(abbrev->attributes, ie.attrValues)) if (a.Index == DW_IDX_parent && a.Form == DW_FORM_ref4) - v.attrValue = ie.parentEntry->poolOfset; + v.attrValue = ie.parentEntry->poolOffset; } } }); @@ -3230,8 +3230,8 @@ template void DebugNamesSection::writeTo(uint8_t *buf) { buf += hdr.AugmentationStringSize; // Write the CU list. - for (OutputChunk &chunk : chunks) - for (uint32_t cuOffset : chunk.compUnits) + for (auto i : seq(numChunks)) + for (uint32_t cuOffset : chunks[i].compUnits) endian::writeNext(buf, cuOffset); // Write the local TU list, then the foreign TU list.. From f3700800cedfb1ae2d63d5759b6216c3f84e17b8 Mon Sep 17 00:00:00 2001 From: Caroline Tice Date: Wed, 17 Apr 2024 13:46:45 -0700 Subject: [PATCH 32/37] [lld][ELF] Update code related to type units. - Keep type unit counts in output header at zero, regardless of input, to avoid crashing LLD, since we're not actually handling type units yet. - Move the type units warning to the point where we can check the input counts. - Add a type units test (that LLD doesn't crash and outputs the warning). --- lld/ELF/SyntheticSections.cpp | 18 +- lld/test/ELF/debug-names-tus.s | 528 +++++++++++++++++++++++++++++++++ 2 files changed, 539 insertions(+), 7 deletions(-) create mode 100644 lld/test/ELF/debug-names-tus.s diff --git a/lld/ELF/SyntheticSections.cpp b/lld/ELF/SyntheticSections.cpp index 98f1f68d05c41..606099cbe3b31 100644 --- a/lld/ELF/SyntheticSections.cpp +++ b/lld/ELF/SyntheticSections.cpp @@ -2904,8 +2904,15 @@ void DebugNamesBaseSection::computeHdrAndAbbrevTable( numCu += chunks[i].compUnits.size(); for (const NameData &nd : inputChunk.nameData) { hdr.CompUnitCount += nd.hdr.CompUnitCount; - hdr.LocalTypeUnitCount += nd.hdr.LocalTypeUnitCount; - hdr.ForeignTypeUnitCount += nd.hdr.ForeignTypeUnitCount; + // We are not actually handling or emitting type units yet, so + // so non-zero type unit counts will crash LLD. + // TODO: Uncomment the two lines below when we implement this for + // type units & remove the following check/warning. + //hdr.LocalTypeUnitCount += nd.hdr.LocalTypeUnitCount; + //hdr.ForeignTypeUnitCount += nd.hdr.ForeignTypeUnitCount; + if (nd.hdr.LocalTypeUnitCount || nd. hdr.ForeignTypeUnitCount) + warn(toString(inputChunk.section.sec) + + Twine(": type units are not implemented")); // If augmentation strings are not identical, use an empty string. if (i == 0) { hdr.AugmentationStringSize = nd.hdr.AugmentationStringSize; @@ -3039,7 +3046,7 @@ std::pair DebugNamesBaseSection::computeEntryPool( } }); - // Compute entry offsets in parallel. First, comptute offsets relative to the + // Compute entry offsets in parallel. First, compute offsets relative to the // current shard. uint32_t offsets[numShards]; parallelFor(0, numShards, [&](size_t shard) { @@ -3234,10 +3241,7 @@ template void DebugNamesSection::writeTo(uint8_t *buf) { for (uint32_t cuOffset : chunks[i].compUnits) endian::writeNext(buf, cuOffset); - // Write the local TU list, then the foreign TU list.. - // TODO: Fix this, once we get everything working without TUs. - if (hdr.LocalTypeUnitCount || hdr.ForeignTypeUnitCount) - warn(".debug_names: type units are not implemented"); + // TODO: Write the local TU list, then the foreign TU list.. // Write the hash lookup table. SmallVector, 0> buckets(hdr.BucketCount); diff --git a/lld/test/ELF/debug-names-tus.s b/lld/test/ELF/debug-names-tus.s new file mode 100644 index 0000000000000..a97e54a28c187 --- /dev/null +++ b/lld/test/ELF/debug-names-tus.s @@ -0,0 +1,528 @@ +# The .s files were generated with: + +# clang++ -g -gpubnames -fdebug-compilation-dir='/proc/self/cwd' \ +# -fdebug-types-section -S a.cpp -o a.tu.s + +# clang++ -g -gpubnames -fdebug-compilation-dir='/proc/self/cwd' \ +# -fdebug-types-section -gsplit-dwarf -S a.cpp -o a.foreign-tu.s + +# clang++ -g -gpubnames -fdebug-compilation-dir='/proc/self/cwd' \ +# -S b.cpp -o b.s + +# a.cpp contents: + +# struct t1 { }; +# void f1(t1) { } + +# b.cpp contents: + +# struct t1 { }; +# int main() { +# t1 v1; +# } +# + +# REQUIRES: x86 +# RUN: rm -rf %t && split-file %s %t && cd %t +# RUN: llvm-mc -filetype=obj -triple=x86_64 a.tu.s -o a.tu.o +# RUN: llvm-mc -filetype=obj -triple=x86_64 a.foreign-tu.s -o a.foreign-tu.o +# RUN: llvm-mc -filetype=obj -triple=x86_64 b.s -o b.o + +# RUN: ld.lld --debug-names a.tu.o b.o -o out0 2>&1 \ +# RUN: | FileCheck --check-prefix=WARN %s +# RUN: llvm-dwarfdump --debug-names out0 | FileCheck --check-prefix=DWARF %s + +# WARN: warning: a.tu.o:(.debug_names): type units are not implemented + +# DWARF:Name Index @ 0x0 { +# DWARF: Compilation Unit offsets [ +# DWARF-NEXT: CU[0]: +# DWARF-SAME: 0x00000004 +# DWARF-NEXT: CU[1]: +# DWARF-SAME: 0x00000008 +# DWARF-NEXT: ] +# DWARF-NEXT: Abbreviations [ +# DWARF-NEXT: Abbreviation 0x1 { +# DWARF-NEXT: Tag: DW_TAG_structure_type +# DWARF-NEXT: DW_IDX_type_unit: DW_FORM_data1 +# DWARF-NEXT: DW_IDX_die_offset: DW_FORM_ref4 +# DWARF-NEXT: DW_IDX_parent: DW_FORM_flag_present +# DWARF-NEXT: DW_IDX_compile_unit: DW_FORM_data1 +# DWARF-NEXT: } + + +# RUN: ld.lld --debug-names a.foreign-tu.o b.o -o out1 2>&1 \ +# RUN: | FileCheck %s --check-prefix=WARN2 +# RUN: llvm-dwarfdump --debug-names out1 | FileCheck --check-prefix=DWARF2 %s + +# WARN2: warning: a.foreign-tu.o:(.debug_names): type units are not implemented + +# DWARF2:Name Index @ 0x0 { +# DWARF2: Compilation Unit offsets [ +# DWARF2-NEXT: CU[0]: +# DWARF2-SAME: 0x00000000 +# DWARF2-NEXT: CU[1]: +# DWARF2-SAME: 0x00000001 +# DWARF2-NEXT: ] +# DWARF2-NEXT: Abbreviations [ +# DWARF2-NEXT: Abbreviation 0x1 { +# DWARF2-NEXT: Tag: DW_TAG_structure_type +# DWARF2-NEXT: DW_IDX_type_unit: DW_FORM_data1 +# DWARF2-NEXT: DW_IDX_die_offset: DW_FORM_ref4 +# DWARF2-NEXT: DW_IDX_parent: DW_FORM_flag_present +# DWARF2-NEXT: DW_IDX_compile_unit: DW_FORM_data1 +# DWARF2-NEXT: } + + +#--- a.tu.s + .text + .globl _Z2f12t1 # -- Begin function _Z2f12t1 + .p2align 4, 0x90 + .type _Z2f12t1,@function +_Z2f12t1: # @_Z2f12t1 +.Lfunc_begin0: + .cfi_startproc +# %bb.0: # %entry + pushq %rbp + .cfi_def_cfa_offset 16 + .cfi_offset %rbp, -16 + movq %rsp, %rbp + .cfi_def_cfa_register %rbp +.Ltmp0: + popq %rbp + .cfi_def_cfa %rsp, 8 + retq +.Ltmp1: +.Lfunc_end0: + .size _Z2f12t1, .Lfunc_end0-_Z2f12t1 + .cfi_endproc + # -- End function + .section .debug_info,"G",@progbits,14297044602779165170,comdat +.Ltu_begin0: + .long .Ldebug_info_end0-.Ldebug_info_start0 # Length of Unit +.Ldebug_info_start0: +.Ldebug_info_end0: + .section .debug_info,"",@progbits +.Lcu_begin0: + .long .Ldebug_info_end1-.Ldebug_info_start1 # Length of Unit +.Ldebug_info_start1: +.Ldebug_info_end1: + .section .debug_str,"MS",@progbits,1 +.Linfo_string0: + .asciz "clang version 19.0.0git (git@github.com:llvm/llvm-project.git d12762cdb6357915e0f6f6dbfc09c2c75d746ee7)" # string offset=0 +.Linfo_string1: + .asciz "a.cpp" # string offset=104 +.Linfo_string2: + .asciz "debug-names-test" # string offset=110 +.Linfo_string3: + .asciz "f1" # string offset=127 +.Linfo_string4: + .asciz "_Z2f12t1" # string offset=130 +.Linfo_string5: + .asciz "t1" # string offset=139 + .section .debug_names,"",@progbits + .long .Lnames_end0-.Lnames_start0 # Header: unit length +.Lnames_start0: + .short 5 # Header: version + .short 0 # Header: padding + .long 1 # Header: compilation unit count + .long 1 # Header: local type unit count + .long 0 # Header: foreign type unit count + .long 3 # Header: bucket count + .long 3 # Header: name count + .long .Lnames_abbrev_end0-.Lnames_abbrev_start0 # Header: abbreviation table size + .long 8 # Header: augmentation string size + .ascii "LLVM0700" # Header: augmentation string + .long .Lcu_begin0 # Compilation unit 0 + .long .Ltu_begin0 # Type unit 0 + .long 0 # Bucket 0 + .long 1 # Bucket 1 + .long 3 # Bucket 2 + .long 5863324 # Hash in Bucket 1 + .long 5863786 # Hash in Bucket 1 + .long 1398125246 # Hash in Bucket 2 + .long .Linfo_string3 # String in Bucket 1: f1 + .long .Linfo_string5 # String in Bucket 1: t1 + .long .Linfo_string4 # String in Bucket 2: _Z2f12t1 + .long .Lnames0-.Lnames_entries0 # Offset in Bucket 1 + .long .Lnames2-.Lnames_entries0 # Offset in Bucket 1 + .long .Lnames1-.Lnames_entries0 # Offset in Bucket 2 +.Lnames_abbrev_start0: + .byte 1 # Abbrev code + .byte 46 # DW_TAG_subprogram + .byte 3 # DW_IDX_die_offset + .byte 19 # DW_FORM_ref4 + .byte 4 # DW_IDX_parent + .byte 25 # DW_FORM_flag_present + .byte 0 # End of abbrev + .byte 0 # End of abbrev + .byte 2 # Abbrev code + .byte 19 # DW_TAG_structure_type + .byte 2 # DW_IDX_type_unit + .byte 11 # DW_FORM_data1 + .byte 3 # DW_IDX_die_offset + .byte 19 # DW_FORM_ref4 + .byte 4 # DW_IDX_parent + .byte 25 # DW_FORM_flag_present + .byte 0 # End of abbrev + .byte 0 # End of abbrev + .byte 3 # Abbrev code + .byte 19 # DW_TAG_structure_type + .byte 3 # DW_IDX_die_offset + .byte 19 # DW_FORM_ref4 + .byte 4 # DW_IDX_parent + .byte 25 # DW_FORM_flag_present + .byte 0 # End of abbrev + .byte 0 # End of abbrev + .byte 0 # End of abbrev list +.Lnames_abbrev_end0: +.Lnames_entries0: +.Lnames0: +.L1: + .byte 1 # Abbreviation code + .long 35 # DW_IDX_die_offset + .byte 0 # DW_IDX_parent + # End of list: f1 +.Lnames2: + .byte 2 # Abbreviation code + .byte 0 # DW_IDX_type_unit + .long 35 # DW_IDX_die_offset +.L0: # DW_IDX_parent + .byte 3 # Abbreviation code + .long 58 # DW_IDX_die_offset + .byte 0 # DW_IDX_parent + # End of list: t1 +.Lnames1: + .byte 1 # Abbreviation code + .long 35 # DW_IDX_die_offset + .byte 0 # DW_IDX_parent + # End of list: _Z2f12t1 + .p2align 2, 0x0 +.Lnames_end0: + .ident "clang version 19.0.0git (git@github.com:llvm/llvm-project.git d12762cdb6357915e0f6f6dbfc09c2c75d746ee7)" + .section ".note.GNU-stack","",@progbits + .addrsig + .section .debug_line,"",@progbits +.Lline_table_start0: + + +#--- a.foreign-tu.s + .text + .globl _Z2f12t1 # -- Begin function _Z2f12t1 + .p2align 4, 0x90 + .type _Z2f12t1,@function +_Z2f12t1: # @_Z2f12t1 +.Lfunc_begin0: + .cfi_startproc +# %bb.0: # %entry + pushq %rbp + .cfi_def_cfa_offset 16 + .cfi_offset %rbp, -16 + movq %rsp, %rbp + .cfi_def_cfa_register %rbp +.Ltmp0: + popq %rbp + .cfi_def_cfa %rsp, 8 + retq +.Ltmp1: +.Lfunc_end0: + .size _Z2f12t1, .Lfunc_end0-_Z2f12t1 + .cfi_endproc + # -- End function + .section .debug_info.dwo,"e",@progbits + .byte 0 + .section .debug_info,"",@progbits +.Lcu_begin0: + .byte 0 + .section .debug_str,"MS",@progbits,1 +.Lskel_string0: + .asciz "debug-names-test" # string offset=0 +.Lskel_string1: + .asciz "f1" # string offset=17 +.Lskel_string2: + .asciz "_Z2f12t1" # string offset=20 +.Lskel_string3: + .asciz "t1" # string offset=29 +.Lskel_string4: + .asciz "a.dwo" # string offset=32 + .section .debug_str.dwo,"eMS",@progbits,1 +.Linfo_string0: + .asciz "_Z2f12t1" # string offset=0 +.Linfo_string1: + .asciz "f1" # string offset=9 +.Linfo_string2: + .asciz "debug-names-test" # string offset=12 +.Linfo_string3: + .asciz "a.dwo" # string offset=29 +.Linfo_string4: + .asciz "t1" # string offset=35 +.Linfo_string5: + .asciz "clang version 19.0.0git (git@github.com:llvm/llvm-project.git d12762cdb6357915e0f6f6dbfc09c2c75d746ee7)" # string offset=38 +.Linfo_string6: + .asciz "a.cpp" # string offset=142 + .section .debug_info.dwo,"e",@progbits + .byte 0 + .section .debug_line.dwo,"e",@progbits +.Ltmp2: + .long .Ldebug_line_end0-.Ldebug_line_start0 # unit length +.Ldebug_line_start0: + .short 5 + .byte 8 + .byte 0 + .long .Lprologue_end0-.Lprologue_start0 +.Lprologue_start0: + .byte 1 + .byte 1 + .byte 1 + .byte -5 + .byte 14 + .byte 1 + .byte 1 + .byte 1 + .byte 8 + .byte 1 + .ascii "debug-names-test" + .byte 0 + .byte 3 + .byte 1 + .byte 8 + .byte 2 + .byte 15 + .byte 5 + .byte 30 + .byte 1 + .ascii "a.cpp" + .byte 0 + .byte 0 + .byte 0x5e, 0xc4, 0x4d, 0x3b + .byte 0x78, 0xd0, 0x2a, 0x57 + .byte 0xd2, 0x75, 0xc1, 0x22 + .byte 0x36, 0xb7, 0x17, 0xbf +.Lprologue_end0: +.Ldebug_line_end0: + .section .debug_names,"",@progbits + .long .Lnames_end0-.Lnames_start0 # Header: unit length +.Lnames_start0: + .short 5 # Header: version + .short 0 # Header: padding + .long 1 # Header: compilation unit count + .long 0 # Header: local type unit count + .long 1 # Header: foreign type unit count + .long 3 # Header: bucket count + .long 3 # Header: name count + .long .Lnames_abbrev_end0-.Lnames_abbrev_start0 # Header: abbreviation table size + .long 8 # Header: augmentation string size + .ascii "LLVM0700" # Header: augmentation string + .long .Lcu_begin0 # Compilation unit 0 + .quad -4149699470930386446 # Type unit 0 + .long 0 # Bucket 0 + .long 1 # Bucket 1 + .long 3 # Bucket 2 + .long 5863324 # Hash in Bucket 1 + .long 5863786 # Hash in Bucket 1 + .long 1398125246 # Hash in Bucket 2 + .long .Lskel_string1 # String in Bucket 1: f1 + .long .Lskel_string3 # String in Bucket 1: t1 + .long .Lskel_string2 # String in Bucket 2: _Z2f12t1 + .long .Lnames0-.Lnames_entries0 # Offset in Bucket 1 + .long .Lnames2-.Lnames_entries0 # Offset in Bucket 1 + .long .Lnames1-.Lnames_entries0 # Offset in Bucket 2 +.Lnames_abbrev_start0: + .byte 1 # Abbrev code + .byte 46 # DW_TAG_subprogram + .byte 3 # DW_IDX_die_offset + .byte 19 # DW_FORM_ref4 + .byte 4 # DW_IDX_parent + .byte 25 # DW_FORM_flag_present + .byte 0 # End of abbrev + .byte 0 # End of abbrev + .byte 2 # Abbrev code + .byte 19 # DW_TAG_structure_type + .byte 2 # DW_IDX_type_unit + .byte 11 # DW_FORM_data1 + .byte 3 # DW_IDX_die_offset + .byte 19 # DW_FORM_ref4 + .byte 4 # DW_IDX_parent + .byte 25 # DW_FORM_flag_present + .byte 0 # End of abbrev + .byte 0 # End of abbrev + .byte 3 # Abbrev code + .byte 19 # DW_TAG_structure_type + .byte 3 # DW_IDX_die_offset + .byte 19 # DW_FORM_ref4 + .byte 4 # DW_IDX_parent + .byte 25 # DW_FORM_flag_present + .byte 0 # End of abbrev + .byte 0 # End of abbrev + .byte 0 # End of abbrev list +.Lnames_abbrev_end0: +.Lnames_entries0: +.Lnames0: +.L0: + .byte 1 # Abbreviation code + .long 26 # DW_IDX_die_offset + .byte 0 # DW_IDX_parent + # End of list: f1 +.Lnames2: +.L1: + .byte 2 # Abbreviation code + .byte 0 # DW_IDX_type_unit + .long 33 # DW_IDX_die_offset +.L2: # DW_IDX_parent + .byte 3 # Abbreviation code + .long 49 # DW_IDX_die_offset + .byte 0 # DW_IDX_parent + # End of list: t1 +.Lnames1: + .byte 1 # Abbreviation code + .long 26 # DW_IDX_die_offset + .byte 0 # DW_IDX_parent + # End of list: _Z2f12t1 + .p2align 2, 0x0 +.Lnames_end0: + .ident "clang version 19.0.0git (git@github.com:llvm/llvm-project.git d12762cdb6357915e0f6f6dbfc09c2c75d746ee7)" + .section ".note.GNU-stack","",@progbits + .addrsig + .section .debug_line,"",@progbits +.Lline_table_start0: + +#--- b.s + + .text + .globl main # -- Begin function main + .p2align 4, 0x90 + .type main,@function +main: # @main +.Lfunc_begin0: + .cfi_startproc +# %bb.0: # %entry + pushq %rbp + .cfi_def_cfa_offset 16 + .cfi_offset %rbp, -16 + movq %rsp, %rbp + .cfi_def_cfa_register %rbp +.Ltmp0: + xorl %eax, %eax + popq %rbp + .cfi_def_cfa %rsp, 8 + retq +.Ltmp1: +.Lfunc_end0: + .size main, .Lfunc_end0-main + .cfi_endproc + # -- End function + .section .debug_abbrev,"",@progbits + .byte 0 # EOM(1) + .byte 0 # EOM(2) + .byte 0 # EOM(3) + .section .debug_info,"",@progbits +.Lcu_begin0: + .long .Ldebug_info_end0-.Ldebug_info_start0 # Length of Unit +.Ldebug_info_start0: + .short 5 # DWARF version number + .byte 1 # DWARF Unit Type + .byte 8 # Address Size (in bytes) + .long .debug_abbrev # Offset Into Abbrev. Section +.Ldebug_info_end0: + .section .debug_str_offsets,"",@progbits + .long 32 # Length of String Offsets Set + .short 5 + .short 0 +.Lstr_offsets_base0: + .section .debug_str,"MS",@progbits,1 +.Linfo_string0: + .asciz "clang version 19.0.0git (git@github.com:llvm/llvm-project.git 53b14cd9ce2b57da73d173fc876d2e9e199f5640)" # string offset=0 +.Linfo_string1: + .asciz "b.cpp" # string offset=104 +.Linfo_string2: + .asciz "/proc/self/cwd" # string offset=110 +.Linfo_string3: + .asciz "main" # string offset=125 +.Linfo_string4: + .asciz "int" # string offset=130 +.Linfo_string5: + .asciz "v1" # string offset=134 +.Linfo_string6: + .asciz "t1" # string offset=137 +.Laddr_table_base0: + .quad .Lfunc_begin0 +.Ldebug_addr_end0: + .section .debug_names,"",@progbits + .long .Lnames_end0-.Lnames_start0 # Header: unit length +.Lnames_start0: + .short 5 # Header: version + .short 0 # Header: padding + .long 1 # Header: compilation unit count + .long 0 # Header: local type unit count + .long 0 # Header: foreign type unit count + .long 3 # Header: bucket count + .long 3 # Header: name count + .long .Lnames_abbrev_end0-.Lnames_abbrev_start0 # Header: abbreviation table size + .long 8 # Header: augmentation string size + .ascii "LLVM0700" # Header: augmentation string + .long .Lcu_begin0 # Compilation unit 0 + .long 0 # Bucket 0 + .long 1 # Bucket 1 + .long 3 # Bucket 2 + .long 5863786 # Hash in Bucket 1 + .long 2090499946 # Hash in Bucket 1 + .long 193495088 # Hash in Bucket 2 + .long .Linfo_string6 # String in Bucket 1: t1 + .long .Linfo_string3 # String in Bucket 1: main + .long .Linfo_string4 # String in Bucket 2: int + .long .Lnames2-.Lnames_entries0 # Offset in Bucket 1 + .long .Lnames0-.Lnames_entries0 # Offset in Bucket 1 + .long .Lnames1-.Lnames_entries0 # Offset in Bucket 2 +.Lnames_abbrev_start0: + .byte 1 # Abbrev code + .byte 19 # DW_TAG_structure_type + .byte 3 # DW_IDX_die_offset + .byte 19 # DW_FORM_ref4 + .byte 4 # DW_IDX_parent + .byte 25 # DW_FORM_flag_present + .byte 0 # End of abbrev + .byte 0 # End of abbrev + .byte 2 # Abbrev code + .byte 46 # DW_TAG_subprogram + .byte 3 # DW_IDX_die_offset + .byte 19 # DW_FORM_ref4 + .byte 4 # DW_IDX_parent + .byte 25 # DW_FORM_flag_present + .byte 0 # End of abbrev + .byte 0 # End of abbrev + .byte 3 # Abbrev code + .byte 36 # DW_TAG_base_type + .byte 3 # DW_IDX_die_offset + .byte 19 # DW_FORM_ref4 + .byte 4 # DW_IDX_parent + .byte 25 # DW_FORM_flag_present + .byte 0 # End of abbrev + .byte 0 # End of abbrev + .byte 0 # End of abbrev list +.Lnames_abbrev_end0: +.Lnames_entries0: +.Lnames2: +.L1: + .byte 1 # Abbreviation code + .long 66 # DW_IDX_die_offset + .byte 0 # DW_IDX_parent + # End of list: t1 +.Lnames0: +.L2: + .byte 2 # Abbreviation code + .long 35 # DW_IDX_die_offset + .byte 0 # DW_IDX_parent + # End of list: main +.Lnames1: +.L0: + .byte 3 # Abbreviation code + .long 62 # DW_IDX_die_offset + .byte 0 # DW_IDX_parent + # End of list: int + .p2align 2, 0x0 +.Lnames_end0: + .ident "clang version 19.0.0git (git@github.com:llvm/llvm-project.git 53b14cd9ce2b57da73d173fc876d2e9e199f5640)" + .section ".note.GNU-stack","",@progbits + .addrsig + .section .debug_line,"",@progbits +.Lline_table_start0: From ac233d46a3f36dc55690e4a5c2feb21de50b09bc Mon Sep 17 00:00:00 2001 From: Fangrui Song Date: Wed, 17 Apr 2024 14:38:58 -0700 Subject: [PATCH 33/37] Clean up more tests Remove tools/generate-content.py. We will use a generic tool intended for llvm/utils: https://discourse.llvm.org/t/utility-to-generate-elaborated-assembly-ir-tests/78408 --- lld/test/ELF/Inputs/debug-names-a.s | 2 +- lld/test/ELF/Inputs/debug-names-b.s | 2 +- lld/test/ELF/Inputs/debug-names-bcd.s | 2 +- lld/test/ELF/Inputs/debug-names-ef.s | 2 +- lld/test/ELF/debug-names-bad.s | 6 + lld/test/ELF/debug-names-invalid-parent-idx.s | 153 --------- lld/test/ELF/debug-names-missing-parent.s | 298 +++++++++--------- lld/test/ELF/tools/generate-content.py | 82 ----- 8 files changed, 164 insertions(+), 383 deletions(-) delete mode 100644 lld/test/ELF/debug-names-invalid-parent-idx.s delete mode 100755 lld/test/ELF/tools/generate-content.py diff --git a/lld/test/ELF/Inputs/debug-names-a.s b/lld/test/ELF/Inputs/debug-names-a.s index 32fe3b88b0433..0adc520e765ca 100644 --- a/lld/test/ELF/Inputs/debug-names-a.s +++ b/lld/test/ELF/Inputs/debug-names-a.s @@ -3,7 +3,7 @@ struct t1 {}; extern "C" void _start(t1) {} #--- gen -clang -S -g -gpubnames a.cc -o - +clang --target=x86_64-linux -S -g -gpubnames a.cc -o - .endif .text .file "a.cc" diff --git a/lld/test/ELF/Inputs/debug-names-b.s b/lld/test/ELF/Inputs/debug-names-b.s index 938a44690ee91..2e3996742020b 100644 --- a/lld/test/ELF/Inputs/debug-names-b.s +++ b/lld/test/ELF/Inputs/debug-names-b.s @@ -6,7 +6,7 @@ struct t2 {}; } int main() { t1 v1; ns::t2 v2; } #--- gen -clang -S -g -gpubnames b.cc -o - +clang --target=x86_64-linux -S -g -gpubnames b.cc -o - .endif .text .file "b.cc" diff --git a/lld/test/ELF/Inputs/debug-names-bcd.s b/lld/test/ELF/Inputs/debug-names-bcd.s index 690485515b6c0..4f40ed4d15bfd 100644 --- a/lld/test/ELF/Inputs/debug-names-bcd.s +++ b/lld/test/ELF/Inputs/debug-names-bcd.s @@ -8,7 +8,7 @@ namespace ns { [[gnu::used]] int vd; } //--- gen -clang -O1 -g -gpubnames -flto b.cc c.cc d.cc -nostdlib -fuse-ld=lld -Wl,--lto-emit-asm +clang --target=x86_64-linux -O1 -g -gpubnames -flto b.cc c.cc d.cc -nostdlib -fuse-ld=lld -Wl,--lto-emit-asm cat a.out.lto.s .endif .text diff --git a/lld/test/ELF/Inputs/debug-names-ef.s b/lld/test/ELF/Inputs/debug-names-ef.s index d50f3b131e5f6..b97d41c9e5489 100644 --- a/lld/test/ELF/Inputs/debug-names-ef.s +++ b/lld/test/ELF/Inputs/debug-names-ef.s @@ -6,7 +6,7 @@ namespace ns { [[gnu::used]] int vf; } //--- gen -clang -O1 -g -gpubnames -flto e.cc f.cc -nostdlib -fuse-ld=lld -Wl,--lto-emit-asm +clang --target=x86_64-linux -O1 -g -gpubnames -flto e.cc f.cc -nostdlib -fuse-ld=lld -Wl,--lto-emit-asm cat a.out.lto.s .endif .text diff --git a/lld/test/ELF/debug-names-bad.s b/lld/test/ELF/debug-names-bad.s index 4b0c0b9bbf4e4..9a4441ee3488b 100644 --- a/lld/test/ELF/debug-names-bad.s +++ b/lld/test/ELF/debug-names-bad.s @@ -22,6 +22,12 @@ # ENTRY-OFFSET-IN-BYTE-COUNT-2: error: entry-offset-in-byte.o:(.debug_names): index entry is out of bounds ## Test errors in the abbrev table. +# RUN: sed -E '/DW_IDX_parent/{n;s/[0-9]+.*DW_FORM_flag_present/16/}' %S/Inputs/debug-names-a.s > bad-parent-form.s +# RUN: llvm-mc -filetype=obj -triple=x86_64 bad-parent-form.s -o bad-parent-form.o +# RUN: not ld.lld --debug-names bad-parent-form.o 2>&1 | FileCheck %s --check-prefix=BAD-PARENT-FORM --implicit-check-not=error: + +# BAD-PARENT-FORM: error: bad-parent-form.o:(.debug_names): invalid form for DW_IDX_parent + # RUN: sed -E '/DW_IDX_die_offset/{n;s/[0-9]+.*DW_FORM_ref4/16/}' %S/Inputs/debug-names-a.s > bad-die-form.s # RUN: llvm-mc -filetype=obj -triple=x86_64 bad-die-form.s -o bad-die-form.o # RUN: not ld.lld --debug-names bad-die-form.o 2>&1 | FileCheck %s --check-prefix=BAD-DIE-FORM --implicit-check-not=error: diff --git a/lld/test/ELF/debug-names-invalid-parent-idx.s b/lld/test/ELF/debug-names-invalid-parent-idx.s deleted file mode 100644 index 5db11ee10b32e..0000000000000 --- a/lld/test/ELF/debug-names-invalid-parent-idx.s +++ /dev/null @@ -1,153 +0,0 @@ -# This file was generated by: -# clang++ -g -O0 -S -fdebug-compilation-dir='/proc/self/cwd' \ -# -gpubnames a.cpp - -# Then manually editing .debug_names section, changing the form for a -# DW_IDX_parent from DW_FORM_flag_present to DW_FORM_ref1 (invalid). - -# Contents of a.cpp -# int main (int argc, char **argv) { } - -# REQUIRES: x86 -# RUN: llvm-mc -filetype=obj -triple=x86_64 %s -o %t1.o -# RUN: not ld.lld --debug-names %t1.o -o /dev/null 2>&1 \ -# RUN: | FileCheck -DFILE=%t1.o --implicit-check-not=error: %s - -# CHECK: error: [[FILE]]:(.debug_names): invalid form for DW_IDX_parent -# CHECK: error: [[FILE]]:(.debug_names): invalid form for DW_IDX_parent - - .text - .globl main # -- Begin function main - .p2align 4, 0x90 - .type main,@function -main: # @main -.Lfunc_begin0: - .file 0 "/proc/self/cwd" "a.cpp" md5 0xb5f4ba9cf33ca376f9981b3284aa785f - .cfi_startproc -# %bb.0: # %entry - pushq %rbp - .cfi_def_cfa_offset 16 - .cfi_offset %rbp, -16 - movq %rsp, %rbp - .cfi_def_cfa_register %rbp - movl %edi, -4(%rbp) - movq %rsi, -16(%rbp) -.Ltmp0: - xorl %eax, %eax - popq %rbp - .cfi_def_cfa %rsp, 8 - retq -.Ltmp1: -.Lfunc_end0: - .size main, .Lfunc_end0-main - .cfi_endproc - # -- End function - .section .debug_abbrev,"",@progbits - .byte 0 # EOM(1) - .byte 0 # EOM(2) - .byte 0 # EOM(3) - .section .debug_info,"",@progbits -.Lcu_begin0: - .long .Ldebug_info_end0-.Ldebug_info_start0 # Length of Unit -.Ldebug_info_start0: - .short 5 # DWARF version number - .byte 1 # DWARF Unit Type - .byte 8 # Address Size (in bytes) - .long .debug_abbrev # Offset Into Abbrev. Section -.Ldebug_info_end0: - .section .debug_str_offsets,"",@progbits - .long 36 # Length of String Offsets Set - .short 5 - .short 0 -.Lstr_offsets_base0: - .section .debug_str,"MS",@progbits,1 -.Linfo_string0: - .asciz "clang version 19.0.0git (git@github.com:llvm/llvm-project.git 53b14cd9ce2b57da73d173fc876d2e9e199f5640)" # string offset=0 -.Linfo_string1: - .asciz "a.cpp" # string offset=104 -.Linfo_string2: - .asciz "/proc/self/cwd" # string offset=110 -.Linfo_string3: - .asciz "main" # string offset=125 -.Linfo_string4: - .asciz "int" # string offset=130 -.Linfo_string5: - .asciz "argc" # string offset=134 -.Linfo_string6: - .asciz "argv" # string offset=139 -.Linfo_string7: - .asciz "char" # string offset=144 -.Laddr_table_base0: - .quad .Lfunc_begin0 -.Ldebug_addr_end0: - .section .debug_names,"",@progbits - .long .Lnames_end0-.Lnames_start0 # Header: unit length -.Lnames_start0: - .short 5 # Header: version - .short 0 # Header: padding - .long 1 # Header: compilation unit count - .long 0 # Header: local type unit count - .long 0 # Header: foreign type unit count - .long 3 # Header: bucket count - .long 3 # Header: name count - .long .Lnames_abbrev_end0-.Lnames_abbrev_start0 # Header: abbreviation table size - .long 8 # Header: augmentation string size - .ascii "LLVM0700" # Header: augmentation string - .long .Lcu_begin0 # Compilation unit 0 - .long 0 # Bucket 0 - .long 1 # Bucket 1 - .long 2 # Bucket 2 - .long 2090499946 # Hash in Bucket 1 - .long 193495088 # Hash in Bucket 2 - .long 2090147939 # Hash in Bucket 2 - .long .Linfo_string3 # String in Bucket 1: main - .long .Linfo_string4 # String in Bucket 2: int - .long .Linfo_string7 # String in Bucket 2: char - .long .Lnames0-.Lnames_entries0 # Offset in Bucket 1 - .long .Lnames1-.Lnames_entries0 # Offset in Bucket 2 - .long .Lnames2-.Lnames_entries0 # Offset in Bucket 2 -.Lnames_abbrev_start0: - .byte 1 # Abbrev code - .byte 46 # DW_TAG_subprogram - .byte 3 # DW_IDX_die_offset - .byte 19 # DW_FORM_ref4 - .byte 4 # DW_IDX_parent - .byte 25 # DW_FORM_flag_present - .byte 0 # End of abbrev - .byte 0 # End of abbrev - .byte 2 # Abbrev code - .byte 36 # DW_TAG_base_type - .byte 3 # DW_IDX_die_offset - .byte 19 # DW_FORM_ref4 - .byte 4 # DW_IDX_parent - .byte 17 # DW_FORM_ref1 - .byte 0 # End of abbrev - .byte 0 # End of abbrev - .byte 0 # End of abbrev list -.Lnames_abbrev_end0: -.Lnames_entries0: -.Lnames0: -.L1: - .byte 1 # Abbreviation code - .long 35 # DW_IDX_die_offset - .byte 0 # DW_IDX_parent - # End of list: main -.Lnames1: -.L0: - .byte 2 # Abbreviation code - .long 73 # DW_IDX_die_offset - .byte 0 # DW_IDX_parent - # End of list: int -.Lnames2: -.L2: - .byte 2 # Abbreviation code - .long 87 # DW_IDX_die_offset - .byte 0 # DW_IDX_parent - # End of list: char - .p2align 2, 0x0 -.Lnames_end0: - .ident "clang version 19.0.0git (git@github.com:llvm/llvm-project.git 53b14cd9ce2b57da73d173fc876d2e9e199f5640)" - .section ".note.GNU-stack","",@progbits - .addrsig - .section .debug_line,"",@progbits -.Lline_table_start0: diff --git a/lld/test/ELF/debug-names-missing-parent.s b/lld/test/ELF/debug-names-missing-parent.s index 480d047504934..7140157b01d84 100644 --- a/lld/test/ELF/debug-names-missing-parent.s +++ b/lld/test/ELF/debug-names-missing-parent.s @@ -1,121 +1,106 @@ -# debug-names-missing-parent was generated with - -# clang++ -g -O0 -S -fdebug-compilation-dir='/proc/self/cwd' \ -# -gpubnames a.cpp - -# a.cpp contents: - -# int main (int argc, char **argv) { } - -# Then manually edit the .s file: -# - Remove DW_IDX_parent & DW_FORM_flag_present from DW_TAG_subprogram abbrev -# - Remove DW_IDX_parent value from entry for 'main' - # REQUIRES: x86 -# RUN: llvm-mc -filetype=obj -triple=x86_64 %s -o %t1.o -# RUN: ld.lld --debug-names %t1.o -o %t -# RUN: llvm-dwarfdump --debug-names %t | FileCheck %s --check-prefix=DWARF +## Test clang-17-generated DW_TAG_subprogram, which do not contain DW_IDX_parent +## attributes. -# DWARF: .debug_names contents: -# DWARF: Name Index @ 0x0 { -# DWARF-NEXT: Header { -# DWARF-NEXT: Length: 0x8A -# DWARF-NEXT: Format: DWARF32 -# DWARF-NEXT: Version: 5 -# DWARF-NEXT: CU count: 1 -# DWARF-NEXT: Local TU count: 0 -# DWARF-NEXT: Foreign TU count: 0 -# DWARF-NEXT: Bucket count: 3 -# DWARF-NEXT: Name count: 3 -# DWARF-NEXT: Abbreviations table size: 0x13 -# DWARF-NEXT: Augmentation: 'LLVM0700' -# DWARF: Compilation Unit offsets [ -# DWARF-NEXT: CU[0]: 0x00000000 -# DWARF: Abbreviations [ -# DWARF-NEXT: Abbreviation 0x1 { -# DWARF: Tag: DW_TAG_base_type -# DWARF-NEXT: DW_IDX_die_offset: DW_FORM_ref4 -# DWARF-NEXT: DW_IDX_parent: DW_FORM_flag_present -# DWARF-NEXT: DW_IDX_compile_unit: DW_FORM_data1 -# DWARF: Abbreviation 0x2 { -# DWARF-NEXT: Tag: DW_TAG_subprogram -# DWARF-NEXT: DW_IDX_die_offset: DW_FORM_ref4 -# DWARF-NEXT: DW_IDX_compile_unit: DW_FORM_data1 -# DWARF: Bucket 0 [ -# DWARF-NEXT: EMPTY -# DWARF-NEXT: ] -# DWARF-NEXT: Bucket 1 [ -# DWARF-NEXT: Name 1 { -# DWARF-NEXT: Hash: 0x7C9A7F6A -# DWARF-NEXT: String: 0x0000007d "main" -# DWARF-NEXT: Entry @ 0x7a { -# DWARF-NEXT: Abbrev: 0x2 -# DWARF-NEXT: Tag: DW_TAG_subprogram -# DWARF-NEXT: DW_IDX_die_offset: 0x00000023 -# DWARF-NEXT: DW_IDX_compile_unit: 0x00 -# DWARF-NEXT: } -# DWARF-NEXT: Entry @ 0x80 { -# DWARF-NEXT: Abbrev: 0x1 -# DWARF-NEXT: Tag: DW_TAG_base_type -# DWARF-NEXT: DW_IDX_die_offset: 0x00000049 -# DWARF-NEXT: DW_IDX_parent: -# DWARF-NEXT: DW_IDX_compile_unit: 0x00 -# DWARF-NEXT: } -# DWARF-NEXT: } -# DWARF-NEXT: ] -# DWARF-NEXT: Bucket 2 [ -# DWARF-NEXT: Name 2 { -# DWARF-NEXT: Hash: 0xB888030 -# DWARF-NEXT: String: 0x00000082 "int" -# DWARF-NEXT: Entry @ 0x73 { -# DWARF-NEXT: Abbrev: 0x1 -# DWARF-NEXT: Tag: DW_TAG_base_type -# DWARF-NEXT: DW_IDX_die_offset: 0x00000049 -# DWARF-NEXT: DW_IDX_parent: -# DWARF-NEXT: DW_IDX_compile_unit: 0x00 -# DWARF-NEXT: } -# DWARF-NEXT: } -# DWARF-NEXT: Name 3 { -# DWARF-NEXT: Hash: 0x7C952063 -# DWARF-NEXT: String: 0x0000008b "char" -# DWARF-NEXT: Entry @ 0x87 { -# DWARF-NEXT: Abbrev: 0x1 -# DWARF-NEXT: Tag: DW_TAG_base_type -# DWARF-NEXT: DW_IDX_die_offset: 0x00000057 -# DWARF-NEXT: DW_IDX_parent: -# DWARF-NEXT: DW_IDX_compile_unit: 0x00 -# DWARF-NEXT: } -# DWARF-NEXT: } -# DWARF-NEXT: ] +# RUN: llvm-mc -filetype=obj -triple=x86_64 %s -o %t.o +# RUN: ld.lld --debug-names %t.o -o %t +# RUN: llvm-dwarfdump --debug-info --debug-names %t | FileCheck %s --check-prefix=DWARF -# --- a.s +# DWARF: 0x00000023: DW_TAG_namespace +# DWARF: 0x00000025: DW_TAG_subprogram +# DWARF: String: {{.*}} "fa" +# DWARF-NEXT: Entry @ 0x71 { +# DWARF-NEXT: Abbrev: 0x1 +# DWARF-NEXT: Tag: DW_TAG_subprogram +# DWARF-NEXT: DW_IDX_die_offset: 0x00000025 +# DWARF-NEXT: DW_IDX_compile_unit: 0x00 +# DWARF-NEXT: } +# DWARF: String: {{.*}} "ns" +# DWARF-NEXT: Entry @ 0x78 { +# DWARF-NEXT: Abbrev: 0x2 +# DWARF-NEXT: Tag: DW_TAG_namespace +# DWARF-NEXT: DW_IDX_die_offset: 0x00000023 +# DWARF-NEXT: DW_IDX_compile_unit: 0x00 +# DWARF-NEXT: } + +.ifdef GEN +//--- a.cc +namespace ns { +void fa() {} +} +//--- gen +clang-17 --target=x86_64-linux -S -O1 -g -gpubnames a.cc -o - +.endif .text - .globl main # -- Begin function main + .file "a.cc" + .globl _ZN2ns2faEv # -- Begin function _ZN2ns2faEv .p2align 4, 0x90 - .type main,@function -main: # @main + .type _ZN2ns2faEv,@function +_ZN2ns2faEv: # @_ZN2ns2faEv .Lfunc_begin0: + .file 0 "/proc/self/cwd" "a.cc" md5 0xb3281d5b5a0b2997d7d59d49bc912274 .cfi_startproc -# %bb.0: # %entry - pushq %rbp - .cfi_def_cfa_offset 16 - .cfi_offset %rbp, -16 - movq %rsp, %rbp - .cfi_def_cfa_register %rbp - movl %edi, -4(%rbp) - movq %rsi, -16(%rbp) -.Ltmp0: - xorl %eax, %eax - popq %rbp - .cfi_def_cfa %rsp, 8 +# %bb.0: + .loc 0 2 12 prologue_end # a.cc:2:12 retq -.Ltmp1: +.Ltmp0: .Lfunc_end0: - .size main, .Lfunc_end0-main + .size _ZN2ns2faEv, .Lfunc_end0-_ZN2ns2faEv .cfi_endproc # -- End function .section .debug_abbrev,"",@progbits + .byte 1 # Abbreviation Code + .byte 17 # DW_TAG_compile_unit + .byte 1 # DW_CHILDREN_yes + .byte 37 # DW_AT_producer + .byte 37 # DW_FORM_strx1 + .byte 19 # DW_AT_language + .byte 5 # DW_FORM_data2 + .byte 3 # DW_AT_name + .byte 37 # DW_FORM_strx1 + .byte 114 # DW_AT_str_offsets_base + .byte 23 # DW_FORM_sec_offset + .byte 16 # DW_AT_stmt_list + .byte 23 # DW_FORM_sec_offset + .byte 27 # DW_AT_comp_dir + .byte 37 # DW_FORM_strx1 + .byte 17 # DW_AT_low_pc + .byte 27 # DW_FORM_addrx + .byte 18 # DW_AT_high_pc + .byte 6 # DW_FORM_data4 + .byte 115 # DW_AT_addr_base + .byte 23 # DW_FORM_sec_offset + .byte 0 # EOM(1) + .byte 0 # EOM(2) + .byte 2 # Abbreviation Code + .byte 57 # DW_TAG_namespace + .byte 1 # DW_CHILDREN_yes + .byte 3 # DW_AT_name + .byte 37 # DW_FORM_strx1 + .byte 0 # EOM(1) + .byte 0 # EOM(2) + .byte 3 # Abbreviation Code + .byte 46 # DW_TAG_subprogram + .byte 0 # DW_CHILDREN_no + .byte 17 # DW_AT_low_pc + .byte 27 # DW_FORM_addrx + .byte 18 # DW_AT_high_pc + .byte 6 # DW_FORM_data4 + .byte 64 # DW_AT_frame_base + .byte 24 # DW_FORM_exprloc + .byte 122 # DW_AT_call_all_calls + .byte 25 # DW_FORM_flag_present + .byte 110 # DW_AT_linkage_name + .byte 37 # DW_FORM_strx1 + .byte 3 # DW_AT_name + .byte 37 # DW_FORM_strx1 + .byte 58 # DW_AT_decl_file + .byte 11 # DW_FORM_data1 + .byte 59 # DW_AT_decl_line + .byte 11 # DW_FORM_data1 + .byte 63 # DW_AT_external + .byte 25 # DW_FORM_flag_present .byte 0 # EOM(1) .byte 0 # EOM(2) .byte 0 # EOM(3) @@ -127,30 +112,63 @@ main: # @main .byte 1 # DWARF Unit Type .byte 8 # Address Size (in bytes) .long .debug_abbrev # Offset Into Abbrev. Section + .byte 1 # Abbrev [1] 0xc:0x27 DW_TAG_compile_unit + .byte 0 # DW_AT_producer + .short 33 # DW_AT_language + .byte 1 # DW_AT_name + .long .Lstr_offsets_base0 # DW_AT_str_offsets_base + .long .Lline_table_start0 # DW_AT_stmt_list + .byte 2 # DW_AT_comp_dir + .byte 0 # DW_AT_low_pc + .long .Lfunc_end0-.Lfunc_begin0 # DW_AT_high_pc + .long .Laddr_table_base0 # DW_AT_addr_base + .byte 2 # Abbrev [2] 0x23:0xf DW_TAG_namespace + .byte 3 # DW_AT_name + .byte 3 # Abbrev [3] 0x25:0xc DW_TAG_subprogram + .byte 0 # DW_AT_low_pc + .long .Lfunc_end0-.Lfunc_begin0 # DW_AT_high_pc + .byte 1 # DW_AT_frame_base + .byte 87 + # DW_AT_call_all_calls + .byte 4 # DW_AT_linkage_name + .byte 5 # DW_AT_name + .byte 0 # DW_AT_decl_file + .byte 2 # DW_AT_decl_line + # DW_AT_external + .byte 0 # End Of Children Mark + .byte 0 # End Of Children Mark .Ldebug_info_end0: .section .debug_str_offsets,"",@progbits - .long 36 # Length of String Offsets Set + .long 28 # Length of String Offsets Set .short 5 .short 0 .Lstr_offsets_base0: .section .debug_str,"MS",@progbits,1 .Linfo_string0: - .asciz "clang version 19.0.0git (git@github.com:llvm/llvm-project.git 53b14cd9ce2b57da73d173fc876d2e9e199f5640)" # string offset=0 + .byte 0 # string offset=0 .Linfo_string1: - .asciz "a.cpp" # string offset=104 + .asciz "a.cc" # string offset=1 .Linfo_string2: - .asciz "/proc/self/cwd" # string offset=110 + .asciz "/proc/self/cwd" # string offset=6 .Linfo_string3: - .asciz "main" # string offset=125 + .asciz "ns" # string offset=21 .Linfo_string4: - .asciz "int" # string offset=130 + .asciz "fa" # string offset=24 .Linfo_string5: - .asciz "argc" # string offset=134 -.Linfo_string6: - .asciz "argv" # string offset=139 -.Linfo_string7: - .asciz "char" # string offset=144 + .asciz "_ZN2ns2faEv" # string offset=27 .section .debug_str_offsets,"",@progbits + .long .Linfo_string0 + .long .Linfo_string1 + .long .Linfo_string2 + .long .Linfo_string3 + .long .Linfo_string5 + .long .Linfo_string4 + .section .debug_addr,"",@progbits + .long .Ldebug_addr_end0-.Ldebug_addr_start0 # Length of contribution +.Ldebug_addr_start0: + .short 5 # DWARF version number + .byte 8 # Address size + .byte 0 # Segment selector size .Laddr_table_base0: .quad .Lfunc_begin0 .Ldebug_addr_end0: @@ -170,54 +188,46 @@ main: # @main .long .Lcu_begin0 # Compilation unit 0 .long 0 # Bucket 0 .long 1 # Bucket 1 - .long 2 # Bucket 2 - .long 2090499946 # Hash in Bucket 1 - .long 193495088 # Hash in Bucket 2 - .long 2090147939 # Hash in Bucket 2 - .long .Linfo_string3 # String in Bucket 1: main - .long .Linfo_string4 # String in Bucket 2: int - .long .Linfo_string7 # String in Bucket 2: char + .long 3 # Bucket 2 + .long 5863372 # Hash in Bucket 1 + .long 5863654 # Hash in Bucket 1 + .long -1413999533 # Hash in Bucket 2 + .long .Linfo_string4 # String in Bucket 1: fa + .long .Linfo_string3 # String in Bucket 1: ns + .long .Linfo_string5 # String in Bucket 2: _ZN2ns2faEv + .long .Lnames1-.Lnames_entries0 # Offset in Bucket 1 .long .Lnames0-.Lnames_entries0 # Offset in Bucket 1 - .long .Lnames1-.Lnames_entries0 # Offset in Bucket 2 .long .Lnames2-.Lnames_entries0 # Offset in Bucket 2 .Lnames_abbrev_start0: - .byte 1 # Abbrev code + .byte 46 # Abbrev code .byte 46 # DW_TAG_subprogram .byte 3 # DW_IDX_die_offset .byte 19 # DW_FORM_ref4 .byte 0 # End of abbrev .byte 0 # End of abbrev - .byte 2 # Abbrev code - .byte 36 # DW_TAG_base_type + .byte 57 # Abbrev code + .byte 57 # DW_TAG_namespace .byte 3 # DW_IDX_die_offset .byte 19 # DW_FORM_ref4 - .byte 4 # DW_IDX_parent - .byte 25 # DW_FORM_flag_present .byte 0 # End of abbrev .byte 0 # End of abbrev .byte 0 # End of abbrev list .Lnames_abbrev_end0: .Lnames_entries0: +.Lnames1: + .byte 46 # Abbreviation code + .long 37 # DW_IDX_die_offset + .byte 0 # End of list: fa .Lnames0: -.L1: - .byte 1 # Abbreviation code + .byte 57 # Abbreviation code .long 35 # DW_IDX_die_offset - # End of list: main -.Lnames1: -.L0: - .byte 2 # Abbreviation code - .long 73 # DW_IDX_die_offset - .byte 0 # DW_IDX_parent - # End of list: int + .byte 0 # End of list: ns .Lnames2: -.L2: - .byte 2 # Abbreviation code - .long 87 # DW_IDX_die_offset - .byte 0 # DW_IDX_parent - # End of list: char + .byte 46 # Abbreviation code + .long 37 # DW_IDX_die_offset + .byte 0 # End of list: _ZN2ns2faEv .p2align 2, 0x0 .Lnames_end0: - .ident "clang version 19.0.0git (git@github.com:llvm/llvm-project.git 53b14cd9ce2b57da73d173fc876d2e9e199f5640)" .section ".note.GNU-stack","",@progbits .addrsig .section .debug_line,"",@progbits diff --git a/lld/test/ELF/tools/generate-content.py b/lld/test/ELF/tools/generate-content.py deleted file mode 100755 index 3665865a257a4..0000000000000 --- a/lld/test/ELF/tools/generate-content.py +++ /dev/null @@ -1,82 +0,0 @@ -#!/usr/bin/env python -"""Given a test file with the following content: - - .ifdef GEN - #--- a.cc - int va; - #--- gen - clang -S -g a.cc -o - - .endif - # content - -The script will replace the content after 'endif' with the stdout of 'gen'. -The extra files are generated in a temporary directory with split-file. - -Example: -PATH=/path/to/clang_build/bin:$PATH tools/generate-debug-names.py debug-names-*.s Inputs/debug-names*.s -""" -import contextlib, os, subprocess, sys, tempfile - - -@contextlib.contextmanager -def cd(dir): - cwd = os.getcwd() - os.chdir(dir) - try: - yield - finally: - os.chdir(cwd) - - -def process(path): - split_file_input = [] - prolog = [] - is_cc = False - is_prolog = True - with open(path) as f: - for line in f.readlines(): - line = line.rstrip() - if is_prolog: - prolog.append(line) - if line.startswith(".endif"): - is_cc = is_prolog = False - if is_cc: - split_file_input.append(line) - if line.startswith(".ifdef GEN"): - is_cc = True - - if not split_file_input: - print("no .ifdef GEN, bail out", file=sys.stderr) - return - with tempfile.TemporaryDirectory() as dir: - sub = subprocess.run( - ["split-file", "-", dir], - input="\n".join(split_file_input).encode(), - capture_output=True, - ) - if sub.returncode != 0: - sys.stderr.write(f"split-file failed\n{sub.stderr.decode()}") - return - with cd(dir): - if not os.path.exists("gen"): - print("'gen' not found", file=sys.stderr) - return - - env = dict( - os.environ, CCC_OVERRIDE_OPTIONS="+-fno-ident", PWD="/proc/self/cwd" - ) - sub = subprocess.run(["zsh", "gen"], capture_output=True, env=env) - if sub.returncode != 0: - sys.stderr.write(f"'gen' failed\n{sub.stderr.decode()}") - return - content = sub.stdout.decode() - - with open(path, "w") as f: - # Print lines up to '.endif'. - print("\n".join(prolog), file=f) - # Then print the stdout of 'gen'. - f.write(content) - - -for path in sys.argv[1:]: - process(path) From 232c7292cd9230ca5b2566c3bbf7b6f97cb119ff Mon Sep 17 00:00:00 2001 From: Fangrui Song Date: Wed, 17 Apr 2024 14:38:58 -0700 Subject: [PATCH 34/37] Clean up more tests Remove tools/generate-content.py. We will use a generic tool intended for llvm/utils: https://discourse.llvm.org/t/utility-to-generate-elaborated-assembly-ir-tests/78408 --- lld/test/ELF/Inputs/debug-names-a.s | 2 +- lld/test/ELF/Inputs/debug-names-b.s | 2 +- lld/test/ELF/Inputs/debug-names-bcd.s | 406 -------- lld/test/ELF/Inputs/debug-names-ef.s | 332 ------- lld/test/ELF/debug-names-bad-die-idx-sizes.s | 156 --- lld/test/ELF/debug-names-bad-name-count.s | 162 ---- lld/test/ELF/debug-names-bad.s | 6 + lld/test/ELF/debug-names-dwarf64.s | 2 +- lld/test/ELF/debug-names-invalid-parent-idx.s | 153 --- lld/test/ELF/debug-names-missing-parent.s | 298 +++--- lld/test/ELF/debug-names-multi-cus.s | 773 ++++++++++++++- lld/test/ELF/debug-names-tus.s | 528 ----------- lld/test/ELF/debug-names-type-units.s | 895 ++++++++++++++++++ lld/test/ELF/tools/generate-content.py | 82 -- 14 files changed, 1815 insertions(+), 1982 deletions(-) delete mode 100644 lld/test/ELF/Inputs/debug-names-bcd.s delete mode 100644 lld/test/ELF/Inputs/debug-names-ef.s delete mode 100644 lld/test/ELF/debug-names-bad-die-idx-sizes.s delete mode 100644 lld/test/ELF/debug-names-bad-name-count.s delete mode 100644 lld/test/ELF/debug-names-invalid-parent-idx.s delete mode 100644 lld/test/ELF/debug-names-tus.s create mode 100644 lld/test/ELF/debug-names-type-units.s delete mode 100755 lld/test/ELF/tools/generate-content.py diff --git a/lld/test/ELF/Inputs/debug-names-a.s b/lld/test/ELF/Inputs/debug-names-a.s index 32fe3b88b0433..0adc520e765ca 100644 --- a/lld/test/ELF/Inputs/debug-names-a.s +++ b/lld/test/ELF/Inputs/debug-names-a.s @@ -3,7 +3,7 @@ struct t1 {}; extern "C" void _start(t1) {} #--- gen -clang -S -g -gpubnames a.cc -o - +clang --target=x86_64-linux -S -g -gpubnames a.cc -o - .endif .text .file "a.cc" diff --git a/lld/test/ELF/Inputs/debug-names-b.s b/lld/test/ELF/Inputs/debug-names-b.s index 938a44690ee91..2e3996742020b 100644 --- a/lld/test/ELF/Inputs/debug-names-b.s +++ b/lld/test/ELF/Inputs/debug-names-b.s @@ -6,7 +6,7 @@ struct t2 {}; } int main() { t1 v1; ns::t2 v2; } #--- gen -clang -S -g -gpubnames b.cc -o - +clang --target=x86_64-linux -S -g -gpubnames b.cc -o - .endif .text .file "b.cc" diff --git a/lld/test/ELF/Inputs/debug-names-bcd.s b/lld/test/ELF/Inputs/debug-names-bcd.s deleted file mode 100644 index 690485515b6c0..0000000000000 --- a/lld/test/ELF/Inputs/debug-names-bcd.s +++ /dev/null @@ -1,406 +0,0 @@ -.ifdef GEN -//--- b.cc -[[gnu::used]] int vb; -//--- c.cc -[[gnu::used]] int vc; -//--- d.cc -namespace ns { -[[gnu::used]] int vd; -} -//--- gen -clang -O1 -g -gpubnames -flto b.cc c.cc d.cc -nostdlib -fuse-ld=lld -Wl,--lto-emit-asm -cat a.out.lto.s -.endif - .text - .file "ld-temp.o" - .file 1 "/proc/self/cwd" "b.cc" md5 0x78dad32a49063326a4de543198e54944 - .file 2 "/proc/self/cwd" "c.cc" md5 0x7a0f7bf2cb0ec8c297f794908d91ab1b - .file 3 "/proc/self/cwd" "d.cc" md5 0x035bb8b2da82db6f75693f2a941c3294 - .type vb,@object # @vb - .section .bss.vb,"aw",@nobits - .globl vb - .p2align 2, 0x0 -vb: - .long 0 # 0x0 - .size vb, 4 - - .type vc,@object # @vc - .section .bss.vc,"aw",@nobits - .globl vc - .p2align 2, 0x0 -vc: - .long 0 # 0x0 - .size vc, 4 - - .type _ZN2ns2vdE,@object # @_ZN2ns2vdE - .section .bss._ZN2ns2vdE,"aw",@nobits - .globl _ZN2ns2vdE - .p2align 2, 0x0 -_ZN2ns2vdE: - .long 0 # 0x0 - .size _ZN2ns2vdE, 4 - - .section .debug_abbrev,"",@progbits - .byte 1 # Abbreviation Code - .byte 17 # DW_TAG_compile_unit - .byte 1 # DW_CHILDREN_yes - .byte 37 # DW_AT_producer - .byte 37 # DW_FORM_strx1 - .byte 19 # DW_AT_language - .byte 5 # DW_FORM_data2 - .byte 3 # DW_AT_name - .byte 37 # DW_FORM_strx1 - .byte 114 # DW_AT_str_offsets_base - .byte 23 # DW_FORM_sec_offset - .byte 16 # DW_AT_stmt_list - .byte 23 # DW_FORM_sec_offset - .byte 27 # DW_AT_comp_dir - .byte 37 # DW_FORM_strx1 - .byte 115 # DW_AT_addr_base - .byte 23 # DW_FORM_sec_offset - .byte 0 # EOM(1) - .byte 0 # EOM(2) - .byte 2 # Abbreviation Code - .byte 52 # DW_TAG_variable - .byte 0 # DW_CHILDREN_no - .byte 3 # DW_AT_name - .byte 37 # DW_FORM_strx1 - .byte 73 # DW_AT_type - .byte 19 # DW_FORM_ref4 - .byte 63 # DW_AT_external - .byte 25 # DW_FORM_flag_present - .byte 58 # DW_AT_decl_file - .byte 11 # DW_FORM_data1 - .byte 59 # DW_AT_decl_line - .byte 11 # DW_FORM_data1 - .byte 2 # DW_AT_location - .byte 24 # DW_FORM_exprloc - .byte 0 # EOM(1) - .byte 0 # EOM(2) - .byte 3 # Abbreviation Code - .byte 36 # DW_TAG_base_type - .byte 0 # DW_CHILDREN_no - .byte 3 # DW_AT_name - .byte 37 # DW_FORM_strx1 - .byte 62 # DW_AT_encoding - .byte 11 # DW_FORM_data1 - .byte 11 # DW_AT_byte_size - .byte 11 # DW_FORM_data1 - .byte 0 # EOM(1) - .byte 0 # EOM(2) - .byte 4 # Abbreviation Code - .byte 52 # DW_TAG_variable - .byte 0 # DW_CHILDREN_no - .byte 3 # DW_AT_name - .byte 37 # DW_FORM_strx1 - .byte 73 # DW_AT_type - .byte 16 # DW_FORM_ref_addr - .byte 63 # DW_AT_external - .byte 25 # DW_FORM_flag_present - .byte 58 # DW_AT_decl_file - .byte 11 # DW_FORM_data1 - .byte 59 # DW_AT_decl_line - .byte 11 # DW_FORM_data1 - .byte 2 # DW_AT_location - .byte 24 # DW_FORM_exprloc - .byte 0 # EOM(1) - .byte 0 # EOM(2) - .byte 5 # Abbreviation Code - .byte 57 # DW_TAG_namespace - .byte 1 # DW_CHILDREN_yes - .byte 3 # DW_AT_name - .byte 37 # DW_FORM_strx1 - .byte 0 # EOM(1) - .byte 0 # EOM(2) - .byte 6 # Abbreviation Code - .byte 52 # DW_TAG_variable - .byte 0 # DW_CHILDREN_no - .byte 3 # DW_AT_name - .byte 37 # DW_FORM_strx1 - .byte 73 # DW_AT_type - .byte 16 # DW_FORM_ref_addr - .byte 63 # DW_AT_external - .byte 25 # DW_FORM_flag_present - .byte 58 # DW_AT_decl_file - .byte 11 # DW_FORM_data1 - .byte 59 # DW_AT_decl_line - .byte 11 # DW_FORM_data1 - .byte 2 # DW_AT_location - .byte 24 # DW_FORM_exprloc - .byte 110 # DW_AT_linkage_name - .byte 37 # DW_FORM_strx1 - .byte 0 # EOM(1) - .byte 0 # EOM(2) - .byte 0 # EOM(3) - .section .debug_info,"",@progbits -.Lcu_begin0: - .long .Ldebug_info_end0-.Ldebug_info_start0 # Length of Unit -.Ldebug_info_start0: - .short 5 # DWARF version number - .byte 1 # DWARF Unit Type - .byte 8 # Address Size (in bytes) - .long .debug_abbrev # Offset Into Abbrev. Section - .byte 1 # Abbrev [1] 0xc:0x22 DW_TAG_compile_unit - .byte 0 # DW_AT_producer - .short 33 # DW_AT_language - .byte 1 # DW_AT_name - .long .Lstr_offsets_base0 # DW_AT_str_offsets_base - .long .Lline_table_start0 # DW_AT_stmt_list - .byte 2 # DW_AT_comp_dir - .long .Laddr_table_base0 # DW_AT_addr_base - .byte 2 # Abbrev [2] 0x1e:0xb DW_TAG_variable - .byte 3 # DW_AT_name - .long 41 # DW_AT_type - # DW_AT_external - .byte 1 # DW_AT_decl_file - .byte 1 # DW_AT_decl_line - .byte 2 # DW_AT_location - .byte 161 - .byte 0 - .byte 3 # Abbrev [3] 0x29:0x4 DW_TAG_base_type - .byte 4 # DW_AT_name - .byte 5 # DW_AT_encoding - .byte 4 # DW_AT_byte_size - .byte 0 # End Of Children Mark -.Ldebug_info_end0: -.Lcu_begin1: - .long .Ldebug_info_end1-.Ldebug_info_start1 # Length of Unit -.Ldebug_info_start1: - .short 5 # DWARF version number - .byte 1 # DWARF Unit Type - .byte 8 # Address Size (in bytes) - .long .debug_abbrev # Offset Into Abbrev. Section - .byte 1 # Abbrev [1] 0xc:0x1e DW_TAG_compile_unit - .byte 0 # DW_AT_producer - .short 33 # DW_AT_language - .byte 5 # DW_AT_name - .long .Lstr_offsets_base0 # DW_AT_str_offsets_base - .long .Lline_table_start0 # DW_AT_stmt_list - .byte 2 # DW_AT_comp_dir - .long .Laddr_table_base0 # DW_AT_addr_base - .byte 4 # Abbrev [4] 0x1e:0xb DW_TAG_variable - .byte 6 # DW_AT_name - .long .debug_info+41 # DW_AT_type - # DW_AT_external - .byte 2 # DW_AT_decl_file - .byte 1 # DW_AT_decl_line - .byte 2 # DW_AT_location - .byte 161 - .byte 1 - .byte 0 # End Of Children Mark -.Ldebug_info_end1: -.Lcu_begin2: - .long .Ldebug_info_end2-.Ldebug_info_start2 # Length of Unit -.Ldebug_info_start2: - .short 5 # DWARF version number - .byte 1 # DWARF Unit Type - .byte 8 # Address Size (in bytes) - .long .debug_abbrev # Offset Into Abbrev. Section - .byte 1 # Abbrev [1] 0xc:0x22 DW_TAG_compile_unit - .byte 0 # DW_AT_producer - .short 33 # DW_AT_language - .byte 7 # DW_AT_name - .long .Lstr_offsets_base0 # DW_AT_str_offsets_base - .long .Lline_table_start0 # DW_AT_stmt_list - .byte 2 # DW_AT_comp_dir - .long .Laddr_table_base0 # DW_AT_addr_base - .byte 5 # Abbrev [5] 0x1e:0xf DW_TAG_namespace - .byte 8 # DW_AT_name - .byte 6 # Abbrev [6] 0x20:0xc DW_TAG_variable - .byte 9 # DW_AT_name - .long .debug_info+41 # DW_AT_type - # DW_AT_external - .byte 3 # DW_AT_decl_file - .byte 2 # DW_AT_decl_line - .byte 2 # DW_AT_location - .byte 161 - .byte 2 - .byte 10 # DW_AT_linkage_name - .byte 0 # End Of Children Mark - .byte 0 # End Of Children Mark -.Ldebug_info_end2: - .section .debug_str_offsets,"",@progbits - .long 48 # Length of String Offsets Set - .short 5 - .short 0 -.Lstr_offsets_base0: - .section .debug_str,"MS",@progbits,1 -.Linfo_string0: - .byte 0 # string offset=0 -.Linfo_string1: - .asciz "b.cc" # string offset=1 -.Linfo_string2: - .asciz "/proc/self/cwd" # string offset=6 -.Linfo_string3: - .asciz "vb" # string offset=21 -.Linfo_string4: - .asciz "int" # string offset=24 -.Linfo_string5: - .asciz "c.cc" # string offset=28 -.Linfo_string6: - .asciz "vc" # string offset=33 -.Linfo_string7: - .asciz "d.cc" # string offset=36 -.Linfo_string8: - .asciz "ns" # string offset=41 -.Linfo_string9: - .asciz "vd" # string offset=44 -.Linfo_string10: - .asciz "_ZN2ns2vdE" # string offset=47 - .section .debug_str_offsets,"",@progbits - .long .Linfo_string0 - .long .Linfo_string1 - .long .Linfo_string2 - .long .Linfo_string3 - .long .Linfo_string4 - .long .Linfo_string5 - .long .Linfo_string6 - .long .Linfo_string7 - .long .Linfo_string8 - .long .Linfo_string9 - .long .Linfo_string10 - .section .debug_addr,"",@progbits - .long .Ldebug_addr_end0-.Ldebug_addr_start0 # Length of contribution -.Ldebug_addr_start0: - .short 5 # DWARF version number - .byte 8 # Address size - .byte 0 # Segment selector size -.Laddr_table_base0: - .quad vb - .quad vc - .quad _ZN2ns2vdE -.Ldebug_addr_end0: - .section .debug_names,"",@progbits - .long .Lnames_end0-.Lnames_start0 # Header: unit length -.Lnames_start0: - .short 5 # Header: version - .short 0 # Header: padding - .long 3 # Header: compilation unit count - .long 0 # Header: local type unit count - .long 0 # Header: foreign type unit count - .long 6 # Header: bucket count - .long 6 # Header: name count - .long .Lnames_abbrev_end0-.Lnames_abbrev_start0 # Header: abbreviation table size - .long 8 # Header: augmentation string size - .ascii "LLVM0700" # Header: augmentation string - .long .Lcu_begin0 # Compilation unit 0 - .long .Lcu_begin1 # Compilation unit 1 - .long .Lcu_begin2 # Compilation unit 2 - .long 1 # Bucket 0 - .long 2 # Bucket 1 - .long 3 # Bucket 2 - .long 0 # Bucket 3 - .long 4 # Bucket 4 - .long 6 # Bucket 5 - .long 5863902 # Hash in Bucket 0 - .long 5863903 # Hash in Bucket 1 - .long 193495088 # Hash in Bucket 2 - .long 5863654 # Hash in Bucket 4 - .long -823734096 # Hash in Bucket 4 - .long 5863901 # Hash in Bucket 5 - .long .Linfo_string6 # String in Bucket 0: vc - .long .Linfo_string9 # String in Bucket 1: vd - .long .Linfo_string4 # String in Bucket 2: int - .long .Linfo_string8 # String in Bucket 4: ns - .long .Linfo_string10 # String in Bucket 4: _ZN2ns2vdE - .long .Linfo_string3 # String in Bucket 5: vb - .long .Lnames2-.Lnames_entries0 # Offset in Bucket 0 - .long .Lnames4-.Lnames_entries0 # Offset in Bucket 1 - .long .Lnames0-.Lnames_entries0 # Offset in Bucket 2 - .long .Lnames3-.Lnames_entries0 # Offset in Bucket 4 - .long .Lnames5-.Lnames_entries0 # Offset in Bucket 4 - .long .Lnames1-.Lnames_entries0 # Offset in Bucket 5 -.Lnames_abbrev_start0: - .byte 1 # Abbrev code - .byte 52 # DW_TAG_variable - .byte 1 # DW_IDX_compile_unit - .byte 11 # DW_FORM_data1 - .byte 3 # DW_IDX_die_offset - .byte 19 # DW_FORM_ref4 - .byte 4 # DW_IDX_parent - .byte 25 # DW_FORM_flag_present - .byte 0 # End of abbrev - .byte 0 # End of abbrev - .byte 2 # Abbrev code - .byte 52 # DW_TAG_variable - .byte 1 # DW_IDX_compile_unit - .byte 11 # DW_FORM_data1 - .byte 3 # DW_IDX_die_offset - .byte 19 # DW_FORM_ref4 - .byte 4 # DW_IDX_parent - .byte 19 # DW_FORM_ref4 - .byte 0 # End of abbrev - .byte 0 # End of abbrev - .byte 3 # Abbrev code - .byte 36 # DW_TAG_base_type - .byte 1 # DW_IDX_compile_unit - .byte 11 # DW_FORM_data1 - .byte 3 # DW_IDX_die_offset - .byte 19 # DW_FORM_ref4 - .byte 4 # DW_IDX_parent - .byte 25 # DW_FORM_flag_present - .byte 0 # End of abbrev - .byte 0 # End of abbrev - .byte 4 # Abbrev code - .byte 57 # DW_TAG_namespace - .byte 1 # DW_IDX_compile_unit - .byte 11 # DW_FORM_data1 - .byte 3 # DW_IDX_die_offset - .byte 19 # DW_FORM_ref4 - .byte 4 # DW_IDX_parent - .byte 25 # DW_FORM_flag_present - .byte 0 # End of abbrev - .byte 0 # End of abbrev - .byte 0 # End of abbrev list -.Lnames_abbrev_end0: -.Lnames_entries0: -.Lnames2: -.L0: - .byte 1 # Abbreviation code - .byte 1 # DW_IDX_compile_unit - .long 30 # DW_IDX_die_offset - .byte 0 # DW_IDX_parent - # End of list: vc -.Lnames4: -.L4: - .byte 2 # Abbreviation code - .byte 2 # DW_IDX_compile_unit - .long 32 # DW_IDX_die_offset - .long .L2-.Lnames_entries0 # DW_IDX_parent - .byte 0 # End of list: vd -.Lnames0: -.L3: - .byte 3 # Abbreviation code - .byte 0 # DW_IDX_compile_unit - .long 41 # DW_IDX_die_offset - .byte 0 # DW_IDX_parent - # End of list: int -.Lnames3: -.L2: - .byte 4 # Abbreviation code - .byte 2 # DW_IDX_compile_unit - .long 30 # DW_IDX_die_offset - .byte 0 # DW_IDX_parent - # End of list: ns -.Lnames5: - .byte 2 # Abbreviation code - .byte 2 # DW_IDX_compile_unit - .long 32 # DW_IDX_die_offset - .long .L2-.Lnames_entries0 # DW_IDX_parent - .byte 0 # End of list: _ZN2ns2vdE -.Lnames1: -.L1: - .byte 1 # Abbreviation code - .byte 0 # DW_IDX_compile_unit - .long 30 # DW_IDX_die_offset - .byte 0 # DW_IDX_parent - # End of list: vb - .p2align 2, 0x0 -.Lnames_end0: - .section ".note.GNU-stack","",@progbits - .addrsig - .addrsig_sym vb - .addrsig_sym vc - .addrsig_sym _ZN2ns2vdE - .section .debug_line,"",@progbits -.Lline_table_start0: diff --git a/lld/test/ELF/Inputs/debug-names-ef.s b/lld/test/ELF/Inputs/debug-names-ef.s deleted file mode 100644 index d50f3b131e5f6..0000000000000 --- a/lld/test/ELF/Inputs/debug-names-ef.s +++ /dev/null @@ -1,332 +0,0 @@ -.ifdef GEN -//--- e.cc -[[gnu::used]] int ve; -//--- f.cc -namespace ns { -[[gnu::used]] int vf; -} -//--- gen -clang -O1 -g -gpubnames -flto e.cc f.cc -nostdlib -fuse-ld=lld -Wl,--lto-emit-asm -cat a.out.lto.s -.endif - .text - .file "ld-temp.o" - .file 1 "/proc/self/cwd" "e.cc" md5 0xa8d6c645998197bd15436f2a351ebd6a - .file 2 "/proc/self/cwd" "f.cc" md5 0x6bf8b64f7d7116a3398f9522a92447f9 - .type ve,@object # @ve - .section .bss.ve,"aw",@nobits - .globl ve - .p2align 2, 0x0 -ve: - .long 0 # 0x0 - .size ve, 4 - - .type _ZN2ns2vfE,@object # @_ZN2ns2vfE - .section .bss._ZN2ns2vfE,"aw",@nobits - .globl _ZN2ns2vfE - .p2align 2, 0x0 -_ZN2ns2vfE: - .long 0 # 0x0 - .size _ZN2ns2vfE, 4 - - .section .debug_abbrev,"",@progbits - .byte 1 # Abbreviation Code - .byte 17 # DW_TAG_compile_unit - .byte 1 # DW_CHILDREN_yes - .byte 37 # DW_AT_producer - .byte 37 # DW_FORM_strx1 - .byte 19 # DW_AT_language - .byte 5 # DW_FORM_data2 - .byte 3 # DW_AT_name - .byte 37 # DW_FORM_strx1 - .byte 114 # DW_AT_str_offsets_base - .byte 23 # DW_FORM_sec_offset - .byte 16 # DW_AT_stmt_list - .byte 23 # DW_FORM_sec_offset - .byte 27 # DW_AT_comp_dir - .byte 37 # DW_FORM_strx1 - .byte 115 # DW_AT_addr_base - .byte 23 # DW_FORM_sec_offset - .byte 0 # EOM(1) - .byte 0 # EOM(2) - .byte 2 # Abbreviation Code - .byte 52 # DW_TAG_variable - .byte 0 # DW_CHILDREN_no - .byte 3 # DW_AT_name - .byte 37 # DW_FORM_strx1 - .byte 73 # DW_AT_type - .byte 19 # DW_FORM_ref4 - .byte 63 # DW_AT_external - .byte 25 # DW_FORM_flag_present - .byte 58 # DW_AT_decl_file - .byte 11 # DW_FORM_data1 - .byte 59 # DW_AT_decl_line - .byte 11 # DW_FORM_data1 - .byte 2 # DW_AT_location - .byte 24 # DW_FORM_exprloc - .byte 0 # EOM(1) - .byte 0 # EOM(2) - .byte 3 # Abbreviation Code - .byte 36 # DW_TAG_base_type - .byte 0 # DW_CHILDREN_no - .byte 3 # DW_AT_name - .byte 37 # DW_FORM_strx1 - .byte 62 # DW_AT_encoding - .byte 11 # DW_FORM_data1 - .byte 11 # DW_AT_byte_size - .byte 11 # DW_FORM_data1 - .byte 0 # EOM(1) - .byte 0 # EOM(2) - .byte 4 # Abbreviation Code - .byte 57 # DW_TAG_namespace - .byte 1 # DW_CHILDREN_yes - .byte 3 # DW_AT_name - .byte 37 # DW_FORM_strx1 - .byte 0 # EOM(1) - .byte 0 # EOM(2) - .byte 5 # Abbreviation Code - .byte 52 # DW_TAG_variable - .byte 0 # DW_CHILDREN_no - .byte 3 # DW_AT_name - .byte 37 # DW_FORM_strx1 - .byte 73 # DW_AT_type - .byte 16 # DW_FORM_ref_addr - .byte 63 # DW_AT_external - .byte 25 # DW_FORM_flag_present - .byte 58 # DW_AT_decl_file - .byte 11 # DW_FORM_data1 - .byte 59 # DW_AT_decl_line - .byte 11 # DW_FORM_data1 - .byte 2 # DW_AT_location - .byte 24 # DW_FORM_exprloc - .byte 110 # DW_AT_linkage_name - .byte 37 # DW_FORM_strx1 - .byte 0 # EOM(1) - .byte 0 # EOM(2) - .byte 0 # EOM(3) - .section .debug_info,"",@progbits -.Lcu_begin0: - .long .Ldebug_info_end0-.Ldebug_info_start0 # Length of Unit -.Ldebug_info_start0: - .short 5 # DWARF version number - .byte 1 # DWARF Unit Type - .byte 8 # Address Size (in bytes) - .long .debug_abbrev # Offset Into Abbrev. Section - .byte 1 # Abbrev [1] 0xc:0x22 DW_TAG_compile_unit - .byte 0 # DW_AT_producer - .short 33 # DW_AT_language - .byte 1 # DW_AT_name - .long .Lstr_offsets_base0 # DW_AT_str_offsets_base - .long .Lline_table_start0 # DW_AT_stmt_list - .byte 2 # DW_AT_comp_dir - .long .Laddr_table_base0 # DW_AT_addr_base - .byte 2 # Abbrev [2] 0x1e:0xb DW_TAG_variable - .byte 3 # DW_AT_name - .long 41 # DW_AT_type - # DW_AT_external - .byte 1 # DW_AT_decl_file - .byte 1 # DW_AT_decl_line - .byte 2 # DW_AT_location - .byte 161 - .byte 0 - .byte 3 # Abbrev [3] 0x29:0x4 DW_TAG_base_type - .byte 4 # DW_AT_name - .byte 5 # DW_AT_encoding - .byte 4 # DW_AT_byte_size - .byte 0 # End Of Children Mark -.Ldebug_info_end0: -.Lcu_begin1: - .long .Ldebug_info_end1-.Ldebug_info_start1 # Length of Unit -.Ldebug_info_start1: - .short 5 # DWARF version number - .byte 1 # DWARF Unit Type - .byte 8 # Address Size (in bytes) - .long .debug_abbrev # Offset Into Abbrev. Section - .byte 1 # Abbrev [1] 0xc:0x22 DW_TAG_compile_unit - .byte 0 # DW_AT_producer - .short 33 # DW_AT_language - .byte 5 # DW_AT_name - .long .Lstr_offsets_base0 # DW_AT_str_offsets_base - .long .Lline_table_start0 # DW_AT_stmt_list - .byte 2 # DW_AT_comp_dir - .long .Laddr_table_base0 # DW_AT_addr_base - .byte 4 # Abbrev [4] 0x1e:0xf DW_TAG_namespace - .byte 6 # DW_AT_name - .byte 5 # Abbrev [5] 0x20:0xc DW_TAG_variable - .byte 7 # DW_AT_name - .long .debug_info+41 # DW_AT_type - # DW_AT_external - .byte 2 # DW_AT_decl_file - .byte 2 # DW_AT_decl_line - .byte 2 # DW_AT_location - .byte 161 - .byte 1 - .byte 8 # DW_AT_linkage_name - .byte 0 # End Of Children Mark - .byte 0 # End Of Children Mark -.Ldebug_info_end1: - .section .debug_str_offsets,"",@progbits - .long 40 # Length of String Offsets Set - .short 5 - .short 0 -.Lstr_offsets_base0: - .section .debug_str,"MS",@progbits,1 -.Linfo_string0: - .byte 0 # string offset=0 -.Linfo_string1: - .asciz "e.cc" # string offset=1 -.Linfo_string2: - .asciz "/proc/self/cwd" # string offset=6 -.Linfo_string3: - .asciz "ve" # string offset=21 -.Linfo_string4: - .asciz "int" # string offset=24 -.Linfo_string5: - .asciz "f.cc" # string offset=28 -.Linfo_string6: - .asciz "ns" # string offset=33 -.Linfo_string7: - .asciz "vf" # string offset=36 -.Linfo_string8: - .asciz "_ZN2ns2vfE" # string offset=39 - .section .debug_str_offsets,"",@progbits - .long .Linfo_string0 - .long .Linfo_string1 - .long .Linfo_string2 - .long .Linfo_string3 - .long .Linfo_string4 - .long .Linfo_string5 - .long .Linfo_string6 - .long .Linfo_string7 - .long .Linfo_string8 - .section .debug_addr,"",@progbits - .long .Ldebug_addr_end0-.Ldebug_addr_start0 # Length of contribution -.Ldebug_addr_start0: - .short 5 # DWARF version number - .byte 8 # Address size - .byte 0 # Segment selector size -.Laddr_table_base0: - .quad ve - .quad _ZN2ns2vfE -.Ldebug_addr_end0: - .section .debug_names,"",@progbits - .long .Lnames_end0-.Lnames_start0 # Header: unit length -.Lnames_start0: - .short 5 # Header: version - .short 0 # Header: padding - .long 2 # Header: compilation unit count - .long 0 # Header: local type unit count - .long 0 # Header: foreign type unit count - .long 5 # Header: bucket count - .long 5 # Header: name count - .long .Lnames_abbrev_end0-.Lnames_abbrev_start0 # Header: abbreviation table size - .long 8 # Header: augmentation string size - .ascii "LLVM0700" # Header: augmentation string - .long .Lcu_begin0 # Compilation unit 0 - .long .Lcu_begin1 # Compilation unit 1 - .long 1 # Bucket 0 - .long 2 # Bucket 1 - .long 0 # Bucket 2 - .long 3 # Bucket 3 - .long 4 # Bucket 4 - .long 5863905 # Hash in Bucket 0 - .long -823734030 # Hash in Bucket 1 - .long 193495088 # Hash in Bucket 3 - .long 5863654 # Hash in Bucket 4 - .long 5863904 # Hash in Bucket 4 - .long .Linfo_string7 # String in Bucket 0: vf - .long .Linfo_string8 # String in Bucket 1: _ZN2ns2vfE - .long .Linfo_string4 # String in Bucket 3: int - .long .Linfo_string6 # String in Bucket 4: ns - .long .Linfo_string3 # String in Bucket 4: ve - .long .Lnames3-.Lnames_entries0 # Offset in Bucket 0 - .long .Lnames4-.Lnames_entries0 # Offset in Bucket 1 - .long .Lnames0-.Lnames_entries0 # Offset in Bucket 3 - .long .Lnames2-.Lnames_entries0 # Offset in Bucket 4 - .long .Lnames1-.Lnames_entries0 # Offset in Bucket 4 -.Lnames_abbrev_start0: - .byte 1 # Abbrev code - .byte 52 # DW_TAG_variable - .byte 1 # DW_IDX_compile_unit - .byte 11 # DW_FORM_data1 - .byte 3 # DW_IDX_die_offset - .byte 19 # DW_FORM_ref4 - .byte 4 # DW_IDX_parent - .byte 19 # DW_FORM_ref4 - .byte 0 # End of abbrev - .byte 0 # End of abbrev - .byte 2 # Abbrev code - .byte 36 # DW_TAG_base_type - .byte 1 # DW_IDX_compile_unit - .byte 11 # DW_FORM_data1 - .byte 3 # DW_IDX_die_offset - .byte 19 # DW_FORM_ref4 - .byte 4 # DW_IDX_parent - .byte 25 # DW_FORM_flag_present - .byte 0 # End of abbrev - .byte 0 # End of abbrev - .byte 3 # Abbrev code - .byte 57 # DW_TAG_namespace - .byte 1 # DW_IDX_compile_unit - .byte 11 # DW_FORM_data1 - .byte 3 # DW_IDX_die_offset - .byte 19 # DW_FORM_ref4 - .byte 4 # DW_IDX_parent - .byte 25 # DW_FORM_flag_present - .byte 0 # End of abbrev - .byte 0 # End of abbrev - .byte 4 # Abbrev code - .byte 52 # DW_TAG_variable - .byte 1 # DW_IDX_compile_unit - .byte 11 # DW_FORM_data1 - .byte 3 # DW_IDX_die_offset - .byte 19 # DW_FORM_ref4 - .byte 4 # DW_IDX_parent - .byte 25 # DW_FORM_flag_present - .byte 0 # End of abbrev - .byte 0 # End of abbrev - .byte 0 # End of abbrev list -.Lnames_abbrev_end0: -.Lnames_entries0: -.Lnames3: -.L2: - .byte 1 # Abbreviation code - .byte 1 # DW_IDX_compile_unit - .long 32 # DW_IDX_die_offset - .long .L0-.Lnames_entries0 # DW_IDX_parent - .byte 0 # End of list: vf -.Lnames4: - .byte 1 # Abbreviation code - .byte 1 # DW_IDX_compile_unit - .long 32 # DW_IDX_die_offset - .long .L0-.Lnames_entries0 # DW_IDX_parent - .byte 0 # End of list: _ZN2ns2vfE -.Lnames0: -.L3: - .byte 2 # Abbreviation code - .byte 0 # DW_IDX_compile_unit - .long 41 # DW_IDX_die_offset - .byte 0 # DW_IDX_parent - # End of list: int -.Lnames2: -.L0: - .byte 3 # Abbreviation code - .byte 1 # DW_IDX_compile_unit - .long 30 # DW_IDX_die_offset - .byte 0 # DW_IDX_parent - # End of list: ns -.Lnames1: -.L1: - .byte 4 # Abbreviation code - .byte 0 # DW_IDX_compile_unit - .long 30 # DW_IDX_die_offset - .byte 0 # DW_IDX_parent - # End of list: ve - .p2align 2, 0x0 -.Lnames_end0: - .section ".note.GNU-stack","",@progbits - .addrsig - .addrsig_sym ve - .addrsig_sym _ZN2ns2vfE - .section .debug_line,"",@progbits -.Lline_table_start0: diff --git a/lld/test/ELF/debug-names-bad-die-idx-sizes.s b/lld/test/ELF/debug-names-bad-die-idx-sizes.s deleted file mode 100644 index 850629b308660..0000000000000 --- a/lld/test/ELF/debug-names-bad-die-idx-sizes.s +++ /dev/null @@ -1,156 +0,0 @@ -# This file was generated by first compiling a.cpp: -# clang++ -g -O0 -S -gpubnames -fdebug-compilation-dir='/proc/self/cwd' a.cpp - -# Then manually edit the .debug_names section. In the entries, change the -# size of the DW_IDX_die_offset from '.long' to '.byte'. - -# Contents of a.cpp: -# int main (int argc, char **argv) { } - -# REQUIRES: x86 -# RUN: llvm-mc -filetype=obj -triple=x86_64 %s -o %t1.o -# RUN: not ld.lld --debug-names %t1.o -o /dev/null 2>&1 \ -# RUN: | FileCheck -DFILE=%t1.o --implicit-check-not=error: %s - -# CHECK: error: [[FILE]]:(.debug_names): index entry is out of bounds - -# RUN: llvm-mc -filetype=obj -triple=x86_64 %s -o %t1.o -# RUN: ld.lld --debug-names --noinhibit-exec %t1.o -o /dev/null 2>&1 \ -# RUN: | FileCheck -DFILE=%t1.o %s --check-prefix=WARN - -# WARN: warning: [[FILE]]:(.debug_names): index entry is out of bounds - - .text - .globl main # -- Begin function main - .p2align 4, 0x90 - .type main,@function -main: # @main -.Lfunc_begin0: - .cfi_startproc -# %bb.0: # %entry - pushq %rbp - .cfi_def_cfa_offset 16 - .cfi_offset %rbp, -16 - movq %rsp, %rbp - .cfi_def_cfa_register %rbp - movl %edi, -4(%rbp) - movq %rsi, -16(%rbp) -.Ltmp0: - xorl %eax, %eax - popq %rbp - .cfi_def_cfa %rsp, 8 - retq -.Ltmp1: -.Lfunc_end0: - .size main, .Lfunc_end0-main - .cfi_endproc - # -- End function - .section .debug_abbrev,"",@progbits - .byte 0 # EOM(1) - .byte 0 # EOM(2) - .byte 0 # EOM(3) - .section .debug_info,"",@progbits -.Lcu_begin0: - .long .Ldebug_info_end0-.Ldebug_info_start0 # Length of Unit -.Ldebug_info_start0: - .short 5 # DWARF version number - .byte 1 # DWARF Unit Type - .byte 8 # Address Size (in bytes) - .long .debug_abbrev # Offset Into Abbrev. Section -.Ldebug_info_end0: - .section .debug_str_offsets,"",@progbits - .long 36 # Length of String Offsets Set - .short 5 - .short 0 -.Lstr_offsets_base0: - .section .debug_str,"MS",@progbits,1 -.Linfo_string0: - .asciz "clang version 19.0.0git (git@github.com:llvm/llvm-project.git 53b14cd9ce2b57da73d173fc876d2e9e199f5640)" # string offset=0 -.Linfo_string1: - .asciz "a.cpp" # string offset=104 -.Linfo_string2: - .asciz "/proc/self/cwd" # string offset=110 -.Linfo_string3: - .asciz "main" # string offset=125 -.Linfo_string4: - .asciz "int" # string offset=130 -.Linfo_string5: - .asciz "argc" # string offset=134 -.Linfo_string6: - .asciz "argv" # string offset=139 -.Linfo_string7: - .asciz "char" # string offset=144 -.Laddr_table_base0: - .quad .Lfunc_begin0 -.Ldebug_addr_end0: - .section .debug_names,"",@progbits - .long .Lnames_end0-.Lnames_start0 # Header: unit length -.Lnames_start0: - .short 5 # Header: version - .short 0 # Header: padding - .long 1 # Header: compilation unit count - .long 0 # Header: local type unit count - .long 0 # Header: foreign type unit count - .long 3 # Header: bucket count - .long 3 # Header: name count - .long .Lnames_abbrev_end0-.Lnames_abbrev_start0 # Header: abbreviation table size - .long 8 # Header: augmentation string size - .ascii "LLVM0700" # Header: augmentation string - .long .Lcu_begin0 # Compilation unit 0 - .long 0 # Bucket 0 - .long 1 # Bucket 1 - .long 2 # Bucket 2 - .long 2090499946 # Hash in Bucket 1 - .long 193495088 # Hash in Bucket 2 - .long 2090147939 # Hash in Bucket 2 - .long .Linfo_string3 # String in Bucket 1: main - .long .Linfo_string4 # String in Bucket 2: int - .long .Linfo_string7 # String in Bucket 2: char - .long .Lnames0-.Lnames_entries0 # Offset in Bucket 1 - .long .Lnames1-.Lnames_entries0 # Offset in Bucket 2 - .long .Lnames2-.Lnames_entries0 # Offset in Bucket 2 -.Lnames_abbrev_start0: - .byte 1 # Abbrev code - .byte 46 # DW_TAG_subprogram - .byte 3 # DW_IDX_die_offset - .byte 19 # DW_FORM_ref4 - .byte 4 # DW_IDX_parent - .byte 25 # DW_FORM_flag_present - .byte 0 # End of abbrev - .byte 0 # End of abbrev - .byte 2 # Abbrev code - .byte 36 # DW_TAG_base_type - .byte 3 # DW_IDX_die_offset - .byte 19 # DW_FORM_ref4 - .byte 4 # DW_IDX_parent - .byte 25 # DW_FORM_flag_present - .byte 0 # End of abbrev - .byte 0 # End of abbrev - .byte 0 # End of abbrev list -.Lnames_abbrev_end0: -.Lnames_entries0: -.Lnames0: -.L1: - .byte 1 # Abbreviation code - .byte 35 # DW_IDX_die_offset - .byte 0 # DW_IDX_parent - # End of list: main -.Lnames1: -.L0: - .byte 2 # Abbreviation code - .byte 73 # DW_IDX_die_offset - .byte 0 # DW_IDX_parent - # End of list: int -.Lnames2: -.L2: - .byte 2 # Abbreviation code - .byte 87 # DW_IDX_die_offset - .byte 0 # DW_IDX_parent - # End of list: char - .p2align 2, 0x0 -.Lnames_end0: - .ident "clang version 19.0.0git (git@github.com:llvm/llvm-project.git 53b14cd9ce2b57da73d173fc876d2e9e199f5640)" - .section ".note.GNU-stack","",@progbits - .addrsig - .section .debug_line,"",@progbits -.Lline_table_start0: diff --git a/lld/test/ELF/debug-names-bad-name-count.s b/lld/test/ELF/debug-names-bad-name-count.s deleted file mode 100644 index 11a418177e1c1..0000000000000 --- a/lld/test/ELF/debug-names-bad-name-count.s +++ /dev/null @@ -1,162 +0,0 @@ -# REQUIRES: x86 -# RUN: llvm-mc -filetype=obj -triple=x86_64 %s -o %t1.o - -# RUN: not ld.lld --debug-names %t1.o -o /dev/null 2>&1 \ -# RUN: | FileCheck -DFILE=%t1.o --implicit-check-not=error: %s - -# CHECK: error: [[FILE]]:(.debug_names): index entry is out of bounds -# CHECK: error: [[FILE]]:(.debug_names): index entry is out of bounds -# CHECK: error: [[FILE]]:(.debug_names): index entry is out of bounds -# CHECK: error: [[FILE]]:(.debug_names): index entry is out of bounds - -# RUN: ld.lld --noinhibit-exec --debug-names %t1.o -o /dev/null 2>&1 \ -# RUN: | FileCheck -DFILE=%t1.o %s --check-prefix=WARN - -# WARN: warning: [[FILE]]:(.debug_names): index entry is out of bounds -# WARN: warning: [[FILE]]:(.debug_names): index entry is out of bounds -# WARN: warning: [[FILE]]:(.debug_names): index entry is out of bounds -# WARN: warning: [[FILE]]:(.debug_names): index entry is out of bounds - -# This file was generated by first compiling a.cpp: -# clang++ -g -O0 -S -gpubnames -fdebug-compilation-dir='/proc/self/cwd' a.cpp - -# Then manually edit .debug_names section: change value for -# 'Header: name count' from 3 to 4. - -# Contents of a.cpp: -# int main (int argc, char **argv) { } - - .text - .globl main # -- Begin function main - .p2align 4, 0x90 - .type main,@function -main: # @main -.Lfunc_begin0: - .cfi_startproc -# %bb.0: # %entry - pushq %rbp - .cfi_def_cfa_offset 16 - .cfi_offset %rbp, -16 - movq %rsp, %rbp - .cfi_def_cfa_register %rbp - movl %edi, -4(%rbp) - movq %rsi, -16(%rbp) -.Ltmp0: - xorl %eax, %eax - popq %rbp - .cfi_def_cfa %rsp, 8 - retq -.Ltmp1: -.Lfunc_end0: - .size main, .Lfunc_end0-main - .cfi_endproc - # -- End function - .section .debug_abbrev,"",@progbits - .byte 0 # EOM(1) - .byte 0 # EOM(2) - .byte 0 # EOM(3) - .section .debug_info,"",@progbits -.Lcu_begin0: - .long .Ldebug_info_end0-.Ldebug_info_start0 # Length of Unit -.Ldebug_info_start0: - .short 5 # DWARF version number - .byte 1 # DWARF Unit Type - .byte 8 # Address Size (in bytes) - .long .debug_abbrev # Offset Into Abbrev. Section -.Ldebug_info_end0: - .section .debug_str_offsets,"",@progbits - .long 36 # Length of String Offsets Set - .short 5 - .short 0 -.Lstr_offsets_base0: - .section .debug_str,"MS",@progbits,1 -.Linfo_string0: - .asciz "clang version 19.0.0git (git@github.com:llvm/llvm-project.git 53b14cd9ce2b57da73d173fc876d2e9e199f5640)" # string offset=0 -.Linfo_string1: - .asciz "a.cpp" # string offset=104 -.Linfo_string2: - .asciz "/proc/self/cwd" # string offset=110 -.Linfo_string3: - .asciz "main" # string offset=125 -.Linfo_string4: - .asciz "int" # string offset=130 -.Linfo_string5: - .asciz "argc" # string offset=134 -.Linfo_string6: - .asciz "argv" # string offset=139 -.Linfo_string7: - .asciz "char" # string offset=144 -.Laddr_table_base0: - .quad .Lfunc_begin0 -.Ldebug_addr_end0: - .section .debug_names,"",@progbits - .long .Lnames_end0-.Lnames_start0 # Header: unit length -.Lnames_start0: - .short 5 # Header: version - .short 0 # Header: padding - .long 1 # Header: compilation unit count - .long 0 # Header: local type unit count - .long 0 # Header: foreign type unit count - .long 3 # Header: bucket count - .long 4 # Header: name count - .long .Lnames_abbrev_end0-.Lnames_abbrev_start0 # Header: abbreviation table size - .long 8 # Header: augmentation string size - .ascii "LLVM0700" # Header: augmentation string - .long .Lcu_begin0 # Compilation unit 0 - .long 0 # Bucket 0 - .long 1 # Bucket 1 - .long 2 # Bucket 2 - .long 2090499946 # Hash in Bucket 1 - .long 193495088 # Hash in Bucket 2 - .long 2090147939 # Hash in Bucket 2 - .long .Linfo_string3 # String in Bucket 1: main - .long .Linfo_string4 # String in Bucket 2: int - .long .Linfo_string7 # String in Bucket 2: char - .long .Lnames0-.Lnames_entries0 # Offset in Bucket 1 - .long .Lnames1-.Lnames_entries0 # Offset in Bucket 2 - .long .Lnames2-.Lnames_entries0 # Offset in Bucket 2 -.Lnames_abbrev_start0: - .byte 1 # Abbrev code - .byte 46 # DW_TAG_subprogram - .byte 3 # DW_IDX_die_offset - .byte 19 # DW_FORM_ref4 - .byte 4 # DW_IDX_parent - .byte 25 # DW_FORM_flag_present - .byte 0 # End of abbrev - .byte 0 # End of abbrev - .byte 2 # Abbrev code - .byte 36 # DW_TAG_base_type - .byte 3 # DW_IDX_die_offset - .byte 19 # DW_FORM_ref4 - .byte 4 # DW_IDX_parent - .byte 25 # DW_FORM_flag_present - .byte 0 # End of abbrev - .byte 0 # End of abbrev - .byte 0 # End of abbrev list -.Lnames_abbrev_end0: -.Lnames_entries0: -.Lnames0: -.L1: - .byte 1 # Abbreviation code - .long 35 # DW_IDX_die_offset - .byte 0 # DW_IDX_parent - # End of list: main -.Lnames1: -.L0: - .byte 2 # Abbreviation code - .long 73 # DW_IDX_die_offset - .byte 0 # DW_IDX_parent - # End of list: int -.Lnames2: -.L2: - .byte 2 # Abbreviation code - .long 87 # DW_IDX_die_offset - .byte 0 # DW_IDX_parent - # End of list: char - .p2align 2, 0x0 -.Lnames_end0: - .ident "clang version 19.0.0git (git@github.com:llvm/llvm-project.git 53b14cd9ce2b57da73d173fc876d2e9e199f5640)" - .section ".note.GNU-stack","",@progbits - .addrsig - .section .debug_line,"",@progbits -.Lline_table_start0: diff --git a/lld/test/ELF/debug-names-bad.s b/lld/test/ELF/debug-names-bad.s index 4b0c0b9bbf4e4..6d644514172fe 100644 --- a/lld/test/ELF/debug-names-bad.s +++ b/lld/test/ELF/debug-names-bad.s @@ -22,6 +22,12 @@ # ENTRY-OFFSET-IN-BYTE-COUNT-2: error: entry-offset-in-byte.o:(.debug_names): index entry is out of bounds ## Test errors in the abbrev table. +# RUN: sed -E '/DW_IDX_parent/{n;s/[0-9]+.*DW_FORM_flag_present/16/}' %S/Inputs/debug-names-a.s > bad-parent-form.s +# RUN: llvm-mc -filetype=obj -triple=x86_64 bad-parent-form.s -o bad-parent-form.o +# RUN: not ld.lld --debug-names bad-parent-form.o 2>&1 | FileCheck %s --check-prefix=BAD-PARENT-FORM --implicit-check-not=error: + +# BAD-PARENT-FORM-COUNT-2: error: bad-parent-form.o:(.debug_names): invalid form for DW_IDX_parent + # RUN: sed -E '/DW_IDX_die_offset/{n;s/[0-9]+.*DW_FORM_ref4/16/}' %S/Inputs/debug-names-a.s > bad-die-form.s # RUN: llvm-mc -filetype=obj -triple=x86_64 bad-die-form.s -o bad-die-form.o # RUN: not ld.lld --debug-names bad-die-form.o 2>&1 | FileCheck %s --check-prefix=BAD-DIE-FORM --implicit-check-not=error: diff --git a/lld/test/ELF/debug-names-dwarf64.s b/lld/test/ELF/debug-names-dwarf64.s index 0bbceff8cb0ce..8261e9e2d01c7 100644 --- a/lld/test/ELF/debug-names-dwarf64.s +++ b/lld/test/ELF/debug-names-dwarf64.s @@ -10,7 +10,7 @@ struct t1 {}; extern "C" void _start(t1) {} //--- gen -clang -S -g -gpubnames -gdwarf64 a.cc -o - +clang --target=x86_64-linux -S -g -gpubnames -gdwarf64 a.cc -o - .endif .text .file "a.cc" diff --git a/lld/test/ELF/debug-names-invalid-parent-idx.s b/lld/test/ELF/debug-names-invalid-parent-idx.s deleted file mode 100644 index 5db11ee10b32e..0000000000000 --- a/lld/test/ELF/debug-names-invalid-parent-idx.s +++ /dev/null @@ -1,153 +0,0 @@ -# This file was generated by: -# clang++ -g -O0 -S -fdebug-compilation-dir='/proc/self/cwd' \ -# -gpubnames a.cpp - -# Then manually editing .debug_names section, changing the form for a -# DW_IDX_parent from DW_FORM_flag_present to DW_FORM_ref1 (invalid). - -# Contents of a.cpp -# int main (int argc, char **argv) { } - -# REQUIRES: x86 -# RUN: llvm-mc -filetype=obj -triple=x86_64 %s -o %t1.o -# RUN: not ld.lld --debug-names %t1.o -o /dev/null 2>&1 \ -# RUN: | FileCheck -DFILE=%t1.o --implicit-check-not=error: %s - -# CHECK: error: [[FILE]]:(.debug_names): invalid form for DW_IDX_parent -# CHECK: error: [[FILE]]:(.debug_names): invalid form for DW_IDX_parent - - .text - .globl main # -- Begin function main - .p2align 4, 0x90 - .type main,@function -main: # @main -.Lfunc_begin0: - .file 0 "/proc/self/cwd" "a.cpp" md5 0xb5f4ba9cf33ca376f9981b3284aa785f - .cfi_startproc -# %bb.0: # %entry - pushq %rbp - .cfi_def_cfa_offset 16 - .cfi_offset %rbp, -16 - movq %rsp, %rbp - .cfi_def_cfa_register %rbp - movl %edi, -4(%rbp) - movq %rsi, -16(%rbp) -.Ltmp0: - xorl %eax, %eax - popq %rbp - .cfi_def_cfa %rsp, 8 - retq -.Ltmp1: -.Lfunc_end0: - .size main, .Lfunc_end0-main - .cfi_endproc - # -- End function - .section .debug_abbrev,"",@progbits - .byte 0 # EOM(1) - .byte 0 # EOM(2) - .byte 0 # EOM(3) - .section .debug_info,"",@progbits -.Lcu_begin0: - .long .Ldebug_info_end0-.Ldebug_info_start0 # Length of Unit -.Ldebug_info_start0: - .short 5 # DWARF version number - .byte 1 # DWARF Unit Type - .byte 8 # Address Size (in bytes) - .long .debug_abbrev # Offset Into Abbrev. Section -.Ldebug_info_end0: - .section .debug_str_offsets,"",@progbits - .long 36 # Length of String Offsets Set - .short 5 - .short 0 -.Lstr_offsets_base0: - .section .debug_str,"MS",@progbits,1 -.Linfo_string0: - .asciz "clang version 19.0.0git (git@github.com:llvm/llvm-project.git 53b14cd9ce2b57da73d173fc876d2e9e199f5640)" # string offset=0 -.Linfo_string1: - .asciz "a.cpp" # string offset=104 -.Linfo_string2: - .asciz "/proc/self/cwd" # string offset=110 -.Linfo_string3: - .asciz "main" # string offset=125 -.Linfo_string4: - .asciz "int" # string offset=130 -.Linfo_string5: - .asciz "argc" # string offset=134 -.Linfo_string6: - .asciz "argv" # string offset=139 -.Linfo_string7: - .asciz "char" # string offset=144 -.Laddr_table_base0: - .quad .Lfunc_begin0 -.Ldebug_addr_end0: - .section .debug_names,"",@progbits - .long .Lnames_end0-.Lnames_start0 # Header: unit length -.Lnames_start0: - .short 5 # Header: version - .short 0 # Header: padding - .long 1 # Header: compilation unit count - .long 0 # Header: local type unit count - .long 0 # Header: foreign type unit count - .long 3 # Header: bucket count - .long 3 # Header: name count - .long .Lnames_abbrev_end0-.Lnames_abbrev_start0 # Header: abbreviation table size - .long 8 # Header: augmentation string size - .ascii "LLVM0700" # Header: augmentation string - .long .Lcu_begin0 # Compilation unit 0 - .long 0 # Bucket 0 - .long 1 # Bucket 1 - .long 2 # Bucket 2 - .long 2090499946 # Hash in Bucket 1 - .long 193495088 # Hash in Bucket 2 - .long 2090147939 # Hash in Bucket 2 - .long .Linfo_string3 # String in Bucket 1: main - .long .Linfo_string4 # String in Bucket 2: int - .long .Linfo_string7 # String in Bucket 2: char - .long .Lnames0-.Lnames_entries0 # Offset in Bucket 1 - .long .Lnames1-.Lnames_entries0 # Offset in Bucket 2 - .long .Lnames2-.Lnames_entries0 # Offset in Bucket 2 -.Lnames_abbrev_start0: - .byte 1 # Abbrev code - .byte 46 # DW_TAG_subprogram - .byte 3 # DW_IDX_die_offset - .byte 19 # DW_FORM_ref4 - .byte 4 # DW_IDX_parent - .byte 25 # DW_FORM_flag_present - .byte 0 # End of abbrev - .byte 0 # End of abbrev - .byte 2 # Abbrev code - .byte 36 # DW_TAG_base_type - .byte 3 # DW_IDX_die_offset - .byte 19 # DW_FORM_ref4 - .byte 4 # DW_IDX_parent - .byte 17 # DW_FORM_ref1 - .byte 0 # End of abbrev - .byte 0 # End of abbrev - .byte 0 # End of abbrev list -.Lnames_abbrev_end0: -.Lnames_entries0: -.Lnames0: -.L1: - .byte 1 # Abbreviation code - .long 35 # DW_IDX_die_offset - .byte 0 # DW_IDX_parent - # End of list: main -.Lnames1: -.L0: - .byte 2 # Abbreviation code - .long 73 # DW_IDX_die_offset - .byte 0 # DW_IDX_parent - # End of list: int -.Lnames2: -.L2: - .byte 2 # Abbreviation code - .long 87 # DW_IDX_die_offset - .byte 0 # DW_IDX_parent - # End of list: char - .p2align 2, 0x0 -.Lnames_end0: - .ident "clang version 19.0.0git (git@github.com:llvm/llvm-project.git 53b14cd9ce2b57da73d173fc876d2e9e199f5640)" - .section ".note.GNU-stack","",@progbits - .addrsig - .section .debug_line,"",@progbits -.Lline_table_start0: diff --git a/lld/test/ELF/debug-names-missing-parent.s b/lld/test/ELF/debug-names-missing-parent.s index 480d047504934..7140157b01d84 100644 --- a/lld/test/ELF/debug-names-missing-parent.s +++ b/lld/test/ELF/debug-names-missing-parent.s @@ -1,121 +1,106 @@ -# debug-names-missing-parent was generated with - -# clang++ -g -O0 -S -fdebug-compilation-dir='/proc/self/cwd' \ -# -gpubnames a.cpp - -# a.cpp contents: - -# int main (int argc, char **argv) { } - -# Then manually edit the .s file: -# - Remove DW_IDX_parent & DW_FORM_flag_present from DW_TAG_subprogram abbrev -# - Remove DW_IDX_parent value from entry for 'main' - # REQUIRES: x86 -# RUN: llvm-mc -filetype=obj -triple=x86_64 %s -o %t1.o -# RUN: ld.lld --debug-names %t1.o -o %t -# RUN: llvm-dwarfdump --debug-names %t | FileCheck %s --check-prefix=DWARF +## Test clang-17-generated DW_TAG_subprogram, which do not contain DW_IDX_parent +## attributes. -# DWARF: .debug_names contents: -# DWARF: Name Index @ 0x0 { -# DWARF-NEXT: Header { -# DWARF-NEXT: Length: 0x8A -# DWARF-NEXT: Format: DWARF32 -# DWARF-NEXT: Version: 5 -# DWARF-NEXT: CU count: 1 -# DWARF-NEXT: Local TU count: 0 -# DWARF-NEXT: Foreign TU count: 0 -# DWARF-NEXT: Bucket count: 3 -# DWARF-NEXT: Name count: 3 -# DWARF-NEXT: Abbreviations table size: 0x13 -# DWARF-NEXT: Augmentation: 'LLVM0700' -# DWARF: Compilation Unit offsets [ -# DWARF-NEXT: CU[0]: 0x00000000 -# DWARF: Abbreviations [ -# DWARF-NEXT: Abbreviation 0x1 { -# DWARF: Tag: DW_TAG_base_type -# DWARF-NEXT: DW_IDX_die_offset: DW_FORM_ref4 -# DWARF-NEXT: DW_IDX_parent: DW_FORM_flag_present -# DWARF-NEXT: DW_IDX_compile_unit: DW_FORM_data1 -# DWARF: Abbreviation 0x2 { -# DWARF-NEXT: Tag: DW_TAG_subprogram -# DWARF-NEXT: DW_IDX_die_offset: DW_FORM_ref4 -# DWARF-NEXT: DW_IDX_compile_unit: DW_FORM_data1 -# DWARF: Bucket 0 [ -# DWARF-NEXT: EMPTY -# DWARF-NEXT: ] -# DWARF-NEXT: Bucket 1 [ -# DWARF-NEXT: Name 1 { -# DWARF-NEXT: Hash: 0x7C9A7F6A -# DWARF-NEXT: String: 0x0000007d "main" -# DWARF-NEXT: Entry @ 0x7a { -# DWARF-NEXT: Abbrev: 0x2 -# DWARF-NEXT: Tag: DW_TAG_subprogram -# DWARF-NEXT: DW_IDX_die_offset: 0x00000023 -# DWARF-NEXT: DW_IDX_compile_unit: 0x00 -# DWARF-NEXT: } -# DWARF-NEXT: Entry @ 0x80 { -# DWARF-NEXT: Abbrev: 0x1 -# DWARF-NEXT: Tag: DW_TAG_base_type -# DWARF-NEXT: DW_IDX_die_offset: 0x00000049 -# DWARF-NEXT: DW_IDX_parent: -# DWARF-NEXT: DW_IDX_compile_unit: 0x00 -# DWARF-NEXT: } -# DWARF-NEXT: } -# DWARF-NEXT: ] -# DWARF-NEXT: Bucket 2 [ -# DWARF-NEXT: Name 2 { -# DWARF-NEXT: Hash: 0xB888030 -# DWARF-NEXT: String: 0x00000082 "int" -# DWARF-NEXT: Entry @ 0x73 { -# DWARF-NEXT: Abbrev: 0x1 -# DWARF-NEXT: Tag: DW_TAG_base_type -# DWARF-NEXT: DW_IDX_die_offset: 0x00000049 -# DWARF-NEXT: DW_IDX_parent: -# DWARF-NEXT: DW_IDX_compile_unit: 0x00 -# DWARF-NEXT: } -# DWARF-NEXT: } -# DWARF-NEXT: Name 3 { -# DWARF-NEXT: Hash: 0x7C952063 -# DWARF-NEXT: String: 0x0000008b "char" -# DWARF-NEXT: Entry @ 0x87 { -# DWARF-NEXT: Abbrev: 0x1 -# DWARF-NEXT: Tag: DW_TAG_base_type -# DWARF-NEXT: DW_IDX_die_offset: 0x00000057 -# DWARF-NEXT: DW_IDX_parent: -# DWARF-NEXT: DW_IDX_compile_unit: 0x00 -# DWARF-NEXT: } -# DWARF-NEXT: } -# DWARF-NEXT: ] +# RUN: llvm-mc -filetype=obj -triple=x86_64 %s -o %t.o +# RUN: ld.lld --debug-names %t.o -o %t +# RUN: llvm-dwarfdump --debug-info --debug-names %t | FileCheck %s --check-prefix=DWARF -# --- a.s +# DWARF: 0x00000023: DW_TAG_namespace +# DWARF: 0x00000025: DW_TAG_subprogram +# DWARF: String: {{.*}} "fa" +# DWARF-NEXT: Entry @ 0x71 { +# DWARF-NEXT: Abbrev: 0x1 +# DWARF-NEXT: Tag: DW_TAG_subprogram +# DWARF-NEXT: DW_IDX_die_offset: 0x00000025 +# DWARF-NEXT: DW_IDX_compile_unit: 0x00 +# DWARF-NEXT: } +# DWARF: String: {{.*}} "ns" +# DWARF-NEXT: Entry @ 0x78 { +# DWARF-NEXT: Abbrev: 0x2 +# DWARF-NEXT: Tag: DW_TAG_namespace +# DWARF-NEXT: DW_IDX_die_offset: 0x00000023 +# DWARF-NEXT: DW_IDX_compile_unit: 0x00 +# DWARF-NEXT: } + +.ifdef GEN +//--- a.cc +namespace ns { +void fa() {} +} +//--- gen +clang-17 --target=x86_64-linux -S -O1 -g -gpubnames a.cc -o - +.endif .text - .globl main # -- Begin function main + .file "a.cc" + .globl _ZN2ns2faEv # -- Begin function _ZN2ns2faEv .p2align 4, 0x90 - .type main,@function -main: # @main + .type _ZN2ns2faEv,@function +_ZN2ns2faEv: # @_ZN2ns2faEv .Lfunc_begin0: + .file 0 "/proc/self/cwd" "a.cc" md5 0xb3281d5b5a0b2997d7d59d49bc912274 .cfi_startproc -# %bb.0: # %entry - pushq %rbp - .cfi_def_cfa_offset 16 - .cfi_offset %rbp, -16 - movq %rsp, %rbp - .cfi_def_cfa_register %rbp - movl %edi, -4(%rbp) - movq %rsi, -16(%rbp) -.Ltmp0: - xorl %eax, %eax - popq %rbp - .cfi_def_cfa %rsp, 8 +# %bb.0: + .loc 0 2 12 prologue_end # a.cc:2:12 retq -.Ltmp1: +.Ltmp0: .Lfunc_end0: - .size main, .Lfunc_end0-main + .size _ZN2ns2faEv, .Lfunc_end0-_ZN2ns2faEv .cfi_endproc # -- End function .section .debug_abbrev,"",@progbits + .byte 1 # Abbreviation Code + .byte 17 # DW_TAG_compile_unit + .byte 1 # DW_CHILDREN_yes + .byte 37 # DW_AT_producer + .byte 37 # DW_FORM_strx1 + .byte 19 # DW_AT_language + .byte 5 # DW_FORM_data2 + .byte 3 # DW_AT_name + .byte 37 # DW_FORM_strx1 + .byte 114 # DW_AT_str_offsets_base + .byte 23 # DW_FORM_sec_offset + .byte 16 # DW_AT_stmt_list + .byte 23 # DW_FORM_sec_offset + .byte 27 # DW_AT_comp_dir + .byte 37 # DW_FORM_strx1 + .byte 17 # DW_AT_low_pc + .byte 27 # DW_FORM_addrx + .byte 18 # DW_AT_high_pc + .byte 6 # DW_FORM_data4 + .byte 115 # DW_AT_addr_base + .byte 23 # DW_FORM_sec_offset + .byte 0 # EOM(1) + .byte 0 # EOM(2) + .byte 2 # Abbreviation Code + .byte 57 # DW_TAG_namespace + .byte 1 # DW_CHILDREN_yes + .byte 3 # DW_AT_name + .byte 37 # DW_FORM_strx1 + .byte 0 # EOM(1) + .byte 0 # EOM(2) + .byte 3 # Abbreviation Code + .byte 46 # DW_TAG_subprogram + .byte 0 # DW_CHILDREN_no + .byte 17 # DW_AT_low_pc + .byte 27 # DW_FORM_addrx + .byte 18 # DW_AT_high_pc + .byte 6 # DW_FORM_data4 + .byte 64 # DW_AT_frame_base + .byte 24 # DW_FORM_exprloc + .byte 122 # DW_AT_call_all_calls + .byte 25 # DW_FORM_flag_present + .byte 110 # DW_AT_linkage_name + .byte 37 # DW_FORM_strx1 + .byte 3 # DW_AT_name + .byte 37 # DW_FORM_strx1 + .byte 58 # DW_AT_decl_file + .byte 11 # DW_FORM_data1 + .byte 59 # DW_AT_decl_line + .byte 11 # DW_FORM_data1 + .byte 63 # DW_AT_external + .byte 25 # DW_FORM_flag_present .byte 0 # EOM(1) .byte 0 # EOM(2) .byte 0 # EOM(3) @@ -127,30 +112,63 @@ main: # @main .byte 1 # DWARF Unit Type .byte 8 # Address Size (in bytes) .long .debug_abbrev # Offset Into Abbrev. Section + .byte 1 # Abbrev [1] 0xc:0x27 DW_TAG_compile_unit + .byte 0 # DW_AT_producer + .short 33 # DW_AT_language + .byte 1 # DW_AT_name + .long .Lstr_offsets_base0 # DW_AT_str_offsets_base + .long .Lline_table_start0 # DW_AT_stmt_list + .byte 2 # DW_AT_comp_dir + .byte 0 # DW_AT_low_pc + .long .Lfunc_end0-.Lfunc_begin0 # DW_AT_high_pc + .long .Laddr_table_base0 # DW_AT_addr_base + .byte 2 # Abbrev [2] 0x23:0xf DW_TAG_namespace + .byte 3 # DW_AT_name + .byte 3 # Abbrev [3] 0x25:0xc DW_TAG_subprogram + .byte 0 # DW_AT_low_pc + .long .Lfunc_end0-.Lfunc_begin0 # DW_AT_high_pc + .byte 1 # DW_AT_frame_base + .byte 87 + # DW_AT_call_all_calls + .byte 4 # DW_AT_linkage_name + .byte 5 # DW_AT_name + .byte 0 # DW_AT_decl_file + .byte 2 # DW_AT_decl_line + # DW_AT_external + .byte 0 # End Of Children Mark + .byte 0 # End Of Children Mark .Ldebug_info_end0: .section .debug_str_offsets,"",@progbits - .long 36 # Length of String Offsets Set + .long 28 # Length of String Offsets Set .short 5 .short 0 .Lstr_offsets_base0: .section .debug_str,"MS",@progbits,1 .Linfo_string0: - .asciz "clang version 19.0.0git (git@github.com:llvm/llvm-project.git 53b14cd9ce2b57da73d173fc876d2e9e199f5640)" # string offset=0 + .byte 0 # string offset=0 .Linfo_string1: - .asciz "a.cpp" # string offset=104 + .asciz "a.cc" # string offset=1 .Linfo_string2: - .asciz "/proc/self/cwd" # string offset=110 + .asciz "/proc/self/cwd" # string offset=6 .Linfo_string3: - .asciz "main" # string offset=125 + .asciz "ns" # string offset=21 .Linfo_string4: - .asciz "int" # string offset=130 + .asciz "fa" # string offset=24 .Linfo_string5: - .asciz "argc" # string offset=134 -.Linfo_string6: - .asciz "argv" # string offset=139 -.Linfo_string7: - .asciz "char" # string offset=144 + .asciz "_ZN2ns2faEv" # string offset=27 .section .debug_str_offsets,"",@progbits + .long .Linfo_string0 + .long .Linfo_string1 + .long .Linfo_string2 + .long .Linfo_string3 + .long .Linfo_string5 + .long .Linfo_string4 + .section .debug_addr,"",@progbits + .long .Ldebug_addr_end0-.Ldebug_addr_start0 # Length of contribution +.Ldebug_addr_start0: + .short 5 # DWARF version number + .byte 8 # Address size + .byte 0 # Segment selector size .Laddr_table_base0: .quad .Lfunc_begin0 .Ldebug_addr_end0: @@ -170,54 +188,46 @@ main: # @main .long .Lcu_begin0 # Compilation unit 0 .long 0 # Bucket 0 .long 1 # Bucket 1 - .long 2 # Bucket 2 - .long 2090499946 # Hash in Bucket 1 - .long 193495088 # Hash in Bucket 2 - .long 2090147939 # Hash in Bucket 2 - .long .Linfo_string3 # String in Bucket 1: main - .long .Linfo_string4 # String in Bucket 2: int - .long .Linfo_string7 # String in Bucket 2: char + .long 3 # Bucket 2 + .long 5863372 # Hash in Bucket 1 + .long 5863654 # Hash in Bucket 1 + .long -1413999533 # Hash in Bucket 2 + .long .Linfo_string4 # String in Bucket 1: fa + .long .Linfo_string3 # String in Bucket 1: ns + .long .Linfo_string5 # String in Bucket 2: _ZN2ns2faEv + .long .Lnames1-.Lnames_entries0 # Offset in Bucket 1 .long .Lnames0-.Lnames_entries0 # Offset in Bucket 1 - .long .Lnames1-.Lnames_entries0 # Offset in Bucket 2 .long .Lnames2-.Lnames_entries0 # Offset in Bucket 2 .Lnames_abbrev_start0: - .byte 1 # Abbrev code + .byte 46 # Abbrev code .byte 46 # DW_TAG_subprogram .byte 3 # DW_IDX_die_offset .byte 19 # DW_FORM_ref4 .byte 0 # End of abbrev .byte 0 # End of abbrev - .byte 2 # Abbrev code - .byte 36 # DW_TAG_base_type + .byte 57 # Abbrev code + .byte 57 # DW_TAG_namespace .byte 3 # DW_IDX_die_offset .byte 19 # DW_FORM_ref4 - .byte 4 # DW_IDX_parent - .byte 25 # DW_FORM_flag_present .byte 0 # End of abbrev .byte 0 # End of abbrev .byte 0 # End of abbrev list .Lnames_abbrev_end0: .Lnames_entries0: +.Lnames1: + .byte 46 # Abbreviation code + .long 37 # DW_IDX_die_offset + .byte 0 # End of list: fa .Lnames0: -.L1: - .byte 1 # Abbreviation code + .byte 57 # Abbreviation code .long 35 # DW_IDX_die_offset - # End of list: main -.Lnames1: -.L0: - .byte 2 # Abbreviation code - .long 73 # DW_IDX_die_offset - .byte 0 # DW_IDX_parent - # End of list: int + .byte 0 # End of list: ns .Lnames2: -.L2: - .byte 2 # Abbreviation code - .long 87 # DW_IDX_die_offset - .byte 0 # DW_IDX_parent - # End of list: char + .byte 46 # Abbreviation code + .long 37 # DW_IDX_die_offset + .byte 0 # End of list: _ZN2ns2faEv .p2align 2, 0x0 .Lnames_end0: - .ident "clang version 19.0.0git (git@github.com:llvm/llvm-project.git 53b14cd9ce2b57da73d173fc876d2e9e199f5640)" .section ".note.GNU-stack","",@progbits .addrsig .section .debug_line,"",@progbits diff --git a/lld/test/ELF/debug-names-multi-cus.s b/lld/test/ELF/debug-names-multi-cus.s index 19e99be58e701..78fcdc227ef25 100644 --- a/lld/test/ELF/debug-names-multi-cus.s +++ b/lld/test/ELF/debug-names-multi-cus.s @@ -1,10 +1,10 @@ # REQUIRES: x86 ## Test name indexes that contain multiple CU offsets due to LTO. -# RUN: rm -rf %t && mkdir %t && cd %t +# RUN: rm -rf %t && split-file %s %t && cd %t # RUN: llvm-mc -filetype=obj -triple=x86_64 %S/Inputs/debug-names-a.s -o a.o -# RUN: llvm-mc -filetype=obj -triple=x86_64 %S/Inputs/debug-names-bcd.s -o bcd.o -# RUN: llvm-mc -filetype=obj -triple=x86_64 %S/Inputs/debug-names-ef.s -o ef.o +# RUN: llvm-mc -filetype=obj -triple=x86_64 bcd.s -o bcd.o +# RUN: llvm-mc -filetype=obj -triple=x86_64 ef.s -o ef.o # RUN: ld.lld --debug-names a.o bcd.o ef.o -o out # RUN: llvm-dwarfdump --debug-info --debug-names out | FileCheck %s --check-prefix=DWARF @@ -13,20 +13,19 @@ # RUN: ld.lld --debug-names abcd.o ef.o -o out # RUN: llvm-dwarfdump --debug-info --debug-names out | FileCheck %s --check-prefix=DWARF -# DWARF: 0x00000000: Compile Unit -# DWARF: 0x00000040: Compile Unit -# DWARF: 0x0000006e: Compile Unit -# DWARF: 0x00000098: Compile Unit -# DWARF: 0x000000c6: Compile Unit -# DWARF: 0x000000f4: Compile Unit - +# DWARF: [[CU0:0x[^:]+]]: Compile Unit +# DWARF: [[CU1:0x[^:]+]]: Compile Unit +# DWARF: [[CU2:0x[^:]+]]: Compile Unit +# DWARF: [[CU3:0x[^:]+]]: Compile Unit +# DWARF: [[CU4:0x[^:]+]]: Compile Unit +# DWARF: [[CU5:0x[^:]+]]: Compile Unit # DWARF: Compilation Unit offsets [ -# DWARF-NEXT: CU[0]: 0x00000000 -# DWARF-NEXT: CU[1]: 0x00000040 -# DWARF-NEXT: CU[2]: 0x0000006e -# DWARF-NEXT: CU[3]: 0x00000098 -# DWARF-NEXT: CU[4]: 0x000000c6 -# DWARF-NEXT: CU[5]: 0x000000f4 +# DWARF-NEXT: CU[0]: [[CU0]] +# DWARF-NEXT: CU[1]: [[CU1]] +# DWARF-NEXT: CU[2]: [[CU2]] +# DWARF-NEXT: CU[3]: [[CU3]] +# DWARF-NEXT: CU[4]: [[CU4]] +# DWARF-NEXT: CU[5]: [[CU5]] # DWARF-NEXT: ] # DWARF: String: {{.*}} "vc" # DWARF: DW_IDX_compile_unit: 0x02 @@ -46,3 +45,745 @@ # DWARF: String: {{.*}} "vb" # DWARF: DW_IDX_compile_unit: # DWARF-SAME: 0x01 + +.ifdef GEN +#--- b.cc +[[gnu::used]] int vb; +#--- c.cc +[[gnu::used]] int vc; +#--- d.cc +namespace ns { +[[gnu::used]] int vd; +} + +//--- e.cc +[[gnu::used]] int ve; +//--- f.cc +namespace ns { +[[gnu::used]] int vf; +} + +#--- gen +clang --target=x86_64-linux -O1 -g -gpubnames -flto b.cc c.cc d.cc -nostdlib -fuse-ld=lld -Wl,--lto-emit-asm +echo '#--- bcd.s' +cat a.out.lto.s +clang --target=x86_64-linux -O1 -g -gpubnames -flto e.cc f.cc -nostdlib -fuse-ld=lld -Wl,--lto-emit-asm +echo '#--- ef.s' +cat a.out.lto.s +.endif +#--- bcd.s + .text + .file "ld-temp.o" + .file 1 "/proc/self/cwd" "b.cc" md5 0x78dad32a49063326a4de543198e54944 + .file 2 "/proc/self/cwd" "c.cc" md5 0x7a0f7bf2cb0ec8c297f794908d91ab1b + .file 3 "/proc/self/cwd" "d.cc" md5 0xf7e2af89615ce48bf9a98fdae55ab5ad + .type vb,@object # @vb + .section .bss.vb,"aw",@nobits + .globl vb + .p2align 2, 0x0 +vb: + .long 0 # 0x0 + .size vb, 4 + + .type vc,@object # @vc + .section .bss.vc,"aw",@nobits + .globl vc + .p2align 2, 0x0 +vc: + .long 0 # 0x0 + .size vc, 4 + + .type _ZN2ns2vdE,@object # @_ZN2ns2vdE + .section .bss._ZN2ns2vdE,"aw",@nobits + .globl _ZN2ns2vdE + .p2align 2, 0x0 +_ZN2ns2vdE: + .long 0 # 0x0 + .size _ZN2ns2vdE, 4 + + .section .debug_abbrev,"",@progbits + .byte 1 # Abbreviation Code + .byte 17 # DW_TAG_compile_unit + .byte 1 # DW_CHILDREN_yes + .byte 37 # DW_AT_producer + .byte 37 # DW_FORM_strx1 + .byte 19 # DW_AT_language + .byte 5 # DW_FORM_data2 + .byte 3 # DW_AT_name + .byte 37 # DW_FORM_strx1 + .byte 114 # DW_AT_str_offsets_base + .byte 23 # DW_FORM_sec_offset + .byte 16 # DW_AT_stmt_list + .byte 23 # DW_FORM_sec_offset + .byte 27 # DW_AT_comp_dir + .byte 37 # DW_FORM_strx1 + .byte 115 # DW_AT_addr_base + .byte 23 # DW_FORM_sec_offset + .byte 0 # EOM(1) + .byte 0 # EOM(2) + .byte 2 # Abbreviation Code + .byte 52 # DW_TAG_variable + .byte 0 # DW_CHILDREN_no + .byte 3 # DW_AT_name + .byte 37 # DW_FORM_strx1 + .byte 73 # DW_AT_type + .byte 19 # DW_FORM_ref4 + .byte 63 # DW_AT_external + .byte 25 # DW_FORM_flag_present + .byte 58 # DW_AT_decl_file + .byte 11 # DW_FORM_data1 + .byte 59 # DW_AT_decl_line + .byte 11 # DW_FORM_data1 + .byte 2 # DW_AT_location + .byte 24 # DW_FORM_exprloc + .byte 0 # EOM(1) + .byte 0 # EOM(2) + .byte 3 # Abbreviation Code + .byte 36 # DW_TAG_base_type + .byte 0 # DW_CHILDREN_no + .byte 3 # DW_AT_name + .byte 37 # DW_FORM_strx1 + .byte 62 # DW_AT_encoding + .byte 11 # DW_FORM_data1 + .byte 11 # DW_AT_byte_size + .byte 11 # DW_FORM_data1 + .byte 0 # EOM(1) + .byte 0 # EOM(2) + .byte 4 # Abbreviation Code + .byte 52 # DW_TAG_variable + .byte 0 # DW_CHILDREN_no + .byte 3 # DW_AT_name + .byte 37 # DW_FORM_strx1 + .byte 73 # DW_AT_type + .byte 16 # DW_FORM_ref_addr + .byte 63 # DW_AT_external + .byte 25 # DW_FORM_flag_present + .byte 58 # DW_AT_decl_file + .byte 11 # DW_FORM_data1 + .byte 59 # DW_AT_decl_line + .byte 11 # DW_FORM_data1 + .byte 2 # DW_AT_location + .byte 24 # DW_FORM_exprloc + .byte 0 # EOM(1) + .byte 0 # EOM(2) + .byte 5 # Abbreviation Code + .byte 57 # DW_TAG_namespace + .byte 1 # DW_CHILDREN_yes + .byte 3 # DW_AT_name + .byte 37 # DW_FORM_strx1 + .byte 0 # EOM(1) + .byte 0 # EOM(2) + .byte 6 # Abbreviation Code + .byte 52 # DW_TAG_variable + .byte 0 # DW_CHILDREN_no + .byte 3 # DW_AT_name + .byte 37 # DW_FORM_strx1 + .byte 73 # DW_AT_type + .byte 16 # DW_FORM_ref_addr + .byte 63 # DW_AT_external + .byte 25 # DW_FORM_flag_present + .byte 58 # DW_AT_decl_file + .byte 11 # DW_FORM_data1 + .byte 59 # DW_AT_decl_line + .byte 11 # DW_FORM_data1 + .byte 2 # DW_AT_location + .byte 24 # DW_FORM_exprloc + .byte 110 # DW_AT_linkage_name + .byte 37 # DW_FORM_strx1 + .byte 0 # EOM(1) + .byte 0 # EOM(2) + .byte 0 # EOM(3) + .section .debug_info,"",@progbits +.Lcu_begin0: + .long .Ldebug_info_end0-.Ldebug_info_start0 # Length of Unit +.Ldebug_info_start0: + .short 5 # DWARF version number + .byte 1 # DWARF Unit Type + .byte 8 # Address Size (in bytes) + .long .debug_abbrev # Offset Into Abbrev. Section + .byte 1 # Abbrev [1] 0xc:0x22 DW_TAG_compile_unit + .byte 0 # DW_AT_producer + .short 33 # DW_AT_language + .byte 1 # DW_AT_name + .long .Lstr_offsets_base0 # DW_AT_str_offsets_base + .long .Lline_table_start0 # DW_AT_stmt_list + .byte 2 # DW_AT_comp_dir + .long .Laddr_table_base0 # DW_AT_addr_base + .byte 2 # Abbrev [2] 0x1e:0xb DW_TAG_variable + .byte 3 # DW_AT_name + .long 41 # DW_AT_type + # DW_AT_external + .byte 1 # DW_AT_decl_file + .byte 1 # DW_AT_decl_line + .byte 2 # DW_AT_location + .byte 161 + .byte 0 + .byte 3 # Abbrev [3] 0x29:0x4 DW_TAG_base_type + .byte 4 # DW_AT_name + .byte 5 # DW_AT_encoding + .byte 4 # DW_AT_byte_size + .byte 0 # End Of Children Mark +.Ldebug_info_end0: +.Lcu_begin1: + .long .Ldebug_info_end1-.Ldebug_info_start1 # Length of Unit +.Ldebug_info_start1: + .short 5 # DWARF version number + .byte 1 # DWARF Unit Type + .byte 8 # Address Size (in bytes) + .long .debug_abbrev # Offset Into Abbrev. Section + .byte 1 # Abbrev [1] 0xc:0x1e DW_TAG_compile_unit + .byte 0 # DW_AT_producer + .short 33 # DW_AT_language + .byte 5 # DW_AT_name + .long .Lstr_offsets_base0 # DW_AT_str_offsets_base + .long .Lline_table_start0 # DW_AT_stmt_list + .byte 2 # DW_AT_comp_dir + .long .Laddr_table_base0 # DW_AT_addr_base + .byte 4 # Abbrev [4] 0x1e:0xb DW_TAG_variable + .byte 6 # DW_AT_name + .long .debug_info+41 # DW_AT_type + # DW_AT_external + .byte 2 # DW_AT_decl_file + .byte 1 # DW_AT_decl_line + .byte 2 # DW_AT_location + .byte 161 + .byte 1 + .byte 0 # End Of Children Mark +.Ldebug_info_end1: +.Lcu_begin2: + .long .Ldebug_info_end2-.Ldebug_info_start2 # Length of Unit +.Ldebug_info_start2: + .short 5 # DWARF version number + .byte 1 # DWARF Unit Type + .byte 8 # Address Size (in bytes) + .long .debug_abbrev # Offset Into Abbrev. Section + .byte 1 # Abbrev [1] 0xc:0x22 DW_TAG_compile_unit + .byte 0 # DW_AT_producer + .short 33 # DW_AT_language + .byte 7 # DW_AT_name + .long .Lstr_offsets_base0 # DW_AT_str_offsets_base + .long .Lline_table_start0 # DW_AT_stmt_list + .byte 2 # DW_AT_comp_dir + .long .Laddr_table_base0 # DW_AT_addr_base + .byte 5 # Abbrev [5] 0x1e:0xf DW_TAG_namespace + .byte 8 # DW_AT_name + .byte 6 # Abbrev [6] 0x20:0xc DW_TAG_variable + .byte 9 # DW_AT_name + .long .debug_info+41 # DW_AT_type + # DW_AT_external + .byte 3 # DW_AT_decl_file + .byte 2 # DW_AT_decl_line + .byte 2 # DW_AT_location + .byte 161 + .byte 2 + .byte 10 # DW_AT_linkage_name + .byte 0 # End Of Children Mark + .byte 0 # End Of Children Mark +.Ldebug_info_end2: + .section .debug_str_offsets,"",@progbits + .long 48 # Length of String Offsets Set + .short 5 + .short 0 +.Lstr_offsets_base0: + .section .debug_str,"MS",@progbits,1 +.Linfo_string0: + .byte 0 # string offset=0 +.Linfo_string1: + .asciz "b.cc" # string offset=1 +.Linfo_string2: + .asciz "/proc/self/cwd" # string offset=6 +.Linfo_string3: + .asciz "vb" # string offset=21 +.Linfo_string4: + .asciz "int" # string offset=24 +.Linfo_string5: + .asciz "c.cc" # string offset=28 +.Linfo_string6: + .asciz "vc" # string offset=33 +.Linfo_string7: + .asciz "d.cc" # string offset=36 +.Linfo_string8: + .asciz "ns" # string offset=41 +.Linfo_string9: + .asciz "vd" # string offset=44 +.Linfo_string10: + .asciz "_ZN2ns2vdE" # string offset=47 + .section .debug_str_offsets,"",@progbits + .long .Linfo_string0 + .long .Linfo_string1 + .long .Linfo_string2 + .long .Linfo_string3 + .long .Linfo_string4 + .long .Linfo_string5 + .long .Linfo_string6 + .long .Linfo_string7 + .long .Linfo_string8 + .long .Linfo_string9 + .long .Linfo_string10 + .section .debug_addr,"",@progbits + .long .Ldebug_addr_end0-.Ldebug_addr_start0 # Length of contribution +.Ldebug_addr_start0: + .short 5 # DWARF version number + .byte 8 # Address size + .byte 0 # Segment selector size +.Laddr_table_base0: + .quad vb + .quad vc + .quad _ZN2ns2vdE +.Ldebug_addr_end0: + .section .debug_names,"",@progbits + .long .Lnames_end0-.Lnames_start0 # Header: unit length +.Lnames_start0: + .short 5 # Header: version + .short 0 # Header: padding + .long 3 # Header: compilation unit count + .long 0 # Header: local type unit count + .long 0 # Header: foreign type unit count + .long 6 # Header: bucket count + .long 6 # Header: name count + .long .Lnames_abbrev_end0-.Lnames_abbrev_start0 # Header: abbreviation table size + .long 8 # Header: augmentation string size + .ascii "LLVM0700" # Header: augmentation string + .long .Lcu_begin0 # Compilation unit 0 + .long .Lcu_begin1 # Compilation unit 1 + .long .Lcu_begin2 # Compilation unit 2 + .long 1 # Bucket 0 + .long 2 # Bucket 1 + .long 3 # Bucket 2 + .long 0 # Bucket 3 + .long 4 # Bucket 4 + .long 6 # Bucket 5 + .long 5863902 # Hash in Bucket 0 + .long 5863903 # Hash in Bucket 1 + .long 193495088 # Hash in Bucket 2 + .long 5863654 # Hash in Bucket 4 + .long -823734096 # Hash in Bucket 4 + .long 5863901 # Hash in Bucket 5 + .long .Linfo_string6 # String in Bucket 0: vc + .long .Linfo_string9 # String in Bucket 1: vd + .long .Linfo_string4 # String in Bucket 2: int + .long .Linfo_string8 # String in Bucket 4: ns + .long .Linfo_string10 # String in Bucket 4: _ZN2ns2vdE + .long .Linfo_string3 # String in Bucket 5: vb + .long .Lnames2-.Lnames_entries0 # Offset in Bucket 0 + .long .Lnames4-.Lnames_entries0 # Offset in Bucket 1 + .long .Lnames0-.Lnames_entries0 # Offset in Bucket 2 + .long .Lnames3-.Lnames_entries0 # Offset in Bucket 4 + .long .Lnames5-.Lnames_entries0 # Offset in Bucket 4 + .long .Lnames1-.Lnames_entries0 # Offset in Bucket 5 +.Lnames_abbrev_start0: + .byte 1 # Abbrev code + .byte 52 # DW_TAG_variable + .byte 1 # DW_IDX_compile_unit + .byte 11 # DW_FORM_data1 + .byte 3 # DW_IDX_die_offset + .byte 19 # DW_FORM_ref4 + .byte 4 # DW_IDX_parent + .byte 25 # DW_FORM_flag_present + .byte 0 # End of abbrev + .byte 0 # End of abbrev + .byte 2 # Abbrev code + .byte 52 # DW_TAG_variable + .byte 1 # DW_IDX_compile_unit + .byte 11 # DW_FORM_data1 + .byte 3 # DW_IDX_die_offset + .byte 19 # DW_FORM_ref4 + .byte 4 # DW_IDX_parent + .byte 19 # DW_FORM_ref4 + .byte 0 # End of abbrev + .byte 0 # End of abbrev + .byte 3 # Abbrev code + .byte 36 # DW_TAG_base_type + .byte 1 # DW_IDX_compile_unit + .byte 11 # DW_FORM_data1 + .byte 3 # DW_IDX_die_offset + .byte 19 # DW_FORM_ref4 + .byte 4 # DW_IDX_parent + .byte 25 # DW_FORM_flag_present + .byte 0 # End of abbrev + .byte 0 # End of abbrev + .byte 4 # Abbrev code + .byte 57 # DW_TAG_namespace + .byte 1 # DW_IDX_compile_unit + .byte 11 # DW_FORM_data1 + .byte 3 # DW_IDX_die_offset + .byte 19 # DW_FORM_ref4 + .byte 4 # DW_IDX_parent + .byte 25 # DW_FORM_flag_present + .byte 0 # End of abbrev + .byte 0 # End of abbrev + .byte 0 # End of abbrev list +.Lnames_abbrev_end0: +.Lnames_entries0: +.Lnames2: +.L0: + .byte 1 # Abbreviation code + .byte 1 # DW_IDX_compile_unit + .long 30 # DW_IDX_die_offset + .byte 0 # DW_IDX_parent + # End of list: vc +.Lnames4: +.L4: + .byte 2 # Abbreviation code + .byte 2 # DW_IDX_compile_unit + .long 32 # DW_IDX_die_offset + .long .L2-.Lnames_entries0 # DW_IDX_parent + .byte 0 # End of list: vd +.Lnames0: +.L3: + .byte 3 # Abbreviation code + .byte 0 # DW_IDX_compile_unit + .long 41 # DW_IDX_die_offset + .byte 0 # DW_IDX_parent + # End of list: int +.Lnames3: +.L2: + .byte 4 # Abbreviation code + .byte 2 # DW_IDX_compile_unit + .long 30 # DW_IDX_die_offset + .byte 0 # DW_IDX_parent + # End of list: ns +.Lnames5: + .byte 2 # Abbreviation code + .byte 2 # DW_IDX_compile_unit + .long 32 # DW_IDX_die_offset + .long .L2-.Lnames_entries0 # DW_IDX_parent + .byte 0 # End of list: _ZN2ns2vdE +.Lnames1: +.L1: + .byte 1 # Abbreviation code + .byte 0 # DW_IDX_compile_unit + .long 30 # DW_IDX_die_offset + .byte 0 # DW_IDX_parent + # End of list: vb + .p2align 2, 0x0 +.Lnames_end0: + .section ".note.GNU-stack","",@progbits + .addrsig + .addrsig_sym vb + .addrsig_sym vc + .addrsig_sym _ZN2ns2vdE + .section .debug_line,"",@progbits +.Lline_table_start0: +#--- ef.s + .text + .file "ld-temp.o" + .file 1 "/proc/self/cwd" "e.cc" md5 0xa8d6c645998197bd15436f2a351ebd6a + .file 2 "/proc/self/cwd" "f.cc" md5 0x6ec1ec6b7f003f84cb0bf3409e65b085 + .type ve,@object # @ve + .section .bss.ve,"aw",@nobits + .globl ve + .p2align 2, 0x0 +ve: + .long 0 # 0x0 + .size ve, 4 + + .type _ZN2ns2vfE,@object # @_ZN2ns2vfE + .section .bss._ZN2ns2vfE,"aw",@nobits + .globl _ZN2ns2vfE + .p2align 2, 0x0 +_ZN2ns2vfE: + .long 0 # 0x0 + .size _ZN2ns2vfE, 4 + + .section .debug_abbrev,"",@progbits + .byte 1 # Abbreviation Code + .byte 17 # DW_TAG_compile_unit + .byte 1 # DW_CHILDREN_yes + .byte 37 # DW_AT_producer + .byte 37 # DW_FORM_strx1 + .byte 19 # DW_AT_language + .byte 5 # DW_FORM_data2 + .byte 3 # DW_AT_name + .byte 37 # DW_FORM_strx1 + .byte 114 # DW_AT_str_offsets_base + .byte 23 # DW_FORM_sec_offset + .byte 16 # DW_AT_stmt_list + .byte 23 # DW_FORM_sec_offset + .byte 27 # DW_AT_comp_dir + .byte 37 # DW_FORM_strx1 + .byte 115 # DW_AT_addr_base + .byte 23 # DW_FORM_sec_offset + .byte 0 # EOM(1) + .byte 0 # EOM(2) + .byte 2 # Abbreviation Code + .byte 52 # DW_TAG_variable + .byte 0 # DW_CHILDREN_no + .byte 3 # DW_AT_name + .byte 37 # DW_FORM_strx1 + .byte 73 # DW_AT_type + .byte 19 # DW_FORM_ref4 + .byte 63 # DW_AT_external + .byte 25 # DW_FORM_flag_present + .byte 58 # DW_AT_decl_file + .byte 11 # DW_FORM_data1 + .byte 59 # DW_AT_decl_line + .byte 11 # DW_FORM_data1 + .byte 2 # DW_AT_location + .byte 24 # DW_FORM_exprloc + .byte 0 # EOM(1) + .byte 0 # EOM(2) + .byte 3 # Abbreviation Code + .byte 36 # DW_TAG_base_type + .byte 0 # DW_CHILDREN_no + .byte 3 # DW_AT_name + .byte 37 # DW_FORM_strx1 + .byte 62 # DW_AT_encoding + .byte 11 # DW_FORM_data1 + .byte 11 # DW_AT_byte_size + .byte 11 # DW_FORM_data1 + .byte 0 # EOM(1) + .byte 0 # EOM(2) + .byte 4 # Abbreviation Code + .byte 57 # DW_TAG_namespace + .byte 1 # DW_CHILDREN_yes + .byte 3 # DW_AT_name + .byte 37 # DW_FORM_strx1 + .byte 0 # EOM(1) + .byte 0 # EOM(2) + .byte 5 # Abbreviation Code + .byte 52 # DW_TAG_variable + .byte 0 # DW_CHILDREN_no + .byte 3 # DW_AT_name + .byte 37 # DW_FORM_strx1 + .byte 73 # DW_AT_type + .byte 16 # DW_FORM_ref_addr + .byte 63 # DW_AT_external + .byte 25 # DW_FORM_flag_present + .byte 58 # DW_AT_decl_file + .byte 11 # DW_FORM_data1 + .byte 59 # DW_AT_decl_line + .byte 11 # DW_FORM_data1 + .byte 2 # DW_AT_location + .byte 24 # DW_FORM_exprloc + .byte 110 # DW_AT_linkage_name + .byte 37 # DW_FORM_strx1 + .byte 0 # EOM(1) + .byte 0 # EOM(2) + .byte 0 # EOM(3) + .section .debug_info,"",@progbits +.Lcu_begin0: + .long .Ldebug_info_end0-.Ldebug_info_start0 # Length of Unit +.Ldebug_info_start0: + .short 5 # DWARF version number + .byte 1 # DWARF Unit Type + .byte 8 # Address Size (in bytes) + .long .debug_abbrev # Offset Into Abbrev. Section + .byte 1 # Abbrev [1] 0xc:0x22 DW_TAG_compile_unit + .byte 0 # DW_AT_producer + .short 33 # DW_AT_language + .byte 1 # DW_AT_name + .long .Lstr_offsets_base0 # DW_AT_str_offsets_base + .long .Lline_table_start0 # DW_AT_stmt_list + .byte 2 # DW_AT_comp_dir + .long .Laddr_table_base0 # DW_AT_addr_base + .byte 2 # Abbrev [2] 0x1e:0xb DW_TAG_variable + .byte 3 # DW_AT_name + .long 41 # DW_AT_type + # DW_AT_external + .byte 1 # DW_AT_decl_file + .byte 1 # DW_AT_decl_line + .byte 2 # DW_AT_location + .byte 161 + .byte 0 + .byte 3 # Abbrev [3] 0x29:0x4 DW_TAG_base_type + .byte 4 # DW_AT_name + .byte 5 # DW_AT_encoding + .byte 4 # DW_AT_byte_size + .byte 0 # End Of Children Mark +.Ldebug_info_end0: +.Lcu_begin1: + .long .Ldebug_info_end1-.Ldebug_info_start1 # Length of Unit +.Ldebug_info_start1: + .short 5 # DWARF version number + .byte 1 # DWARF Unit Type + .byte 8 # Address Size (in bytes) + .long .debug_abbrev # Offset Into Abbrev. Section + .byte 1 # Abbrev [1] 0xc:0x22 DW_TAG_compile_unit + .byte 0 # DW_AT_producer + .short 33 # DW_AT_language + .byte 5 # DW_AT_name + .long .Lstr_offsets_base0 # DW_AT_str_offsets_base + .long .Lline_table_start0 # DW_AT_stmt_list + .byte 2 # DW_AT_comp_dir + .long .Laddr_table_base0 # DW_AT_addr_base + .byte 4 # Abbrev [4] 0x1e:0xf DW_TAG_namespace + .byte 6 # DW_AT_name + .byte 5 # Abbrev [5] 0x20:0xc DW_TAG_variable + .byte 7 # DW_AT_name + .long .debug_info+41 # DW_AT_type + # DW_AT_external + .byte 2 # DW_AT_decl_file + .byte 2 # DW_AT_decl_line + .byte 2 # DW_AT_location + .byte 161 + .byte 1 + .byte 8 # DW_AT_linkage_name + .byte 0 # End Of Children Mark + .byte 0 # End Of Children Mark +.Ldebug_info_end1: + .section .debug_str_offsets,"",@progbits + .long 40 # Length of String Offsets Set + .short 5 + .short 0 +.Lstr_offsets_base0: + .section .debug_str,"MS",@progbits,1 +.Linfo_string0: + .byte 0 # string offset=0 +.Linfo_string1: + .asciz "e.cc" # string offset=1 +.Linfo_string2: + .asciz "/proc/self/cwd" # string offset=6 +.Linfo_string3: + .asciz "ve" # string offset=21 +.Linfo_string4: + .asciz "int" # string offset=24 +.Linfo_string5: + .asciz "f.cc" # string offset=28 +.Linfo_string6: + .asciz "ns" # string offset=33 +.Linfo_string7: + .asciz "vf" # string offset=36 +.Linfo_string8: + .asciz "_ZN2ns2vfE" # string offset=39 + .section .debug_str_offsets,"",@progbits + .long .Linfo_string0 + .long .Linfo_string1 + .long .Linfo_string2 + .long .Linfo_string3 + .long .Linfo_string4 + .long .Linfo_string5 + .long .Linfo_string6 + .long .Linfo_string7 + .long .Linfo_string8 + .section .debug_addr,"",@progbits + .long .Ldebug_addr_end0-.Ldebug_addr_start0 # Length of contribution +.Ldebug_addr_start0: + .short 5 # DWARF version number + .byte 8 # Address size + .byte 0 # Segment selector size +.Laddr_table_base0: + .quad ve + .quad _ZN2ns2vfE +.Ldebug_addr_end0: + .section .debug_names,"",@progbits + .long .Lnames_end0-.Lnames_start0 # Header: unit length +.Lnames_start0: + .short 5 # Header: version + .short 0 # Header: padding + .long 2 # Header: compilation unit count + .long 0 # Header: local type unit count + .long 0 # Header: foreign type unit count + .long 5 # Header: bucket count + .long 5 # Header: name count + .long .Lnames_abbrev_end0-.Lnames_abbrev_start0 # Header: abbreviation table size + .long 8 # Header: augmentation string size + .ascii "LLVM0700" # Header: augmentation string + .long .Lcu_begin0 # Compilation unit 0 + .long .Lcu_begin1 # Compilation unit 1 + .long 1 # Bucket 0 + .long 2 # Bucket 1 + .long 0 # Bucket 2 + .long 3 # Bucket 3 + .long 4 # Bucket 4 + .long 5863905 # Hash in Bucket 0 + .long -823734030 # Hash in Bucket 1 + .long 193495088 # Hash in Bucket 3 + .long 5863654 # Hash in Bucket 4 + .long 5863904 # Hash in Bucket 4 + .long .Linfo_string7 # String in Bucket 0: vf + .long .Linfo_string8 # String in Bucket 1: _ZN2ns2vfE + .long .Linfo_string4 # String in Bucket 3: int + .long .Linfo_string6 # String in Bucket 4: ns + .long .Linfo_string3 # String in Bucket 4: ve + .long .Lnames3-.Lnames_entries0 # Offset in Bucket 0 + .long .Lnames4-.Lnames_entries0 # Offset in Bucket 1 + .long .Lnames0-.Lnames_entries0 # Offset in Bucket 3 + .long .Lnames2-.Lnames_entries0 # Offset in Bucket 4 + .long .Lnames1-.Lnames_entries0 # Offset in Bucket 4 +.Lnames_abbrev_start0: + .byte 1 # Abbrev code + .byte 52 # DW_TAG_variable + .byte 1 # DW_IDX_compile_unit + .byte 11 # DW_FORM_data1 + .byte 3 # DW_IDX_die_offset + .byte 19 # DW_FORM_ref4 + .byte 4 # DW_IDX_parent + .byte 19 # DW_FORM_ref4 + .byte 0 # End of abbrev + .byte 0 # End of abbrev + .byte 2 # Abbrev code + .byte 36 # DW_TAG_base_type + .byte 1 # DW_IDX_compile_unit + .byte 11 # DW_FORM_data1 + .byte 3 # DW_IDX_die_offset + .byte 19 # DW_FORM_ref4 + .byte 4 # DW_IDX_parent + .byte 25 # DW_FORM_flag_present + .byte 0 # End of abbrev + .byte 0 # End of abbrev + .byte 3 # Abbrev code + .byte 57 # DW_TAG_namespace + .byte 1 # DW_IDX_compile_unit + .byte 11 # DW_FORM_data1 + .byte 3 # DW_IDX_die_offset + .byte 19 # DW_FORM_ref4 + .byte 4 # DW_IDX_parent + .byte 25 # DW_FORM_flag_present + .byte 0 # End of abbrev + .byte 0 # End of abbrev + .byte 4 # Abbrev code + .byte 52 # DW_TAG_variable + .byte 1 # DW_IDX_compile_unit + .byte 11 # DW_FORM_data1 + .byte 3 # DW_IDX_die_offset + .byte 19 # DW_FORM_ref4 + .byte 4 # DW_IDX_parent + .byte 25 # DW_FORM_flag_present + .byte 0 # End of abbrev + .byte 0 # End of abbrev + .byte 0 # End of abbrev list +.Lnames_abbrev_end0: +.Lnames_entries0: +.Lnames3: +.L2: + .byte 1 # Abbreviation code + .byte 1 # DW_IDX_compile_unit + .long 32 # DW_IDX_die_offset + .long .L0-.Lnames_entries0 # DW_IDX_parent + .byte 0 # End of list: vf +.Lnames4: + .byte 1 # Abbreviation code + .byte 1 # DW_IDX_compile_unit + .long 32 # DW_IDX_die_offset + .long .L0-.Lnames_entries0 # DW_IDX_parent + .byte 0 # End of list: _ZN2ns2vfE +.Lnames0: +.L3: + .byte 2 # Abbreviation code + .byte 0 # DW_IDX_compile_unit + .long 41 # DW_IDX_die_offset + .byte 0 # DW_IDX_parent + # End of list: int +.Lnames2: +.L0: + .byte 3 # Abbreviation code + .byte 1 # DW_IDX_compile_unit + .long 30 # DW_IDX_die_offset + .byte 0 # DW_IDX_parent + # End of list: ns +.Lnames1: +.L1: + .byte 4 # Abbreviation code + .byte 0 # DW_IDX_compile_unit + .long 30 # DW_IDX_die_offset + .byte 0 # DW_IDX_parent + # End of list: ve + .p2align 2, 0x0 +.Lnames_end0: + .section ".note.GNU-stack","",@progbits + .addrsig + .addrsig_sym ve + .addrsig_sym _ZN2ns2vfE + .section .debug_line,"",@progbits +.Lline_table_start0: diff --git a/lld/test/ELF/debug-names-tus.s b/lld/test/ELF/debug-names-tus.s deleted file mode 100644 index a97e54a28c187..0000000000000 --- a/lld/test/ELF/debug-names-tus.s +++ /dev/null @@ -1,528 +0,0 @@ -# The .s files were generated with: - -# clang++ -g -gpubnames -fdebug-compilation-dir='/proc/self/cwd' \ -# -fdebug-types-section -S a.cpp -o a.tu.s - -# clang++ -g -gpubnames -fdebug-compilation-dir='/proc/self/cwd' \ -# -fdebug-types-section -gsplit-dwarf -S a.cpp -o a.foreign-tu.s - -# clang++ -g -gpubnames -fdebug-compilation-dir='/proc/self/cwd' \ -# -S b.cpp -o b.s - -# a.cpp contents: - -# struct t1 { }; -# void f1(t1) { } - -# b.cpp contents: - -# struct t1 { }; -# int main() { -# t1 v1; -# } -# - -# REQUIRES: x86 -# RUN: rm -rf %t && split-file %s %t && cd %t -# RUN: llvm-mc -filetype=obj -triple=x86_64 a.tu.s -o a.tu.o -# RUN: llvm-mc -filetype=obj -triple=x86_64 a.foreign-tu.s -o a.foreign-tu.o -# RUN: llvm-mc -filetype=obj -triple=x86_64 b.s -o b.o - -# RUN: ld.lld --debug-names a.tu.o b.o -o out0 2>&1 \ -# RUN: | FileCheck --check-prefix=WARN %s -# RUN: llvm-dwarfdump --debug-names out0 | FileCheck --check-prefix=DWARF %s - -# WARN: warning: a.tu.o:(.debug_names): type units are not implemented - -# DWARF:Name Index @ 0x0 { -# DWARF: Compilation Unit offsets [ -# DWARF-NEXT: CU[0]: -# DWARF-SAME: 0x00000004 -# DWARF-NEXT: CU[1]: -# DWARF-SAME: 0x00000008 -# DWARF-NEXT: ] -# DWARF-NEXT: Abbreviations [ -# DWARF-NEXT: Abbreviation 0x1 { -# DWARF-NEXT: Tag: DW_TAG_structure_type -# DWARF-NEXT: DW_IDX_type_unit: DW_FORM_data1 -# DWARF-NEXT: DW_IDX_die_offset: DW_FORM_ref4 -# DWARF-NEXT: DW_IDX_parent: DW_FORM_flag_present -# DWARF-NEXT: DW_IDX_compile_unit: DW_FORM_data1 -# DWARF-NEXT: } - - -# RUN: ld.lld --debug-names a.foreign-tu.o b.o -o out1 2>&1 \ -# RUN: | FileCheck %s --check-prefix=WARN2 -# RUN: llvm-dwarfdump --debug-names out1 | FileCheck --check-prefix=DWARF2 %s - -# WARN2: warning: a.foreign-tu.o:(.debug_names): type units are not implemented - -# DWARF2:Name Index @ 0x0 { -# DWARF2: Compilation Unit offsets [ -# DWARF2-NEXT: CU[0]: -# DWARF2-SAME: 0x00000000 -# DWARF2-NEXT: CU[1]: -# DWARF2-SAME: 0x00000001 -# DWARF2-NEXT: ] -# DWARF2-NEXT: Abbreviations [ -# DWARF2-NEXT: Abbreviation 0x1 { -# DWARF2-NEXT: Tag: DW_TAG_structure_type -# DWARF2-NEXT: DW_IDX_type_unit: DW_FORM_data1 -# DWARF2-NEXT: DW_IDX_die_offset: DW_FORM_ref4 -# DWARF2-NEXT: DW_IDX_parent: DW_FORM_flag_present -# DWARF2-NEXT: DW_IDX_compile_unit: DW_FORM_data1 -# DWARF2-NEXT: } - - -#--- a.tu.s - .text - .globl _Z2f12t1 # -- Begin function _Z2f12t1 - .p2align 4, 0x90 - .type _Z2f12t1,@function -_Z2f12t1: # @_Z2f12t1 -.Lfunc_begin0: - .cfi_startproc -# %bb.0: # %entry - pushq %rbp - .cfi_def_cfa_offset 16 - .cfi_offset %rbp, -16 - movq %rsp, %rbp - .cfi_def_cfa_register %rbp -.Ltmp0: - popq %rbp - .cfi_def_cfa %rsp, 8 - retq -.Ltmp1: -.Lfunc_end0: - .size _Z2f12t1, .Lfunc_end0-_Z2f12t1 - .cfi_endproc - # -- End function - .section .debug_info,"G",@progbits,14297044602779165170,comdat -.Ltu_begin0: - .long .Ldebug_info_end0-.Ldebug_info_start0 # Length of Unit -.Ldebug_info_start0: -.Ldebug_info_end0: - .section .debug_info,"",@progbits -.Lcu_begin0: - .long .Ldebug_info_end1-.Ldebug_info_start1 # Length of Unit -.Ldebug_info_start1: -.Ldebug_info_end1: - .section .debug_str,"MS",@progbits,1 -.Linfo_string0: - .asciz "clang version 19.0.0git (git@github.com:llvm/llvm-project.git d12762cdb6357915e0f6f6dbfc09c2c75d746ee7)" # string offset=0 -.Linfo_string1: - .asciz "a.cpp" # string offset=104 -.Linfo_string2: - .asciz "debug-names-test" # string offset=110 -.Linfo_string3: - .asciz "f1" # string offset=127 -.Linfo_string4: - .asciz "_Z2f12t1" # string offset=130 -.Linfo_string5: - .asciz "t1" # string offset=139 - .section .debug_names,"",@progbits - .long .Lnames_end0-.Lnames_start0 # Header: unit length -.Lnames_start0: - .short 5 # Header: version - .short 0 # Header: padding - .long 1 # Header: compilation unit count - .long 1 # Header: local type unit count - .long 0 # Header: foreign type unit count - .long 3 # Header: bucket count - .long 3 # Header: name count - .long .Lnames_abbrev_end0-.Lnames_abbrev_start0 # Header: abbreviation table size - .long 8 # Header: augmentation string size - .ascii "LLVM0700" # Header: augmentation string - .long .Lcu_begin0 # Compilation unit 0 - .long .Ltu_begin0 # Type unit 0 - .long 0 # Bucket 0 - .long 1 # Bucket 1 - .long 3 # Bucket 2 - .long 5863324 # Hash in Bucket 1 - .long 5863786 # Hash in Bucket 1 - .long 1398125246 # Hash in Bucket 2 - .long .Linfo_string3 # String in Bucket 1: f1 - .long .Linfo_string5 # String in Bucket 1: t1 - .long .Linfo_string4 # String in Bucket 2: _Z2f12t1 - .long .Lnames0-.Lnames_entries0 # Offset in Bucket 1 - .long .Lnames2-.Lnames_entries0 # Offset in Bucket 1 - .long .Lnames1-.Lnames_entries0 # Offset in Bucket 2 -.Lnames_abbrev_start0: - .byte 1 # Abbrev code - .byte 46 # DW_TAG_subprogram - .byte 3 # DW_IDX_die_offset - .byte 19 # DW_FORM_ref4 - .byte 4 # DW_IDX_parent - .byte 25 # DW_FORM_flag_present - .byte 0 # End of abbrev - .byte 0 # End of abbrev - .byte 2 # Abbrev code - .byte 19 # DW_TAG_structure_type - .byte 2 # DW_IDX_type_unit - .byte 11 # DW_FORM_data1 - .byte 3 # DW_IDX_die_offset - .byte 19 # DW_FORM_ref4 - .byte 4 # DW_IDX_parent - .byte 25 # DW_FORM_flag_present - .byte 0 # End of abbrev - .byte 0 # End of abbrev - .byte 3 # Abbrev code - .byte 19 # DW_TAG_structure_type - .byte 3 # DW_IDX_die_offset - .byte 19 # DW_FORM_ref4 - .byte 4 # DW_IDX_parent - .byte 25 # DW_FORM_flag_present - .byte 0 # End of abbrev - .byte 0 # End of abbrev - .byte 0 # End of abbrev list -.Lnames_abbrev_end0: -.Lnames_entries0: -.Lnames0: -.L1: - .byte 1 # Abbreviation code - .long 35 # DW_IDX_die_offset - .byte 0 # DW_IDX_parent - # End of list: f1 -.Lnames2: - .byte 2 # Abbreviation code - .byte 0 # DW_IDX_type_unit - .long 35 # DW_IDX_die_offset -.L0: # DW_IDX_parent - .byte 3 # Abbreviation code - .long 58 # DW_IDX_die_offset - .byte 0 # DW_IDX_parent - # End of list: t1 -.Lnames1: - .byte 1 # Abbreviation code - .long 35 # DW_IDX_die_offset - .byte 0 # DW_IDX_parent - # End of list: _Z2f12t1 - .p2align 2, 0x0 -.Lnames_end0: - .ident "clang version 19.0.0git (git@github.com:llvm/llvm-project.git d12762cdb6357915e0f6f6dbfc09c2c75d746ee7)" - .section ".note.GNU-stack","",@progbits - .addrsig - .section .debug_line,"",@progbits -.Lline_table_start0: - - -#--- a.foreign-tu.s - .text - .globl _Z2f12t1 # -- Begin function _Z2f12t1 - .p2align 4, 0x90 - .type _Z2f12t1,@function -_Z2f12t1: # @_Z2f12t1 -.Lfunc_begin0: - .cfi_startproc -# %bb.0: # %entry - pushq %rbp - .cfi_def_cfa_offset 16 - .cfi_offset %rbp, -16 - movq %rsp, %rbp - .cfi_def_cfa_register %rbp -.Ltmp0: - popq %rbp - .cfi_def_cfa %rsp, 8 - retq -.Ltmp1: -.Lfunc_end0: - .size _Z2f12t1, .Lfunc_end0-_Z2f12t1 - .cfi_endproc - # -- End function - .section .debug_info.dwo,"e",@progbits - .byte 0 - .section .debug_info,"",@progbits -.Lcu_begin0: - .byte 0 - .section .debug_str,"MS",@progbits,1 -.Lskel_string0: - .asciz "debug-names-test" # string offset=0 -.Lskel_string1: - .asciz "f1" # string offset=17 -.Lskel_string2: - .asciz "_Z2f12t1" # string offset=20 -.Lskel_string3: - .asciz "t1" # string offset=29 -.Lskel_string4: - .asciz "a.dwo" # string offset=32 - .section .debug_str.dwo,"eMS",@progbits,1 -.Linfo_string0: - .asciz "_Z2f12t1" # string offset=0 -.Linfo_string1: - .asciz "f1" # string offset=9 -.Linfo_string2: - .asciz "debug-names-test" # string offset=12 -.Linfo_string3: - .asciz "a.dwo" # string offset=29 -.Linfo_string4: - .asciz "t1" # string offset=35 -.Linfo_string5: - .asciz "clang version 19.0.0git (git@github.com:llvm/llvm-project.git d12762cdb6357915e0f6f6dbfc09c2c75d746ee7)" # string offset=38 -.Linfo_string6: - .asciz "a.cpp" # string offset=142 - .section .debug_info.dwo,"e",@progbits - .byte 0 - .section .debug_line.dwo,"e",@progbits -.Ltmp2: - .long .Ldebug_line_end0-.Ldebug_line_start0 # unit length -.Ldebug_line_start0: - .short 5 - .byte 8 - .byte 0 - .long .Lprologue_end0-.Lprologue_start0 -.Lprologue_start0: - .byte 1 - .byte 1 - .byte 1 - .byte -5 - .byte 14 - .byte 1 - .byte 1 - .byte 1 - .byte 8 - .byte 1 - .ascii "debug-names-test" - .byte 0 - .byte 3 - .byte 1 - .byte 8 - .byte 2 - .byte 15 - .byte 5 - .byte 30 - .byte 1 - .ascii "a.cpp" - .byte 0 - .byte 0 - .byte 0x5e, 0xc4, 0x4d, 0x3b - .byte 0x78, 0xd0, 0x2a, 0x57 - .byte 0xd2, 0x75, 0xc1, 0x22 - .byte 0x36, 0xb7, 0x17, 0xbf -.Lprologue_end0: -.Ldebug_line_end0: - .section .debug_names,"",@progbits - .long .Lnames_end0-.Lnames_start0 # Header: unit length -.Lnames_start0: - .short 5 # Header: version - .short 0 # Header: padding - .long 1 # Header: compilation unit count - .long 0 # Header: local type unit count - .long 1 # Header: foreign type unit count - .long 3 # Header: bucket count - .long 3 # Header: name count - .long .Lnames_abbrev_end0-.Lnames_abbrev_start0 # Header: abbreviation table size - .long 8 # Header: augmentation string size - .ascii "LLVM0700" # Header: augmentation string - .long .Lcu_begin0 # Compilation unit 0 - .quad -4149699470930386446 # Type unit 0 - .long 0 # Bucket 0 - .long 1 # Bucket 1 - .long 3 # Bucket 2 - .long 5863324 # Hash in Bucket 1 - .long 5863786 # Hash in Bucket 1 - .long 1398125246 # Hash in Bucket 2 - .long .Lskel_string1 # String in Bucket 1: f1 - .long .Lskel_string3 # String in Bucket 1: t1 - .long .Lskel_string2 # String in Bucket 2: _Z2f12t1 - .long .Lnames0-.Lnames_entries0 # Offset in Bucket 1 - .long .Lnames2-.Lnames_entries0 # Offset in Bucket 1 - .long .Lnames1-.Lnames_entries0 # Offset in Bucket 2 -.Lnames_abbrev_start0: - .byte 1 # Abbrev code - .byte 46 # DW_TAG_subprogram - .byte 3 # DW_IDX_die_offset - .byte 19 # DW_FORM_ref4 - .byte 4 # DW_IDX_parent - .byte 25 # DW_FORM_flag_present - .byte 0 # End of abbrev - .byte 0 # End of abbrev - .byte 2 # Abbrev code - .byte 19 # DW_TAG_structure_type - .byte 2 # DW_IDX_type_unit - .byte 11 # DW_FORM_data1 - .byte 3 # DW_IDX_die_offset - .byte 19 # DW_FORM_ref4 - .byte 4 # DW_IDX_parent - .byte 25 # DW_FORM_flag_present - .byte 0 # End of abbrev - .byte 0 # End of abbrev - .byte 3 # Abbrev code - .byte 19 # DW_TAG_structure_type - .byte 3 # DW_IDX_die_offset - .byte 19 # DW_FORM_ref4 - .byte 4 # DW_IDX_parent - .byte 25 # DW_FORM_flag_present - .byte 0 # End of abbrev - .byte 0 # End of abbrev - .byte 0 # End of abbrev list -.Lnames_abbrev_end0: -.Lnames_entries0: -.Lnames0: -.L0: - .byte 1 # Abbreviation code - .long 26 # DW_IDX_die_offset - .byte 0 # DW_IDX_parent - # End of list: f1 -.Lnames2: -.L1: - .byte 2 # Abbreviation code - .byte 0 # DW_IDX_type_unit - .long 33 # DW_IDX_die_offset -.L2: # DW_IDX_parent - .byte 3 # Abbreviation code - .long 49 # DW_IDX_die_offset - .byte 0 # DW_IDX_parent - # End of list: t1 -.Lnames1: - .byte 1 # Abbreviation code - .long 26 # DW_IDX_die_offset - .byte 0 # DW_IDX_parent - # End of list: _Z2f12t1 - .p2align 2, 0x0 -.Lnames_end0: - .ident "clang version 19.0.0git (git@github.com:llvm/llvm-project.git d12762cdb6357915e0f6f6dbfc09c2c75d746ee7)" - .section ".note.GNU-stack","",@progbits - .addrsig - .section .debug_line,"",@progbits -.Lline_table_start0: - -#--- b.s - - .text - .globl main # -- Begin function main - .p2align 4, 0x90 - .type main,@function -main: # @main -.Lfunc_begin0: - .cfi_startproc -# %bb.0: # %entry - pushq %rbp - .cfi_def_cfa_offset 16 - .cfi_offset %rbp, -16 - movq %rsp, %rbp - .cfi_def_cfa_register %rbp -.Ltmp0: - xorl %eax, %eax - popq %rbp - .cfi_def_cfa %rsp, 8 - retq -.Ltmp1: -.Lfunc_end0: - .size main, .Lfunc_end0-main - .cfi_endproc - # -- End function - .section .debug_abbrev,"",@progbits - .byte 0 # EOM(1) - .byte 0 # EOM(2) - .byte 0 # EOM(3) - .section .debug_info,"",@progbits -.Lcu_begin0: - .long .Ldebug_info_end0-.Ldebug_info_start0 # Length of Unit -.Ldebug_info_start0: - .short 5 # DWARF version number - .byte 1 # DWARF Unit Type - .byte 8 # Address Size (in bytes) - .long .debug_abbrev # Offset Into Abbrev. Section -.Ldebug_info_end0: - .section .debug_str_offsets,"",@progbits - .long 32 # Length of String Offsets Set - .short 5 - .short 0 -.Lstr_offsets_base0: - .section .debug_str,"MS",@progbits,1 -.Linfo_string0: - .asciz "clang version 19.0.0git (git@github.com:llvm/llvm-project.git 53b14cd9ce2b57da73d173fc876d2e9e199f5640)" # string offset=0 -.Linfo_string1: - .asciz "b.cpp" # string offset=104 -.Linfo_string2: - .asciz "/proc/self/cwd" # string offset=110 -.Linfo_string3: - .asciz "main" # string offset=125 -.Linfo_string4: - .asciz "int" # string offset=130 -.Linfo_string5: - .asciz "v1" # string offset=134 -.Linfo_string6: - .asciz "t1" # string offset=137 -.Laddr_table_base0: - .quad .Lfunc_begin0 -.Ldebug_addr_end0: - .section .debug_names,"",@progbits - .long .Lnames_end0-.Lnames_start0 # Header: unit length -.Lnames_start0: - .short 5 # Header: version - .short 0 # Header: padding - .long 1 # Header: compilation unit count - .long 0 # Header: local type unit count - .long 0 # Header: foreign type unit count - .long 3 # Header: bucket count - .long 3 # Header: name count - .long .Lnames_abbrev_end0-.Lnames_abbrev_start0 # Header: abbreviation table size - .long 8 # Header: augmentation string size - .ascii "LLVM0700" # Header: augmentation string - .long .Lcu_begin0 # Compilation unit 0 - .long 0 # Bucket 0 - .long 1 # Bucket 1 - .long 3 # Bucket 2 - .long 5863786 # Hash in Bucket 1 - .long 2090499946 # Hash in Bucket 1 - .long 193495088 # Hash in Bucket 2 - .long .Linfo_string6 # String in Bucket 1: t1 - .long .Linfo_string3 # String in Bucket 1: main - .long .Linfo_string4 # String in Bucket 2: int - .long .Lnames2-.Lnames_entries0 # Offset in Bucket 1 - .long .Lnames0-.Lnames_entries0 # Offset in Bucket 1 - .long .Lnames1-.Lnames_entries0 # Offset in Bucket 2 -.Lnames_abbrev_start0: - .byte 1 # Abbrev code - .byte 19 # DW_TAG_structure_type - .byte 3 # DW_IDX_die_offset - .byte 19 # DW_FORM_ref4 - .byte 4 # DW_IDX_parent - .byte 25 # DW_FORM_flag_present - .byte 0 # End of abbrev - .byte 0 # End of abbrev - .byte 2 # Abbrev code - .byte 46 # DW_TAG_subprogram - .byte 3 # DW_IDX_die_offset - .byte 19 # DW_FORM_ref4 - .byte 4 # DW_IDX_parent - .byte 25 # DW_FORM_flag_present - .byte 0 # End of abbrev - .byte 0 # End of abbrev - .byte 3 # Abbrev code - .byte 36 # DW_TAG_base_type - .byte 3 # DW_IDX_die_offset - .byte 19 # DW_FORM_ref4 - .byte 4 # DW_IDX_parent - .byte 25 # DW_FORM_flag_present - .byte 0 # End of abbrev - .byte 0 # End of abbrev - .byte 0 # End of abbrev list -.Lnames_abbrev_end0: -.Lnames_entries0: -.Lnames2: -.L1: - .byte 1 # Abbreviation code - .long 66 # DW_IDX_die_offset - .byte 0 # DW_IDX_parent - # End of list: t1 -.Lnames0: -.L2: - .byte 2 # Abbreviation code - .long 35 # DW_IDX_die_offset - .byte 0 # DW_IDX_parent - # End of list: main -.Lnames1: -.L0: - .byte 3 # Abbreviation code - .long 62 # DW_IDX_die_offset - .byte 0 # DW_IDX_parent - # End of list: int - .p2align 2, 0x0 -.Lnames_end0: - .ident "clang version 19.0.0git (git@github.com:llvm/llvm-project.git 53b14cd9ce2b57da73d173fc876d2e9e199f5640)" - .section ".note.GNU-stack","",@progbits - .addrsig - .section .debug_line,"",@progbits -.Lline_table_start0: diff --git a/lld/test/ELF/debug-names-type-units.s b/lld/test/ELF/debug-names-type-units.s new file mode 100644 index 0000000000000..dda065b238d85 --- /dev/null +++ b/lld/test/ELF/debug-names-type-units.s @@ -0,0 +1,895 @@ +# REQUIRES: x86 +# RUN: rm -rf %t && split-file %s %t && cd %t +# RUN: llvm-mc -filetype=obj -triple=x86_64 a.tu.s -o a.tu.o +# RUN: llvm-mc -filetype=obj -triple=x86_64 a.foreign-tu.s -o a.foreign-tu.o +# RUN: llvm-mc -filetype=obj -triple=x86_64 b.s -o b.o + +# RUN: ld.lld --debug-names a.tu.o b.o -o out0 2>&1 | FileCheck --check-prefix=WARN %s +# RUN: llvm-dwarfdump --debug-names out0 | FileCheck --check-prefix=DWARF %s + +# WARN: warning: a.tu.o:(.debug_names): type units are not implemented + +# DWARF: CU count: 2 +# DWARF-NEXT: Local TU count: 0 +# DWARF-NEXT: Foreign TU count: 0 +# DWARF: Compilation Unit offsets [ +# DWARF-NEXT: CU[0]: +# DWARF-SAME: 0x0000002a +# DWARF-NEXT: CU[1]: +# DWARF-SAME: 0x0000006a +# DWARF-NEXT: ] +# DWARF: String: {{.*}} "t1" +# DWARF-NEXT: Entry @ 0x8f { +# DWARF-NEXT: Abbrev: 0x2 +# DWARF-NEXT: Tag: DW_TAG_structure_type +# DWARF-NEXT: DW_IDX_type_unit: 0x00 +# DWARF-NEXT: DW_IDX_die_offset: 0x00000023 +# DWARF-NEXT: DW_IDX_parent: +# DWARF-NEXT: DW_IDX_compile_unit: 0x00 +# DWARF-NEXT: } +# DWARF-NEXT: Entry @ 0x96 { +# DWARF-NEXT: Abbrev: 0x1 +# DWARF-NEXT: Tag: DW_TAG_structure_type +# DWARF-NEXT: DW_IDX_die_offset: 0x00000036 +# DWARF-NEXT: DW_IDX_parent: +# DWARF-NEXT: DW_IDX_compile_unit: 0x00 +# DWARF-NEXT: } +# DWARF-NEXT: Entry @ 0x9c { +# DWARF-NEXT: Abbrev: 0x1 +# DWARF-NEXT: Tag: DW_TAG_structure_type +# DWARF-NEXT: DW_IDX_die_offset: 0x00000029 +# DWARF-NEXT: DW_IDX_parent: +# DWARF-NEXT: DW_IDX_compile_unit: 0x01 +# DWARF-NEXT: } + +# RUN: ld.lld --debug-names a.foreign-tu.o b.o -o out1 2>&1 | FileCheck %s --check-prefix=WARN2 +# RUN: llvm-dwarfdump --debug-names out1 | FileCheck --check-prefix=DWARF2 %s + +# WARN2: warning: a.foreign-tu.o:(.debug_names): type units are not implemented + +# DWARF2: CU count: 2 +# DWARF2-NEXT: Local TU count: 0 +# DWARF2-NEXT: Foreign TU count: 0 +# DWARF2: Compilation Unit offsets [ +# DWARF2-NEXT: CU[0]: +# DWARF2-SAME: 0x00000000 +# DWARF2-NEXT: CU[1]: +# DWARF2-SAME: 0x00000028 +# DWARF2-NEXT: ] + +.ifdef GEN +#--- a.cc +struct t1 {}; +extern "C" void _start(t1) {} +#--- b.cc +struct t1 { } vb; +#--- gen +echo '#--- a.tu.s' +clang --target=x86_64-linux -S -O1 -g -gpubnames -fdebug-types-section a.cc -o - +echo '#--- a.foreign-tu.s' +clang --target=x86_64-linux -S -O1 -g -gpubnames -fdebug-types-section -gsplit-dwarf a.cc -o - +echo '#--- b.s' +clang --target=x86_64-linux -S -O1 -g -gpubnames b.cc -o - +.endif +#--- a.tu.s + .text + .file "a.cc" + .globl _start # -- Begin function _start + .p2align 4, 0x90 + .type _start,@function +_start: # @_start +.Lfunc_begin0: + .file 0 "/proc/self/cwd" "a.cc" md5 0x6835f89a7d36054002b51e54e47d852e + .cfi_startproc +# %bb.0: # %entry + .loc 0 2 29 prologue_end # a.cc:2:29 + retq +.Ltmp0: +.Lfunc_end0: + .size _start, .Lfunc_end0-_start + .cfi_endproc + # -- End function + .section .debug_info,"G",@progbits,14297044602779165170,comdat +.Ltu_begin0: + .long .Ldebug_info_end0-.Ldebug_info_start0 # Length of Unit +.Ldebug_info_start0: + .short 5 # DWARF version number + .byte 2 # DWARF Unit Type + .byte 8 # Address Size (in bytes) + .long .debug_abbrev # Offset Into Abbrev. Section + .quad -4149699470930386446 # Type Signature + .long 35 # Type DIE Offset + .byte 1 # Abbrev [1] 0x18:0x12 DW_TAG_type_unit + .short 33 # DW_AT_language + .long .Lline_table_start0 # DW_AT_stmt_list + .long .Lstr_offsets_base0 # DW_AT_str_offsets_base + .byte 2 # Abbrev [2] 0x23:0x6 DW_TAG_structure_type + .byte 5 # DW_AT_calling_convention + .byte 4 # DW_AT_name + .byte 1 # DW_AT_byte_size + .byte 0 # DW_AT_decl_file + .byte 1 # DW_AT_decl_line + .byte 0 # End Of Children Mark +.Ldebug_info_end0: + .section .debug_abbrev,"",@progbits + .byte 1 # Abbreviation Code + .byte 65 # DW_TAG_type_unit + .byte 1 # DW_CHILDREN_yes + .byte 19 # DW_AT_language + .byte 5 # DW_FORM_data2 + .byte 16 # DW_AT_stmt_list + .byte 23 # DW_FORM_sec_offset + .byte 114 # DW_AT_str_offsets_base + .byte 23 # DW_FORM_sec_offset + .byte 0 # EOM(1) + .byte 0 # EOM(2) + .byte 2 # Abbreviation Code + .byte 19 # DW_TAG_structure_type + .byte 0 # DW_CHILDREN_no + .byte 54 # DW_AT_calling_convention + .byte 11 # DW_FORM_data1 + .byte 3 # DW_AT_name + .byte 37 # DW_FORM_strx1 + .byte 11 # DW_AT_byte_size + .byte 11 # DW_FORM_data1 + .byte 58 # DW_AT_decl_file + .byte 11 # DW_FORM_data1 + .byte 59 # DW_AT_decl_line + .byte 11 # DW_FORM_data1 + .byte 0 # EOM(1) + .byte 0 # EOM(2) + .byte 3 # Abbreviation Code + .byte 17 # DW_TAG_compile_unit + .byte 1 # DW_CHILDREN_yes + .byte 37 # DW_AT_producer + .byte 37 # DW_FORM_strx1 + .byte 19 # DW_AT_language + .byte 5 # DW_FORM_data2 + .byte 3 # DW_AT_name + .byte 37 # DW_FORM_strx1 + .byte 114 # DW_AT_str_offsets_base + .byte 23 # DW_FORM_sec_offset + .byte 16 # DW_AT_stmt_list + .byte 23 # DW_FORM_sec_offset + .byte 27 # DW_AT_comp_dir + .byte 37 # DW_FORM_strx1 + .byte 17 # DW_AT_low_pc + .byte 27 # DW_FORM_addrx + .byte 18 # DW_AT_high_pc + .byte 6 # DW_FORM_data4 + .byte 115 # DW_AT_addr_base + .byte 23 # DW_FORM_sec_offset + .byte 0 # EOM(1) + .byte 0 # EOM(2) + .byte 4 # Abbreviation Code + .byte 46 # DW_TAG_subprogram + .byte 1 # DW_CHILDREN_yes + .byte 17 # DW_AT_low_pc + .byte 27 # DW_FORM_addrx + .byte 18 # DW_AT_high_pc + .byte 6 # DW_FORM_data4 + .byte 64 # DW_AT_frame_base + .byte 24 # DW_FORM_exprloc + .byte 122 # DW_AT_call_all_calls + .byte 25 # DW_FORM_flag_present + .byte 3 # DW_AT_name + .byte 37 # DW_FORM_strx1 + .byte 58 # DW_AT_decl_file + .byte 11 # DW_FORM_data1 + .byte 59 # DW_AT_decl_line + .byte 11 # DW_FORM_data1 + .byte 63 # DW_AT_external + .byte 25 # DW_FORM_flag_present + .byte 0 # EOM(1) + .byte 0 # EOM(2) + .byte 5 # Abbreviation Code + .byte 5 # DW_TAG_formal_parameter + .byte 0 # DW_CHILDREN_no + .byte 58 # DW_AT_decl_file + .byte 11 # DW_FORM_data1 + .byte 59 # DW_AT_decl_line + .byte 11 # DW_FORM_data1 + .byte 73 # DW_AT_type + .byte 19 # DW_FORM_ref4 + .byte 0 # EOM(1) + .byte 0 # EOM(2) + .byte 6 # Abbreviation Code + .byte 19 # DW_TAG_structure_type + .byte 0 # DW_CHILDREN_no + .byte 60 # DW_AT_declaration + .byte 25 # DW_FORM_flag_present + .byte 105 # DW_AT_signature + .byte 32 # DW_FORM_ref_sig8 + .byte 0 # EOM(1) + .byte 0 # EOM(2) + .byte 0 # EOM(3) + .section .debug_info,"",@progbits +.Lcu_begin0: + .long .Ldebug_info_end1-.Ldebug_info_start1 # Length of Unit +.Ldebug_info_start1: + .short 5 # DWARF version number + .byte 1 # DWARF Unit Type + .byte 8 # Address Size (in bytes) + .long .debug_abbrev # Offset Into Abbrev. Section + .byte 3 # Abbrev [3] 0xc:0x34 DW_TAG_compile_unit + .byte 0 # DW_AT_producer + .short 33 # DW_AT_language + .byte 1 # DW_AT_name + .long .Lstr_offsets_base0 # DW_AT_str_offsets_base + .long .Lline_table_start0 # DW_AT_stmt_list + .byte 2 # DW_AT_comp_dir + .byte 0 # DW_AT_low_pc + .long .Lfunc_end0-.Lfunc_begin0 # DW_AT_high_pc + .long .Laddr_table_base0 # DW_AT_addr_base + .byte 4 # Abbrev [4] 0x23:0x13 DW_TAG_subprogram + .byte 0 # DW_AT_low_pc + .long .Lfunc_end0-.Lfunc_begin0 # DW_AT_high_pc + .byte 1 # DW_AT_frame_base + .byte 87 + # DW_AT_call_all_calls + .byte 3 # DW_AT_name + .byte 0 # DW_AT_decl_file + .byte 2 # DW_AT_decl_line + # DW_AT_external + .byte 5 # Abbrev [5] 0x2e:0x7 DW_TAG_formal_parameter + .byte 0 # DW_AT_decl_file + .byte 2 # DW_AT_decl_line + .long 54 # DW_AT_type + .byte 0 # End Of Children Mark + .byte 6 # Abbrev [6] 0x36:0x9 DW_TAG_structure_type + # DW_AT_declaration + .quad -4149699470930386446 # DW_AT_signature + .byte 0 # End Of Children Mark +.Ldebug_info_end1: + .section .debug_str_offsets,"",@progbits + .long 24 # Length of String Offsets Set + .short 5 + .short 0 +.Lstr_offsets_base0: + .section .debug_str,"MS",@progbits,1 +.Linfo_string0: + .byte 0 # string offset=0 +.Linfo_string1: + .asciz "a.cc" # string offset=1 +.Linfo_string2: + .asciz "/proc/self/cwd" # string offset=6 +.Linfo_string3: + .asciz "_start" # string offset=21 +.Linfo_string4: + .asciz "t1" # string offset=28 + .section .debug_str_offsets,"",@progbits + .long .Linfo_string0 + .long .Linfo_string1 + .long .Linfo_string2 + .long .Linfo_string3 + .long .Linfo_string4 + .section .debug_addr,"",@progbits + .long .Ldebug_addr_end0-.Ldebug_addr_start0 # Length of contribution +.Ldebug_addr_start0: + .short 5 # DWARF version number + .byte 8 # Address size + .byte 0 # Segment selector size +.Laddr_table_base0: + .quad .Lfunc_begin0 +.Ldebug_addr_end0: + .section .debug_names,"",@progbits + .long .Lnames_end0-.Lnames_start0 # Header: unit length +.Lnames_start0: + .short 5 # Header: version + .short 0 # Header: padding + .long 1 # Header: compilation unit count + .long 1 # Header: local type unit count + .long 0 # Header: foreign type unit count + .long 2 # Header: bucket count + .long 2 # Header: name count + .long .Lnames_abbrev_end0-.Lnames_abbrev_start0 # Header: abbreviation table size + .long 8 # Header: augmentation string size + .ascii "LLVM0700" # Header: augmentation string + .long .Lcu_begin0 # Compilation unit 0 + .long .Ltu_begin0 # Type unit 0 + .long 1 # Bucket 0 + .long 0 # Bucket 1 + .long 5863786 # Hash in Bucket 0 + .long -304389582 # Hash in Bucket 0 + .long .Linfo_string4 # String in Bucket 0: t1 + .long .Linfo_string3 # String in Bucket 0: _start + .long .Lnames1-.Lnames_entries0 # Offset in Bucket 0 + .long .Lnames0-.Lnames_entries0 # Offset in Bucket 0 +.Lnames_abbrev_start0: + .byte 1 # Abbrev code + .byte 19 # DW_TAG_structure_type + .byte 2 # DW_IDX_type_unit + .byte 11 # DW_FORM_data1 + .byte 3 # DW_IDX_die_offset + .byte 19 # DW_FORM_ref4 + .byte 4 # DW_IDX_parent + .byte 25 # DW_FORM_flag_present + .byte 0 # End of abbrev + .byte 0 # End of abbrev + .byte 2 # Abbrev code + .byte 19 # DW_TAG_structure_type + .byte 3 # DW_IDX_die_offset + .byte 19 # DW_FORM_ref4 + .byte 4 # DW_IDX_parent + .byte 25 # DW_FORM_flag_present + .byte 0 # End of abbrev + .byte 0 # End of abbrev + .byte 3 # Abbrev code + .byte 46 # DW_TAG_subprogram + .byte 3 # DW_IDX_die_offset + .byte 19 # DW_FORM_ref4 + .byte 4 # DW_IDX_parent + .byte 25 # DW_FORM_flag_present + .byte 0 # End of abbrev + .byte 0 # End of abbrev + .byte 0 # End of abbrev list +.Lnames_abbrev_end0: +.Lnames_entries0: +.Lnames1: +.L1: + .byte 1 # Abbreviation code + .byte 0 # DW_IDX_type_unit + .long 35 # DW_IDX_die_offset +.L0: # DW_IDX_parent + .byte 2 # Abbreviation code + .long 54 # DW_IDX_die_offset + .byte 0 # DW_IDX_parent + # End of list: t1 +.Lnames0: + .byte 3 # Abbreviation code + .long 35 # DW_IDX_die_offset + .byte 0 # DW_IDX_parent + # End of list: _start + .p2align 2, 0x0 +.Lnames_end0: + .section ".note.GNU-stack","",@progbits + .addrsig + .section .debug_line,"",@progbits +.Lline_table_start0: +#--- a.foreign-tu.s + .text + .file "a.cc" + .globl _start # -- Begin function _start + .p2align 4, 0x90 + .type _start,@function +_start: # @_start +.Lfunc_begin0: + .file 0 "/proc/self/cwd" "a.cc" md5 0x6835f89a7d36054002b51e54e47d852e + .cfi_startproc +# %bb.0: # %entry + .loc 0 2 29 prologue_end # a.cc:2:29 + retq +.Ltmp0: +.Lfunc_end0: + .size _start, .Lfunc_end0-_start + .cfi_endproc + # -- End function + .section .debug_info.dwo,"e",@progbits + .long .Ldebug_info_dwo_end0-.Ldebug_info_dwo_start0 # Length of Unit +.Ldebug_info_dwo_start0: + .short 5 # DWARF version number + .byte 6 # DWARF Unit Type + .byte 8 # Address Size (in bytes) + .long 0 # Offset Into Abbrev. Section + .quad -4149699470930386446 # Type Signature + .long 33 # Type DIE Offset + .byte 1 # Abbrev [1] 0x18:0x10 DW_TAG_type_unit + .short 33 # DW_AT_language + .byte 1 # DW_AT_comp_dir + .byte 2 # DW_AT_dwo_name + .long 0 # DW_AT_stmt_list + .byte 2 # Abbrev [2] 0x21:0x6 DW_TAG_structure_type + .byte 5 # DW_AT_calling_convention + .byte 3 # DW_AT_name + .byte 1 # DW_AT_byte_size + .byte 0 # DW_AT_decl_file + .byte 1 # DW_AT_decl_line + .byte 0 # End Of Children Mark +.Ldebug_info_dwo_end0: + .section .debug_abbrev,"",@progbits + .byte 1 # Abbreviation Code + .byte 74 # DW_TAG_skeleton_unit + .byte 0 # DW_CHILDREN_no + .byte 16 # DW_AT_stmt_list + .byte 23 # DW_FORM_sec_offset + .byte 114 # DW_AT_str_offsets_base + .byte 23 # DW_FORM_sec_offset + .byte 27 # DW_AT_comp_dir + .byte 37 # DW_FORM_strx1 + .byte 118 # DW_AT_dwo_name + .byte 37 # DW_FORM_strx1 + .byte 17 # DW_AT_low_pc + .byte 27 # DW_FORM_addrx + .byte 18 # DW_AT_high_pc + .byte 6 # DW_FORM_data4 + .byte 115 # DW_AT_addr_base + .byte 23 # DW_FORM_sec_offset + .byte 0 # EOM(1) + .byte 0 # EOM(2) + .byte 0 # EOM(3) + .section .debug_info,"",@progbits +.Lcu_begin0: + .long .Ldebug_info_end0-.Ldebug_info_start0 # Length of Unit +.Ldebug_info_start0: + .short 5 # DWARF version number + .byte 4 # DWARF Unit Type + .byte 8 # Address Size (in bytes) + .long .debug_abbrev # Offset Into Abbrev. Section + .quad -2763464185488304260 + .byte 1 # Abbrev [1] 0x14:0x14 DW_TAG_skeleton_unit + .long .Lline_table_start0 # DW_AT_stmt_list + .long .Lstr_offsets_base0 # DW_AT_str_offsets_base + .byte 0 # DW_AT_comp_dir + .byte 1 # DW_AT_dwo_name + .byte 0 # DW_AT_low_pc + .long .Lfunc_end0-.Lfunc_begin0 # DW_AT_high_pc + .long .Laddr_table_base0 # DW_AT_addr_base +.Ldebug_info_end0: + .section .debug_str_offsets,"",@progbits + .long 12 # Length of String Offsets Set + .short 5 + .short 0 +.Lstr_offsets_base0: + .section .debug_str,"MS",@progbits,1 +.Lskel_string0: + .asciz "/proc/self/cwd" # string offset=0 +.Lskel_string1: + .asciz "_start" # string offset=15 +.Lskel_string2: + .asciz "t1" # string offset=22 +.Lskel_string3: + .asciz "a.dwo" # string offset=25 + .section .debug_str_offsets,"",@progbits + .long .Lskel_string0 + .long .Lskel_string3 + .section .debug_str_offsets.dwo,"e",@progbits + .long 28 # Length of String Offsets Set + .short 5 + .short 0 + .section .debug_str.dwo,"eMS",@progbits,1 +.Linfo_string0: + .asciz "_start" # string offset=0 +.Linfo_string1: + .asciz "/proc/self/cwd" # string offset=7 +.Linfo_string2: + .asciz "a.dwo" # string offset=22 +.Linfo_string3: + .asciz "t1" # string offset=28 +.Linfo_string4: + .byte 0 # string offset=31 +.Linfo_string5: + .asciz "a.cc" # string offset=32 + .section .debug_str_offsets.dwo,"e",@progbits + .long 0 + .long 7 + .long 22 + .long 28 + .long 31 + .long 32 + .section .debug_info.dwo,"e",@progbits + .long .Ldebug_info_dwo_end1-.Ldebug_info_dwo_start1 # Length of Unit +.Ldebug_info_dwo_start1: + .short 5 # DWARF version number + .byte 5 # DWARF Unit Type + .byte 8 # Address Size (in bytes) + .long 0 # Offset Into Abbrev. Section + .quad -2763464185488304260 + .byte 3 # Abbrev [3] 0x14:0x23 DW_TAG_compile_unit + .byte 4 # DW_AT_producer + .short 33 # DW_AT_language + .byte 5 # DW_AT_name + .byte 2 # DW_AT_dwo_name + .byte 4 # Abbrev [4] 0x1a:0x13 DW_TAG_subprogram + .byte 0 # DW_AT_low_pc + .long .Lfunc_end0-.Lfunc_begin0 # DW_AT_high_pc + .byte 1 # DW_AT_frame_base + .byte 87 + # DW_AT_call_all_calls + .byte 0 # DW_AT_name + .byte 0 # DW_AT_decl_file + .byte 2 # DW_AT_decl_line + # DW_AT_external + .byte 5 # Abbrev [5] 0x25:0x7 DW_TAG_formal_parameter + .byte 0 # DW_AT_decl_file + .byte 2 # DW_AT_decl_line + .long 45 # DW_AT_type + .byte 0 # End Of Children Mark + .byte 6 # Abbrev [6] 0x2d:0x9 DW_TAG_structure_type + # DW_AT_declaration + .quad -4149699470930386446 # DW_AT_signature + .byte 0 # End Of Children Mark +.Ldebug_info_dwo_end1: + .section .debug_abbrev.dwo,"e",@progbits + .byte 1 # Abbreviation Code + .byte 65 # DW_TAG_type_unit + .byte 1 # DW_CHILDREN_yes + .byte 19 # DW_AT_language + .byte 5 # DW_FORM_data2 + .byte 27 # DW_AT_comp_dir + .byte 37 # DW_FORM_strx1 + .byte 118 # DW_AT_dwo_name + .byte 37 # DW_FORM_strx1 + .byte 16 # DW_AT_stmt_list + .byte 23 # DW_FORM_sec_offset + .byte 0 # EOM(1) + .byte 0 # EOM(2) + .byte 2 # Abbreviation Code + .byte 19 # DW_TAG_structure_type + .byte 0 # DW_CHILDREN_no + .byte 54 # DW_AT_calling_convention + .byte 11 # DW_FORM_data1 + .byte 3 # DW_AT_name + .byte 37 # DW_FORM_strx1 + .byte 11 # DW_AT_byte_size + .byte 11 # DW_FORM_data1 + .byte 58 # DW_AT_decl_file + .byte 11 # DW_FORM_data1 + .byte 59 # DW_AT_decl_line + .byte 11 # DW_FORM_data1 + .byte 0 # EOM(1) + .byte 0 # EOM(2) + .byte 3 # Abbreviation Code + .byte 17 # DW_TAG_compile_unit + .byte 1 # DW_CHILDREN_yes + .byte 37 # DW_AT_producer + .byte 37 # DW_FORM_strx1 + .byte 19 # DW_AT_language + .byte 5 # DW_FORM_data2 + .byte 3 # DW_AT_name + .byte 37 # DW_FORM_strx1 + .byte 118 # DW_AT_dwo_name + .byte 37 # DW_FORM_strx1 + .byte 0 # EOM(1) + .byte 0 # EOM(2) + .byte 4 # Abbreviation Code + .byte 46 # DW_TAG_subprogram + .byte 1 # DW_CHILDREN_yes + .byte 17 # DW_AT_low_pc + .byte 27 # DW_FORM_addrx + .byte 18 # DW_AT_high_pc + .byte 6 # DW_FORM_data4 + .byte 64 # DW_AT_frame_base + .byte 24 # DW_FORM_exprloc + .byte 122 # DW_AT_call_all_calls + .byte 25 # DW_FORM_flag_present + .byte 3 # DW_AT_name + .byte 37 # DW_FORM_strx1 + .byte 58 # DW_AT_decl_file + .byte 11 # DW_FORM_data1 + .byte 59 # DW_AT_decl_line + .byte 11 # DW_FORM_data1 + .byte 63 # DW_AT_external + .byte 25 # DW_FORM_flag_present + .byte 0 # EOM(1) + .byte 0 # EOM(2) + .byte 5 # Abbreviation Code + .byte 5 # DW_TAG_formal_parameter + .byte 0 # DW_CHILDREN_no + .byte 58 # DW_AT_decl_file + .byte 11 # DW_FORM_data1 + .byte 59 # DW_AT_decl_line + .byte 11 # DW_FORM_data1 + .byte 73 # DW_AT_type + .byte 19 # DW_FORM_ref4 + .byte 0 # EOM(1) + .byte 0 # EOM(2) + .byte 6 # Abbreviation Code + .byte 19 # DW_TAG_structure_type + .byte 0 # DW_CHILDREN_no + .byte 60 # DW_AT_declaration + .byte 25 # DW_FORM_flag_present + .byte 105 # DW_AT_signature + .byte 32 # DW_FORM_ref_sig8 + .byte 0 # EOM(1) + .byte 0 # EOM(2) + .byte 0 # EOM(3) + .section .debug_line.dwo,"e",@progbits +.Ltmp1: + .long .Ldebug_line_end0-.Ldebug_line_start0 # unit length +.Ldebug_line_start0: + .short 5 + .byte 8 + .byte 0 + .long .Lprologue_end0-.Lprologue_start0 +.Lprologue_start0: + .byte 1 + .byte 1 + .byte 1 + .byte -5 + .byte 14 + .byte 1 + .byte 1 + .byte 1 + .byte 8 + .byte 1 + .ascii "/proc/self/cwd" + .byte 0 + .byte 3 + .byte 1 + .byte 8 + .byte 2 + .byte 15 + .byte 5 + .byte 30 + .byte 1 + .ascii "a.cc" + .byte 0 + .byte 0 + .byte 0x68, 0x35, 0xf8, 0x9a + .byte 0x7d, 0x36, 0x05, 0x40 + .byte 0x02, 0xb5, 0x1e, 0x54 + .byte 0xe4, 0x7d, 0x85, 0x2e +.Lprologue_end0: +.Ldebug_line_end0: + .section .debug_addr,"",@progbits + .long .Ldebug_addr_end0-.Ldebug_addr_start0 # Length of contribution +.Ldebug_addr_start0: + .short 5 # DWARF version number + .byte 8 # Address size + .byte 0 # Segment selector size +.Laddr_table_base0: + .quad .Lfunc_begin0 +.Ldebug_addr_end0: + .section .debug_names,"",@progbits + .long .Lnames_end0-.Lnames_start0 # Header: unit length +.Lnames_start0: + .short 5 # Header: version + .short 0 # Header: padding + .long 1 # Header: compilation unit count + .long 0 # Header: local type unit count + .long 1 # Header: foreign type unit count + .long 2 # Header: bucket count + .long 2 # Header: name count + .long .Lnames_abbrev_end0-.Lnames_abbrev_start0 # Header: abbreviation table size + .long 8 # Header: augmentation string size + .ascii "LLVM0700" # Header: augmentation string + .long .Lcu_begin0 # Compilation unit 0 + .quad -4149699470930386446 # Type unit 0 + .long 1 # Bucket 0 + .long 0 # Bucket 1 + .long 5863786 # Hash in Bucket 0 + .long -304389582 # Hash in Bucket 0 + .long .Lskel_string2 # String in Bucket 0: t1 + .long .Lskel_string1 # String in Bucket 0: _start + .long .Lnames1-.Lnames_entries0 # Offset in Bucket 0 + .long .Lnames0-.Lnames_entries0 # Offset in Bucket 0 +.Lnames_abbrev_start0: + .byte 1 # Abbrev code + .byte 19 # DW_TAG_structure_type + .byte 2 # DW_IDX_type_unit + .byte 11 # DW_FORM_data1 + .byte 3 # DW_IDX_die_offset + .byte 19 # DW_FORM_ref4 + .byte 4 # DW_IDX_parent + .byte 25 # DW_FORM_flag_present + .byte 0 # End of abbrev + .byte 0 # End of abbrev + .byte 2 # Abbrev code + .byte 19 # DW_TAG_structure_type + .byte 3 # DW_IDX_die_offset + .byte 19 # DW_FORM_ref4 + .byte 4 # DW_IDX_parent + .byte 25 # DW_FORM_flag_present + .byte 0 # End of abbrev + .byte 0 # End of abbrev + .byte 3 # Abbrev code + .byte 46 # DW_TAG_subprogram + .byte 3 # DW_IDX_die_offset + .byte 19 # DW_FORM_ref4 + .byte 4 # DW_IDX_parent + .byte 25 # DW_FORM_flag_present + .byte 0 # End of abbrev + .byte 0 # End of abbrev + .byte 0 # End of abbrev list +.Lnames_abbrev_end0: +.Lnames_entries0: +.Lnames1: +.L2: + .byte 1 # Abbreviation code + .byte 0 # DW_IDX_type_unit + .long 33 # DW_IDX_die_offset +.L1: # DW_IDX_parent + .byte 2 # Abbreviation code + .long 45 # DW_IDX_die_offset + .byte 0 # DW_IDX_parent + # End of list: t1 +.Lnames0: +.L0: + .byte 3 # Abbreviation code + .long 26 # DW_IDX_die_offset + .byte 0 # DW_IDX_parent + # End of list: _start + .p2align 2, 0x0 +.Lnames_end0: + .section ".note.GNU-stack","",@progbits + .addrsig + .section .debug_line,"",@progbits +.Lline_table_start0: +#--- b.s + .text + .file "b.cc" + .file 0 "/proc/self/cwd" "b.cc" md5 0xe69190c4224a66c796605e3a1324674b + .type vb,@object # @vb + .bss + .globl vb +vb: + .zero 1 + .size vb, 1 + + .section .debug_abbrev,"",@progbits + .byte 1 # Abbreviation Code + .byte 17 # DW_TAG_compile_unit + .byte 1 # DW_CHILDREN_yes + .byte 37 # DW_AT_producer + .byte 37 # DW_FORM_strx1 + .byte 19 # DW_AT_language + .byte 5 # DW_FORM_data2 + .byte 3 # DW_AT_name + .byte 37 # DW_FORM_strx1 + .byte 114 # DW_AT_str_offsets_base + .byte 23 # DW_FORM_sec_offset + .byte 16 # DW_AT_stmt_list + .byte 23 # DW_FORM_sec_offset + .byte 27 # DW_AT_comp_dir + .byte 37 # DW_FORM_strx1 + .byte 115 # DW_AT_addr_base + .byte 23 # DW_FORM_sec_offset + .byte 0 # EOM(1) + .byte 0 # EOM(2) + .byte 2 # Abbreviation Code + .byte 52 # DW_TAG_variable + .byte 0 # DW_CHILDREN_no + .byte 3 # DW_AT_name + .byte 37 # DW_FORM_strx1 + .byte 73 # DW_AT_type + .byte 19 # DW_FORM_ref4 + .byte 63 # DW_AT_external + .byte 25 # DW_FORM_flag_present + .byte 58 # DW_AT_decl_file + .byte 11 # DW_FORM_data1 + .byte 59 # DW_AT_decl_line + .byte 11 # DW_FORM_data1 + .byte 2 # DW_AT_location + .byte 24 # DW_FORM_exprloc + .byte 0 # EOM(1) + .byte 0 # EOM(2) + .byte 3 # Abbreviation Code + .byte 19 # DW_TAG_structure_type + .byte 0 # DW_CHILDREN_no + .byte 54 # DW_AT_calling_convention + .byte 11 # DW_FORM_data1 + .byte 3 # DW_AT_name + .byte 37 # DW_FORM_strx1 + .byte 11 # DW_AT_byte_size + .byte 11 # DW_FORM_data1 + .byte 58 # DW_AT_decl_file + .byte 11 # DW_FORM_data1 + .byte 59 # DW_AT_decl_line + .byte 11 # DW_FORM_data1 + .byte 0 # EOM(1) + .byte 0 # EOM(2) + .byte 0 # EOM(3) + .section .debug_info,"",@progbits +.Lcu_begin0: + .long .Ldebug_info_end0-.Ldebug_info_start0 # Length of Unit +.Ldebug_info_start0: + .short 5 # DWARF version number + .byte 1 # DWARF Unit Type + .byte 8 # Address Size (in bytes) + .long .debug_abbrev # Offset Into Abbrev. Section + .byte 1 # Abbrev [1] 0xc:0x24 DW_TAG_compile_unit + .byte 0 # DW_AT_producer + .short 33 # DW_AT_language + .byte 1 # DW_AT_name + .long .Lstr_offsets_base0 # DW_AT_str_offsets_base + .long .Lline_table_start0 # DW_AT_stmt_list + .byte 2 # DW_AT_comp_dir + .long .Laddr_table_base0 # DW_AT_addr_base + .byte 2 # Abbrev [2] 0x1e:0xb DW_TAG_variable + .byte 3 # DW_AT_name + .long 41 # DW_AT_type + # DW_AT_external + .byte 0 # DW_AT_decl_file + .byte 1 # DW_AT_decl_line + .byte 2 # DW_AT_location + .byte 161 + .byte 0 + .byte 3 # Abbrev [3] 0x29:0x6 DW_TAG_structure_type + .byte 5 # DW_AT_calling_convention + .byte 4 # DW_AT_name + .byte 1 # DW_AT_byte_size + .byte 0 # DW_AT_decl_file + .byte 1 # DW_AT_decl_line + .byte 0 # End Of Children Mark +.Ldebug_info_end0: + .section .debug_str_offsets,"",@progbits + .long 24 # Length of String Offsets Set + .short 5 + .short 0 +.Lstr_offsets_base0: + .section .debug_str,"MS",@progbits,1 +.Linfo_string0: + .byte 0 # string offset=0 +.Linfo_string1: + .asciz "b.cc" # string offset=1 +.Linfo_string2: + .asciz "/proc/self/cwd" # string offset=6 +.Linfo_string3: + .asciz "vb" # string offset=21 +.Linfo_string4: + .asciz "t1" # string offset=24 + .section .debug_str_offsets,"",@progbits + .long .Linfo_string0 + .long .Linfo_string1 + .long .Linfo_string2 + .long .Linfo_string3 + .long .Linfo_string4 + .section .debug_addr,"",@progbits + .long .Ldebug_addr_end0-.Ldebug_addr_start0 # Length of contribution +.Ldebug_addr_start0: + .short 5 # DWARF version number + .byte 8 # Address size + .byte 0 # Segment selector size +.Laddr_table_base0: + .quad vb +.Ldebug_addr_end0: + .section .debug_names,"",@progbits + .long .Lnames_end0-.Lnames_start0 # Header: unit length +.Lnames_start0: + .short 5 # Header: version + .short 0 # Header: padding + .long 1 # Header: compilation unit count + .long 0 # Header: local type unit count + .long 0 # Header: foreign type unit count + .long 2 # Header: bucket count + .long 2 # Header: name count + .long .Lnames_abbrev_end0-.Lnames_abbrev_start0 # Header: abbreviation table size + .long 8 # Header: augmentation string size + .ascii "LLVM0700" # Header: augmentation string + .long .Lcu_begin0 # Compilation unit 0 + .long 1 # Bucket 0 + .long 2 # Bucket 1 + .long 5863786 # Hash in Bucket 0 + .long 5863901 # Hash in Bucket 1 + .long .Linfo_string4 # String in Bucket 0: t1 + .long .Linfo_string3 # String in Bucket 1: vb + .long .Lnames0-.Lnames_entries0 # Offset in Bucket 0 + .long .Lnames1-.Lnames_entries0 # Offset in Bucket 1 +.Lnames_abbrev_start0: + .byte 1 # Abbrev code + .byte 19 # DW_TAG_structure_type + .byte 3 # DW_IDX_die_offset + .byte 19 # DW_FORM_ref4 + .byte 4 # DW_IDX_parent + .byte 25 # DW_FORM_flag_present + .byte 0 # End of abbrev + .byte 0 # End of abbrev + .byte 2 # Abbrev code + .byte 52 # DW_TAG_variable + .byte 3 # DW_IDX_die_offset + .byte 19 # DW_FORM_ref4 + .byte 4 # DW_IDX_parent + .byte 25 # DW_FORM_flag_present + .byte 0 # End of abbrev + .byte 0 # End of abbrev + .byte 0 # End of abbrev list +.Lnames_abbrev_end0: +.Lnames_entries0: +.Lnames0: +.L1: + .byte 1 # Abbreviation code + .long 41 # DW_IDX_die_offset + .byte 0 # DW_IDX_parent + # End of list: t1 +.Lnames1: +.L0: + .byte 2 # Abbreviation code + .long 30 # DW_IDX_die_offset + .byte 0 # DW_IDX_parent + # End of list: vb + .p2align 2, 0x0 +.Lnames_end0: + .section ".note.GNU-stack","",@progbits + .addrsig + .section .debug_line,"",@progbits +.Lline_table_start0: diff --git a/lld/test/ELF/tools/generate-content.py b/lld/test/ELF/tools/generate-content.py deleted file mode 100755 index 3665865a257a4..0000000000000 --- a/lld/test/ELF/tools/generate-content.py +++ /dev/null @@ -1,82 +0,0 @@ -#!/usr/bin/env python -"""Given a test file with the following content: - - .ifdef GEN - #--- a.cc - int va; - #--- gen - clang -S -g a.cc -o - - .endif - # content - -The script will replace the content after 'endif' with the stdout of 'gen'. -The extra files are generated in a temporary directory with split-file. - -Example: -PATH=/path/to/clang_build/bin:$PATH tools/generate-debug-names.py debug-names-*.s Inputs/debug-names*.s -""" -import contextlib, os, subprocess, sys, tempfile - - -@contextlib.contextmanager -def cd(dir): - cwd = os.getcwd() - os.chdir(dir) - try: - yield - finally: - os.chdir(cwd) - - -def process(path): - split_file_input = [] - prolog = [] - is_cc = False - is_prolog = True - with open(path) as f: - for line in f.readlines(): - line = line.rstrip() - if is_prolog: - prolog.append(line) - if line.startswith(".endif"): - is_cc = is_prolog = False - if is_cc: - split_file_input.append(line) - if line.startswith(".ifdef GEN"): - is_cc = True - - if not split_file_input: - print("no .ifdef GEN, bail out", file=sys.stderr) - return - with tempfile.TemporaryDirectory() as dir: - sub = subprocess.run( - ["split-file", "-", dir], - input="\n".join(split_file_input).encode(), - capture_output=True, - ) - if sub.returncode != 0: - sys.stderr.write(f"split-file failed\n{sub.stderr.decode()}") - return - with cd(dir): - if not os.path.exists("gen"): - print("'gen' not found", file=sys.stderr) - return - - env = dict( - os.environ, CCC_OVERRIDE_OPTIONS="+-fno-ident", PWD="/proc/self/cwd" - ) - sub = subprocess.run(["zsh", "gen"], capture_output=True, env=env) - if sub.returncode != 0: - sys.stderr.write(f"'gen' failed\n{sub.stderr.decode()}") - return - content = sub.stdout.decode() - - with open(path, "w") as f: - # Print lines up to '.endif'. - print("\n".join(prolog), file=f) - # Then print the stdout of 'gen'. - f.write(content) - - -for path in sys.argv[1:]: - process(path) From 254ceed66d7a04b3eeaa0a862d3c8c87fd937377 Mon Sep 17 00:00:00 2001 From: Caroline Tice Date: Thu, 18 Apr 2024 00:44:17 -0700 Subject: [PATCH 35/37] [lld][ELF] Address last review comments. - Pulled body of loop that reads/parses IndexEntries into a separate function (readEntry) - Removed unnecessary 'const' qualifiers on local vars - Updated comment about handling type units - Created getChunks accessor function; used it to eliminate use of 'seq' in for-loop. - Enhanced some error messages - Update debug-names-bad.s test to handle udpated error messages --- lld/ELF/SyntheticSections.cpp | 190 ++++++++++++++++++--------------- lld/ELF/SyntheticSections.h | 4 + lld/test/ELF/debug-names-bad.s | 4 +- 3 files changed, 111 insertions(+), 87 deletions(-) diff --git a/lld/ELF/SyntheticSections.cpp b/lld/ELF/SyntheticSections.cpp index 606099cbe3b31..54e575c554ea4 100644 --- a/lld/ELF/SyntheticSections.cpp +++ b/lld/ELF/SyntheticSections.cpp @@ -2734,6 +2734,91 @@ static uint32_t getDebugNamesHeaderSize(uint32_t augmentationStringSize) { /* Augmentation string */ augmentationStringSize; } +static Expected +readEntry(uint64_t &offset, const DWARFDebugNames::NameIndex &ni, + uint64_t entriesBase, DWARFDataExtractor &namesExtractor, + const LLDDWARFSection &namesSec) { + std::string errMsg; + auto ie = makeThreadLocal(); + ie->poolOffset = offset; + Error err = Error::success(); + uint64_t ulebVal = namesExtractor.getULEB128(&offset, &err); + if (err) { + errMsg = ": invalid abbrev code in entry: "; + errMsg.append(toString(std::move(err))); + return createStringError(inconvertibleErrorCode(), errMsg.c_str()); + } + if (ulebVal < UINT32_MAX) + ie->abbrevCode = static_cast(ulebVal); + else { + errMsg = ": abbrev code in entry too large for DWARF32: "; + errMsg.append(std::to_string(ulebVal)); + return createStringError(inconvertibleErrorCode(), errMsg.c_str()); + } + auto it = ni.getAbbrevs().find_as(ie->abbrevCode); + if (it == ni.getAbbrevs().end()) { + errMsg = ": entry abbrev code not found in abbrev table: "; + errMsg.append(std::to_string(ie->abbrevCode)); + return createStringError(inconvertibleErrorCode(), errMsg.c_str()); + } + + DebugNamesBaseSection::AttrValue attr, cuAttr = {0, 0}; + for (DWARFDebugNames::AttributeEncoding a : it->Attributes) { + if (a.Index == dwarf::DW_IDX_parent) { + if (a.Form == dwarf::DW_FORM_ref4) { + attr.attrValue = namesExtractor.getU32(&offset, &err); + attr.attrSize = 4; + ie->parentOffset = entriesBase + attr.attrValue; + } else if (a.Form != DW_FORM_flag_present) { + errMsg = ": invalid form for DW_IDX_parent"; + } + } else { + switch (a.Form) { + case DW_FORM_data1: + case DW_FORM_ref1: { + attr.attrValue = namesExtractor.getU8(&offset, &err); + attr.attrSize = 1; + break; + } + case DW_FORM_data2: + case DW_FORM_ref2: { + attr.attrValue = namesExtractor.getU16(&offset, &err); + attr.attrSize = 2; + break; + } + case DW_FORM_data4: + case DW_FORM_ref4: { + attr.attrValue = namesExtractor.getU32(&offset, &err); + attr.attrSize = 4; + break; + } + default: + errMsg = ": unrecognized form encoding "; + errMsg.append(std::to_string(a.Form)); + errMsg.append(" in abbrev table"); + return createStringError(inconvertibleErrorCode(), errMsg.c_str()); + } + } + if (err) { + errMsg = ": error while reading attributes: "; + errMsg.append(toString(std::move(err))); + return createStringError(inconvertibleErrorCode(), errMsg.c_str()); + } + if (a.Index == DW_IDX_compile_unit) + cuAttr = attr; + else if (a.Form != DW_FORM_flag_present) + ie->attrValues.push_back(attr); + } + + // Canonicalize abbrev by placing the CU/TU index at the end. + ie->attrValues.push_back(cuAttr); + + if (!errMsg.empty()) + return createStringError(inconvertibleErrorCode(), errMsg.c_str()); + else + return ie; +} + void DebugNamesBaseSection::parseDebugNames( InputChunk &inputChunk, OutputChunk &chunk, DWARFDataExtractor &namesExtractor, DataExtractor &strExtractor, @@ -2741,7 +2826,7 @@ void DebugNamesBaseSection::parseDebugNames( uint32_t numCus, const DWARFDebugNames::Header &, const DWARFDebugNames::DWARFDebugNamesOffsets &)> readOffsets) { - const LLDDWARFSection namesSec = inputChunk.section; + const LLDDWARFSection &namesSec = inputChunk.section; DenseMap offsetMap; // Number of CUs seen in previous NameIndex sections within current chunk. uint32_t numCus = 0; @@ -2758,8 +2843,7 @@ void DebugNamesBaseSection::parseDebugNames( Twine(nd.hdr.Version)); return; } - const uint32_t dwarfSize = - dwarf::getDwarfOffsetByteSize(DwarfFormat::DWARF32); + uint32_t dwarfSize = dwarf::getDwarfOffsetByteSize(DwarfFormat::DWARF32); DWARFDebugNames::DWARFDebugNamesOffsets locs = ni.getOffsets(); if (locs.EntriesBase > namesExtractor.getData().size()) { errorOrWarn(toString(namesSec.sec) + @@ -2782,83 +2866,23 @@ void DebugNamesBaseSection::parseDebugNames( ne.hashValue = caseFoldingDjbHash(name); // Read a series of index entries that end with abbreviation code 0. - const char *errMsg = nullptr; + std::string errMsg; uint64_t offset = locs.EntriesBase + entryOffsets[i]; while (offset < namesSec.Data.size() && namesSec.Data[offset] != 0) { // Read & store all entries (for the same string). - auto ie = makeThreadLocal(); - ie->poolOffset = offset; - Error err = Error::success(); - ie->abbrevCode = - static_cast(namesExtractor.getULEB128(&offset, &err)); - if (err) { - consumeError(std::move(err)); - errMsg = ": invalid abbrev code in entry"; - break; + Expected ieOrErr = + readEntry(offset, ni, locs.EntriesBase, namesExtractor, namesSec); + if (!ieOrErr) { + errorOrWarn(toString(namesSec.sec) + + Twine(toString(ieOrErr.takeError()))); + return; } - auto it = ni.getAbbrevs().find_as(ie->abbrevCode); - if (it == ni.getAbbrevs().end()) { - errMsg = ": invalid abbrev code in entry"; - break; - } - - AttrValue attr, cuAttr = {0, 0}; - for (DWARFDebugNames::AttributeEncoding a : it->Attributes) { - if (a.Index == dwarf::DW_IDX_parent) { - if (a.Form == dwarf::DW_FORM_ref4) { - attr.attrValue = namesExtractor.getU32(&offset, &err); - attr.attrSize = 4; - ie->parentOffset = locs.EntriesBase + attr.attrValue; - } else if (a.Form != DW_FORM_flag_present) { - errMsg = ": invalid form for DW_IDX_parent"; - } - } else { - switch (a.Form) { - case DW_FORM_data1: - case DW_FORM_ref1: { - attr.attrValue = namesExtractor.getU8(&offset, &err); - attr.attrSize = 1; - break; - } - case DW_FORM_data2: - case DW_FORM_ref2: { - attr.attrValue = namesExtractor.getU16(&offset, &err); - attr.attrSize = 2; - break; - } - case DW_FORM_data4: - case DW_FORM_ref4: { - attr.attrValue = namesExtractor.getU32(&offset, &err); - attr.attrSize = 4; - break; - } - default: - errorOrWarn(toString(namesSec.sec) + - Twine(": unrecognized form encoding ") + - Twine(a.Form) + Twine(" in abbrev table")); - return; - } - } - if (err) { - errorOrWarn(toString(namesSec.sec) + - Twine(": error while reading attributes: ") + - toString(std::move(err))); - return; - } - if (a.Index == DW_IDX_compile_unit) - cuAttr = attr; - else if (a.Form != DW_FORM_flag_present) - ie->attrValues.push_back(attr); - } - - // Canonicalize abbrev by placing the CU/TU index at the end. - ie->attrValues.push_back(cuAttr); - ne.indexEntries.push_back(std::move(ie)); + ne.indexEntries.push_back(std::move(*ieOrErr)); } if (offset >= namesSec.Data.size()) errMsg = ": index entry is out of bounds"; - if (errMsg) - errorOrWarn(toString(namesSec.sec) + Twine(errMsg)); + if (!errMsg.empty()) + errorOrWarn(toString(namesSec.sec) + Twine(errMsg.c_str())); for (IndexEntry &ie : ne.entries()) offsetMap[ie.poolOffset] = &ie; @@ -2904,12 +2928,8 @@ void DebugNamesBaseSection::computeHdrAndAbbrevTable( numCu += chunks[i].compUnits.size(); for (const NameData &nd : inputChunk.nameData) { hdr.CompUnitCount += nd.hdr.CompUnitCount; - // We are not actually handling or emitting type units yet, so - // so non-zero type unit counts will crash LLD. - // TODO: Uncomment the two lines below when we implement this for - // type units & remove the following check/warning. - //hdr.LocalTypeUnitCount += nd.hdr.LocalTypeUnitCount; - //hdr.ForeignTypeUnitCount += nd.hdr.ForeignTypeUnitCount; + // TODO: We don't handle type units yet, so LocalTypeUnitCount & + // ForeignTypeUnitCount are left as 0. if (nd.hdr.LocalTypeUnitCount || nd. hdr.ForeignTypeUnitCount) warn(toString(inputChunk.section.sec) + Twine(": type units are not implemented")); @@ -2932,7 +2952,7 @@ void DebugNamesBaseSection::computeHdrAndAbbrevTable( FoldingSet abbrevSet; // Determine the form for the DW_IDX_compile_unit attributes in the merged // index. The input form may not be big enough for all CU indices. - const dwarf::Form cuAttrForm = getMergedCuCountForm(hdr.CompUnitCount).second; + dwarf::Form cuAttrForm = getMergedCuCountForm(hdr.CompUnitCount).second; for (InputChunk &inputChunk : inputChunks) { for (auto [i, ni] : enumerate(*inputChunk.llvmDebugNames)) { for (const DWARFDebugNames::Abbrev &oldAbbrev : ni.getAbbrevs()) { @@ -3003,10 +3023,10 @@ std::pair DebugNamesBaseSection::computeEntryPool( // Collect and de-duplicate all the names (preserving all the entries). // Speed it up using multithreading, as the number of symbols can be in the // order of millions. - const size_t concurrency = + size_t concurrency = bit_floor(std::min(config->threadCount, numShards)); - const size_t shift = 32 - countr_zero(numShards); - const uint8_t cuAttrSize = getMergedCuCountForm(hdr.CompUnitCount).first; + size_t shift = 32 - countr_zero(numShards); + uint8_t cuAttrSize = getMergedCuCountForm(hdr.CompUnitCount).first; DenseMap maps[numShards]; parallelFor(0, concurrency, [&](size_t threadId) { @@ -3237,8 +3257,8 @@ template void DebugNamesSection::writeTo(uint8_t *buf) { buf += hdr.AugmentationStringSize; // Write the CU list. - for (auto i : seq(numChunks)) - for (uint32_t cuOffset : chunks[i].compUnits) + for (auto &chunk : getChunks()) + for (uint32_t cuOffset : chunk.compUnits) endian::writeNext(buf, cuOffset); // TODO: Write the local TU list, then the foreign TU list.. diff --git a/lld/ELF/SyntheticSections.h b/lld/ELF/SyntheticSections.h index 91babfb92da61..bd2db3bd450b5 100644 --- a/lld/ELF/SyntheticSections.h +++ b/lld/ELF/SyntheticSections.h @@ -892,6 +892,10 @@ class DebugNamesBaseSection : public SyntheticSection { SmallVector abbrevTable; SmallVector abbrevTableBuf; + ArrayRef getChunks() { + return ArrayRef(chunks.get(), numChunks); + } + // Sharded name entries that will be used to compute bucket_count and the // count name table. static constexpr size_t numShards = 32; diff --git a/lld/test/ELF/debug-names-bad.s b/lld/test/ELF/debug-names-bad.s index 6d644514172fe..49fe4091895bd 100644 --- a/lld/test/ELF/debug-names-bad.s +++ b/lld/test/ELF/debug-names-bad.s @@ -26,7 +26,7 @@ # RUN: llvm-mc -filetype=obj -triple=x86_64 bad-parent-form.s -o bad-parent-form.o # RUN: not ld.lld --debug-names bad-parent-form.o 2>&1 | FileCheck %s --check-prefix=BAD-PARENT-FORM --implicit-check-not=error: -# BAD-PARENT-FORM-COUNT-2: error: bad-parent-form.o:(.debug_names): invalid form for DW_IDX_parent +# BAD-PARENT-FORM: error: bad-parent-form.o:(.debug_names): invalid form for DW_IDX_parent # RUN: sed -E '/DW_IDX_die_offset/{n;s/[0-9]+.*DW_FORM_ref4/16/}' %S/Inputs/debug-names-a.s > bad-die-form.s # RUN: llvm-mc -filetype=obj -triple=x86_64 bad-die-form.s -o bad-die-form.o @@ -41,7 +41,7 @@ # RUN: ld.lld --debug-names bad-abbrev-code.o -o bad-abbrev-code --noinhibit-exec # RUN: llvm-dwarfdump --debug-names bad-abbrev-code | FileCheck %s --check-prefix=BAD-ABBREV-CODE-DWARF -# BAD-ABBREV-CODE-COUNT-2: error: bad-abbrev-code.o:(.debug_names): invalid abbrev code in entry +# BAD-ABBREV-CODE: error: bad-abbrev-code.o:(.debug_names): entry abbrev code not found in abbrev table: 3 # BAD-ABBREV-CODE-DWARF: Abbreviations [ # BAD-ABBREV-CODE-DWARF-NEXT: Abbreviation 0x1 { From 22f1ef4597af4854a53ed4cc96e087a6fcb241d4 Mon Sep 17 00:00:00 2001 From: Caroline Tice Date: Thu, 18 Apr 2024 12:16:36 -0700 Subject: [PATCH 36/37] [lld][ELF] Clean up error messages. - Clean up the error messages in readEntry function - Restore 'const' qualifier to size_t vars in computeEntryPool - Add 'const' qualifier to getChunks function. --- lld/ELF/SyntheticSections.cpp | 71 +++++++++++++++-------------------- lld/ELF/SyntheticSections.h | 2 +- 2 files changed, 31 insertions(+), 42 deletions(-) diff --git a/lld/ELF/SyntheticSections.cpp b/lld/ELF/SyntheticSections.cpp index 54e575c554ea4..3e3c293bc6877 100644 --- a/lld/ELF/SyntheticSections.cpp +++ b/lld/ELF/SyntheticSections.cpp @@ -2738,29 +2738,25 @@ static Expected readEntry(uint64_t &offset, const DWARFDebugNames::NameIndex &ni, uint64_t entriesBase, DWARFDataExtractor &namesExtractor, const LLDDWARFSection &namesSec) { - std::string errMsg; auto ie = makeThreadLocal(); ie->poolOffset = offset; Error err = Error::success(); uint64_t ulebVal = namesExtractor.getULEB128(&offset, &err); - if (err) { - errMsg = ": invalid abbrev code in entry: "; - errMsg.append(toString(std::move(err))); - return createStringError(inconvertibleErrorCode(), errMsg.c_str()); - } - if (ulebVal < UINT32_MAX) + if (err) + return createStringError(inconvertibleErrorCode(), + "invalid abbrev code in entry: %s", + toString(std::move(err)).c_str()); + if (ulebVal <= UINT32_MAX) ie->abbrevCode = static_cast(ulebVal); - else { - errMsg = ": abbrev code in entry too large for DWARF32: "; - errMsg.append(std::to_string(ulebVal)); - return createStringError(inconvertibleErrorCode(), errMsg.c_str()); - } + else + return createStringError(inconvertibleErrorCode(), + "abbrev code in entry too large for DWARF32: %d", + ulebVal); auto it = ni.getAbbrevs().find_as(ie->abbrevCode); - if (it == ni.getAbbrevs().end()) { - errMsg = ": entry abbrev code not found in abbrev table: "; - errMsg.append(std::to_string(ie->abbrevCode)); - return createStringError(inconvertibleErrorCode(), errMsg.c_str()); - } + if (it == ni.getAbbrevs().end()) + return createStringError(inconvertibleErrorCode(), + "entry abbrev code not found in abbrev table: %d", + ie->abbrevCode); DebugNamesBaseSection::AttrValue attr, cuAttr = {0, 0}; for (DWARFDebugNames::AttributeEncoding a : it->Attributes) { @@ -2769,9 +2765,9 @@ readEntry(uint64_t &offset, const DWARFDebugNames::NameIndex &ni, attr.attrValue = namesExtractor.getU32(&offset, &err); attr.attrSize = 4; ie->parentOffset = entriesBase + attr.attrValue; - } else if (a.Form != DW_FORM_flag_present) { - errMsg = ": invalid form for DW_IDX_parent"; - } + } else if (a.Form != DW_FORM_flag_present) + return createStringError(inconvertibleErrorCode(), + "invalid form for DW_IDX_parent"); } else { switch (a.Form) { case DW_FORM_data1: @@ -2793,17 +2789,15 @@ readEntry(uint64_t &offset, const DWARFDebugNames::NameIndex &ni, break; } default: - errMsg = ": unrecognized form encoding "; - errMsg.append(std::to_string(a.Form)); - errMsg.append(" in abbrev table"); - return createStringError(inconvertibleErrorCode(), errMsg.c_str()); + return createStringError( + inconvertibleErrorCode(), + "unrecognized form encoding %d in abbrev table", a.Form); } } - if (err) { - errMsg = ": error while reading attributes: "; - errMsg.append(toString(std::move(err))); - return createStringError(inconvertibleErrorCode(), errMsg.c_str()); - } + if (err) + return createStringError(inconvertibleErrorCode(), + "error while reading attributes: %s", + toString(std::move(err)).c_str()); if (a.Index == DW_IDX_compile_unit) cuAttr = attr; else if (a.Form != DW_FORM_flag_present) @@ -2813,10 +2807,7 @@ readEntry(uint64_t &offset, const DWARFDebugNames::NameIndex &ni, // Canonicalize abbrev by placing the CU/TU index at the end. ie->attrValues.push_back(cuAttr); - if (!errMsg.empty()) - return createStringError(inconvertibleErrorCode(), errMsg.c_str()); - else - return ie; + return ie; } void DebugNamesBaseSection::parseDebugNames( @@ -2866,23 +2857,21 @@ void DebugNamesBaseSection::parseDebugNames( ne.hashValue = caseFoldingDjbHash(name); // Read a series of index entries that end with abbreviation code 0. - std::string errMsg; uint64_t offset = locs.EntriesBase + entryOffsets[i]; while (offset < namesSec.Data.size() && namesSec.Data[offset] != 0) { // Read & store all entries (for the same string). Expected ieOrErr = readEntry(offset, ni, locs.EntriesBase, namesExtractor, namesSec); if (!ieOrErr) { - errorOrWarn(toString(namesSec.sec) + - Twine(toString(ieOrErr.takeError()))); + errorOrWarn(toString(namesSec.sec) + ": " + + toString(ieOrErr.takeError())); return; } ne.indexEntries.push_back(std::move(*ieOrErr)); } if (offset >= namesSec.Data.size()) - errMsg = ": index entry is out of bounds"; - if (!errMsg.empty()) - errorOrWarn(toString(namesSec.sec) + Twine(errMsg.c_str())); + errorOrWarn(toString(namesSec.sec) + + Twine(": index entry is out of bounds")); for (IndexEntry &ie : ne.entries()) offsetMap[ie.poolOffset] = &ie; @@ -3023,9 +3012,9 @@ std::pair DebugNamesBaseSection::computeEntryPool( // Collect and de-duplicate all the names (preserving all the entries). // Speed it up using multithreading, as the number of symbols can be in the // order of millions. - size_t concurrency = + const size_t concurrency = bit_floor(std::min(config->threadCount, numShards)); - size_t shift = 32 - countr_zero(numShards); + const size_t shift = 32 - countr_zero(numShards); uint8_t cuAttrSize = getMergedCuCountForm(hdr.CompUnitCount).first; DenseMap maps[numShards]; diff --git a/lld/ELF/SyntheticSections.h b/lld/ELF/SyntheticSections.h index bd2db3bd450b5..995fd4b344b07 100644 --- a/lld/ELF/SyntheticSections.h +++ b/lld/ELF/SyntheticSections.h @@ -892,7 +892,7 @@ class DebugNamesBaseSection : public SyntheticSection { SmallVector abbrevTable; SmallVector abbrevTableBuf; - ArrayRef getChunks() { + ArrayRef getChunks() const { return ArrayRef(chunks.get(), numChunks); } From 69870a570ec674ad35dfaf9962c91c841d1d9e87 Mon Sep 17 00:00:00 2001 From: Fangrui Song Date: Thu, 18 Apr 2024 12:51:19 -0700 Subject: [PATCH 37/37] Update some diagnostics in readEntry and clang-format --- lld/ELF/SyntheticSections.cpp | 15 +++++++-------- lld/docs/ReleaseNotes.rst | 3 ++- lld/test/ELF/debug-names-bad.s | 2 +- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/lld/ELF/SyntheticSections.cpp b/lld/ELF/SyntheticSections.cpp index 3e3c293bc6877..3001857406765 100644 --- a/lld/ELF/SyntheticSections.cpp +++ b/lld/ELF/SyntheticSections.cpp @@ -42,6 +42,7 @@ #include "llvm/Support/LEB128.h" #include "llvm/Support/Parallel.h" #include "llvm/Support/TimeProfiler.h" +#include #include using namespace llvm; @@ -2744,18 +2745,17 @@ readEntry(uint64_t &offset, const DWARFDebugNames::NameIndex &ni, uint64_t ulebVal = namesExtractor.getULEB128(&offset, &err); if (err) return createStringError(inconvertibleErrorCode(), - "invalid abbrev code in entry: %s", + "invalid abbrev code: %s", toString(std::move(err)).c_str()); - if (ulebVal <= UINT32_MAX) - ie->abbrevCode = static_cast(ulebVal); - else + if (!isUInt<32>(ulebVal)) return createStringError(inconvertibleErrorCode(), - "abbrev code in entry too large for DWARF32: %d", + "abbrev code too large for DWARF32: %" PRIu64, ulebVal); + ie->abbrevCode = static_cast(ulebVal); auto it = ni.getAbbrevs().find_as(ie->abbrevCode); if (it == ni.getAbbrevs().end()) return createStringError(inconvertibleErrorCode(), - "entry abbrev code not found in abbrev table: %d", + "abbrev code not found in abbrev table: %" PRIu32, ie->abbrevCode); DebugNamesBaseSection::AttrValue attr, cuAttr = {0, 0}; @@ -2806,7 +2806,6 @@ readEntry(uint64_t &offset, const DWARFDebugNames::NameIndex &ni, // Canonicalize abbrev by placing the CU/TU index at the end. ie->attrValues.push_back(cuAttr); - return ie; } @@ -2919,7 +2918,7 @@ void DebugNamesBaseSection::computeHdrAndAbbrevTable( hdr.CompUnitCount += nd.hdr.CompUnitCount; // TODO: We don't handle type units yet, so LocalTypeUnitCount & // ForeignTypeUnitCount are left as 0. - if (nd.hdr.LocalTypeUnitCount || nd. hdr.ForeignTypeUnitCount) + if (nd.hdr.LocalTypeUnitCount || nd.hdr.ForeignTypeUnitCount) warn(toString(inputChunk.section.sec) + Twine(": type units are not implemented")); // If augmentation strings are not identical, use an empty string. diff --git a/lld/docs/ReleaseNotes.rst b/lld/docs/ReleaseNotes.rst index 8efe877caf6aa..a7ed49726fd99 100644 --- a/lld/docs/ReleaseNotes.rst +++ b/lld/docs/ReleaseNotes.rst @@ -33,7 +33,8 @@ ELF Improvements ``R_AARCH64_AUTH_RELATIVE`` relocations are now supported. (`#72714 `_) * ``--debug-names`` is added to create a merged ``.debug_names`` index - from input ``.debug_names`` sections. + from input ``.debug_names`` sections. Type units are not handled yet. + (`#86508 `_) Breaking changes ---------------- diff --git a/lld/test/ELF/debug-names-bad.s b/lld/test/ELF/debug-names-bad.s index 49fe4091895bd..69a7f753e971a 100644 --- a/lld/test/ELF/debug-names-bad.s +++ b/lld/test/ELF/debug-names-bad.s @@ -41,7 +41,7 @@ # RUN: ld.lld --debug-names bad-abbrev-code.o -o bad-abbrev-code --noinhibit-exec # RUN: llvm-dwarfdump --debug-names bad-abbrev-code | FileCheck %s --check-prefix=BAD-ABBREV-CODE-DWARF -# BAD-ABBREV-CODE: error: bad-abbrev-code.o:(.debug_names): entry abbrev code not found in abbrev table: 3 +# BAD-ABBREV-CODE: error: bad-abbrev-code.o:(.debug_names): abbrev code not found in abbrev table: 3 # BAD-ABBREV-CODE-DWARF: Abbreviations [ # BAD-ABBREV-CODE-DWARF-NEXT: Abbreviation 0x1 {