122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao//===- Stub.cpp -----------------------------------------------------------===// 222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao// 322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao// The MCLinker Project 422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao// 522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao// This file is distributed under the University of Illinois Open Source 622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao// License. See LICENSE.TXT for details. 722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao// 822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao//===----------------------------------------------------------------------===// 937b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/Fragment/Stub.h" 1022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 11b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines#include "mcld/IRBuilder.h" 12b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines#include "mcld/Fragment/Relocation.h" 13b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines#include "mcld/LD/BranchIsland.h" 14b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines#include "mcld/LD/ResolveInfo.h" 15b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines 16b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines#include <cassert> 17b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines 1837b74a387bb3993387029859c2d9d051c41c724eStephen Hinesnamespace mcld { 1922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 2037b74a387bb3993387029859c2d9d051c41c724eStephen HinesStub::Stub() : Fragment(Fragment::Stub), m_pSymInfo(NULL) { 2122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao} 2222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 2337b74a387bb3993387029859c2d9d051c41c724eStephen HinesStub::~Stub() { 2437b74a387bb3993387029859c2d9d051c41c724eStephen Hines for (fixup_iterator fixup = fixup_begin(); fixup != fixup_end(); ++fixup) 2537b74a387bb3993387029859c2d9d051c41c724eStephen Hines delete (*fixup); 2622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao} 2722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 2837b74a387bb3993387029859c2d9d051c41c724eStephen Hinesvoid Stub::setSymInfo(ResolveInfo* pSymInfo) { 2922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao m_pSymInfo = pSymInfo; 3022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao} 3122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 32b0d0eb206527b43c771933602e147bbd7b471082Stephen Hinesvoid Stub::applyFixup(Relocation& pSrcReloc, 33b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines IRBuilder& pBuilder, 34b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines BranchIsland& pIsland) { 35b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines // build a name for stub symbol 36b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines std::string sym_name("__"); 37b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines sym_name.append(pSrcReloc.symInfo()->name()) 38b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines .append("_") 39b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines .append(name()) 40b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines .append("@") 41b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines .append(pIsland.name()); 42b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines 43b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines // create LDSymbol for the stub 44b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines LDSymbol* symbol = 45b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines pBuilder.AddSymbol<IRBuilder::Force, IRBuilder::Unresolve>( 46b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines sym_name, 47b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines ResolveInfo::Function, 48b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines ResolveInfo::Define, 49b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines ResolveInfo::Local, 50b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines size(), 51b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines initSymValue(), 52b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines FragmentRef::Create(*this, initSymValue()), 53b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines ResolveInfo::Default); 54b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines setSymInfo(symbol->resolveInfo()); 55b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines 56b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines // add relocations of this stub (i.e., set the branch target of the stub) 57b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines for (fixup_iterator it = fixup_begin(), ie = fixup_end(); it != ie; ++it) { 58b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines Relocation* reloc = 59b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines Relocation::Create((*it)->type(), 60b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines *(FragmentRef::Create(*this, (*it)->offset())), 61b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines (*it)->addend()); 62b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines reloc->setSymInfo(pSrcReloc.symInfo()); 63b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines pIsland.addRelocation(*reloc); 64b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines } 65b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines} 66b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines 67b0d0eb206527b43c771933602e147bbd7b471082Stephen Hinesvoid Stub::applyFixup(FragmentRef& pSrcFragRef, 68b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines IRBuilder& pBuilder, 69b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines BranchIsland& pIsland) { 70b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines // If applying fixups is based on the source FragmentRef, each target stub 71b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines // probably should override this function. 72b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines assert(0 && "target stub should override this function"); 73b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines} 74b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines 7537b74a387bb3993387029859c2d9d051c41c724eStephen Hinesvoid Stub::addFixup(DWord pOffset, SWord pAddend, Type pType) { 7622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao assert(pOffset < size()); 7722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao m_FixupList.push_back(new Fixup(pOffset, pAddend, pType)); 7822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao} 7922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 8037b74a387bb3993387029859c2d9d051c41c724eStephen Hinesvoid Stub::addFixup(const Fixup& pFixup) { 8122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao assert(pFixup.offset() < size()); 8222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao m_FixupList.push_back(new Fixup(pFixup)); 8322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao} 8422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 8537b74a387bb3993387029859c2d9d051c41c724eStephen Hines} // namespace mcld 86