[lld] r296439 - Refactor {Gnu,}HashTableSection classes.

Rui Ueyama via llvm-commits llvm-commits at lists.llvm.org
Mon Feb 27 21:53:48 PST 2017


Author: ruiu
Date: Mon Feb 27 23:53:47 2017
New Revision: 296439

URL: http://llvm.org/viewvc/llvm-project?rev=296439&view=rev
Log:
Refactor {Gnu,}HashTableSection classes.

In other places in LLD, we use write32<E> instead of Elf_Word.
This patch uses the same technique in the hash table classes.
The hash table classes needs improving as they have almost no
comments. We at least need to describe the hash table structure
and why we have to support two different on-disk hash tables
for the same purpose. I'll do that later.

Modified:
    lld/trunk/ELF/SyntheticSections.cpp
    lld/trunk/ELF/SyntheticSections.h

Modified: lld/trunk/ELF/SyntheticSections.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/SyntheticSections.cpp?rev=296439&r1=296438&r2=296439&view=diff
==============================================================================
--- lld/trunk/ELF/SyntheticSections.cpp (original)
+++ lld/trunk/ELF/SyntheticSections.cpp Mon Feb 27 23:53:47 2017
@@ -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 GnuHashTableS
 
   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>::writeBlo
                 (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>::addSymbo
 
 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 HashTableSect
   // 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

Modified: lld/trunk/ELF/SyntheticSections.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/SyntheticSections.h?rev=296439&r1=296438&r2=296439&view=diff
==============================================================================
--- lld/trunk/ELF/SyntheticSections.h (original)
+++ lld/trunk/ELF/SyntheticSections.h Mon Feb 27 23:53:47 2017
@@ -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;




More information about the llvm-commits mailing list