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 19namespace mcld { 20 21MipsELFDynamic::MipsELFDynamic(const MipsGNULDBackend& pParent, 22 const LinkerConfig& pConfig) 23 : ELFDynamic(pParent, pConfig), m_pParent(pParent), m_pConfig(pConfig) { 24} 25 26void 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 41void 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 56size_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 64size_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 71size_t MipsELFDynamic::getLocalGotNum(const ELFFileFormat& pFormat) const { 72 if (!pFormat.hasGOT()) 73 return 0; 74 75 return m_pParent.getGOT().getLocalNum(); 76} 77 78uint64_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