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