X86LDBackend.cpp revision 6f75755c9204b1d8817ae5a65a2f7e5af0ec3f70
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
159affc150dc44fab1911775a49636d0ce85333b634Zonr Changvoid X86GNULDBackend::addCopyReloc(ResolveInfo& pSym)
1605460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
16122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  Relocation& rel_entry = *m_pRelDyn->consumeEntry();
1626f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  rel_entry.setType(m_CopyRel);
163affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  assert(pSym.outSymbol()->hasFragRef());
164affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  rel_entry.targetRef().assign(*pSym.outSymbol()->fragRef());
165affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  rel_entry.setSymInfo(&pSym);
1665460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
1675460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
16822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// defineSymbolforCopyReloc
16922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// For a symbol needing copy relocation, define a copy symbol in the BSS
17022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// section and all other reference to this symbol should refer to this
17122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// copy.
17222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// @note This is executed at `scan relocation' stage.
1736f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen HinesLDSymbol& X86GNULDBackend::defineSymbolforCopyReloc(IRBuilder& pBuilder,
174affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                                    const ResolveInfo& pSym)
1755460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
176affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  // get or create corresponding BSS LDSection
177affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  LDSection* bss_sect_hdr = NULL;
17822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  ELFFileFormat* file_format = getOutputFormat();
17922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  if (ResolveInfo::ThreadLocal == pSym.type())
18022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    bss_sect_hdr = &file_format->getTBSS();
18122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  else
18222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    bss_sect_hdr = &file_format->getBSS();
1835460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
184cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao  // get or create corresponding BSS SectionData
185affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  assert(NULL != bss_sect_hdr);
18622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  SectionData* bss_section = NULL;
18722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  if (bss_sect_hdr->hasSectionData())
18822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    bss_section = bss_sect_hdr->getSectionData();
18922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  else
19022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    bss_section = IRBuilder::CreateSectionData(*bss_sect_hdr);
191affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
192affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  // Determine the alignment by the symbol value
193affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  // FIXME: here we use the largest alignment
194d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  uint32_t addralign = config().targets().bitclass() / 8;
195affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
196affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  // allocate space in BSS for the copy symbol
197cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao  Fragment* frag = new FillFragment(0x0, 1, pSym.size());
19822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  uint64_t size = ObjectBuilder::AppendFragment(*frag,
19922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                                                *bss_section,
20022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                                                addralign);
201affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  bss_sect_hdr->setSize(bss_sect_hdr->size() + size);
202affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
203affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  // change symbol binding to Global if it's a weak symbol
204affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  ResolveInfo::Binding binding = (ResolveInfo::Binding)pSym.binding();
205affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  if (binding == ResolveInfo::Weak)
206affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    binding = ResolveInfo::Global;
207affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
208affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  // Define the copy symbol in the bss section and resolve it
2096f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  LDSymbol* cpy_sym = pBuilder.AddSymbol<IRBuilder::Force, IRBuilder::Resolve>(
210affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                      pSym.name(),
211affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                      (ResolveInfo::Type)pSym.type(),
212affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                      ResolveInfo::Define,
213affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                      binding,
214affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                      pSym.size(),  // size
215affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                      0x0,          // value
21622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                      FragmentRef::Create(*frag, 0x0),
217affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                      (ResolveInfo::Visibility)pSym.other());
218affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
219affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  return *cpy_sym;
2205460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
2215460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
2226f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinesvoid X86GNULDBackend::scanRelocation(Relocation& pReloc,
2236f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines                                     IRBuilder& pLinker,
22422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                                     Module& pModule,
2256f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines                                     LDSection& pSection)
2266f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines{
2276f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  if (LinkerConfig::Object == config().codeGenType())
2286f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    return;
2296f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  // rsym - The relocation target symbol
2306f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  ResolveInfo* rsym = pReloc.symInfo();
2316f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  assert(NULL != rsym &&
2326f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines         "ResolveInfo of relocation not set while scanRelocation");
2336f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
2346f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  pReloc.updateAddend();
2356f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  assert(NULL != pSection.getLink());
2366f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  if (0 == (pSection.getLink()->flag() & llvm::ELF::SHF_ALLOC))
2376f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    return;
2386f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
2396f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  // Scan relocation type to determine if the GOT/PLT/Dynamic Relocation
2406f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  // entries should be created.
2416f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  if (rsym->isLocal()) // rsym is local
2426f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    scanLocalReloc(pReloc, pLinker, pModule, pSection);
2436f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  else // rsym is external
2446f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    scanGlobalReloc(pReloc, pLinker, pModule, pSection);
2456f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
2466f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  // check if we should issue undefined reference for the relocation target
2476f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  // symbol
2486f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  if (rsym->isUndef() && !rsym->isDyn() && !rsym->isWeak() && !rsym->isNull())
2496f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    fatal(diag::undefined_reference) << rsym->name();
2506f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines}
2516f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
2526f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinesuint64_t X86GNULDBackend::emitSectionData(const LDSection& pSection,
2536f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines                                          MemoryRegion& pRegion) const
2546f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines{
2556f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  assert(pRegion.size() && "Size of MemoryRegion is zero!");
2566f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
2576f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  const ELFFileFormat* FileFormat = getOutputFormat();
2586f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  assert(FileFormat &&
2596f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines         "ELFFileFormat is NULL in X86GNULDBackend::emitSectionData!");
2606f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
2616f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  unsigned int EntrySize = 0;
2626f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  uint64_t RegionSize = 0;
2636f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
2646f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  if (&pSection == &(FileFormat->getPLT())) {
2656f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    assert(m_pPLT && "emitSectionData failed, m_pPLT is NULL!");
2666f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
2676f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    unsigned char* buffer = pRegion.getBuffer();
2686f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
2696f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    m_pPLT->applyPLT0();
2706f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    m_pPLT->applyPLT1();
2716f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    X86PLT::iterator it = m_pPLT->begin();
2726f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    unsigned int plt0_size = llvm::cast<PLTEntryBase>((*it)).size();
2736f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
2746f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    memcpy(buffer, llvm::cast<PLTEntryBase>((*it)).getValue(), plt0_size);
2756f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    RegionSize += plt0_size;
2766f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    ++it;
2776f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
2786f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    PLTEntryBase* plt1 = 0;
2796f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    X86PLT::iterator ie = m_pPLT->end();
2806f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    while (it != ie) {
2816f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      plt1 = &(llvm::cast<PLTEntryBase>(*it));
2826f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      EntrySize = plt1->size();
2836f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      memcpy(buffer + RegionSize, plt1->getValue(), EntrySize);
2846f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      RegionSize += EntrySize;
2856f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      ++it;
2866f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    }
2876f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  }
2886f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
2896f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  else if (&pSection == &(FileFormat->getGOT())) {
2906f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    RegionSize += emitGOTSectionData(pRegion);
2916f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  }
2926f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
2936f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  else if (&pSection == &(FileFormat->getGOTPLT())) {
2946f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    RegionSize += emitGOTPLTSectionData(pRegion, FileFormat);
2956f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  }
2966f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
2976f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  else {
2986f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    fatal(diag::unrecognized_output_sectoin)
2996f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines            << pSection.name()
3006f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines            << "mclinker@googlegroups.com";
3016f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  }
3026f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  return RegionSize;
3036f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines}
3046f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
3056f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen HinesX86PLT& X86GNULDBackend::getPLT()
3066f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines{
3076f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  assert(NULL != m_pPLT && "PLT section not exist");
3086f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  return *m_pPLT;
3096f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines}
3106f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
3116f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinesconst X86PLT& X86GNULDBackend::getPLT() const
3126f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines{
3136f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  assert(NULL != m_pPLT && "PLT section not exist");
3146f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  return *m_pPLT;
3156f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines}
3166f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
3176f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen HinesOutputRelocSection& X86GNULDBackend::getRelDyn()
3186f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines{
3196f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  assert(NULL != m_pRelDyn && ".rel.dyn/.rela.dyn section not exist");
3206f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  return *m_pRelDyn;
3216f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines}
3226f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
3236f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinesconst OutputRelocSection& X86GNULDBackend::getRelDyn() const
3246f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines{
3256f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  assert(NULL != m_pRelDyn && ".rel.dyn/.rela.dyn section not exist");
3266f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  return *m_pRelDyn;
3276f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines}
3286f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
3296f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen HinesOutputRelocSection& X86GNULDBackend::getRelPLT()
3306f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines{
3316f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  assert(NULL != m_pRelPLT && ".rel.plt/.rela.plt section not exist");
3326f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  return *m_pRelPLT;
3336f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines}
3346f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
3356f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinesconst OutputRelocSection& X86GNULDBackend::getRelPLT() const
3366f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines{
3376f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  assert(NULL != m_pRelPLT && ".rel.plt/.rela.plt section not exist");
3386f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  return *m_pRelPLT;
3396f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines}
3406f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
3416f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinesunsigned int
3426f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen HinesX86GNULDBackend::getTargetSectionOrder(const LDSection& pSectHdr) const
3436f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines{
3446f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  const ELFFileFormat* file_format = getOutputFormat();
3456f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
3466f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  if (&pSectHdr == &file_format->getGOT()) {
3476f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    if (config().options().hasNow())
3486f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      return SHO_RELRO;
3496f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    return SHO_RELRO_LAST;
3506f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  }
3516f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
3526f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  if (&pSectHdr == &file_format->getGOTPLT()) {
3536f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    if (config().options().hasNow())
3546f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      return SHO_RELRO;
3556f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    return SHO_NON_RELRO_FIRST;
3566f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  }
3576f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
3586f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  if (&pSectHdr == &file_format->getPLT())
3596f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    return SHO_PLT;
3606f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
3616f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  return SHO_UNDEFINED;
3626f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines}
3636f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
3646f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinesvoid X86GNULDBackend::initTargetSymbols(IRBuilder& pBuilder, Module& pModule)
3656f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines{
3666f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  if (LinkerConfig::Object != config().codeGenType()) {
3676f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    // Define the symbol _GLOBAL_OFFSET_TABLE_ if there is a symbol with the
3686f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    // same name in input
3696f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    m_pGOTSymbol =
3706f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      pBuilder.AddSymbol<IRBuilder::AsReferred, IRBuilder::Resolve>(
3716f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines                                                "_GLOBAL_OFFSET_TABLE_",
3726f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines                                                ResolveInfo::Object,
3736f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines                                                ResolveInfo::Define,
3746f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines                                                ResolveInfo::Local,
3756f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines                                                0x0,  // size
3766f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines                                                0x0,  // value
3776f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines                                                FragmentRef::Null(), // FragRef
3786f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines                                                ResolveInfo::Hidden);
3796f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  }
3806f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines}
3816f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
3826f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines/// finalizeSymbol - finalize the symbol value
3836f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinesbool X86GNULDBackend::finalizeTargetSymbols()
3846f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines{
3856f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  return true;
3866f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines}
3876f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
3886f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines/// doCreateProgramHdrs - backend can implement this function to create the
3896f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines/// target-dependent segments
3906f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinesvoid X86GNULDBackend::doCreateProgramHdrs(Module& pModule)
3916f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines{
3926f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  // TODO
3936f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines}
3946f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
3956f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen HinesX86_32GNULDBackend::X86_32GNULDBackend(const LinkerConfig& pConfig,
3966f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines				       GNUInfo* pInfo)
3976f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  : X86GNULDBackend(pConfig, pInfo, llvm::ELF::R_386_COPY),
3986f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    m_pGOT (NULL),
3996f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    m_pGOTPLT (NULL) {
4006f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines}
4016f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
4026f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen HinesX86_32GNULDBackend::~X86_32GNULDBackend()
4036f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines{
4046f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  delete m_pGOT;
4056f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  delete m_pGOTPLT;
4066f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines}
4076f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
4086f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinesbool X86_32GNULDBackend::initRelocator()
4096f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines{
4106f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  if (NULL == m_pRelocator) {
4116f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    m_pRelocator = new X86_32Relocator(*this);
4126f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  }
4136f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  return true;
4146f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines}
4156f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
4166f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinesvoid X86_32GNULDBackend::scanLocalReloc(Relocation& pReloc,
4176f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines					IRBuilder& pBuilder,
4186f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines					Module& pModule,
4196f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines					LDSection& pSection)
4205460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
4215460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // rsym - The relocation target symbol
4225460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  ResolveInfo* rsym = pReloc.symInfo();
4235460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
4245460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  switch(pReloc.type()){
4255460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
4265460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_386_32:
42722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    case llvm::ELF::R_386_16:
42822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    case llvm::ELF::R_386_8:
4295460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      // If buiding PIC object (shared library or PIC executable),
4305460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      // a dynamic relocations with RELATIVE type to this location is needed.
4315460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      // Reserve an entry in .rel.dyn
4326f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      if (config().isCodeIndep()) {
433d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao        m_pRelDyn->reserveEntry();
4345460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        // set Rel bit
4355460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        rsym->setReserved(rsym->reserved() | ReserveRel);
4366f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines        checkAndSetHasTextRel(*pSection.getLink());
4375460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      }
4385460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      return;
4395460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
4405460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_386_GOTOFF:
4415460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_386_GOTPC:
44222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      // FIXME: A GOT section is needed
44322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      return;
44422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
44522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    case llvm::ELF::R_386_GOT32:
44622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      // Symbol needs GOT entry, reserve entry in .got
44722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      // return if we already create GOT for this symbol
44822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      if (rsym->reserved() & (ReserveGOT | GOTRel))
44922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        return;
45022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      // FIXME: check STT_GNU_IFUNC symbol
45122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      m_pGOT->reserve();
4526f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
4536f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      // If the GOT is used in statically linked binaries,
4546f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      // the GOT entry is enough and no relocation is needed.
4556f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      if (config().isCodeStatic()) {
4566f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines        rsym->setReserved(rsym->reserved() | ReserveGOT);
4576f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines        return;
4586f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      }
45922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      // If building shared object or the symbol is undefined, a dynamic
46022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      // relocation is needed to relocate this GOT entry. Reserve an
46122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      // entry in .rel.dyn
46222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      if (LinkerConfig::DynObj ==
46322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                   config().codeGenType() || rsym->isUndef() || rsym->isDyn()) {
464d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao        m_pRelDyn->reserveEntry();
46522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        // set GOTRel bit
46622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        rsym->setReserved(rsym->reserved() | GOTRel);
46722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        return;
46822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      }
46922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      // set GOT bit
47022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      rsym->setReserved(rsym->reserved() | ReserveGOT);
4715460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      return;
4725460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
4735460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_386_PC32:
47422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    case llvm::ELF::R_386_PC16:
47522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    case llvm::ELF::R_386_PC8:
47622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      return;
47722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
47822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    case llvm::ELF::R_386_TLS_GD: {
47922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      // FIXME: no linker optimization for TLS relocation
48022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      if (rsym->reserved() & GOTRel)
48122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        return;
48222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      m_pGOT->reserve(2);
48322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      // reserve an rel entry
484d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao      m_pRelDyn->reserveEntry();
48522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      // set GOTRel bit
48622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      rsym->setReserved(rsym->reserved() | GOTRel);
48722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      // define the section symbol for .tdata or .tbss
48822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      // the target symbol of the created dynamic relocation should be the
48922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      // section symbol of the section which this symbol defined. so we
49022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      // need to define that section symbol here
49122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      ELFFileFormat* file_format = getOutputFormat();
49222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      const LDSection* sym_sect =
49322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao               &rsym->outSymbol()->fragRef()->frag()->getParent()->getSection();
49422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      if (&file_format->getTData() == sym_sect) {
49522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        if (NULL == f_pTDATA)
49622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao          f_pTDATA = pModule.getSectionSymbolSet().get(*sym_sect);
49722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      }
49822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      else if (&file_format->getTBSS() == sym_sect || rsym->isCommon()) {
49922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        if (NULL == f_pTBSS)
50022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao          f_pTBSS = pModule.getSectionSymbolSet().get(*sym_sect);
50122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      }
50222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      else
50322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        error(diag::invalid_tls) << rsym->name() << sym_sect->name();
50422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      return;
50522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    }
50622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
50722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    case llvm::ELF::R_386_TLS_LDM:
50822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      getTLSModuleID();
50922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      return;
51022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
51122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    case llvm::ELF::R_386_TLS_LDO_32:
51222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      return;
51322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
51422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    case llvm::ELF::R_386_TLS_IE:
51522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      setHasStaticTLS();
51622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      // if buildint shared object, a RELATIVE dynamic relocation is needed
51722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      if (LinkerConfig::DynObj == config().codeGenType()) {
518d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao        m_pRelDyn->reserveEntry();
51922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        rsym->setReserved(rsym->reserved() | ReserveRel);
5206f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines        checkAndSetHasTextRel(*pSection.getLink());
5216f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      } else {
5226f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines        // for local sym, we can convert ie to le if not building shared object
5236f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines        convertTLSIEtoLE(pReloc, pSection);
5246f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines        return;
52522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      }
52622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      if (rsym->reserved() & GOTRel)
52722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        return;
52822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      // reserve got and dyn relocation entries for tp-relative offset
52922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      m_pGOT->reserve();
530d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao      m_pRelDyn->reserveEntry();
53122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      // set GOTRel bit
53222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      rsym->setReserved(rsym->reserved() | GOTRel);
53322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      m_pRelDyn->addSymbolToDynSym(*rsym->outSymbol());
53422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      return;
53522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
53622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    case llvm::ELF::R_386_TLS_GOTIE:
53722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      setHasStaticTLS();
53822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      if (rsym->reserved() & GOTRel)
53922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        return;
54022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      // reserve got and dyn relocation entries for tp-relative offset
54122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      m_pGOT->reserve();
542d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao      m_pRelDyn->reserveEntry();
54322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      // set GOTRel bit
54422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      rsym->setReserved(rsym->reserved() | GOTRel);
54522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      m_pRelDyn->addSymbolToDynSym(*rsym->outSymbol());
54622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      return;
54722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
54822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    case llvm::ELF::R_386_TLS_LE:
54922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    case llvm::ELF::R_386_TLS_LE_32:
55022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      setHasStaticTLS();
55122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      // if buildint shared object, a dynamic relocation is needed
55222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      if (LinkerConfig::DynObj == config().codeGenType()) {
553d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao        m_pRelDyn->reserveEntry();
55422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        rsym->setReserved(rsym->reserved() | ReserveRel);
5556f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines        checkAndSetHasTextRel(*pSection.getLink());
55622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        // the target symbol of the dynamic relocation is rsym, so we need to
55722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        // emit it into .dynsym
55822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        assert(NULL != rsym->outSymbol());
55922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        m_pRelDyn->addSymbolToDynSym(*rsym->outSymbol());
56022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      }
5615460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      return;
5625460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
5635460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    default:
564affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      fatal(diag::unsupported_relocation) << (int)pReloc.type()
565affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                          << "mclinker@googlegroups.com";
5665460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      break;
5675460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  } // end switch
5685460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
5695460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
5706f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinesvoid X86_32GNULDBackend::scanGlobalReloc(Relocation& pReloc,
5716f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines					 IRBuilder& pBuilder,
5726f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines					 Module& pModule,
5736f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines					 LDSection& pSection)
5745460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
5755460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // rsym - The relocation target symbol
5765460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  ResolveInfo* rsym = pReloc.symInfo();
5775460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
5785460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  switch(pReloc.type()) {
5795460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_386_32:
58022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    case llvm::ELF::R_386_16:
58122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    case llvm::ELF::R_386_8:
5825460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      // Absolute relocation type, symbol may needs PLT entry or
5835460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      // dynamic relocation entry
5846f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      if (symbolNeedsPLT(*rsym)) {
5855460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        // create plt for this symbol if it does not have one
586affc150dc44fab1911775a49636d0ce85333b634Zonr Chang        if (!(rsym->reserved() & ReservePLT)){
5875460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao          // Symbol needs PLT entry, we need to reserve a PLT entry
5885460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao          // and the corresponding GOT and dynamic relocation entry
5895460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao          // in .got and .rel.plt. (GOT entry will be reserved simultaneously
5905460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao          // when calling X86PLT->reserveEntry())
5915460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao          m_pPLT->reserveEntry();
59222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao          m_pGOTPLT->reserve();
593d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao          m_pRelPLT->reserveEntry();
5945460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao          // set PLT bit
5955460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao          rsym->setReserved(rsym->reserved() | ReservePLT);
5965460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        }
5975460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      }
5985460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
5996f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      if (symbolNeedsDynRel(*rsym, (rsym->reserved() & ReservePLT), true)) {
6005460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        // symbol needs dynamic relocation entry, reserve an entry in .rel.dyn
601d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao        m_pRelDyn->reserveEntry();
6026f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines        if (symbolNeedsCopyReloc(pReloc, *rsym)) {
6036f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines          LDSymbol& cpy_sym = defineSymbolforCopyReloc(pBuilder, *rsym);
604affc150dc44fab1911775a49636d0ce85333b634Zonr Chang          addCopyReloc(*cpy_sym.resolveInfo());
605affc150dc44fab1911775a49636d0ce85333b634Zonr Chang        }
606affc150dc44fab1911775a49636d0ce85333b634Zonr Chang        else {
607affc150dc44fab1911775a49636d0ce85333b634Zonr Chang          // set Rel bit
608affc150dc44fab1911775a49636d0ce85333b634Zonr Chang          rsym->setReserved(rsym->reserved() | ReserveRel);
6096f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines          checkAndSetHasTextRel(pSection);
610affc150dc44fab1911775a49636d0ce85333b634Zonr Chang        }
6115460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      }
6125460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      return;
6135460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
6145460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_386_GOTOFF:
6155460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_386_GOTPC: {
61622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      // FIXME: A GOT section is needed
6175460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      return;
6185460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    }
6195460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
6205460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_386_PLT32:
6215460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      // A PLT entry is needed when building shared library
6225460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
6235460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      // return if we already create plt for this symbol
624affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      if (rsym->reserved() & ReservePLT)
6255460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        return;
6265460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
62722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      // if the symbol's value can be decided at link time, then no need plt
6286f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      if (symbolFinalValueIsKnown(*rsym))
62922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        return;
63022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
6315460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      // if symbol is defined in the ouput file and it's not
6325460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      // preemptible, no need plt
633affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      if (rsym->isDefine() && !rsym->isDyn() &&
63422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao         !isSymbolPreemptible(*rsym)) {
6355460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        return;
6365460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      }
6375460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
6385460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      // Symbol needs PLT entry, we need to reserve a PLT entry
6395460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      // and the corresponding GOT and dynamic relocation entry
6405460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      // in .got and .rel.plt. (GOT entry will be reserved simultaneously
6415460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      // when calling X86PLT->reserveEntry())
6425460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      m_pPLT->reserveEntry();
64322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      m_pGOTPLT->reserve();
644d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao      m_pRelPLT->reserveEntry();
6455460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      // set PLT bit
6465460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      rsym->setReserved(rsym->reserved() | ReservePLT);
6475460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      return;
6485460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
6495460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_386_GOT32:
6505460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      // Symbol needs GOT entry, reserve entry in .got
6515460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      // return if we already create GOT for this symbol
652affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      if (rsym->reserved() & (ReserveGOT | GOTRel))
6535460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        return;
65422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      m_pGOT->reserve();
6556f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
6566f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      // If the GOT is used in statically linked binaries,
6576f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      // the GOT entry is enough and no relocation is needed.
6586f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      if (config().isCodeStatic()) {
6596f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines        rsym->setReserved(rsym->reserved() | ReserveGOT);
6606f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines        return;
6616f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      }
6625460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      // If building shared object or the symbol is undefined, a dynamic
6635460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      // relocation is needed to relocate this GOT entry. Reserve an
6645460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      // entry in .rel.dyn
66522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      if (LinkerConfig::DynObj ==
66622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                   config().codeGenType() || rsym->isUndef() || rsym->isDyn()) {
667d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao        m_pRelDyn->reserveEntry();
6685460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        // set GOTRel bit
6695460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        rsym->setReserved(rsym->reserved() | GOTRel);
6705460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        return;
6715460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      }
6725460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      // set GOT bit
6735460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      rsym->setReserved(rsym->reserved() | ReserveGOT);
6745460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      return;
6755460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
6765460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_386_PC32:
67722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    case llvm::ELF::R_386_PC16:
67822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    case llvm::ELF::R_386_PC8:
6795460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
6806f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      if (symbolNeedsPLT(*rsym) &&
6816f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines          LinkerConfig::DynObj != config().codeGenType()) {
682affc150dc44fab1911775a49636d0ce85333b634Zonr Chang        // create plt for this symbol if it does not have one
683affc150dc44fab1911775a49636d0ce85333b634Zonr Chang        if (!(rsym->reserved() & ReservePLT)){
684affc150dc44fab1911775a49636d0ce85333b634Zonr Chang          // Symbol needs PLT entry, we need to reserve a PLT entry
685affc150dc44fab1911775a49636d0ce85333b634Zonr Chang          // and the corresponding GOT and dynamic relocation entry
686affc150dc44fab1911775a49636d0ce85333b634Zonr Chang          // in .got and .rel.plt. (GOT entry will be reserved simultaneously
687affc150dc44fab1911775a49636d0ce85333b634Zonr Chang          // when calling X86PLT->reserveEntry())
688affc150dc44fab1911775a49636d0ce85333b634Zonr Chang          m_pPLT->reserveEntry();
68922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao          m_pGOTPLT->reserve();
690d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao          m_pRelPLT->reserveEntry();
691affc150dc44fab1911775a49636d0ce85333b634Zonr Chang          // set PLT bit
692affc150dc44fab1911775a49636d0ce85333b634Zonr Chang          rsym->setReserved(rsym->reserved() | ReservePLT);
693affc150dc44fab1911775a49636d0ce85333b634Zonr Chang        }
694affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      }
695affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
6966f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      if (symbolNeedsDynRel(*rsym, (rsym->reserved() & ReservePLT), false)) {
697affc150dc44fab1911775a49636d0ce85333b634Zonr Chang        // symbol needs dynamic relocation entry, reserve an entry in .rel.dyn
698d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao        m_pRelDyn->reserveEntry();
6996f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines        if (symbolNeedsCopyReloc(pReloc, *rsym)) {
7006f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines          LDSymbol& cpy_sym = defineSymbolforCopyReloc(pBuilder, *rsym);
701affc150dc44fab1911775a49636d0ce85333b634Zonr Chang          addCopyReloc(*cpy_sym.resolveInfo());
702affc150dc44fab1911775a49636d0ce85333b634Zonr Chang        }
703affc150dc44fab1911775a49636d0ce85333b634Zonr Chang        else {
704affc150dc44fab1911775a49636d0ce85333b634Zonr Chang          // set Rel bit
705affc150dc44fab1911775a49636d0ce85333b634Zonr Chang          rsym->setReserved(rsym->reserved() | ReserveRel);
7066f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines          checkAndSetHasTextRel(pSection);
707affc150dc44fab1911775a49636d0ce85333b634Zonr Chang        }
708affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      }
709affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      return;
71022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
71122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    case llvm::ELF::R_386_TLS_GD: {
71222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      // FIXME: no linker optimization for TLS relocation
71322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      if (rsym->reserved() & GOTRel)
71422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        return;
71522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      // reserve two pairs of got entry and dynamic relocation
71622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      m_pGOT->reserve(2);
717d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao      m_pRelDyn->reserveEntry(2);
71822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      // set GOTRel bit
71922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      rsym->setReserved(rsym->reserved() | GOTRel);
72022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      return;
72122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    }
72222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
72322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    case llvm::ELF::R_386_TLS_LDM:
72422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      getTLSModuleID();
72522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      return;
72622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
72722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    case llvm::ELF::R_386_TLS_LDO_32:
72822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      return;
72922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
73022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    case llvm::ELF::R_386_TLS_IE:
73122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      setHasStaticTLS();
73222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      // if buildint shared object, a RELATIVE dynamic relocation is needed
73322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      if (LinkerConfig::DynObj == config().codeGenType()) {
734d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao        m_pRelDyn->reserveEntry();
73522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        rsym->setReserved(rsym->reserved() | ReserveRel);
7366f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines        checkAndSetHasTextRel(*pSection.getLink());
7376f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      } else {
7386f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines        // for global sym, we can convert ie to le if its final value is known
7396f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines        if (symbolFinalValueIsKnown(*rsym)) {
7406f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines          convertTLSIEtoLE(pReloc, pSection);
7416f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines          return;
7426f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines        }
74322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      }
74422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      if (rsym->reserved() & GOTRel)
74522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        return;
74622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      // reserve got and dyn relocation entries for tp-relative offset
74722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      m_pGOT->reserve();
748d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao      m_pRelDyn->reserveEntry();
74922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      // set GOTRel bit
75022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      rsym->setReserved(rsym->reserved() | GOTRel);
75122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      return;
75222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
75322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    case llvm::ELF::R_386_TLS_GOTIE:
75422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      setHasStaticTLS();
75522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      if (rsym->reserved() & GOTRel)
75622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        return;
75722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      // reserve got and dyn relocation entries for tp-relative offset
75822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      m_pGOT->reserve();
759d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao      m_pRelDyn->reserveEntry();
76022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      // set GOTRel bit
76122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      rsym->setReserved(rsym->reserved() | GOTRel);
76222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      return;
76322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
76422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    case llvm::ELF::R_386_TLS_LE:
76522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    case llvm::ELF::R_386_TLS_LE_32:
76622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      setHasStaticTLS();
76722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      // if buildint shared object, a dynamic relocation is needed
76822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      if (LinkerConfig::DynObj == config().codeGenType()) {
769d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao        m_pRelDyn->reserveEntry();
77022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        rsym->setReserved(rsym->reserved() | ReserveRel);
7716f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines        checkAndSetHasTextRel(*pSection.getLink());
77222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      }
77322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      return;
77422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
7755460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    default: {
776affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      fatal(diag::unsupported_relocation) << (int)pReloc.type()
777affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                          << "mclinker@googlegroups.com";
7785460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      break;
7795460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    }
7805460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  } // end switch
7815460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
7825460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
7836f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinesvoid X86_32GNULDBackend::initTargetSections(Module& pModule,
7846f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines					    ObjectBuilder& pBuilder)
7855460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
7866f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  if (LinkerConfig::Object != config().codeGenType()) {
7876f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    ELFFileFormat* file_format = getOutputFormat();
7886f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    // initialize .got
7896f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    LDSection& got = file_format->getGOT();
7906f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    m_pGOT = new X86_32GOT(got);
7915460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
7926f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    // initialize .got.plt
7936f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    LDSection& gotplt = file_format->getGOTPLT();
7946f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    m_pGOTPLT = new X86_32GOTPLT(gotplt);
795affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
7966f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    // initialize .plt
7976f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    LDSection& plt = file_format->getPLT();
7986f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    m_pPLT = new X86_32PLT(plt,
7996f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines			   *m_pGOTPLT,
8006f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines			   config());
80122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
8026f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    // initialize .rel.plt
8036f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    LDSection& relplt = file_format->getRelPlt();
8046f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    relplt.setLink(&plt);
8056f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    m_pRelPLT = new OutputRelocSection(pModule, relplt);
8066f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
8076f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    // initialize .rel.dyn
8086f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    LDSection& reldyn = file_format->getRelDyn();
8096f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    m_pRelDyn = new OutputRelocSection(pModule, reldyn);
81022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
8115460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
8125460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
8135460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
8146f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen HinesX86_32GOT& X86_32GNULDBackend::getGOT()
8155460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
8166f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  assert(NULL != m_pGOT);
8176f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  return *m_pGOT;
8186f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines}
8195460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
8206f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinesconst X86_32GOT& X86_32GNULDBackend::getGOT() const
8216f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines{
8226f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  assert(NULL != m_pGOT);
8236f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  return *m_pGOT;
8246f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines}
8255460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
8266f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen HinesX86_32GOTPLT& X86_32GNULDBackend::getGOTPLT()
8276f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines{
8286f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  assert(NULL != m_pGOTPLT);
8296f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  return *m_pGOTPLT;
8306f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines}
8315460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
8326f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinesconst X86_32GOTPLT& X86_32GNULDBackend::getGOTPLT() const
8336f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines{
8346f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  assert(NULL != m_pGOTPLT);
8356f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  return *m_pGOTPLT;
8366f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines}
8375460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
8386f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinesvoid X86_32GNULDBackend::setRelDynSize()
8396f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines{
8406f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  ELFFileFormat* file_format = getOutputFormat();
8416f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  file_format->getRelDyn().setSize
8426f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    (m_pRelDyn->numOfRelocs() * getRelEntrySize());
8436f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines}
8445460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
8456f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinesvoid X86_32GNULDBackend::setRelPLTSize()
8466f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines{
8476f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  ELFFileFormat* file_format = getOutputFormat();
8486f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  file_format->getRelPlt().setSize
8496f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    (m_pRelPLT->numOfRelocs() * getRelEntrySize());
8506f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines}
8515460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
8526f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinesvoid X86_32GNULDBackend::setGOTSectionSize(IRBuilder& pBuilder)
8536f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines{
8546f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  // set .got.plt size
8556f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  if (LinkerConfig::DynObj == config().codeGenType() ||
8566f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      m_pGOTPLT->hasGOT1() ||
8576f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      NULL != m_pGOTSymbol) {
8586f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    m_pGOTPLT->finalizeSectionSize();
8596f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    defineGOTSymbol(pBuilder, *(m_pGOTPLT->begin()));
8605460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
8615460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
8626f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  // set .got size
8636f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  if (!m_pGOT->empty())
8646f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    m_pGOT->finalizeSectionSize();
8656f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines}
8665460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
8676f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinesuint64_t X86_32GNULDBackend::emitGOTSectionData(MemoryRegion& pRegion) const
8686f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines{
8696f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  assert(m_pGOT && "emitGOTSectionData failed, m_pGOT is NULL!");
8705460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
8716f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  uint32_t* buffer = reinterpret_cast<uint32_t*>(pRegion.getBuffer());
8725460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
8736f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  X86_32GOTEntry* got = 0;
8746f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  unsigned int EntrySize = X86_32GOTEntry::EntrySize;
8756f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  uint64_t RegionSize = 0;
8766f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
8776f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  for (X86_32GOT::iterator it = m_pGOT->begin(),
8786f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines       ie = m_pGOT->end(); it != ie; ++it, ++buffer) {
8796f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    got = &(llvm::cast<X86_32GOTEntry>((*it)));
8806f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    *buffer = static_cast<uint32_t>(got->getValue());
8816f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    RegionSize += EntrySize;
8825460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
8835460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
8846f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  return RegionSize;
8856f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines}
886affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
8876f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinesuint64_t X86_32GNULDBackend::emitGOTPLTSectionData(MemoryRegion& pRegion,
8886f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines						   const ELFFileFormat* FileFormat) const
8896f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines{
8906f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  assert(m_pGOTPLT && "emitGOTPLTSectionData failed, m_pGOTPLT is NULL!");
8916f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  m_pGOTPLT->applyGOT0(FileFormat->getDynamic().addr());
8926f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  m_pGOTPLT->applyAllGOTPLT(*m_pPLT);
893affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
8946f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  uint32_t* buffer = reinterpret_cast<uint32_t*>(pRegion.getBuffer());
8955460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
8966f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  X86_32GOTEntry* got = 0;
8976f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  unsigned int EntrySize = X86_32GOTEntry::EntrySize;
8986f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  uint64_t RegionSize = 0;
8996f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
9006f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  for (X86_32GOTPLT::iterator it = m_pGOTPLT->begin(),
9016f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines       ie = m_pGOTPLT->end(); it != ie; ++it, ++buffer) {
9026f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    got = &(llvm::cast<X86_32GOTEntry>((*it)));
9036f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    *buffer = static_cast<uint32_t>(got->getValue());
9046f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    RegionSize += EntrySize;
9056f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  }
9066f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
9076f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  return RegionSize;
9086f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines}
9096f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
9106f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines/// convert R_386_TLS_IE to R_386_TLS_LE
9116f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinesvoid X86_32GNULDBackend::convertTLSIEtoLE(Relocation& pReloc,
9126f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines					  LDSection& pSection)
9136f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines{
9146f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  assert(pReloc.type() == llvm::ELF::R_386_TLS_IE);
9156f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  assert(NULL != pReloc.targetRef().frag());
9166f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
9176f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  // 1. create the fragment references and new relocs
9186f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  uint64_t off = pReloc.targetRef().offset();
9196f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  if (off >= 4)
9206f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    off -= 4;
9216f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  else
9226f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    off = 0;
9236f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
9246f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  FragmentRef* fragref = FragmentRef::Create(*pReloc.targetRef().frag(), off);
9256f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  // TODO: add symbols for R_386_TLS_OPT relocs
9266f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  Relocation* reloc = Relocation::Create(X86_32Relocator::R_386_TLS_OPT,
9276f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines                                         *fragref,
9286f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines                                         0x0);
9296f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
9306f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  // 2. modify the opcodes to the appropriate ones
9316f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  uint8_t* op =  (reinterpret_cast<uint8_t*>(&reloc->target()));
9326f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  off = pReloc.targetRef().offset() - reloc->targetRef().offset() - 1;
9336f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  if (op[off] == 0xa1) {
9346f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    op[off] = 0xb8;
9356f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  } else {
9366f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    switch (op[off - 1]) {
9376f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      case 0x8b:
9386f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines        assert((op[off] & 0xc7) == 0x05);
9396f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines        op[off - 1] = 0xc7;
9406f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines        op[off]     = 0xc0 | ((op[off] >> 3) & 7);
9416f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines        break;
9426f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      case 0x03:
9436f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines        assert((op[off] & 0xc7) == 0x05);
9446f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines        op[off - 1] = 0x81;
9456f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines        op[off]     = 0xc0 | ((op[off] >> 3) & 7);
9466f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines        break;
9476f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      default:
9486f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines        assert(0);
9496f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines        break;
950affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    }
951affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  }
952affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
9536f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  // 3. insert the new relocs "BEFORE" the original reloc.
9546f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  pSection.getRelocData()->getRelocationList().insert(
9556f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    RelocData::iterator(pReloc), reloc);
9566f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
9576f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  // 4. change the type of the original reloc
9586f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  pReloc.setType(llvm::ELF::R_386_TLS_LE);
9596f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines}
9606f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
9616f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines// Create a GOT entry for the TLS module index
9626f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen HinesX86_32GOTEntry& X86_32GNULDBackend::getTLSModuleID()
9636f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines{
9646f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  static X86_32GOTEntry* got_entry = NULL;
9656f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  if (NULL != got_entry)
9666f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    return *got_entry;
9676f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
9686f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  // Allocate 2 got entries and 1 dynamic reloc for R_386_TLS_LDM
9696f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  m_pGOT->reserve(2);
9706f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  got_entry = m_pGOT->consume();
9716f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  m_pGOT->consume()->setValue(0x0);
9726f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
9736f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  m_pRelDyn->reserveEntry();
9746f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  Relocation* rel_entry = m_pRelDyn->consumeEntry();
9756f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  rel_entry->setType(llvm::ELF::R_386_TLS_DTPMOD32);
9766f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  rel_entry->targetRef().assign(*got_entry, 0x0);
9776f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  rel_entry->setSymInfo(NULL);
9786f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
9796f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  return *got_entry;
9806f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines}
9816f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
9826f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen HinesX86_64GNULDBackend::X86_64GNULDBackend(const LinkerConfig& pConfig,
9836f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines				       GNUInfo* pInfo)
9846f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  : X86GNULDBackend(pConfig, pInfo, llvm::ELF::R_X86_64_COPY),
9856f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    m_pGOT (NULL),
9866f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    m_pGOTPLT (NULL) {
9876f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines}
9886f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
9896f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen HinesX86_64GNULDBackend::~X86_64GNULDBackend()
9906f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines{
9916f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  delete m_pGOT;
9926f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  delete m_pGOTPLT;
9936f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines}
9946f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
9956f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinesbool X86_64GNULDBackend::initRelocator()
9966f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines{
9976f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  if (NULL == m_pRelocator) {
9986f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    m_pRelocator = new X86_64Relocator(*this);
999affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  }
10006f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  return true;
10015460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
100222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
10036f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen HinesX86_64GOT& X86_64GNULDBackend::getGOT()
10045460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
10055460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  assert(NULL != m_pGOT);
10065460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  return *m_pGOT;
10075460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
10085460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
10096f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinesconst X86_64GOT& X86_64GNULDBackend::getGOT() const
10105460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
10115460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  assert(NULL != m_pGOT);
10125460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  return *m_pGOT;
10135460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
10145460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
10156f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen HinesX86_64GOTPLT& X86_64GNULDBackend::getGOTPLT()
1016affc150dc44fab1911775a49636d0ce85333b634Zonr Chang{
1017affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  assert(NULL != m_pGOTPLT);
1018affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  return *m_pGOTPLT;
1019affc150dc44fab1911775a49636d0ce85333b634Zonr Chang}
1020affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
10216f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinesconst X86_64GOTPLT& X86_64GNULDBackend::getGOTPLT() const
1022affc150dc44fab1911775a49636d0ce85333b634Zonr Chang{
1023affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  assert(NULL != m_pGOTPLT);
1024affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  return *m_pGOTPLT;
1025affc150dc44fab1911775a49636d0ce85333b634Zonr Chang}
1026affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
10276f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinesvoid X86_64GNULDBackend::setRelDynSize()
10285460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
10296f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  ELFFileFormat* file_format = getOutputFormat();
10306f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  file_format->getRelaDyn().setSize
10316f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    (m_pRelDyn->numOfRelocs() * getRelaEntrySize());
10325460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
10335460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
10346f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinesvoid X86_64GNULDBackend::setRelPLTSize()
10355460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
10366f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  ELFFileFormat* file_format = getOutputFormat();
10376f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  file_format->getRelaPlt().setSize
10386f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    (m_pRelPLT->numOfRelocs() * getRelaEntrySize());
10395460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
10405460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
10416f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinesvoid X86_64GNULDBackend::scanLocalReloc(Relocation& pReloc,
10426f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines					IRBuilder& pBuilder,
10436f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines					Module& pModule,
10446f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines					LDSection& pSection)
10455460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
10466f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  // rsym - The relocation target symbol
10476f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  ResolveInfo* rsym = pReloc.symInfo();
10485460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
10496f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  switch(pReloc.type()){
10506f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    case llvm::ELF::R_X86_64_64:
10516f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    case llvm::ELF::R_X86_64_32:
10526f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    case llvm::ELF::R_X86_64_16:
10536f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    case llvm::ELF::R_X86_64_8:
10546f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    case llvm::ELF::R_X86_64_32S:
10556f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      // If buiding PIC object (shared library or PIC executable),
10566f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      // a dynamic relocations with RELATIVE type to this location is needed.
10576f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      // Reserve an entry in .rela.dyn
10586f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      if (config().isCodeIndep()) {
10596f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines        m_pRelDyn->reserveEntry();
10606f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines        // set Rel bit
10616f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines        rsym->setReserved(rsym->reserved() | ReserveRel);
10626f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines        checkAndSetHasTextRel(*pSection.getLink());
10636f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      }
10646f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      return;
10655460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
10666f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    case llvm::ELF::R_X86_64_PC32:
10676f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    case llvm::ELF::R_X86_64_PC16:
10686f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    case llvm::ELF::R_X86_64_PC8:
10696f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      return;
107022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
10716f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    case llvm::ELF::R_X86_64_GOTPCREL:
10726f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      // Symbol needs GOT entry, reserve entry in .got
10736f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      // return if we already create GOT for this symbol
10746f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      if (rsym->reserved() & (ReserveGOT | GOTRel))
10756f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines        return;
10766f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      m_pGOT->reserve();
107722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
10786f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      // If the GOT is used in statically linked binaries,
10796f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      // the GOT entry is enough and no relocation is needed.
10806f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      if (config().isCodeStatic()) {
10816f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines        rsym->setReserved(rsym->reserved() | ReserveGOT);
10826f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines        return;
10836f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      }
10846f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      // If building shared object or the symbol is undefined, a dynamic
10856f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      // relocation is needed to relocate this GOT entry. Reserve an
10866f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      // entry in .rela.dyn
10876f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      if (LinkerConfig::DynObj ==
10886f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines                   config().codeGenType() || rsym->isUndef() || rsym->isDyn()) {
10896f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines        m_pRelDyn->reserveEntry();
10906f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines        // set GOTRel bit
10916f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines        rsym->setReserved(rsym->reserved() | GOTRel);
10926f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines        return;
10936f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      }
10946f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      // set GOT bit
10956f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      rsym->setReserved(rsym->reserved() | ReserveGOT);
10966f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      return;
109722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
10986f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    default:
10996f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      fatal(diag::unsupported_relocation) << (int)pReloc.type()
11006f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines                                          << "mclinker@googlegroups.com";
11016f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      break;
11026f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  } // end switch
110322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao}
110422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
11056f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinesvoid X86_64GNULDBackend::scanGlobalReloc(Relocation& pReloc,
11066f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines					 IRBuilder& pBuilder,
11076f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines					 Module& pModule,
11086f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines					 LDSection& pSection)
11095460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
11106f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  // rsym - The relocation target symbol
11116f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  ResolveInfo* rsym = pReloc.symInfo();
11125460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
11136f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  switch(pReloc.type()) {
11146f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    case llvm::ELF::R_X86_64_64:
11156f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    case llvm::ELF::R_X86_64_32:
11166f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    case llvm::ELF::R_X86_64_16:
11176f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    case llvm::ELF::R_X86_64_8:
11186f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    case llvm::ELF::R_X86_64_32S:
11196f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      // Absolute relocation type, symbol may needs PLT entry or
11206f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      // dynamic relocation entry
11216f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      if (symbolNeedsPLT(*rsym)) {
11226f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines        // create plt for this symbol if it does not have one
11236f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines        if (!(rsym->reserved() & ReservePLT)){
11246f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines          // Symbol needs PLT entry, we need to reserve a PLT entry
11256f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines          // and the corresponding GOT and dynamic relocation entry
11266f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines          // in .got and .rela.plt. (GOT entry will be reserved simultaneously
11276f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines          // when calling X86PLT->reserveEntry())
11286f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines          m_pPLT->reserveEntry();
11296f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines          m_pGOTPLT->reserve();
11306f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines          m_pRelPLT->reserveEntry();
11316f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines          // set PLT bit
11326f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines          rsym->setReserved(rsym->reserved() | ReservePLT);
11336f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines        }
11346f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      }
11355460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
11366f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      if (symbolNeedsDynRel(*rsym, (rsym->reserved() & ReservePLT), true)) {
11376f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines        // symbol needs dynamic relocation entry, reserve an entry in .rela.dyn
11386f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines        m_pRelDyn->reserveEntry();
11396f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines        if (symbolNeedsCopyReloc(pReloc, *rsym)) {
11406f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines          LDSymbol& cpy_sym = defineSymbolforCopyReloc(pBuilder, *rsym);
11416f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines          addCopyReloc(*cpy_sym.resolveInfo());
11426f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines        }
11436f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines        else {
11446f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines          // set Rel bit
11456f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines          rsym->setReserved(rsym->reserved() | ReserveRel);
11466f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines	  checkAndSetHasTextRel(*pSection.getLink());
11476f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines        }
11486f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      }
11496f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      return;
11505460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
11516f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    case llvm::ELF::R_X86_64_GOTPCREL:
11526f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      // Symbol needs GOT entry, reserve entry in .got
11536f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      // return if we already create GOT for this symbol
11546f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      if (rsym->reserved() & (ReserveGOT | GOTRel))
11556f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines        return;
11566f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      m_pGOT->reserve();
11575460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
11586f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      // If the GOT is used in statically linked binaries,
11596f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      // the GOT entry is enough and no relocation is needed.
11606f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      if (config().isCodeStatic()) {
11616f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines        rsym->setReserved(rsym->reserved() | ReserveGOT);
11626f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines        return;
11636f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      }
11646f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      // If building shared object or the symbol is undefined, a dynamic
11656f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      // relocation is needed to relocate this GOT entry. Reserve an
11666f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      // entry in .rela.dyn
11676f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      if (LinkerConfig::DynObj ==
11686f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines                   config().codeGenType() || rsym->isUndef() || rsym->isDyn()) {
11696f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines        m_pRelDyn->reserveEntry();
11706f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines        // set GOTRel bit
11716f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines        rsym->setReserved(rsym->reserved() | GOTRel);
11726f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines        return;
11736f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      }
11746f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      // set GOT bit
11756f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      rsym->setReserved(rsym->reserved() | ReserveGOT);
11766f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      return;
11775460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
11786f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    case llvm::ELF::R_X86_64_PLT32:
11796f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      // A PLT entry is needed when building shared library
11805460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
11816f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      // return if we already create plt for this symbol
11826f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      if (rsym->reserved() & ReservePLT)
11836f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines        return;
11846f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
11856f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      // if the symbol's value can be decided at link time, then no need plt
11866f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      if (symbolFinalValueIsKnown(*rsym))
11876f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines        return;
11886f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
11896f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      // if symbol is defined in the ouput file and it's not
11906f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      // preemptible, no need plt
11916f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      if (rsym->isDefine() && !rsym->isDyn() &&
11926f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines         !isSymbolPreemptible(*rsym)) {
11936f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines        return;
11946f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      }
11956f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
11966f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      // Symbol needs PLT entry, we need to reserve a PLT entry
11976f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      // and the corresponding GOT and dynamic relocation entry
11986f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      // in .got and .rel.plt. (GOT entry will be reserved simultaneously
11996f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      // when calling X86PLT->reserveEntry())
12006f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      m_pPLT->reserveEntry();
12016f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      m_pGOTPLT->reserve();
12026f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      m_pRelPLT->reserveEntry();
12036f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      // set PLT bit
12046f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      rsym->setReserved(rsym->reserved() | ReservePLT);
12056f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      return;
12066f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
12076f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    case llvm::ELF::R_X86_64_PC32:
12086f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    case llvm::ELF::R_X86_64_PC16:
12096f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    case llvm::ELF::R_X86_64_PC8:
12106f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      if (symbolNeedsPLT(*rsym) &&
12116f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines          LinkerConfig::DynObj != config().codeGenType()) {
12126f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines        // create plt for this symbol if it does not have one
12136f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines        if (!(rsym->reserved() & ReservePLT)){
12146f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines          // Symbol needs PLT entry, we need to reserve a PLT entry
12156f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines          // and the corresponding GOT and dynamic relocation entry
12166f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines          // in .got and .rel.plt. (GOT entry will be reserved simultaneously
12176f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines          // when calling X86PLT->reserveEntry())
12186f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines          m_pPLT->reserveEntry();
12196f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines          m_pGOTPLT->reserve();
12206f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines          m_pRelPLT->reserveEntry();
12216f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines          // set PLT bit
12226f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines          rsym->setReserved(rsym->reserved() | ReservePLT);
12236f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines        }
12246f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      }
12256f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
12266f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      // Only PC relative relocation against dynamic symbol needs a
12276f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      // dynamic relocation.  Only dynamic copy relocation is allowed
12286f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      // and PC relative relocation will be resolved to the local copy.
12296f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      // All other dynamic relocations may lead to run-time relocation
12306f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      // overflow.
12316f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      if (isDynamicSymbol(*rsym) &&
12326f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines	  symbolNeedsDynRel(*rsym, (rsym->reserved() & ReservePLT), false) &&
12336f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines	  symbolNeedsCopyReloc(pReloc, *rsym)) {
12346f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines        m_pRelDyn->reserveEntry();
12356f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines	LDSymbol& cpy_sym = defineSymbolforCopyReloc(pBuilder, *rsym);
12366f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines	addCopyReloc(*cpy_sym.resolveInfo());
12376f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      }
12386f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      return;
12396f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
12406f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    default:
12416f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      fatal(diag::unsupported_relocation) << (int)pReloc.type()
12426f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines                                          << "mclinker@googlegroups.com";
12436f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      break;
12446f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  } // end switch
12455460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
12465460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
12476f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinesvoid X86_64GNULDBackend::initTargetSections(Module& pModule,
12486f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines					    ObjectBuilder& pBuilder)
124922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao{
125022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  if (LinkerConfig::Object != config().codeGenType()) {
125122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    ELFFileFormat* file_format = getOutputFormat();
125222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    // initialize .got
125322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    LDSection& got = file_format->getGOT();
12546f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    m_pGOT = new X86_64GOT(got);
125522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
125622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    // initialize .got.plt
125722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    LDSection& gotplt = file_format->getGOTPLT();
12586f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    m_pGOTPLT = new X86_64GOTPLT(gotplt);
125922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
126022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    // initialize .plt
126122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    LDSection& plt = file_format->getPLT();
12626f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    m_pPLT = new X86_64PLT(plt,
12636f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines			   *m_pGOTPLT,
12646f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines			   config());
126522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
12666f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    // initialize .rela.plt
12676f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    LDSection& relplt = file_format->getRelaPlt();
126822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    relplt.setLink(&plt);
1269d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao    m_pRelPLT = new OutputRelocSection(pModule, relplt);
1270d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao
12716f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    // initialize .rela.dyn
12726f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    LDSection& reldyn = file_format->getRelaDyn();
1273d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao    m_pRelDyn = new OutputRelocSection(pModule, reldyn);
1274d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao
127522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  }
12765460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
12775460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
12786f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinesvoid X86_64GNULDBackend::setGOTSectionSize(IRBuilder& pBuilder)
127922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao{
12806f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  // set .got.plt size
12816f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  if (LinkerConfig::DynObj == config().codeGenType() ||
12826f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      m_pGOTPLT->hasGOT1() ||
12836f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      NULL != m_pGOTSymbol) {
12846f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    m_pGOTPLT->finalizeSectionSize();
12856f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    defineGOTSymbol(pBuilder, *(m_pGOTPLT->begin()));
128622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  }
12876f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
12886f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  // set .got size
12896f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  if (!m_pGOT->empty())
12906f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    m_pGOT->finalizeSectionSize();
12915460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
12925460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
12936f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinesuint64_t X86_64GNULDBackend::emitGOTSectionData(MemoryRegion& pRegion) const
12945460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
12956f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  assert(m_pGOT && "emitGOTSectionData failed, m_pGOT is NULL!");
12966f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
12976f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  uint64_t* buffer = reinterpret_cast<uint64_t*>(pRegion.getBuffer());
12986f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
12996f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  X86_64GOTEntry* got = 0;
13006f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  unsigned int EntrySize = X86_64GOTEntry::EntrySize;
13016f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  uint64_t RegionSize = 0;
13026f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
13036f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  for (X86_64GOT::iterator it = m_pGOT->begin(),
13046f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines       ie = m_pGOT->end(); it != ie; ++it, ++buffer) {
13056f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    got = &(llvm::cast<X86_64GOTEntry>((*it)));
13066f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    *buffer = static_cast<uint64_t>(got->getValue());
13076f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    RegionSize += EntrySize;
13086f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  }
13096f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
13106f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  return RegionSize;
13115460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
13125460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
13136f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinesuint64_t X86_64GNULDBackend::emitGOTPLTSectionData(MemoryRegion& pRegion,
13146f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines						   const ELFFileFormat* FileFormat) const
1315affc150dc44fab1911775a49636d0ce85333b634Zonr Chang{
13166f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  assert(m_pGOTPLT && "emitGOTPLTSectionData failed, m_pGOTPLT is NULL!");
13176f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  m_pGOTPLT->applyGOT0(FileFormat->getDynamic().addr());
13186f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  m_pGOTPLT->applyAllGOTPLT(*m_pPLT);
13196f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
13206f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  uint64_t* buffer = reinterpret_cast<uint64_t*>(pRegion.getBuffer());
13216f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
13226f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  X86_64GOTEntry* got = 0;
13236f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  unsigned int EntrySize = X86_64GOTEntry::EntrySize;
13246f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  uint64_t RegionSize = 0;
13256f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
13266f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  for (X86_64GOTPLT::iterator it = m_pGOTPLT->begin(),
13276f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines       ie = m_pGOTPLT->end(); it != ie; ++it, ++buffer) {
13286f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    got = &(llvm::cast<X86_64GOTEntry>((*it)));
13296f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    *buffer = static_cast<uint64_t>(got->getValue());
13306f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    RegionSize += EntrySize;
13316f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  }
13326f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
13336f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  return RegionSize;
13345460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
13355460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
13365460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaonamespace mcld {
13375460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
13385460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao//===----------------------------------------------------------------------===//
13395460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// createX86LDBackend - the help funtion to create corresponding X86LDBackend
13405460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao///
13415460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei LiaoTargetLDBackend* createX86LDBackend(const llvm::Target& pTarget,
134222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                                    const LinkerConfig& pConfig)
13435460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
1344d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  if (pConfig.targets().triple().isOSDarwin()) {
13455460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    assert(0 && "MachO linker is not supported yet");
13465460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    /**
13475460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    return new X86MachOLDBackend(createX86MachOArchiveReader,
13485460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                               createX86MachOObjectReader,
13495460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                               createX86MachOObjectWriter);
13505460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    **/
13515460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
1352d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  if (pConfig.targets().triple().isOSWindows()) {
13535460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    assert(0 && "COFF linker is not supported yet");
13545460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    /**
13555460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    return new X86COFFLDBackend(createX86COFFArchiveReader,
13565460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                               createX86COFFObjectReader,
13575460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                               createX86COFFObjectWriter);
13585460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    **/
13595460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
13606f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  Triple::ArchType arch = pConfig.targets().triple().getArch();
13616f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  if (arch == Triple::x86)
13626f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    return new X86_32GNULDBackend(pConfig,
13636f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines				  new X86_32GNUInfo(pConfig.targets().triple()));
13646f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  assert (arch == Triple::x86_64);
13656f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  return new X86_64GNULDBackend(pConfig,
13666f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines				new X86_64GNUInfo(pConfig.targets().triple()));
13675460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
13685460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
13695460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} // namespace of mcld
13705460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
137122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao//===----------------------------------------------------------------------===//
13725460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao// Force static initialization.
137322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao//===----------------------------------------------------------------------===//
137422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaoextern "C" void MCLDInitializeX86LDBackend() {
13755460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // Register the linker backend
13766f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  mcld::TargetRegistry::RegisterTargetLDBackend(TheX86_32Target, createX86LDBackend);
13776f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  mcld::TargetRegistry::RegisterTargetLDBackend(TheX86_64Target, createX86LDBackend);
13785460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
1379