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