15460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao//===- ARMLDBackend.cpp ---------------------------------------------------===//
25460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao//
35460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao//                     The MCLinker Project
45460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao//
55460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao// This file is distributed under the University of Illinois Open Source
65460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao// License. See LICENSE.TXT for details.
75460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao//
85460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao//===----------------------------------------------------------------------===//
9cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao#include "ARM.h"
10d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao#include "ARMGNUInfo.h"
11cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao#include "ARMELFDynamic.h"
12cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao#include "ARMLDBackend.h"
13d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao#include "ARMRelocator.h"
1422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao#include "ARMToARMStub.h"
1522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao#include "ARMToTHMStub.h"
1622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao#include "THMToTHMStub.h"
1722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao#include "THMToARMStub.h"
18cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao
19cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao#include <cstring>
20cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao
215460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include <llvm/ADT/Triple.h>
225460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include <llvm/ADT/Twine.h>
235460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include <llvm/Support/ELF.h>
24cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao#include <llvm/Support/Casting.h>
255460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
2622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao#include <mcld/IRBuilder.h>
2722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao#include <mcld/LinkerConfig.h>
2822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao#include <mcld/Fragment/FillFragment.h>
2922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao#include <mcld/Fragment/AlignFragment.h>
3022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao#include <mcld/Fragment/RegionFragment.h>
315460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include <mcld/Support/MemoryRegion.h>
3222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao#include <mcld/Support/MemoryArea.h>
33affc150dc44fab1911775a49636d0ce85333b634Zonr Chang#include <mcld/Support/MsgHandling.h>
345460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include <mcld/Support/TargetRegistry.h>
3522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao#include <mcld/Fragment/Stub.h>
3622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao#include <mcld/LD/BranchIslandFactory.h>
3722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao#include <mcld/LD/StubFactory.h>
3822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao#include <mcld/Object/ObjectBuilder.h>
3922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao#include <mcld/Fragment/NullFragment.h>
4022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao#include <mcld/LD/LDContext.h>
41d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao#include <mcld/Target/GNUInfo.h>
425460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
435460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaousing namespace mcld;
445460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
45cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao//===----------------------------------------------------------------------===//
46cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao// ARMGNULDBackend
47cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao//===----------------------------------------------------------------------===//
48d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei LiaoARMGNULDBackend::ARMGNULDBackend(const LinkerConfig& pConfig, GNUInfo* pInfo)
49d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  : GNULDBackend(pConfig, pInfo),
50d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao    m_pRelocator(NULL),
515460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    m_pGOT(NULL),
525460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    m_pPLT(NULL),
535460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    m_pRelDyn(NULL),
545460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    m_pRelPLT(NULL),
555460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    m_pDynamic(NULL),
5667e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao    m_pGOTSymbol(NULL),
5722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    m_pEXIDXStart(NULL),
5822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    m_pEXIDXEnd(NULL),
595460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    m_pEXIDX(NULL),
605460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    m_pEXTAB(NULL),
615460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    m_pAttributes(NULL) {
625460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
635460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
645460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei LiaoARMGNULDBackend::~ARMGNULDBackend()
655460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
66d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  delete m_pRelocator;
6722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  delete m_pGOT;
6822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  delete m_pPLT;
6922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  delete m_pRelDyn;
7022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  delete m_pRelPLT;
7122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  delete m_pDynamic;
725460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
735460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
7422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaovoid ARMGNULDBackend::initTargetSections(Module& pModule, ObjectBuilder& pBuilder)
755460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
765460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // FIXME: Currently we set exidx and extab to "Exception" and directly emit
775460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // them from input
7822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  m_pEXIDX        = pBuilder.CreateSection(".ARM.exidx",
7922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                                           LDFileFormat::Target,
8022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                                           llvm::ELF::SHT_ARM_EXIDX,
8122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                                           llvm::ELF::SHF_ALLOC | llvm::ELF::SHF_LINK_ORDER,
82d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao                                           config().targets().bitclass() / 8);
8322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  m_pEXTAB        = pBuilder.CreateSection(".ARM.extab",
8422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                                           LDFileFormat::Target,
8522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                                           llvm::ELF::SHT_PROGBITS,
8622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                                           llvm::ELF::SHF_ALLOC,
8722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                                           0x1);
8822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  m_pAttributes   = pBuilder.CreateSection(".ARM.attributes",
8922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                                           LDFileFormat::Target,
9022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                                           llvm::ELF::SHT_ARM_ATTRIBUTES,
9122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                                           0x0,
9222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                                           0x1);
9322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
9422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  if (LinkerConfig::Object != config().codeGenType()) {
9522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    ELFFileFormat* file_format = getOutputFormat();
9622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
9722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    // initialize .got
9822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    LDSection& got = file_format->getGOT();
9922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    m_pGOT = new ARMGOT(got);
10022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
10122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    // initialize .plt
10222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    LDSection& plt = file_format->getPLT();
10322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    m_pPLT = new ARMPLT(plt, *m_pGOT);
10422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
10522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    // initialize .rel.plt
10622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    LDSection& relplt = file_format->getRelPlt();
10722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    relplt.setLink(&plt);
10822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    // create SectionData and ARMRelDynSection
109d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao    m_pRelPLT = new OutputRelocSection(pModule, relplt);
11022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
11122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    // initialize .rel.dyn
11222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    LDSection& reldyn = file_format->getRelDyn();
113d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao    m_pRelDyn = new OutputRelocSection(pModule, reldyn);
11422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  }
11522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao}
11622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
1176f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinesvoid ARMGNULDBackend::initTargetSymbols(IRBuilder& pBuilder, Module& pModule)
1185460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
1195460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // Define the symbol _GLOBAL_OFFSET_TABLE_ if there is a symbol with the
1205460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // same name in input
121f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines  if (LinkerConfig::Object != config().codeGenType()) {
122f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines    m_pGOTSymbol = pBuilder.AddSymbol<IRBuilder::AsReferred, IRBuilder::Resolve>(
1236f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines                                                  "_GLOBAL_OFFSET_TABLE_",
1246f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines                                                  ResolveInfo::Object,
1256f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines                                                  ResolveInfo::Define,
1266f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines                                                  ResolveInfo::Local,
12722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                                                  0x0,  // size
12822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                                                  0x0,  // value
1296f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines                                                  FragmentRef::Null(),
13022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                                                  ResolveInfo::Hidden);
131f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines  }
1326f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  if (NULL != m_pEXIDX && 0x0 != m_pEXIDX->size()) {
1336f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    FragmentRef* exidx_start =
1346f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      FragmentRef::Create(m_pEXIDX->getSectionData()->front(), 0x0);
1356f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    FragmentRef* exidx_end =
1366f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      FragmentRef::Create(m_pEXIDX->getSectionData()->front(),
1376f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines                          m_pEXIDX->size());
1386f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    m_pEXIDXStart =
1396f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      pBuilder.AddSymbol<IRBuilder::AsReferred, IRBuilder::Resolve>(
1406f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines                                                    "__exidx_start",
1416f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines                                                    ResolveInfo::Object,
1426f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines                                                    ResolveInfo::Define,
1436f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines                                                    ResolveInfo::Local,
1446f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines                                                    0x0, // size
1456f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines                                                    0x0, // value
1466f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines                                                    exidx_start, // FragRef
1476f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines                                                    ResolveInfo::Default);
1486f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
1496f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    m_pEXIDXEnd =
1506f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      pBuilder.AddSymbol<IRBuilder::AsReferred, IRBuilder::Resolve>(
1516f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines                                                    "__exidx_end",
1526f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines                                                    ResolveInfo::Object,
1536f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines                                                    ResolveInfo::Define,
1546f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines                                                    ResolveInfo::Local,
1556f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines                                                    0x0, // size
1566f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines                                                    0x0, // value
1576f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines                                                    exidx_end, // FragRef
1586f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines                                                    ResolveInfo::Default);
1596f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    // change __exidx_start/_end to local dynamic category
1606f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    if (NULL != m_pEXIDXStart)
161f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines      pModule.getSymbolTable().changeToDynamic(*m_pEXIDXStart);
1626f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    if (NULL != m_pEXIDXEnd)
163f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines      pModule.getSymbolTable().changeToDynamic(*m_pEXIDXEnd);
1646f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  } else {
1656f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    m_pEXIDXStart =
1666f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      pBuilder.AddSymbol<IRBuilder::AsReferred, IRBuilder::Resolve>(
1676f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines                                                    "__exidx_start",
1686f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines                                                    ResolveInfo::NoType,
1696f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines                                                    ResolveInfo::Define,
1706f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines                                                    ResolveInfo::Absolute,
1716f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines                                                    0x0, // size
1726f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines                                                    0x0, // value
1736f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines                                                    FragmentRef::Null(),
1746f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines                                                    ResolveInfo::Default);
1756f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
1766f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    m_pEXIDXEnd =
1776f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      pBuilder.AddSymbol<IRBuilder::AsReferred, IRBuilder::Resolve>(
1786f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines                                                    "__exidx_end",
1796f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines                                                    ResolveInfo::NoType,
1806f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines                                                    ResolveInfo::Define,
1816f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines                                                    ResolveInfo::Absolute,
1826f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines                                                    0x0, // size
1836f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines                                                    0x0, // value
1846f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines                                                    FragmentRef::Null(),
1856f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines                                                    ResolveInfo::Default);
1866f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  }
1875460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
1885460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1896f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinesbool ARMGNULDBackend::initRelocator()
190d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao{
191d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  if (NULL == m_pRelocator) {
192f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines    m_pRelocator = new ARMRelocator(*this, config());
193d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  }
194d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  return true;
195d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao}
196d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao
197d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei LiaoRelocator* ARMGNULDBackend::getRelocator()
198d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao{
199d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  assert(NULL != m_pRelocator);
200d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  return m_pRelocator;
201d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao}
202d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao
2036f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinesvoid ARMGNULDBackend::doPreLayout(IRBuilder& pBuilder)
2045460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
2056f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  // initialize .dynamic data
2066f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  if (!config().isCodeStatic() && NULL == m_pDynamic)
2076f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    m_pDynamic = new ARMELFDynamic(*this, config());
2086f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
20922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  // set .got size
21022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  // when building shared object, the .got section is must
21122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  if (LinkerConfig::Object != config().codeGenType()) {
21222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    if (LinkerConfig::DynObj == config().codeGenType() ||
21322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        m_pGOT->hasGOT1() ||
21422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        NULL != m_pGOTSymbol) {
21522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      m_pGOT->finalizeSectionSize();
2166f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      defineGOTSymbol(pBuilder);
21722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    }
21822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
21922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    // set .plt size
22022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    if (m_pPLT->hasPLT1())
22122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      m_pPLT->finalizeSectionSize();
22222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
223d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao    ELFFileFormat* file_format = getOutputFormat();
22422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    // set .rel.dyn size
2256f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    if (!m_pRelDyn->empty()) {
2266f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      assert(!config().isCodeStatic() &&
2276f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines            "static linkage should not result in a dynamic relocation section");
228d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao      file_format->getRelDyn().setSize(
229d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao                                  m_pRelDyn->numOfRelocs() * getRelEntrySize());
2306f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    }
23122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
23222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    // set .rel.plt size
2336f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    if (!m_pRelPLT->empty()) {
2346f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      assert(!config().isCodeStatic() &&
2356f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines            "static linkage should not result in a dynamic relocation section");
236d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao      file_format->getRelPlt().setSize(
237d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao                                  m_pRelPLT->numOfRelocs() * getRelEntrySize());
2386f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    }
2395460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
2405460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
2415460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
2426f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinesvoid ARMGNULDBackend::doPostLayout(Module& pModule, IRBuilder& pBuilder)
2435460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
24422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  const ELFFileFormat *file_format = getOutputFormat();
2455460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
2465460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // apply PLT
2475460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  if (file_format->hasPLT()) {
2485460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    // Since we already have the size of LDSection PLT, m_pPLT should not be
2495460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    // NULL.
2505460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    assert(NULL != m_pPLT);
2515460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    m_pPLT->applyPLT0();
2525460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    m_pPLT->applyPLT1();
2535460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
2545460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
2555460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // apply GOT
2565460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  if (file_format->hasGOT()) {
2575460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    // Since we already have the size of GOT, m_pGOT should not be NULL.
2585460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    assert(NULL != m_pGOT);
25922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    if (LinkerConfig::DynObj == config().codeGenType())
2605460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      m_pGOT->applyGOT0(file_format->getDynamic().addr());
2615460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    else {
2625460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      // executable file and object file? should fill with zero.
2635460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      m_pGOT->applyGOT0(0);
2645460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    }
2655460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
2665460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
2675460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
2685460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// dynamic - the dynamic section of the target machine.
2695460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// Use co-variant return type to return its own dynamic section.
2705460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei LiaoARMELFDynamic& ARMGNULDBackend::dynamic()
2715460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
2726f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  assert(NULL != m_pDynamic);
2735460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  return *m_pDynamic;
2745460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
2755460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
2765460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// dynamic - the dynamic section of the target machine.
2775460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// Use co-variant return type to return its own dynamic section.
2785460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaoconst ARMELFDynamic& ARMGNULDBackend::dynamic() const
2795460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
2806f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  assert(NULL != m_pDynamic);
2815460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  return *m_pDynamic;
2825460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
2835460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
2846f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinesvoid ARMGNULDBackend::defineGOTSymbol(IRBuilder& pBuilder)
2855460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
2865460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // define symbol _GLOBAL_OFFSET_TABLE_ when .got create
287affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  if (m_pGOTSymbol != NULL) {
2886f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    pBuilder.AddSymbol<IRBuilder::Force, IRBuilder::Unresolve>(
2895460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                     "_GLOBAL_OFFSET_TABLE_",
2905460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                     ResolveInfo::Object,
2915460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                     ResolveInfo::Define,
2925460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                     ResolveInfo::Local,
2935460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                     0x0, // size
2945460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                     0x0, // value
29522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                     FragmentRef::Create(*(m_pGOT->begin()), 0x0),
2965460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                     ResolveInfo::Hidden);
2975460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
2985460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  else {
2996f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    m_pGOTSymbol = pBuilder.AddSymbol<IRBuilder::Force, IRBuilder::Resolve>(
3005460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                     "_GLOBAL_OFFSET_TABLE_",
3015460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                     ResolveInfo::Object,
3025460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                     ResolveInfo::Define,
3035460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                     ResolveInfo::Local,
3045460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                     0x0, // size
3055460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                     0x0, // value
30622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                     FragmentRef::Create(*(m_pGOT->begin()), 0x0),
3075460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                     ResolveInfo::Hidden);
3085460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
3095460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
3105460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
3115460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
31222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaouint64_t ARMGNULDBackend::emitSectionData(const LDSection& pSection,
3135460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                          MemoryRegion& pRegion) const
3145460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
3155460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  assert(pRegion.size() && "Size of MemoryRegion is zero!");
3165460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
31722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  const ELFFileFormat* file_format = getOutputFormat();
3185460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
319affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  if (&pSection == m_pAttributes ||
320affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      &pSection == m_pEXIDX ||
321affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      &pSection == m_pEXTAB) {
322affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    // FIXME: Currently Emitting .ARM.attributes, .ARM.exidx, and .ARM.extab
323affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    // directly from the input file.
324cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao    const SectionData* sect_data = pSection.getSectionData();
325cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao    SectionData::const_iterator frag_iter, frag_end = sect_data->end();
326affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    uint8_t* out_offset = pRegion.start();
327affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    for (frag_iter = sect_data->begin(); frag_iter != frag_end; ++frag_iter) {
32822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      size_t size = frag_iter->size();
329affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      switch(frag_iter->getKind()) {
33022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        case Fragment::Fillment: {
33122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao          const FillFragment& fill_frag =
33222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao            llvm::cast<FillFragment>(*frag_iter);
33322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao          if (0 == fill_frag.getValueSize()) {
33422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao            // virtual fillment, ignore it.
33522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao            break;
33622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao          }
33722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
33822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao          memset(out_offset, fill_frag.getValue(), fill_frag.size());
33922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao          break;
34022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        }
341cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao        case Fragment::Region: {
342cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao          const RegionFragment& region_frag =
343cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao            llvm::cast<RegionFragment>(*frag_iter);
344affc150dc44fab1911775a49636d0ce85333b634Zonr Chang          const uint8_t* start = region_frag.getRegion().start();
345affc150dc44fab1911775a49636d0ce85333b634Zonr Chang          memcpy(out_offset, start, size);
346affc150dc44fab1911775a49636d0ce85333b634Zonr Chang          break;
347affc150dc44fab1911775a49636d0ce85333b634Zonr Chang        }
348cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao        case Fragment::Alignment: {
3496f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines          const AlignFragment& align_frag = llvm::cast<AlignFragment>(*frag_iter);
350affc150dc44fab1911775a49636d0ce85333b634Zonr Chang          uint64_t count = size / align_frag.getValueSize();
351affc150dc44fab1911775a49636d0ce85333b634Zonr Chang          switch (align_frag.getValueSize()) {
352affc150dc44fab1911775a49636d0ce85333b634Zonr Chang            case 1u:
353affc150dc44fab1911775a49636d0ce85333b634Zonr Chang              std::memset(out_offset, align_frag.getValue(), count);
354affc150dc44fab1911775a49636d0ce85333b634Zonr Chang              break;
355affc150dc44fab1911775a49636d0ce85333b634Zonr Chang            default:
356affc150dc44fab1911775a49636d0ce85333b634Zonr Chang              llvm::report_fatal_error(
357affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                "unsupported value size for align fragment emission yet.\n");
358affc150dc44fab1911775a49636d0ce85333b634Zonr Chang              break;
359affc150dc44fab1911775a49636d0ce85333b634Zonr Chang          } // end switch
360affc150dc44fab1911775a49636d0ce85333b634Zonr Chang          break;
361affc150dc44fab1911775a49636d0ce85333b634Zonr Chang        }
36222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        case Fragment::Null: {
36322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao          assert(0x0 == size);
36422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao          break;
36522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        }
366affc150dc44fab1911775a49636d0ce85333b634Zonr Chang        default:
367affc150dc44fab1911775a49636d0ce85333b634Zonr Chang          llvm::report_fatal_error("unsupported fragment type.\n");
368affc150dc44fab1911775a49636d0ce85333b634Zonr Chang          break;
369affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      } // end switch
370affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      out_offset += size;
371affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    } // end for
3725460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    return pRegion.size();
373affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  } // end if
3745460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
3755460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  if (&pSection == &(file_format->getPLT())) {
3765460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    assert(NULL != m_pPLT && "emitSectionData failed, m_pPLT is NULL!");
3775460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    uint64_t result = m_pPLT->emit(pRegion);
3785460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    return result;
3795460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
3805460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
3815460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  if (&pSection == &(file_format->getGOT())) {
3825460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    assert(NULL != m_pGOT && "emitSectionData failed, m_pGOT is NULL!");
3835460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    uint64_t result = m_pGOT->emit(pRegion);
3845460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    return result;
3855460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
386affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  fatal(diag::unrecognized_output_sectoin)
387affc150dc44fab1911775a49636d0ce85333b634Zonr Chang          << pSection.name()
388affc150dc44fab1911775a49636d0ce85333b634Zonr Chang          << "mclinker@googlegroups.com";
3895460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  return 0x0;
3905460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
3915460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
3925460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// finalizeSymbol - finalize the symbol value
3936f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinesbool ARMGNULDBackend::finalizeTargetSymbols()
3945460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
3955460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  return true;
3965460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
3975460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
39822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaobool ARMGNULDBackend::mergeSection(Module& pModule, LDSection& pSection)
39922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao{
40022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  switch (pSection.type()) {
40122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    case llvm::ELF::SHT_ARM_ATTRIBUTES: {
40222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      // FIXME: (Luba)
40322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      // Handle ARM attributes in the right way.
4046f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      // In current milestone, we goes through the shortcut.
40522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      // It reads input's ARM attributes and copies the first ARM attributes
40622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      // into the output file. The correct way is merge these sections, not
40722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      // just copy.
40822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      if (0 != m_pAttributes->size())
40922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        return true;
41022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
41122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      // First time we meet a ARM attributes section.
41222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      SectionData* sd = IRBuilder::CreateSectionData(*m_pAttributes);
41322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      ObjectBuilder::MoveSectionData(*pSection.getSectionData(), *sd);
41422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      return true;
41522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    }
41622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    default: {
41722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      ObjectBuilder builder(config(), pModule);
41822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      return builder.MergeSection(pSection);
41922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    }
42022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  } // end of switch
42122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  return true;
42222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao}
4235460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
42422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaobool ARMGNULDBackend::readSection(Input& pInput, SectionData& pSD)
42522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao{
426cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao  Fragment* frag = NULL;
42722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  uint32_t offset = pInput.fileOffset() + pSD.getSection().offset();
42822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  uint32_t size = pSD.getSection().size();
42922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
43022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  MemoryRegion* region = pInput.memArea()->request(offset, size);
431affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  if (NULL == region) {
432affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    // If the input section's size is zero, we got a NULL region.
433affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    // use a virtual fill fragment
434cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao    frag = new FillFragment(0x0, 0, 0);
435affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  }
43622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  else {
437cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao    frag = new RegionFragment(*region);
43822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  }
439affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
44022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  ObjectBuilder::AppendFragment(*frag, pSD);
4415460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  return true;
4425460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
4435460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
4445460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei LiaoARMGOT& ARMGNULDBackend::getGOT()
4455460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
4465460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  assert(NULL != m_pGOT && "GOT section not exist");
4475460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  return *m_pGOT;
4485460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
4495460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
4505460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaoconst ARMGOT& ARMGNULDBackend::getGOT() const
4515460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
4525460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  assert(NULL != m_pGOT && "GOT section not exist");
4535460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  return *m_pGOT;
4545460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
4555460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
4565460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei LiaoARMPLT& ARMGNULDBackend::getPLT()
4575460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
4585460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  assert(NULL != m_pPLT && "PLT section not exist");
4595460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  return *m_pPLT;
4605460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
4615460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
4625460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaoconst ARMPLT& ARMGNULDBackend::getPLT() const
4635460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
4645460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  assert(NULL != m_pPLT && "PLT section not exist");
4655460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  return *m_pPLT;
4665460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
4675460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
4685460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei LiaoOutputRelocSection& ARMGNULDBackend::getRelDyn()
4695460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
4705460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  assert(NULL != m_pRelDyn && ".rel.dyn section not exist");
4715460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  return *m_pRelDyn;
4725460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
4735460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
4745460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaoconst OutputRelocSection& ARMGNULDBackend::getRelDyn() const
4755460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
4765460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  assert(NULL != m_pRelDyn && ".rel.dyn section not exist");
4775460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  return *m_pRelDyn;
4785460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
4795460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
4805460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei LiaoOutputRelocSection& ARMGNULDBackend::getRelPLT()
4815460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
4825460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  assert(NULL != m_pRelPLT && ".rel.plt section not exist");
4835460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  return *m_pRelPLT;
4845460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
4855460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
4865460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaoconst OutputRelocSection& ARMGNULDBackend::getRelPLT() const
4875460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
4885460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  assert(NULL != m_pRelPLT && ".rel.plt section not exist");
4895460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  return *m_pRelPLT;
4905460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
4915460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
4925460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaounsigned int
49322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei LiaoARMGNULDBackend::getTargetSectionOrder(const LDSection& pSectHdr) const
4945460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
49522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  const ELFFileFormat* file_format = getOutputFormat();
4965460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
497affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  if (&pSectHdr == &file_format->getGOT()) {
49822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    if (config().options().hasNow())
499affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      return SHO_RELRO_LAST;
5005460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    return SHO_DATA;
501affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  }
5025460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
5035460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  if (&pSectHdr == &file_format->getPLT())
5045460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    return SHO_PLT;
5055460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
506affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  if (&pSectHdr == m_pEXIDX || &pSectHdr == m_pEXTAB) {
507affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    // put ARM.exidx and ARM.extab in the same order of .eh_frame
508affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    return SHO_EXCEPTION;
509affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  }
510affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
5115460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  return SHO_UNDEFINED;
5125460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
5135460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
51422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// doRelax
5156f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinesbool
5166f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen HinesARMGNULDBackend::doRelax(Module& pModule, IRBuilder& pBuilder, bool& pFinished)
51722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao{
51822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  assert(NULL != getStubFactory() && NULL != getBRIslandFactory());
51922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
52022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  bool isRelaxed = false;
52122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  ELFFileFormat* file_format = getOutputFormat();
52222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  // check branch relocs and create the related stubs if needed
52322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  Module::obj_iterator input, inEnd = pModule.obj_end();
52422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  for (input = pModule.obj_begin(); input != inEnd; ++input) {
52522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    LDContext::sect_iterator rs, rsEnd = (*input)->context()->relocSectEnd();
52622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    for (rs = (*input)->context()->relocSectBegin(); rs != rsEnd; ++rs) {
52722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      if (LDFileFormat::Ignore == (*rs)->kind() || !(*rs)->hasRelocData())
52822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        continue;
52922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      RelocData::iterator reloc, rEnd = (*rs)->getRelocData()->end();
53022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      for (reloc = (*rs)->getRelocData()->begin(); reloc != rEnd; ++reloc) {
53122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        Relocation* relocation = llvm::cast<Relocation>(reloc);
53222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
53322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        switch (relocation->type()) {
534f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines          case llvm::ELF::R_ARM_PC24:
53522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao          case llvm::ELF::R_ARM_CALL:
53622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao          case llvm::ELF::R_ARM_JUMP24:
53722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao          case llvm::ELF::R_ARM_PLT32:
53822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao          case llvm::ELF::R_ARM_THM_CALL:
53922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao          case llvm::ELF::R_ARM_THM_XPC22:
54022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao          case llvm::ELF::R_ARM_THM_JUMP24:
54122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao          case llvm::ELF::R_ARM_THM_JUMP19:
54222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao          case llvm::ELF::R_ARM_V4BX: {
54322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao            // calculate the possible symbol value
54422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao            uint64_t sym_value = 0x0;
54522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao            LDSymbol* symbol = relocation->symInfo()->outSymbol();
54622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao            if (symbol->hasFragRef()) {
54722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao              uint64_t value = symbol->fragRef()->getOutputOffset();
54822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao              uint64_t addr =
54922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                symbol->fragRef()->frag()->getParent()->getSection().addr();
55022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao              sym_value = addr + value;
55122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao            }
55222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao            if (relocation->symInfo()->isGlobal() &&
553f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines                (relocation->symInfo()->reserved() & ARMRelocator::ReservePLT) != 0x0) {
55422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao              // FIXME: we need to find out the address of the specific plt entry
55522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao              assert(file_format->hasPLT());
55622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao              sym_value = file_format->getPLT().addr();
55722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao            }
55822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
55922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao            Stub* stub = getStubFactory()->create(*relocation, // relocation
56022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                                                  sym_value, // symbol value
5616f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines                                                  pBuilder,
56222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                                                  *getBRIslandFactory());
56322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao            if (NULL != stub) {
5646f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines              // a stub symbol should be local
5656f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines              assert(NULL != stub->symInfo() && stub->symInfo()->isLocal());
56622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao              LDSection& symtab = file_format->getSymTab();
56722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao              LDSection& strtab = file_format->getStrTab();
5686f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
5696f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines              // increase the size of .symtab and .strtab if needed
570d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao              if (config().targets().is32Bits())
57122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                symtab.setSize(symtab.size() + sizeof(llvm::ELF::Elf32_Sym));
57222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao              else
57322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                symtab.setSize(symtab.size() + sizeof(llvm::ELF::Elf64_Sym));
5746f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines              symtab.setInfo(symtab.getInfo() + 1);
57522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao              strtab.setSize(strtab.size() + stub->symInfo()->nameSize() + 1);
57622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
57722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao              isRelaxed = true;
57822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao            }
57922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao            break;
58022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao          }
58122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao          default:
58222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao            break;
58322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        } // end of switch
58422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
58522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      } // for all relocations
58622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    } // for all relocation section
58722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  } // for all inputs
58822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
58922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  // find the first fragment w/ invalid offset due to stub insertion
59022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  Fragment* invalid = NULL;
59122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  pFinished = true;
59222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  for (BranchIslandFactory::iterator island = getBRIslandFactory()->begin(),
59322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao       island_end = getBRIslandFactory()->end(); island != island_end; ++island) {
59422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    if ((*island).end() == file_format->getText().getSectionData()->end())
59522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      break;
59622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
59722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    Fragment* exit = (*island).end();
59822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    if (((*island).offset() + (*island).size()) > exit->getOffset()) {
59922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      invalid = exit;
60022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      pFinished = false;
60122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      break;
60222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    }
60322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  }
60422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
60522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  // reset the offset of invalid fragments
60622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  while (NULL != invalid) {
60722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    invalid->setOffset(invalid->getPrevNode()->getOffset() +
60822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                       invalid->getPrevNode()->size());
60922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    invalid = invalid->getNextNode();
61022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  }
61122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
61222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  // reset the size of .text
61322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  if (isRelaxed) {
61422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    file_format->getText().setSize(
61522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      file_format->getText().getSectionData()->back().getOffset() +
61622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      file_format->getText().getSectionData()->back().size());
61722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  }
61822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  return isRelaxed;
61922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao}
62022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
62122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// initTargetStubs
6226f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinesbool ARMGNULDBackend::initTargetStubs()
62322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao{
62422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  if (NULL != getStubFactory()) {
6256f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    getStubFactory()->addPrototype(new ARMToARMStub(config().isCodeIndep()));
6266f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    getStubFactory()->addPrototype(new ARMToTHMStub(config().isCodeIndep()));
6276f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    getStubFactory()->addPrototype(new THMToTHMStub(config().isCodeIndep()));
6286f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    getStubFactory()->addPrototype(new THMToARMStub(config().isCodeIndep()));
62922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    return true;
63022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  }
63122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  return false;
63222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao}
63322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
63422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// doCreateProgramHdrs - backend can implement this function to create the
63522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// target-dependent segments
6366f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinesvoid ARMGNULDBackend::doCreateProgramHdrs(Module& pModule)
63722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao{
63822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao   if (NULL != m_pEXIDX && 0x0 != m_pEXIDX->size()) {
63922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao     // make PT_ARM_EXIDX
64086036a3bd999904d071826b2f0a84023e28aeebcShih-wei Liao     ELFSegment* exidx_seg = elfSegmentTable().produce(llvm::ELF::PT_ARM_EXIDX,
64122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                                                       llvm::ELF::PF_R);
64222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao     exidx_seg->addSection(m_pEXIDX);
64322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao   }
64422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao}
64522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
6465460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaonamespace mcld {
6475460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
6485460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao//===----------------------------------------------------------------------===//
6495460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// createARMLDBackend - the help funtion to create corresponding ARMLDBackend
6505460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao///
6515460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei LiaoTargetLDBackend* createARMLDBackend(const llvm::Target& pTarget,
65222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                                    const LinkerConfig& pConfig)
6535460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
654d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  if (pConfig.targets().triple().isOSDarwin()) {
6555460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    assert(0 && "MachO linker is not supported yet");
6565460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    /**
6575460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    return new ARMMachOLDBackend(createARMMachOArchiveReader,
6585460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                               createARMMachOObjectReader,
6595460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                               createARMMachOObjectWriter);
6605460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    **/
6615460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
662d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  if (pConfig.targets().triple().isOSWindows()) {
6635460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    assert(0 && "COFF linker is not supported yet");
6645460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    /**
6655460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    return new ARMCOFFLDBackend(createARMCOFFArchiveReader,
6665460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                               createARMCOFFObjectReader,
6675460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                               createARMCOFFObjectWriter);
6685460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    **/
6695460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
670d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  return new ARMGNULDBackend(pConfig, new ARMGNUInfo(pConfig.targets().triple()));
6715460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
6725460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
6735460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} // namespace of mcld
6745460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
67522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao//===----------------------------------------------------------------------===//
6765460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao// Force static initialization.
67722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao//===----------------------------------------------------------------------===//
67822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaoextern "C" void MCLDInitializeARMLDBackend() {
6795460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // Register the linker backend
6805460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  mcld::TargetRegistry::RegisterTargetLDBackend(TheARMTarget, createARMLDBackend);
681affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  mcld::TargetRegistry::RegisterTargetLDBackend(TheThumbTarget, createARMLDBackend);
6825460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
683affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
684