HexagonAbsoluteStub.cpp revision f7ac0f19a1c8d0ad14bcf6456ce368b830fea886
1//===- HexagonAbsoluteStub.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 "HexagonAbsoluteStub.h"
11#include "HexagonLDBackend.h"
12
13#include <llvm/Support/ELF.h>
14#include <mcld/LD/ResolveInfo.h>
15#include <mcld/LD/LDSymbol.h>
16#include <mcld/Fragment/Relocation.h>
17
18using namespace mcld;
19
20//===----------------------------------------------------------------------===//
21// HexagonAbsoluteStub
22//===----------------------------------------------------------------------===//
23
24const uint32_t HexagonAbsoluteStub::TEMPLATE[] = {
25  0xbffd7f1d, /* { sp = add (sp, #-8)      */
26  0xa79dfcfe, /*   memw (sp + #-8) = r28 } */
27  0x723cc000, /* r28.h = #HI (foo)         */
28  0x713cc000, /* r28.l = #LO (foo)         */
29  0xb01d411d, /* { sp = add (sp, #8)       */
30  0x529c4000, /*   jumpr r28               */
31  0x919dc01c  /*   r28 = memw (sp) }       */
32};
33
34#define FITS_IN_NBITS(D, B) \
35    ((int64_t) abs (D) < (~(~(int64_t) 0 << ((B) - 1)) & -(4 * 4)))
36
37HexagonAbsoluteStub::HexagonAbsoluteStub(bool pIsOutputPIC)
38 : Stub(), m_Name("HexagonTrampoline"), m_pData(NULL), m_Size(0x0)
39{
40  m_pData = TEMPLATE;
41  m_Size = sizeof(TEMPLATE);
42  addFixup(8u, 0x0, llvm::ELF::R_HEX_HI16);
43  addFixup(12u, 0x0, llvm::ELF::R_HEX_LO16);
44}
45
46/// for doClone
47HexagonAbsoluteStub::HexagonAbsoluteStub(const uint32_t* pData,
48                           size_t pSize,
49                           const_fixup_iterator pBegin,
50                           const_fixup_iterator pEnd)
51 : Stub(), m_Name("AbsVeneer"), m_pData(pData), m_Size(pSize)
52{
53  for (const_fixup_iterator it = pBegin, ie = pEnd; it != ie; ++it)
54    addFixup(**it);
55}
56
57HexagonAbsoluteStub::~HexagonAbsoluteStub()
58{
59}
60
61bool HexagonAbsoluteStub::isMyDuty(const class Relocation& pReloc,
62                            uint64_t pSource,
63                            uint64_t pTargetSymValue) const
64{
65  int nbits = 0;
66  switch (pReloc.type()) {
67    case llvm::ELF::R_HEX_B22_PCREL:
68      nbits = 24;
69      break;
70    case llvm::ELF::R_HEX_B15_PCREL:
71      nbits = 17;
72      break;
73    case llvm::ELF::R_HEX_B7_PCREL:
74      nbits = 9;
75      break;
76    case llvm::ELF::R_HEX_B13_PCREL:
77      nbits = 15;
78      break;
79    case llvm::ELF::R_HEX_B9_PCREL:
80      nbits = 17;
81      break;
82    default:
83      return false;
84  }
85
86  int64_t offset = pTargetSymValue - pSource;
87  // if offset is going to fit in nbits then we dont
88  // need a stub to be created
89  if (FITS_IN_NBITS(offset, nbits))
90    return false;
91  return true;
92}
93
94const std::string& HexagonAbsoluteStub::name() const
95{
96  return m_Name;
97}
98
99const uint8_t* HexagonAbsoluteStub::getContent() const
100{
101  return reinterpret_cast<const uint8_t*>(m_pData);
102}
103
104size_t HexagonAbsoluteStub::size() const
105{
106  return m_Size;
107}
108
109size_t HexagonAbsoluteStub::alignment() const
110{
111  return 4u;
112}
113
114Stub* HexagonAbsoluteStub::doClone()
115{
116  return new HexagonAbsoluteStub(m_pData, m_Size, fixup_begin(), fixup_end());
117}
118