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 } // anonymous namespace
23
24 namespace mcld {
25
26 //===----------------------------------------------------------------------===//
27 // MipsLA25Stub
28 //===----------------------------------------------------------------------===//
29
MipsLA25Stub(const MipsGNULDBackend & pTarget)30 MipsLA25Stub::MipsLA25Stub(const MipsGNULDBackend& pTarget)
31 : m_Target(pTarget),
32 m_Name("MipsLA25_Prototype"),
33 m_pData(STUB),
34 m_Size(sizeof(STUB)) {
35 addFixup(0, 0x0, llvm::ELF::R_MIPS_HI16);
36 addFixup(4, 0x0, llvm::ELF::R_MIPS_26);
37 addFixup(8, 0x0, llvm::ELF::R_MIPS_LO16);
38 }
39
MipsLA25Stub(const MipsGNULDBackend & pTarget,const uint32_t * pData,size_t pSize,const_fixup_iterator pBegin,const_fixup_iterator pEnd)40 MipsLA25Stub::MipsLA25Stub(const MipsGNULDBackend& pTarget,
41 const uint32_t* pData,
42 size_t pSize,
43 const_fixup_iterator pBegin,
44 const_fixup_iterator pEnd)
45 : m_Target(pTarget), m_Name("pic"), m_pData(pData), m_Size(pSize) {
46 for (const_fixup_iterator it = pBegin, ie = pEnd; it != ie; ++it)
47 addFixup(**it);
48 }
49
isMyDuty(const Relocation & pReloc,uint64_t pSource,uint64_t pTargetSymValue) const50 bool MipsLA25Stub::isMyDuty(const Relocation& pReloc,
51 uint64_t pSource,
52 uint64_t pTargetSymValue) const {
53 if (llvm::ELF::R_MIPS_26 != pReloc.type())
54 return false;
55
56 const ResolveInfo* rsym = pReloc.symInfo();
57
58 if (!rsym->isDefine())
59 return false;
60
61 if (rsym->isDyn() || rsym->isUndef())
62 return false;
63
64 if (!m_Target.hasNonPICBranch(rsym))
65 return false;
66
67 return true;
68 }
69
name() const70 const std::string& MipsLA25Stub::name() const {
71 return m_Name;
72 }
73
getContent() const74 const uint8_t* MipsLA25Stub::getContent() const {
75 return reinterpret_cast<const uint8_t*>(m_pData);
76 }
77
size() const78 size_t MipsLA25Stub::size() const {
79 return m_Size;
80 }
81
alignment() const82 size_t MipsLA25Stub::alignment() const {
83 return 4;
84 }
85
doClone()86 Stub* MipsLA25Stub::doClone() {
87 return new MipsLA25Stub(
88 m_Target, m_pData, m_Size, fixup_begin(), fixup_end());
89 }
90
91 } // namespace mcld
92