diff options
| author | Rui Ueyama <ruiu@google.com> | 2017-02-28 05:53:47 +0000 | 
|---|---|---|
| committer | Rui Ueyama <ruiu@google.com> | 2017-02-28 05:53:47 +0000 | 
| commit | 6b776ad985e102cb206346c8ec6044fc12a32a0c (patch) | |
| tree | bdda40cee496a0d5cd234c91a8214350cf243e7f | |
| parent | c647dcfba062256006ed2eb6a54193c4fb6e4622 (diff) | |
| download | bcm5719-llvm-6b776ad985e102cb206346c8ec6044fc12a32a0c.tar.gz bcm5719-llvm-6b776ad985e102cb206346c8ec6044fc12a32a0c.zip  | |
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.
llvm-svn: 296439
| -rw-r--r-- | lld/ELF/SyntheticSections.cpp | 49 | ||||
| -rw-r--r-- | lld/ELF/SyntheticSections.h | 8 | 
2 files changed, 31 insertions, 26 deletions
diff --git a/lld/ELF/SyntheticSections.cpp b/lld/ELF/SyntheticSections.cpp index 40a584d4f21..2e16d563226 100644 --- a/lld/ELF/SyntheticSections.cpp +++ b/lld/ELF/SyntheticSections.cpp @@ -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 GnuHashTableSection<ELFT>::finalizeContents() {    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>::writeBloomFilter(uint8_t *&Buf) {                  (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>::addSymbols(std::vector<SymbolTableEntry> &V) {  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 HashTableSection<ELFT>::finalizeContents() {    // 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 diff --git a/lld/ELF/SyntheticSections.h b/lld/ELF/SyntheticSections.h index 0aef47881f3..0174b619e5c 100644 --- a/lld/ELF/SyntheticSections.h +++ b/lld/ELF/SyntheticSections.h @@ -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;  | 

