diff --git a/lld/ELF/InputFiles.cpp b/lld/ELF/InputFiles.cpp --- a/lld/ELF/InputFiles.cpp +++ b/lld/ELF/InputFiles.cpp @@ -30,6 +30,8 @@ #include "llvm/Support/RISCVAttributeParser.h" #include "llvm/Support/TarWriter.h" #include "llvm/Support/raw_ostream.h" +#include <cstdint> +#include <utility> using namespace llvm; using namespace llvm::ELF; @@ -518,6 +520,30 @@ this); } + +/// For DWARF4 the Type Units are in their own seperate .debug_types section. +/// For DWARF5 they are part of the .debug_info section. +/// Returns true if link group contains either of those sections. +template <class ELFT, class Elf_Word> +static bool isDebugGroupSection(ObjFile<ELFT> &objFile, + ArrayRef<Elf_Word> &ndxArray, + StringRef &shstrtab) { + object::ELFFile<ELFT> obj = objFile.getObj(); + for (uint32_t ndx : ndxArray) { + Expected<const typename ELFT::Shdr *> grpSection = obj.getSection(ndx); + if (!grpSection) { + warn(toString(&objFile) + " : " + + toString(std::move(grpSection.takeError()))); + break; + } + StringRef name = check(obj.getSectionName(**grpSection, shstrtab)); + if ((name.find("debug_types") != StringRef::npos) || + (name.find("debug_info") != StringRef::npos)) + return true; + } + return false; +} + template <class ELFT> void ObjFile<ELFT>::parse(bool ignoreComdats) { object::ELFFile<ELFT> obj = this->getObj(); // Read a section table. justSymbols is usually false. @@ -583,18 +609,20 @@ if (sec.sh_type != SHT_GROUP) continue; + StringRef name = check(obj.getSectionName(sec, shstrtab)); StringRef signature = getShtGroupSignature(objSections, sec); ArrayRef<Elf_Word> entries = CHECK(obj.template getSectionContentsAsArray<Elf_Word>(sec), this); if (entries.empty()) fatal(toString(this) + ": empty SHT_GROUP"); - Elf_Word flag = entries[0]; if (flag && flag != GRP_COMDAT) fatal(toString(this) + ": unsupported SHT_GROUP format"); + ArrayRef<Elf_Word> ndxArray = entries.slice(1); + bool isDebugSection = isDebugGroupSection<ELFT, Elf_Word>(*this, ndxArray, shstrtab); bool keepGroup = - (flag & GRP_COMDAT) == 0 || ignoreComdats || + (flag & GRP_COMDAT) == 0 || (ignoreComdats && !isDebugSection) || symtab.comdatGroups.try_emplace(CachedHashStringRef(signature), this) .second; if (keepGroup) { @@ -690,6 +718,8 @@ template <class ELFT> void ObjFile<ELFT>::initializeSections(bool ignoreComdats, const llvm::object::ELFFile<ELFT> &obj) { + static std::mutex io_mutex; + std::lock_guard<std::mutex> lk(io_mutex); ArrayRef<Elf_Shdr> objSections = getELFShdrs<ELFT>(); StringRef shstrtab = CHECK(obj.getSectionStringTable(objSections), this); uint64_t size = objSections.size();