Index: ELF/SyntheticSections.h =================================================================== --- ELF/SyntheticSections.h +++ 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->Wordsize == 8) ? 6 : 5; } void writeBloomFilter(uint8_t *Buf); void writeHashTable(uint8_t *Buf); Index: ELF/SyntheticSections.cpp =================================================================== --- ELF/SyntheticSections.cpp +++ ELF/SyntheticSections.cpp @@ -1438,8 +1438,9 @@ // 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") { - this->Entsize = ELFT::Is64Bits ? 0 : 4; + : SyntheticSection(SHF_ALLOC, SHT_GNU_HASH, Config->Wordsize, ".gnu.hash") { + // 64 bit .gnu.hash sections have mixed element size, sh_entsize is 0. + this->Entsize = (Config->Wordsize == 8) ? 0 : 4; } template void GnuHashTableSection::finalizeContents() { @@ -1450,26 +1451,28 @@ 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()); + support::endianness E = + Config->IsLE ? support::endianness::little : support::endianness::big; + write32(Buf, NBuckets, E); + write32(Buf + 4, In::DynSymTab->getNumSymbols() - Symbols.size(), E); + write32(Buf + 8, MaskWords, E); + write32(Buf + 12, getShift2(), E); Buf += 16; // Write a bloom filter and a hash table. writeBloomFilter(Buf); - Buf += sizeof(uintX_t) * MaskWords; + Buf += Config->Wordsize * MaskWords; writeHashTable(Buf); } @@ -1482,22 +1485,22 @@ // 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); + support::endianness E = + Config->IsLE ? support::endianness::little : support::endianness::big; + 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 = (Config->Wordsize == 8) ? read64(&((uint64_t *)Buf)[I], E) + : read32(&((uint32_t *)Buf)[I], E); + 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; - + const endianness E = Config->IsLE ? endianness::little : endianness::big; // Group symbols by hash value. std::vector> Syms(NBuckets); for (const Entry &Ent : Symbols) @@ -1505,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, E); // 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, E); + write32(&Values[I++], Vec.back().Hash | 1, E); } }