diff options
| author | Shankar Easwaran <shankare@codeaurora.org> | 2014-01-27 01:21:02 +0000 |
|---|---|---|
| committer | Shankar Easwaran <shankare@codeaurora.org> | 2014-01-27 01:21:02 +0000 |
| commit | b11964707ca24b4bfc4c39f3c6c42ef9c2ef800b (patch) | |
| tree | 84862e61f7c57f4025951ca97e65a6eb0ab73e8c /lld/lib/ReaderWriter/ELF/Mips/MipsTargetHandler.cpp | |
| parent | af7fbd8cf426f74239bd6d30b52beda7524f46c1 (diff) | |
| download | bcm5719-llvm-b11964707ca24b4bfc4c39f3c6c42ef9c2ef800b.tar.gz bcm5719-llvm-b11964707ca24b4bfc4c39f3c6c42ef9c2ef800b.zip | |
[ELF] Make changes to all the targets supported currently
X86_64,X86,PPC,Hexagon,Mips
No change in functionality.
llvm-svn: 200177
Diffstat (limited to 'lld/lib/ReaderWriter/ELF/Mips/MipsTargetHandler.cpp')
| -rw-r--r-- | lld/lib/ReaderWriter/ELF/Mips/MipsTargetHandler.cpp | 212 |
1 files changed, 23 insertions, 189 deletions
diff --git a/lld/lib/ReaderWriter/ELF/Mips/MipsTargetHandler.cpp b/lld/lib/ReaderWriter/ELF/Mips/MipsTargetHandler.cpp index 601c9bf0723..be3d1e466cb 100644 --- a/lld/lib/ReaderWriter/ELF/Mips/MipsTargetHandler.cpp +++ b/lld/lib/ReaderWriter/ELF/Mips/MipsTargetHandler.cpp @@ -10,201 +10,35 @@ #include "ELFFile.h" #include "MipsLinkingContext.h" #include "MipsTargetHandler.h" +#include "MipsExecutableWriter.h" +#include "MipsDynamicLibraryWriter.h" using namespace lld; using namespace elf; -namespace { - -class MipsDynamicSymbolTable : public DynamicSymbolTable<Mips32ElELFType> { -public: - MipsDynamicSymbolTable(const MipsLinkingContext &context) - : DynamicSymbolTable<Mips32ElELFType>( - context, ".dynsym", - DefaultLayout<Mips32ElELFType>::ORDER_DYNAMIC_SYMBOLS), - _layout(context.getTargetLayout()) {} - - virtual void sortSymbols() { - std::stable_sort(_symbolTable.begin(), _symbolTable.end(), - [this](const SymbolEntry &A, const SymbolEntry &B) { - if (A._symbol.getBinding() != STB_GLOBAL && - B._symbol.getBinding() != STB_GLOBAL) - return A._symbol.getBinding() < B._symbol.getBinding(); - - return _layout.getGOTSection().compare(A._atom, B._atom); - }); - } - -private: - const MipsTargetLayout<Mips32ElELFType> &_layout; -}; - -class MipsDynamicTable : public DynamicTable<Mips32ElELFType> { -public: - MipsDynamicTable(MipsLinkingContext &context) - : DynamicTable<Mips32ElELFType>( - context, ".dynamic", DefaultLayout<Mips32ElELFType>::ORDER_DYNAMIC), - _layout(context.getTargetLayout()) {} - - virtual void createDefaultEntries() { - DynamicTable<Mips32ElELFType>::createDefaultEntries(); - - Elf_Dyn dyn; - - // Version id for the Runtime Linker Interface. - dyn.d_un.d_val = 1; - dyn.d_tag = DT_MIPS_RLD_VERSION; - addEntry(dyn); - - // MIPS flags. - dyn.d_un.d_val = RHF_NOTPOT; - dyn.d_tag = DT_MIPS_FLAGS; - addEntry(dyn); - - // The base address of the segment. - dyn.d_un.d_ptr = 0; - dyn.d_tag = DT_MIPS_BASE_ADDRESS; - _dt_baseaddr = addEntry(dyn); - - // Number of local global offset table entries. - dyn.d_un.d_val = 0; - dyn.d_tag = DT_MIPS_LOCAL_GOTNO; - _dt_localgot = addEntry(dyn); - - // Number of entries in the .dynsym section. - dyn.d_un.d_val = 0; - dyn.d_tag = DT_MIPS_SYMTABNO; - _dt_symtabno = addEntry(dyn); - - // The index of the first dynamic symbol table entry that corresponds - // to an entry in the global offset table. - dyn.d_un.d_val = 0; - dyn.d_tag = DT_MIPS_GOTSYM; - _dt_gotsym = addEntry(dyn); - - // Address of the .got section. - dyn.d_un.d_val = 0; - dyn.d_tag = DT_PLTGOT; - _dt_pltgot = addEntry(dyn); - } - - virtual void updateDynamicTable() { - DynamicTable<Mips32ElELFType>::updateDynamicTable(); - - // Assign the minimum segment address to the DT_MIPS_BASE_ADDRESS tag. - auto baseAddr = std::numeric_limits<uint64_t>::max(); - for (auto si : _layout.segments()) - if (si->segmentType() != llvm::ELF::PT_NULL) - baseAddr = std::min(baseAddr, si->virtualAddr()); - _entries[_dt_baseaddr].d_un.d_val = baseAddr; - - auto &got = _layout.getGOTSection(); - - _entries[_dt_symtabno].d_un.d_val = getSymbolTable()->size(); - _entries[_dt_gotsym].d_un.d_val = - getSymbolTable()->size() - got.getGlobalCount(); - _entries[_dt_localgot].d_un.d_val = got.getLocalCount(); - _entries[_dt_pltgot].d_un.d_ptr = - _layout.findOutputSection(".got")->virtualAddr(); - } - -private: - MipsTargetLayout<Mips32ElELFType> &_layout; - - std::size_t _dt_symtabno; - std::size_t _dt_localgot; - std::size_t _dt_gotsym; - std::size_t _dt_pltgot; - std::size_t _dt_baseaddr; -}; -} +typedef llvm::object::ELFType<llvm::support::little, 2, false> Mips32ElELFType; MipsTargetHandler::MipsTargetHandler(MipsLinkingContext &context) - : DefaultTargetHandler(context), _targetLayout(context), - _relocationHandler(context, *this), _gpDispSymAtom(nullptr) {} - -uint64_t MipsTargetHandler::getGPDispSymAddr() const { - return _gpDispSymAtom ? _gpDispSymAtom->_virtualAddr : 0; -} - -bool MipsTargetHandler::doesOverrideELFHeader() { return true; } - -void MipsTargetHandler::setELFHeader(ELFHeader<Mips32ElELFType> *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); - else - elfHeader->e_ident(llvm::ELF::EI_ABIVERSION, 0); - - // FIXME (simon): Read elf flags from all inputs, check compatibility, - // merge them and write result here. - uint32_t flags = llvm::ELF::EF_MIPS_NOREORDER | llvm::ELF::EF_MIPS_ABI_O32 | - llvm::ELF::EF_MIPS_CPIC | llvm::ELF::EF_MIPS_ARCH_32R2; - if (_context.getOutputELFType() == llvm::ELF::ET_DYN) - flags |= EF_MIPS_PIC; - elfHeader->e_flags(flags); -} - -MipsTargetLayout<Mips32ElELFType> &MipsTargetHandler::targetLayout() { - return _targetLayout; -} - -const MipsTargetRelocationHandler & -MipsTargetHandler::getRelocationHandler() const { - return _relocationHandler; -} - -LLD_UNIQUE_BUMP_PTR(DynamicTable<Mips32ElELFType>) -MipsTargetHandler::createDynamicTable() { - return LLD_UNIQUE_BUMP_PTR(DynamicTable<Mips32ElELFType>)( - new (_alloc) MipsDynamicTable( - static_cast<MipsLinkingContext &>(_context))); -} - -LLD_UNIQUE_BUMP_PTR(DynamicSymbolTable<Mips32ElELFType>) -MipsTargetHandler::createDynamicSymbolTable() { - return LLD_UNIQUE_BUMP_PTR(DynamicSymbolTable<Mips32ElELFType>)( - new (_alloc) MipsDynamicSymbolTable( - static_cast<MipsLinkingContext &>(_context))); -} - -bool MipsTargetHandler::createImplicitFiles( - std::vector<std::unique_ptr<File>> &result) { - typedef CRuntimeFile<Mips32ElELFType> RFile; - auto file = std::unique_ptr<RFile>(new RFile(_context, "MIPS runtime file")); - - if (_context.isDynamic()) { - file->addAbsoluteAtom("_GLOBAL_OFFSET_TABLE_"); - file->addAbsoluteAtom("_gp"); - file->addAbsoluteAtom("_gp_disp"); - } - result.push_back(std::move(file)); - return true; -} - -void MipsTargetHandler::finalizeSymbolValues() { - DefaultTargetHandler<Mips32ElELFType>::finalizeSymbolValues(); - - if (_context.isDynamic()) { - auto gotSection = _targetLayout.findOutputSection(".got"); - auto got = gotSection ? gotSection->virtualAddr() : 0; - auto gp = gotSection ? got + _targetLayout.getGPOffset() : 0; - - auto gotAtomIter = _targetLayout.findAbsoluteAtom("_GLOBAL_OFFSET_TABLE_"); - assert(gotAtomIter != _targetLayout.absoluteAtoms().end()); - (*gotAtomIter)->_virtualAddr = got; - - auto gpAtomIter = _targetLayout.findAbsoluteAtom("_gp"); - assert(gpAtomIter != _targetLayout.absoluteAtoms().end()); - (*gpAtomIter)->_virtualAddr = gp; - - auto gpDispAtomIter = _targetLayout.findAbsoluteAtom("_gp_disp"); - assert(gpDispAtomIter != _targetLayout.absoluteAtoms().end()); - _gpDispSymAtom = (*gpDispAtomIter); - _gpDispSymAtom->_virtualAddr = gp; + : DefaultTargetHandler(context), _mipsLinkingContext(context), + _mipsRuntimeFile(new MipsRuntimeFile<Mips32ElELFType>(context)), + _mipsTargetLayout(new MipsTargetLayout<Mips32ElELFType>(context)), + _mipsRelocationHandler( + new MipsTargetRelocationHandler(context, *_mipsTargetLayout.get())) {} + +std::unique_ptr<Writer> MipsTargetHandler::getWriter() { + switch (_mipsLinkingContext.getOutputELFType()) { + case llvm::ELF::ET_EXEC: + return std::unique_ptr<Writer>( + new elf::MipsExecutableWriter<Mips32ElELFType>( + _mipsLinkingContext, *_mipsTargetLayout.get())); + case llvm::ELF::ET_DYN: + return std::unique_ptr<Writer>( + new elf::MipsDynamicLibraryWriter<Mips32ElELFType>( + _mipsLinkingContext, *_mipsTargetLayout.get())); + case llvm::ELF::ET_REL: + llvm_unreachable("TODO: support -r mode"); + default: + llvm_unreachable("unsupported output type"); } } |

