• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
MipsELFDynamic(const MipsGNULDBackend & pParent,const LinkerConfig & pConfig)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 
reserveTargetEntries(const ELFFileFormat & pFormat)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 
applyTargetEntries(const ELFFileFormat & pFormat)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 
getSymTabNum(const ELFFileFormat & pFormat) const60 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 
getGotSym(const ELFFileFormat & pFormat) const69 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 
getLocalGotNum(const ELFFileFormat & pFormat) const77 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 
getBaseAddress()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