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
105460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include "X86.h"
115460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include "X86ELFDynamic.h"
125460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include "X86LDBackend.h"
135460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include "X86RelocationFactory.h"
145460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
155460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include <llvm/ADT/Triple.h>
16cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao#include <llvm/Support/Casting.h>
17cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao
18affc150dc44fab1911775a49636d0ce85333b634Zonr Chang#include <mcld/LD/SectionMap.h>
19cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao#include <mcld/LD/FillFragment.h>
20cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao#include <mcld/LD/RegionFragment.h>
215460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include <mcld/MC/MCLDInfo.h>
225460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include <mcld/MC/MCLDOutput.h>
235460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include <mcld/MC/MCLinker.h>
24affc150dc44fab1911775a49636d0ce85333b634Zonr Chang#include <mcld/Support/MemoryRegion.h>
25affc150dc44fab1911775a49636d0ce85333b634Zonr Chang#include <mcld/Support/MsgHandling.h>
26affc150dc44fab1911775a49636d0ce85333b634Zonr Chang#include <mcld/Support/TargetRegistry.h>
275460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
285460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include <cstring>
295460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
305460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaousing namespace mcld;
315460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
325460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei LiaoX86GNULDBackend::X86GNULDBackend()
335460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  : m_pRelocFactory(NULL),
345460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    m_pGOT(NULL),
355460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    m_pPLT(NULL),
36affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    m_pGOTPLT(NULL),
375460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    m_pRelDyn(NULL),
385460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    m_pRelPLT(NULL),
3967e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao    m_pDynamic(NULL),
4067e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao    m_pGOTSymbol(NULL) {
415460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
425460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
435460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei LiaoX86GNULDBackend::~X86GNULDBackend()
445460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
455460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  if (NULL != m_pRelocFactory)
465460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    delete m_pRelocFactory;
475460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  if (NULL != m_pGOT)
485460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    delete m_pGOT;
495460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  if (NULL != m_pPLT)
505460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    delete m_pPLT;
51affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  if (NULL != m_pGOTPLT)
52affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    delete m_pGOTPLT;
535460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  if (NULL !=m_pRelDyn)
545460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    delete m_pRelDyn;
555460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  if (NULL != m_pRelPLT)
565460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    delete m_pRelPLT;
575460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  if (NULL != m_pDynamic)
585460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    delete m_pDynamic;
595460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
605460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
615460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei LiaoRelocationFactory* X86GNULDBackend::getRelocFactory()
625460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
635460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  assert(NULL != m_pRelocFactory);
645460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  return m_pRelocFactory;
655460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
665460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
675460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaobool X86GNULDBackend::initRelocFactory(const MCLinker& pLinker)
685460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
695460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  if (NULL == m_pRelocFactory) {
705460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    m_pRelocFactory = new X86RelocationFactory(1024, *this);
715460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    m_pRelocFactory->setLayout(pLinker.getLayout());
725460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
735460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  return true;
745460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
755460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
765460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaovoid X86GNULDBackend::doPreLayout(const Output& pOutput,
775460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                  const MCLDInfo& pInfo,
785460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                  MCLinker& pLinker)
795460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
805460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // when building shared object, the .got section is needed
81affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  if (Output::DynObj == pOutput.type() && (NULL == m_pGOTPLT)) {
82affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    createX86GOTPLT(pLinker, pOutput);
83affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  }
845460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
855460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
865460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaovoid X86GNULDBackend::doPostLayout(const Output& pOutput,
875460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                   const MCLDInfo& pInfo,
885460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                   MCLinker& pLinker)
895460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
905460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
915460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
925460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// dynamic - the dynamic section of the target machine.
935460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// Use co-variant return type to return its own dynamic section.
945460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei LiaoX86ELFDynamic& X86GNULDBackend::dynamic()
955460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
965460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  if (NULL == m_pDynamic)
975460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    m_pDynamic = new X86ELFDynamic(*this);
985460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
995460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  return *m_pDynamic;
1005460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
1015460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1025460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// dynamic - the dynamic section of the target machine.
1035460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// Use co-variant return type to return its own dynamic section.
1045460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaoconst X86ELFDynamic& X86GNULDBackend::dynamic() const
1055460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
1065460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  assert( NULL != m_pDynamic);
1075460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  return *m_pDynamic;
1085460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
1095460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1105460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaovoid X86GNULDBackend::createX86GOT(MCLinker& pLinker, const Output& pOutput)
1115460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
112cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao  // get .got LDSection and create SectionData
1135460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  ELFFileFormat* file_format = getOutputFormat(pOutput);
1145460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1155460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  LDSection& got = file_format->getGOT();
1165460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  m_pGOT = new X86GOT(got, pLinker.getOrCreateSectData(got));
117affc150dc44fab1911775a49636d0ce85333b634Zonr Chang}
1185460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
119affc150dc44fab1911775a49636d0ce85333b634Zonr Changvoid X86GNULDBackend::createX86GOTPLT(MCLinker& pLinker, const Output& pOutput)
120affc150dc44fab1911775a49636d0ce85333b634Zonr Chang{
121cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao  // get .got.plt LDSection and create SectionData
122affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  ELFFileFormat* file_format = getOutputFormat(pOutput);
123affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
124affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  LDSection& gotplt = file_format->getGOTPLT();
125affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  m_pGOTPLT = new X86GOTPLT(gotplt, pLinker.getOrCreateSectData(gotplt));
126affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
127affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  // define symbol _GLOBAL_OFFSET_TABLE_ when .got.plt create
128affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  if (m_pGOTSymbol != NULL) {
1295460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    pLinker.defineSymbol<MCLinker::Force, MCLinker::Unresolve>(
1305460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                     "_GLOBAL_OFFSET_TABLE_",
1315460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                     false,
1325460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                     ResolveInfo::Object,
1335460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                     ResolveInfo::Define,
1345460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                     ResolveInfo::Local,
1355460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                     0x0, // size
1365460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                     0x0, // value
137affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                     pLinker.getLayout().getFragmentRef(*(m_pGOTPLT->begin()),
138affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                                         0x0),
1395460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                     ResolveInfo::Hidden);
1405460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
1415460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  else {
1425460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    m_pGOTSymbol = pLinker.defineSymbol<MCLinker::Force, MCLinker::Resolve>(
1435460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                     "_GLOBAL_OFFSET_TABLE_",
1445460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                     false,
1455460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                     ResolveInfo::Object,
1465460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                     ResolveInfo::Define,
1475460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                     ResolveInfo::Local,
1485460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                     0x0, // size
1495460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                     0x0, // value
150affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                     pLinker.getLayout().getFragmentRef(*(m_pGOTPLT->begin()),
151affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                                          0x0),
1525460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                     ResolveInfo::Hidden);
1535460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
1545460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
1555460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1565460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaovoid X86GNULDBackend::createX86PLTandRelPLT(MCLinker& pLinker,
1575460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                            const Output& pOutput)
1585460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
1595460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  ELFFileFormat* file_format = getOutputFormat(pOutput);
1605460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1615460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  LDSection& plt = file_format->getPLT();
1625460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  LDSection& relplt = file_format->getRelPlt();
163affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  assert(m_pGOTPLT != NULL);
164cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao  // create SectionData and X86PLT
165affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  m_pPLT = new X86PLT(plt, pLinker.getOrCreateSectData(plt), *m_pGOTPLT, pOutput);
1665460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1675460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // set info of .rel.plt to .plt
1685460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  relplt.setLink(&plt);
169cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao  // create SectionData and X86RelDynSection
1705460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  m_pRelPLT = new OutputRelocSection(relplt,
1715460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                     pLinker.getOrCreateSectData(relplt),
1725460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                     8);
1735460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
1745460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1755460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaovoid X86GNULDBackend::createX86RelDyn(MCLinker& pLinker,
1765460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                      const Output& pOutput)
1775460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
178cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao  // get .rel.dyn LDSection and create SectionData
1795460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  ELFFileFormat* file_format = getOutputFormat(pOutput);
1805460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1815460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  LDSection& reldyn = file_format->getRelDyn();
182cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao  // create SectionData and X86RelDynSection
1835460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  m_pRelDyn = new OutputRelocSection(reldyn,
1845460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                     pLinker.getOrCreateSectData(reldyn),
1855460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                     8);
1865460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
1875460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
188affc150dc44fab1911775a49636d0ce85333b634Zonr Changvoid X86GNULDBackend::addCopyReloc(ResolveInfo& pSym)
1895460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
190affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  bool exist;
191affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  Relocation& rel_entry = *m_pRelDyn->getEntry(pSym, false, exist);
192affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  rel_entry.setType(llvm::ELF::R_386_COPY);
193affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  assert(pSym.outSymbol()->hasFragRef());
194affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  rel_entry.targetRef().assign(*pSym.outSymbol()->fragRef());
195affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  rel_entry.setSymInfo(&pSym);
1965460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
1975460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
198affc150dc44fab1911775a49636d0ce85333b634Zonr ChangLDSymbol& X86GNULDBackend::defineSymbolforCopyReloc(MCLinker& pLinker,
199affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                                    const ResolveInfo& pSym)
2005460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
201affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  // For a symbol needing copy relocation, define a copy symbol in the BSS
202affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  // section and all other reference to this symbol should refer to this
203affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  // copy.
2045460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
205affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  // get or create corresponding BSS LDSection
206affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  LDSection* bss_sect_hdr = NULL;
207affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  if (ResolveInfo::ThreadLocal == pSym.type()) {
208affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    bss_sect_hdr = &pLinker.getOrCreateOutputSectHdr(
209affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                   ".tbss",
210affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                   LDFileFormat::BSS,
211affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                   llvm::ELF::SHT_NOBITS,
212affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                   llvm::ELF::SHF_WRITE | llvm::ELF::SHF_ALLOC);
213affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  }
214affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  else {
215affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    bss_sect_hdr = &pLinker.getOrCreateOutputSectHdr(".bss",
216affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                   LDFileFormat::BSS,
217affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                   llvm::ELF::SHT_NOBITS,
218affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                   llvm::ELF::SHF_WRITE | llvm::ELF::SHF_ALLOC);
219affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  }
2205460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
221cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao  // get or create corresponding BSS SectionData
222affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  assert(NULL != bss_sect_hdr);
223cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao  SectionData& bss_section = pLinker.getOrCreateSectData(
224affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                     *bss_sect_hdr);
225affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
226affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  // Determine the alignment by the symbol value
227affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  // FIXME: here we use the largest alignment
228affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  uint32_t addralign = bitclass() / 8;
229affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
230affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  // allocate space in BSS for the copy symbol
231cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao  Fragment* frag = new FillFragment(0x0, 1, pSym.size());
232affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  uint64_t size = pLinker.getLayout().appendFragment(*frag,
233affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                                     bss_section,
234affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                                     addralign);
235affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  bss_sect_hdr->setSize(bss_sect_hdr->size() + size);
236affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
237affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  // change symbol binding to Global if it's a weak symbol
238affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  ResolveInfo::Binding binding = (ResolveInfo::Binding)pSym.binding();
239affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  if (binding == ResolveInfo::Weak)
240affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    binding = ResolveInfo::Global;
241affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
242affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  // Define the copy symbol in the bss section and resolve it
243affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  LDSymbol* cpy_sym = pLinker.defineSymbol<MCLinker::Force, MCLinker::Resolve>(
244affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                      pSym.name(),
245affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                      false,
246affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                      (ResolveInfo::Type)pSym.type(),
247affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                      ResolveInfo::Define,
248affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                      binding,
249affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                      pSym.size(),  // size
250affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                      0x0,          // value
251affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                      pLinker.getLayout().getFragmentRef(*frag, 0x0),
252affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                      (ResolveInfo::Visibility)pSym.other());
253affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
254affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  return *cpy_sym;
2555460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
2565460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
2575460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaovoid X86GNULDBackend::updateAddend(Relocation& pReloc,
2585460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                   const LDSymbol& pInputSym,
2595460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                   const Layout& pLayout) const
2605460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
2615460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // Update value keep in addend if we meet a section symbol
262affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  if (pReloc.symInfo()->type() == ResolveInfo::Section) {
2635460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    pReloc.setAddend(pLayout.getOutputOffset(
2645460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                     *pInputSym.fragRef()) + pReloc.addend());
2655460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
2665460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
2675460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
2685460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaovoid X86GNULDBackend::scanLocalReloc(Relocation& pReloc,
2695460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                     const LDSymbol& pInputSym,
2705460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                     MCLinker& pLinker,
2715460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                     const MCLDInfo& pLDInfo,
2725460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                     const Output& pOutput)
2735460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
2745460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // rsym - The relocation target symbol
2755460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  ResolveInfo* rsym = pReloc.symInfo();
2765460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
2775460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  updateAddend(pReloc, pInputSym, pLinker.getLayout());
2785460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
2795460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  switch(pReloc.type()){
2805460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
2815460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_386_32:
2825460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      // If buiding PIC object (shared library or PIC executable),
2835460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      // a dynamic relocations with RELATIVE type to this location is needed.
2845460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      // Reserve an entry in .rel.dyn
285affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      if (isOutputPIC(pOutput, pLDInfo)) {
2865460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        // create .rel.dyn section if not exist
287affc150dc44fab1911775a49636d0ce85333b634Zonr Chang        if (NULL == m_pRelDyn)
2885460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao          createX86RelDyn(pLinker, pOutput);
2895460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        m_pRelDyn->reserveEntry(*m_pRelocFactory);
2905460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        // set Rel bit
2915460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        rsym->setReserved(rsym->reserved() | ReserveRel);
2925460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      }
2935460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      return;
2945460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
2955460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_386_GOTOFF:
2965460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_386_GOTPC:
2975460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      // A GOT section is needed
298affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      if (NULL == m_pGOT)
2995460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        createX86GOT(pLinker, pOutput);
3005460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      return;
3015460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
3025460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_386_PC32:
3035460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      return;
3045460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
3055460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    default:
306affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      fatal(diag::unsupported_relocation) << (int)pReloc.type()
307affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                          << "mclinker@googlegroups.com";
3085460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      break;
3095460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  } // end switch
3105460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
3115460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
3125460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaovoid X86GNULDBackend::scanGlobalReloc(Relocation& pReloc,
3135460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                      const LDSymbol& pInputSym,
3145460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                      MCLinker& pLinker,
3155460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                      const MCLDInfo& pLDInfo,
3165460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                      const Output& pOutput)
3175460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
3185460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // rsym - The relocation target symbol
3195460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  ResolveInfo* rsym = pReloc.symInfo();
3205460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
3215460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  switch(pReloc.type()) {
3225460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_386_32:
3235460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      // Absolute relocation type, symbol may needs PLT entry or
3245460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      // dynamic relocation entry
325affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      if (symbolNeedsPLT(*rsym, pLDInfo, pOutput)) {
3265460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        // create plt for this symbol if it does not have one
327affc150dc44fab1911775a49636d0ce85333b634Zonr Chang        if (!(rsym->reserved() & ReservePLT)){
3285460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao          // Create .got section if it dosen't exist
329affc150dc44fab1911775a49636d0ce85333b634Zonr Chang          if (NULL == m_pGOTPLT)
330affc150dc44fab1911775a49636d0ce85333b634Zonr Chang            createX86GOTPLT(pLinker, pOutput);
3315460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao          // create .plt and .rel.plt if not exist
332affc150dc44fab1911775a49636d0ce85333b634Zonr Chang          if (NULL == m_pPLT)
3335460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao            createX86PLTandRelPLT(pLinker, pOutput);
3345460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao          // Symbol needs PLT entry, we need to reserve a PLT entry
3355460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao          // and the corresponding GOT and dynamic relocation entry
3365460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao          // in .got and .rel.plt. (GOT entry will be reserved simultaneously
3375460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao          // when calling X86PLT->reserveEntry())
3385460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao          m_pPLT->reserveEntry();
3395460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao          m_pRelPLT->reserveEntry(*m_pRelocFactory);
3405460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao          // set PLT bit
3415460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao          rsym->setReserved(rsym->reserved() | ReservePLT);
3425460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        }
3435460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      }
3445460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
345affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      if (symbolNeedsDynRel(*rsym, (rsym->reserved() & ReservePLT),
346affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                            pLDInfo, pOutput, true)) {
3475460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        // symbol needs dynamic relocation entry, reserve an entry in .rel.dyn
3485460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        // create .rel.dyn section if not exist
349affc150dc44fab1911775a49636d0ce85333b634Zonr Chang        if (NULL == m_pRelDyn)
3505460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao          createX86RelDyn(pLinker, pOutput);
3515460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        m_pRelDyn->reserveEntry(*m_pRelocFactory);
352affc150dc44fab1911775a49636d0ce85333b634Zonr Chang        if (symbolNeedsCopyReloc(pLinker.getLayout(), pReloc, *rsym, pLDInfo,
353affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                          pOutput)) {
354affc150dc44fab1911775a49636d0ce85333b634Zonr Chang          LDSymbol& cpy_sym = defineSymbolforCopyReloc(pLinker, *rsym);
355affc150dc44fab1911775a49636d0ce85333b634Zonr Chang          addCopyReloc(*cpy_sym.resolveInfo());
356affc150dc44fab1911775a49636d0ce85333b634Zonr Chang        }
357affc150dc44fab1911775a49636d0ce85333b634Zonr Chang        else {
358affc150dc44fab1911775a49636d0ce85333b634Zonr Chang          // set Rel bit
359affc150dc44fab1911775a49636d0ce85333b634Zonr Chang          rsym->setReserved(rsym->reserved() | ReserveRel);
360affc150dc44fab1911775a49636d0ce85333b634Zonr Chang        }
3615460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      }
3625460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      return;
3635460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
3645460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_386_GOTOFF:
3655460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_386_GOTPC: {
3665460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      // A GOT section is needed
367affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      if (NULL == m_pGOT)
3685460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        createX86GOT(pLinker, pOutput);
3695460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      return;
3705460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    }
3715460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
3725460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_386_PLT32:
3735460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      // A PLT entry is needed when building shared library
3745460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
3755460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      // return if we already create plt for this symbol
376affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      if (rsym->reserved() & ReservePLT)
3775460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        return;
3785460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
3795460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      // if symbol is defined in the ouput file and it's not
3805460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      // preemptible, no need plt
381affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      if (rsym->isDefine() && !rsym->isDyn() &&
3825460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao         !isSymbolPreemptible(*rsym, pLDInfo, pOutput)) {
3835460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        return;
3845460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      }
3855460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
3865460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      // Create .got section if it dosen't exist
387affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      if (NULL == m_pGOTPLT)
388affc150dc44fab1911775a49636d0ce85333b634Zonr Chang         createX86GOTPLT(pLinker, pOutput);
3895460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      // create .plt and .rel.plt if not exist
390affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      if (NULL == m_pPLT)
3915460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao         createX86PLTandRelPLT(pLinker, pOutput);
3925460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      // Symbol needs PLT entry, we need to reserve a PLT entry
3935460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      // and the corresponding GOT and dynamic relocation entry
3945460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      // in .got and .rel.plt. (GOT entry will be reserved simultaneously
3955460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      // when calling X86PLT->reserveEntry())
3965460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      m_pPLT->reserveEntry();
3975460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      m_pRelPLT->reserveEntry(*m_pRelocFactory);
3985460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      // set PLT bit
3995460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      rsym->setReserved(rsym->reserved() | ReservePLT);
4005460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      return;
4015460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
4025460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_386_GOT32:
4035460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      // Symbol needs GOT entry, reserve entry in .got
4045460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      // return if we already create GOT for this symbol
405affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      if (rsym->reserved() & (ReserveGOT | GOTRel))
4065460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        return;
407affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      if (NULL == m_pGOT)
4085460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        createX86GOT(pLinker, pOutput);
4095460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      m_pGOT->reserveEntry();
4105460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      // If building shared object or the symbol is undefined, a dynamic
4115460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      // relocation is needed to relocate this GOT entry. Reserve an
4125460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      // entry in .rel.dyn
413affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      if (Output::DynObj == pOutput.type() || rsym->isUndef() || rsym->isDyn()) {
4145460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        // create .rel.dyn section if not exist
415affc150dc44fab1911775a49636d0ce85333b634Zonr Chang        if (NULL == m_pRelDyn)
4165460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao          createX86RelDyn(pLinker, pOutput);
4175460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        m_pRelDyn->reserveEntry(*m_pRelocFactory);
4185460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        // set GOTRel bit
4195460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        rsym->setReserved(rsym->reserved() | GOTRel);
4205460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        return;
4215460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      }
4225460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      // set GOT bit
4235460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      rsym->setReserved(rsym->reserved() | ReserveGOT);
4245460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      return;
4255460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
4265460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_386_PC32:
4275460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
428affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      if (symbolNeedsPLT(*rsym, pLDInfo, pOutput) &&
429affc150dc44fab1911775a49636d0ce85333b634Zonr Chang          pOutput.type() != Output::DynObj) {
430affc150dc44fab1911775a49636d0ce85333b634Zonr Chang        // create plt for this symbol if it does not have one
431affc150dc44fab1911775a49636d0ce85333b634Zonr Chang        if (!(rsym->reserved() & ReservePLT)){
432affc150dc44fab1911775a49636d0ce85333b634Zonr Chang          // Create .got section if it dosen't exist
433affc150dc44fab1911775a49636d0ce85333b634Zonr Chang          if (NULL == m_pGOTPLT)
434affc150dc44fab1911775a49636d0ce85333b634Zonr Chang            createX86GOTPLT(pLinker, pOutput);
435affc150dc44fab1911775a49636d0ce85333b634Zonr Chang          // create .plt and .rel.plt if not exist
436affc150dc44fab1911775a49636d0ce85333b634Zonr Chang          if (NULL == m_pPLT)
437affc150dc44fab1911775a49636d0ce85333b634Zonr Chang            createX86PLTandRelPLT(pLinker, pOutput);
438affc150dc44fab1911775a49636d0ce85333b634Zonr Chang          // Symbol needs PLT entry, we need to reserve a PLT entry
439affc150dc44fab1911775a49636d0ce85333b634Zonr Chang          // and the corresponding GOT and dynamic relocation entry
440affc150dc44fab1911775a49636d0ce85333b634Zonr Chang          // in .got and .rel.plt. (GOT entry will be reserved simultaneously
441affc150dc44fab1911775a49636d0ce85333b634Zonr Chang          // when calling X86PLT->reserveEntry())
442affc150dc44fab1911775a49636d0ce85333b634Zonr Chang          m_pPLT->reserveEntry();
443affc150dc44fab1911775a49636d0ce85333b634Zonr Chang          m_pRelPLT->reserveEntry(*m_pRelocFactory);
444affc150dc44fab1911775a49636d0ce85333b634Zonr Chang          // set PLT bit
445affc150dc44fab1911775a49636d0ce85333b634Zonr Chang          rsym->setReserved(rsym->reserved() | ReservePLT);
446affc150dc44fab1911775a49636d0ce85333b634Zonr Chang        }
447affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      }
448affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
449affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      if (symbolNeedsDynRel(*rsym, (rsym->reserved() & ReservePLT),
450affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                            pLDInfo, pOutput, false)) {
451affc150dc44fab1911775a49636d0ce85333b634Zonr Chang        // symbol needs dynamic relocation entry, reserve an entry in .rel.dyn
452affc150dc44fab1911775a49636d0ce85333b634Zonr Chang        // create .rel.dyn section if not exist
453affc150dc44fab1911775a49636d0ce85333b634Zonr Chang        if (NULL == m_pRelDyn)
454affc150dc44fab1911775a49636d0ce85333b634Zonr Chang          createX86RelDyn(pLinker, pOutput);
455affc150dc44fab1911775a49636d0ce85333b634Zonr Chang        m_pRelDyn->reserveEntry(*m_pRelocFactory);
456affc150dc44fab1911775a49636d0ce85333b634Zonr Chang        if (symbolNeedsCopyReloc(pLinker.getLayout(), pReloc, *rsym, pLDInfo,
457affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                          pOutput)) {
458affc150dc44fab1911775a49636d0ce85333b634Zonr Chang          LDSymbol& cpy_sym = defineSymbolforCopyReloc(pLinker, *rsym);
459affc150dc44fab1911775a49636d0ce85333b634Zonr Chang          addCopyReloc(*cpy_sym.resolveInfo());
460affc150dc44fab1911775a49636d0ce85333b634Zonr Chang        }
461affc150dc44fab1911775a49636d0ce85333b634Zonr Chang        else {
462affc150dc44fab1911775a49636d0ce85333b634Zonr Chang          // set Rel bit
463affc150dc44fab1911775a49636d0ce85333b634Zonr Chang          rsym->setReserved(rsym->reserved() | ReserveRel);
464affc150dc44fab1911775a49636d0ce85333b634Zonr Chang        }
465affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      }
466affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      return;
4675460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    default: {
468affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      fatal(diag::unsupported_relocation) << (int)pReloc.type()
469affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                          << "mclinker@googlegroups.com";
4705460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      break;
4715460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    }
4725460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  } // end switch
4735460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
4745460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
4755460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaovoid X86GNULDBackend::scanRelocation(Relocation& pReloc,
4765460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                     const LDSymbol& pInputSym,
4775460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                     MCLinker& pLinker,
4785460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                     const MCLDInfo& pLDInfo,
479affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                     const Output& pOutput,
480affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                     const LDSection& pSection)
4815460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
4825460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // rsym - The relocation target symbol
4835460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  ResolveInfo* rsym = pReloc.symInfo();
4845460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  assert(NULL != rsym && "ResolveInfo of relocation not set while scanRelocation");
4855460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
486affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  assert(NULL != pSection.getLink());
487affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  if (0 == (pSection.getLink()->flag() & llvm::ELF::SHF_ALLOC)) {
488affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    if (rsym->isLocal()) {
489affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      updateAddend(pReloc, pInputSym, pLinker.getLayout());
490affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    }
491affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    return;
492affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  }
493affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
4945460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // Scan relocation type to determine if an GOT/PLT/Dynamic Relocation
4955460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // entries should be created.
4965460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // FIXME: Below judgements concern only .so is generated as output
4975460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // FIXME: Below judgements concren nothing about TLS related relocation
4985460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
499affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  // A refernece to symbol _GLOBAL_OFFSET_TABLE_ implies that a .got.plt
500affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  // section is needed
501affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  if (NULL == m_pGOTPLT && NULL != m_pGOTSymbol) {
502affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    if (rsym == m_pGOTSymbol->resolveInfo()) {
503affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      createX86GOTPLT(pLinker, pOutput);
5045460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    }
5055460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
5065460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
5075460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // rsym is local
508affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  if (rsym->isLocal())
5095460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    scanLocalReloc(pReloc, pInputSym,  pLinker, pLDInfo, pOutput);
5105460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
5115460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // rsym is external
5125460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  else
5135460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    scanGlobalReloc(pReloc, pInputSym ,pLinker, pLDInfo, pOutput);
5145460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
5155460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
5165460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
5175460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaouint64_t X86GNULDBackend::emitSectionData(const Output& pOutput,
5185460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                          const LDSection& pSection,
5195460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                          const MCLDInfo& pInfo,
520affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                          const Layout& pLayout,
5215460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                          MemoryRegion& pRegion) const
5225460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
5235460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  assert(pRegion.size() && "Size of MemoryRegion is zero!");
5245460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
525affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  const ELFFileFormat* FileFormat = getOutputFormat(pOutput);
5265460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  assert(FileFormat &&
5275460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao         "ELFFileFormat is NULL in X86GNULDBackend::emitSectionData!");
5285460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
5295460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  unsigned int EntrySize = 0;
5305460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  uint64_t RegionSize = 0;
5315460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
5325460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  if (&pSection == &(FileFormat->getPLT())) {
5335460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    assert(m_pPLT && "emitSectionData failed, m_pPLT is NULL!");
5345460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
5355460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    unsigned char* buffer = pRegion.getBuffer();
5365460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
5375460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    m_pPLT->applyPLT0();
5385460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    m_pPLT->applyPLT1();
5395460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
5405460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    X86PLT::iterator it = m_pPLT->begin();
5415460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    unsigned int plt0_size = llvm::cast<X86PLT0>((*it)).getEntrySize();
5425460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
5435460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    memcpy(buffer, llvm::cast<X86PLT0>((*it)).getContent(), plt0_size);
5445460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    RegionSize += plt0_size;
5455460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    ++it;
5465460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
5475460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    X86PLT1* plt1 = 0;
5485460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    X86PLT::iterator ie = m_pPLT->end();
5495460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    while (it != ie) {
5505460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      plt1 = &(llvm::cast<X86PLT1>(*it));
5515460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      EntrySize = plt1->getEntrySize();
5525460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      memcpy(buffer + RegionSize, plt1->getContent(), EntrySize);
5535460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      RegionSize += EntrySize;
5545460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      ++it;
5555460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    }
5565460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
5575460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
5585460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  else if (&pSection == &(FileFormat->getGOT())) {
5595460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    assert(m_pGOT && "emitSectionData failed, m_pGOT is NULL!");
5605460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
5615460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    uint32_t* buffer = reinterpret_cast<uint32_t*>(pRegion.getBuffer());
5625460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
5635460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    GOTEntry* got = 0;
5645460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    EntrySize = m_pGOT->getEntrySize();
5655460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
5665460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    for (X86GOT::iterator it = m_pGOT->begin(),
5675460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao         ie = m_pGOT->end(); it != ie; ++it, ++buffer) {
5685460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      got = &(llvm::cast<GOTEntry>((*it)));
5695460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      *buffer = static_cast<uint32_t>(got->getContent());
5705460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      RegionSize += EntrySize;
5715460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    }
5725460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
5735460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
574affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  else if (&pSection == &(FileFormat->getGOTPLT())) {
575affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    assert(m_pGOTPLT && "emitSectionData failed, m_pGOTPLT is NULL!");
576affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    m_pGOTPLT->applyGOT0(FileFormat->getDynamic().addr());
577affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
578affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    uint32_t* buffer = reinterpret_cast<uint32_t*>(pRegion.getBuffer());
579affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
580affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    GOTEntry* got = 0;
581affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    EntrySize = m_pGOTPLT->getEntrySize();
5825460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
583affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    for (X86GOTPLT::iterator it = m_pGOTPLT->begin(),
584affc150dc44fab1911775a49636d0ce85333b634Zonr Chang         ie = m_pGOTPLT->end(); it != ie; ++it, ++buffer) {
585affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      got = &(llvm::cast<GOTEntry>((*it)));
586affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      *buffer = static_cast<uint32_t>(got->getContent());
587affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      RegionSize += EntrySize;
588affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    }
589affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  }
590affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
591affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  else {
592affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    fatal(diag::unrecognized_output_sectoin)
593affc150dc44fab1911775a49636d0ce85333b634Zonr Chang            << pSection.name()
594affc150dc44fab1911775a49636d0ce85333b634Zonr Chang            << "mclinker@googlegroups.com";
595affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  }
5965460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  return RegionSize;
5975460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
5985460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaouint32_t X86GNULDBackend::machine() const
5995460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
6005460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  return llvm::ELF::EM_386;
6015460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
6025460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
6035460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei LiaoX86GOT& X86GNULDBackend::getGOT()
6045460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
6055460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  assert(NULL != m_pGOT);
6065460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  return *m_pGOT;
6075460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
6085460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
6095460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaoconst X86GOT& X86GNULDBackend::getGOT() const
6105460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
6115460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  assert(NULL != m_pGOT);
6125460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  return *m_pGOT;
6135460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
6145460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
615affc150dc44fab1911775a49636d0ce85333b634Zonr ChangX86GOTPLT& X86GNULDBackend::getGOTPLT()
616affc150dc44fab1911775a49636d0ce85333b634Zonr Chang{
617affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  assert(NULL != m_pGOTPLT);
618affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  return *m_pGOTPLT;
619affc150dc44fab1911775a49636d0ce85333b634Zonr Chang}
620affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
621affc150dc44fab1911775a49636d0ce85333b634Zonr Changconst X86GOTPLT& X86GNULDBackend::getGOTPLT() const
622affc150dc44fab1911775a49636d0ce85333b634Zonr Chang{
623affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  assert(NULL != m_pGOTPLT);
624affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  return *m_pGOTPLT;
625affc150dc44fab1911775a49636d0ce85333b634Zonr Chang}
626affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
6275460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei LiaoX86PLT& X86GNULDBackend::getPLT()
6285460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
6295460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  assert(NULL != m_pPLT && "PLT section not exist");
6305460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  return *m_pPLT;
6315460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
6325460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
6335460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaoconst X86PLT& X86GNULDBackend::getPLT() const
6345460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
6355460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  assert(NULL != m_pPLT && "PLT section not exist");
6365460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  return *m_pPLT;
6375460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
6385460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
6395460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei LiaoOutputRelocSection& X86GNULDBackend::getRelDyn()
6405460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
6415460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  assert(NULL != m_pRelDyn && ".rel.dyn section not exist");
6425460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  return *m_pRelDyn;
6435460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
6445460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
6455460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaoconst OutputRelocSection& X86GNULDBackend::getRelDyn() const
6465460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
6475460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  assert(NULL != m_pRelDyn && ".rel.dyn section not exist");
6485460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  return *m_pRelDyn;
6495460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
6505460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
6515460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei LiaoOutputRelocSection& X86GNULDBackend::getRelPLT()
6525460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
6535460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  assert(NULL != m_pRelPLT && ".rel.plt section not exist");
6545460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  return *m_pRelPLT;
6555460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
6565460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
6575460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaoconst OutputRelocSection& X86GNULDBackend::getRelPLT() const
6585460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
6595460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  assert(NULL != m_pRelPLT && ".rel.plt section not exist");
6605460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  return *m_pRelPLT;
6615460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
6625460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
6635460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaounsigned int
6645460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei LiaoX86GNULDBackend::getTargetSectionOrder(const Output& pOutput,
665affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                       const LDSection& pSectHdr,
666affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                       const MCLDInfo& pInfo) const
6675460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
668affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  const ELFFileFormat* file_format = getOutputFormat(pOutput);
6695460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
670affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  if (&pSectHdr == &file_format->getGOT()) {
671affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    if (pInfo.options().hasNow())
672affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      return SHO_RELRO;
6735460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    return SHO_RELRO_LAST;
674affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  }
6755460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
676affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  if (&pSectHdr == &file_format->getGOTPLT()) {
677affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    if (pInfo.options().hasNow())
678affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      return SHO_RELRO;
6795460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    return SHO_NON_RELRO_FIRST;
680affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  }
6815460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
6825460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  if (&pSectHdr == &file_format->getPLT())
6835460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    return SHO_PLT;
6845460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
6855460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  return SHO_UNDEFINED;
6865460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
6875460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
6885460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaounsigned int X86GNULDBackend::bitclass() const
6895460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
6905460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  return 32;
6915460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
6925460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
6935460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaobool X86GNULDBackend::initTargetSectionMap(SectionMap& pSectionMap)
6945460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
6955460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  return true;
6965460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
6975460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
6985460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaovoid X86GNULDBackend::initTargetSections(MCLinker& pLinker)
6995460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
7005460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
7015460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
702affc150dc44fab1911775a49636d0ce85333b634Zonr Changvoid X86GNULDBackend::initTargetSymbols(MCLinker& pLinker, const Output& pOutput)
7035460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
7045460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // Define the symbol _GLOBAL_OFFSET_TABLE_ if there is a symbol with the
7055460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // same name in input
7065460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  m_pGOTSymbol = pLinker.defineSymbol<MCLinker::AsRefered, MCLinker::Resolve>(
7075460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                   "_GLOBAL_OFFSET_TABLE_",
7085460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                   false,
7095460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                   ResolveInfo::Object,
7105460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                   ResolveInfo::Define,
7115460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                   ResolveInfo::Local,
7125460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                   0x0,  // size
7135460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                   0x0,  // value
7145460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                   NULL, // FragRef
7155460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                   ResolveInfo::Hidden);
7165460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
7175460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
7185460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// finalizeSymbol - finalize the symbol value
719affc150dc44fab1911775a49636d0ce85333b634Zonr Changbool X86GNULDBackend::finalizeTargetSymbols(MCLinker& pLinker, const Output& pOutput)
720affc150dc44fab1911775a49636d0ce85333b634Zonr Chang{
7215460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  return true;
7225460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
7235460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
7245460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaonamespace mcld {
7255460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
7265460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao//===----------------------------------------------------------------------===//
7275460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// createX86LDBackend - the help funtion to create corresponding X86LDBackend
7285460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao///
7295460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei LiaoTargetLDBackend* createX86LDBackend(const llvm::Target& pTarget,
7305460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                    const std::string& pTriple)
7315460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
7325460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  Triple theTriple(pTriple);
7335460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  if (theTriple.isOSDarwin()) {
7345460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    assert(0 && "MachO linker is not supported yet");
7355460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    /**
7365460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    return new X86MachOLDBackend(createX86MachOArchiveReader,
7375460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                               createX86MachOObjectReader,
7385460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                               createX86MachOObjectWriter);
7395460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    **/
7405460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
7415460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  if (theTriple.isOSWindows()) {
7425460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    assert(0 && "COFF linker is not supported yet");
7435460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    /**
7445460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    return new X86COFFLDBackend(createX86COFFArchiveReader,
7455460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                               createX86COFFObjectReader,
7465460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                               createX86COFFObjectWriter);
7475460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    **/
7485460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
7495460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  return new X86GNULDBackend();
7505460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
7515460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
7525460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} // namespace of mcld
7535460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
7545460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao//=============================
7555460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao// Force static initialization.
7565460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaoextern "C" void LLVMInitializeX86LDBackend() {
7575460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // Register the linker backend
7585460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  mcld::TargetRegistry::RegisterTargetLDBackend(TheX86Target, createX86LDBackend);
7595460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
760