diff options
-rw-r--r-- | lld/lib/ReaderWriter/ELF/SectionChunks.h | 37 | ||||
-rw-r--r-- | lld/lib/ReaderWriter/ELF/Writer.cpp | 4 | ||||
-rw-r--r-- | lld/test/elf/dynamic-hash.test | 7 |
3 files changed, 48 insertions, 0 deletions
diff --git a/lld/lib/ReaderWriter/ELF/SectionChunks.h b/lld/lib/ReaderWriter/ELF/SectionChunks.h index b5ca8541097..00dcbd19519 100644 --- a/lld/lib/ReaderWriter/ELF/SectionChunks.h +++ b/lld/lib/ReaderWriter/ELF/SectionChunks.h @@ -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 diff --git a/lld/lib/ReaderWriter/ELF/Writer.cpp b/lld/lib/ReaderWriter/ELF/Writer.cpp index 5e2bb1edbfc..13048b71fe4 100644 --- a/lld/lib/ReaderWriter/ELF/Writer.cpp +++ b/lld/lib/ReaderWriter/ELF/Writer.cpp @@ -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 index 00000000000..094d0bb2590 --- /dev/null +++ b/lld/test/elf/dynamic-hash.test @@ -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 |