diff options
Diffstat (limited to 'contrib/llvm/tools/lld/ELF')
| -rw-r--r-- | contrib/llvm/tools/lld/ELF/ICF.cpp | 25 | ||||
| -rw-r--r-- | contrib/llvm/tools/lld/ELF/InputFiles.cpp | 44 | ||||
| -rw-r--r-- | contrib/llvm/tools/lld/ELF/InputFiles.h | 1 | ||||
| -rw-r--r-- | contrib/llvm/tools/lld/ELF/SyntheticSections.cpp | 4 |
4 files changed, 38 insertions, 36 deletions
diff --git a/contrib/llvm/tools/lld/ELF/ICF.cpp b/contrib/llvm/tools/lld/ELF/ICF.cpp index e917ae76a689..d08ac73ded80 100644 --- a/contrib/llvm/tools/lld/ELF/ICF.cpp +++ b/contrib/llvm/tools/lld/ELF/ICF.cpp @@ -426,16 +426,17 @@ void ICF<ELFT>::forEachClass(llvm::function_ref<void(size_t, size_t)> Fn) { // Combine the hashes of the sections referenced by the given section into its // hash. template <class ELFT, class RelTy> -static void combineRelocHashes(InputSection *IS, ArrayRef<RelTy> Rels) { - uint32_t Hash = IS->Class[1]; +static void combineRelocHashes(unsigned Cnt, InputSection *IS, + ArrayRef<RelTy> Rels) { + uint32_t Hash = IS->Class[Cnt % 2]; for (RelTy Rel : Rels) { Symbol &S = IS->template getFile<ELFT>()->getRelocTargetSym(Rel); if (auto *D = dyn_cast<Defined>(&S)) if (auto *RelSec = dyn_cast_or_null<InputSection>(D->Section)) - Hash ^= RelSec->Class[1]; + Hash += RelSec->Class[Cnt % 2]; } // Set MSB to 1 to avoid collisions with non-hash IDs. - IS->Class[0] = Hash | (1U << 31); + IS->Class[(Cnt + 1) % 2] = Hash | (1U << 31); } static void print(const Twine &S) { @@ -453,15 +454,17 @@ template <class ELFT> void ICF<ELFT>::run() { // Initially, we use hash values to partition sections. parallelForEach(Sections, [&](InputSection *S) { - S->Class[1] = xxHash64(S->data()); + S->Class[0] = xxHash64(S->data()); }); - parallelForEach(Sections, [&](InputSection *S) { - if (S->AreRelocsRela) - combineRelocHashes<ELFT>(S, S->template relas<ELFT>()); - else - combineRelocHashes<ELFT>(S, S->template rels<ELFT>()); - }); + for (unsigned Cnt = 0; Cnt != 2; ++Cnt) { + parallelForEach(Sections, [&](InputSection *S) { + if (S->AreRelocsRela) + combineRelocHashes<ELFT>(Cnt, S, S->template relas<ELFT>()); + else + combineRelocHashes<ELFT>(Cnt, S, S->template rels<ELFT>()); + }); + } // From now on, sections in Sections vector are ordered so that sections // in the same equivalence class are consecutive in the vector. diff --git a/contrib/llvm/tools/lld/ELF/InputFiles.cpp b/contrib/llvm/tools/lld/ELF/InputFiles.cpp index e4d1dec7cbcb..bc7e61072e64 100644 --- a/contrib/llvm/tools/lld/ELF/InputFiles.cpp +++ b/contrib/llvm/tools/lld/ELF/InputFiles.cpp @@ -320,17 +320,6 @@ StringRef ObjFile<ELFT>::getShtGroupSignature(ArrayRef<Elf_Shdr> Sections, return Signature; } -template <class ELFT> -ArrayRef<typename ObjFile<ELFT>::Elf_Word> -ObjFile<ELFT>::getShtGroupEntries(const Elf_Shdr &Sec) { - const ELFFile<ELFT> &Obj = this->getObj(); - ArrayRef<Elf_Word> Entries = - CHECK(Obj.template getSectionContentsAsArray<Elf_Word>(&Sec), this); - if (Entries.empty() || Entries[0] != GRP_COMDAT) - fatal(toString(this) + ": unsupported SHT_GROUP format"); - return Entries.slice(1); -} - template <class ELFT> bool ObjFile<ELFT>::shouldMerge(const Elf_Shdr &Sec) { // On a regular link we don't merge sections if -O0 (default is -O1). This // sometimes makes the linker significantly faster, although the output will @@ -440,26 +429,34 @@ void ObjFile<ELFT>::initializeSections( case SHT_GROUP: { // De-duplicate section groups by their signatures. StringRef Signature = getShtGroupSignature(ObjSections, Sec); - bool IsNew = ComdatGroups.insert(CachedHashStringRef(Signature)).second; this->Sections[I] = &InputSection::Discarded; - // We only support GRP_COMDAT type of group. Get the all entries of the - // section here to let getShtGroupEntries to check the type early for us. - ArrayRef<Elf_Word> Entries = getShtGroupEntries(Sec); - // If it is a new section group, we want to keep group members. - // Group leader sections, which contain indices of group members, are - // discarded because they are useless beyond this point. The only - // exception is the -r option because in order to produce re-linkable - // object files, we want to pass through basically everything. + ArrayRef<Elf_Word> Entries = + CHECK(Obj.template getSectionContentsAsArray<Elf_Word>(&Sec), this); + if (Entries.empty()) + fatal(toString(this) + ": empty SHT_GROUP"); + + // The first word of a SHT_GROUP section contains flags. Currently, + // the standard defines only "GRP_COMDAT" flag for the COMDAT group. + // An group with the empty flag doesn't define anything; such sections + // are just skipped. + if (Entries[0] == 0) + continue; + + if (Entries[0] != GRP_COMDAT) + fatal(toString(this) + ": unsupported SHT_GROUP format"); + + bool IsNew = ComdatGroups.insert(CachedHashStringRef(Signature)).second; if (IsNew) { if (Config->Relocatable) this->Sections[I] = createInputSection(Sec); - continue; + continue; } + // Otherwise, discard group members. - for (uint32_t SecIndex : Entries) { + for (uint32_t SecIndex : Entries.slice(1)) { if (SecIndex >= Size) fatal(toString(this) + ": invalid section index in group: " + Twine(SecIndex)); @@ -739,7 +736,8 @@ InputSectionBase *ObjFile<ELFT>::createInputSection(const Elf_Shdr &Sec) { // sections. Drop those sections to avoid duplicate symbol errors. // FIXME: This is glibc PR20543, we should remove this hack once that has been // fixed for a while. - if (Name.startswith(".gnu.linkonce.")) + if (Name == ".gnu.linkonce.t.__x86.get_pc_thunk.bx" || + Name == ".gnu.linkonce.t.__i686.get_pc_thunk.bx") return &InputSection::Discarded; // If we are creating a new .build-id section, strip existing .build-id diff --git a/contrib/llvm/tools/lld/ELF/InputFiles.h b/contrib/llvm/tools/lld/ELF/InputFiles.h index 5094ddd804a5..d7cbbc67a365 100644 --- a/contrib/llvm/tools/lld/ELF/InputFiles.h +++ b/contrib/llvm/tools/lld/ELF/InputFiles.h @@ -175,7 +175,6 @@ template <class ELFT> class ObjFile : public ELFFileBase<ELFT> { StringRef getShtGroupSignature(ArrayRef<Elf_Shdr> Sections, const Elf_Shdr &Sec); - ArrayRef<Elf_Word> getShtGroupEntries(const Elf_Shdr &Sec); public: static bool classof(const InputFile *F) { return F->kind() == Base::ObjKind; } diff --git a/contrib/llvm/tools/lld/ELF/SyntheticSections.cpp b/contrib/llvm/tools/lld/ELF/SyntheticSections.cpp index f459c1b6b479..b1a3f8bc70ae 100644 --- a/contrib/llvm/tools/lld/ELF/SyntheticSections.cpp +++ b/contrib/llvm/tools/lld/ELF/SyntheticSections.cpp @@ -1513,8 +1513,10 @@ void RelocationBaseSection::finalizeContents() { else getParent()->Link = 0; - if (In.RelaIplt == this || In.RelaPlt == this) + if (In.RelaPlt == this) getParent()->Info = In.GotPlt->getParent()->SectionIndex; + if (In.RelaIplt == this) + getParent()->Info = In.IgotPlt->getParent()->SectionIndex; } RelrBaseSection::RelrBaseSection() |
