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 18 using namespace mcld; 19 20 //===----------------------------------------------------------------------===// 21 // HexagonAbsoluteStub 22 //===----------------------------------------------------------------------===// 23 24 const 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 37 HexagonAbsoluteStub::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 47 HexagonAbsoluteStub::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 57 HexagonAbsoluteStub::~HexagonAbsoluteStub() 58 { 59 } 60 61 bool 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 94 const std::string& HexagonAbsoluteStub::name() const 95 { 96 return m_Name; 97 } 98 99 const uint8_t* HexagonAbsoluteStub::getContent() const 100 { 101 return reinterpret_cast<const uint8_t*>(m_pData); 102 } 103 104 size_t HexagonAbsoluteStub::size() const 105 { 106 return m_Size; 107 } 108 109 size_t HexagonAbsoluteStub::alignment() const 110 { 111 return 4u; 112 } 113 114 Stub* HexagonAbsoluteStub::doClone() 115 { 116 return new HexagonAbsoluteStub(m_pData, m_Size, fixup_begin(), fixup_end()); 117 } 118