[ELF][Writer] Add hash table.

llvm-svn: 175972
diff --git a/lld/lib/ReaderWriter/ELF/SectionChunks.h b/lld/lib/ReaderWriter/ELF/SectionChunks.h
index b5ca854..00dcbd1 100644
--- a/lld/lib/ReaderWriter/ELF/SectionChunks.h
+++ b/lld/lib/ReaderWriter/ELF/SectionChunks.h
@@ -836,6 +836,43 @@
 private:
   StringRef _interp;
 };
+
+template <class ELFT> class HashSection : public Section<ELFT> {
+  struct SymbolTableEntry {
+    StringRef _name;
+    uint32_t _index;
+  };
+
+public:
+  HashSection(const ELFTargetInfo &ti, StringRef name, int32_t order)
+      : Section<ELFT>(ti, name) {
+    this->setOrder(order);
+    this->_align2 = 4; // Alignment of Elf32_Word.
+    this->_type = SHT_HASH;
+    this->_flags = SHF_ALLOC;
+    // The size of nbucket and nchain.
+    this->_fsize = 8;
+    this->_msize = this->_fsize;
+  }
+
+  void addSymbol(StringRef name, uint32_t index) {
+    SymbolTableEntry ste;
+    ste._name = name;
+    ste._index = index;
+    _entries.push_back(ste);
+  }
+
+  virtual void write(ELFWriter *writer, llvm::FileOutputBuffer &buffer) {
+    uint8_t *chunkBuffer = buffer.getBufferStart();
+    uint8_t *dest = chunkBuffer + this->fileOffset();
+    // TODO: Calculate hashes and build the hash table in finalize. We currently
+    // just emit an empty hash table so the dynamic loader doesn't crash.
+    std::memset(dest, 0, this->_fsize);
+  }
+
+private:
+  std::vector<SymbolTableEntry> _entries;
+};
 } // end namespace elf
 } // end namespace lld
 
diff --git a/lld/lib/ReaderWriter/ELF/Writer.cpp b/lld/lib/ReaderWriter/ELF/Writer.cpp
index 5e2bb1e..13048b7 100644
--- a/lld/lib/ReaderWriter/ELF/Writer.cpp
+++ b/lld/lib/ReaderWriter/ELF/Writer.cpp
@@ -72,6 +72,7 @@
   LLD_UNIQUE_BUMP_PTR(DynamicSymbolTable<ELFT>) _dynamicSymbolTable;
   LLD_UNIQUE_BUMP_PTR(StringTable<ELFT>) _dynamicStringTable;
   LLD_UNIQUE_BUMP_PTR(InterpSection<ELFT>) _interpSection;
+  LLD_UNIQUE_BUMP_PTR(HashSection<ELFT>) _hashTable;
   /// @}
   CRuntimeFile<ELFT> _runtimeFile;
 };
@@ -348,10 +349,13 @@
     _interpSection.reset(new (_alloc) InterpSection<ELFT>(
         _targetInfo, ".interp", DefaultLayout<ELFT>::ORDER_INTERP,
         _targetInfo.getInterpreter()));
+    _hashTable.reset(new (_alloc) HashSection<ELFT>(
+        _targetInfo, ".hash", DefaultLayout<ELFT>::ORDER_HASH));
     _layout->addSection(_dynamicTable.get());
     _layout->addSection(_dynamicStringTable.get());
     _layout->addSection(_dynamicSymbolTable.get());
     _layout->addSection(_interpSection.get());
+    _layout->addSection(_hashTable.get());
     _dynamicSymbolTable->setStringSection(_dynamicStringTable.get());
   }