| //===- MipsELFDynamic.cpp -------------------------------------------------===// |
| // |
| // The MCLinker Project |
| // |
| // This file is distributed under the University of Illinois Open Source |
| // License. See LICENSE.TXT for details. |
| // |
| //===----------------------------------------------------------------------===// |
| |
| #include <mcld/LD/ELFFileFormat.h> |
| #include <mcld/Target/GNULDBackend.h> |
| #include "MipsELFDynamic.h" |
| #include "MipsLDBackend.h" |
| |
| using namespace mcld; |
| |
| // MIPS mandatory dynamic section entries |
| enum { |
| MIPS_RLD_VERSION = 0x70000001, |
| MIPS_FLAGS = 0x70000005, |
| MIPS_BASE_ADDRESS = 0x70000006, |
| MIPS_LOCAL_GOTNO = 0x7000000a, |
| MIPS_SYMTABNO = 0x70000011, |
| MIPS_GOTSYM = 0x70000013, |
| }; |
| |
| MipsELFDynamic::MipsELFDynamic(const MipsGNULDBackend& pParent) |
| : ELFDynamic(pParent), |
| m_pParent(pParent) |
| { |
| } |
| |
| MipsELFDynamic::~MipsELFDynamic() |
| { |
| } |
| |
| void MipsELFDynamic::reserveTargetEntries(const ELFFileFormat& pFormat) |
| { |
| // reservePLTGOT |
| if (pFormat.hasGOT()) |
| reserveOne(llvm::ELF::DT_PLTGOT); |
| |
| reserveOne(MIPS_RLD_VERSION); |
| reserveOne(MIPS_FLAGS); |
| reserveOne(MIPS_BASE_ADDRESS); |
| reserveOne(MIPS_LOCAL_GOTNO); |
| reserveOne(MIPS_SYMTABNO); |
| reserveOne(MIPS_GOTSYM); |
| } |
| |
| void MipsELFDynamic::applyTargetEntries(const ELFFileFormat& pFormat) |
| { |
| // applyPLTGOT |
| if (pFormat.hasGOT()) |
| applyOne(llvm::ELF::DT_PLTGOT, pFormat.getGOT().addr()); |
| |
| applyOne(MIPS_RLD_VERSION, 1); |
| applyOne(MIPS_FLAGS, 0); |
| applyOne(MIPS_BASE_ADDRESS, 0); |
| applyOne(MIPS_LOCAL_GOTNO, getLocalGotNum(pFormat)); |
| applyOne(MIPS_SYMTABNO, getSymTabNum(pFormat)); |
| applyOne(MIPS_GOTSYM, getGotSym(pFormat)); |
| } |
| |
| 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().getTotalNum() + |
| m_pParent.getGOT().getLocalNum(); |
| } |
| |
| size_t MipsELFDynamic::getLocalGotNum(const ELFFileFormat& pFormat) const |
| { |
| if (!pFormat.hasGOT()) |
| return 0; |
| |
| return m_pParent.getGOT().getLocalNum(); |
| } |