[lld] r176724 - [ELF] Create baseclass for all ELF writers
Shankar Easwaran
shankare at codeaurora.org
Fri Mar 8 13:42:52 PST 2013
Author: shankare
Date: Fri Mar 8 15:42:51 2013
New Revision: 176724
URL: http://llvm.org/viewvc/llvm-project?rev=176724&view=rev
Log:
[ELF] Create baseclass for all ELF writers
Added:
lld/trunk/lib/ReaderWriter/ELF/OutputELFWriter.h
Modified:
lld/trunk/lib/ReaderWriter/ELF/DynamicLibraryWriter.h
lld/trunk/lib/ReaderWriter/ELF/ExecutableWriter.h
Modified: lld/trunk/lib/ReaderWriter/ELF/DynamicLibraryWriter.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/DynamicLibraryWriter.h?rev=176724&r1=176723&r2=176724&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/DynamicLibraryWriter.h (original)
+++ lld/trunk/lib/ReaderWriter/ELF/DynamicLibraryWriter.h Fri Mar 8 15:42:51 2013
@@ -9,15 +9,7 @@
#ifndef LLD_READER_WRITER_ELF_DYNAMIC_LIBRARY_WRITER_H
#define LLD_READER_WRITER_ELF_DYNAMIC_LIBRARY_WRITER_H
-#include "lld/ReaderWriter/Writer.h"
-
-#include "DefaultLayout.h"
-#include "TargetLayout.h"
-#include "ExecutableAtoms.h"
-
-#include "lld/ReaderWriter/ELFTargetInfo.h"
-
-#include "llvm/ADT/StringSet.h"
+#include "OutputELFWriter.h"
namespace lld {
namespace elf {
@@ -31,326 +23,53 @@ class DynamicLibraryWriter;
// DynamicLibraryWriter Class
//===----------------------------------------------------------------------===//
template<class ELFT>
-class DynamicLibraryWriter : public ELFWriter {
+class DynamicLibraryWriter : public OutputELFWriter<ELFT> {
public:
- typedef Elf_Shdr_Impl<ELFT> Elf_Shdr;
- typedef Elf_Sym_Impl<ELFT> Elf_Sym;
- typedef Elf_Dyn_Impl<ELFT> Elf_Dyn;
-
- DynamicLibraryWriter(const ELFTargetInfo &ti);
+ DynamicLibraryWriter(const ELFTargetInfo &ti):OutputELFWriter<ELFT>(ti)
+ {}
private:
- // build the sections that need to be created
- void buildChunks(const File &file);
- virtual error_code writeFile(const File &File, StringRef path);
- void buildAtomToAddressMap();
- void buildStaticSymbolTable(const File &file);
void buildDynamicSymbolTable(const File &file);
- void buildSectionHeaderTable();
- void assignSectionsWithNoSegments();
void addDefaultAtoms();
void addFiles(InputFiles&);
void finalizeDefaultAtomValues();
- uint64_t addressOfAtom(const Atom *atom) {
- return _atomToAddressMap[atom];
- }
-
- void createDefaultSections();
-
- void createDefaultDynamicEntries() {}
-
llvm::BumpPtrAllocator _alloc;
-
- const ELFTargetInfo &_targetInfo;
- TargetHandler<ELFT> &_targetHandler;
-
- typedef llvm::DenseMap<const Atom *, uint64_t> AtomToAddress;
- AtomToAddress _atomToAddressMap;
- TargetLayout<ELFT> *_layout;
- LLD_UNIQUE_BUMP_PTR(Header<ELFT>) _Header;
- LLD_UNIQUE_BUMP_PTR(ProgramHeader<ELFT>) _programHeader;
- LLD_UNIQUE_BUMP_PTR(SymbolTable<ELFT>) _symtab;
- 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;
- 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;
- llvm::StringSet<> _soNeeded;
- /// @}
- CRuntimeFile<ELFT> _runtimeFile;
};
//===----------------------------------------------------------------------===//
// DynamicLibraryWriter
//===----------------------------------------------------------------------===//
template <class ELFT>
-DynamicLibraryWriter<ELFT>::DynamicLibraryWriter(const ELFTargetInfo &ti)
- : _targetInfo(ti), _targetHandler(ti.getTargetHandler<ELFT>()),
- _runtimeFile(ti) {
- _layout = &_targetHandler.targetLayout();
-}
-
-template <class ELFT>
-void DynamicLibraryWriter<ELFT>::buildChunks(const File &file) {
- for (const DefinedAtom *definedAtom : file.defined()) {
- _layout->addAtom(definedAtom);
- }
- for (const AbsoluteAtom *absoluteAtom : file.absolute())
- _layout->addAtom(absoluteAtom);
-}
-
-template <class ELFT>
-void DynamicLibraryWriter<ELFT>::buildStaticSymbolTable(const File &file) {
- for (auto sec : _layout->sections())
- if (auto section = dyn_cast<AtomSection<ELFT>>(sec))
- for (const auto &atom : section->atoms())
- _symtab->addSymbol(atom->_atom, section->ordinal(), atom->_virtualAddr);
- for (auto &atom : _layout->absoluteAtoms())
- _symtab->addSymbol(atom->_atom, ELF::SHN_ABS, atom->_virtualAddr);
- for (const UndefinedAtom *a : file.undefined())
- _symtab->addSymbol(a, ELF::SHN_UNDEF);
-}
-
-template <class ELFT>
void DynamicLibraryWriter<ELFT>::buildDynamicSymbolTable(const File &file) {
- for (const auto sla : file.sharedLibrary()) {
- _dynamicSymbolTable->addSymbol(sla, ELF::SHN_UNDEF);
- _soNeeded.insert(sla->loadName());
- }
// Add all the defined symbols to the dynamic symbol table
// we need hooks into the Atom to find out which atoms need
// to be exported
- for (auto sec : _layout->sections())
+ for (auto sec : this->_layout->sections())
if (auto section = dyn_cast<AtomSection<ELFT>>(sec))
for (const auto &atom : section->atoms()) {
const DefinedAtom *da = dyn_cast<const DefinedAtom>(atom->_atom);
if (da && (da->scope() != DefinedAtom::scopeTranslationUnit))
- _dynamicSymbolTable->addSymbol(atom->_atom, section->ordinal(),
- atom->_virtualAddr, atom);
+ this->_dynamicSymbolTable->addSymbol(atom->_atom, section->ordinal(),
+ atom->_virtualAddr, atom);
}
- 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);
- }
-}
-template <class ELFT> void DynamicLibraryWriter<ELFT>::buildAtomToAddressMap() {
- for (auto sec : _layout->sections())
- if (auto section = dyn_cast<AtomSection<ELFT>>(sec))
- for (const auto &atom : section->atoms())
- _atomToAddressMap[atom->_atom] = atom->_virtualAddr;
- // build the atomToAddressMap that contains absolute symbols too
- for (auto &atom : _layout->absoluteAtoms())
- _atomToAddressMap[atom->_atom] = atom->_virtualAddr;
+ OutputELFWriter<ELFT>::buildDynamicSymbolTable(file);
}
template<class ELFT>
-void DynamicLibraryWriter<ELFT>::buildSectionHeaderTable() {
- for (auto mergedSec : _layout->mergedSections()) {
- if (mergedSec->kind() != Chunk<ELFT>::K_ELFSection &&
- mergedSec->kind() != Chunk<ELFT>::K_AtomSection)
- continue;
- if (mergedSec->hasSegment())
- _shdrtab->appendSection(mergedSec);
- }
-}
-
-template<class ELFT>
-void DynamicLibraryWriter<ELFT>::assignSectionsWithNoSegments() {
- for (auto mergedSec : _layout->mergedSections()) {
- if (mergedSec->kind() != Chunk<ELFT>::K_ELFSection &&
- mergedSec->kind() != Chunk<ELFT>::K_AtomSection)
- continue;
- if (!mergedSec->hasSegment())
- _shdrtab->appendSection(mergedSec);
- }
- _layout->assignOffsetsForMiscSections();
- for (auto sec : _layout->sections())
- if (auto section = dyn_cast<Section<ELFT>>(sec))
- if (!DefaultLayout<ELFT>::hasOutputSegment(section))
- _shdrtab->updateSection(section);
-}
-
-/// \brief Add absolute symbols by default. These are linker added
-/// absolute symbols
-template<class ELFT>
-void DynamicLibraryWriter<ELFT>::addDefaultAtoms() {
- _runtimeFile.addAbsoluteAtom("__bss_start");
-}
+void DynamicLibraryWriter<ELFT>::addDefaultAtoms() { }
-/// \brief Hook in lld to add CRuntime file
template <class ELFT>
void DynamicLibraryWriter<ELFT>::addFiles(InputFiles &inputFiles) {
- addDefaultAtoms();
- inputFiles.prependFile(_runtimeFile);
- // Give a chance for the target to add atoms
- _targetHandler.addFiles(inputFiles);
+ this->_targetHandler.addFiles(inputFiles);
}
-/// Finalize the value of all the absolute symbols that we
-/// created
template<class ELFT>
void DynamicLibraryWriter<ELFT>::finalizeDefaultAtomValues() {
- auto bssStartAtomIter = _layout->findAbsoluteAtom("__bss_start");
-
- assert(!(bssStartAtomIter == _layout->absoluteAtoms().end()) &&
- "Unable to find the absolute atoms that have been added by lld");
-
- auto phe = _programHeader->findProgramHeader(
- llvm::ELF::PT_LOAD, llvm::ELF::PF_W, llvm::ELF::PF_X);
-
- (*bssStartAtomIter)->_virtualAddr = (*phe)->p_vaddr + (*phe)->p_filesz;
-
- // Give a chance for the target to finalize its atom values
- _targetHandler.finalizeSymbolValues();
-}
-
-template <class ELFT>
-error_code DynamicLibraryWriter<ELFT>::writeFile(const File &file, StringRef path) {
- buildChunks(file);
-
- // Call the preFlight callbacks to modify the sections and the atoms
- // contained in them, in anyway the targets may want
- _layout->doPreFlight();
-
- // Create the default sections like the symbol table, string table, and the
- // section string table
- createDefaultSections();
-
- _dynamicTable->createDefaultEntries();
- buildDynamicSymbolTable(file);
-
- // Set the Layout
- _layout->assignSectionsToSegments();
- _layout->assignFileOffsets();
- _layout->assignVirtualAddress();
-
- // Finalize the default value of symbols that the linker adds
- finalizeDefaultAtomValues();
-
- // Build the Atom To Address map for applying relocations
- buildAtomToAddressMap();
-
- // Create symbol table and section string table
- buildStaticSymbolTable(file);
-
- // Finalize the layout by calling the finalize() functions
- _layout->finalize();
-
- // build Section Header table
- buildSectionHeaderTable();
-
- // assign Offsets and virtual addresses
- // for sections with no segments
- assignSectionsWithNoSegments();
-
- _dynamicTable->updateDynamicTable(_hashTable.get(),
- _dynamicSymbolTable.get());
-
- uint64_t totalSize = _shdrtab->fileOffset() + _shdrtab->fileSize();
-
- OwningPtr<FileOutputBuffer> buffer;
- error_code ec = FileOutputBuffer::create(path,
- totalSize, buffer,
- FileOutputBuffer::F_executable);
- if (ec)
- return ec;
-
- _Header->e_ident(ELF::EI_CLASS, _targetInfo.is64Bits() ? ELF::ELFCLASS64 :
- ELF::ELFCLASS32);
- _Header->e_ident(ELF::EI_DATA, _targetInfo.isLittleEndian() ?
- ELF::ELFDATA2LSB : ELF::ELFDATA2MSB);
- _Header->e_type(_targetInfo.getOutputType());
- _Header->e_machine(_targetInfo.getOutputMachine());
-
- if (!_targetHandler.doesOverrideHeader()) {
- _Header->e_ident(ELF::EI_VERSION, 1);
- _Header->e_ident(ELF::EI_OSABI, 0);
- _Header->e_version(1);
- } else {
- // override the contents of the ELF Header
- _targetHandler.setHeaderInfo(_Header.get());
- }
- _Header->e_phoff(_programHeader->fileOffset());
- _Header->e_shoff(_shdrtab->fileOffset());
- _Header->e_phentsize(_programHeader->entsize());
- _Header->e_phnum(_programHeader->numHeaders());
- _Header->e_shentsize(_shdrtab->entsize());
- _Header->e_shnum(_shdrtab->numHeaders());
- _Header->e_shstrndx(_shstrtab->ordinal());
- uint64_t virtualAddr = 0;
- _layout->findAtomAddrByName(_targetInfo.getEntry(), virtualAddr);
-
- // HACK: We have to write out the header and program header here even though
- // they are a member of a segment because only sections are written in the
- // following loop.
- _Header->write(this, *buffer);
- _programHeader->write(this, *buffer);
-
- for (auto section : _layout->sections())
- section->write(this, *buffer);
-
- return buffer->commit();
+ this->_targetHandler.finalizeSymbolValues();
}
-template<class ELFT>
-void DynamicLibraryWriter<ELFT>::createDefaultSections() {
- _Header.reset(new (_alloc) Header<ELFT>(_targetInfo));
- _programHeader.reset(new (_alloc) ProgramHeader<ELFT>(_targetInfo));
- _layout->setHeader(_Header.get());
- _layout->setProgramHeader(_programHeader.get());
-
- _symtab.reset(new (_alloc) SymbolTable<ELFT>(
- _targetInfo, ".symtab", DefaultLayout<ELFT>::ORDER_SYMBOL_TABLE));
- _strtab.reset(new (_alloc) StringTable<ELFT>(
- _targetInfo, ".strtab", DefaultLayout<ELFT>::ORDER_STRING_TABLE));
- _shstrtab.reset(new (_alloc) StringTable<ELFT>(
- _targetInfo, ".shstrtab", DefaultLayout<ELFT>::ORDER_SECTION_STRINGS));
- _shdrtab.reset(new (_alloc) SectionHeader<ELFT>(
- _targetInfo, DefaultLayout<ELFT>::ORDER_SECTION_HEADERS));
- _layout->addSection(_symtab.get());
- _layout->addSection(_strtab.get());
- _layout->addSection(_shstrtab.get());
- _shdrtab->setStringSection(_shstrtab.get());
- _symtab->setStringSection(_strtab.get());
- _layout->addSection(_shdrtab.get());
-
- _dynamicTable.reset(new (_alloc) DynamicTable<ELFT>(
- _targetInfo, ".dynamic", DefaultLayout<ELFT>::ORDER_DYNAMIC));
- _dynamicStringTable.reset(new (_alloc) StringTable<ELFT>(
- _targetInfo, ".dynstr", DefaultLayout<ELFT>::ORDER_DYNAMIC_STRINGS,
- true));
- _dynamicSymbolTable.reset(new (_alloc) DynamicSymbolTable<ELFT>(
- _targetInfo, ".dynsym", DefaultLayout<ELFT>::ORDER_DYNAMIC_SYMBOLS));
- _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());
- if (_layout->hasDynamicRelocationTable())
- _layout->getDynamicRelocationTable()->setSymbolTable(
- _dynamicSymbolTable.get());
- if (_layout->hasPLTRelocationTable())
- _layout->getPLTRelocationTable()->setSymbolTable(
- _dynamicSymbolTable.get());
-
- // give a chance for the target to add sections
- _targetHandler.createDefaultSections();
-}
} // namespace elf
} // namespace lld
Modified: lld/trunk/lib/ReaderWriter/ELF/ExecutableWriter.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/ExecutableWriter.h?rev=176724&r1=176723&r2=176724&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/ExecutableWriter.h (original)
+++ lld/trunk/lib/ReaderWriter/ELF/ExecutableWriter.h Fri Mar 8 15:42:51 2013
@@ -9,15 +9,7 @@
#ifndef LLD_READER_WRITER_ELF_EXECUTABLE_WRITER_H
#define LLD_READER_WRITER_ELF_EXECUTABLE_WRITER_H
-#include "lld/ReaderWriter/Writer.h"
-
-#include "DefaultLayout.h"
-#include "TargetLayout.h"
-#include "ExecutableAtoms.h"
-
-#include "lld/ReaderWriter/ELFTargetInfo.h"
-
-#include "llvm/ADT/StringSet.h"
+#include "OutputELFWriter.h"
namespace lld {
namespace elf {
@@ -31,148 +23,29 @@ class ExecutableWriter;
// ExecutableWriter Class
//===----------------------------------------------------------------------===//
template<class ELFT>
-class ExecutableWriter : public ELFWriter {
+class ExecutableWriter : public OutputELFWriter<ELFT> {
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);
+ ExecutableWriter(const ELFTargetInfo &ti)
+ : OutputELFWriter<ELFT>(ti), _runtimeFile(ti)
+ {}
private:
- // build the sections that need to be created
- void buildChunks(const File &file);
- virtual error_code writeFile(const File &File, StringRef path);
- void buildAtomToAddressMap();
- void buildStaticSymbolTable(const File &file);
- void buildDynamicSymbolTable(const File &file);
- void buildSectionHeaderTable();
- void assignSectionsWithNoSegments();
- void addDefaultAtoms();
- void addFiles(InputFiles&);
- void finalizeDefaultAtomValues();
-
- uint64_t addressOfAtom(const Atom *atom) {
- return _atomToAddressMap[atom];
- }
-
- void createDefaultSections();
-
- void createDefaultDynamicEntries() {}
-
- llvm::BumpPtrAllocator _alloc;
-
- const ELFTargetInfo &_targetInfo;
- TargetHandler<ELFT> &_targetHandler;
-
- typedef llvm::DenseMap<const Atom *, uint64_t> AtomToAddress;
- AtomToAddress _atomToAddressMap;
- TargetLayout<ELFT> *_layout;
- LLD_UNIQUE_BUMP_PTR(Header<ELFT>) _Header;
- LLD_UNIQUE_BUMP_PTR(ProgramHeader<ELFT>) _programHeader;
- LLD_UNIQUE_BUMP_PTR(SymbolTable<ELFT>) _symtab;
- 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;
- 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;
- llvm::StringSet<> _soNeeded;
- /// @}
+ virtual void addDefaultAtoms();
+ virtual void addFiles(InputFiles&);
+ virtual void finalizeDefaultAtomValues();
+
CRuntimeFile<ELFT> _runtimeFile;
};
//===----------------------------------------------------------------------===//
// ExecutableWriter
//===----------------------------------------------------------------------===//
-template <class ELFT>
-ExecutableWriter<ELFT>::ExecutableWriter(const ELFTargetInfo &ti)
- : _targetInfo(ti), _targetHandler(ti.getTargetHandler<ELFT>()),
- _runtimeFile(ti) {
- _layout = &_targetHandler.targetLayout();
-}
-
-template <class ELFT>
-void ExecutableWriter<ELFT>::buildChunks(const File &file) {
- for (const DefinedAtom *definedAtom : file.defined()) {
- _layout->addAtom(definedAtom);
- }
- for (const AbsoluteAtom *absoluteAtom : file.absolute())
- _layout->addAtom(absoluteAtom);
-}
-
-template <class ELFT>
-void ExecutableWriter<ELFT>::buildStaticSymbolTable(const File &file) {
- for (auto sec : _layout->sections())
- if (auto section = dyn_cast<AtomSection<ELFT>>(sec))
- for (const auto &atom : section->atoms())
- _symtab->addSymbol(atom->_atom, section->ordinal(), atom->_virtualAddr);
- for (auto &atom : _layout->absoluteAtoms())
- _symtab->addSymbol(atom->_atom, ELF::SHN_ABS, atom->_virtualAddr);
- for (const UndefinedAtom *a : file.undefined())
- _symtab->addSymbol(a, ELF::SHN_UNDEF);
-}
-
-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);
- }
-}
-
-template <class ELFT> void ExecutableWriter<ELFT>::buildAtomToAddressMap() {
- for (auto sec : _layout->sections())
- if (auto section = dyn_cast<AtomSection<ELFT>>(sec))
- for (const auto &atom : section->atoms())
- _atomToAddressMap[atom->_atom] = atom->_virtualAddr;
- // build the atomToAddressMap that contains absolute symbols too
- for (auto &atom : _layout->absoluteAtoms())
- _atomToAddressMap[atom->_atom] = atom->_virtualAddr;
-}
-
-template<class ELFT>
-void ExecutableWriter<ELFT>::buildSectionHeaderTable() {
- for (auto mergedSec : _layout->mergedSections()) {
- if (mergedSec->kind() != Chunk<ELFT>::K_ELFSection &&
- mergedSec->kind() != Chunk<ELFT>::K_AtomSection)
- continue;
- if (mergedSec->hasSegment())
- _shdrtab->appendSection(mergedSec);
- }
-}
-
-template<class ELFT>
-void ExecutableWriter<ELFT>::assignSectionsWithNoSegments() {
- for (auto mergedSec : _layout->mergedSections()) {
- if (mergedSec->kind() != Chunk<ELFT>::K_ELFSection &&
- mergedSec->kind() != Chunk<ELFT>::K_AtomSection)
- continue;
- if (!mergedSec->hasSegment())
- _shdrtab->appendSection(mergedSec);
- }
- _layout->assignOffsetsForMiscSections();
- for (auto sec : _layout->sections())
- if (auto section = dyn_cast<Section<ELFT>>(sec))
- if (!DefaultLayout<ELFT>::hasOutputSegment(section))
- _shdrtab->updateSection(section);
-}
/// \brief Add absolute symbols by default. These are linker added
/// absolute symbols
template<class ELFT>
void ExecutableWriter<ELFT>::addDefaultAtoms() {
- _runtimeFile.addUndefinedAtom(_targetInfo.getEntry());
+ _runtimeFile.addUndefinedAtom(this->_targetInfo.getEntry());
_runtimeFile.addAbsoluteAtom("__bss_start");
_runtimeFile.addAbsoluteAtom("__bss_end");
_runtimeFile.addAbsoluteAtom("_end");
@@ -193,17 +66,17 @@ void ExecutableWriter<ELFT>::addFiles(In
addDefaultAtoms();
inputFiles.prependFile(_runtimeFile);
// Give a chance for the target to add atoms
- _targetHandler.addFiles(inputFiles);
+ this->_targetHandler.addFiles(inputFiles);
}
/// Finalize the value of all the absolute symbols that we
/// created
template<class ELFT>
void ExecutableWriter<ELFT>::finalizeDefaultAtomValues() {
- auto bssStartAtomIter = _layout->findAbsoluteAtom("__bss_start");
- auto bssEndAtomIter = _layout->findAbsoluteAtom("__bss_end");
- auto underScoreEndAtomIter = _layout->findAbsoluteAtom("_end");
- auto endAtomIter = _layout->findAbsoluteAtom("end");
+ auto bssStartAtomIter = this->_layout->findAbsoluteAtom("__bss_start");
+ auto bssEndAtomIter = this->_layout->findAbsoluteAtom("__bss_end");
+ auto underScoreEndAtomIter = this->_layout->findAbsoluteAtom("_end");
+ auto endAtomIter = this->_layout->findAbsoluteAtom("end");
auto startEnd = [&](StringRef sym, StringRef sec) -> void {
// TODO: This looks like a good place to use Twine...
@@ -212,9 +85,9 @@ void ExecutableWriter<ELFT>::finalizeDef
start += "_start";
end += sym;
end += "_end";
- auto s = _layout->findAbsoluteAtom(start);
- auto e = _layout->findAbsoluteAtom(end);
- auto section = _layout->findOutputSection(sec);
+ auto s = this->_layout->findAbsoluteAtom(start);
+ auto e = this->_layout->findAbsoluteAtom(end);
+ auto section = this->_layout->findOutputSection(sec);
if (section) {
(*s)->_virtualAddr = section->virtualAddr();
(*e)->_virtualAddr = section->virtualAddr() + section->memSize();
@@ -229,16 +102,16 @@ void ExecutableWriter<ELFT>::finalizeDef
startEnd("rela_iplt", ".rela.plt");
startEnd("fini_array", ".fini_array");
- assert(!(bssStartAtomIter == _layout->absoluteAtoms().end() ||
- bssEndAtomIter == _layout->absoluteAtoms().end() ||
- underScoreEndAtomIter == _layout->absoluteAtoms().end() ||
- endAtomIter == _layout->absoluteAtoms().end()) &&
+ assert(!(bssStartAtomIter == this->_layout->absoluteAtoms().end() ||
+ bssEndAtomIter == this->_layout->absoluteAtoms().end() ||
+ underScoreEndAtomIter == this->_layout->absoluteAtoms().end() ||
+ endAtomIter == this->_layout->absoluteAtoms().end()) &&
"Unable to find the absolute atoms that have been added by lld");
- auto phe = _programHeader->findProgramHeader(
+ auto phe = this->_programHeader->findProgramHeader(
llvm::ELF::PT_LOAD, llvm::ELF::PF_W, llvm::ELF::PF_X);
- assert(!(phe == _programHeader->end()) &&
+ assert(!(phe == this->_programHeader->end()) &&
"Can't find a data segment in the program header!");
(*bssStartAtomIter)->_virtualAddr = (*phe)->p_vaddr + (*phe)->p_filesz;
@@ -247,153 +120,9 @@ void ExecutableWriter<ELFT>::finalizeDef
(*endAtomIter)->_virtualAddr = (*phe)->p_vaddr + (*phe)->p_memsz;
// Give a chance for the target to finalize its atom values
- _targetHandler.finalizeSymbolValues();
-}
-
-template <class ELFT>
-error_code ExecutableWriter<ELFT>::writeFile(const File &file, StringRef path) {
- buildChunks(file);
-
- // Call the preFlight callbacks to modify the sections and the atoms
- // contained in them, in anyway the targets may want
- _layout->doPreFlight();
-
- // Create the default sections like the symbol table, string table, and the
- // section string table
- createDefaultSections();
-
- if (_targetInfo.isDynamic()) {
- _dynamicTable->createDefaultEntries();
- buildDynamicSymbolTable(file);
- }
-
- // Set the Layout
- _layout->assignSectionsToSegments();
- _layout->assignFileOffsets();
- _layout->assignVirtualAddress();
-
- // Finalize the default value of symbols that the linker adds
- finalizeDefaultAtomValues();
-
- // Build the Atom To Address map for applying relocations
- buildAtomToAddressMap();
-
- // Create symbol table and section string table
- buildStaticSymbolTable(file);
-
- // Finalize the layout by calling the finalize() functions
- _layout->finalize();
-
- // build Section Header table
- buildSectionHeaderTable();
-
- // assign Offsets and virtual addresses
- // for sections with no segments
- assignSectionsWithNoSegments();
-
- if (_targetInfo.isDynamic())
- _dynamicTable->updateDynamicTable(_hashTable.get(),
- _dynamicSymbolTable.get());
-
- uint64_t totalSize = _shdrtab->fileOffset() + _shdrtab->fileSize();
-
- OwningPtr<FileOutputBuffer> buffer;
- error_code ec = FileOutputBuffer::create(path,
- totalSize, buffer,
- FileOutputBuffer::F_executable);
- if (ec)
- return ec;
-
- _Header->e_ident(ELF::EI_CLASS, _targetInfo.is64Bits() ? ELF::ELFCLASS64 :
- ELF::ELFCLASS32);
- _Header->e_ident(ELF::EI_DATA, _targetInfo.isLittleEndian() ?
- ELF::ELFDATA2LSB : ELF::ELFDATA2MSB);
- _Header->e_type(_targetInfo.getOutputType());
- _Header->e_machine(_targetInfo.getOutputMachine());
-
- if (!_targetHandler.doesOverrideHeader()) {
- _Header->e_ident(ELF::EI_VERSION, 1);
- _Header->e_ident(ELF::EI_OSABI, 0);
- _Header->e_version(1);
- } else {
- // override the contents of the ELF Header
- _targetHandler.setHeaderInfo(_Header.get());
- }
- _Header->e_phoff(_programHeader->fileOffset());
- _Header->e_shoff(_shdrtab->fileOffset());
- _Header->e_phentsize(_programHeader->entsize());
- _Header->e_phnum(_programHeader->numHeaders());
- _Header->e_shentsize(_shdrtab->entsize());
- _Header->e_shnum(_shdrtab->numHeaders());
- _Header->e_shstrndx(_shstrtab->ordinal());
- uint64_t virtualAddr = 0;
- _layout->findAtomAddrByName(_targetInfo.getEntry(), virtualAddr);
- _Header->e_entry(virtualAddr);
-
- // HACK: We have to write out the header and program header here even though
- // they are a member of a segment because only sections are written in the
- // following loop.
- _Header->write(this, *buffer);
- _programHeader->write(this, *buffer);
-
- for (auto section : _layout->sections())
- section->write(this, *buffer);
-
- return buffer->commit();
+ this->_targetHandler.finalizeSymbolValues();
}
-template<class ELFT>
-void ExecutableWriter<ELFT>::createDefaultSections() {
- _Header.reset(new (_alloc) Header<ELFT>(_targetInfo));
- _programHeader.reset(new (_alloc) ProgramHeader<ELFT>(_targetInfo));
- _layout->setHeader(_Header.get());
- _layout->setProgramHeader(_programHeader.get());
-
- _symtab.reset(new (_alloc) SymbolTable<ELFT>(
- _targetInfo, ".symtab", DefaultLayout<ELFT>::ORDER_SYMBOL_TABLE));
- _strtab.reset(new (_alloc) StringTable<ELFT>(
- _targetInfo, ".strtab", DefaultLayout<ELFT>::ORDER_STRING_TABLE));
- _shstrtab.reset(new (_alloc) StringTable<ELFT>(
- _targetInfo, ".shstrtab", DefaultLayout<ELFT>::ORDER_SECTION_STRINGS));
- _shdrtab.reset(new (_alloc) SectionHeader<ELFT>(
- _targetInfo, DefaultLayout<ELFT>::ORDER_SECTION_HEADERS));
- _layout->addSection(_symtab.get());
- _layout->addSection(_strtab.get());
- _layout->addSection(_shstrtab.get());
- _shdrtab->setStringSection(_shstrtab.get());
- _symtab->setStringSection(_strtab.get());
- _layout->addSection(_shdrtab.get());
-
- if (_targetInfo.isDynamic()) {
- _dynamicTable.reset(new (_alloc) DynamicTable<ELFT>(
- _targetInfo, ".dynamic", DefaultLayout<ELFT>::ORDER_DYNAMIC));
- _dynamicStringTable.reset(new (_alloc) StringTable<ELFT>(
- _targetInfo, ".dynstr", DefaultLayout<ELFT>::ORDER_DYNAMIC_STRINGS,
- true));
- _dynamicSymbolTable.reset(new (_alloc) DynamicSymbolTable<ELFT>(
- _targetInfo, ".dynsym", DefaultLayout<ELFT>::ORDER_DYNAMIC_SYMBOLS));
- _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());
- if (_layout->hasDynamicRelocationTable())
- _layout->getDynamicRelocationTable()->setSymbolTable(
- _dynamicSymbolTable.get());
- if (_layout->hasPLTRelocationTable())
- _layout->getPLTRelocationTable()->setSymbolTable(
- _dynamicSymbolTable.get());
- }
-
- // give a chance for the target to add sections
- _targetHandler.createDefaultSections();
-}
} // namespace elf
} // namespace lld
Added: lld/trunk/lib/ReaderWriter/ELF/OutputELFWriter.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/OutputELFWriter.h?rev=176724&view=auto
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/OutputELFWriter.h (added)
+++ lld/trunk/lib/ReaderWriter/ELF/OutputELFWriter.h Fri Mar 8 15:42:51 2013
@@ -0,0 +1,354 @@
+//===- lib/ReaderWriter/ELF/OutputELFWriter.h ----------------------------===//
+//
+// The LLVM Linker
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#ifndef LLD_READER_WRITER_OUTPUT_ELF_WRITER_H
+#define LLD_READER_WRITER_OUTPUT_ELF_WRITER_H
+
+#include "lld/ReaderWriter/Writer.h"
+
+#include "DefaultLayout.h"
+#include "TargetLayout.h"
+#include "ExecutableAtoms.h"
+
+#include "lld/ReaderWriter/ELFTargetInfo.h"
+
+#include "llvm/ADT/StringSet.h"
+
+namespace lld {
+namespace elf {
+using namespace llvm;
+using namespace llvm::object;
+
+template<class ELFT>
+class OutputELFWriter;
+
+//===----------------------------------------------------------------------===//
+// OutputELFWriter Class
+//===----------------------------------------------------------------------===//
+/// \brief This acts as the base class for all the ELF writers that are output
+/// for emitting an ELF output file. This class also acts as a common class for
+/// creating static and dynamic executables. All the function in this class
+/// can be overridden and an appropriate writer be created
+template<class ELFT>
+class OutputELFWriter : public ELFWriter {
+public:
+ typedef Elf_Shdr_Impl<ELFT> Elf_Shdr;
+ typedef Elf_Sym_Impl<ELFT> Elf_Sym;
+ typedef Elf_Dyn_Impl<ELFT> Elf_Dyn;
+
+ OutputELFWriter(const ELFTargetInfo &ti);
+
+protected:
+ // build the sections that need to be created
+ virtual void createDefaultSections();
+
+ // Build all the output sections
+ virtual void buildChunks(const File &file);
+
+ // Build the output file
+ virtual error_code buildOutput(const File &file);
+
+ // Write the file to the path specified
+ virtual error_code writeFile(const File &File, StringRef path);
+
+ // Build the atom to address map, this has to be called
+ // before applying relocations
+ virtual void buildAtomToAddressMap();
+
+ // Build the symbol table for static linking
+ virtual void buildStaticSymbolTable(const File &file);
+
+ // Build the dynamic symbol table for dynamic linking
+ virtual void buildDynamicSymbolTable(const File &file);
+
+ // Build the section header table
+ virtual void buildSectionHeaderTable();
+
+ // Assign sections that have no segments such as the symbol table,
+ // section header table, string table etc
+ virtual void assignSectionsWithNoSegments();
+
+ // Add default atoms that need to be present in the output file
+ virtual void addDefaultAtoms() = 0;
+
+ // Add any runtime files and their atoms to the output
+ virtual void addFiles(InputFiles&) = 0;
+
+ // Finalize the default atom values
+ virtual void finalizeDefaultAtomValues() = 0;
+
+ // This is called by the write section to apply relocations
+ virtual uint64_t addressOfAtom(const Atom *atom) {
+ return _atomToAddressMap[atom];
+ }
+
+ // This is a hook for creating default dynamic entries
+ virtual void createDefaultDynamicEntries() {}
+
+ llvm::BumpPtrAllocator _alloc;
+
+ const ELFTargetInfo &_targetInfo;
+ TargetHandler<ELFT> &_targetHandler;
+
+ typedef llvm::DenseMap<const Atom *, uint64_t> AtomToAddress;
+ AtomToAddress _atomToAddressMap;
+ TargetLayout<ELFT> *_layout;
+ LLD_UNIQUE_BUMP_PTR(Header<ELFT>) _Header;
+ LLD_UNIQUE_BUMP_PTR(ProgramHeader<ELFT>) _programHeader;
+ LLD_UNIQUE_BUMP_PTR(SymbolTable<ELFT>) _symtab;
+ 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;
+ 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;
+ llvm::StringSet<> _soNeeded;
+ /// @}
+};
+
+//===----------------------------------------------------------------------===//
+// OutputELFWriter
+//===----------------------------------------------------------------------===//
+template <class ELFT>
+OutputELFWriter<ELFT>::OutputELFWriter(const ELFTargetInfo &ti)
+ : _targetInfo(ti), _targetHandler(ti.getTargetHandler<ELFT>()) {
+ _layout = &_targetHandler.targetLayout();
+}
+
+template <class ELFT>
+void OutputELFWriter<ELFT>::buildChunks(const File &file) {
+ for (const DefinedAtom *definedAtom : file.defined()) {
+ _layout->addAtom(definedAtom);
+ }
+ for (const AbsoluteAtom *absoluteAtom : file.absolute())
+ _layout->addAtom(absoluteAtom);
+}
+
+template <class ELFT>
+void OutputELFWriter<ELFT>::buildStaticSymbolTable(const File &file) {
+ for (auto sec : _layout->sections())
+ if (auto section = dyn_cast<AtomSection<ELFT>>(sec))
+ for (const auto &atom : section->atoms())
+ _symtab->addSymbol(atom->_atom, section->ordinal(), atom->_virtualAddr);
+ for (auto &atom : _layout->absoluteAtoms())
+ _symtab->addSymbol(atom->_atom, ELF::SHN_ABS, atom->_virtualAddr);
+ for (const UndefinedAtom *a : file.undefined())
+ _symtab->addSymbol(a, ELF::SHN_UNDEF);
+}
+
+template <class ELFT>
+void OutputELFWriter<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);
+ }
+}
+
+template <class ELFT> void OutputELFWriter<ELFT>::buildAtomToAddressMap() {
+ for (auto sec : _layout->sections())
+ if (auto section = dyn_cast<AtomSection<ELFT>>(sec))
+ for (const auto &atom : section->atoms())
+ _atomToAddressMap[atom->_atom] = atom->_virtualAddr;
+ // build the atomToAddressMap that contains absolute symbols too
+ for (auto &atom : _layout->absoluteAtoms())
+ _atomToAddressMap[atom->_atom] = atom->_virtualAddr;
+}
+
+template<class ELFT>
+void OutputELFWriter<ELFT>::buildSectionHeaderTable() {
+ for (auto mergedSec : _layout->mergedSections()) {
+ if (mergedSec->kind() != Chunk<ELFT>::K_ELFSection &&
+ mergedSec->kind() != Chunk<ELFT>::K_AtomSection)
+ continue;
+ if (mergedSec->hasSegment())
+ _shdrtab->appendSection(mergedSec);
+ }
+}
+
+template<class ELFT>
+void OutputELFWriter<ELFT>::assignSectionsWithNoSegments() {
+ for (auto mergedSec : _layout->mergedSections()) {
+ if (mergedSec->kind() != Chunk<ELFT>::K_ELFSection &&
+ mergedSec->kind() != Chunk<ELFT>::K_AtomSection)
+ continue;
+ if (!mergedSec->hasSegment())
+ _shdrtab->appendSection(mergedSec);
+ }
+ _layout->assignOffsetsForMiscSections();
+ for (auto sec : _layout->sections())
+ if (auto section = dyn_cast<Section<ELFT>>(sec))
+ if (!DefaultLayout<ELFT>::hasOutputSegment(section))
+ _shdrtab->updateSection(section);
+}
+
+template<class ELFT>
+void OutputELFWriter<ELFT>::createDefaultSections() {
+ _Header.reset(new (_alloc) Header<ELFT>(_targetInfo));
+ _programHeader.reset(new (_alloc) ProgramHeader<ELFT>(_targetInfo));
+ _layout->setHeader(_Header.get());
+ _layout->setProgramHeader(_programHeader.get());
+
+ _symtab.reset(new (_alloc) SymbolTable<ELFT>(
+ _targetInfo, ".symtab", DefaultLayout<ELFT>::ORDER_SYMBOL_TABLE));
+ _strtab.reset(new (_alloc) StringTable<ELFT>(
+ _targetInfo, ".strtab", DefaultLayout<ELFT>::ORDER_STRING_TABLE));
+ _shstrtab.reset(new (_alloc) StringTable<ELFT>(
+ _targetInfo, ".shstrtab", DefaultLayout<ELFT>::ORDER_SECTION_STRINGS));
+ _shdrtab.reset(new (_alloc) SectionHeader<ELFT>(
+ _targetInfo, DefaultLayout<ELFT>::ORDER_SECTION_HEADERS));
+ _layout->addSection(_symtab.get());
+ _layout->addSection(_strtab.get());
+ _layout->addSection(_shstrtab.get());
+ _shdrtab->setStringSection(_shstrtab.get());
+ _symtab->setStringSection(_strtab.get());
+ _layout->addSection(_shdrtab.get());
+
+ if (_targetInfo.isDynamic()) {
+ _dynamicTable.reset(new (_alloc) DynamicTable<ELFT>(
+ _targetInfo, ".dynamic", DefaultLayout<ELFT>::ORDER_DYNAMIC));
+ _dynamicStringTable.reset(new (_alloc) StringTable<ELFT>(
+ _targetInfo, ".dynstr", DefaultLayout<ELFT>::ORDER_DYNAMIC_STRINGS,
+ true));
+ _dynamicSymbolTable.reset(new (_alloc) DynamicSymbolTable<ELFT>(
+ _targetInfo, ".dynsym", DefaultLayout<ELFT>::ORDER_DYNAMIC_SYMBOLS));
+ _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());
+ if (_layout->hasDynamicRelocationTable())
+ _layout->getDynamicRelocationTable()->setSymbolTable(
+ _dynamicSymbolTable.get());
+ if (_layout->hasPLTRelocationTable())
+ _layout->getPLTRelocationTable()->setSymbolTable(
+ _dynamicSymbolTable.get());
+ }
+
+ // give a chance for the target to add sections
+ _targetHandler.createDefaultSections();
+}
+
+template <class ELFT>
+error_code OutputELFWriter<ELFT>::buildOutput(const File &file) {
+ buildChunks(file);
+
+ // Call the preFlight callbacks to modify the sections and the atoms
+ // contained in them, in anyway the targets may want
+ _layout->doPreFlight();
+
+ // Create the default sections like the symbol table, string table, and the
+ // section string table
+ createDefaultSections();
+
+ if (_targetInfo.isDynamic()) {
+ _dynamicTable->createDefaultEntries();
+ buildDynamicSymbolTable(file);
+ }
+
+ // Set the Layout
+ _layout->assignSectionsToSegments();
+ _layout->assignFileOffsets();
+ _layout->assignVirtualAddress();
+
+ // Finalize the default value of symbols that the linker adds
+ finalizeDefaultAtomValues();
+
+ // Build the Atom To Address map for applying relocations
+ buildAtomToAddressMap();
+
+ // Create symbol table and section string table
+ buildStaticSymbolTable(file);
+
+ // Finalize the layout by calling the finalize() functions
+ _layout->finalize();
+
+ // build Section Header table
+ buildSectionHeaderTable();
+
+ // assign Offsets and virtual addresses
+ // for sections with no segments
+ assignSectionsWithNoSegments();
+
+ if (_targetInfo.isDynamic())
+ _dynamicTable->updateDynamicTable(_hashTable.get(),
+ _dynamicSymbolTable.get());
+
+ return error_code::success();
+}
+
+template <class ELFT>
+error_code OutputELFWriter<ELFT>::writeFile(const File &file, StringRef path) {
+
+ buildOutput(file);
+
+ uint64_t totalSize = _shdrtab->fileOffset() + _shdrtab->fileSize();
+
+ OwningPtr<FileOutputBuffer> buffer;
+ error_code ec = FileOutputBuffer::create(path,
+ totalSize, buffer,
+ FileOutputBuffer::F_executable);
+ if (ec)
+ return ec;
+
+ _Header->e_ident(ELF::EI_CLASS, _targetInfo.is64Bits() ? ELF::ELFCLASS64 :
+ ELF::ELFCLASS32);
+ _Header->e_ident(ELF::EI_DATA, _targetInfo.isLittleEndian() ?
+ ELF::ELFDATA2LSB : ELF::ELFDATA2MSB);
+ _Header->e_type(_targetInfo.getOutputType());
+ _Header->e_machine(_targetInfo.getOutputMachine());
+
+ if (!_targetHandler.doesOverrideHeader()) {
+ _Header->e_ident(ELF::EI_VERSION, 1);
+ _Header->e_ident(ELF::EI_OSABI, 0);
+ _Header->e_version(1);
+ } else {
+ // override the contents of the ELF Header
+ _targetHandler.setHeaderInfo(_Header.get());
+ }
+ _Header->e_phoff(_programHeader->fileOffset());
+ _Header->e_shoff(_shdrtab->fileOffset());
+ _Header->e_phentsize(_programHeader->entsize());
+ _Header->e_phnum(_programHeader->numHeaders());
+ _Header->e_shentsize(_shdrtab->entsize());
+ _Header->e_shnum(_shdrtab->numHeaders());
+ _Header->e_shstrndx(_shstrtab->ordinal());
+ uint64_t virtualAddr = 0;
+ _layout->findAtomAddrByName(_targetInfo.getEntry(), virtualAddr);
+ _Header->e_entry(virtualAddr);
+
+ // HACK: We have to write out the header and program header here even though
+ // they are a member of a segment because only sections are written in the
+ // following loop.
+ _Header->write(this, *buffer);
+ _programHeader->write(this, *buffer);
+
+ for (auto section : _layout->sections())
+ section->write(this, *buffer);
+
+ return buffer->commit();
+}
+} // namespace elf
+} // namespace lld
+
+#endif // LLD_READER_WRITER_OUTPUT_ELF_WRITER_H
More information about the llvm-commits
mailing list