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