[PATCH] [lld][ELF][Writer] Add dynamic table.
Michael Spencer
bigcheesegs at gmail.com
Tue Feb 19 19:06:19 PST 2013
Hi shankarke,
This adds the dynamic table section and program header.
http://llvm-reviews.chandlerc.com/D427
Files:
include/lld/ReaderWriter/ELFTargetInfo.h
lib/ReaderWriter/ELF/HeaderChunks.h
lib/ReaderWriter/ELF/SectionChunks.h
lib/ReaderWriter/ELF/Writer.cpp
lib/ReaderWriter/ELF/X86_64/X86_64TargetHandler.cpp
test/elf/dynamic-table.test
Index: include/lld/ReaderWriter/ELFTargetInfo.h
===================================================================
--- include/lld/ReaderWriter/ELFTargetInfo.h
+++ include/lld/ReaderWriter/ELFTargetInfo.h
@@ -49,6 +49,12 @@
return false;
}
+ /// \brief Does the output have dynamic sections.
+ bool isDynamic() const {
+ return _options._outputKind == OutputKind::DynamicExecutable ||
+ _options._outputKind == OutputKind::Shared;
+ }
+
virtual ErrorOr<Reader &> getReader(const LinkerInput &input) const;
virtual ErrorOr<Writer &> getWriter() const;
Index: lib/ReaderWriter/ELF/HeaderChunks.h
===================================================================
--- lib/ReaderWriter/ELF/HeaderChunks.h
+++ lib/ReaderWriter/ELF/HeaderChunks.h
@@ -182,7 +182,8 @@
bool allocatedNew = false;
for (auto slice : segment->slices()) {
// If we have a TLS segment, emit a LOAD first.
- if (segment->segmentType() == llvm::ELF::PT_TLS) {
+ if (segment->segmentType() == llvm::ELF::PT_TLS ||
+ segment->segmentType() == llvm::ELF::PT_DYNAMIC) {
auto phdr = allocateProgramHeader();
if (phdr.second)
allocatedNew = true;
@@ -193,7 +194,7 @@
phdr.first->p_filesz = slice->fileSize();
phdr.first->p_memsz = slice->memSize();
phdr.first->p_flags = segment->flags();
- phdr.first->p_align = slice->align2();
+ phdr.first->p_align = segment->pageSize();
}
auto phdr = allocateProgramHeader();
if (phdr.second)
Index: lib/ReaderWriter/ELF/SectionChunks.h
===================================================================
--- lib/ReaderWriter/ELF/SectionChunks.h
+++ lib/ReaderWriter/ELF/SectionChunks.h
@@ -716,6 +716,48 @@
private:
std::vector<std::pair<const DefinedAtom *, const Reference *>> _relocs;
};
+
+template <class ELFT> class DynamicTable : public Section<ELFT> {
+ typedef llvm::object::Elf_Dyn_Impl<ELFT> Elf_Dyn;
+ typedef std::vector<Elf_Dyn> EntriesT;
+
+public:
+ DynamicTable(const ELFTargetInfo &ti, StringRef str, int32_t order)
+ : Section<ELFT>(ti, str) {
+ this->setOrder(order);
+ this->_entSize = sizeof(Elf_Dyn);
+ this->_align2 = llvm::alignOf<Elf_Dyn>();
+ // Reserve space for the DT_NULL entry.
+ this->_fsize = sizeof(Elf_Dyn);
+ this->_msize = sizeof(Elf_Dyn);
+ this->_type = SHT_DYNAMIC;
+ this->_flags = SHF_ALLOC;
+ }
+
+ range<typename EntriesT::iterator> entries() { return _entries; }
+
+ /// \returns the index of the entry.
+ std::size_t addEntry(Elf_Dyn e) {
+ _entries.push_back(e);
+ this->_fsize = (_entries.size() * sizeof(Elf_Dyn)) + sizeof(Elf_Dyn);
+ this->_msize = this->_fsize;
+ return _entries.size() - 1;
+ }
+
+ void write(ELFWriter *writer, llvm::FileOutputBuffer &buffer) {
+ uint8_t *chunkBuffer = buffer.getBufferStart();
+ uint8_t *dest = chunkBuffer + this->fileOffset();
+ // Add the null entry.
+ Elf_Dyn d;
+ d.d_tag = 0;
+ d.d_un.d_val = 0;
+ _entries.push_back(d);
+ std::memcpy(dest, _entries.data(), this->_fsize);
+ }
+
+private:
+ EntriesT _entries;
+};
} // end namespace elf
} // end namespace lld
Index: lib/ReaderWriter/ELF/Writer.cpp
===================================================================
--- lib/ReaderWriter/ELF/Writer.cpp
+++ lib/ReaderWriter/ELF/Writer.cpp
@@ -66,6 +66,10 @@
LLD_UNIQUE_BUMP_PTR(StringTable<ELFT>) _strtab;
LLD_UNIQUE_BUMP_PTR(StringTable<ELFT>) _shstrtab;
LLD_UNIQUE_BUMP_PTR(SectionHeader<ELFT>) _shdrtab;
+ /// \name Dynamic sections.
+ /// @{
+ LLD_UNIQUE_BUMP_PTR(DynamicTable<ELFT>) _dynamicTable;
+ /// @}
CRuntimeFile<ELFT> _runtimeFile;
};
@@ -330,6 +334,12 @@
_symtab->setStringSection(_strtab.get());
_layout->addSection(_shdrtab.get());
+ if (_targetInfo.isDynamic()) {
+ _dynamicTable.reset(new (_alloc) DynamicTable<ELFT>(
+ _targetInfo, ".dynamic", DefaultLayout<ELFT>::ORDER_DYNAMIC));
+ _layout->addSection(_dynamicTable.get());
+ }
+
// give a chance for the target to add sections
_targetHandler.createDefaultSections();
}
Index: lib/ReaderWriter/ELF/X86_64/X86_64TargetHandler.cpp
===================================================================
--- lib/ReaderWriter/ELF/X86_64/X86_64TargetHandler.cpp
+++ lib/ReaderWriter/ELF/X86_64/X86_64TargetHandler.cpp
@@ -97,6 +97,7 @@
break;
}
// Runtime only relocations. Ignore here.
+ case R_X86_64_RELATIVE:
case R_X86_64_IRELATIVE:
break;
Index: test/elf/dynamic-table.test
===================================================================
--- /dev/null
+++ test/elf/dynamic-table.test
@@ -0,0 +1,9 @@
+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: Dynamic section contains 1 entries
+CHECK: Tag Type Name/Value
+CHECK: 0x0000000000000000 (NULL) 0x0
+CHECK: Total: 1
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D427.1.patch
Type: text/x-patch
Size: 5025 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20130219/658bba88/attachment.bin>
More information about the llvm-commits
mailing list