[ELF][Writer] Add hash table.
authorMichael J. Spencer <bigcheesegs@gmail.com>
Sat, 23 Feb 2013 19:46:18 +0000 (19:46 +0000)
committerMichael J. Spencer <bigcheesegs@gmail.com>
Sat, 23 Feb 2013 19:46:18 +0000 (19:46 +0000)
llvm-svn: 175972

lld/lib/ReaderWriter/ELF/SectionChunks.h
lld/lib/ReaderWriter/ELF/Writer.cpp
lld/test/elf/dynamic-hash.test [new file with mode: 0644]

index b5ca854..00dcbd1 100644 (file)
@@ -836,6 +836,43 @@ public:
 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
 
index 5e2bb1e..13048b7 100644 (file)
@@ -72,6 +72,7 @@ private:
   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 @@ void ExecutableWriter<ELFT>::createDefaultSections() {
     _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());
   }
 
diff --git a/lld/test/elf/dynamic-hash.test b/lld/test/elf/dynamic-hash.test
new file mode 100644 (file)
index 0000000..094d0bb
--- /dev/null
@@ -0,0 +1,7 @@
+RUN: lld -core -target x86_64-linux %p/Inputs/use-shared.x86-64 \
+RUN:   %p/Inputs/shared.so-x86-64 -output=%t -entry=main \
+RUN:   -output-type=dynamic
+RUN: llvm-readobj %t | FileCheck %s
+
+CHECK: Sections:
+CHECK:   .hash {{[0-9a-f]+}} 8 4 required,rodata