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