1//===- MipsLA25Stub.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#include <mcld/LD/ResolveInfo.h> 10#include "MipsLA25Stub.h" 11#include "MipsLDBackend.h" 12 13namespace { 14 15const uint32_t STUB[] = { 16 0x3c190000, // lui $25,%hi(func) 17 0x08000000, // j func 18 0x27390000, // add $25,$25,%lo(func) 19 0x00000000 // nop 20}; 21 22enum { 23 // Fake relocations for patching LA25 stubs. 24 R_MIPS_LA25_LUI = 200, 25 R_MIPS_LA25_J = 201, 26 R_MIPS_LA25_ADD = 202 27}; 28 29} 30 31namespace mcld { 32 33//===----------------------------------------------------------------------===// 34// MipsLA25Stub 35//===----------------------------------------------------------------------===// 36 37MipsLA25Stub::MipsLA25Stub(const MipsGNULDBackend& pTarget) 38 : m_Target(pTarget), 39 m_Name("MipsLA25_Prototype"), 40 m_pData(STUB), 41 m_Size(sizeof(STUB)) 42{ 43 addFixup(0, 0x0, R_MIPS_LA25_LUI); 44 addFixup(4, 0x0, R_MIPS_LA25_J); 45 addFixup(8, 0x0, R_MIPS_LA25_ADD); 46} 47 48MipsLA25Stub::MipsLA25Stub(const MipsGNULDBackend& pTarget, 49 const uint32_t* pData, 50 size_t pSize, 51 const_fixup_iterator pBegin, 52 const_fixup_iterator pEnd) 53 : m_Target(pTarget), 54 m_Name("pic"), 55 m_pData(pData), 56 m_Size(pSize) 57{ 58 for (const_fixup_iterator it = pBegin, ie = pEnd; it != ie; ++it) 59 addFixup(**it); 60} 61 62bool MipsLA25Stub::isMyDuty(const Relocation& pReloc, 63 uint64_t pSource, 64 uint64_t pTargetSymValue) const 65{ 66 if (llvm::ELF::R_MIPS_26 != pReloc.type()) 67 return false; 68 69 const ResolveInfo* rsym = pReloc.symInfo(); 70 71 if (!rsym->isDefine()) 72 return false; 73 74 if (rsym->isDyn() || rsym->isUndef()) 75 return false; 76 77 if (!m_Target.hasNonPICBranch(rsym)) 78 return false; 79 80 return true; 81} 82 83const std::string& MipsLA25Stub::name() const 84{ 85 return m_Name; 86} 87 88const uint8_t* MipsLA25Stub::getContent() const 89{ 90 return reinterpret_cast<const uint8_t*>(m_pData); 91} 92 93size_t MipsLA25Stub::size() const 94{ 95 return m_Size; 96} 97 98size_t MipsLA25Stub::alignment() const 99{ 100 return 4; 101} 102 103Stub* MipsLA25Stub::doClone() 104{ 105 return new MipsLA25Stub(m_Target, m_pData, m_Size, 106 fixup_begin(), fixup_end()); 107} 108 109} //end mcld namespace 110