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