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 20 Stub::Stub() : Fragment(Fragment::Stub), m_pSymInfo(NULL) { 21 } 22 23 Stub::~Stub() { 24 for (fixup_iterator fixup = fixup_begin(); fixup != fixup_end(); ++fixup) 25 delete (*fixup); 26 } 27 28 void Stub::setSymInfo(ResolveInfo* pSymInfo) { 29 m_pSymInfo = pSymInfo; 30 } 31 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 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 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 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