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