summaryrefslogtreecommitdiff
path: root/lib/Target/Hexagon/HexagonPLT.h
blob: 4acce49ebde68893af6975ad3e18965dbfda86e3 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
//===- HexagonPLT.h -------------------------------------------------------===//
//
//                     The MCLinker Project
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#ifndef TARGET_HEXAGON_HEXAGONPLT_H
#define TARGET_HEXAGON_HEXAGONPLT_H

#include "HexagonGOT.h"
#include "HexagonGOTPLT.h"
#include <mcld/Target/GOT.h>
#include <mcld/Target/PLT.h>
#include <mcld/Support/MemoryRegion.h>

namespace {

const uint8_t hexagon_plt0[] = {
 0x00, 0x40, 0x00, 0x00,  // { immext (#0)
 0x1c, 0xc0, 0x49, 0x6a,  //   r28 = add (pc, ##GOT0@PCREL) } # address of GOT0
 0x0e, 0x42, 0x9c, 0xe2,  // { r14 -= add (r28, #16)  # offset of GOTn from GOTa
 0x4f, 0x40, 0x9c, 0x91,  //   r15 = memw (r28 + #8)  # object ID at GOT2
 0x3c, 0xc0, 0x9c, 0x91,  //   r28 = memw (r28 + #4) }# dynamic link at GOT1
 0x0e, 0x42, 0x0e, 0x8c,  // { r14 = asr (r14, #2)    # index of PLTn
 0x00, 0xc0, 0x9c, 0x52,  //   jumpr r28 }            # call dynamic linker
 0x00, 0x00, 0x00, 0x00,
 0x00, 0x00, 0x00, 0x00,
 0x00, 0x00, 0x00, 0x00,
 0x00, 0x00, 0x00, 0x00,
 0x00, 0x00, 0x00, 0x00
};

const uint8_t hexagon_plt1[] = {
  0x00, 0x40, 0x00, 0x00, // { immext (#0)
  0x0e, 0xc0, 0x49, 0x6a, //   r14 = add (pc, ##GOTn@PCREL) } # address of GOTn
  0x1c, 0xc0, 0x8e, 0x91, // r28 = memw (r14)                 # contents of GOTn
  0x00, 0xc0, 0x9c, 0x52  // jumpr r28                        # call it
};

} // anonymous namespace

namespace mcld {

class GOTEntry;
class LinkerConfig;
class HexagonPLT1;

//===----------------------------------------------------------------------===//
// HexagonPLT Entry
//===----------------------------------------------------------------------===//
class HexagonPLT0 : public PLT::Entry<sizeof(hexagon_plt0)>
{
public:
  HexagonPLT0(SectionData& pParent);
};

//===----------------------------------------------------------------------===//
// HexagonPLT
//===----------------------------------------------------------------------===//
/** \class HexagonPLT
 *  \brief Hexagon Procedure Linkage Table
 */
class HexagonPLT : public PLT
{
public:
  HexagonPLT(LDSection& pSection,
             HexagonGOTPLT& pGOTPLT,
             const LinkerConfig& pConfig);
  ~HexagonPLT();

  // finalizeSectionSize - set LDSection size
  void finalizeSectionSize();

  // hasPLT1 - return if this PLT has any PLT1 entry
  bool hasPLT1() const;

  HexagonPLT1* create();

  void applyPLT0();

  void applyPLT1();

  uint64_t emit(MemoryRegion& pRegion);

  PLTEntryBase* getPLT0() const;

private:
  HexagonGOTPLT& m_GOTPLT;

  const uint8_t *m_PLT0;
  unsigned int m_PLT0Size;

  const LinkerConfig& m_Config;
};

class HexagonPLT1 : public PLT::Entry<sizeof(hexagon_plt1)>
{
public:
  HexagonPLT1(SectionData& pParent);
};

} // namespace of mcld

#endif