Home | History | Annotate | Download | only in ARM
      1 //===- THMToTHMStub.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 
     10 #include "THMToTHMStub.h"
     11 #include "ARMLDBackend.h"
     12 
     13 #include <llvm/Support/ELF.h>
     14 #include <mcld/LD/ResolveInfo.h>
     15 #include <mcld/LD/LDSymbol.h>
     16 #include <mcld/Fragment/Relocation.h>
     17 
     18 using namespace mcld;
     19 
     20 //===----------------------------------------------------------------------===//
     21 // THMToTHMStub
     22 //===----------------------------------------------------------------------===//
     23 const uint32_t THMToTHMStub::PIC_TEMPLATE[] = {
     24   0x46c04778, // bx    pc ... nop
     25   0xe59fc004, // ldr   r12, [pc, #4]
     26   0xe08fc00c, // add   ip, pc, ip
     27   0xe12fff1c, // bx    ip
     28   0x0         // dcd   R_ARM_REL32(X)
     29 };
     30 
     31 const uint32_t THMToTHMStub::TEMPLATE[] = {
     32   0x46c04778, // bx    pc ... nop
     33   0xe59fc000, // ldr   ip, [pc, #0]
     34   0xe12fff1c, // bx    ip
     35   0x0         // dcd   R_ARM_ABS32(X)
     36 };
     37 
     38 THMToTHMStub::THMToTHMStub(bool pIsOutputPIC)
     39  : Stub(), m_Name("T2T_prototype"), m_pData(NULL), m_Size(0x0)
     40 {
     41   if (pIsOutputPIC) {
     42     m_pData = PIC_TEMPLATE;
     43     m_Size = sizeof(PIC_TEMPLATE);
     44     addFixup(16u, 0x0, llvm::ELF::R_ARM_REL32);
     45   }
     46   else {
     47     m_pData = TEMPLATE;
     48     m_Size = sizeof(TEMPLATE);
     49     addFixup(12u, 0x0, llvm::ELF::R_ARM_ABS32);
     50   }
     51 }
     52 
     53 /// for doClone
     54 THMToTHMStub::THMToTHMStub(const uint32_t* pData,
     55                            size_t pSize,
     56                            const_fixup_iterator pBegin,
     57                            const_fixup_iterator pEnd)
     58  : Stub(), m_Name("T2T_veneer"), m_pData(pData), m_Size(pSize)
     59 {
     60   for (const_fixup_iterator it = pBegin, ie = pEnd; it != ie; ++it)
     61     addFixup(**it);
     62 }
     63 
     64 THMToTHMStub::~THMToTHMStub()
     65 {
     66 }
     67 
     68 bool THMToTHMStub::isMyDuty(const class Relocation& pReloc,
     69                             uint64_t pSource,
     70                             uint64_t pTargetSymValue) const
     71 {
     72   bool result = false;
     73   // Check if the branch target is THUMB
     74   if ((pTargetSymValue & 0x1) != 0x0) {
     75     switch (pReloc.type()) {
     76       case llvm::ELF::R_ARM_THM_CALL:
     77       case llvm::ELF::R_ARM_THM_JUMP24: {
     78         // Check if the branch target is too far
     79         uint64_t dest = pTargetSymValue + pReloc.addend() + 4u;
     80         int64_t branch_offset = static_cast<int64_t>(dest) - pSource;
     81         if ((branch_offset > ARMGNULDBackend::THM_MAX_FWD_BRANCH_OFFSET) ||
     82             (branch_offset < ARMGNULDBackend::THM_MAX_BWD_BRANCH_OFFSET))
     83           result =  true;
     84         break;
     85       }
     86       default:
     87         break;
     88     }
     89   }
     90   return result;
     91 }
     92 
     93 const std::string& THMToTHMStub::name() const
     94 {
     95   return m_Name;
     96 }
     97 
     98 const uint8_t* THMToTHMStub::getContent() const
     99 {
    100   return reinterpret_cast<const uint8_t*>(m_pData);
    101 }
    102 
    103 size_t THMToTHMStub::size() const
    104 {
    105   return m_Size;
    106 }
    107 
    108 size_t THMToTHMStub::alignment() const
    109 {
    110   return 4u;
    111 }
    112 
    113 uint64_t THMToTHMStub::initSymValue() const
    114 {
    115   return 0x1;
    116 }
    117 
    118 Stub* THMToTHMStub::doClone()
    119 {
    120   return new THMToTHMStub(m_pData, m_Size, fixup_begin(), fixup_end());
    121 }
    122 
    123