summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--lld/ELF/SyntheticSections.cpp49
-rw-r--r--lld/ELF/SyntheticSections.h8
2 files changed, 31 insertions, 26 deletions
diff --git a/lld/ELF/SyntheticSections.cpp b/lld/ELF/SyntheticSections.cpp
index 40a584d4f21..2e16d563226 100644
--- a/lld/ELF/SyntheticSections.cpp
+++ b/lld/ELF/SyntheticSections.cpp
@@ -1461,7 +1461,7 @@ template <class ELFT>
unsigned GnuHashTableSection<ELFT>::calcMaskWords(unsigned NumHashed) {
if (!NumHashed)
return 1;
- return NextPowerOf2((NumHashed - 1) / sizeof(Elf_Off));
+ return NextPowerOf2((NumHashed - 1) / sizeof(uintX_t));
}
template <class ELFT> void GnuHashTableSection<ELFT>::finalizeContents() {
@@ -1473,33 +1473,35 @@ template <class ELFT> void GnuHashTableSection<ELFT>::finalizeContents() {
this->OutSec->Entsize = this->Entsize;
this->OutSec->Link = In<ELFT>::DynSymTab->OutSec->SectionIndex;
- this->Size = sizeof(Elf_Word) * 4 // Header
- + sizeof(Elf_Off) * MaskWords // Bloom Filter
- + sizeof(Elf_Word) * NBuckets // Hash Buckets
- + sizeof(Elf_Word) * NumHashed; // Hash Values
+ this->Size = sizeof(uint32_t) * 4 // Header
+ + sizeof(uintX_t) * MaskWords // Bloom Filter
+ + sizeof(uint32_t) * NBuckets // Hash Buckets
+ + sizeof(uint32_t) * NumHashed; // Hash Values
}
template <class ELFT> void GnuHashTableSection<ELFT>::writeTo(uint8_t *Buf) {
- writeHeader(Buf);
+ Buf = writeHeader(Buf);
if (Symbols.empty())
return;
- writeBloomFilter(Buf);
+ Buf = writeBloomFilter(Buf);
writeHashTable(Buf);
}
template <class ELFT>
-void GnuHashTableSection<ELFT>::writeHeader(uint8_t *&Buf) {
- auto *P = reinterpret_cast<Elf_Word *>(Buf);
- *P++ = NBuckets;
- *P++ = In<ELFT>::DynSymTab->getNumSymbols() - Symbols.size();
- *P++ = MaskWords;
- *P++ = Shift2;
- Buf = reinterpret_cast<uint8_t *>(P);
+uint8_t *GnuHashTableSection<ELFT>::writeHeader(uint8_t *Buf) {
+ const endianness E = ELFT::TargetEndianness;
+ write32<E>(Buf, NBuckets);
+ write32<E>(Buf + 4, In<ELFT>::DynSymTab->getNumSymbols() - Symbols.size());
+ write32<E>(Buf + 8, MaskWords);
+ write32<E>(Buf + 12, Shift2);
+ return Buf + 16;
}
template <class ELFT>
-void GnuHashTableSection<ELFT>::writeBloomFilter(uint8_t *&Buf) {
- unsigned C = sizeof(Elf_Off) * 8;
+uint8_t *GnuHashTableSection<ELFT>::writeBloomFilter(uint8_t *Buf) {
+ typedef typename ELFT::Off Elf_Off;
+
+ const unsigned C = sizeof(uintX_t) * 8;
auto *Masks = reinterpret_cast<Elf_Off *>(Buf);
for (const SymbolData &Sym : Symbols) {
@@ -1508,11 +1510,14 @@ void GnuHashTableSection<ELFT>::writeBloomFilter(uint8_t *&Buf) {
(uintX_t(1) << ((Sym.Hash >> Shift2) % C));
Masks[Pos] |= V;
}
- Buf += sizeof(Elf_Off) * MaskWords;
+ return Buf + sizeof(uintX_t) * MaskWords;
}
template <class ELFT>
void GnuHashTableSection<ELFT>::writeHashTable(uint8_t *Buf) {
+ // A 32-bit integer type in the target endianness.
+ typedef typename ELFT::Word Elf_Word;
+
Elf_Word *Buckets = reinterpret_cast<Elf_Word *>(Buf);
Elf_Word *Values = Buckets + NBuckets;
@@ -1573,8 +1578,8 @@ void GnuHashTableSection<ELFT>::addSymbols(std::vector<SymbolTableEntry> &V) {
template <class ELFT>
HashTableSection<ELFT>::HashTableSection()
- : SyntheticSection(SHF_ALLOC, SHT_HASH, sizeof(Elf_Word), ".hash") {
- this->Entsize = sizeof(Elf_Word);
+ : SyntheticSection(SHF_ALLOC, SHT_HASH, 4, ".hash") {
+ this->Entsize = 4;
}
template <class ELFT> void HashTableSection<ELFT>::finalizeContents() {
@@ -1588,11 +1593,15 @@ template <class ELFT> void HashTableSection<ELFT>::finalizeContents() {
// 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);
+ this->Size = NumEntries * 4;
}
template <class ELFT> void HashTableSection<ELFT>::writeTo(uint8_t *Buf) {
+ // A 32-bit integer type in the target endianness.
+ typedef typename ELFT::Word Elf_Word;
+
unsigned NumSymbols = In<ELFT>::DynSymTab->getNumSymbols();
+
auto *P = reinterpret_cast<Elf_Word *>(Buf);
*P++ = NumSymbols; // nbucket
*P++ = NumSymbols; // nchain
diff --git a/lld/ELF/SyntheticSections.h b/lld/ELF/SyntheticSections.h
index 0aef47881f3..0174b619e5c 100644
--- a/lld/ELF/SyntheticSections.h
+++ b/lld/ELF/SyntheticSections.h
@@ -432,8 +432,6 @@ private:
// https://blogs.oracle.com/ali/entry/gnu_hash_elf_sections
template <class ELFT>
class GnuHashTableSection final : public SyntheticSection {
- typedef typename ELFT::Off Elf_Off;
- typedef typename ELFT::Word Elf_Word;
typedef typename ELFT::uint uintX_t;
public:
@@ -450,8 +448,8 @@ private:
static unsigned calcNBuckets(unsigned NumHashed);
static unsigned calcMaskWords(unsigned NumHashed);
- void writeHeader(uint8_t *&Buf);
- void writeBloomFilter(uint8_t *&Buf);
+ uint8_t *writeHeader(uint8_t *Buf);
+ uint8_t *writeBloomFilter(uint8_t *Buf);
void writeHashTable(uint8_t *Buf);
struct SymbolData {
@@ -469,8 +467,6 @@ private:
};
template <class ELFT> class HashTableSection final : public SyntheticSection {
- typedef typename ELFT::Word Elf_Word;
-
public:
HashTableSection();
void finalizeContents() override;
OpenPOWER on IntegriCloud