15460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao//===- X86LDBackend.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//===----------------------------------------------------------------------===//
95460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include "X86.h"
105460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include "X86ELFDynamic.h"
115460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include "X86LDBackend.h"
12d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao#include "X86Relocator.h"
13d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao#include "X86GNUInfo.h"
145460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines#include <llvm/ADT/StringRef.h>
165460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include <llvm/ADT/Triple.h>
17cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao#include <llvm/Support/Casting.h>
18cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao
1922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao#include <mcld/LinkerConfig.h>
2022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao#include <mcld/IRBuilder.h>
2187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines#include <mcld/LD/ELFFileFormat.h>
2222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao#include <mcld/Fragment/FillFragment.h>
2322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao#include <mcld/Fragment/RegionFragment.h>
24affc150dc44fab1911775a49636d0ce85333b634Zonr Chang#include <mcld/Support/MsgHandling.h>
25affc150dc44fab1911775a49636d0ce85333b634Zonr Chang#include <mcld/Support/TargetRegistry.h>
2622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao#include <mcld/Object/ObjectBuilder.h>
2787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines#include <llvm/Support/Dwarf.h>
285460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
295460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include <cstring>
305460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
315460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaousing namespace mcld;
325460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
3322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao//===----------------------------------------------------------------------===//
3422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao// X86GNULDBackend
3522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao//===----------------------------------------------------------------------===//
366f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen HinesX86GNULDBackend::X86GNULDBackend(const LinkerConfig& pConfig,
37551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines                                 GNUInfo* pInfo,
38551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines                                 Relocation::Type pCopyRel)
39d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  : GNULDBackend(pConfig, pInfo),
40d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao    m_pRelocator(NULL),
415460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    m_pPLT(NULL),
425460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    m_pRelDyn(NULL),
435460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    m_pRelPLT(NULL),
4467e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao    m_pDynamic(NULL),
456f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    m_pGOTSymbol(NULL),
466f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    m_CopyRel(pCopyRel)
476f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines{
4887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  llvm::Triple::ArchType arch = pConfig.targets().triple().getArch();
4987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  assert (arch == llvm::Triple::x86 || arch == llvm::Triple::x86_64);
5087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  if (arch == llvm::Triple::x86 ||
5187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines      pConfig.targets().triple().getEnvironment() == llvm::Triple::GNUX32) {
526f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    m_RelEntrySize = 8;
536f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    m_RelaEntrySize = 12;
5487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    if (arch == llvm::Triple::x86)
556f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      m_PointerRel = llvm::ELF::R_386_32;
566f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    else
576f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      m_PointerRel = llvm::ELF::R_X86_64_32;
586f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  }
596f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  else {
606f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    m_RelEntrySize = 16;
616f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    m_RelaEntrySize = 24;
626f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    m_PointerRel = llvm::ELF::R_X86_64_64;
636f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  }
645460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
655460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
665460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei LiaoX86GNULDBackend::~X86GNULDBackend()
675460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
68d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  delete m_pRelocator;
6922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  delete m_pPLT;
7022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  delete m_pRelDyn;
7122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  delete m_pRelPLT;
7222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  delete m_pDynamic;
735460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
745460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
75a790f0a8f3175183bea088389b3e4ae41813e192Stephen Hinesconst Relocator* X86GNULDBackend::getRelocator() const
76a790f0a8f3175183bea088389b3e4ae41813e192Stephen Hines{
77a790f0a8f3175183bea088389b3e4ae41813e192Stephen Hines  assert(NULL != m_pRelocator);
78a790f0a8f3175183bea088389b3e4ae41813e192Stephen Hines  return m_pRelocator;
79a790f0a8f3175183bea088389b3e4ae41813e192Stephen Hines}
80a790f0a8f3175183bea088389b3e4ae41813e192Stephen Hines
81d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei LiaoRelocator* X86GNULDBackend::getRelocator()
825460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
83d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  assert(NULL != m_pRelocator);
84d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  return m_pRelocator;
855460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
865460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
876f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinesvoid X86GNULDBackend::doPreLayout(IRBuilder& pBuilder)
885460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
896f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  // initialize .dynamic data
906f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  if (!config().isCodeStatic() && NULL == m_pDynamic)
916f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    m_pDynamic = new X86ELFDynamic(*this, config());
926f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
936f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  // set .got.plt and .got sizes
9422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  // when building shared object, the .got section is must
9522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  if (LinkerConfig::Object != config().codeGenType()) {
966f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    setGOTSectionSize(pBuilder);
9722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
9822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    // set .plt size
9922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    if (m_pPLT->hasPLT1())
10022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      m_pPLT->finalizeSectionSize();
10122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
1026f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    // set .rel.dyn/.rela.dyn size
1036f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    if (!m_pRelDyn->empty()) {
1046f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      assert(!config().isCodeStatic() &&
1056f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines            "static linkage should not result in a dynamic relocation section");
1066f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      setRelDynSize();
1076f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    }
1086f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    // set .rel.plt/.rela.plt size
1096f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    if (!m_pRelPLT->empty()) {
1106f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      assert(!config().isCodeStatic() &&
1116f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines            "static linkage should not result in a dynamic relocation section");
1126f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      setRelPLTSize();
1136f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    }
114affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  }
11587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
11687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  if (config().options().genUnwindInfo())
11787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    addEhFrameForPLT(pBuilder.getModule());
1185460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
1195460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
12022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaovoid X86GNULDBackend::doPostLayout(Module& pModule,
1216f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines                                   IRBuilder& pBuilder)
1225460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
1235460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
1245460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1255460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// dynamic - the dynamic section of the target machine.
1265460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// Use co-variant return type to return its own dynamic section.
1275460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei LiaoX86ELFDynamic& X86GNULDBackend::dynamic()
1285460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
1296f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  assert(NULL != m_pDynamic);
1305460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  return *m_pDynamic;
1315460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
1325460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1335460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// dynamic - the dynamic section of the target machine.
1345460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// Use co-variant return type to return its own dynamic section.
1355460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaoconst X86ELFDynamic& X86GNULDBackend::dynamic() const
1365460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
1376f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  assert(NULL != m_pDynamic);
1385460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  return *m_pDynamic;
1395460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
1405460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
141551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hinesvoid X86GNULDBackend::defineGOTSymbol(IRBuilder& pBuilder, Fragment& pFrag)
1425460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
14322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  // define symbol _GLOBAL_OFFSET_TABLE_
144affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  if (m_pGOTSymbol != NULL) {
1456f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    pBuilder.AddSymbol<IRBuilder::Force, IRBuilder::Unresolve>(
1465460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                     "_GLOBAL_OFFSET_TABLE_",
1475460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                     ResolveInfo::Object,
1485460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                     ResolveInfo::Define,
1495460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                     ResolveInfo::Local,
1505460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                     0x0, // size
1515460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                     0x0, // value
1526f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines                     FragmentRef::Create(pFrag, 0x0),
1535460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                     ResolveInfo::Hidden);
1545460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
1555460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  else {
1566f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    m_pGOTSymbol = pBuilder.AddSymbol<IRBuilder::Force, IRBuilder::Resolve>(
1575460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                     "_GLOBAL_OFFSET_TABLE_",
1585460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                     ResolveInfo::Object,
1595460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                     ResolveInfo::Define,
1605460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                     ResolveInfo::Local,
1615460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                     0x0, // size
1625460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                     0x0, // value
1636f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines                     FragmentRef::Create(pFrag, 0x0),
1645460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                     ResolveInfo::Hidden);
1655460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
1665460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
1675460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1686f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinesuint64_t X86GNULDBackend::emitSectionData(const LDSection& pSection,
1696f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines                                          MemoryRegion& pRegion) const
1706f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines{
1716f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  assert(pRegion.size() && "Size of MemoryRegion is zero!");
1726f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
1736f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  const ELFFileFormat* FileFormat = getOutputFormat();
1746f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  assert(FileFormat &&
1756f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines         "ELFFileFormat is NULL in X86GNULDBackend::emitSectionData!");
1766f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
1776f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  unsigned int EntrySize = 0;
1786f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  uint64_t RegionSize = 0;
1796f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
18087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  if (FileFormat->hasPLT() && (&pSection == &(FileFormat->getPLT()))) {
18187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    unsigned char* buffer = pRegion.begin();
1826f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
1836f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    m_pPLT->applyPLT0();
1846f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    m_pPLT->applyPLT1();
1856f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    X86PLT::iterator it = m_pPLT->begin();
1866f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    unsigned int plt0_size = llvm::cast<PLTEntryBase>((*it)).size();
1876f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
1886f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    memcpy(buffer, llvm::cast<PLTEntryBase>((*it)).getValue(), plt0_size);
1896f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    RegionSize += plt0_size;
1906f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    ++it;
1916f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
1926f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    PLTEntryBase* plt1 = 0;
1936f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    X86PLT::iterator ie = m_pPLT->end();
1946f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    while (it != ie) {
1956f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      plt1 = &(llvm::cast<PLTEntryBase>(*it));
1966f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      EntrySize = plt1->size();
1976f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      memcpy(buffer + RegionSize, plt1->getValue(), EntrySize);
1986f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      RegionSize += EntrySize;
1996f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      ++it;
2006f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    }
2016f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  }
20287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  else if (FileFormat->hasGOT() && (&pSection == &(FileFormat->getGOT()))) {
2036f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    RegionSize += emitGOTSectionData(pRegion);
2046f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  }
20587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  else if (FileFormat->hasGOTPLT() &&
20687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines           (&pSection == &(FileFormat->getGOTPLT()))) {
2076f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    RegionSize += emitGOTPLTSectionData(pRegion, FileFormat);
2086f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  }
2096f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  else {
2106f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    fatal(diag::unrecognized_output_sectoin)
2116f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines            << pSection.name()
2126f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines            << "mclinker@googlegroups.com";
2136f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  }
2146f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  return RegionSize;
2156f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines}
2166f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
2176f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen HinesX86PLT& X86GNULDBackend::getPLT()
2186f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines{
2196f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  assert(NULL != m_pPLT && "PLT section not exist");
2206f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  return *m_pPLT;
2216f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines}
2226f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
2236f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinesconst X86PLT& X86GNULDBackend::getPLT() const
2246f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines{
2256f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  assert(NULL != m_pPLT && "PLT section not exist");
2266f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  return *m_pPLT;
2276f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines}
2286f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
2296f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen HinesOutputRelocSection& X86GNULDBackend::getRelDyn()
2306f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines{
2316f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  assert(NULL != m_pRelDyn && ".rel.dyn/.rela.dyn section not exist");
2326f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  return *m_pRelDyn;
2336f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines}
2346f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
2356f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinesconst OutputRelocSection& X86GNULDBackend::getRelDyn() const
2366f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines{
2376f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  assert(NULL != m_pRelDyn && ".rel.dyn/.rela.dyn section not exist");
2386f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  return *m_pRelDyn;
2396f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines}
2406f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
2416f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen HinesOutputRelocSection& X86GNULDBackend::getRelPLT()
2426f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines{
2436f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  assert(NULL != m_pRelPLT && ".rel.plt/.rela.plt section not exist");
2446f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  return *m_pRelPLT;
2456f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines}
2466f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
2476f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinesconst OutputRelocSection& X86GNULDBackend::getRelPLT() const
2486f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines{
2496f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  assert(NULL != m_pRelPLT && ".rel.plt/.rela.plt section not exist");
2506f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  return *m_pRelPLT;
2516f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines}
2526f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
2536f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinesunsigned int
2546f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen HinesX86GNULDBackend::getTargetSectionOrder(const LDSection& pSectHdr) const
2556f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines{
2566f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  const ELFFileFormat* file_format = getOutputFormat();
2576f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
25887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  if (file_format->hasGOT() && (&pSectHdr == &file_format->getGOT())) {
2596f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    if (config().options().hasNow())
2606f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      return SHO_RELRO;
2616f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    return SHO_RELRO_LAST;
2626f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  }
2636f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
26487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  if (file_format->hasGOTPLT() && (&pSectHdr == &file_format->getGOTPLT())) {
2656f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    if (config().options().hasNow())
2666f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      return SHO_RELRO;
2676f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    return SHO_NON_RELRO_FIRST;
2686f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  }
2696f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
27087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  if (file_format->hasPLT() && (&pSectHdr == &file_format->getPLT()))
2716f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    return SHO_PLT;
2726f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
2736f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  return SHO_UNDEFINED;
2746f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines}
2756f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
2766f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinesvoid X86GNULDBackend::initTargetSymbols(IRBuilder& pBuilder, Module& pModule)
2776f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines{
2786f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  if (LinkerConfig::Object != config().codeGenType()) {
2796f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    // Define the symbol _GLOBAL_OFFSET_TABLE_ if there is a symbol with the
2806f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    // same name in input
2816f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    m_pGOTSymbol =
2826f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      pBuilder.AddSymbol<IRBuilder::AsReferred, IRBuilder::Resolve>(
2836f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines                                                "_GLOBAL_OFFSET_TABLE_",
2846f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines                                                ResolveInfo::Object,
2856f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines                                                ResolveInfo::Define,
2866f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines                                                ResolveInfo::Local,
2876f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines                                                0x0,  // size
2886f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines                                                0x0,  // value
2896f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines                                                FragmentRef::Null(), // FragRef
2906f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines                                                ResolveInfo::Hidden);
2916f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  }
2926f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines}
2936f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
29487f34658dec9097d987d254a990ea7f311bfc95fStephen Hinesvoid X86GNULDBackend::addEhFrameForPLT(Module& pModule)
29587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines{
29687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  LDSection* plt_sect = pModule.getSection(".plt");
29787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  if (!plt_sect || plt_sect->size() == 0u)
29887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    return;
29987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
30087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  LDSection* eh_sect = pModule.getSection(".eh_frame");
30187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  if (!eh_sect || !eh_sect->hasEhFrame())
30287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    return;
30387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
30487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  EhFrame* eh_frame = eh_sect->getEhFrame();
30587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  SectionData::FragmentListType& frag_list =
30687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines      eh_frame->getSectionData()->getFragmentList();
30787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  llvm::StringRef cie_region = createCIERegionForPLT();
30887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  llvm::StringRef fde_region = createFDERegionForPLT();
30987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  EhFrame::CIE* cie = new EhFrame::GeneratedCIE(cie_region);
31087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  EhFrame::FDE* fde = new EhFrame::GeneratedFDE(fde_region, *cie);
31187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  // Augmentation data only contains FDE encoding.
31287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  uint8_t aug_data = (uint8_t)(llvm::dwarf::DW_EH_PE_pcrel |
31387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines                               llvm::dwarf::DW_EH_PE_sdata4);
31487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  cie->setFDEEncode(aug_data);
31587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  cie->setAugmentationData(std::string(1, aug_data));
31687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
31787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  EhFrame::cie_iterator i = eh_frame->cie_begin();
31887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  for (EhFrame::cie_iterator e = eh_frame->cie_end(); i != e; ++i) {
31987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    EhFrame::CIE& exist_cie = **i;
32087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    if (exist_cie == *cie) {
32187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines      // Insert the FDE fragment
32287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines      SectionData::iterator cur_iter(exist_cie);
32387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines      frag_list.insertAfter(cur_iter, fde);
32487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines      fde->setCIE(exist_cie);
32587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
32687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines      // Cleanup the CIE we created
32787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines      cie->clearFDEs();
32887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines      delete cie;
32987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines      break;
33087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    }
33187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  }
33287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  if (i == eh_frame->cie_end()) {
33387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    // Newly insert
33487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    eh_frame->addCIE(*cie);
33587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    eh_frame->addFDE(*fde);
33687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  }
33787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines}
33887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
3396f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines/// finalizeSymbol - finalize the symbol value
3406f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinesbool X86GNULDBackend::finalizeTargetSymbols()
3416f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines{
3426f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  return true;
3436f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines}
3446f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
3456f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines/// doCreateProgramHdrs - backend can implement this function to create the
3466f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines/// target-dependent segments
3476f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinesvoid X86GNULDBackend::doCreateProgramHdrs(Module& pModule)
3486f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines{
3496f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  // TODO
3506f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines}
3516f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
3526f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen HinesX86_32GNULDBackend::X86_32GNULDBackend(const LinkerConfig& pConfig,
353551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines                                       GNUInfo* pInfo)
3546f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  : X86GNULDBackend(pConfig, pInfo, llvm::ELF::R_386_COPY),
3556f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    m_pGOT (NULL),
3566f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    m_pGOTPLT (NULL) {
3576f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines}
3586f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
3596f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen HinesX86_32GNULDBackend::~X86_32GNULDBackend()
3606f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines{
3616f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  delete m_pGOT;
3626f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  delete m_pGOTPLT;
3636f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines}
3646f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
3656f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinesbool X86_32GNULDBackend::initRelocator()
3666f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines{
3676f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  if (NULL == m_pRelocator) {
368f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines    m_pRelocator = new X86_32Relocator(*this, config());
3696f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  }
3706f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  return true;
3716f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines}
3726f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
3736f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinesvoid X86_32GNULDBackend::initTargetSections(Module& pModule,
374551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines                                            ObjectBuilder& pBuilder)
3755460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
3766f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  if (LinkerConfig::Object != config().codeGenType()) {
3776f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    ELFFileFormat* file_format = getOutputFormat();
3786f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    // initialize .got
3796f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    LDSection& got = file_format->getGOT();
3806f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    m_pGOT = new X86_32GOT(got);
3815460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
3826f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    // initialize .got.plt
3836f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    LDSection& gotplt = file_format->getGOTPLT();
3846f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    m_pGOTPLT = new X86_32GOTPLT(gotplt);
385affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
3866f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    // initialize .plt
3876f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    LDSection& plt = file_format->getPLT();
38887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    plt.setAlign(16u);
389551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines    m_pPLT = new X86_32PLT(plt, *m_pGOTPLT, config());
39022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
3916f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    // initialize .rel.plt
3926f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    LDSection& relplt = file_format->getRelPlt();
3936f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    relplt.setLink(&plt);
3946f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    m_pRelPLT = new OutputRelocSection(pModule, relplt);
3956f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
3966f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    // initialize .rel.dyn
3976f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    LDSection& reldyn = file_format->getRelDyn();
3986f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    m_pRelDyn = new OutputRelocSection(pModule, reldyn);
39922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
4005460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
4015460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
4025460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
4036f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen HinesX86_32GOT& X86_32GNULDBackend::getGOT()
4045460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
4056f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  assert(NULL != m_pGOT);
4066f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  return *m_pGOT;
4076f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines}
4085460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
4096f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinesconst X86_32GOT& X86_32GNULDBackend::getGOT() const
4106f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines{
4116f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  assert(NULL != m_pGOT);
4126f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  return *m_pGOT;
4136f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines}
4145460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
4156f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen HinesX86_32GOTPLT& X86_32GNULDBackend::getGOTPLT()
4166f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines{
4176f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  assert(NULL != m_pGOTPLT);
4186f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  return *m_pGOTPLT;
4196f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines}
4205460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
4216f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinesconst X86_32GOTPLT& X86_32GNULDBackend::getGOTPLT() const
4226f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines{
4236f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  assert(NULL != m_pGOTPLT);
4246f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  return *m_pGOTPLT;
4256f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines}
4265460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
42787f34658dec9097d987d254a990ea7f311bfc95fStephen Hinesllvm::StringRef X86_32GNULDBackend::createCIERegionForPLT()
42887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines{
42987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  using namespace llvm::dwarf;
43087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  static const uint8_t data[4+4+16] = {
43187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    0x14, 0, 0, 0, // length
43287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    0, 0, 0, 0, // ID
43387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    1,  // version
43487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    'z', 'R', '\0', // augmentation string
43587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    1,  // code alignment factor
43687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    0x7c, // data alignment factor
43787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    8,  // return address column
43887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    1,  // augmentation data size
43987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    DW_EH_PE_pcrel | DW_EH_PE_sdata4, // FDE encoding
44087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    DW_CFA_def_cfa, 4, 4,
44187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    DW_CFA_offset + 8, 1,
44287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    DW_CFA_nop,
44387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    DW_CFA_nop
44487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  };
44587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  return llvm::StringRef((const char*)data, 4+4+16);
44687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines}
44787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
44887f34658dec9097d987d254a990ea7f311bfc95fStephen Hinesllvm::StringRef X86_32GNULDBackend::createFDERegionForPLT()
44987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines{
45087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  using namespace llvm::dwarf;
45187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  static const uint8_t data[4+4+32] = {
45287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    0x24, 0, 0, 0,  // length
45387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    0, 0, 0, 0,   // offset to CIE
45487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    0, 0, 0, 0,   // offset to PLT
45587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    0, 0, 0, 0,   // size of PLT
45687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    0,            // augmentation data size
45787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    DW_CFA_def_cfa_offset, 8,
45887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    DW_CFA_advance_loc + 6,
45987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    DW_CFA_def_cfa_offset, 12,
46087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    DW_CFA_advance_loc + 10,
46187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    DW_CFA_def_cfa_expression,
46287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    11,
46387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    DW_OP_breg4, 4,
46487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    DW_OP_breg8, 0,
46587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    DW_OP_lit15,
46687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    DW_OP_and,
46787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    DW_OP_lit11,
46887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    DW_OP_ge,
46987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    DW_OP_lit2,
47087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    DW_OP_shl,
47187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    DW_OP_plus,
47287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    DW_CFA_nop,
47387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    DW_CFA_nop,
47487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    DW_CFA_nop,
47587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    DW_CFA_nop
47687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  };
47787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  return llvm::StringRef((const char*)data, 4+4+32);
47887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines}
47987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
4806f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinesvoid X86_32GNULDBackend::setRelDynSize()
4816f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines{
4826f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  ELFFileFormat* file_format = getOutputFormat();
4836f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  file_format->getRelDyn().setSize
4846f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    (m_pRelDyn->numOfRelocs() * getRelEntrySize());
4856f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines}
4865460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
4876f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinesvoid X86_32GNULDBackend::setRelPLTSize()
4886f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines{
4896f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  ELFFileFormat* file_format = getOutputFormat();
4906f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  file_format->getRelPlt().setSize
4916f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    (m_pRelPLT->numOfRelocs() * getRelEntrySize());
4926f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines}
4935460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
4946f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinesvoid X86_32GNULDBackend::setGOTSectionSize(IRBuilder& pBuilder)
4956f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines{
4966f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  // set .got.plt size
4976f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  if (LinkerConfig::DynObj == config().codeGenType() ||
4986f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      m_pGOTPLT->hasGOT1() ||
4996f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      NULL != m_pGOTSymbol) {
5006f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    m_pGOTPLT->finalizeSectionSize();
5016f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    defineGOTSymbol(pBuilder, *(m_pGOTPLT->begin()));
5025460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
5035460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
5046f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  // set .got size
5056f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  if (!m_pGOT->empty())
5066f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    m_pGOT->finalizeSectionSize();
5076f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines}
5085460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
5096f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinesuint64_t X86_32GNULDBackend::emitGOTSectionData(MemoryRegion& pRegion) const
5106f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines{
5116f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  assert(m_pGOT && "emitGOTSectionData failed, m_pGOT is NULL!");
5125460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
51387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  uint32_t* buffer = reinterpret_cast<uint32_t*>(pRegion.begin());
5145460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
5156f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  X86_32GOTEntry* got = 0;
5166f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  unsigned int EntrySize = X86_32GOTEntry::EntrySize;
5176f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  uint64_t RegionSize = 0;
5186f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
5196f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  for (X86_32GOT::iterator it = m_pGOT->begin(),
5206f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines       ie = m_pGOT->end(); it != ie; ++it, ++buffer) {
5216f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    got = &(llvm::cast<X86_32GOTEntry>((*it)));
5226f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    *buffer = static_cast<uint32_t>(got->getValue());
5236f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    RegionSize += EntrySize;
5245460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
5255460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
5266f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  return RegionSize;
5276f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines}
528affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
5296f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinesuint64_t X86_32GNULDBackend::emitGOTPLTSectionData(MemoryRegion& pRegion,
530551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines                                                   const ELFFileFormat* FileFormat) const
5316f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines{
5326f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  assert(m_pGOTPLT && "emitGOTPLTSectionData failed, m_pGOTPLT is NULL!");
5336f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  m_pGOTPLT->applyGOT0(FileFormat->getDynamic().addr());
5346f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  m_pGOTPLT->applyAllGOTPLT(*m_pPLT);
535affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
53687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  uint32_t* buffer = reinterpret_cast<uint32_t*>(pRegion.begin());
5375460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
5386f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  X86_32GOTEntry* got = 0;
5396f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  unsigned int EntrySize = X86_32GOTEntry::EntrySize;
5406f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  uint64_t RegionSize = 0;
5416f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
5426f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  for (X86_32GOTPLT::iterator it = m_pGOTPLT->begin(),
5436f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines       ie = m_pGOTPLT->end(); it != ie; ++it, ++buffer) {
5446f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    got = &(llvm::cast<X86_32GOTEntry>((*it)));
5456f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    *buffer = static_cast<uint32_t>(got->getValue());
5466f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    RegionSize += EntrySize;
5476f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  }
5486f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
5496f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  return RegionSize;
5506f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines}
5516f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
5526f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen HinesX86_64GNULDBackend::X86_64GNULDBackend(const LinkerConfig& pConfig,
553551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines                                       GNUInfo* pInfo)
5546f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  : X86GNULDBackend(pConfig, pInfo, llvm::ELF::R_X86_64_COPY),
5556f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    m_pGOT (NULL),
5566f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    m_pGOTPLT (NULL) {
5576f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines}
5586f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
5596f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen HinesX86_64GNULDBackend::~X86_64GNULDBackend()
5606f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines{
5616f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  delete m_pGOT;
5626f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  delete m_pGOTPLT;
5636f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines}
5646f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
5656f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinesbool X86_64GNULDBackend::initRelocator()
5666f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines{
5676f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  if (NULL == m_pRelocator) {
568f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines    m_pRelocator = new X86_64Relocator(*this, config());
569affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  }
5706f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  return true;
5715460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
57222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
5736f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen HinesX86_64GOT& X86_64GNULDBackend::getGOT()
5745460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
5755460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  assert(NULL != m_pGOT);
5765460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  return *m_pGOT;
5775460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
5785460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
5796f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinesconst X86_64GOT& X86_64GNULDBackend::getGOT() const
5805460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
5815460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  assert(NULL != m_pGOT);
5825460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  return *m_pGOT;
5835460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
5845460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
5856f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen HinesX86_64GOTPLT& X86_64GNULDBackend::getGOTPLT()
586affc150dc44fab1911775a49636d0ce85333b634Zonr Chang{
587affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  assert(NULL != m_pGOTPLT);
588affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  return *m_pGOTPLT;
589affc150dc44fab1911775a49636d0ce85333b634Zonr Chang}
590affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
5916f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinesconst X86_64GOTPLT& X86_64GNULDBackend::getGOTPLT() const
592affc150dc44fab1911775a49636d0ce85333b634Zonr Chang{
593affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  assert(NULL != m_pGOTPLT);
594affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  return *m_pGOTPLT;
595affc150dc44fab1911775a49636d0ce85333b634Zonr Chang}
596affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
59787f34658dec9097d987d254a990ea7f311bfc95fStephen Hinesllvm::StringRef X86_64GNULDBackend::createCIERegionForPLT()
59887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines{
59987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  using namespace llvm::dwarf;
60087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  static const uint8_t data[4+4+16] = {
60187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    0x14, 0, 0, 0,  // length
60287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    0, 0, 0, 0,   // ID
60387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    1,          // CIE version
60487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    'z', 'R', '\0', // augmentation string
60587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    1,          // code alignment factor
60687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    0x78,       // data alignment factor
60787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    16,         // return address column
60887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    1,          // augmentation data size
60987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    DW_EH_PE_pcrel | DW_EH_PE_sdata4, // FDE encoding
61087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    DW_CFA_def_cfa, 7, 8,
61187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    DW_CFA_offset + 16, 1,
61287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    DW_CFA_nop,
61387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    DW_CFA_nop
61487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  };
61587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  return llvm::StringRef((const char*)data, 4+4+16);
61687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines}
61787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
61887f34658dec9097d987d254a990ea7f311bfc95fStephen Hinesllvm::StringRef X86_64GNULDBackend::createFDERegionForPLT()
61987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines{
62087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  using namespace llvm::dwarf;
62187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  static const uint8_t data[4+4+32] = {
62287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    0x24, 0, 0, 0,  // length
62387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    0, 0, 0, 0,   // ID
62487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    0, 0, 0, 0,   // offset to PLT
62587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    0, 0, 0, 0,   // size of PLT
62687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    0,            // augmentation data size
62787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    DW_CFA_def_cfa_offset, 16,
62887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    DW_CFA_advance_loc + 6,
62987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    DW_CFA_def_cfa_offset, 24,
63087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    DW_CFA_advance_loc + 10,
63187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    DW_CFA_def_cfa_expression,
63287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    11,
63387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    DW_OP_breg7, 8,
63487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    DW_OP_breg16, 0,
63587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    DW_OP_lit15,
63687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    DW_OP_and,
63787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    DW_OP_lit11,
63887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    DW_OP_ge,
63987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    DW_OP_lit3,
64087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    DW_OP_shl,
64187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    DW_OP_plus,
64287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    DW_CFA_nop,
64387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    DW_CFA_nop,
64487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    DW_CFA_nop,
64587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    DW_CFA_nop
64687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  };
64787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  return llvm::StringRef((const char*)data, 4+4+32);
64887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines}
64987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
6506f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinesvoid X86_64GNULDBackend::setRelDynSize()
6515460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
6526f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  ELFFileFormat* file_format = getOutputFormat();
6536f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  file_format->getRelaDyn().setSize
6546f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    (m_pRelDyn->numOfRelocs() * getRelaEntrySize());
6555460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
6565460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
6576f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinesvoid X86_64GNULDBackend::setRelPLTSize()
6585460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
6596f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  ELFFileFormat* file_format = getOutputFormat();
6606f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  file_format->getRelaPlt().setSize
6616f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    (m_pRelPLT->numOfRelocs() * getRelaEntrySize());
6625460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
6635460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
6646f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinesvoid X86_64GNULDBackend::initTargetSections(Module& pModule,
665551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines                                            ObjectBuilder& pBuilder)
66622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao{
66722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  if (LinkerConfig::Object != config().codeGenType()) {
66822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    ELFFileFormat* file_format = getOutputFormat();
66922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    // initialize .got
67022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    LDSection& got = file_format->getGOT();
6716f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    m_pGOT = new X86_64GOT(got);
67222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
67322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    // initialize .got.plt
67422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    LDSection& gotplt = file_format->getGOTPLT();
6756f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    m_pGOTPLT = new X86_64GOTPLT(gotplt);
67622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
67722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    // initialize .plt
67822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    LDSection& plt = file_format->getPLT();
67987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    plt.setAlign(16u);
680551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines    m_pPLT = new X86_64PLT(plt, *m_pGOTPLT, config());
68122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
6826f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    // initialize .rela.plt
6836f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    LDSection& relplt = file_format->getRelaPlt();
68422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    relplt.setLink(&plt);
685d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao    m_pRelPLT = new OutputRelocSection(pModule, relplt);
686d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao
6876f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    // initialize .rela.dyn
6886f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    LDSection& reldyn = file_format->getRelaDyn();
689d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao    m_pRelDyn = new OutputRelocSection(pModule, reldyn);
690d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao
69122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  }
6925460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
6935460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
6946f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinesvoid X86_64GNULDBackend::setGOTSectionSize(IRBuilder& pBuilder)
69522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao{
6966f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  // set .got.plt size
6976f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  if (LinkerConfig::DynObj == config().codeGenType() ||
6986f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      m_pGOTPLT->hasGOT1() ||
6996f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      NULL != m_pGOTSymbol) {
7006f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    m_pGOTPLT->finalizeSectionSize();
7016f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    defineGOTSymbol(pBuilder, *(m_pGOTPLT->begin()));
70222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  }
7036f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
7046f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  // set .got size
7056f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  if (!m_pGOT->empty())
7066f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    m_pGOT->finalizeSectionSize();
7075460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
7085460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
7096f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinesuint64_t X86_64GNULDBackend::emitGOTSectionData(MemoryRegion& pRegion) const
7105460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
7116f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  assert(m_pGOT && "emitGOTSectionData failed, m_pGOT is NULL!");
7126f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
71387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  uint64_t* buffer = reinterpret_cast<uint64_t*>(pRegion.begin());
7146f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
7156f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  X86_64GOTEntry* got = 0;
7166f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  unsigned int EntrySize = X86_64GOTEntry::EntrySize;
7176f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  uint64_t RegionSize = 0;
7186f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
7196f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  for (X86_64GOT::iterator it = m_pGOT->begin(),
7206f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines       ie = m_pGOT->end(); it != ie; ++it, ++buffer) {
7216f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    got = &(llvm::cast<X86_64GOTEntry>((*it)));
7226f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    *buffer = static_cast<uint64_t>(got->getValue());
7236f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    RegionSize += EntrySize;
7246f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  }
7256f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
7266f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  return RegionSize;
7275460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
7285460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
729551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hinesuint64_t
730551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen HinesX86_64GNULDBackend::emitGOTPLTSectionData(MemoryRegion& pRegion,
731551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines                                          const ELFFileFormat* FileFormat) const
732affc150dc44fab1911775a49636d0ce85333b634Zonr Chang{
7336f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  assert(m_pGOTPLT && "emitGOTPLTSectionData failed, m_pGOTPLT is NULL!");
7346f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  m_pGOTPLT->applyGOT0(FileFormat->getDynamic().addr());
7356f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  m_pGOTPLT->applyAllGOTPLT(*m_pPLT);
7366f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
73787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  uint64_t* buffer = reinterpret_cast<uint64_t*>(pRegion.begin());
7386f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
7396f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  X86_64GOTEntry* got = 0;
7406f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  unsigned int EntrySize = X86_64GOTEntry::EntrySize;
7416f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  uint64_t RegionSize = 0;
7426f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
7436f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  for (X86_64GOTPLT::iterator it = m_pGOTPLT->begin(),
7446f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines       ie = m_pGOTPLT->end(); it != ie; ++it, ++buffer) {
7456f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    got = &(llvm::cast<X86_64GOTEntry>((*it)));
7466f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    *buffer = static_cast<uint64_t>(got->getValue());
7476f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    RegionSize += EntrySize;
7486f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  }
7496f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
7506f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  return RegionSize;
7515460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
7525460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
7535460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaonamespace mcld {
7545460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
7555460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao//===----------------------------------------------------------------------===//
7565460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// createX86LDBackend - the help funtion to create corresponding X86LDBackend
7575460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao///
75887f34658dec9097d987d254a990ea7f311bfc95fStephen HinesTargetLDBackend* createX86LDBackend(const LinkerConfig& pConfig)
7595460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
760d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  if (pConfig.targets().triple().isOSDarwin()) {
7615460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    assert(0 && "MachO linker is not supported yet");
7625460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    /**
7635460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    return new X86MachOLDBackend(createX86MachOArchiveReader,
7645460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                               createX86MachOObjectReader,
7655460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                               createX86MachOObjectWriter);
7665460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    **/
7675460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
768d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  if (pConfig.targets().triple().isOSWindows()) {
7695460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    assert(0 && "COFF linker is not supported yet");
7705460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    /**
7715460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    return new X86COFFLDBackend(createX86COFFArchiveReader,
7725460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                               createX86COFFObjectReader,
7735460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                               createX86COFFObjectWriter);
7745460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    **/
7755460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
77687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  llvm::Triple::ArchType arch = pConfig.targets().triple().getArch();
77787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  if (arch == llvm::Triple::x86)
7786f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    return new X86_32GNULDBackend(pConfig,
779551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines                                  new X86_32GNUInfo(pConfig.targets().triple()));
78087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  assert (arch == llvm::Triple::x86_64);
7816f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  return new X86_64GNULDBackend(pConfig,
782551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines                                new X86_64GNUInfo(pConfig.targets().triple()));
7835460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
7845460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
7855460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} // namespace of mcld
7865460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
78722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao//===----------------------------------------------------------------------===//
7885460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao// Force static initialization.
78922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao//===----------------------------------------------------------------------===//
79022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaoextern "C" void MCLDInitializeX86LDBackend() {
7915460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // Register the linker backend
7926f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  mcld::TargetRegistry::RegisterTargetLDBackend(TheX86_32Target, createX86LDBackend);
7936f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  mcld::TargetRegistry::RegisterTargetLDBackend(TheX86_64Target, createX86LDBackend);
7945460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
795