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 13 namespace { 14 15 const 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 22 enum { 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 31 namespace mcld { 32 33 //===----------------------------------------------------------------------===// 34 // MipsLA25Stub 35 //===----------------------------------------------------------------------===// 36 37 MipsLA25Stub::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 48 MipsLA25Stub::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 62 bool 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 83 const std::string& MipsLA25Stub::name() const 84 { 85 return m_Name; 86 } 87 88 const uint8_t* MipsLA25Stub::getContent() const 89 { 90 return reinterpret_cast<const uint8_t*>(m_pData); 91 } 92 93 size_t MipsLA25Stub::size() const 94 { 95 return m_Size; 96 } 97 98 size_t MipsLA25Stub::alignment() const 99 { 100 return 4; 101 } 102 103 Stub* 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