Index: lld/trunk/ELF/SyntheticSections.h =================================================================== --- lld/trunk/ELF/SyntheticSections.h +++ lld/trunk/ELF/SyntheticSections.h @@ -433,8 +433,6 @@ // https://blogs.oracle.com/ali/entry/gnu_hash_elf_sections template class GnuHashTableSection final : public SyntheticSection { - typedef typename ELFT::uint uintX_t; - public: GnuHashTableSection(); void finalizeContents() override; @@ -446,7 +444,7 @@ void addSymbols(std::vector &Symbols); private: - size_t getShift2() const { return ELFT::Is64Bits ? 6 : 5; } + size_t getShift2() const { return Config->Is64 ? 6 : 5; } void writeBloomFilter(uint8_t *Buf); void writeHashTable(uint8_t *Buf); Index: lld/trunk/ELF/SyntheticSections.cpp =================================================================== --- lld/trunk/ELF/SyntheticSections.cpp +++ lld/trunk/ELF/SyntheticSections.cpp @@ -846,6 +846,12 @@ return ElfSym::MipsGp->getVA(0); } +static uint64_t readUint(uint8_t *Buf) { + if (Config->Is64) + return read64(Buf, Config->Endianness); + return read32(Buf, Config->Endianness); +} + static void writeUint(uint8_t *Buf, uint64_t Val) { if (Config->Is64) write64(Buf, Val, Config->Endianness); @@ -1439,7 +1445,8 @@ // safe bet is to specify -hash-style=both for backward compatibilty. template GnuHashTableSection::GnuHashTableSection() - : SyntheticSection(SHF_ALLOC, SHT_GNU_HASH, sizeof(uintX_t), ".gnu.hash") {} + : SyntheticSection(SHF_ALLOC, SHT_GNU_HASH, Config->Wordsize, ".gnu.hash") { +} template void GnuHashTableSection::finalizeContents() { this->OutSec->Link = In::DynSymTab->OutSec->SectionIndex; @@ -1449,26 +1456,27 @@ if (Symbols.empty()) MaskWords = 1; else - MaskWords = NextPowerOf2((Symbols.size() - 1) / sizeof(uintX_t)); + MaskWords = NextPowerOf2((Symbols.size() - 1) / Config->Wordsize); - Size = 16; // Header - Size += sizeof(uintX_t) * MaskWords; // Bloom filter - Size += NBuckets * 4; // Hash buckets - Size += Symbols.size() * 4; // Hash values + Size = 16; // Header + Size += Config->Wordsize * MaskWords; // Bloom filter + Size += NBuckets * 4; // Hash buckets + Size += Symbols.size() * 4; // Hash values } -template void GnuHashTableSection::writeTo(uint8_t *Buf) { +template +void GnuHashTableSection::writeTo(uint8_t *Buf) { // Write a header. - const endianness E = ELFT::TargetEndianness; - write32(Buf, NBuckets); - write32(Buf + 4, In::DynSymTab->getNumSymbols() - Symbols.size()); - write32(Buf + 8, MaskWords); - write32(Buf + 12, getShift2()); + write32(Buf, NBuckets, Config->Endianness); + write32(Buf + 4, In::DynSymTab->getNumSymbols() - Symbols.size(), + Config->Endianness); + write32(Buf + 8, MaskWords, Config->Endianness); + write32(Buf + 12, getShift2(), Config->Endianness); Buf += 16; // Write a bloom filter and a hash table. writeBloomFilter(Buf); - Buf += sizeof(uintX_t) * MaskWords; + Buf += Config->Wordsize * MaskWords; writeHashTable(Buf); } @@ -1481,22 +1489,18 @@ // p.9, https://www.akkadia.org/drepper/dsohowto.pdf template void GnuHashTableSection::writeBloomFilter(uint8_t *Buf) { - typedef typename ELFT::Off Elf_Off; - const unsigned C = sizeof(uintX_t) * 8; - - auto *Filter = reinterpret_cast(Buf); + const unsigned C = Config->Wordsize * 8; for (const Entry &Sym : Symbols) { size_t I = (Sym.Hash / C) & (MaskWords - 1); - Filter[I] |= uintX_t(1) << (Sym.Hash % C); - Filter[I] |= uintX_t(1) << ((Sym.Hash >> getShift2()) % C); + uint64_t Val = readUint(Buf + I * Config->Wordsize); + Val |= uint64_t(1) << (Sym.Hash % C); + Val |= uint64_t(1) << ((Sym.Hash >> getShift2()) % C); + writeUint(Buf + I * Config->Wordsize, Val); } } template void GnuHashTableSection::writeHashTable(uint8_t *Buf) { - // A 32-bit integer type in the target endianness. - typedef typename ELFT::Word Elf_Word; - // Group symbols by hash value. std::vector> Syms(NBuckets); for (const Entry &Ent : Symbols) @@ -1504,22 +1508,22 @@ // Write hash buckets. Hash buckets contain indices in the following // hash value table. - Elf_Word *Buckets = reinterpret_cast(Buf); + uint32_t *Buckets = reinterpret_cast(Buf); for (size_t I = 0; I < NBuckets; ++I) if (!Syms[I].empty()) - Buckets[I] = Syms[I][0].Body->DynsymIndex; + write32(Buckets + I, Syms[I][0].Body->DynsymIndex, Config->Endianness); // Write a hash value table. It represents a sequence of chains that // share the same hash modulo value. The last element of each chain // is terminated by LSB 1. - Elf_Word *Values = Buckets + NBuckets; + uint32_t *Values = Buckets + NBuckets; size_t I = 0; for (std::vector &Vec : Syms) { if (Vec.empty()) continue; for (const Entry &Ent : makeArrayRef(Vec).drop_back()) - Values[I++] = Ent.Hash & ~1; - Values[I++] = Vec.back().Hash | 1; + write32(Values + I++, Ent.Hash & ~1, Config->Endianness); + write32(Values + I++, Vec.back().Hash | 1, Config->Endianness); } }