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
10#include <mcld/LD/ELFFileFormat.h>
11#include <mcld/Target/GNULDBackend.h>
12#include "MipsELFDynamic.h"
13#include "MipsLDBackend.h"
14
15using namespace mcld;
16
17// MIPS mandatory dynamic section entries
18enum {
19  MIPS_RLD_VERSION  = 0x70000001,
20  MIPS_FLAGS        = 0x70000005,
21  MIPS_BASE_ADDRESS = 0x70000006,
22  MIPS_LOCAL_GOTNO  = 0x7000000a,
23  MIPS_SYMTABNO     = 0x70000011,
24  MIPS_GOTSYM       = 0x70000013,
25};
26
27MipsELFDynamic::MipsELFDynamic(const MipsGNULDBackend& pParent)
28  : ELFDynamic(pParent),
29    m_pParent(pParent)
30{
31}
32
33MipsELFDynamic::~MipsELFDynamic()
34{
35}
36
37void MipsELFDynamic::reserveTargetEntries(const ELFFileFormat& pFormat)
38{
39  // reservePLTGOT
40  if (pFormat.hasGOT())
41    reserveOne(llvm::ELF::DT_PLTGOT);
42
43  reserveOne(MIPS_RLD_VERSION);
44  reserveOne(MIPS_FLAGS);
45  reserveOne(MIPS_BASE_ADDRESS);
46  reserveOne(MIPS_LOCAL_GOTNO);
47  reserveOne(MIPS_SYMTABNO);
48  reserveOne(MIPS_GOTSYM);
49}
50
51void MipsELFDynamic::applyTargetEntries(const ELFFileFormat& pFormat)
52{
53  // applyPLTGOT
54  if (pFormat.hasGOT())
55    applyOne(llvm::ELF::DT_PLTGOT, pFormat.getGOT().addr());
56
57  applyOne(MIPS_RLD_VERSION, 1);
58  applyOne(MIPS_FLAGS, 0);
59  applyOne(MIPS_BASE_ADDRESS, 0);
60  applyOne(MIPS_LOCAL_GOTNO, getLocalGotNum(pFormat));
61  applyOne(MIPS_SYMTABNO, getSymTabNum(pFormat));
62  applyOne(MIPS_GOTSYM, getGotSym(pFormat));
63}
64
65size_t MipsELFDynamic::getSymTabNum(const ELFFileFormat& pFormat) const
66{
67  if (!pFormat.hasDynSymTab())
68    return 0;
69
70  const LDSection& dynsym = pFormat.getDynSymTab();
71  return dynsym.size() / symbolSize();
72}
73
74size_t MipsELFDynamic::getGotSym(const ELFFileFormat& pFormat) const
75{
76  if (!pFormat.hasGOT())
77    return 0;
78
79  return getSymTabNum(pFormat) -
80         m_pParent.getGOT().getTotalNum() +
81         m_pParent.getGOT().getLocalNum();
82}
83
84size_t MipsELFDynamic::getLocalGotNum(const ELFFileFormat& pFormat) const
85{
86  if (!pFormat.hasGOT())
87    return 0;
88
89  return m_pParent.getGOT().getLocalNum();
90}
91