1 //===- Stub.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/Fragment/Stub.h"
10
11 #include "mcld/IRBuilder.h"
12 #include "mcld/Fragment/Relocation.h"
13 #include "mcld/LD/BranchIsland.h"
14 #include "mcld/LD/ResolveInfo.h"
15
16 #include <cassert>
17
18 namespace mcld {
19
Stub()20 Stub::Stub() : Fragment(Fragment::Stub), m_pSymInfo(NULL) {
21 }
22
~Stub()23 Stub::~Stub() {
24 for (fixup_iterator fixup = fixup_begin(); fixup != fixup_end(); ++fixup)
25 delete (*fixup);
26 }
27
setSymInfo(ResolveInfo * pSymInfo)28 void Stub::setSymInfo(ResolveInfo* pSymInfo) {
29 m_pSymInfo = pSymInfo;
30 }
31
applyFixup(Relocation & pSrcReloc,IRBuilder & pBuilder,BranchIsland & pIsland)32 void Stub::applyFixup(Relocation& pSrcReloc,
33 IRBuilder& pBuilder,
34 BranchIsland& pIsland) {
35 // build a name for stub symbol
36 std::string sym_name("__");
37 sym_name.append(pSrcReloc.symInfo()->name())
38 .append("_")
39 .append(name())
40 .append("@")
41 .append(pIsland.name());
42
43 // create LDSymbol for the stub
44 LDSymbol* symbol =
45 pBuilder.AddSymbol<IRBuilder::Force, IRBuilder::Unresolve>(
46 sym_name,
47 ResolveInfo::Function,
48 ResolveInfo::Define,
49 ResolveInfo::Local,
50 size(),
51 initSymValue(),
52 FragmentRef::Create(*this, initSymValue()),
53 ResolveInfo::Default);
54 setSymInfo(symbol->resolveInfo());
55
56 // add relocations of this stub (i.e., set the branch target of the stub)
57 for (fixup_iterator it = fixup_begin(), ie = fixup_end(); it != ie; ++it) {
58 Relocation* reloc =
59 Relocation::Create((*it)->type(),
60 *(FragmentRef::Create(*this, (*it)->offset())),
61 (*it)->addend());
62 reloc->setSymInfo(pSrcReloc.symInfo());
63 pIsland.addRelocation(*reloc);
64 }
65 }
66
applyFixup(FragmentRef & pSrcFragRef,IRBuilder & pBuilder,BranchIsland & pIsland)67 void Stub::applyFixup(FragmentRef& pSrcFragRef,
68 IRBuilder& pBuilder,
69 BranchIsland& pIsland) {
70 // If applying fixups is based on the source FragmentRef, each target stub
71 // probably should override this function.
72 assert(0 && "target stub should override this function");
73 }
74
addFixup(DWord pOffset,SWord pAddend,Type pType)75 void Stub::addFixup(DWord pOffset, SWord pAddend, Type pType) {
76 assert(pOffset < size());
77 m_FixupList.push_back(new Fixup(pOffset, pAddend, pType));
78 }
79
addFixup(const Fixup & pFixup)80 void Stub::addFixup(const Fixup& pFixup) {
81 assert(pFixup.offset() < size());
82 m_FixupList.push_back(new Fixup(pFixup));
83 }
84
85 } // namespace mcld
86