summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--lld/lib/ReaderWriter/ELF/Writer.cpp55
-rw-r--r--lld/test/elf/dynamic-table.test10
2 files changed, 62 insertions, 3 deletions
diff --git a/lld/lib/ReaderWriter/ELF/Writer.cpp b/lld/lib/ReaderWriter/ELF/Writer.cpp
index 1b9fcc862d1..2412515ad43 100644
--- a/lld/lib/ReaderWriter/ELF/Writer.cpp
+++ b/lld/lib/ReaderWriter/ELF/Writer.cpp
@@ -15,6 +15,8 @@
#include "lld/ReaderWriter/ELFTargetInfo.h"
+#include "llvm/ADT/StringSet.h"
+
using namespace llvm;
using namespace llvm::object;
namespace lld {
@@ -30,6 +32,7 @@ class ExecutableWriter : public ELFWriter {
public:
typedef Elf_Shdr_Impl<ELFT> Elf_Shdr;
typedef Elf_Sym_Impl<ELFT> Elf_Sym;
+ typedef Elf_Dyn_Impl<ELFT> Elf_Dyn;
ExecutableWriter(const ELFTargetInfo &ti);
@@ -52,6 +55,31 @@ private:
void createDefaultSections();
+ void createDefaultDynamicEntries() {
+ Elf_Dyn dyn;
+ dyn.d_un.d_val = 0;
+
+ dyn.d_tag = DT_HASH;
+ _dt_hash = _dynamicTable->addEntry(dyn);
+ dyn.d_tag = DT_STRTAB;
+ _dt_strtab = _dynamicTable->addEntry(dyn);
+ dyn.d_tag = DT_SYMTAB;
+ _dt_symtab = _dynamicTable->addEntry(dyn);
+ dyn.d_tag = DT_STRSZ;
+ _dt_strsz = _dynamicTable->addEntry(dyn);
+ dyn.d_tag = DT_SYMENT;
+ _dt_syment = _dynamicTable->addEntry(dyn);
+ }
+
+ void updateDynamicTable() {
+ auto tbl = _dynamicTable->entries();
+ tbl[_dt_hash].d_un.d_val = _hashTable->virtualAddr();
+ tbl[_dt_strtab].d_un.d_val = _dynamicStringTable->virtualAddr();
+ tbl[_dt_symtab].d_un.d_val = _dynamicSymbolTable->virtualAddr();
+ tbl[_dt_strsz].d_un.d_val = _dynamicStringTable->memSize();
+ tbl[_dt_syment].d_un.d_val = _dynamicSymbolTable->getEntSize();
+ }
+
llvm::BumpPtrAllocator _alloc;
const ELFTargetInfo &_targetInfo;
@@ -73,6 +101,19 @@ private:
LLD_UNIQUE_BUMP_PTR(StringTable<ELFT>) _dynamicStringTable;
LLD_UNIQUE_BUMP_PTR(InterpSection<ELFT>) _interpSection;
LLD_UNIQUE_BUMP_PTR(HashSection<ELFT>) _hashTable;
+ llvm::StringSet<> _soNeeded;
+ std::size_t _dt_hash;
+ std::size_t _dt_strtab;
+ std::size_t _dt_symtab;
+ std::size_t _dt_rela;
+ std::size_t _dt_relasz;
+ std::size_t _dt_relaent;
+ std::size_t _dt_strsz;
+ std::size_t _dt_syment;
+ std::size_t _dt_pltrelsz;
+ std::size_t _dt_pltgot;
+ std::size_t _dt_pltrel;
+ std::size_t _dt_jmprel;
/// @}
CRuntimeFile<ELFT> _runtimeFile;
};
@@ -112,6 +153,13 @@ template <class ELFT>
void ExecutableWriter<ELFT>::buildDynamicSymbolTable(const File &file) {
for (const auto sla : file.sharedLibrary()) {
_dynamicSymbolTable->addSymbol(sla, ELF::SHN_UNDEF);
+ _soNeeded.insert(sla->loadName());
+ }
+ for (const auto &loadName : _soNeeded) {
+ Elf_Dyn dyn;
+ dyn.d_tag = DT_NEEDED;
+ dyn.d_un.d_val = _dynamicStringTable->addString(loadName.getKey());
+ _dynamicTable->addEntry(dyn);
}
}
@@ -246,8 +294,10 @@ error_code ExecutableWriter<ELFT>::writeFile(const File &file, StringRef path) {
// section string table
createDefaultSections();
- if (_targetInfo.isDynamic())
+ if (_targetInfo.isDynamic()) {
+ createDefaultDynamicEntries();
buildDynamicSymbolTable(file);
+ }
// Set the Layout
_layout->assignSectionsToSegments();
@@ -273,6 +323,9 @@ error_code ExecutableWriter<ELFT>::writeFile(const File &file, StringRef path) {
// for sections with no segments
assignSectionsWithNoSegments();
+ if (_targetInfo.isDynamic())
+ updateDynamicTable();
+
uint64_t totalSize = _shdrtab->fileOffset() + _shdrtab->fileSize();
OwningPtr<FileOutputBuffer> buffer;
diff --git a/lld/test/elf/dynamic-table.test b/lld/test/elf/dynamic-table.test
index ca47724161c..14965c93da9 100644
--- a/lld/test/elf/dynamic-table.test
+++ b/lld/test/elf/dynamic-table.test
@@ -3,7 +3,13 @@ RUN: %p/Inputs/shared.so-x86-64 -output=%t -entry=main \
RUN: -output-type=dynamic
RUN: llvm-readobj %t | FileCheck %s
-CHECK: Dynamic section contains 1 entries
+CHECK: Dynamic section contains 7 entries
CHECK: Tag Type Name/Value
+CHECK: 0x0000000000000004 (HASH)
+CHECK: 0x0000000000000005 (STRTAB)
+CHECK: 0x0000000000000006 (SYMTAB)
+CHECK: 0x000000000000000a (STRSZ)
+CHECK: 0x000000000000000b (SYMENT) 24
+CHECK: 0x0000000000000001 (NEEDED) Shared library: [shared.so-x86-64]
CHECK: 0x0000000000000000 (NULL) 0x0
-CHECK: Total: 1
+CHECK: Total: 7
OpenPOWER on IntegriCloud