blob: 9bcf85fec939183db591f193c60012344782cbb4 [file] [log] [blame]
Stephen Hinesf33f6de2014-02-14 18:00:16 -08001//===- 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//===----------------------------------------------------------------------===//
Stephen Hines37b74a32014-11-26 18:48:20 -08009#include "mcld/LD/ResolveInfo.h"
Stephen Hinesf33f6de2014-02-14 18:00:16 -080010#include "MipsLA25Stub.h"
11#include "MipsLDBackend.h"
12
13namespace {
14
15const uint32_t STUB[] = {
Stephen Hines37b74a32014-11-26 18:48:20 -080016 0x3c190000, // lui $25,%hi(func)
17 0x08000000, // j func
18 0x27390000, // add $25,$25,%lo(func)
19 0x00000000 // nop
Stephen Hinesf33f6de2014-02-14 18:00:16 -080020};
21
Stephen Hines37b74a32014-11-26 18:48:20 -080022} // anonymous namespace
Stephen Hinesf33f6de2014-02-14 18:00:16 -080023
24namespace mcld {
25
26//===----------------------------------------------------------------------===//
27// MipsLA25Stub
28//===----------------------------------------------------------------------===//
29
30MipsLA25Stub::MipsLA25Stub(const MipsGNULDBackend& pTarget)
Stephen Hines37b74a32014-11-26 18:48:20 -080031 : m_Target(pTarget),
32 m_Name("MipsLA25_Prototype"),
33 m_pData(STUB),
34 m_Size(sizeof(STUB)) {
Stephen Hinescfcb2242016-03-08 00:18:09 -080035 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);
Stephen Hinesf33f6de2014-02-14 18:00:16 -080038}
39
40MipsLA25Stub::MipsLA25Stub(const MipsGNULDBackend& pTarget,
41 const uint32_t* pData,
42 size_t pSize,
43 const_fixup_iterator pBegin,
44 const_fixup_iterator pEnd)
Stephen Hines37b74a32014-11-26 18:48:20 -080045 : m_Target(pTarget), m_Name("pic"), m_pData(pData), m_Size(pSize) {
Stephen Hinesf33f6de2014-02-14 18:00:16 -080046 for (const_fixup_iterator it = pBegin, ie = pEnd; it != ie; ++it)
47 addFixup(**it);
48}
49
50bool MipsLA25Stub::isMyDuty(const Relocation& pReloc,
51 uint64_t pSource,
Stephen Hines37b74a32014-11-26 18:48:20 -080052 uint64_t pTargetSymValue) const {
Stephen Hinesf33f6de2014-02-14 18:00:16 -080053 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
Stephen Hines37b74a32014-11-26 18:48:20 -080070const std::string& MipsLA25Stub::name() const {
Stephen Hinesf33f6de2014-02-14 18:00:16 -080071 return m_Name;
72}
73
Stephen Hines37b74a32014-11-26 18:48:20 -080074const uint8_t* MipsLA25Stub::getContent() const {
Stephen Hinesf33f6de2014-02-14 18:00:16 -080075 return reinterpret_cast<const uint8_t*>(m_pData);
76}
77
Stephen Hines37b74a32014-11-26 18:48:20 -080078size_t MipsLA25Stub::size() const {
Stephen Hinesf33f6de2014-02-14 18:00:16 -080079 return m_Size;
80}
81
Stephen Hines37b74a32014-11-26 18:48:20 -080082size_t MipsLA25Stub::alignment() const {
Stephen Hinesf33f6de2014-02-14 18:00:16 -080083 return 4;
84}
85
Stephen Hines37b74a32014-11-26 18:48:20 -080086Stub* MipsLA25Stub::doClone() {
87 return new MipsLA25Stub(
88 m_Target, m_pData, m_Size, fixup_begin(), fixup_end());
Stephen Hinesf33f6de2014-02-14 18:00:16 -080089}
90
Stephen Hines37b74a32014-11-26 18:48:20 -080091} // namespace mcld