forked from OSchip/llvm-project
[ELF] Convert HashTableSection to input section
Differential revision: https://reviews.llvm.org/D26834 llvm-svn: 287326
This commit is contained in:
parent
f8f6f1e783
commit
b96e809c7f
|
@ -140,45 +140,6 @@ template <class ELFT> void PltSection<ELFT>::finalize() {
|
||||||
this->Size = Target->PltHeaderSize + Entries.size() * Target->PltEntrySize;
|
this->Size = Target->PltHeaderSize + Entries.size() * Target->PltEntrySize;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class ELFT>
|
|
||||||
HashTableSection<ELFT>::HashTableSection()
|
|
||||||
: OutputSectionBase(".hash", SHT_HASH, SHF_ALLOC) {
|
|
||||||
this->Entsize = sizeof(Elf_Word);
|
|
||||||
this->Addralign = sizeof(Elf_Word);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class ELFT> void HashTableSection<ELFT>::finalize() {
|
|
||||||
this->Link = In<ELFT>::DynSymTab->OutSec->SectionIndex;
|
|
||||||
|
|
||||||
unsigned NumEntries = 2; // nbucket and nchain.
|
|
||||||
NumEntries += In<ELFT>::DynSymTab->getNumSymbols(); // The chain entries.
|
|
||||||
|
|
||||||
// Create as many buckets as there are symbols.
|
|
||||||
// FIXME: This is simplistic. We can try to optimize it, but implementing
|
|
||||||
// support for SHT_GNU_HASH is probably even more profitable.
|
|
||||||
NumEntries += In<ELFT>::DynSymTab->getNumSymbols();
|
|
||||||
this->Size = NumEntries * sizeof(Elf_Word);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class ELFT> void HashTableSection<ELFT>::writeTo(uint8_t *Buf) {
|
|
||||||
unsigned NumSymbols = In<ELFT>::DynSymTab->getNumSymbols();
|
|
||||||
auto *P = reinterpret_cast<Elf_Word *>(Buf);
|
|
||||||
*P++ = NumSymbols; // nbucket
|
|
||||||
*P++ = NumSymbols; // nchain
|
|
||||||
|
|
||||||
Elf_Word *Buckets = P;
|
|
||||||
Elf_Word *Chains = P + NumSymbols;
|
|
||||||
|
|
||||||
for (const SymbolTableEntry &S : In<ELFT>::DynSymTab->getSymbols()) {
|
|
||||||
SymbolBody *Body = S.Symbol;
|
|
||||||
StringRef Name = Body->getName();
|
|
||||||
unsigned I = Body->DynsymIndex;
|
|
||||||
uint32_t Hash = hashSysV(Name) % NumSymbols;
|
|
||||||
Chains[I] = Buckets[Hash];
|
|
||||||
Buckets[Hash] = I;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Returns the number of version definition entries. Because the first entry
|
// Returns the number of version definition entries. Because the first entry
|
||||||
// is for the version definition itself, it is the number of versioned symbols
|
// is for the version definition itself, it is the number of versioned symbols
|
||||||
// plus one. Note that we don't support multiple versions yet.
|
// plus one. Note that we don't support multiple versions yet.
|
||||||
|
@ -938,11 +899,6 @@ template class PltSection<ELF32BE>;
|
||||||
template class PltSection<ELF64LE>;
|
template class PltSection<ELF64LE>;
|
||||||
template class PltSection<ELF64BE>;
|
template class PltSection<ELF64BE>;
|
||||||
|
|
||||||
template class HashTableSection<ELF32LE>;
|
|
||||||
template class HashTableSection<ELF32BE>;
|
|
||||||
template class HashTableSection<ELF64LE>;
|
|
||||||
template class HashTableSection<ELF64BE>;
|
|
||||||
|
|
||||||
template class OutputSection<ELF32LE>;
|
template class OutputSection<ELF32LE>;
|
||||||
template class OutputSection<ELF32BE>;
|
template class OutputSection<ELF32BE>;
|
||||||
template class OutputSection<ELF64LE>;
|
template class OutputSection<ELF64LE>;
|
||||||
|
|
|
@ -44,7 +44,6 @@ public:
|
||||||
Base,
|
Base,
|
||||||
EHFrame,
|
EHFrame,
|
||||||
EHFrameHdr,
|
EHFrameHdr,
|
||||||
HashTable,
|
|
||||||
Merge,
|
Merge,
|
||||||
Plt,
|
Plt,
|
||||||
Regular,
|
Regular,
|
||||||
|
@ -317,19 +316,6 @@ private:
|
||||||
llvm::DenseMap<std::pair<ArrayRef<uint8_t>, SymbolBody *>, CieRecord> CieMap;
|
llvm::DenseMap<std::pair<ArrayRef<uint8_t>, SymbolBody *>, CieRecord> CieMap;
|
||||||
};
|
};
|
||||||
|
|
||||||
template <class ELFT> class HashTableSection final : public OutputSectionBase {
|
|
||||||
typedef typename ELFT::Word Elf_Word;
|
|
||||||
|
|
||||||
public:
|
|
||||||
HashTableSection();
|
|
||||||
void finalize() override;
|
|
||||||
void writeTo(uint8_t *Buf) override;
|
|
||||||
Kind getKind() const override { return HashTable; }
|
|
||||||
static bool classof(const OutputSectionBase *B) {
|
|
||||||
return B->getKind() == HashTable;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// --eh-frame-hdr option tells linker to construct a header for all the
|
// --eh-frame-hdr option tells linker to construct a header for all the
|
||||||
// .eh_frame sections. This header is placed to a section named .eh_frame_hdr
|
// .eh_frame sections. This header is placed to a section named .eh_frame_hdr
|
||||||
// and also to a PT_GNU_EH_FRAME segment.
|
// and also to a PT_GNU_EH_FRAME segment.
|
||||||
|
@ -372,7 +358,6 @@ template <class ELFT> struct Out {
|
||||||
static EhFrameHeader<ELFT> *EhFrameHdr;
|
static EhFrameHeader<ELFT> *EhFrameHdr;
|
||||||
static EhOutputSection<ELFT> *EhFrame;
|
static EhOutputSection<ELFT> *EhFrame;
|
||||||
static GdbIndexSection<ELFT> *GdbIndex;
|
static GdbIndexSection<ELFT> *GdbIndex;
|
||||||
static HashTableSection<ELFT> *HashTab;
|
|
||||||
static OutputSection<ELFT> *Bss;
|
static OutputSection<ELFT> *Bss;
|
||||||
static OutputSection<ELFT> *MipsRldMap;
|
static OutputSection<ELFT> *MipsRldMap;
|
||||||
static OutputSectionBase *Opd;
|
static OutputSectionBase *Opd;
|
||||||
|
@ -427,7 +412,6 @@ template <class ELFT> uint8_t Out<ELFT>::First;
|
||||||
template <class ELFT> EhFrameHeader<ELFT> *Out<ELFT>::EhFrameHdr;
|
template <class ELFT> EhFrameHeader<ELFT> *Out<ELFT>::EhFrameHdr;
|
||||||
template <class ELFT> EhOutputSection<ELFT> *Out<ELFT>::EhFrame;
|
template <class ELFT> EhOutputSection<ELFT> *Out<ELFT>::EhFrame;
|
||||||
template <class ELFT> GdbIndexSection<ELFT> *Out<ELFT>::GdbIndex;
|
template <class ELFT> GdbIndexSection<ELFT> *Out<ELFT>::GdbIndex;
|
||||||
template <class ELFT> HashTableSection<ELFT> *Out<ELFT>::HashTab;
|
|
||||||
template <class ELFT> OutputSection<ELFT> *Out<ELFT>::Bss;
|
template <class ELFT> OutputSection<ELFT> *Out<ELFT>::Bss;
|
||||||
template <class ELFT> OutputSection<ELFT> *Out<ELFT>::MipsRldMap;
|
template <class ELFT> OutputSection<ELFT> *Out<ELFT>::MipsRldMap;
|
||||||
template <class ELFT> OutputSectionBase *Out<ELFT>::Opd;
|
template <class ELFT> OutputSectionBase *Out<ELFT>::Opd;
|
||||||
|
|
|
@ -796,8 +796,8 @@ template <class ELFT> void DynamicSection<ELFT>::finalize() {
|
||||||
add({DT_STRSZ, In<ELFT>::DynStrTab->getSize()});
|
add({DT_STRSZ, In<ELFT>::DynStrTab->getSize()});
|
||||||
if (In<ELFT>::GnuHashTab)
|
if (In<ELFT>::GnuHashTab)
|
||||||
add({DT_GNU_HASH, In<ELFT>::GnuHashTab});
|
add({DT_GNU_HASH, In<ELFT>::GnuHashTab});
|
||||||
if (Out<ELFT>::HashTab)
|
if (In<ELFT>::HashTab)
|
||||||
add({DT_HASH, Out<ELFT>::HashTab});
|
add({DT_HASH, In<ELFT>::HashTab});
|
||||||
|
|
||||||
if (Out<ELFT>::PreinitArray) {
|
if (Out<ELFT>::PreinitArray) {
|
||||||
add({DT_PREINIT_ARRAY, Out<ELFT>::PreinitArray});
|
add({DT_PREINIT_ARRAY, Out<ELFT>::PreinitArray});
|
||||||
|
@ -1290,6 +1290,45 @@ void GnuHashTableSection<ELFT>::addSymbols(std::vector<SymbolTableEntry> &V) {
|
||||||
V.push_back({Sym.Body, Sym.STName});
|
V.push_back({Sym.Body, Sym.STName});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <class ELFT>
|
||||||
|
HashTableSection<ELFT>::HashTableSection()
|
||||||
|
: SyntheticSection<ELFT>(SHF_ALLOC, SHT_HASH, sizeof(Elf_Word), ".hash") {
|
||||||
|
this->Entsize = sizeof(Elf_Word);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class ELFT> void HashTableSection<ELFT>::finalize() {
|
||||||
|
this->OutSec->Link = this->Link = In<ELFT>::DynSymTab->OutSec->SectionIndex;
|
||||||
|
this->OutSec->Entsize = this->Entsize;
|
||||||
|
|
||||||
|
unsigned NumEntries = 2; // nbucket and nchain.
|
||||||
|
NumEntries += In<ELFT>::DynSymTab->getNumSymbols(); // The chain entries.
|
||||||
|
|
||||||
|
// Create as many buckets as there are symbols.
|
||||||
|
// FIXME: This is simplistic. We can try to optimize it, but implementing
|
||||||
|
// support for SHT_GNU_HASH is probably even more profitable.
|
||||||
|
NumEntries += In<ELFT>::DynSymTab->getNumSymbols();
|
||||||
|
this->Size = NumEntries * sizeof(Elf_Word);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class ELFT> void HashTableSection<ELFT>::writeTo(uint8_t *Buf) {
|
||||||
|
unsigned NumSymbols = In<ELFT>::DynSymTab->getNumSymbols();
|
||||||
|
auto *P = reinterpret_cast<Elf_Word *>(Buf);
|
||||||
|
*P++ = NumSymbols; // nbucket
|
||||||
|
*P++ = NumSymbols; // nchain
|
||||||
|
|
||||||
|
Elf_Word *Buckets = P;
|
||||||
|
Elf_Word *Chains = P + NumSymbols;
|
||||||
|
|
||||||
|
for (const SymbolTableEntry &S : In<ELFT>::DynSymTab->getSymbols()) {
|
||||||
|
SymbolBody *Body = S.Symbol;
|
||||||
|
StringRef Name = Body->getName();
|
||||||
|
unsigned I = Body->DynsymIndex;
|
||||||
|
uint32_t Hash = hashSysV(Name) % NumSymbols;
|
||||||
|
Chains[I] = Buckets[Hash];
|
||||||
|
Buckets[Hash] = I;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
template InputSection<ELF32LE> *elf::createCommonSection();
|
template InputSection<ELF32LE> *elf::createCommonSection();
|
||||||
template InputSection<ELF32BE> *elf::createCommonSection();
|
template InputSection<ELF32BE> *elf::createCommonSection();
|
||||||
template InputSection<ELF64LE> *elf::createCommonSection();
|
template InputSection<ELF64LE> *elf::createCommonSection();
|
||||||
|
@ -1389,3 +1428,8 @@ template class elf::GnuHashTableSection<ELF32LE>;
|
||||||
template class elf::GnuHashTableSection<ELF32BE>;
|
template class elf::GnuHashTableSection<ELF32BE>;
|
||||||
template class elf::GnuHashTableSection<ELF64LE>;
|
template class elf::GnuHashTableSection<ELF64LE>;
|
||||||
template class elf::GnuHashTableSection<ELF64BE>;
|
template class elf::GnuHashTableSection<ELF64BE>;
|
||||||
|
|
||||||
|
template class elf::HashTableSection<ELF32LE>;
|
||||||
|
template class elf::HashTableSection<ELF32BE>;
|
||||||
|
template class elf::HashTableSection<ELF64LE>;
|
||||||
|
template class elf::HashTableSection<ELF64BE>;
|
||||||
|
|
|
@ -476,6 +476,20 @@ private:
|
||||||
uintX_t Size = 0;
|
uintX_t Size = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
template <class ELFT>
|
||||||
|
class HashTableSection final : public SyntheticSection<ELFT> {
|
||||||
|
typedef typename ELFT::Word Elf_Word;
|
||||||
|
|
||||||
|
public:
|
||||||
|
HashTableSection();
|
||||||
|
void finalize() override;
|
||||||
|
void writeTo(uint8_t *Buf) override;
|
||||||
|
size_t getSize() const override { return this->Size; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
size_t Size = 0;
|
||||||
|
};
|
||||||
|
|
||||||
template <class ELFT> InputSection<ELFT> *createCommonSection();
|
template <class ELFT> InputSection<ELFT> *createCommonSection();
|
||||||
template <class ELFT> InputSection<ELFT> *createInterpSection();
|
template <class ELFT> InputSection<ELFT> *createInterpSection();
|
||||||
template <class ELFT> MergeInputSection<ELFT> *createCommentSection();
|
template <class ELFT> MergeInputSection<ELFT> *createCommentSection();
|
||||||
|
@ -491,6 +505,7 @@ template <class ELFT> struct In {
|
||||||
static GotSection<ELFT> *Got;
|
static GotSection<ELFT> *Got;
|
||||||
static MipsGotSection<ELFT> *MipsGot;
|
static MipsGotSection<ELFT> *MipsGot;
|
||||||
static GotPltSection<ELFT> *GotPlt;
|
static GotPltSection<ELFT> *GotPlt;
|
||||||
|
static HashTableSection<ELFT> *HashTab;
|
||||||
static InputSection<ELFT> *Interp;
|
static InputSection<ELFT> *Interp;
|
||||||
static MipsAbiFlagsSection<ELFT> *MipsAbiFlags;
|
static MipsAbiFlagsSection<ELFT> *MipsAbiFlags;
|
||||||
static MipsOptionsSection<ELFT> *MipsOptions;
|
static MipsOptionsSection<ELFT> *MipsOptions;
|
||||||
|
@ -511,6 +526,7 @@ template <class ELFT> GnuHashTableSection<ELFT> *In<ELFT>::GnuHashTab;
|
||||||
template <class ELFT> GotSection<ELFT> *In<ELFT>::Got;
|
template <class ELFT> GotSection<ELFT> *In<ELFT>::Got;
|
||||||
template <class ELFT> MipsGotSection<ELFT> *In<ELFT>::MipsGot;
|
template <class ELFT> MipsGotSection<ELFT> *In<ELFT>::MipsGot;
|
||||||
template <class ELFT> GotPltSection<ELFT> *In<ELFT>::GotPlt;
|
template <class ELFT> GotPltSection<ELFT> *In<ELFT>::GotPlt;
|
||||||
|
template <class ELFT> HashTableSection<ELFT> *In<ELFT>::HashTab;
|
||||||
template <class ELFT> InputSection<ELFT> *In<ELFT>::Interp;
|
template <class ELFT> InputSection<ELFT> *In<ELFT>::Interp;
|
||||||
template <class ELFT> MipsAbiFlagsSection<ELFT> *In<ELFT>::MipsAbiFlags;
|
template <class ELFT> MipsAbiFlagsSection<ELFT> *In<ELFT>::MipsAbiFlags;
|
||||||
template <class ELFT> MipsOptionsSection<ELFT> *In<ELFT>::MipsOptions;
|
template <class ELFT> MipsOptionsSection<ELFT> *In<ELFT>::MipsOptions;
|
||||||
|
|
|
@ -241,7 +241,7 @@ template <class ELFT> void Writer<ELFT>::createSyntheticSections() {
|
||||||
if (Config->GnuHash)
|
if (Config->GnuHash)
|
||||||
In<ELFT>::GnuHashTab = make<GnuHashTableSection<ELFT>>();
|
In<ELFT>::GnuHashTab = make<GnuHashTableSection<ELFT>>();
|
||||||
if (Config->SysvHash)
|
if (Config->SysvHash)
|
||||||
Out<ELFT>::HashTab = make<HashTableSection<ELFT>>();
|
In<ELFT>::HashTab = make<HashTableSection<ELFT>>();
|
||||||
if (Config->GdbIndex)
|
if (Config->GdbIndex)
|
||||||
Out<ELFT>::GdbIndex = make<GdbIndexSection<ELFT>>();
|
Out<ELFT>::GdbIndex = make<GdbIndexSection<ELFT>>();
|
||||||
|
|
||||||
|
@ -952,10 +952,10 @@ template <class ELFT> void Writer<ELFT>::finalizeSections() {
|
||||||
// Dynamic section must be the last one in this list and dynamic
|
// Dynamic section must be the last one in this list and dynamic
|
||||||
// symbol table section (DynSymTab) must be the first one.
|
// symbol table section (DynSymTab) must be the first one.
|
||||||
finalizeSynthetic<ELFT>(
|
finalizeSynthetic<ELFT>(
|
||||||
{In<ELFT>::DynSymTab, In<ELFT>::GnuHashTab, In<ELFT>::SymTab,
|
{In<ELFT>::DynSymTab, In<ELFT>::GnuHashTab, In<ELFT>::HashTab,
|
||||||
In<ELFT>::ShStrTab, In<ELFT>::StrTab, In<ELFT>::DynStrTab, In<ELFT>::Got,
|
In<ELFT>::SymTab, In<ELFT>::ShStrTab, In<ELFT>::StrTab,
|
||||||
In<ELFT>::MipsGot, In<ELFT>::GotPlt, In<ELFT>::RelaDyn,
|
In<ELFT>::DynStrTab, In<ELFT>::Got, In<ELFT>::MipsGot, In<ELFT>::GotPlt,
|
||||||
In<ELFT>::RelaPlt, In<ELFT>::Dynamic});
|
In<ELFT>::RelaDyn, In<ELFT>::RelaPlt, In<ELFT>::Dynamic});
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class ELFT> bool Writer<ELFT>::needsGot() {
|
template <class ELFT> bool Writer<ELFT>::needsGot() {
|
||||||
|
@ -997,7 +997,7 @@ template <class ELFT> void Writer<ELFT>::addPredefinedSections() {
|
||||||
Add(Out<ELFT>::VerNeed);
|
Add(Out<ELFT>::VerNeed);
|
||||||
|
|
||||||
addInputSec(In<ELFT>::GnuHashTab);
|
addInputSec(In<ELFT>::GnuHashTab);
|
||||||
Add(Out<ELFT>::HashTab);
|
addInputSec(In<ELFT>::HashTab);
|
||||||
addInputSec(In<ELFT>::Dynamic);
|
addInputSec(In<ELFT>::Dynamic);
|
||||||
addInputSec(In<ELFT>::DynStrTab);
|
addInputSec(In<ELFT>::DynStrTab);
|
||||||
if (In<ELFT>::RelaDyn->hasRelocs())
|
if (In<ELFT>::RelaDyn->hasRelocs())
|
||||||
|
|
Loading…
Reference in New Issue