summaryrefslogtreecommitdiff
path: root/contrib/llvm/tools/lld/ELF
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/llvm/tools/lld/ELF')
-rw-r--r--contrib/llvm/tools/lld/ELF/ICF.cpp25
-rw-r--r--contrib/llvm/tools/lld/ELF/InputFiles.cpp44
-rw-r--r--contrib/llvm/tools/lld/ELF/InputFiles.h1
-rw-r--r--contrib/llvm/tools/lld/ELF/SyntheticSections.cpp4
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()