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
155460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include <llvm/ADT/Triple.h>
16cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao#include <llvm/Support/Casting.h>
17cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao
1822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao#include <mcld/LinkerConfig.h>
1922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao#include <mcld/IRBuilder.h>
2022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao#include <mcld/Fragment/FillFragment.h>
2122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao#include <mcld/Fragment/RegionFragment.h>
2222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao#include <mcld/Fragment/FragmentLinker.h>
23affc150dc44fab1911775a49636d0ce85333b634Zonr Chang#include <mcld/Support/MemoryRegion.h>
24affc150dc44fab1911775a49636d0ce85333b634Zonr Chang#include <mcld/Support/MsgHandling.h>
25affc150dc44fab1911775a49636d0ce85333b634Zonr Chang#include <mcld/Support/TargetRegistry.h>
2622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao#include <mcld/Object/ObjectBuilder.h>
275460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
285460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include <cstring>
295460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
305460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaousing namespace mcld;
315460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
3222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao//===----------------------------------------------------------------------===//
3322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao// X86GNULDBackend
3422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao//===----------------------------------------------------------------------===//
356f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen HinesX86GNULDBackend::X86GNULDBackend(const LinkerConfig& pConfig,
366f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines				 GNUInfo* pInfo,
376f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines				 Relocation::Type pCopyRel)
38d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  : GNULDBackend(pConfig, pInfo),
39d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao    m_pRelocator(NULL),
405460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    m_pPLT(NULL),
415460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    m_pRelDyn(NULL),
425460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    m_pRelPLT(NULL),
4367e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao    m_pDynamic(NULL),
446f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    m_pGOTSymbol(NULL),
456f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    m_CopyRel(pCopyRel)
466f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines{
476f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  Triple::ArchType arch = pConfig.targets().triple().getArch();
486f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  assert (arch == Triple::x86 || arch == Triple::x86_64);
496f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  if (arch == Triple::x86 ||
506f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      pConfig.targets().triple().getEnvironment() == Triple::GNUX32) {
516f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    m_RelEntrySize = 8;
526f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    m_RelaEntrySize = 12;
536f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    if (arch == Triple::x86)
546f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      m_PointerRel = llvm::ELF::R_386_32;
556f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    else
566f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      m_PointerRel = llvm::ELF::R_X86_64_32;
576f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  }
586f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  else {
596f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    m_RelEntrySize = 16;
606f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    m_RelaEntrySize = 24;
616f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    m_PointerRel = llvm::ELF::R_X86_64_64;
626f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  }
635460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
645460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
655460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei LiaoX86GNULDBackend::~X86GNULDBackend()
665460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
67d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  delete m_pRelocator;
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
74d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei LiaoRelocator* X86GNULDBackend::getRelocator()
755460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
76d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  assert(NULL != m_pRelocator);
77d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  return m_pRelocator;
785460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
795460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
806f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinesvoid X86GNULDBackend::doPreLayout(IRBuilder& pBuilder)
815460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
826f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  // initialize .dynamic data
836f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  if (!config().isCodeStatic() && NULL == m_pDynamic)
846f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    m_pDynamic = new X86ELFDynamic(*this, config());
856f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
866f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  // set .got.plt and .got sizes
8722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  // when building shared object, the .got section is must
8822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  if (LinkerConfig::Object != config().codeGenType()) {
896f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    setGOTSectionSize(pBuilder);
9022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
9122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    // set .plt size
9222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    if (m_pPLT->hasPLT1())
9322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      m_pPLT->finalizeSectionSize();
9422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
956f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    // set .rel.dyn/.rela.dyn size
966f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    if (!m_pRelDyn->empty()) {
976f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      assert(!config().isCodeStatic() &&
986f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines            "static linkage should not result in a dynamic relocation section");
996f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      setRelDynSize();
1006f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    }
1016f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    // set .rel.plt/.rela.plt size
1026f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    if (!m_pRelPLT->empty()) {
1036f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      assert(!config().isCodeStatic() &&
1046f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines            "static linkage should not result in a dynamic relocation section");
1056f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      setRelPLTSize();
1066f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    }
107affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  }
1085460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
1095460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
11022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaovoid X86GNULDBackend::doPostLayout(Module& pModule,
1116f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines                                   IRBuilder& pBuilder)
1125460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
1135460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
1145460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1155460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// dynamic - the dynamic section of the target machine.
1165460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// Use co-variant return type to return its own dynamic section.
1175460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei LiaoX86ELFDynamic& X86GNULDBackend::dynamic()
1185460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
1196f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  assert(NULL != m_pDynamic);
1205460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  return *m_pDynamic;
1215460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
1225460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1235460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// dynamic - the dynamic section of the target machine.
1245460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// Use co-variant return type to return its own dynamic section.
1255460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaoconst X86ELFDynamic& X86GNULDBackend::dynamic() const
1265460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
1276f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  assert(NULL != m_pDynamic);
1285460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  return *m_pDynamic;
1295460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
1305460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1316f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinesvoid X86GNULDBackend::defineGOTSymbol(IRBuilder& pBuilder,
1326f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines				      Fragment& pFrag)
1335460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
13422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  // define symbol _GLOBAL_OFFSET_TABLE_
135affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  if (m_pGOTSymbol != NULL) {
1366f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    pBuilder.AddSymbol<IRBuilder::Force, IRBuilder::Unresolve>(
1375460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                     "_GLOBAL_OFFSET_TABLE_",
1385460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                     ResolveInfo::Object,
1395460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                     ResolveInfo::Define,
1405460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                     ResolveInfo::Local,
1415460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                     0x0, // size
1425460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                     0x0, // value
1436f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines                     FragmentRef::Create(pFrag, 0x0),
1445460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                     ResolveInfo::Hidden);
1455460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
1465460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  else {
1476f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    m_pGOTSymbol = pBuilder.AddSymbol<IRBuilder::Force, IRBuilder::Resolve>(
1485460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                     "_GLOBAL_OFFSET_TABLE_",
1495460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                     ResolveInfo::Object,
1505460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                     ResolveInfo::Define,
1515460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                     ResolveInfo::Local,
1525460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                     0x0, // size
1535460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                     0x0, // value
1546f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines                     FragmentRef::Create(pFrag, 0x0),
1555460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                     ResolveInfo::Hidden);
1565460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
1575460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
1585460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1596f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinesuint64_t X86GNULDBackend::emitSectionData(const LDSection& pSection,
1606f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines                                          MemoryRegion& pRegion) const
1616f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines{
1626f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  assert(pRegion.size() && "Size of MemoryRegion is zero!");
1636f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
1646f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  const ELFFileFormat* FileFormat = getOutputFormat();
1656f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  assert(FileFormat &&
1666f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines         "ELFFileFormat is NULL in X86GNULDBackend::emitSectionData!");
1676f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
1686f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  unsigned int EntrySize = 0;
1696f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  uint64_t RegionSize = 0;
1706f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
1716f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  if (&pSection == &(FileFormat->getPLT())) {
1726f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    assert(m_pPLT && "emitSectionData failed, m_pPLT is NULL!");
1736f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
1746f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    unsigned char* buffer = pRegion.getBuffer();
1756f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
1766f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    m_pPLT->applyPLT0();
1776f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    m_pPLT->applyPLT1();
1786f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    X86PLT::iterator it = m_pPLT->begin();
1796f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    unsigned int plt0_size = llvm::cast<PLTEntryBase>((*it)).size();
1806f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
1816f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    memcpy(buffer, llvm::cast<PLTEntryBase>((*it)).getValue(), plt0_size);
1826f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    RegionSize += plt0_size;
1836f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    ++it;
1846f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
1856f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    PLTEntryBase* plt1 = 0;
1866f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    X86PLT::iterator ie = m_pPLT->end();
1876f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    while (it != ie) {
1886f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      plt1 = &(llvm::cast<PLTEntryBase>(*it));
1896f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      EntrySize = plt1->size();
1906f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      memcpy(buffer + RegionSize, plt1->getValue(), EntrySize);
1916f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      RegionSize += EntrySize;
1926f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      ++it;
1936f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    }
1946f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  }
1956f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
1966f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  else if (&pSection == &(FileFormat->getGOT())) {
1976f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    RegionSize += emitGOTSectionData(pRegion);
1986f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  }
1996f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
2006f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  else if (&pSection == &(FileFormat->getGOTPLT())) {
2016f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    RegionSize += emitGOTPLTSectionData(pRegion, FileFormat);
2026f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  }
2036f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
2046f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  else {
2056f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    fatal(diag::unrecognized_output_sectoin)
2066f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines            << pSection.name()
2076f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines            << "mclinker@googlegroups.com";
2086f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  }
2096f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  return RegionSize;
2106f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines}
2116f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
2126f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen HinesX86PLT& X86GNULDBackend::getPLT()
2136f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines{
2146f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  assert(NULL != m_pPLT && "PLT section not exist");
2156f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  return *m_pPLT;
2166f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines}
2176f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
2186f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinesconst X86PLT& X86GNULDBackend::getPLT() const
2196f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines{
2206f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  assert(NULL != m_pPLT && "PLT section not exist");
2216f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  return *m_pPLT;
2226f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines}
2236f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
2246f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen HinesOutputRelocSection& X86GNULDBackend::getRelDyn()
2256f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines{
2266f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  assert(NULL != m_pRelDyn && ".rel.dyn/.rela.dyn section not exist");
2276f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  return *m_pRelDyn;
2286f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines}
2296f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
2306f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinesconst OutputRelocSection& X86GNULDBackend::getRelDyn() const
2316f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines{
2326f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  assert(NULL != m_pRelDyn && ".rel.dyn/.rela.dyn section not exist");
2336f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  return *m_pRelDyn;
2346f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines}
2356f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
2366f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen HinesOutputRelocSection& X86GNULDBackend::getRelPLT()
2376f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines{
2386f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  assert(NULL != m_pRelPLT && ".rel.plt/.rela.plt section not exist");
2396f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  return *m_pRelPLT;
2406f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines}
2416f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
2426f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinesconst OutputRelocSection& X86GNULDBackend::getRelPLT() const
2436f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines{
2446f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  assert(NULL != m_pRelPLT && ".rel.plt/.rela.plt section not exist");
2456f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  return *m_pRelPLT;
2466f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines}
2476f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
2486f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinesunsigned int
2496f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen HinesX86GNULDBackend::getTargetSectionOrder(const LDSection& pSectHdr) const
2506f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines{
2516f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  const ELFFileFormat* file_format = getOutputFormat();
2526f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
2536f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  if (&pSectHdr == &file_format->getGOT()) {
2546f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    if (config().options().hasNow())
2556f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      return SHO_RELRO;
2566f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    return SHO_RELRO_LAST;
2576f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  }
2586f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
2596f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  if (&pSectHdr == &file_format->getGOTPLT()) {
2606f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    if (config().options().hasNow())
2616f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      return SHO_RELRO;
2626f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    return SHO_NON_RELRO_FIRST;
2636f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  }
2646f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
2656f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  if (&pSectHdr == &file_format->getPLT())
2666f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    return SHO_PLT;
2676f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
2686f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  return SHO_UNDEFINED;
2696f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines}
2706f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
2716f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinesvoid X86GNULDBackend::initTargetSymbols(IRBuilder& pBuilder, Module& pModule)
2726f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines{
2736f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  if (LinkerConfig::Object != config().codeGenType()) {
2746f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    // Define the symbol _GLOBAL_OFFSET_TABLE_ if there is a symbol with the
2756f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    // same name in input
2766f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    m_pGOTSymbol =
2776f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      pBuilder.AddSymbol<IRBuilder::AsReferred, IRBuilder::Resolve>(
2786f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines                                                "_GLOBAL_OFFSET_TABLE_",
2796f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines                                                ResolveInfo::Object,
2806f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines                                                ResolveInfo::Define,
2816f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines                                                ResolveInfo::Local,
2826f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines                                                0x0,  // size
2836f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines                                                0x0,  // value
2846f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines                                                FragmentRef::Null(), // FragRef
2856f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines                                                ResolveInfo::Hidden);
2866f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  }
2876f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines}
2886f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
2896f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines/// finalizeSymbol - finalize the symbol value
2906f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinesbool X86GNULDBackend::finalizeTargetSymbols()
2916f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines{
2926f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  return true;
2936f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines}
2946f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
2956f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines/// doCreateProgramHdrs - backend can implement this function to create the
2966f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines/// target-dependent segments
2976f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinesvoid X86GNULDBackend::doCreateProgramHdrs(Module& pModule)
2986f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines{
2996f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  // TODO
3006f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines}
3016f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
3026f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen HinesX86_32GNULDBackend::X86_32GNULDBackend(const LinkerConfig& pConfig,
3036f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines				       GNUInfo* pInfo)
3046f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  : X86GNULDBackend(pConfig, pInfo, llvm::ELF::R_386_COPY),
3056f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    m_pGOT (NULL),
3066f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    m_pGOTPLT (NULL) {
3076f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines}
3086f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
3096f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen HinesX86_32GNULDBackend::~X86_32GNULDBackend()
3106f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines{
3116f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  delete m_pGOT;
3126f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  delete m_pGOTPLT;
3136f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines}
3146f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
3156f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinesbool X86_32GNULDBackend::initRelocator()
3166f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines{
3176f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  if (NULL == m_pRelocator) {
318f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines    m_pRelocator = new X86_32Relocator(*this, config());
3196f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  }
3206f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  return true;
3216f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines}
3226f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
3236f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinesvoid X86_32GNULDBackend::initTargetSections(Module& pModule,
3246f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines					    ObjectBuilder& pBuilder)
3255460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
3266f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  if (LinkerConfig::Object != config().codeGenType()) {
3276f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    ELFFileFormat* file_format = getOutputFormat();
3286f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    // initialize .got
3296f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    LDSection& got = file_format->getGOT();
3306f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    m_pGOT = new X86_32GOT(got);
3315460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
3326f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    // initialize .got.plt
3336f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    LDSection& gotplt = file_format->getGOTPLT();
3346f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    m_pGOTPLT = new X86_32GOTPLT(gotplt);
335affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
3366f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    // initialize .plt
3376f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    LDSection& plt = file_format->getPLT();
3386f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    m_pPLT = new X86_32PLT(plt,
3396f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines			   *m_pGOTPLT,
3406f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines			   config());
34122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
3426f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    // initialize .rel.plt
3436f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    LDSection& relplt = file_format->getRelPlt();
3446f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    relplt.setLink(&plt);
3456f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    m_pRelPLT = new OutputRelocSection(pModule, relplt);
3466f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
3476f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    // initialize .rel.dyn
3486f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    LDSection& reldyn = file_format->getRelDyn();
3496f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    m_pRelDyn = new OutputRelocSection(pModule, reldyn);
35022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
3515460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
3525460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
3535460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
3546f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen HinesX86_32GOT& X86_32GNULDBackend::getGOT()
3555460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
3566f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  assert(NULL != m_pGOT);
3576f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  return *m_pGOT;
3586f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines}
3595460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
3606f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinesconst X86_32GOT& X86_32GNULDBackend::getGOT() const
3616f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines{
3626f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  assert(NULL != m_pGOT);
3636f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  return *m_pGOT;
3646f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines}
3655460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
3666f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen HinesX86_32GOTPLT& X86_32GNULDBackend::getGOTPLT()
3676f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines{
3686f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  assert(NULL != m_pGOTPLT);
3696f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  return *m_pGOTPLT;
3706f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines}
3715460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
3726f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinesconst X86_32GOTPLT& X86_32GNULDBackend::getGOTPLT() const
3736f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines{
3746f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  assert(NULL != m_pGOTPLT);
3756f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  return *m_pGOTPLT;
3766f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines}
3775460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
3786f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinesvoid X86_32GNULDBackend::setRelDynSize()
3796f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines{
3806f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  ELFFileFormat* file_format = getOutputFormat();
3816f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  file_format->getRelDyn().setSize
3826f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    (m_pRelDyn->numOfRelocs() * getRelEntrySize());
3836f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines}
3845460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
3856f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinesvoid X86_32GNULDBackend::setRelPLTSize()
3866f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines{
3876f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  ELFFileFormat* file_format = getOutputFormat();
3886f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  file_format->getRelPlt().setSize
3896f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    (m_pRelPLT->numOfRelocs() * getRelEntrySize());
3906f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines}
3915460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
3926f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinesvoid X86_32GNULDBackend::setGOTSectionSize(IRBuilder& pBuilder)
3936f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines{
3946f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  // set .got.plt size
3956f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  if (LinkerConfig::DynObj == config().codeGenType() ||
3966f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      m_pGOTPLT->hasGOT1() ||
3976f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      NULL != m_pGOTSymbol) {
3986f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    m_pGOTPLT->finalizeSectionSize();
3996f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    defineGOTSymbol(pBuilder, *(m_pGOTPLT->begin()));
4005460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
4015460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
4026f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  // set .got size
4036f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  if (!m_pGOT->empty())
4046f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    m_pGOT->finalizeSectionSize();
4056f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines}
4065460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
4076f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinesuint64_t X86_32GNULDBackend::emitGOTSectionData(MemoryRegion& pRegion) const
4086f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines{
4096f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  assert(m_pGOT && "emitGOTSectionData failed, m_pGOT is NULL!");
4105460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
4116f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  uint32_t* buffer = reinterpret_cast<uint32_t*>(pRegion.getBuffer());
4125460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
4136f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  X86_32GOTEntry* got = 0;
4146f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  unsigned int EntrySize = X86_32GOTEntry::EntrySize;
4156f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  uint64_t RegionSize = 0;
4166f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
4176f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  for (X86_32GOT::iterator it = m_pGOT->begin(),
4186f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines       ie = m_pGOT->end(); it != ie; ++it, ++buffer) {
4196f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    got = &(llvm::cast<X86_32GOTEntry>((*it)));
4206f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    *buffer = static_cast<uint32_t>(got->getValue());
4216f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    RegionSize += EntrySize;
4225460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
4235460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
4246f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  return RegionSize;
4256f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines}
426affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
4276f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinesuint64_t X86_32GNULDBackend::emitGOTPLTSectionData(MemoryRegion& pRegion,
4286f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines						   const ELFFileFormat* FileFormat) const
4296f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines{
4306f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  assert(m_pGOTPLT && "emitGOTPLTSectionData failed, m_pGOTPLT is NULL!");
4316f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  m_pGOTPLT->applyGOT0(FileFormat->getDynamic().addr());
4326f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  m_pGOTPLT->applyAllGOTPLT(*m_pPLT);
433affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
4346f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  uint32_t* buffer = reinterpret_cast<uint32_t*>(pRegion.getBuffer());
4355460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
4366f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  X86_32GOTEntry* got = 0;
4376f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  unsigned int EntrySize = X86_32GOTEntry::EntrySize;
4386f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  uint64_t RegionSize = 0;
4396f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
4406f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  for (X86_32GOTPLT::iterator it = m_pGOTPLT->begin(),
4416f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines       ie = m_pGOTPLT->end(); it != ie; ++it, ++buffer) {
4426f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    got = &(llvm::cast<X86_32GOTEntry>((*it)));
4436f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    *buffer = static_cast<uint32_t>(got->getValue());
4446f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    RegionSize += EntrySize;
4456f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  }
4466f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
4476f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  return RegionSize;
4486f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines}
4496f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
4506f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen HinesX86_64GNULDBackend::X86_64GNULDBackend(const LinkerConfig& pConfig,
4516f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines				       GNUInfo* pInfo)
4526f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  : X86GNULDBackend(pConfig, pInfo, llvm::ELF::R_X86_64_COPY),
4536f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    m_pGOT (NULL),
4546f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    m_pGOTPLT (NULL) {
4556f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines}
4566f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
4576f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen HinesX86_64GNULDBackend::~X86_64GNULDBackend()
4586f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines{
4596f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  delete m_pGOT;
4606f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  delete m_pGOTPLT;
4616f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines}
4626f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
4636f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinesbool X86_64GNULDBackend::initRelocator()
4646f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines{
4656f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  if (NULL == m_pRelocator) {
466f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines    m_pRelocator = new X86_64Relocator(*this, config());
467affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  }
4686f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  return true;
4695460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
47022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
4716f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen HinesX86_64GOT& X86_64GNULDBackend::getGOT()
4725460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
4735460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  assert(NULL != m_pGOT);
4745460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  return *m_pGOT;
4755460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
4765460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
4776f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinesconst X86_64GOT& X86_64GNULDBackend::getGOT() const
4785460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
4795460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  assert(NULL != m_pGOT);
4805460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  return *m_pGOT;
4815460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
4825460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
4836f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen HinesX86_64GOTPLT& X86_64GNULDBackend::getGOTPLT()
484affc150dc44fab1911775a49636d0ce85333b634Zonr Chang{
485affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  assert(NULL != m_pGOTPLT);
486affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  return *m_pGOTPLT;
487affc150dc44fab1911775a49636d0ce85333b634Zonr Chang}
488affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
4896f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinesconst X86_64GOTPLT& X86_64GNULDBackend::getGOTPLT() const
490affc150dc44fab1911775a49636d0ce85333b634Zonr Chang{
491affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  assert(NULL != m_pGOTPLT);
492affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  return *m_pGOTPLT;
493affc150dc44fab1911775a49636d0ce85333b634Zonr Chang}
494affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
4956f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinesvoid X86_64GNULDBackend::setRelDynSize()
4965460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
4976f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  ELFFileFormat* file_format = getOutputFormat();
4986f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  file_format->getRelaDyn().setSize
4996f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    (m_pRelDyn->numOfRelocs() * getRelaEntrySize());
5005460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
5015460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
5026f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinesvoid X86_64GNULDBackend::setRelPLTSize()
5035460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
5046f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  ELFFileFormat* file_format = getOutputFormat();
5056f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  file_format->getRelaPlt().setSize
5066f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    (m_pRelPLT->numOfRelocs() * getRelaEntrySize());
5075460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
5085460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
5096f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinesvoid X86_64GNULDBackend::initTargetSections(Module& pModule,
5106f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines					    ObjectBuilder& pBuilder)
51122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao{
51222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  if (LinkerConfig::Object != config().codeGenType()) {
51322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    ELFFileFormat* file_format = getOutputFormat();
51422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    // initialize .got
51522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    LDSection& got = file_format->getGOT();
5166f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    m_pGOT = new X86_64GOT(got);
51722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
51822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    // initialize .got.plt
51922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    LDSection& gotplt = file_format->getGOTPLT();
5206f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    m_pGOTPLT = new X86_64GOTPLT(gotplt);
52122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
52222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    // initialize .plt
52322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    LDSection& plt = file_format->getPLT();
5246f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    m_pPLT = new X86_64PLT(plt,
5256f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines			   *m_pGOTPLT,
5266f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines			   config());
52722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
5286f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    // initialize .rela.plt
5296f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    LDSection& relplt = file_format->getRelaPlt();
53022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    relplt.setLink(&plt);
531d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao    m_pRelPLT = new OutputRelocSection(pModule, relplt);
532d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao
5336f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    // initialize .rela.dyn
5346f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    LDSection& reldyn = file_format->getRelaDyn();
535d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao    m_pRelDyn = new OutputRelocSection(pModule, reldyn);
536d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao
53722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  }
5385460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
5395460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
5406f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinesvoid X86_64GNULDBackend::setGOTSectionSize(IRBuilder& pBuilder)
54122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao{
5426f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  // set .got.plt size
5436f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  if (LinkerConfig::DynObj == config().codeGenType() ||
5446f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      m_pGOTPLT->hasGOT1() ||
5456f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      NULL != m_pGOTSymbol) {
5466f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    m_pGOTPLT->finalizeSectionSize();
5476f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    defineGOTSymbol(pBuilder, *(m_pGOTPLT->begin()));
54822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  }
5496f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
5506f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  // set .got size
5516f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  if (!m_pGOT->empty())
5526f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    m_pGOT->finalizeSectionSize();
5535460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
5545460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
5556f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinesuint64_t X86_64GNULDBackend::emitGOTSectionData(MemoryRegion& pRegion) const
5565460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
5576f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  assert(m_pGOT && "emitGOTSectionData failed, m_pGOT is NULL!");
5586f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
5596f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  uint64_t* buffer = reinterpret_cast<uint64_t*>(pRegion.getBuffer());
5606f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
5616f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  X86_64GOTEntry* got = 0;
5626f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  unsigned int EntrySize = X86_64GOTEntry::EntrySize;
5636f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  uint64_t RegionSize = 0;
5646f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
5656f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  for (X86_64GOT::iterator it = m_pGOT->begin(),
5666f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines       ie = m_pGOT->end(); it != ie; ++it, ++buffer) {
5676f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    got = &(llvm::cast<X86_64GOTEntry>((*it)));
5686f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    *buffer = static_cast<uint64_t>(got->getValue());
5696f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    RegionSize += EntrySize;
5706f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  }
5716f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
5726f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  return RegionSize;
5735460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
5745460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
5756f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinesuint64_t X86_64GNULDBackend::emitGOTPLTSectionData(MemoryRegion& pRegion,
5766f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines						   const ELFFileFormat* FileFormat) const
577affc150dc44fab1911775a49636d0ce85333b634Zonr Chang{
5786f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  assert(m_pGOTPLT && "emitGOTPLTSectionData failed, m_pGOTPLT is NULL!");
5796f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  m_pGOTPLT->applyGOT0(FileFormat->getDynamic().addr());
5806f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  m_pGOTPLT->applyAllGOTPLT(*m_pPLT);
5816f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
5826f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  uint64_t* buffer = reinterpret_cast<uint64_t*>(pRegion.getBuffer());
5836f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
5846f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  X86_64GOTEntry* got = 0;
5856f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  unsigned int EntrySize = X86_64GOTEntry::EntrySize;
5866f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  uint64_t RegionSize = 0;
5876f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
5886f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  for (X86_64GOTPLT::iterator it = m_pGOTPLT->begin(),
5896f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines       ie = m_pGOTPLT->end(); it != ie; ++it, ++buffer) {
5906f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    got = &(llvm::cast<X86_64GOTEntry>((*it)));
5916f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    *buffer = static_cast<uint64_t>(got->getValue());
5926f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    RegionSize += EntrySize;
5936f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  }
5946f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
5956f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  return RegionSize;
5965460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
5975460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
5985460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaonamespace mcld {
5995460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
6005460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao//===----------------------------------------------------------------------===//
6015460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// createX86LDBackend - the help funtion to create corresponding X86LDBackend
6025460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao///
6035460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei LiaoTargetLDBackend* createX86LDBackend(const llvm::Target& pTarget,
60422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                                    const LinkerConfig& pConfig)
6055460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
606d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  if (pConfig.targets().triple().isOSDarwin()) {
6075460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    assert(0 && "MachO linker is not supported yet");
6085460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    /**
6095460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    return new X86MachOLDBackend(createX86MachOArchiveReader,
6105460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                               createX86MachOObjectReader,
6115460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                               createX86MachOObjectWriter);
6125460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    **/
6135460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
614d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  if (pConfig.targets().triple().isOSWindows()) {
6155460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    assert(0 && "COFF linker is not supported yet");
6165460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    /**
6175460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    return new X86COFFLDBackend(createX86COFFArchiveReader,
6185460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                               createX86COFFObjectReader,
6195460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                               createX86COFFObjectWriter);
6205460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    **/
6215460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
6226f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  Triple::ArchType arch = pConfig.targets().triple().getArch();
6236f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  if (arch == Triple::x86)
6246f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    return new X86_32GNULDBackend(pConfig,
6256f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines				  new X86_32GNUInfo(pConfig.targets().triple()));
6266f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  assert (arch == Triple::x86_64);
6276f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  return new X86_64GNULDBackend(pConfig,
6286f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines				new X86_64GNUInfo(pConfig.targets().triple()));
6295460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
6305460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
6315460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} // namespace of mcld
6325460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
63322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao//===----------------------------------------------------------------------===//
6345460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao// Force static initialization.
63522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao//===----------------------------------------------------------------------===//
63622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaoextern "C" void MCLDInitializeX86LDBackend() {
6375460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // Register the linker backend
6386f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  mcld::TargetRegistry::RegisterTargetLDBackend(TheX86_32Target, createX86LDBackend);
6396f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  mcld::TargetRegistry::RegisterTargetLDBackend(TheX86_64Target, createX86LDBackend);
6405460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
641