//===- lib/ReaderWriter/ELF/Mips/MipsExecutableWriter.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_ELF_MIPS_MIPS_EXECUTABLE_WRITER_H #define LLD_READER_WRITER_ELF_MIPS_MIPS_EXECUTABLE_WRITER_H #include "ExecutableWriter.h" #include "MipsDynamicTable.h" #include "MipsELFWriters.h" #include "MipsLinkingContext.h" namespace lld { namespace elf { template class MipsTargetLayout; template class MipsExecutableWriter : public ExecutableWriter { public: MipsExecutableWriter(MipsLinkingContext &context, MipsTargetLayout &layout); protected: void buildDynamicSymbolTable(const File &file) override; // Add any runtime files and their atoms to the output bool createImplicitFiles(std::vector> &) override; void finalizeDefaultAtomValues() override; error_code setELFHeader() override { ExecutableWriter::setELFHeader(); _writeHelper.setELFHeader(*this->_elfHeader); return error_code::success(); } LLD_UNIQUE_BUMP_PTR(DynamicTable) createDynamicTable(); LLD_UNIQUE_BUMP_PTR(DynamicSymbolTable) createDynamicSymbolTable(); private: void addDefaultAtoms() { if (this->_context.isDynamic()) { _mipsRuntimeFile->addAbsoluteAtom("_GLOBAL_OFFSET_TABLE_"); _mipsRuntimeFile->addAbsoluteAtom("_gp"); _mipsRuntimeFile->addAbsoluteAtom("_gp_disp"); } } MipsELFWriter _writeHelper; std::unique_ptr> _mipsRuntimeFile; MipsLinkingContext &_mipsContext; MipsTargetLayout &_mipsTargetLayout; }; template MipsExecutableWriter::MipsExecutableWriter(MipsLinkingContext &context, MipsTargetLayout &layout) : ExecutableWriter(context, layout), _writeHelper(context, layout), _mipsRuntimeFile(new MipsRuntimeFile(context)), _mipsContext(context), _mipsTargetLayout(layout) {} template void MipsExecutableWriter::buildDynamicSymbolTable(const File &file) { // MIPS ABI requires to add to dynsym even undefined symbols // if they have a corresponding entries in a global part of GOT. for (const UndefinedAtom *a : file.undefined()) // FIXME (simon): Consider to move this check to the // MipsELFUndefinedAtom class method. That allows to // handle more complex coditions in the future. if (_writeHelper.hasGlobalGOTEntry(a)) this->_dynamicSymbolTable->addSymbol(a, ELF::SHN_UNDEF); ExecutableWriter::buildDynamicSymbolTable(file); } template bool MipsExecutableWriter::createImplicitFiles( std::vector> &result) { ExecutableWriter::createImplicitFiles(result); // Add the default atoms as defined for mips addDefaultAtoms(); result.push_back(std::move(_mipsRuntimeFile)); return true; } template void MipsExecutableWriter::finalizeDefaultAtomValues() { // Finalize the atom values that are part of the parent. ExecutableWriter::finalizeDefaultAtomValues(); _writeHelper.finalizeMipsRuntimeAtomValues(); } /// \brief create dynamic table template LLD_UNIQUE_BUMP_PTR(DynamicTable) MipsExecutableWriter::createDynamicTable() { return LLD_UNIQUE_BUMP_PTR(DynamicTable)(new ( this->_alloc) MipsDynamicTable(_mipsContext, _mipsTargetLayout)); } /// \brief create dynamic symbol table template LLD_UNIQUE_BUMP_PTR(DynamicSymbolTable) MipsExecutableWriter::createDynamicSymbolTable() { return LLD_UNIQUE_BUMP_PTR( DynamicSymbolTable)(new (this->_alloc) MipsDynamicSymbolTable( _mipsContext, _mipsTargetLayout)); } } // namespace elf } // namespace lld #endif