Skip to content

Commit 5f73bc9

Browse files
author
George Rimar
committedMar 29, 2017
[ELF] - Prepare GnuHashTableSection<ELFT> for detemplation.
This patch changes GnuHashTableSection implementation to avoid depend on uintX_t and other ELFT stuff, reducing amount of changes for following patch(es). Differential revision: https://reviews.llvm.org/D31184 llvm-svn: 298998
1 parent ce957f9 commit 5f73bc9

File tree

2 files changed

+32
-30
lines changed

2 files changed

+32
-30
lines changed
 

‎lld/ELF/SyntheticSections.cpp

Lines changed: 31 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -846,6 +846,12 @@ uint64_t MipsGotSection::getGp() const {
846846
return ElfSym::MipsGp->getVA(0);
847847
}
848848

849+
static uint64_t readUint(uint8_t *Buf) {
850+
if (Config->Is64)
851+
return read64(Buf, Config->Endianness);
852+
return read32(Buf, Config->Endianness);
853+
}
854+
849855
static void writeUint(uint8_t *Buf, uint64_t Val) {
850856
if (Config->Is64)
851857
write64(Buf, Val, Config->Endianness);
@@ -1439,7 +1445,8 @@ template <class ELFT> void SymbolTableSection<ELFT>::writeTo(uint8_t *Buf) {
14391445
// safe bet is to specify -hash-style=both for backward compatibilty.
14401446
template <class ELFT>
14411447
GnuHashTableSection<ELFT>::GnuHashTableSection()
1442-
: SyntheticSection(SHF_ALLOC, SHT_GNU_HASH, sizeof(uintX_t), ".gnu.hash") {}
1448+
: SyntheticSection(SHF_ALLOC, SHT_GNU_HASH, Config->Wordsize, ".gnu.hash") {
1449+
}
14431450

14441451
template <class ELFT> void GnuHashTableSection<ELFT>::finalizeContents() {
14451452
this->OutSec->Link = In<ELFT>::DynSymTab->OutSec->SectionIndex;
@@ -1449,26 +1456,27 @@ template <class ELFT> void GnuHashTableSection<ELFT>::finalizeContents() {
14491456
if (Symbols.empty())
14501457
MaskWords = 1;
14511458
else
1452-
MaskWords = NextPowerOf2((Symbols.size() - 1) / sizeof(uintX_t));
1459+
MaskWords = NextPowerOf2((Symbols.size() - 1) / Config->Wordsize);
14531460

1454-
Size = 16; // Header
1455-
Size += sizeof(uintX_t) * MaskWords; // Bloom filter
1456-
Size += NBuckets * 4; // Hash buckets
1457-
Size += Symbols.size() * 4; // Hash values
1461+
Size = 16; // Header
1462+
Size += Config->Wordsize * MaskWords; // Bloom filter
1463+
Size += NBuckets * 4; // Hash buckets
1464+
Size += Symbols.size() * 4; // Hash values
14581465
}
14591466

1460-
template <class ELFT> void GnuHashTableSection<ELFT>::writeTo(uint8_t *Buf) {
1467+
template <class ELFT>
1468+
void GnuHashTableSection<ELFT>::writeTo(uint8_t *Buf) {
14611469
// Write a header.
1462-
const endianness E = ELFT::TargetEndianness;
1463-
write32<E>(Buf, NBuckets);
1464-
write32<E>(Buf + 4, In<ELFT>::DynSymTab->getNumSymbols() - Symbols.size());
1465-
write32<E>(Buf + 8, MaskWords);
1466-
write32<E>(Buf + 12, getShift2());
1470+
write32(Buf, NBuckets, Config->Endianness);
1471+
write32(Buf + 4, In<ELFT>::DynSymTab->getNumSymbols() - Symbols.size(),
1472+
Config->Endianness);
1473+
write32(Buf + 8, MaskWords, Config->Endianness);
1474+
write32(Buf + 12, getShift2(), Config->Endianness);
14671475
Buf += 16;
14681476

14691477
// Write a bloom filter and a hash table.
14701478
writeBloomFilter(Buf);
1471-
Buf += sizeof(uintX_t) * MaskWords;
1479+
Buf += Config->Wordsize * MaskWords;
14721480
writeHashTable(Buf);
14731481
}
14741482

@@ -1481,45 +1489,41 @@ template <class ELFT> void GnuHashTableSection<ELFT>::writeTo(uint8_t *Buf) {
14811489
// p.9, https://www.akkadia.org/drepper/dsohowto.pdf
14821490
template <class ELFT>
14831491
void GnuHashTableSection<ELFT>::writeBloomFilter(uint8_t *Buf) {
1484-
typedef typename ELFT::Off Elf_Off;
1485-
const unsigned C = sizeof(uintX_t) * 8;
1486-
1487-
auto *Filter = reinterpret_cast<Elf_Off *>(Buf);
1492+
const unsigned C = Config->Wordsize * 8;
14881493
for (const Entry &Sym : Symbols) {
14891494
size_t I = (Sym.Hash / C) & (MaskWords - 1);
1490-
Filter[I] |= uintX_t(1) << (Sym.Hash % C);
1491-
Filter[I] |= uintX_t(1) << ((Sym.Hash >> getShift2()) % C);
1495+
uint64_t Val = readUint(Buf + I * Config->Wordsize);
1496+
Val |= uint64_t(1) << (Sym.Hash % C);
1497+
Val |= uint64_t(1) << ((Sym.Hash >> getShift2()) % C);
1498+
writeUint(Buf + I * Config->Wordsize, Val);
14921499
}
14931500
}
14941501

14951502
template <class ELFT>
14961503
void GnuHashTableSection<ELFT>::writeHashTable(uint8_t *Buf) {
1497-
// A 32-bit integer type in the target endianness.
1498-
typedef typename ELFT::Word Elf_Word;
1499-
15001504
// Group symbols by hash value.
15011505
std::vector<std::vector<Entry>> Syms(NBuckets);
15021506
for (const Entry &Ent : Symbols)
15031507
Syms[Ent.Hash % NBuckets].push_back(Ent);
15041508

15051509
// Write hash buckets. Hash buckets contain indices in the following
15061510
// hash value table.
1507-
Elf_Word *Buckets = reinterpret_cast<Elf_Word *>(Buf);
1511+
uint32_t *Buckets = reinterpret_cast<uint32_t *>(Buf);
15081512
for (size_t I = 0; I < NBuckets; ++I)
15091513
if (!Syms[I].empty())
1510-
Buckets[I] = Syms[I][0].Body->DynsymIndex;
1514+
write32(Buckets + I, Syms[I][0].Body->DynsymIndex, Config->Endianness);
15111515

15121516
// Write a hash value table. It represents a sequence of chains that
15131517
// share the same hash modulo value. The last element of each chain
15141518
// is terminated by LSB 1.
1515-
Elf_Word *Values = Buckets + NBuckets;
1519+
uint32_t *Values = Buckets + NBuckets;
15161520
size_t I = 0;
15171521
for (std::vector<Entry> &Vec : Syms) {
15181522
if (Vec.empty())
15191523
continue;
15201524
for (const Entry &Ent : makeArrayRef(Vec).drop_back())
1521-
Values[I++] = Ent.Hash & ~1;
1522-
Values[I++] = Vec.back().Hash | 1;
1525+
write32(Values + I++, Ent.Hash & ~1, Config->Endianness);
1526+
write32(Values + I++, Vec.back().Hash | 1, Config->Endianness);
15231527
}
15241528
}
15251529

‎lld/ELF/SyntheticSections.h

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -433,8 +433,6 @@ template <class ELFT> class SymbolTableSection final : public SyntheticSection {
433433
// https://blogs.oracle.com/ali/entry/gnu_hash_elf_sections
434434
template <class ELFT>
435435
class GnuHashTableSection final : public SyntheticSection {
436-
typedef typename ELFT::uint uintX_t;
437-
438436
public:
439437
GnuHashTableSection();
440438
void finalizeContents() override;
@@ -446,7 +444,7 @@ class GnuHashTableSection final : public SyntheticSection {
446444
void addSymbols(std::vector<SymbolTableEntry> &Symbols);
447445

448446
private:
449-
size_t getShift2() const { return ELFT::Is64Bits ? 6 : 5; }
447+
size_t getShift2() const { return Config->Is64 ? 6 : 5; }
450448

451449
void writeBloomFilter(uint8_t *Buf);
452450
void writeHashTable(uint8_t *Buf);

0 commit comments

Comments
 (0)
Please sign in to comment.