Home | History | Annotate | Download | only in Mips
      1 //===- MipsLA25Stub.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/LD/ResolveInfo.h"
     10 #include "MipsLA25Stub.h"
     11 #include "MipsLDBackend.h"
     12 
     13 namespace {
     14 
     15 const uint32_t STUB[] = {
     16     0x3c190000,  // lui $25,%hi(func)
     17     0x08000000,  // j func
     18     0x27390000,  // add $25,$25,%lo(func)
     19     0x00000000   // nop
     20 };
     21 
     22 }  // anonymous namespace
     23 
     24 namespace mcld {
     25 
     26 //===----------------------------------------------------------------------===//
     27 // MipsLA25Stub
     28 //===----------------------------------------------------------------------===//
     29 
     30 MipsLA25Stub::MipsLA25Stub(const MipsGNULDBackend& pTarget)
     31     : m_Target(pTarget),
     32       m_Name("MipsLA25_Prototype"),
     33       m_pData(STUB),
     34       m_Size(sizeof(STUB)) {
     35   addFixup(0, 0x0, llvm::ELF::R_MIPS_HI16);
     36   addFixup(4, 0x0, llvm::ELF::R_MIPS_26);
     37   addFixup(8, 0x0, llvm::ELF::R_MIPS_LO16);
     38 }
     39 
     40 MipsLA25Stub::MipsLA25Stub(const MipsGNULDBackend& pTarget,
     41                            const uint32_t* pData,
     42                            size_t pSize,
     43                            const_fixup_iterator pBegin,
     44                            const_fixup_iterator pEnd)
     45     : m_Target(pTarget), m_Name("pic"), m_pData(pData), m_Size(pSize) {
     46   for (const_fixup_iterator it = pBegin, ie = pEnd; it != ie; ++it)
     47     addFixup(**it);
     48 }
     49 
     50 bool MipsLA25Stub::isMyDuty(const Relocation& pReloc,
     51                             uint64_t pSource,
     52                             uint64_t pTargetSymValue) const {
     53   if (llvm::ELF::R_MIPS_26 != pReloc.type())
     54     return false;
     55 
     56   const ResolveInfo* rsym = pReloc.symInfo();
     57 
     58   if (!rsym->isDefine())
     59     return false;
     60 
     61   if (rsym->isDyn() || rsym->isUndef())
     62     return false;
     63 
     64   if (!m_Target.hasNonPICBranch(rsym))
     65     return false;
     66 
     67   return true;
     68 }
     69 
     70 const std::string& MipsLA25Stub::name() const {
     71   return m_Name;
     72 }
     73 
     74 const uint8_t* MipsLA25Stub::getContent() const {
     75   return reinterpret_cast<const uint8_t*>(m_pData);
     76 }
     77 
     78 size_t MipsLA25Stub::size() const {
     79   return m_Size;
     80 }
     81 
     82 size_t MipsLA25Stub::alignment() const {
     83   return 4;
     84 }
     85 
     86 Stub* MipsLA25Stub::doClone() {
     87   return new MipsLA25Stub(
     88       m_Target, m_pData, m_Size, fixup_begin(), fixup_end());
     89 }
     90 
     91 }  // namespace mcld
     92