15460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao//===- MipsELFDynamic.cpp -------------------------------------------------===// 25460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao// 35460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao// The MCLinker Project 45460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao// 55460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao// This file is distributed under the University of Illinois Open Source 65460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao// License. See LICENSE.TXT for details. 75460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao// 85460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao//===----------------------------------------------------------------------===// 937b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/LinkerConfig.h" 1037b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/LD/ELFFileFormat.h" 1137b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/LD/ELFSegment.h" 1237b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/LD/ELFSegmentFactory.h" 1337b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/Target/GNULDBackend.h" 14f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines#include "MipsELFDynamic.h" 15f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines#include "MipsLDBackend.h" 165460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 1737b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include <llvm/Support/ELF.h> 1837b74a387bb3993387029859c2d9d051c41c724eStephen Hines 1937b74a387bb3993387029859c2d9d051c41c724eStephen Hinesnamespace mcld { 205460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 21d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei LiaoMipsELFDynamic::MipsELFDynamic(const MipsGNULDBackend& pParent, 22d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao const LinkerConfig& pConfig) 2337b74a387bb3993387029859c2d9d051c41c724eStephen Hines : ELFDynamic(pParent, pConfig), m_pParent(pParent), m_pConfig(pConfig) { 245460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 255460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 2637b74a387bb3993387029859c2d9d051c41c724eStephen Hinesvoid MipsELFDynamic::reserveTargetEntries(const ELFFileFormat& pFormat) { 275460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if (pFormat.hasGOT()) 285460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao reserveOne(llvm::ELF::DT_PLTGOT); 295460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 30f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines reserveOne(llvm::ELF::DT_MIPS_RLD_VERSION); 31f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines reserveOne(llvm::ELF::DT_MIPS_FLAGS); 32f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines reserveOne(llvm::ELF::DT_MIPS_BASE_ADDRESS); 33f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines reserveOne(llvm::ELF::DT_MIPS_LOCAL_GOTNO); 34f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines reserveOne(llvm::ELF::DT_MIPS_SYMTABNO); 35f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines reserveOne(llvm::ELF::DT_MIPS_GOTSYM); 36f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines 37f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines if (pFormat.hasGOTPLT()) 38f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines reserveOne(llvm::ELF::DT_MIPS_PLTGOT); 395460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 405460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 4137b74a387bb3993387029859c2d9d051c41c724eStephen Hinesvoid MipsELFDynamic::applyTargetEntries(const ELFFileFormat& pFormat) { 425460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if (pFormat.hasGOT()) 435460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao applyOne(llvm::ELF::DT_PLTGOT, pFormat.getGOT().addr()); 445460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 45f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines applyOne(llvm::ELF::DT_MIPS_RLD_VERSION, 1); 46f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines applyOne(llvm::ELF::DT_MIPS_FLAGS, llvm::ELF::RHF_NOTPOT); 47f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines applyOne(llvm::ELF::DT_MIPS_BASE_ADDRESS, getBaseAddress()); 48f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines applyOne(llvm::ELF::DT_MIPS_LOCAL_GOTNO, getLocalGotNum(pFormat)); 49f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines applyOne(llvm::ELF::DT_MIPS_SYMTABNO, getSymTabNum(pFormat)); 50f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines applyOne(llvm::ELF::DT_MIPS_GOTSYM, getGotSym(pFormat)); 51f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines 52f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines if (pFormat.hasGOTPLT()) 53f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines applyOne(llvm::ELF::DT_MIPS_PLTGOT, pFormat.getGOTPLT().addr()); 545460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 555460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 5637b74a387bb3993387029859c2d9d051c41c724eStephen Hinessize_t MipsELFDynamic::getSymTabNum(const ELFFileFormat& pFormat) const { 575460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if (!pFormat.hasDynSymTab()) 585460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return 0; 595460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 605460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao const LDSection& dynsym = pFormat.getDynSymTab(); 615460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return dynsym.size() / symbolSize(); 625460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 635460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 6437b74a387bb3993387029859c2d9d051c41c724eStephen Hinessize_t MipsELFDynamic::getGotSym(const ELFFileFormat& pFormat) const { 655460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if (!pFormat.hasGOT()) 665460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return 0; 675460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 68f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines return getSymTabNum(pFormat) - m_pParent.getGOT().getGlobalNum(); 695460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 705460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 7137b74a387bb3993387029859c2d9d051c41c724eStephen Hinessize_t MipsELFDynamic::getLocalGotNum(const ELFFileFormat& pFormat) const { 725460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if (!pFormat.hasGOT()) 735460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return 0; 745460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 755460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return m_pParent.getGOT().getLocalNum(); 765460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 77f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines 7837b74a387bb3993387029859c2d9d051c41c724eStephen Hinesuint64_t MipsELFDynamic::getBaseAddress() { 79f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines if (LinkerConfig::Exec != m_pConfig.codeGenType()) 80f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines return 0; 81f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines 82f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines ELFSegmentFactory::const_iterator baseSeg = 8337b74a387bb3993387029859c2d9d051c41c724eStephen Hines m_pParent.elfSegmentTable().find(llvm::ELF::PT_LOAD, 0x0, 0x0); 84f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines 85f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines return m_pParent.elfSegmentTable().end() == baseSeg ? 0 : (*baseSeg)->vaddr(); 86f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines} 8737b74a387bb3993387029859c2d9d051c41c724eStephen Hines 8837b74a387bb3993387029859c2d9d051c41c724eStephen Hines} // namespace mcld 89