Home | History | Annotate | Download | only in Hexagon
      1 //===- HexagonAbsoluteStub.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 "HexagonAbsoluteStub.h"
     11 #include "HexagonLDBackend.h"
     12 
     13 #include "mcld/LD/ResolveInfo.h"
     14 #include "mcld/LD/LDSymbol.h"
     15 #include "mcld/Fragment/Relocation.h"
     16 
     17 #include <llvm/Support/ELF.h>
     18 #include <llvm/Support/MathExtras.h>
     19 
     20 namespace mcld {
     21 
     22 //===----------------------------------------------------------------------===//
     23 // HexagonAbsoluteStub
     24 //===----------------------------------------------------------------------===//
     25 
     26 const uint32_t HexagonAbsoluteStub::TEMPLATE[] = {
     27     0xbffd7f1d, /* { sp = add (sp, #-8)      */
     28     0xa79dfcfe, /*   memw (sp + #-8) = r28 } */
     29     0x723cc000, /* r28.h = #HI (foo)         */
     30     0x713cc000, /* r28.l = #LO (foo)         */
     31     0xb01d411d, /* { sp = add (sp, #8)       */
     32     0x529c4000, /*   jumpr r28               */
     33     0x919dc01c  /*   r28 = memw (sp) }       */
     34 };
     35 
     36 #define FITS_IN_NBITS(D, B) \
     37   (std::abs(D) < (~(~(int64_t)0 << ((B)-1)) & -(4 * 4)))
     38 
     39 HexagonAbsoluteStub::HexagonAbsoluteStub(bool pIsOutputPIC)
     40     : Stub(), m_Name("HexagonTrampoline"), m_pData(NULL), m_Size(0x0) {
     41   m_pData = TEMPLATE;
     42   m_Size = sizeof(TEMPLATE);
     43   addFixup(8u, 0x0, llvm::ELF::R_HEX_HI16);
     44   addFixup(12u, 0x0, llvm::ELF::R_HEX_LO16);
     45 }
     46 
     47 /// for doClone
     48 HexagonAbsoluteStub::HexagonAbsoluteStub(const uint32_t* pData,
     49                                          size_t pSize,
     50                                          const_fixup_iterator pBegin,
     51                                          const_fixup_iterator pEnd)
     52     : Stub(), m_Name("AbsVeneer"), m_pData(pData), m_Size(pSize) {
     53   for (const_fixup_iterator it = pBegin, ie = pEnd; it != ie; ++it)
     54     addFixup(**it);
     55 }
     56 
     57 HexagonAbsoluteStub::~HexagonAbsoluteStub() {
     58 }
     59 
     60 bool HexagonAbsoluteStub::isMyDuty(const class Relocation& pReloc,
     61                                    uint64_t pSource,
     62                                    uint64_t pTargetSymValue) const {
     63   int nbits = 0;
     64   switch (pReloc.type()) {
     65     case llvm::ELF::R_HEX_B22_PCREL:
     66       nbits = 24;
     67       break;
     68     case llvm::ELF::R_HEX_B15_PCREL:
     69       nbits = 17;
     70       break;
     71     case llvm::ELF::R_HEX_B7_PCREL:
     72       nbits = 9;
     73       break;
     74     case llvm::ELF::R_HEX_B13_PCREL:
     75       nbits = 15;
     76       break;
     77     case llvm::ELF::R_HEX_B9_PCREL:
     78       nbits = 17;
     79       break;
     80     default:
     81       return false;
     82   }
     83 
     84   int64_t offset = pTargetSymValue - pSource;
     85   // if offset is going to fit in nbits then we dont
     86   // need a stub to be created
     87   if (FITS_IN_NBITS(offset, nbits))
     88     return false;
     89   return true;
     90 }
     91 
     92 const std::string& HexagonAbsoluteStub::name() const {
     93   return m_Name;
     94 }
     95 
     96 const uint8_t* HexagonAbsoluteStub::getContent() const {
     97   return reinterpret_cast<const uint8_t*>(m_pData);
     98 }
     99 
    100 size_t HexagonAbsoluteStub::size() const {
    101   return m_Size;
    102 }
    103 
    104 size_t HexagonAbsoluteStub::alignment() const {
    105   return 4u;
    106 }
    107 
    108 Stub* HexagonAbsoluteStub::doClone() {
    109   return new HexagonAbsoluteStub(m_pData, m_Size, fixup_begin(), fixup_end());
    110 }
    111 
    112 }  // namespace mcld
    113