Home | History | Annotate | Download | only in Fragment
      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