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 enum {
     23   // Fake relocations for patching LA25 stubs.
     24   R_MIPS_LA25_LUI = 200,
     25   R_MIPS_LA25_J   = 201,
     26   R_MIPS_LA25_ADD = 202
     27 };
     28 
     29 }
     30 
     31 namespace mcld {
     32 
     33 //===----------------------------------------------------------------------===//
     34 // MipsLA25Stub
     35 //===----------------------------------------------------------------------===//
     36 
     37 MipsLA25Stub::MipsLA25Stub(const MipsGNULDBackend& pTarget)
     38  : m_Target(pTarget),
     39    m_Name("MipsLA25_Prototype"),
     40    m_pData(STUB),
     41    m_Size(sizeof(STUB))
     42 {
     43   addFixup(0, 0x0, R_MIPS_LA25_LUI);
     44   addFixup(4, 0x0, R_MIPS_LA25_J);
     45   addFixup(8, 0x0, R_MIPS_LA25_ADD);
     46 }
     47 
     48 MipsLA25Stub::MipsLA25Stub(const MipsGNULDBackend& pTarget,
     49                            const uint32_t* pData,
     50                            size_t pSize,
     51                            const_fixup_iterator pBegin,
     52                            const_fixup_iterator pEnd)
     53  : m_Target(pTarget),
     54    m_Name("pic"),
     55    m_pData(pData),
     56    m_Size(pSize)
     57 {
     58   for (const_fixup_iterator it = pBegin, ie = pEnd; it != ie; ++it)
     59     addFixup(**it);
     60 }
     61 
     62 bool MipsLA25Stub::isMyDuty(const Relocation& pReloc,
     63                             uint64_t pSource,
     64                             uint64_t pTargetSymValue) const
     65 {
     66   if (llvm::ELF::R_MIPS_26 != pReloc.type())
     67     return false;
     68 
     69   const ResolveInfo* rsym = pReloc.symInfo();
     70 
     71   if (!rsym->isDefine())
     72     return false;
     73 
     74   if (rsym->isDyn() || rsym->isUndef())
     75     return false;
     76 
     77   if (!m_Target.hasNonPICBranch(rsym))
     78     return false;
     79 
     80   return true;
     81 }
     82 
     83 const std::string& MipsLA25Stub::name() const
     84 {
     85   return m_Name;
     86 }
     87 
     88 const uint8_t* MipsLA25Stub::getContent() const
     89 {
     90   return reinterpret_cast<const uint8_t*>(m_pData);
     91 }
     92 
     93 size_t MipsLA25Stub::size() const
     94 {
     95   return m_Size;
     96 }
     97 
     98 size_t MipsLA25Stub::alignment() const
     99 {
    100   return 4;
    101 }
    102 
    103 Stub* MipsLA25Stub::doClone()
    104 {
    105   return new MipsLA25Stub(m_Target, m_pData, m_Size,
    106                           fixup_begin(), fixup_end());
    107 }
    108 
    109 } //end mcld namespace
    110