1//===- MipsELFDynamic.cpp -------------------------------------------------===// 2// 3// The MCLinker Project 4// 5// This file is distributed under the University of Illinois Open Source 6// License. See LICENSE.TXT for details. 7// 8//===----------------------------------------------------------------------===// 9#include <llvm/Support/ELF.h> 10#include <mcld/LinkerConfig.h> 11#include <mcld/LD/ELFFileFormat.h> 12#include <mcld/LD/ELFSegment.h> 13#include <mcld/LD/ELFSegmentFactory.h> 14#include <mcld/Target/GNULDBackend.h> 15#include "MipsELFDynamic.h" 16#include "MipsLDBackend.h" 17 18using namespace mcld; 19 20MipsELFDynamic::MipsELFDynamic(const MipsGNULDBackend& pParent, 21 const LinkerConfig& pConfig) 22 : ELFDynamic(pParent, pConfig), 23 m_pParent(pParent), 24 m_pConfig(pConfig) 25{ 26} 27 28void MipsELFDynamic::reserveTargetEntries(const ELFFileFormat& pFormat) 29{ 30 if (pFormat.hasGOT()) 31 reserveOne(llvm::ELF::DT_PLTGOT); 32 33 reserveOne(llvm::ELF::DT_MIPS_RLD_VERSION); 34 reserveOne(llvm::ELF::DT_MIPS_FLAGS); 35 reserveOne(llvm::ELF::DT_MIPS_BASE_ADDRESS); 36 reserveOne(llvm::ELF::DT_MIPS_LOCAL_GOTNO); 37 reserveOne(llvm::ELF::DT_MIPS_SYMTABNO); 38 reserveOne(llvm::ELF::DT_MIPS_GOTSYM); 39 40 if (pFormat.hasGOTPLT()) 41 reserveOne(llvm::ELF::DT_MIPS_PLTGOT); 42} 43 44void MipsELFDynamic::applyTargetEntries(const ELFFileFormat& pFormat) 45{ 46 if (pFormat.hasGOT()) 47 applyOne(llvm::ELF::DT_PLTGOT, pFormat.getGOT().addr()); 48 49 applyOne(llvm::ELF::DT_MIPS_RLD_VERSION, 1); 50 applyOne(llvm::ELF::DT_MIPS_FLAGS, llvm::ELF::RHF_NOTPOT); 51 applyOne(llvm::ELF::DT_MIPS_BASE_ADDRESS, getBaseAddress()); 52 applyOne(llvm::ELF::DT_MIPS_LOCAL_GOTNO, getLocalGotNum(pFormat)); 53 applyOne(llvm::ELF::DT_MIPS_SYMTABNO, getSymTabNum(pFormat)); 54 applyOne(llvm::ELF::DT_MIPS_GOTSYM, getGotSym(pFormat)); 55 56 if (pFormat.hasGOTPLT()) 57 applyOne(llvm::ELF::DT_MIPS_PLTGOT, pFormat.getGOTPLT().addr()); 58} 59 60size_t MipsELFDynamic::getSymTabNum(const ELFFileFormat& pFormat) const 61{ 62 if (!pFormat.hasDynSymTab()) 63 return 0; 64 65 const LDSection& dynsym = pFormat.getDynSymTab(); 66 return dynsym.size() / symbolSize(); 67} 68 69size_t MipsELFDynamic::getGotSym(const ELFFileFormat& pFormat) const 70{ 71 if (!pFormat.hasGOT()) 72 return 0; 73 74 return getSymTabNum(pFormat) - m_pParent.getGOT().getGlobalNum(); 75} 76 77size_t MipsELFDynamic::getLocalGotNum(const ELFFileFormat& pFormat) const 78{ 79 if (!pFormat.hasGOT()) 80 return 0; 81 82 return m_pParent.getGOT().getLocalNum(); 83} 84 85uint64_t MipsELFDynamic::getBaseAddress() 86{ 87 if (LinkerConfig::Exec != m_pConfig.codeGenType()) 88 return 0; 89 90 ELFSegmentFactory::const_iterator baseSeg = 91 m_pParent.elfSegmentTable().find(llvm::ELF::PT_LOAD, 0x0, 0x0); 92 93 return m_pParent.elfSegmentTable().end() == baseSeg ? 0 : (*baseSeg)->vaddr(); 94} 95