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 18 using namespace mcld; 19 20 MipsELFDynamic::MipsELFDynamic(const MipsGNULDBackend& pParent, 21 const LinkerConfig& pConfig) 22 : ELFDynamic(pParent, pConfig), 23 m_pParent(pParent), 24 m_pConfig(pConfig) 25 { 26 } 27 28 void 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 44 void 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 60 size_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 69 size_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 77 size_t MipsELFDynamic::getLocalGotNum(const ELFFileFormat& pFormat) const 78 { 79 if (!pFormat.hasGOT()) 80 return 0; 81 82 return m_pParent.getGOT().getLocalNum(); 83 } 84 85 uint64_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