@@ -846,6 +846,12 @@ uint64_t MipsGotSection::getGp() const {
846
846
return ElfSym::MipsGp->getVA (0 );
847
847
}
848
848
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
+
849
855
static void writeUint (uint8_t *Buf, uint64_t Val) {
850
856
if (Config->Is64 )
851
857
write64 (Buf, Val, Config->Endianness );
@@ -1439,7 +1445,8 @@ template <class ELFT> void SymbolTableSection<ELFT>::writeTo(uint8_t *Buf) {
1439
1445
// safe bet is to specify -hash-style=both for backward compatibilty.
1440
1446
template <class ELFT >
1441
1447
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
+ }
1443
1450
1444
1451
template <class ELFT > void GnuHashTableSection<ELFT>::finalizeContents() {
1445
1452
this ->OutSec ->Link = In<ELFT>::DynSymTab->OutSec ->SectionIndex ;
@@ -1449,26 +1456,27 @@ template <class ELFT> void GnuHashTableSection<ELFT>::finalizeContents() {
1449
1456
if (Symbols.empty ())
1450
1457
MaskWords = 1 ;
1451
1458
else
1452
- MaskWords = NextPowerOf2 ((Symbols.size () - 1 ) / sizeof (uintX_t) );
1459
+ MaskWords = NextPowerOf2 ((Symbols.size () - 1 ) / Config-> Wordsize );
1453
1460
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
1458
1465
}
1459
1466
1460
- template <class ELFT > void GnuHashTableSection<ELFT>::writeTo(uint8_t *Buf) {
1467
+ template <class ELFT >
1468
+ void GnuHashTableSection<ELFT>::writeTo(uint8_t *Buf) {
1461
1469
// 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 );
1467
1475
Buf += 16 ;
1468
1476
1469
1477
// Write a bloom filter and a hash table.
1470
1478
writeBloomFilter (Buf);
1471
- Buf += sizeof (uintX_t) * MaskWords;
1479
+ Buf += Config-> Wordsize * MaskWords;
1472
1480
writeHashTable (Buf);
1473
1481
}
1474
1482
@@ -1481,45 +1489,41 @@ template <class ELFT> void GnuHashTableSection<ELFT>::writeTo(uint8_t *Buf) {
1481
1489
// p.9, https://www.akkadia.org/drepper/dsohowto.pdf
1482
1490
template <class ELFT >
1483
1491
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 ;
1488
1493
for (const Entry &Sym : Symbols) {
1489
1494
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);
1492
1499
}
1493
1500
}
1494
1501
1495
1502
template <class ELFT >
1496
1503
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
-
1500
1504
// Group symbols by hash value.
1501
1505
std::vector<std::vector<Entry>> Syms (NBuckets);
1502
1506
for (const Entry &Ent : Symbols)
1503
1507
Syms[Ent.Hash % NBuckets].push_back (Ent);
1504
1508
1505
1509
// Write hash buckets. Hash buckets contain indices in the following
1506
1510
// hash value table.
1507
- Elf_Word *Buckets = reinterpret_cast <Elf_Word *>(Buf);
1511
+ uint32_t *Buckets = reinterpret_cast <uint32_t *>(Buf);
1508
1512
for (size_t I = 0 ; I < NBuckets; ++I)
1509
1513
if (!Syms[I].empty ())
1510
- Buckets[I] = Syms[I][0 ].Body ->DynsymIndex ;
1514
+ write32 ( Buckets + I, Syms[I][0 ].Body ->DynsymIndex , Config-> Endianness ) ;
1511
1515
1512
1516
// Write a hash value table. It represents a sequence of chains that
1513
1517
// share the same hash modulo value. The last element of each chain
1514
1518
// is terminated by LSB 1.
1515
- Elf_Word *Values = Buckets + NBuckets;
1519
+ uint32_t *Values = Buckets + NBuckets;
1516
1520
size_t I = 0 ;
1517
1521
for (std::vector<Entry> &Vec : Syms) {
1518
1522
if (Vec.empty ())
1519
1523
continue ;
1520
1524
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 ) ;
1523
1527
}
1524
1528
}
1525
1529
0 commit comments