Index: lib/ReaderWriter/ELF/AArch64/AArch64DynamicLibraryWriter.h =================================================================== --- lib/ReaderWriter/ELF/AArch64/AArch64DynamicLibraryWriter.h +++ /dev/null @@ -1,56 +0,0 @@ -//===- lib/ReaderWriter/ELF/AArch64/AArch64DynamicLibraryWriter.h ---------===// -// -// The LLVM Linker -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -#ifndef AARCH64_DYNAMIC_LIBRARY_WRITER_H -#define AARCH64_DYNAMIC_LIBRARY_WRITER_H - -#include "AArch64LinkingContext.h" -#include "AArch64TargetHandler.h" -#include "DynamicLibraryWriter.h" - -namespace lld { -namespace elf { - -template -class AArch64DynamicLibraryWriter : public DynamicLibraryWriter { -public: - AArch64DynamicLibraryWriter(AArch64LinkingContext &ctx, - TargetLayout &layout); - -protected: - // Add any runtime files and their atoms to the output - void createImplicitFiles(std::vector> &) override; - -private: - class GOTFile : public SimpleFile { - public: - GOTFile(const ELFLinkingContext &eti) : SimpleFile("GOTFile") {} - llvm::BumpPtrAllocator _alloc; - }; - - std::unique_ptr _gotFile; -}; - -template -AArch64DynamicLibraryWriter::AArch64DynamicLibraryWriter( - AArch64LinkingContext &ctx, TargetLayout &layout) - : DynamicLibraryWriter(ctx, layout), _gotFile(new GOTFile(ctx)) {} - -template -void AArch64DynamicLibraryWriter::createImplicitFiles( - std::vector> &result) { - DynamicLibraryWriter::createImplicitFiles(result); - _gotFile->addAtom(*new (_gotFile->_alloc) GlobalOffsetTableAtom(*_gotFile)); - _gotFile->addAtom(*new (_gotFile->_alloc) DynamicAtom(*_gotFile)); - result.push_back(std::move(_gotFile)); -} - -} // namespace elf -} // namespace lld - -#endif Index: lib/ReaderWriter/ELF/AArch64/AArch64ExecutableWriter.h =================================================================== --- lib/ReaderWriter/ELF/AArch64/AArch64ExecutableWriter.h +++ lib/ReaderWriter/ELF/AArch64/AArch64ExecutableWriter.h @@ -9,17 +9,17 @@ #ifndef AARCH64_EXECUTABLE_WRITER_H #define AARCH64_EXECUTABLE_WRITER_H -#include "AArch64LinkingContext.h" +#include "DynamicLibraryWriter.h" #include "ExecutableWriter.h" namespace lld { namespace elf { -template -class AArch64ExecutableWriter : public ExecutableWriter { +template +class AArch64OutputWriter : public OutputELFWriter { public: - AArch64ExecutableWriter(AArch64LinkingContext &ctx, - TargetLayout &layout); + AArch64OutputWriter(ELFLinkingContext &ctx, TargetLayout &layout) + : OutputELFWriter(ctx, layout) {} protected: // Add any runtime files and their atoms to the output @@ -31,25 +31,27 @@ GOTFile(const ELFLinkingContext &eti) : SimpleFile("GOTFile") {} llvm::BumpPtrAllocator _alloc; }; - - std::unique_ptr _gotFile; }; template -AArch64ExecutableWriter::AArch64ExecutableWriter( - AArch64LinkingContext &ctx, TargetLayout &layout) - : ExecutableWriter(ctx, layout), _gotFile(new GOTFile(ctx)) {} - -template -void AArch64ExecutableWriter::createImplicitFiles( +void AArch64OutputWriter::createImplicitFiles( std::vector> &result) { - ExecutableWriter::createImplicitFiles(result); - _gotFile->addAtom(*new (_gotFile->_alloc) GlobalOffsetTableAtom(*_gotFile)); + OutputELFWriter::createImplicitFiles(result); + auto gotFile = llvm::make_unique(this->_ctx); + gotFile->addAtom(*new (gotFile->_alloc) GlobalOffsetTableAtom(*gotFile)); if (this->_ctx.isDynamic()) - _gotFile->addAtom(*new (_gotFile->_alloc) DynamicAtom(*_gotFile)); - result.push_back(std::move(_gotFile)); + gotFile->addAtom(*new (gotFile->_alloc) DynamicAtom(*gotFile)); + result.push_back(gotFile); } +template +using AArch64DynamicLibraryWriter = + DynamicLibraryWriter>; + +template +using AArch64ExecutableWriter = + ExecutableWriter>; + } // namespace elf } // namespace lld Index: lib/ReaderWriter/ELF/AArch64/AArch64TargetHandler.cpp =================================================================== --- lib/ReaderWriter/ELF/AArch64/AArch64TargetHandler.cpp +++ lib/ReaderWriter/ELF/AArch64/AArch64TargetHandler.cpp @@ -8,7 +8,6 @@ //===----------------------------------------------------------------------===// #include "Atoms.h" -#include "AArch64DynamicLibraryWriter.h" #include "AArch64ExecutableWriter.h" #include "AArch64LinkingContext.h" #include "AArch64TargetHandler.h" Index: lib/ReaderWriter/ELF/DynamicLibraryWriter.h =================================================================== --- lib/ReaderWriter/ELF/DynamicLibraryWriter.h +++ lib/ReaderWriter/ELF/DynamicLibraryWriter.h @@ -19,11 +19,11 @@ //===----------------------------------------------------------------------===// // DynamicLibraryWriter Class //===----------------------------------------------------------------------===// -template -class DynamicLibraryWriter : public OutputELFWriter { +template > +class DynamicLibraryWriter : public BaseWriter { public: DynamicLibraryWriter(ELFLinkingContext &ctx, TargetLayout &layout) - : OutputELFWriter(ctx, layout) {} + : BaseWriter(ctx, layout) {} protected: void buildDynamicSymbolTable(const File &file) override; @@ -34,8 +34,9 @@ //===----------------------------------------------------------------------===// // DynamicLibraryWriter //===----------------------------------------------------------------------===// -template -void DynamicLibraryWriter::buildDynamicSymbolTable(const File &file) { +template +void DynamicLibraryWriter::buildDynamicSymbolTable( + const File &file) { // 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 @@ -51,23 +52,23 @@ for (const UndefinedAtom *a : file.undefined()) this->_dynamicSymbolTable->addSymbol(a, ELF::SHN_UNDEF); - OutputELFWriter::buildDynamicSymbolTable(file); + BaseWriter::buildDynamicSymbolTable(file); } /// \brief Hook in lld to add CRuntime file -template -void DynamicLibraryWriter::createImplicitFiles( - std::vector > &result) { - OutputELFWriter::createImplicitFiles(result); +template +void DynamicLibraryWriter::createImplicitFiles( + std::vector> &result) { + BaseWriter::createImplicitFiles(result); // Add the default atoms as defined by executables auto file = llvm::make_unique>(this->_ctx, "C runtime"); file->addAbsoluteAtom("_end"); result.push_back(std::move(file)); } -template -void DynamicLibraryWriter::finalizeDefaultAtomValues() { - OutputELFWriter::finalizeDefaultAtomValues(); +template +void DynamicLibraryWriter::finalizeDefaultAtomValues() { + BaseWriter::finalizeDefaultAtomValues(); lld::AtomLayout *underScoreEndAtom = this->_layout.findAbsoluteAtom("_end"); assert(underScoreEndAtom); Index: lib/ReaderWriter/ELF/ExecutableWriter.h =================================================================== --- lib/ReaderWriter/ELF/ExecutableWriter.h +++ lib/ReaderWriter/ELF/ExecutableWriter.h @@ -19,11 +19,11 @@ //===----------------------------------------------------------------------===// // ExecutableWriter Class //===----------------------------------------------------------------------===// -template -class ExecutableWriter : public OutputELFWriter { +template > +class ExecutableWriter : public BaseWriter { public: ExecutableWriter(ELFLinkingContext &ctx, TargetLayout &layout) - : OutputELFWriter(ctx, layout) {} + : BaseWriter(ctx, layout) {} protected: void buildDynamicSymbolTable(const File &file) override; @@ -36,16 +36,14 @@ } unique_bump_ptr> _interpSection; - -private: - std::unique_ptr> createRuntimeFile(); }; //===----------------------------------------------------------------------===// // ExecutableWriter //===----------------------------------------------------------------------===// -template -void ExecutableWriter::buildDynamicSymbolTable(const File &file) { +template +void ExecutableWriter::buildDynamicSymbolTable( + const File &file) { for (auto sec : this->_layout.sections()) if (auto section = dyn_cast>(sec)) for (const auto &atom : section->atoms()) { @@ -70,11 +68,14 @@ } } - OutputELFWriter::buildDynamicSymbolTable(file); + BaseWriter::buildDynamicSymbolTable(file); } -template -std::unique_ptr> ExecutableWriter::createRuntimeFile() { +/// \brief Hook in lld to add CRuntime file +template +void ExecutableWriter::createImplicitFiles( + std::vector> &result) { + BaseWriter::createImplicitFiles(result); auto file = llvm::make_unique>(this->_ctx, "C runtime"); file->addUndefinedAtom(this->_ctx.entrySymbolName()); file->addAbsoluteAtom("__bss_start"); @@ -94,19 +95,12 @@ } file->addAbsoluteAtom("__fini_array_start"); file->addAbsoluteAtom("__fini_array_end"); - return file; -} - -/// \brief Hook in lld to add CRuntime file -template -void ExecutableWriter::createImplicitFiles( - std::vector > &result) { - OutputELFWriter::createImplicitFiles(result); - result.push_back(createRuntimeFile()); + result.push_back(std::move(file)); } -template void ExecutableWriter::createDefaultSections() { - OutputELFWriter::createDefaultSections(); +template +void ExecutableWriter::createDefaultSections() { + BaseWriter::createDefaultSections(); if (this->_ctx.isDynamic()) { _interpSection.reset(new (this->_alloc) InterpSection( this->_ctx, ".interp", TargetLayout::ORDER_INTERP, @@ -117,8 +111,9 @@ /// Finalize the value of all the absolute symbols that we /// created -template void ExecutableWriter::finalizeDefaultAtomValues() { - OutputELFWriter::finalizeDefaultAtomValues(); +template +void ExecutableWriter::finalizeDefaultAtomValues() { + BaseWriter::finalizeDefaultAtomValues(); AtomLayout *bssStartAtom = this->_layout.findAbsoluteAtom("__bss_start"); AtomLayout *bssEndAtom = this->_layout.findAbsoluteAtom("__bss_end"); AtomLayout *underScoreEndAtom = this->_layout.findAbsoluteAtom("_end"); Index: lib/ReaderWriter/ELF/Hexagon/HexagonDynamicLibraryWriter.h =================================================================== --- lib/ReaderWriter/ELF/Hexagon/HexagonDynamicLibraryWriter.h +++ /dev/null @@ -1,72 +0,0 @@ -//===- lib/ReaderWriter/ELF/Hexagon/HexagonDynamicLibraryWriter.h ---------===// -// -// The LLVM Linker -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -#ifndef HEXAGON_DYNAMIC_LIBRARY_WRITER_H -#define HEXAGON_DYNAMIC_LIBRARY_WRITER_H - -#include "DynamicLibraryWriter.h" -#include "HexagonExecutableAtoms.h" -#include "HexagonLinkingContext.h" - -namespace lld { -namespace elf { - -template class HexagonTargetLayout; - -template -class HexagonDynamicLibraryWriter : public DynamicLibraryWriter { -public: - HexagonDynamicLibraryWriter(HexagonLinkingContext &ctx, - HexagonTargetLayout &layout); - -protected: - // Add any runtime files and their atoms to the output - void createImplicitFiles(std::vector> &) override; - - void finalizeDefaultAtomValues() override; - - std::error_code setELFHeader() override { - DynamicLibraryWriter::setELFHeader(); - setHexagonELFHeader(*this->_elfHeader); - return std::error_code(); - } - -private: - HexagonLinkingContext &_ctx; - HexagonTargetLayout &_targetLayout; -}; - -template -HexagonDynamicLibraryWriter::HexagonDynamicLibraryWriter( - HexagonLinkingContext &ctx, HexagonTargetLayout &layout) - : DynamicLibraryWriter(ctx, layout), _ctx(ctx), - _targetLayout(layout) {} - -template -void HexagonDynamicLibraryWriter::createImplicitFiles( - std::vector> &result) { - DynamicLibraryWriter::createImplicitFiles(result); - // Add the default atoms as defined for hexagon - auto file = llvm::make_unique>(_ctx); - file->addAbsoluteAtom("_GLOBAL_OFFSET_TABLE_"); - file->addAbsoluteAtom("_DYNAMIC"); - result.push_back(std::move(file)); -} - -template -void HexagonDynamicLibraryWriter::finalizeDefaultAtomValues() { - // Finalize the atom values that are part of the parent. - DynamicLibraryWriter::finalizeDefaultAtomValues(); - if (_ctx.isDynamic()) - finalizeHexagonRuntimeAtomValues(_targetLayout); -} - -} // namespace elf -} // namespace lld - -#endif // HEXAGON_DYNAMIC_LIBRARY_WRITER_H Index: lib/ReaderWriter/ELF/Hexagon/HexagonExecutableWriter.h =================================================================== --- lib/ReaderWriter/ELF/Hexagon/HexagonExecutableWriter.h +++ lib/ReaderWriter/ELF/Hexagon/HexagonExecutableWriter.h @@ -9,6 +9,7 @@ #ifndef HEXAGON_EXECUTABLE_WRITER_H #define HEXAGON_EXECUTABLE_WRITER_H +#include "DynamicLibraryWriter.h" #include "ExecutableWriter.h" #include "HexagonExecutableAtoms.h" #include "HexagonLinkingContext.h" @@ -18,58 +19,99 @@ template class HexagonTargetLayout; -template -class HexagonExecutableWriter : public ExecutableWriter { +template +class HexagonOutputWriter : public OutputELFWriter { public: - HexagonExecutableWriter(HexagonLinkingContext &ctx, - HexagonTargetLayout &layout); + HexagonOutputWriter(ELFLinkingContext &ctx, TargetLayout &layout) + : OutputELFWriter(ctx, layout) {} protected: - // Add any runtime files and their atoms to the output - void createImplicitFiles(std::vector> &) override; + virtual std::unique_ptr> createRuntimeFile(); + void createImplicitFiles(std::vector> &) override; void finalizeDefaultAtomValues() override; - - std::error_code setELFHeader() override { - ExecutableWriter::setELFHeader(); - setHexagonELFHeader(*this->_elfHeader); - return std::error_code(); - } - -private: - HexagonLinkingContext &_ctx; - HexagonTargetLayout &_targetLayout; + std::error_code setELFHeader() override; }; template -HexagonExecutableWriter::HexagonExecutableWriter( - HexagonLinkingContext &ctx, HexagonTargetLayout &layout) - : ExecutableWriter(ctx, layout), _ctx(ctx), _targetLayout(layout) {} - -template -void HexagonExecutableWriter::createImplicitFiles( - std::vector> &result) { - ExecutableWriter::createImplicitFiles(result); - // Add the default atoms as defined for hexagon - auto file = llvm::make_unique>(_ctx); - file->addAbsoluteAtom("_SDA_BASE_"); +std::unique_ptr> +HexagonOutputWriter::createRuntimeFile() { + auto &ctx = static_cast(this->_ctx); + auto file = llvm::make_unique>(ctx); if (this->_ctx.isDynamic()) { file->addAbsoluteAtom("_GLOBAL_OFFSET_TABLE_"); file->addAbsoluteAtom("_DYNAMIC"); } - result.push_back(std::move(file)); + return file; +} + +template +void HexagonOutputWriter::createImplicitFiles( + std::vector> &result) { + OutputELFWriter::createImplicitFiles(result); + result.push_back(createRuntimeFile()); +} + +template +void HexagonOutputWriter::finalizeDefaultAtomValues() { + OutputELFWriter::finalizeDefaultAtomValues(); + if (!this->_ctx.isDynamic()) + return; + AtomLayout *gotAtom = this->_layout.findAbsoluteAtom("_GLOBAL_OFFSET_TABLE_"); + OutputSection *gotpltSection = + this->_layout.findOutputSection(".got.plt"); + if (gotpltSection) + gotAtom->_virtualAddr = gotpltSection->virtualAddr(); + else + gotAtom->_virtualAddr = 0; + AtomLayout *dynamicAtom = this->_layout.findAbsoluteAtom("_DYNAMIC"); + OutputSection *dynamicSection = + this->_layout.findOutputSection(".dynamic"); + if (dynamicSection) + dynamicAtom->_virtualAddr = dynamicSection->virtualAddr(); + else + dynamicAtom->_virtualAddr = 0; } template -void HexagonExecutableWriter::finalizeDefaultAtomValues() { - // Finalize the atom values that are part of the parent. - ExecutableWriter::finalizeDefaultAtomValues(); - AtomLayout *sdabaseAtom = _targetLayout.findAbsoluteAtom("_SDA_BASE_"); - sdabaseAtom->_virtualAddr = _targetLayout.getSDataSection()->virtualAddr(); - if (_ctx.isDynamic()) - finalizeHexagonRuntimeAtomValues(_targetLayout); +std::error_code HexagonOutputWriter::setELFHeader() { + if (std::error_code ec = OutputELFWriter::setELFHeader()) + return ec; + this->_elfHeader->e_ident(llvm::ELF::EI_VERSION, 1); + this->_elfHeader->e_ident(llvm::ELF::EI_OSABI, 0); + this->_elfHeader->e_version(1); + this->_elfHeader->e_flags(0x3); + return std::error_code(); } +template +class HexagonExecutableWriter + : public ExecutableWriter> { + typedef ExecutableWriter> BaseWriter; + +public: + HexagonExecutableWriter(ELFLinkingContext &ctx, TargetLayout &layout) + : BaseWriter(ctx, layout) {} + +protected: + std::unique_ptr> createRuntimeFile() override { + auto file = BaseWriter::createRuntimeFile(); + file->addAbsoluteAtom("_SDA_BASE_"); + return file; + } + + void finalizeDefaultAtomValues() override { + BaseWriter::finalizeDefaultAtomValues(); + auto &layout = static_cast &>(this->_layout); + AtomLayout *sdabaseAtom = layout.findAbsoluteAtom("_SDA_BASE_"); + sdabaseAtom->_virtualAddr = layout.getSDataSection()->virtualAddr(); + } +}; + +template +using HexagonDynamicLibraryWriter = + DynamicLibraryWriter>; + } // namespace elf } // namespace lld Index: lib/ReaderWriter/ELF/Hexagon/HexagonLinkingContext.h =================================================================== --- lib/ReaderWriter/ELF/Hexagon/HexagonLinkingContext.h +++ lib/ReaderWriter/ELF/Hexagon/HexagonLinkingContext.h @@ -65,13 +65,6 @@ } }; -template void setHexagonELFHeader(ELFHeader &elfHeader) { - elfHeader.e_ident(llvm::ELF::EI_VERSION, 1); - elfHeader.e_ident(llvm::ELF::EI_OSABI, 0); - elfHeader.e_version(1); - elfHeader.e_flags(0x3); -} - } // elf } // lld Index: lib/ReaderWriter/ELF/Hexagon/HexagonTargetHandler.h =================================================================== --- lib/ReaderWriter/ELF/Hexagon/HexagonTargetHandler.h +++ lib/ReaderWriter/ELF/Hexagon/HexagonTargetHandler.h @@ -125,22 +125,6 @@ std::unique_ptr _relocationHandler; }; -template -void finalizeHexagonRuntimeAtomValues(HexagonTargetLayout &layout) { - AtomLayout *gotAtom = layout.findAbsoluteAtom("_GLOBAL_OFFSET_TABLE_"); - OutputSection *gotpltSection = layout.findOutputSection(".got.plt"); - if (gotpltSection) - gotAtom->_virtualAddr = gotpltSection->virtualAddr(); - else - gotAtom->_virtualAddr = 0; - AtomLayout *dynamicAtom = layout.findAbsoluteAtom("_DYNAMIC"); - OutputSection *dynamicSection = layout.findOutputSection(".dynamic"); - if (dynamicSection) - dynamicAtom->_virtualAddr = dynamicSection->virtualAddr(); - else - dynamicAtom->_virtualAddr = 0; -} - } // end namespace elf } // end namespace lld Index: lib/ReaderWriter/ELF/Hexagon/HexagonTargetHandler.cpp =================================================================== --- lib/ReaderWriter/ELF/Hexagon/HexagonTargetHandler.cpp +++ lib/ReaderWriter/ELF/Hexagon/HexagonTargetHandler.cpp @@ -8,7 +8,6 @@ //===----------------------------------------------------------------------===// #include "HexagonExecutableWriter.h" -#include "HexagonDynamicLibraryWriter.h" #include "HexagonLinkingContext.h" #include "HexagonTargetHandler.h" Index: lib/ReaderWriter/ELF/Mips/MipsDynamicLibraryWriter.h =================================================================== --- lib/ReaderWriter/ELF/Mips/MipsDynamicLibraryWriter.h +++ lib/ReaderWriter/ELF/Mips/MipsDynamicLibraryWriter.h @@ -10,106 +10,14 @@ #define LLD_READER_WRITER_ELF_MIPS_MIPS_DYNAMIC_LIBRARY_WRITER_H #include "DynamicLibraryWriter.h" -#include "MipsDynamicTable.h" #include "MipsELFWriters.h" -#include "MipsLinkingContext.h" -#include "MipsSectionChunks.h" namespace lld { namespace elf { -template class MipsSymbolTable; -template class MipsDynamicSymbolTable; -template class MipsTargetLayout; - -template -class MipsDynamicLibraryWriter : public DynamicLibraryWriter { -public: - MipsDynamicLibraryWriter(MipsLinkingContext &ctx, - MipsTargetLayout &layout); - -protected: - // Add any runtime files and their atoms to the output - void createImplicitFiles(std::vector> &) override; - - void finalizeDefaultAtomValues() override; - void createDefaultSections() override; - - std::error_code setELFHeader() override { - DynamicLibraryWriter::setELFHeader(); - _writeHelper.setELFHeader(*this->_elfHeader); - return std::error_code(); - } - - unique_bump_ptr> createSymbolTable() override; - unique_bump_ptr> createDynamicTable() override; - unique_bump_ptr> createDynamicSymbolTable() override; - -private: - MipsELFWriter _writeHelper; - MipsTargetLayout &_targetLayout; - unique_bump_ptr> _reginfo; -}; - -template -MipsDynamicLibraryWriter::MipsDynamicLibraryWriter( - MipsLinkingContext &ctx, MipsTargetLayout &layout) - : DynamicLibraryWriter(ctx, layout), _writeHelper(ctx, layout), - _targetLayout(layout) {} - -template -void MipsDynamicLibraryWriter::createImplicitFiles( - std::vector> &result) { - DynamicLibraryWriter::createImplicitFiles(result); - result.push_back(std::move(_writeHelper.createRuntimeFile())); -} - -template -void MipsDynamicLibraryWriter::finalizeDefaultAtomValues() { - // Finalize the atom values that are part of the parent. - DynamicLibraryWriter::finalizeDefaultAtomValues(); - _writeHelper.finalizeMipsRuntimeAtomValues(); -} - -template -void MipsDynamicLibraryWriter::createDefaultSections() { - DynamicLibraryWriter::createDefaultSections(); - const auto &ctx = static_cast(this->_ctx); - const auto &mask = ctx.getMergedReginfoMask(); - if (!mask.hasValue()) - return; - if (ELFT::Is64Bits) - _reginfo = unique_bump_ptr>( - new (this->_alloc) MipsOptionsSection(ctx, _targetLayout, *mask)); - else - _reginfo = unique_bump_ptr>( - new (this->_alloc) MipsReginfoSection(ctx, _targetLayout, *mask)); - this->_layout.addSection(_reginfo.get()); -} - -template -unique_bump_ptr> - MipsDynamicLibraryWriter::createSymbolTable() { - return unique_bump_ptr>( - new (this->_alloc) MipsSymbolTable(this->_ctx)); -} - -/// \brief create dynamic table -template -unique_bump_ptr> - MipsDynamicLibraryWriter::createDynamicTable() { - return unique_bump_ptr>( - new (this->_alloc) MipsDynamicTable(this->_ctx, _targetLayout)); -} - -/// \brief create dynamic symbol table template -unique_bump_ptr> - MipsDynamicLibraryWriter::createDynamicSymbolTable() { - return unique_bump_ptr>( - new (this->_alloc) - MipsDynamicSymbolTable(this->_ctx, _targetLayout)); -} +using MipsDynamicLibraryWriter = + DynamicLibraryWriter>; } // namespace elf } // namespace lld Index: lib/ReaderWriter/ELF/Mips/MipsELFWriters.h =================================================================== --- lib/ReaderWriter/ELF/Mips/MipsELFWriters.h +++ lib/ReaderWriter/ELF/Mips/MipsELFWriters.h @@ -10,36 +10,47 @@ #define LLD_READER_WRITER_ELF_MIPS_MIPS_ELF_WRITERS_H #include "MipsLinkingContext.h" +#include "MipsSectionChunks.h" +#include "OutputELFWriter.h" namespace lld { namespace elf { +template class MipsDynamicSymbolTable; +template class MipsDynamicTable; +template class MipsSymbolTable; template class MipsTargetLayout; -template class MipsELFWriter { +template class MipsOutputWriter : public OutputELFWriter { public: - MipsELFWriter(MipsLinkingContext &ctx, MipsTargetLayout &targetLayout) - : _ctx(ctx), _targetLayout(targetLayout) {} - - void setELFHeader(ELFHeader &elfHeader) { - elfHeader.e_version(1); - elfHeader.e_ident(llvm::ELF::EI_VERSION, llvm::ELF::EV_CURRENT); - elfHeader.e_ident(llvm::ELF::EI_OSABI, llvm::ELF::ELFOSABI_NONE); - if (_targetLayout.findOutputSection(".got.plt")) - elfHeader.e_ident(llvm::ELF::EI_ABIVERSION, 1); + MipsOutputWriter(ELFLinkingContext &ctx, TargetLayout &layout) + : OutputELFWriter(ctx, layout) {} + +protected: + std::error_code setELFHeader() override { + if (std::error_code ec = OutputELFWriter::setELFHeader()) + return ec; + + this->_elfHeader->e_version(1); + this->_elfHeader->e_ident(llvm::ELF::EI_VERSION, llvm::ELF::EV_CURRENT); + this->_elfHeader->e_ident(llvm::ELF::EI_OSABI, llvm::ELF::ELFOSABI_NONE); + if (this->_layout.findOutputSection(".got.plt")) + this->_elfHeader->e_ident(llvm::ELF::EI_ABIVERSION, 1); else - elfHeader.e_ident(llvm::ELF::EI_ABIVERSION, 0); + this->_elfHeader->e_ident(llvm::ELF::EI_ABIVERSION, 0); - elfHeader.e_flags(_ctx.getMergedELFFlags()); + this->_elfHeader->e_flags(getCtx().getMergedELFFlags()); + return std::error_code(); } - void finalizeMipsRuntimeAtomValues() { - if (!_ctx.isDynamic()) + void finalizeDefaultAtomValues() override { + OutputELFWriter::finalizeDefaultAtomValues(); + if (!this->_ctx.isDynamic()) return; - auto gotSection = _targetLayout.findOutputSection(".got"); + auto gotSection = this->_layout.findOutputSection(".got"); auto got = gotSection ? gotSection->virtualAddr() : 0; - auto gp = gotSection ? got + _targetLayout.getGPOffset() : 0; + auto gp = gotSection ? got + getLayout().getGPOffset() : 0; setAtomValue("_GLOBAL_OFFSET_TABLE_", got); setAtomValue("_gp", gp); @@ -47,26 +58,66 @@ setAtomValue("__gnu_local_gp", gp); } - std::unique_ptr> createRuntimeFile() { - auto file = llvm::make_unique>(_ctx, "Mips runtime file"); - if (_ctx.isDynamic()) { - file->addAbsoluteAtom("_GLOBAL_OFFSET_TABLE_"); - file->addAbsoluteAtom("_gp"); - file->addAbsoluteAtom("_gp_disp"); - file->addAbsoluteAtom("__gnu_local_gp"); - } - return file; + void + createImplicitFiles(std::vector> &result) override { + OutputELFWriter::createImplicitFiles(result); + if (!this->_ctx.isDynamic()) + return; + auto file = + llvm::make_unique>(this->_ctx, "Mips runtime file"); + file->addAbsoluteAtom("_GLOBAL_OFFSET_TABLE_"); + file->addAbsoluteAtom("_gp"); + file->addAbsoluteAtom("_gp_disp"); + file->addAbsoluteAtom("__gnu_local_gp"); + result.push_back(std::move(file)); + } + + void createDefaultSections() override { + OutputELFWriter::createDefaultSections(); + const auto &mask = getCtx().getMergedReginfoMask(); + if (!mask.hasValue()) + return; + if (ELFT::Is64Bits) + _reginfo = unique_bump_ptr>(new ( + this->_alloc) MipsOptionsSection(getCtx(), getLayout(), *mask)); + else + _reginfo = unique_bump_ptr>(new ( + this->_alloc) MipsReginfoSection(getCtx(), getLayout(), *mask)); + this->_layout.addSection(_reginfo.get()); + } + + unique_bump_ptr> createSymbolTable() override { + return unique_bump_ptr>( + new (this->_alloc) MipsSymbolTable(this->_ctx)); + } + + unique_bump_ptr> createDynamicTable() override { + return unique_bump_ptr>( + new (this->_alloc) MipsDynamicTable(this->_ctx, getLayout())); + } + + unique_bump_ptr> + createDynamicSymbolTable() override { + return unique_bump_ptr>(new ( + this->_alloc) MipsDynamicSymbolTable(this->_ctx, getLayout())); } private: - MipsLinkingContext &_ctx; - MipsTargetLayout &_targetLayout; + unique_bump_ptr> _reginfo; void setAtomValue(StringRef name, uint64_t value) { - AtomLayout *atom = _targetLayout.findAbsoluteAtom(name); + AtomLayout *atom = this->_layout.findAbsoluteAtom(name); assert(atom); atom->_virtualAddr = value; } + + const MipsLinkingContext &getCtx() const { + return static_cast(this->_ctx); + } + + MipsTargetLayout &getLayout() { + return static_cast &>(this->_layout); + } }; } // elf Index: lib/ReaderWriter/ELF/Mips/MipsExecutableWriter.h =================================================================== --- lib/ReaderWriter/ELF/Mips/MipsExecutableWriter.h +++ lib/ReaderWriter/ELF/Mips/MipsExecutableWriter.h @@ -20,39 +20,26 @@ template class MipsTargetLayout; template -class MipsExecutableWriter : public ExecutableWriter { +class MipsExecutableWriter + : public ExecutableWriter> { + typedef ExecutableWriter> BaseWriter; + public: MipsExecutableWriter(MipsLinkingContext &ctx, MipsTargetLayout &layout); protected: void buildDynamicSymbolTable(const File &file) override; - - // Add any runtime files and their atoms to the output - void createImplicitFiles(std::vector> &) override; - - void finalizeDefaultAtomValues() override; - void createDefaultSections() override; std::error_code setELFHeader() override; - - unique_bump_ptr> createSymbolTable() override; - unique_bump_ptr> createDynamicTable() override; - unique_bump_ptr> createDynamicSymbolTable() override; - -private: - MipsELFWriter _writeHelper; - MipsTargetLayout &_targetLayout; - unique_bump_ptr> _reginfo; }; template MipsExecutableWriter::MipsExecutableWriter(MipsLinkingContext &ctx, MipsTargetLayout &layout) - : ExecutableWriter(ctx, layout), _writeHelper(ctx, layout), - _targetLayout(layout) {} + : BaseWriter(ctx, layout) {} template std::error_code MipsExecutableWriter::setELFHeader() { - std::error_code ec = ExecutableWriter::setELFHeader(); + std::error_code ec = BaseWriter::setELFHeader(); if (ec) return ec; @@ -64,19 +51,18 @@ // Adjust entry symbol value if this symbol is microMIPS encoded. this->_elfHeader->e_entry(al->_virtualAddr | 1); } - - _writeHelper.setELFHeader(*this->_elfHeader); return std::error_code(); } template void MipsExecutableWriter::buildDynamicSymbolTable(const File &file) { + auto &layout = static_cast &>(this->_layout); // MIPS ABI requires to add to dynsym even undefined symbols // if they have a corresponding entries in a global part of GOT. for (auto sec : this->_layout.sections()) if (auto section = dyn_cast>(sec)) for (const auto &atom : section->atoms()) { - if (_targetLayout.getGOTSection().hasGlobalGOTEntry(atom->_atom)) { + if (layout.getGOTSection().hasGlobalGOTEntry(atom->_atom)) { this->_dynamicSymbolTable->addSymbol(atom->_atom, section->ordinal(), atom->_virtualAddr, atom); continue; @@ -100,66 +86,13 @@ // FIXME (simon): Consider to move this check to the // MipsELFUndefinedAtom class method. That allows to // handle more complex coditions in the future. - if (_targetLayout.getGOTSection().hasGlobalGOTEntry(a)) + if (layout.getGOTSection().hasGlobalGOTEntry(a)) this->_dynamicSymbolTable->addSymbol(a, ELF::SHN_UNDEF); // Skip our immediate parent class method // ExecutableWriter::buildDynamicSymbolTable because we replaced it - // with our own version. Call OutputELFWriter directly. - OutputELFWriter::buildDynamicSymbolTable(file); -} - -template -void MipsExecutableWriter::createImplicitFiles( - std::vector> &result) { - ExecutableWriter::createImplicitFiles(result); - result.push_back(std::move(_writeHelper.createRuntimeFile())); -} - -template -void MipsExecutableWriter::finalizeDefaultAtomValues() { - // Finalize the atom values that are part of the parent. - ExecutableWriter::finalizeDefaultAtomValues(); - _writeHelper.finalizeMipsRuntimeAtomValues(); -} - -template void MipsExecutableWriter::createDefaultSections() { - ExecutableWriter::createDefaultSections(); - const auto &ctx = static_cast(this->_ctx); - const auto &mask = ctx.getMergedReginfoMask(); - if (!mask.hasValue()) - return; - if (ELFT::Is64Bits) - _reginfo = unique_bump_ptr>( - new (this->_alloc) MipsOptionsSection(ctx, _targetLayout, *mask)); - else - _reginfo = unique_bump_ptr>( - new (this->_alloc) MipsReginfoSection(ctx, _targetLayout, *mask)); - this->_layout.addSection(_reginfo.get()); -} - -template -unique_bump_ptr> - MipsExecutableWriter::createSymbolTable() { - return unique_bump_ptr>( - new (this->_alloc) MipsSymbolTable(this->_ctx)); -} - -/// \brief create dynamic table -template -unique_bump_ptr> - MipsExecutableWriter::createDynamicTable() { - return unique_bump_ptr>( - new (this->_alloc) MipsDynamicTable(this->_ctx, _targetLayout)); -} - -/// \brief create dynamic symbol table -template -unique_bump_ptr> - MipsExecutableWriter::createDynamicSymbolTable() { - return unique_bump_ptr>( - new (this->_alloc) - MipsDynamicSymbolTable(this->_ctx, _targetLayout)); + // with our own version. Call MipsOutputWriter directly. + MipsOutputWriter::buildDynamicSymbolTable(file); } } // namespace elf Index: lib/ReaderWriter/ELF/X86/X86DynamicLibraryWriter.h =================================================================== --- lib/ReaderWriter/ELF/X86/X86DynamicLibraryWriter.h +++ lib/ReaderWriter/ELF/X86/X86DynamicLibraryWriter.h @@ -18,7 +18,8 @@ template class X86DynamicLibraryWriter : public DynamicLibraryWriter { public: - X86DynamicLibraryWriter(X86LinkingContext &ctx, TargetLayout &layout); + X86DynamicLibraryWriter(X86LinkingContext &ctx, TargetLayout &layout) + : DynamicLibraryWriter(ctx, layout) {} protected: // Add any runtime files and their atoms to the output @@ -30,22 +31,16 @@ GOTFile(const ELFLinkingContext &eti) : SimpleFile("GOTFile") {} llvm::BumpPtrAllocator _alloc; }; - - std::unique_ptr _gotFile; }; template -X86DynamicLibraryWriter::X86DynamicLibraryWriter( - X86LinkingContext &ctx, TargetLayout &layout) - : DynamicLibraryWriter(ctx, layout), _gotFile(new GOTFile(ctx)) {} - -template void X86DynamicLibraryWriter::createImplicitFiles( std::vector> &result) { DynamicLibraryWriter::createImplicitFiles(result); - _gotFile->addAtom(*new (_gotFile->_alloc) GlobalOffsetTableAtom(*_gotFile)); - _gotFile->addAtom(*new (_gotFile->_alloc) DynamicAtom(*_gotFile)); - result.push_back(std::move(_gotFile)); + auto gotFile = llvm::make_unique(this->_ctx); + gotFile->addAtom(*new (gotFile->_alloc) GlobalOffsetTableAtom(*gotFile)); + gotFile->addAtom(*new (gotFile->_alloc) DynamicAtom(*gotFile)); + result.push_back(gotFile); } } // namespace elf Index: lib/ReaderWriter/ELF/X86_64/X86_64DynamicLibraryWriter.h =================================================================== --- lib/ReaderWriter/ELF/X86_64/X86_64DynamicLibraryWriter.h +++ /dev/null @@ -1,54 +0,0 @@ -//===- lib/ReaderWriter/ELF/X86/X86_64DynamicLibraryWriter.h ---------------===// -// -// The LLVM Linker -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -#ifndef X86_64_DYNAMIC_LIBRARY_WRITER_H -#define X86_64_DYNAMIC_LIBRARY_WRITER_H - -#include "DynamicLibraryWriter.h" -#include "X86_64ElfType.h" -#include "X86_64LinkingContext.h" -#include "X86_64TargetHandler.h" - -namespace lld { -namespace elf { - -class X86_64DynamicLibraryWriter : public DynamicLibraryWriter { -public: - X86_64DynamicLibraryWriter(X86_64LinkingContext &ctx, - X86_64TargetLayout &layout); - -protected: - // Add any runtime files and their atoms to the output - void createImplicitFiles(std::vector> &) override; - -private: - class GOTFile : public SimpleFile { - public: - GOTFile(const ELFLinkingContext &eti) : SimpleFile("GOTFile") {} - llvm::BumpPtrAllocator _alloc; - }; - - std::unique_ptr _gotFile; -}; - -X86_64DynamicLibraryWriter::X86_64DynamicLibraryWriter( - X86_64LinkingContext &ctx, X86_64TargetLayout &layout) - : DynamicLibraryWriter(ctx, layout), _gotFile(new GOTFile(ctx)) {} - -void X86_64DynamicLibraryWriter::createImplicitFiles( - std::vector> &result) { - DynamicLibraryWriter::createImplicitFiles(result); - _gotFile->addAtom(*new (_gotFile->_alloc) GlobalOffsetTableAtom(*_gotFile)); - _gotFile->addAtom(*new (_gotFile->_alloc) DynamicAtom(*_gotFile)); - result.push_back(std::move(_gotFile)); -} - -} // namespace elf -} // namespace lld - -#endif Index: lib/ReaderWriter/ELF/X86_64/X86_64ExecutableWriter.h =================================================================== --- lib/ReaderWriter/ELF/X86_64/X86_64ExecutableWriter.h +++ lib/ReaderWriter/ELF/X86_64/X86_64ExecutableWriter.h @@ -9,28 +9,29 @@ #ifndef X86_64_EXECUTABLE_WRITER_H #define X86_64_EXECUTABLE_WRITER_H +#include "DynamicLibraryWriter.h" #include "ExecutableWriter.h" #include "X86_64ElfType.h" -#include "X86_64LinkingContext.h" namespace lld { namespace elf { -class X86_64ExecutableWriter : public ExecutableWriter { +template +class X86_64OutputWriter : public OutputELFWriter { public: - X86_64ExecutableWriter(X86_64LinkingContext &ctx, X86_64TargetLayout &layout) - : ExecutableWriter(ctx, layout), _gotFile(new GOTFile(ctx)) {} + X86_64OutputWriter(ELFLinkingContext &ctx, TargetLayout &layout) + : OutputELFWriter(ctx, layout) {} protected: // Add any runtime files and their atoms to the output void createImplicitFiles(std::vector> &result) override { - ExecutableWriter::createImplicitFiles(result); - _gotFile->addAtom(*new (_gotFile->_alloc) - GlobalOffsetTableAtom(*_gotFile)); + OutputELFWriter::createImplicitFiles(result); + auto gotFile = llvm::make_unique(this->_ctx); + gotFile->addAtom(*new (gotFile->_alloc) GlobalOffsetTableAtom(*gotFile)); if (this->_ctx.isDynamic()) - _gotFile->addAtom(*new (_gotFile->_alloc) DynamicAtom(*_gotFile)); - result.push_back(std::move(_gotFile)); + gotFile->addAtom(*new (gotFile->_alloc) DynamicAtom(*gotFile)); + result.push_back(gotFile); } private: @@ -39,10 +40,14 @@ GOTFile(const ELFLinkingContext &eti) : SimpleFile("GOTFile") {} llvm::BumpPtrAllocator _alloc; }; - - std::unique_ptr _gotFile; }; +typedef DynamicLibraryWriter> + X86_64DynamicLibraryWriter; + +typedef ExecutableWriter> + X86_64ExecutableWriter; + } // namespace elf } // namespace lld 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 @@ -8,7 +8,6 @@ //===----------------------------------------------------------------------===// #include "Atoms.h" -#include "X86_64DynamicLibraryWriter.h" #include "X86_64ExecutableWriter.h" #include "X86_64LinkingContext.h" #include "X86_64TargetHandler.h" Index: test/elf/Mips/gp-sym-1-micro.test =================================================================== --- test/elf/Mips/gp-sym-1-micro.test +++ test/elf/Mips/gp-sym-1-micro.test @@ -8,7 +8,7 @@ # RUN: llvm-readobj -symbols %t.exe | FileCheck -check-prefix=SYM %s # RUN: llvm-objdump -s %t.exe | FileCheck -check-prefix=SEC %s -# SYM: Name: _gp (203) +# SYM: Name: _gp (26) # SYM-NEXT: Value: 0x408FF0 # SEC: Contents of section .text: Index: test/elf/Mips/gp-sym-1.test =================================================================== --- test/elf/Mips/gp-sym-1.test +++ test/elf/Mips/gp-sym-1.test @@ -7,7 +7,7 @@ # RUN: llvm-readobj -symbols %t.exe | FileCheck -check-prefix=SYM %s # RUN: llvm-objdump -s %t.exe | FileCheck -check-prefix=SEC %s -# SYM: Name: _gp (203) +# SYM: Name: _gp (26) # SYM-NEXT: Value: 0x408FF0 # SEC: Contents of section .text: Index: test/elf/Mips/mips-options-gp0.test =================================================================== --- test/elf/Mips/mips-options-gp0.test +++ test/elf/Mips/mips-options-gp0.test @@ -13,7 +13,7 @@ # SYM-NEXT: Other: 0 # SYM-NEXT: Section: .text (0x5) -# SYM: Name: _gp (34) +# SYM: Name: _gp (29) # SYM-NEXT: Value: 0x9FF0 # SYM-NEXT: Size: 0 # SYM-NEXT: Binding: Global (0x1) Index: test/elf/Mips/rel-gprel16.test =================================================================== --- test/elf/Mips/rel-gprel16.test +++ test/elf/Mips/rel-gprel16.test @@ -21,7 +21,7 @@ # SYM-NEXT: Other: 0 # SYM-NEXT: Section: .text (0x5) -# SYM: Name: _gp (34) +# SYM: Name: _gp (29) # SYM-NEXT: Value: 0x8FF0 # SYM-NEXT: Size: 0 # SYM-NEXT: Binding: Global (0x1) Index: test/elf/Mips/rel-gprel32.test =================================================================== --- test/elf/Mips/rel-gprel32.test +++ test/elf/Mips/rel-gprel32.test @@ -13,7 +13,7 @@ # SYM-NEXT: Other: 0 # SYM-NEXT: Section: .text (0x6) # -# SYM: Name: _gp (212) +# SYM: Name: _gp (35) # SYM-NEXT: Value: 0x408FF0 # SYM-NEXT: Size: 0 # SYM-NEXT: Binding: Global (0x1)