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