aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2017-02-01 21:35:17 +0000
committerDimitry Andric <dim@FreeBSD.org>2017-02-01 21:35:17 +0000
commit63b9abd1dbe002d940a818f51dd9d6e585e41c84 (patch)
tree8f257c7b94b6320186de5cc06685fbc0b7e0a93f
parentb025d011dd270230aeb50d7174a2a05616fe81eb (diff)
downloadsrc-63b9abd1dbe002d940a818f51dd9d6e585e41c84.tar.gz
src-63b9abd1dbe002d940a818f51dd9d6e585e41c84.zip
Vendor import of lld release_40 branch r293807:vendor/lld/lld-release_40-r293807
Notes
Notes: svn path=/vendor/lld/dist/; revision=313063 svn path=/vendor/lld/lld-release_40-r293807/; revision=313064; tag=vendor/lld/lld-release_40-r293807
-rw-r--r--ELF/InputFiles.h4
-rw-r--r--ELF/InputSection.cpp3
-rw-r--r--ELF/SyntheticSections.cpp76
-rw-r--r--ELF/SyntheticSections.h13
-rw-r--r--ELF/Writer.cpp12
-rw-r--r--test/ELF/Inputs/dtrace-r.obin0 -> 624 bytes
-rw-r--r--test/ELF/aarch64-relro.s14
-rw-r--r--test/ELF/basic-mips.s2
-rw-r--r--test/ELF/basic-ppc.s2
-rw-r--r--test/ELF/dtrace-r.test8
10 files changed, 83 insertions, 51 deletions
diff --git a/ELF/InputFiles.h b/ELF/InputFiles.h
index 73dda7b566b8..95888061d877 100644
--- a/ELF/InputFiles.h
+++ b/ELF/InputFiles.h
@@ -180,10 +180,6 @@ public:
// R_MIPS_GPREL16 / R_MIPS_GPREL32 relocations.
uint32_t MipsGp0 = 0;
- // The number is the offset in the string table. It will be used as the
- // st_name of the symbol.
- std::vector<std::pair<const DefinedRegular<ELFT> *, unsigned>> KeptLocalSyms;
-
// Name of source file obtained from STT_FILE symbol value,
// or empty string if there is no such symbol in object file
// symbol table.
diff --git a/ELF/InputSection.cpp b/ELF/InputSection.cpp
index 358004248373..6b1e92891b98 100644
--- a/ELF/InputSection.cpp
+++ b/ELF/InputSection.cpp
@@ -246,7 +246,8 @@ void InputSection<ELFT>::copyRelocations(uint8_t *Buf, ArrayRef<RelTy> Rels) {
if (Config->Rela)
P->r_addend = getAddend<ELFT>(Rel);
P->r_offset = RelocatedSection->getOffset(Rel.r_offset);
- P->setSymbolAndType(Body.DynsymIndex, Type, Config->Mips64EL);
+ P->setSymbolAndType(In<ELFT>::SymTab->getSymbolIndex(&Body), Type,
+ Config->Mips64EL);
}
}
diff --git a/ELF/SyntheticSections.cpp b/ELF/SyntheticSections.cpp
index f09b60b2b494..204b5993a62a 100644
--- a/ELF/SyntheticSections.cpp
+++ b/ELF/SyntheticSections.cpp
@@ -1065,22 +1065,21 @@ template <class ELFT> void SymbolTableSection<ELFT>::finalize() {
this->OutSec->Info = this->Info = NumLocals + 1;
this->OutSec->Entsize = this->Entsize;
- if (Config->Relocatable) {
- size_t I = NumLocals;
- for (const SymbolTableEntry &S : Symbols)
- S.Symbol->DynsymIndex = ++I;
+ if (Config->Relocatable)
return;
- }
if (!StrTabSec.isDynamic()) {
- std::stable_sort(
- Symbols.begin(), Symbols.end(),
- [](const SymbolTableEntry &L, const SymbolTableEntry &R) {
- return L.Symbol->symbol()->computeBinding() == STB_LOCAL &&
- R.Symbol->symbol()->computeBinding() != STB_LOCAL;
+ auto GlobBegin = Symbols.begin() + NumLocals;
+ auto It = std::stable_partition(
+ GlobBegin, Symbols.end(), [](const SymbolTableEntry &S) {
+ return S.Symbol->symbol()->computeBinding() == STB_LOCAL;
});
+ // update sh_info with number of Global symbols output with computed
+ // binding of STB_LOCAL
+ this->OutSec->Info = this->Info = 1 + It - Symbols.begin();
return;
}
+
if (In<ELFT>::GnuHashTab)
// NB: It also sorts Symbols to meet the GNU hash table requirements.
In<ELFT>::GnuHashTab->addSymbols(Symbols);
@@ -1094,10 +1093,25 @@ template <class ELFT> void SymbolTableSection<ELFT>::finalize() {
S.Symbol->DynsymIndex = ++I;
}
-template <class ELFT> void SymbolTableSection<ELFT>::addSymbol(SymbolBody *B) {
+template <class ELFT> void SymbolTableSection<ELFT>::addGlobal(SymbolBody *B) {
Symbols.push_back({B, StrTabSec.addString(B->getName(), false)});
}
+template <class ELFT> void SymbolTableSection<ELFT>::addLocal(SymbolBody *B) {
+ assert(!StrTabSec.isDynamic());
+ ++NumLocals;
+ Symbols.push_back({B, StrTabSec.addString(B->getName())});
+}
+
+template <class ELFT>
+size_t SymbolTableSection<ELFT>::getSymbolIndex(SymbolBody *Body) {
+ auto I = llvm::find_if(
+ Symbols, [&](const SymbolTableEntry &E) { return E.Symbol == Body; });
+ if (I == Symbols.end())
+ return 0;
+ return I - Symbols.begin() + 1;
+}
+
template <class ELFT> void SymbolTableSection<ELFT>::writeTo(uint8_t *Buf) {
Buf += sizeof(Elf_Sym);
@@ -1113,26 +1127,24 @@ template <class ELFT>
void SymbolTableSection<ELFT>::writeLocalSymbols(uint8_t *&Buf) {
// Iterate over all input object files to copy their local symbols
// to the output symbol table pointed by Buf.
- for (ObjectFile<ELFT> *File : Symtab<ELFT>::X->getObjectFiles()) {
- for (const std::pair<const DefinedRegular<ELFT> *, size_t> &P :
- File->KeptLocalSyms) {
- const DefinedRegular<ELFT> &Body = *P.first;
- InputSectionBase<ELFT> *Section = Body.Section;
- auto *ESym = reinterpret_cast<Elf_Sym *>(Buf);
-
- if (!Section) {
- ESym->st_shndx = SHN_ABS;
- ESym->st_value = Body.Value;
- } else {
- const OutputSectionBase *OutSec = Section->OutSec;
- ESym->st_shndx = OutSec->SectionIndex;
- ESym->st_value = OutSec->Addr + Section->getOffset(Body);
- }
- ESym->st_name = P.second;
- ESym->st_size = Body.template getSize<ELFT>();
- ESym->setBindingAndType(STB_LOCAL, Body.Type);
- Buf += sizeof(*ESym);
+
+ for (auto I = Symbols.begin(); I != Symbols.begin() + NumLocals; ++I) {
+ const DefinedRegular<ELFT> &Body = *cast<DefinedRegular<ELFT>>(I->Symbol);
+ InputSectionBase<ELFT> *Section = Body.Section;
+ auto *ESym = reinterpret_cast<Elf_Sym *>(Buf);
+
+ if (!Section) {
+ ESym->st_shndx = SHN_ABS;
+ ESym->st_value = Body.Value;
+ } else {
+ const OutputSectionBase *OutSec = Section->OutSec;
+ ESym->st_shndx = OutSec->SectionIndex;
+ ESym->st_value = OutSec->Addr + Section->getOffset(Body);
}
+ ESym->st_name = I->StrTabOffset;
+ ESym->st_size = Body.template getSize<ELFT>();
+ ESym->setBindingAndType(STB_LOCAL, Body.Type);
+ Buf += sizeof(*ESym);
}
}
@@ -1141,7 +1153,9 @@ void SymbolTableSection<ELFT>::writeGlobalSymbols(uint8_t *Buf) {
// Write the internal symbol table contents to the output symbol table
// pointed by Buf.
auto *ESym = reinterpret_cast<Elf_Sym *>(Buf);
- for (const SymbolTableEntry &S : Symbols) {
+
+ for (auto I = Symbols.begin() + NumLocals; I != Symbols.end(); ++I) {
+ const SymbolTableEntry &S = *I;
SymbolBody *Body = S.Symbol;
size_t StrOff = S.StrTabOffset;
diff --git a/ELF/SyntheticSections.h b/ELF/SyntheticSections.h
index f7e891ec3a66..df67e079ad0e 100644
--- a/ELF/SyntheticSections.h
+++ b/ELF/SyntheticSections.h
@@ -366,23 +366,26 @@ public:
void finalize() override;
void writeTo(uint8_t *Buf) override;
size_t getSize() const override { return getNumSymbols() * sizeof(Elf_Sym); }
- void addSymbol(SymbolBody *Body);
+ void addGlobal(SymbolBody *Body);
+ void addLocal(SymbolBody *Body);
StringTableSection<ELFT> &getStrTabSec() const { return StrTabSec; }
- unsigned getNumSymbols() const { return NumLocals + Symbols.size() + 1; }
+ unsigned getNumSymbols() const { return Symbols.size() + 1; }
+ size_t getSymbolIndex(SymbolBody *Body);
ArrayRef<SymbolTableEntry> getSymbols() const { return Symbols; }
static const OutputSectionBase *getOutputSection(SymbolBody *Sym);
- unsigned NumLocals = 0;
- StringTableSection<ELFT> &StrTabSec;
-
private:
void writeLocalSymbols(uint8_t *&Buf);
void writeGlobalSymbols(uint8_t *Buf);
// A vector of symbols and their string table offsets.
std::vector<SymbolTableEntry> Symbols;
+
+ StringTableSection<ELFT> &StrTabSec;
+
+ unsigned NumLocals = 0;
};
// Outputs GNU Hash section. For detailed explanation see:
diff --git a/ELF/Writer.cpp b/ELF/Writer.cpp
index 4f2f91993f8d..f00fb6d11ea5 100644
--- a/ELF/Writer.cpp
+++ b/ELF/Writer.cpp
@@ -455,11 +455,7 @@ template <class ELFT> void Writer<ELFT>::copyLocalSymbols() {
InputSectionBase<ELFT> *Sec = DR->Section;
if (!shouldKeepInSymtab<ELFT>(Sec, B->getName(), *B))
continue;
- ++In<ELFT>::SymTab->NumLocals;
- if (Config->Relocatable)
- B->DynsymIndex = In<ELFT>::SymTab->NumLocals;
- F->KeptLocalSyms.push_back(std::make_pair(
- DR, In<ELFT>::SymTab->StrTabSec.addString(B->getName())));
+ In<ELFT>::SymTab->addLocal(B);
}
}
}
@@ -1024,10 +1020,10 @@ template <class ELFT> void Writer<ELFT>::finalizeSections() {
if (!includeInSymtab<ELFT>(*Body))
continue;
if (In<ELFT>::SymTab)
- In<ELFT>::SymTab->addSymbol(Body);
+ In<ELFT>::SymTab->addGlobal(Body);
if (In<ELFT>::DynSymTab && S->includeInDynsym()) {
- In<ELFT>::DynSymTab->addSymbol(Body);
+ In<ELFT>::DynSymTab->addGlobal(Body);
if (auto *SS = dyn_cast<SharedSymbol<ELFT>>(Body))
if (SS->file()->isNeeded())
In<ELFT>::VerNeed->addSymbol(SS);
@@ -1466,7 +1462,7 @@ template <class ELFT> void Writer<ELFT>::setPhdrs() {
// The glibc dynamic loader rounds the size down, so we need to round up
// to protect the last page. This is a no-op on FreeBSD which always
// rounds up.
- P.p_memsz = alignTo(P.p_memsz, Config->MaxPageSize);
+ P.p_memsz = alignTo(P.p_memsz, Target->PageSize);
}
// The TLS pointer goes after PT_TLS. At least glibc will align it,
diff --git a/test/ELF/Inputs/dtrace-r.o b/test/ELF/Inputs/dtrace-r.o
new file mode 100644
index 000000000000..ce742de3bd2b
--- /dev/null
+++ b/test/ELF/Inputs/dtrace-r.o
Binary files differ
diff --git a/test/ELF/aarch64-relro.s b/test/ELF/aarch64-relro.s
new file mode 100644
index 000000000000..3ec19d73d683
--- /dev/null
+++ b/test/ELF/aarch64-relro.s
@@ -0,0 +1,14 @@
+# REQUIRES: aarch64
+# RUN: llvm-mc -filetype=obj -triple=aarch64-unknown-freebsd %s -o %t
+# RUN: ld.lld %t -o %t2
+# RUN: llvm-readobj -program-headers %t2 | FileCheck %s
+
+# CHECK: Type: PT_GNU_RELRO
+# CHECK-NEXT: Offset:
+# CHECK-NEXT: VirtualAddress:
+# CHECK-NEXT: PhysicalAddress:
+# CHECK-NEXT: FileSize:
+# CHECK-NEXT: MemSize: 4096
+
+.section .data.rel.ro,"aw",%progbits
+.byte 1
diff --git a/test/ELF/basic-mips.s b/test/ELF/basic-mips.s
index 67b58f8f028c..57181caf4eaf 100644
--- a/test/ELF/basic-mips.s
+++ b/test/ELF/basic-mips.s
@@ -176,7 +176,7 @@ __start:
# CHECK-NEXT: Offset: 0x20010
# CHECK-NEXT: Size: 48
# CHECK-NEXT: Link: 10
-# CHECK-NEXT: Info: 1
+# CHECK-NEXT: Info: 2
# CHECK-NEXT: AddressAlignment: 4
# CHECK-NEXT: EntrySize: 16
# CHECK-NEXT: }
diff --git a/test/ELF/basic-ppc.s b/test/ELF/basic-ppc.s
index e08c7a32eb7c..aae81fe2ac0e 100644
--- a/test/ELF/basic-ppc.s
+++ b/test/ELF/basic-ppc.s
@@ -178,7 +178,7 @@
// CHECK-NEXT: Offset: 0x2038
// CHECK-NEXT: Size: 32
// CHECK-NEXT: Link: 9
-// CHECK-NEXT: Info: 1
+// CHECK-NEXT: Info: 2
// CHECK-NEXT: AddressAlignment: 4
// CHECK-NEXT: EntrySize: 16
// CHECK-NEXT: SectionData (
diff --git a/test/ELF/dtrace-r.test b/test/ELF/dtrace-r.test
new file mode 100644
index 000000000000..2b6d885d4c89
--- /dev/null
+++ b/test/ELF/dtrace-r.test
@@ -0,0 +1,8 @@
+RUN: ld.lld -r -o %t.o %p/Inputs/dtrace-r.o
+RUN: llvm-readobj -r %t.o | FileCheck %s
+
+CHECK: Relocations [
+CHECK-NEXT: Section ({{.*}}) .rela.text {
+CHECK-NEXT: 0x0 R_X86_64_NONE - 0x0
+CHECK-NEXT: }
+CHECK-NEXT: ]