137b74a387bb3993387029859c2d9d051c41c724eStephen 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 1337b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/LD/ResolveInfo.h" 1437b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/LD/LDSymbol.h" 1537b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/Fragment/Relocation.h" 1637b74a387bb3993387029859c2d9d051c41c724eStephen Hines 17f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines#include <llvm/Support/ELF.h> 18533eae20118036f425f27bf0536ef0ccbb090b65Stephen Hines#include <llvm/Support/MathExtras.h> 19f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 2037b74a387bb3993387029859c2d9d051c41c724eStephen Hinesnamespace mcld { 21f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 22f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines//===----------------------------------------------------------------------===// 23f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines// HexagonAbsoluteStub 24f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines//===----------------------------------------------------------------------===// 25f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 26f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hinesconst uint32_t HexagonAbsoluteStub::TEMPLATE[] = { 2737b74a387bb3993387029859c2d9d051c41c724eStephen Hines 0xbffd7f1d, /* { sp = add (sp, #-8) */ 2837b74a387bb3993387029859c2d9d051c41c724eStephen Hines 0xa79dfcfe, /* memw (sp + #-8) = r28 } */ 2937b74a387bb3993387029859c2d9d051c41c724eStephen Hines 0x723cc000, /* r28.h = #HI (foo) */ 3037b74a387bb3993387029859c2d9d051c41c724eStephen Hines 0x713cc000, /* r28.l = #LO (foo) */ 3137b74a387bb3993387029859c2d9d051c41c724eStephen Hines 0xb01d411d, /* { sp = add (sp, #8) */ 3237b74a387bb3993387029859c2d9d051c41c724eStephen Hines 0x529c4000, /* jumpr r28 */ 3337b74a387bb3993387029859c2d9d051c41c724eStephen Hines 0x919dc01c /* r28 = memw (sp) } */ 34f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines}; 35f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 36f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines#define FITS_IN_NBITS(D, B) \ 3704c59f3b00def22b7c75f5a490c323cec58a7c71Stephen Hines (std::abs(D) < (~(~(int64_t)0 << ((B)-1)) & -(4 * 4))) 38f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 39f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen HinesHexagonAbsoluteStub::HexagonAbsoluteStub(bool pIsOutputPIC) 4037b74a387bb3993387029859c2d9d051c41c724eStephen Hines : Stub(), m_Name("HexagonTrampoline"), m_pData(NULL), m_Size(0x0) { 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) 5237b74a387bb3993387029859c2d9d051c41c724eStephen Hines : Stub(), m_Name("AbsVeneer"), m_pData(pData), m_Size(pSize) { 53f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines for (const_fixup_iterator it = pBegin, ie = pEnd; it != ie; ++it) 54f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines addFixup(**it); 55f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines} 56f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 5737b74a387bb3993387029859c2d9d051c41c724eStephen HinesHexagonAbsoluteStub::~HexagonAbsoluteStub() { 58f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines} 59f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 60f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hinesbool HexagonAbsoluteStub::isMyDuty(const class Relocation& pReloc, 61533eae20118036f425f27bf0536ef0ccbb090b65Stephen Hines uint64_t pSource, 6237b74a387bb3993387029859c2d9d051c41c724eStephen Hines uint64_t pTargetSymValue) const { 63f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines int nbits = 0; 64f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines switch (pReloc.type()) { 65f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines case llvm::ELF::R_HEX_B22_PCREL: 66f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines nbits = 24; 67f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines break; 68f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines case llvm::ELF::R_HEX_B15_PCREL: 69f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines nbits = 17; 70f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines break; 71f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines case llvm::ELF::R_HEX_B7_PCREL: 72f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines nbits = 9; 73f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines break; 74f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines case llvm::ELF::R_HEX_B13_PCREL: 75f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines nbits = 15; 76f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines break; 77f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines case llvm::ELF::R_HEX_B9_PCREL: 78f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines nbits = 17; 79f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines break; 80f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines default: 81f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines return false; 82f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines } 83f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 84f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines int64_t offset = pTargetSymValue - pSource; 85f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines // if offset is going to fit in nbits then we dont 86f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines // need a stub to be created 87f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines if (FITS_IN_NBITS(offset, nbits)) 88f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines return false; 89f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines return true; 90f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines} 91f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 9237b74a387bb3993387029859c2d9d051c41c724eStephen Hinesconst std::string& HexagonAbsoluteStub::name() const { 93f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines return m_Name; 94f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines} 95f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 9637b74a387bb3993387029859c2d9d051c41c724eStephen Hinesconst uint8_t* HexagonAbsoluteStub::getContent() const { 97f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines return reinterpret_cast<const uint8_t*>(m_pData); 98f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines} 99f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 10037b74a387bb3993387029859c2d9d051c41c724eStephen Hinessize_t HexagonAbsoluteStub::size() const { 101f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines return m_Size; 102f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines} 103f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 10437b74a387bb3993387029859c2d9d051c41c724eStephen Hinessize_t HexagonAbsoluteStub::alignment() const { 105f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines return 4u; 106f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines} 107f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 10837b74a387bb3993387029859c2d9d051c41c724eStephen HinesStub* HexagonAbsoluteStub::doClone() { 109f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines return new HexagonAbsoluteStub(m_pData, m_Size, fixup_begin(), fixup_end()); 110f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines} 11137b74a387bb3993387029859c2d9d051c41c724eStephen Hines 11237b74a387bb3993387029859c2d9d051c41c724eStephen Hines} // namespace mcld 113