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