Vendor import of lld release_40 branch r293807:

https://llvm.org/svn/llvm-project/lld/branches/release_40@293807
This commit is contained in:
Dimitry Andric 2017-02-01 21:35:17 +00:00
parent b025d011dd
commit 63b9abd1db
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/vendor/lld/dist/; revision=313063
svn path=/vendor/lld/lld-release_40-r293807/; revision=313064; tag=vendor/lld/lld-release_40-r293807
10 changed files with 85 additions and 53 deletions

View File

@ -180,10 +180,6 @@ template <class ELFT> class ObjectFile : public ELFFileBase<ELFT> {
// 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.

View File

@ -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);
}
}

View File

@ -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()) {
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 (!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;
});
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;

View File

@ -366,23 +366,26 @@ class SymbolTableSection final : public SyntheticSection<ELFT> {
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:

View File

@ -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,

BIN
test/ELF/Inputs/dtrace-r.o Normal file

Binary file not shown.

14
test/ELF/aarch64-relro.s Normal file
View File

@ -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

View File

@ -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: }

View File

@ -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 (

8
test/ELF/dtrace-r.test Normal file
View File

@ -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: ]