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