THMToTHMStub.cpp revision 0dea6bc96bb52346737966839ac68644f7939f58
122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao//===- THMToTHMStub.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//===----------------------------------------------------------------------===//
922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
1022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao#include "THMToTHMStub.h"
1122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao#include "ARMLDBackend.h"
1222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
1322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao#include <llvm/Support/ELF.h>
1422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao#include <mcld/LD/ResolveInfo.h>
1522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao#include <mcld/LD/LDSymbol.h>
1622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao#include <mcld/Fragment/Relocation.h>
1722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
1822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaousing namespace mcld;
1922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
2022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao//===----------------------------------------------------------------------===//
2122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao// THMToTHMStub
2222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao//===----------------------------------------------------------------------===//
2322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaoconst uint32_t THMToTHMStub::PIC_TEMPLATE[] = {
2422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  0x46c04778, // bx    pc ... nop
2522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  0xe59fc004, // ldr   r12, [pc, #4]
2622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  0xe08fc00c, // add   ip, pc, ip
2722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  0xe12fff1c, // bx    ip
2822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  0x0         // dcd   R_ARM_REL32(X)
2922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao};
3022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
3122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaoconst uint32_t THMToTHMStub::TEMPLATE[] = {
3222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  0x46c04778, // bx    pc ... nop
3322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  0xe59fc000, // ldr   ip, [pc, #0]
3422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  0xe12fff1c, // bx    ip
3522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  0x0         // dcd   R_ARM_ABS32(X)
3622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao};
3722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
380dea6bc96bb52346737966839ac68644f7939f58Stephen HinesTHMToTHMStub::THMToTHMStub(bool pIsOutputPIC, bool pUsingThumb2)
390dea6bc96bb52346737966839ac68644f7939f58Stephen Hines : m_pData(NULL),
400dea6bc96bb52346737966839ac68644f7939f58Stephen Hines   m_Name("T2T_prototype"),
410dea6bc96bb52346737966839ac68644f7939f58Stephen Hines   m_Size(0x0),
420dea6bc96bb52346737966839ac68644f7939f58Stephen Hines   m_bUsingThumb2(pUsingThumb2)
4322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao{
4422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  if (pIsOutputPIC) {
4522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    m_pData = PIC_TEMPLATE;
4622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    m_Size = sizeof(PIC_TEMPLATE);
4722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    addFixup(16u, 0x0, llvm::ELF::R_ARM_REL32);
480dea6bc96bb52346737966839ac68644f7939f58Stephen Hines  } else {
4922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    m_pData = TEMPLATE;
5022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    m_Size = sizeof(TEMPLATE);
5122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    addFixup(12u, 0x0, llvm::ELF::R_ARM_ABS32);
5222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  }
5322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao}
5422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
5522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// for doClone
5622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei LiaoTHMToTHMStub::THMToTHMStub(const uint32_t* pData,
5722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                           size_t pSize,
5822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                           const_fixup_iterator pBegin,
590dea6bc96bb52346737966839ac68644f7939f58Stephen Hines                           const_fixup_iterator pEnd,
600dea6bc96bb52346737966839ac68644f7939f58Stephen Hines                           bool pUsingThumb2)
610dea6bc96bb52346737966839ac68644f7939f58Stephen Hines : m_pData(pData),
620dea6bc96bb52346737966839ac68644f7939f58Stephen Hines   m_Name("T2T_veneer"),
630dea6bc96bb52346737966839ac68644f7939f58Stephen Hines   m_Size(pSize),
640dea6bc96bb52346737966839ac68644f7939f58Stephen Hines   m_bUsingThumb2(pUsingThumb2)
6522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao{
6622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  for (const_fixup_iterator it = pBegin, ie = pEnd; it != ie; ++it)
6722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    addFixup(**it);
6822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao}
6922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
7022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei LiaoTHMToTHMStub::~THMToTHMStub()
7122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao{
7222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao}
7322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
7422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaobool THMToTHMStub::isMyDuty(const class Relocation& pReloc,
7522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                            uint64_t pSource,
7622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                            uint64_t pTargetSymValue) const
7722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao{
7822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  bool result = false;
7922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  // Check if the branch target is THUMB
8022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  if ((pTargetSymValue & 0x1) != 0x0) {
8122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    switch (pReloc.type()) {
8222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      case llvm::ELF::R_ARM_THM_CALL:
8322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      case llvm::ELF::R_ARM_THM_JUMP24: {
8422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        // Check if the branch target is too far
8522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        uint64_t dest = pTargetSymValue + pReloc.addend() + 4u;
8622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        int64_t branch_offset = static_cast<int64_t>(dest) - pSource;
870dea6bc96bb52346737966839ac68644f7939f58Stephen Hines        if (m_bUsingThumb2) {
880dea6bc96bb52346737966839ac68644f7939f58Stephen Hines           if ((branch_offset > ARMGNULDBackend::THM2_MAX_FWD_BRANCH_OFFSET) ||
890dea6bc96bb52346737966839ac68644f7939f58Stephen Hines               (branch_offset < ARMGNULDBackend::THM2_MAX_BWD_BRANCH_OFFSET)) {
900dea6bc96bb52346737966839ac68644f7939f58Stephen Hines             result = true;
910dea6bc96bb52346737966839ac68644f7939f58Stephen Hines             break;
920dea6bc96bb52346737966839ac68644f7939f58Stephen Hines           }
930dea6bc96bb52346737966839ac68644f7939f58Stephen Hines        } else {
940dea6bc96bb52346737966839ac68644f7939f58Stephen Hines          if ((branch_offset > ARMGNULDBackend::THM_MAX_FWD_BRANCH_OFFSET) ||
950dea6bc96bb52346737966839ac68644f7939f58Stephen Hines              (branch_offset < ARMGNULDBackend::THM_MAX_BWD_BRANCH_OFFSET)) {
960dea6bc96bb52346737966839ac68644f7939f58Stephen Hines            result = true;
970dea6bc96bb52346737966839ac68644f7939f58Stephen Hines            break;
980dea6bc96bb52346737966839ac68644f7939f58Stephen Hines          }
990dea6bc96bb52346737966839ac68644f7939f58Stephen Hines        }
10022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        break;
10122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      }
10222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      default:
10322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        break;
10422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    }
10522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  }
10622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  return result;
10722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao}
10822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
10922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaoconst std::string& THMToTHMStub::name() const
11022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao{
11122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  return m_Name;
11222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao}
11322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
11422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaoconst uint8_t* THMToTHMStub::getContent() const
11522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao{
11622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  return reinterpret_cast<const uint8_t*>(m_pData);
11722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao}
11822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
11922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaosize_t THMToTHMStub::size() const
12022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao{
12122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  return m_Size;
12222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao}
12322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
12422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaosize_t THMToTHMStub::alignment() const
12522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao{
12622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  return 4u;
12722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao}
12822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
12922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaouint64_t THMToTHMStub::initSymValue() const
13022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao{
13122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  return 0x1;
13222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao}
13322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
13422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei LiaoStub* THMToTHMStub::doClone()
13522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao{
1360dea6bc96bb52346737966839ac68644f7939f58Stephen Hines  return new THMToTHMStub(m_pData,
1370dea6bc96bb52346737966839ac68644f7939f58Stephen Hines                          m_Size,
1380dea6bc96bb52346737966839ac68644f7939f58Stephen Hines                          fixup_begin(),
1390dea6bc96bb52346737966839ac68644f7939f58Stephen Hines                          fixup_end(),
1400dea6bc96bb52346737966839ac68644f7939f58Stephen Hines                          m_bUsingThumb2);
14122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao}
142