//===- MipsELFDynamic.cpp -------------------------------------------------===// // // The MCLinker Project // // This file is distributed under the University of Illinois Open Source // License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// #include "mcld/LinkerConfig.h" #include "mcld/LD/ELFFileFormat.h" #include "mcld/LD/ELFSegment.h" #include "mcld/LD/ELFSegmentFactory.h" #include "mcld/Target/GNULDBackend.h" #include "MipsELFDynamic.h" #include "MipsLDBackend.h" #include namespace mcld { MipsELFDynamic::MipsELFDynamic(const MipsGNULDBackend& pParent, const LinkerConfig& pConfig) : ELFDynamic(pParent, pConfig), m_pParent(pParent), m_pConfig(pConfig) { } void MipsELFDynamic::reserveTargetEntries(const ELFFileFormat& pFormat) { if (pFormat.hasGOT()) reserveOne(llvm::ELF::DT_PLTGOT); reserveOne(llvm::ELF::DT_MIPS_RLD_VERSION); reserveOne(llvm::ELF::DT_MIPS_FLAGS); reserveOne(llvm::ELF::DT_MIPS_BASE_ADDRESS); reserveOne(llvm::ELF::DT_MIPS_LOCAL_GOTNO); reserveOne(llvm::ELF::DT_MIPS_SYMTABNO); reserveOne(llvm::ELF::DT_MIPS_GOTSYM); if (pFormat.hasGOTPLT()) reserveOne(llvm::ELF::DT_MIPS_PLTGOT); } void MipsELFDynamic::applyTargetEntries(const ELFFileFormat& pFormat) { if (pFormat.hasGOT()) applyOne(llvm::ELF::DT_PLTGOT, pFormat.getGOT().addr()); applyOne(llvm::ELF::DT_MIPS_RLD_VERSION, 1); applyOne(llvm::ELF::DT_MIPS_FLAGS, llvm::ELF::RHF_NOTPOT); applyOne(llvm::ELF::DT_MIPS_BASE_ADDRESS, getBaseAddress()); applyOne(llvm::ELF::DT_MIPS_LOCAL_GOTNO, getLocalGotNum(pFormat)); applyOne(llvm::ELF::DT_MIPS_SYMTABNO, getSymTabNum(pFormat)); applyOne(llvm::ELF::DT_MIPS_GOTSYM, getGotSym(pFormat)); if (pFormat.hasGOTPLT()) applyOne(llvm::ELF::DT_MIPS_PLTGOT, pFormat.getGOTPLT().addr()); } size_t MipsELFDynamic::getSymTabNum(const ELFFileFormat& pFormat) const { if (!pFormat.hasDynSymTab()) return 0; const LDSection& dynsym = pFormat.getDynSymTab(); return dynsym.size() / symbolSize(); } size_t MipsELFDynamic::getGotSym(const ELFFileFormat& pFormat) const { if (!pFormat.hasGOT()) return 0; return getSymTabNum(pFormat) - m_pParent.getGOT().getGlobalNum(); } size_t MipsELFDynamic::getLocalGotNum(const ELFFileFormat& pFormat) const { if (!pFormat.hasGOT()) return 0; return m_pParent.getGOT().getLocalNum(); } uint64_t MipsELFDynamic::getBaseAddress() { if (LinkerConfig::Exec != m_pConfig.codeGenType()) return 0; ELFSegmentFactory::const_iterator baseSeg = m_pParent.elfSegmentTable().find(llvm::ELF::PT_LOAD, 0x0, 0x0); return m_pParent.elfSegmentTable().end() == baseSeg ? 0 : (*baseSeg)->vaddr(); } } // namespace mcld