MipsLA25Stub.cpp revision 37b74a387bb3993387029859c2d9d051c41c724e
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} // anonymous namespace 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 addFixup(0, 0x0, R_MIPS_LA25_LUI); 43 addFixup(4, 0x0, R_MIPS_LA25_J); 44 addFixup(8, 0x0, R_MIPS_LA25_ADD); 45} 46 47MipsLA25Stub::MipsLA25Stub(const MipsGNULDBackend& pTarget, 48 const uint32_t* pData, 49 size_t pSize, 50 const_fixup_iterator pBegin, 51 const_fixup_iterator pEnd) 52 : m_Target(pTarget), m_Name("pic"), m_pData(pData), m_Size(pSize) { 53 for (const_fixup_iterator it = pBegin, ie = pEnd; it != ie; ++it) 54 addFixup(**it); 55} 56 57bool MipsLA25Stub::isMyDuty(const Relocation& pReloc, 58 uint64_t pSource, 59 uint64_t pTargetSymValue) const { 60 if (llvm::ELF::R_MIPS_26 != pReloc.type()) 61 return false; 62 63 const ResolveInfo* rsym = pReloc.symInfo(); 64 65 if (!rsym->isDefine()) 66 return false; 67 68 if (rsym->isDyn() || rsym->isUndef()) 69 return false; 70 71 if (!m_Target.hasNonPICBranch(rsym)) 72 return false; 73 74 return true; 75} 76 77const std::string& MipsLA25Stub::name() const { 78 return m_Name; 79} 80 81const uint8_t* MipsLA25Stub::getContent() const { 82 return reinterpret_cast<const uint8_t*>(m_pData); 83} 84 85size_t MipsLA25Stub::size() const { 86 return m_Size; 87} 88 89size_t MipsLA25Stub::alignment() const { 90 return 4; 91} 92 93Stub* MipsLA25Stub::doClone() { 94 return new MipsLA25Stub( 95 m_Target, m_pData, m_Size, fixup_begin(), fixup_end()); 96} 97 98} // namespace mcld 99