[lld] Explicitly ignore comdat groups when parsing LTO object(s)

Any symbols defined in the LTO object are by definition the ones we
want in the final output so we skip the comdat group checking in those
cases.

This change makes the ELF code more explicit about this and means
that wasm and ELF do this in the same way.

Differential Revision: https://reviews.llvm.org/D62884

llvm-svn: 362625
This commit is contained in:
Sam Clegg
2019-06-05 17:39:37 +00:00
parent b67cb3cda0
commit 579c8df701
4 changed files with 23 additions and 39 deletions

View File

@@ -1506,9 +1506,8 @@ template <class ELFT> void LinkerDriver::compileBitcodeFiles() {
LTO->add(*File);
for (InputFile *File : LTO->compile()) {
DenseMap<CachedHashStringRef, const InputFile *> DummyGroups;
auto *Obj = cast<ObjFile<ELFT>>(File);
Obj->parse(DummyGroups);
Obj->parse(/*IgnoreComdats=*/true);
for (Symbol *Sym : Obj->getGlobalSymbols())
Sym->parseSymbolVersion();
ObjectFiles.push_back(File);

View File

@@ -178,13 +178,13 @@ template <class ELFT> static void doParseFile(InputFile *File) {
// LLVM bitcode file
if (auto *F = dyn_cast<BitcodeFile>(File)) {
BitcodeFiles.push_back(F);
F->parse<ELFT>(Symtab->ComdatGroups);
F->parse<ELFT>();
return;
}
// Regular object file
ObjectFiles.push_back(File);
cast<ObjFile<ELFT>>(File)->parse(Symtab->ComdatGroups);
cast<ObjFile<ELFT>>(File)->parse();
}
// Add symbols in File to the symbol table.
@@ -449,14 +449,12 @@ template <class ELFT> ArrayRef<Symbol *> ObjFile<ELFT>::getGlobalSymbols() {
return makeArrayRef(this->Symbols).slice(this->FirstGlobal);
}
template <class ELFT>
void ObjFile<ELFT>::parse(
DenseMap<CachedHashStringRef, const InputFile *> &ComdatGroups) {
template <class ELFT> void ObjFile<ELFT>::parse(bool IgnoreComdats) {
// Read a section table. JustSymbols is usually false.
if (this->JustSymbols)
initializeJustSymbols();
else
initializeSections(ComdatGroups);
initializeSections(IgnoreComdats);
// Read a symbol table.
initializeSymbols();
@@ -564,8 +562,7 @@ static void addDependentLibrary(StringRef Specifier, const InputFile *F) {
}
template <class ELFT>
void ObjFile<ELFT>::initializeSections(
DenseMap<CachedHashStringRef, const InputFile *> &ComdatGroups) {
void ObjFile<ELFT>::initializeSections(bool IgnoreComdats) {
const ELFFile<ELFT> &Obj = this->getObj();
ArrayRef<Elf_Shdr> ObjSections = CHECK(Obj.sections(), this);
@@ -625,7 +622,9 @@ void ObjFile<ELFT>::initializeSections(
fatal(toString(this) + ": unsupported SHT_GROUP format");
bool IsNew =
ComdatGroups.try_emplace(CachedHashStringRef(Signature), this).second;
IgnoreComdats ||
Symtab->ComdatGroups.try_emplace(CachedHashStringRef(Signature), this)
.second;
if (IsNew) {
if (Config->Relocatable)
this->Sections[I] = createInputSection(Sec);
@@ -1478,13 +1477,11 @@ static Symbol *createBitcodeSymbol(const std::vector<bool> &KeptComdats,
return Symtab->addSymbol(New);
}
template <class ELFT>
void BitcodeFile::parse(
DenseMap<CachedHashStringRef, const InputFile *> &ComdatGroups) {
template <class ELFT> void BitcodeFile::parse() {
std::vector<bool> KeptComdats;
for (StringRef S : Obj->getComdatTable())
KeptComdats.push_back(
ComdatGroups.try_emplace(CachedHashStringRef(S), this).second);
Symtab->ComdatGroups.try_emplace(CachedHashStringRef(S), this).second);
for (const lto::InputFile::Symbol &ObjSym : Obj->symbols())
Symbols.push_back(createBitcodeSymbol<ELFT>(KeptComdats, ObjSym, *this));
@@ -1617,14 +1614,10 @@ std::string elf::replaceThinLTOSuffix(StringRef Path) {
return Path;
}
template void
BitcodeFile::parse<ELF32LE>(DenseMap<CachedHashStringRef, const InputFile *> &);
template void
BitcodeFile::parse<ELF32BE>(DenseMap<CachedHashStringRef, const InputFile *> &);
template void
BitcodeFile::parse<ELF64LE>(DenseMap<CachedHashStringRef, const InputFile *> &);
template void
BitcodeFile::parse<ELF64BE>(DenseMap<CachedHashStringRef, const InputFile *> &);
template void BitcodeFile::parse<ELF32LE>();
template void BitcodeFile::parse<ELF32BE>();
template void BitcodeFile::parse<ELF64LE>();
template void BitcodeFile::parse<ELF64BE>();
template void LazyObjFile::parse<ELF32LE>();
template void LazyObjFile::parse<ELF32BE>();

View File

@@ -201,8 +201,7 @@ public:
this->ArchiveName = ArchiveName;
}
void parse(llvm::DenseMap<llvm::CachedHashStringRef, const InputFile *>
&ComdatGroups);
void parse(bool IgnoreComdats = false);
StringRef getShtGroupSignature(ArrayRef<Elf_Shdr> Sections,
const Elf_Shdr &Sec);
@@ -250,8 +249,7 @@ public:
ArrayRef<Elf_CGProfile> CGProfile;
private:
void initializeSections(llvm::DenseMap<llvm::CachedHashStringRef,
const InputFile *> &ComdatGroups);
void initializeSections(bool IgnoreComdats);
void initializeSymbols();
void initializeJustSymbols();
void initializeDwarf();
@@ -340,9 +338,7 @@ public:
BitcodeFile(MemoryBufferRef M, StringRef ArchiveName,
uint64_t OffsetInArchive);
static bool classof(const InputFile *F) { return F->kind() == BitcodeKind; }
template <class ELFT>
void parse(llvm::DenseMap<llvm::CachedHashStringRef, const InputFile *>
&ComdatGroups);
template <class ELFT> void parse();
std::unique_ptr<llvm::lto::InputFile> Obj;
};

View File

@@ -306,11 +306,10 @@ void ObjFile::parse(bool IgnoreComdats) {
TypeIsUsed.resize(getWasmObj()->types().size(), false);
ArrayRef<StringRef> Comdats = WasmObj->linkingData().Comdats;
for (unsigned I = 0; I < Comdats.size(); ++I)
if (IgnoreComdats)
KeptComdats.push_back(true);
else
KeptComdats.push_back(Symtab->addComdat(Comdats[I]));
for (unsigned I = 0; I < Comdats.size(); ++I) {
bool IsNew = IgnoreComdats || Symtab->addComdat(Comdats[I]);
KeptComdats.push_back(IsNew);
}
// Populate `Segments`.
for (const WasmSegment &S : WasmObj->dataSegments())
@@ -535,10 +534,7 @@ void BitcodeFile::parse(bool IgnoreComdats) {
}
std::vector<bool> KeptComdats;
for (StringRef S : Obj->getComdatTable())
if (IgnoreComdats)
KeptComdats.push_back(true);
else
KeptComdats.push_back(Symtab->addComdat(S));
KeptComdats.push_back(Symtab->addComdat(S));
for (const lto::InputFile::Symbol &ObjSym : Obj->symbols())
Symbols.push_back(createBitcodeSymbol(KeptComdats, ObjSym, *this));