X86LDBackend.cpp revision affc150dc44fab1911775a49636d0ce85333b634
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>
16affc150dc44fab1911775a49636d0ce85333b634Zonr Chang#include <mcld/LD/SectionMap.h>
175460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include <mcld/MC/MCLDInfo.h>
185460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include <mcld/MC/MCLDOutput.h>
195460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include <mcld/MC/MCLinker.h>
205460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include <mcld/MC/MCRegionFragment.h>
21affc150dc44fab1911775a49636d0ce85333b634Zonr Chang#include <mcld/Support/MemoryRegion.h>
22affc150dc44fab1911775a49636d0ce85333b634Zonr Chang#include <mcld/Support/MsgHandling.h>
23affc150dc44fab1911775a49636d0ce85333b634Zonr Chang#include <mcld/Support/TargetRegistry.h>
245460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
255460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include <cstring>
265460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
275460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaousing namespace mcld;
285460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
295460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei LiaoX86GNULDBackend::X86GNULDBackend()
305460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  : m_pRelocFactory(NULL),
315460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    m_pGOT(NULL),
325460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    m_pPLT(NULL),
33affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    m_pGOTPLT(NULL),
345460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    m_pRelDyn(NULL),
355460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    m_pRelPLT(NULL),
365460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    m_pDynamic(NULL) {
375460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
385460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
395460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei LiaoX86GNULDBackend::~X86GNULDBackend()
405460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
415460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  if (NULL != m_pRelocFactory)
425460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    delete m_pRelocFactory;
435460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  if (NULL != m_pGOT)
445460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    delete m_pGOT;
455460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  if (NULL != m_pPLT)
465460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    delete m_pPLT;
47affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  if (NULL != m_pGOTPLT)
48affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    delete m_pGOTPLT;
495460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  if (NULL !=m_pRelDyn)
505460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    delete m_pRelDyn;
515460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  if (NULL != m_pRelPLT)
525460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    delete m_pRelPLT;
535460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  if (NULL != m_pDynamic)
545460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    delete m_pDynamic;
555460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
565460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
575460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei LiaoRelocationFactory* X86GNULDBackend::getRelocFactory()
585460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
595460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  assert(NULL != m_pRelocFactory);
605460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  return m_pRelocFactory;
615460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
625460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
635460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaobool X86GNULDBackend::initRelocFactory(const MCLinker& pLinker)
645460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
655460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  if (NULL == m_pRelocFactory) {
665460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    m_pRelocFactory = new X86RelocationFactory(1024, *this);
675460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    m_pRelocFactory->setLayout(pLinker.getLayout());
685460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
695460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  return true;
705460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
715460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
725460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaovoid X86GNULDBackend::doPreLayout(const Output& pOutput,
735460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                  const MCLDInfo& pInfo,
745460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                  MCLinker& pLinker)
755460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
765460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // when building shared object, the .got section is needed
77affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  if (Output::DynObj == pOutput.type() && (NULL == m_pGOTPLT)) {
78affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    createX86GOTPLT(pLinker, pOutput);
79affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  }
805460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
815460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
825460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaovoid X86GNULDBackend::doPostLayout(const Output& pOutput,
835460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                   const MCLDInfo& pInfo,
845460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                   MCLinker& pLinker)
855460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
865460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
875460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
885460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// dynamic - the dynamic section of the target machine.
895460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// Use co-variant return type to return its own dynamic section.
905460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei LiaoX86ELFDynamic& X86GNULDBackend::dynamic()
915460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
925460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  if (NULL == m_pDynamic)
935460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    m_pDynamic = new X86ELFDynamic(*this);
945460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
955460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  return *m_pDynamic;
965460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
975460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
985460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// dynamic - the dynamic section of the target machine.
995460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// Use co-variant return type to return its own dynamic section.
1005460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaoconst X86ELFDynamic& X86GNULDBackend::dynamic() const
1015460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
1025460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  assert( NULL != m_pDynamic);
1035460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  return *m_pDynamic;
1045460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
1055460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1065460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaovoid X86GNULDBackend::createX86GOT(MCLinker& pLinker, const Output& pOutput)
1075460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
1085460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // get .got LDSection and create MCSectionData
1095460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  ELFFileFormat* file_format = getOutputFormat(pOutput);
1105460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1115460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  LDSection& got = file_format->getGOT();
1125460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  m_pGOT = new X86GOT(got, pLinker.getOrCreateSectData(got));
113affc150dc44fab1911775a49636d0ce85333b634Zonr Chang}
1145460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
115affc150dc44fab1911775a49636d0ce85333b634Zonr Changvoid X86GNULDBackend::createX86GOTPLT(MCLinker& pLinker, const Output& pOutput)
116affc150dc44fab1911775a49636d0ce85333b634Zonr Chang{
117affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  // get .got.plt LDSection and create MCSectionData
118affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  ELFFileFormat* file_format = getOutputFormat(pOutput);
119affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
120affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  LDSection& gotplt = file_format->getGOTPLT();
121affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  m_pGOTPLT = new X86GOTPLT(gotplt, pLinker.getOrCreateSectData(gotplt));
122affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
123affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  // define symbol _GLOBAL_OFFSET_TABLE_ when .got.plt create
124affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  if (m_pGOTSymbol != NULL) {
1255460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    pLinker.defineSymbol<MCLinker::Force, MCLinker::Unresolve>(
1265460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                     "_GLOBAL_OFFSET_TABLE_",
1275460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                     false,
1285460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                     ResolveInfo::Object,
1295460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                     ResolveInfo::Define,
1305460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                     ResolveInfo::Local,
1315460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                     0x0, // size
1325460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                     0x0, // value
133affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                     pLinker.getLayout().getFragmentRef(*(m_pGOTPLT->begin()),
134affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                                         0x0),
1355460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                     ResolveInfo::Hidden);
1365460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
1375460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  else {
1385460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    m_pGOTSymbol = pLinker.defineSymbol<MCLinker::Force, MCLinker::Resolve>(
1395460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                     "_GLOBAL_OFFSET_TABLE_",
1405460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                     false,
1415460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                     ResolveInfo::Object,
1425460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                     ResolveInfo::Define,
1435460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                     ResolveInfo::Local,
1445460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                     0x0, // size
1455460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                     0x0, // value
146affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                     pLinker.getLayout().getFragmentRef(*(m_pGOTPLT->begin()),
147affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                                          0x0),
1485460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                     ResolveInfo::Hidden);
1495460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
1505460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
1515460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1525460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaovoid X86GNULDBackend::createX86PLTandRelPLT(MCLinker& pLinker,
1535460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                            const Output& pOutput)
1545460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
1555460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  ELFFileFormat* file_format = getOutputFormat(pOutput);
1565460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1575460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  LDSection& plt = file_format->getPLT();
1585460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  LDSection& relplt = file_format->getRelPlt();
159affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  assert(m_pGOTPLT != NULL);
1605460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // create MCSectionData and X86PLT
161affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  m_pPLT = new X86PLT(plt, pLinker.getOrCreateSectData(plt), *m_pGOTPLT, pOutput);
1625460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1635460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // set info of .rel.plt to .plt
1645460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  relplt.setLink(&plt);
1655460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // create MCSectionData and X86RelDynSection
1665460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  m_pRelPLT = new OutputRelocSection(relplt,
1675460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                     pLinker.getOrCreateSectData(relplt),
1685460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                     8);
1695460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
1705460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1715460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaovoid X86GNULDBackend::createX86RelDyn(MCLinker& pLinker,
1725460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                      const Output& pOutput)
1735460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
1745460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // get .rel.dyn LDSection and create MCSectionData
1755460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  ELFFileFormat* file_format = getOutputFormat(pOutput);
1765460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1775460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  LDSection& reldyn = file_format->getRelDyn();
1785460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // create MCSectionData and X86RelDynSection
1795460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  m_pRelDyn = new OutputRelocSection(reldyn,
1805460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                     pLinker.getOrCreateSectData(reldyn),
1815460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                     8);
1825460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
1835460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
184affc150dc44fab1911775a49636d0ce85333b634Zonr Changvoid X86GNULDBackend::addCopyReloc(ResolveInfo& pSym)
1855460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
186affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  bool exist;
187affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  Relocation& rel_entry = *m_pRelDyn->getEntry(pSym, false, exist);
188affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  rel_entry.setType(llvm::ELF::R_386_COPY);
189affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  assert(pSym.outSymbol()->hasFragRef());
190affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  rel_entry.targetRef().assign(*pSym.outSymbol()->fragRef());
191affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  rel_entry.setSymInfo(&pSym);
1925460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
1935460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
194affc150dc44fab1911775a49636d0ce85333b634Zonr ChangLDSymbol& X86GNULDBackend::defineSymbolforCopyReloc(MCLinker& pLinker,
195affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                                    const ResolveInfo& pSym)
1965460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
197affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  // For a symbol needing copy relocation, define a copy symbol in the BSS
198affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  // section and all other reference to this symbol should refer to this
199affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  // copy.
2005460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
201affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  // get or create corresponding BSS LDSection
202affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  LDSection* bss_sect_hdr = NULL;
203affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  if (ResolveInfo::ThreadLocal == pSym.type()) {
204affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    bss_sect_hdr = &pLinker.getOrCreateOutputSectHdr(
205affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                   ".tbss",
206affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                   LDFileFormat::BSS,
207affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                   llvm::ELF::SHT_NOBITS,
208affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                   llvm::ELF::SHF_WRITE | llvm::ELF::SHF_ALLOC);
209affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  }
210affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  else {
211affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    bss_sect_hdr = &pLinker.getOrCreateOutputSectHdr(".bss",
212affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                   LDFileFormat::BSS,
213affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                   llvm::ELF::SHT_NOBITS,
214affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                   llvm::ELF::SHF_WRITE | llvm::ELF::SHF_ALLOC);
215affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  }
2165460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
217affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  // get or create corresponding BSS MCSectionData
218affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  assert(NULL != bss_sect_hdr);
219affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  llvm::MCSectionData& bss_section = pLinker.getOrCreateSectData(
220affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                     *bss_sect_hdr);
221affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
222affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  // Determine the alignment by the symbol value
223affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  // FIXME: here we use the largest alignment
224affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  uint32_t addralign = bitclass() / 8;
225affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
226affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  // allocate space in BSS for the copy symbol
227affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  llvm::MCFragment* frag = new llvm::MCFillFragment(0x0, 1, pSym.size());
228affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  uint64_t size = pLinker.getLayout().appendFragment(*frag,
229affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                                     bss_section,
230affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                                     addralign);
231affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  bss_sect_hdr->setSize(bss_sect_hdr->size() + size);
232affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
233affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  // change symbol binding to Global if it's a weak symbol
234affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  ResolveInfo::Binding binding = (ResolveInfo::Binding)pSym.binding();
235affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  if (binding == ResolveInfo::Weak)
236affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    binding = ResolveInfo::Global;
237affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
238affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  // Define the copy symbol in the bss section and resolve it
239affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  LDSymbol* cpy_sym = pLinker.defineSymbol<MCLinker::Force, MCLinker::Resolve>(
240affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                      pSym.name(),
241affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                      false,
242affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                      (ResolveInfo::Type)pSym.type(),
243affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                      ResolveInfo::Define,
244affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                      binding,
245affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                      pSym.size(),  // size
246affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                      0x0,          // value
247affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                      pLinker.getLayout().getFragmentRef(*frag, 0x0),
248affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                      (ResolveInfo::Visibility)pSym.other());
249affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
250affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  return *cpy_sym;
2515460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
2525460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
2535460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaovoid X86GNULDBackend::updateAddend(Relocation& pReloc,
2545460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                   const LDSymbol& pInputSym,
2555460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                   const Layout& pLayout) const
2565460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
2575460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // Update value keep in addend if we meet a section symbol
258affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  if (pReloc.symInfo()->type() == ResolveInfo::Section) {
2595460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    pReloc.setAddend(pLayout.getOutputOffset(
2605460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                     *pInputSym.fragRef()) + pReloc.addend());
2615460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
2625460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
2635460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
2645460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaovoid X86GNULDBackend::scanLocalReloc(Relocation& pReloc,
2655460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                     const LDSymbol& pInputSym,
2665460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                     MCLinker& pLinker,
2675460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                     const MCLDInfo& pLDInfo,
2685460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                     const Output& pOutput)
2695460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
2705460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // rsym - The relocation target symbol
2715460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  ResolveInfo* rsym = pReloc.symInfo();
2725460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
2735460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  updateAddend(pReloc, pInputSym, pLinker.getLayout());
2745460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
2755460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  switch(pReloc.type()){
2765460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
2775460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_386_32:
2785460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      // If buiding PIC object (shared library or PIC executable),
2795460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      // a dynamic relocations with RELATIVE type to this location is needed.
2805460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      // Reserve an entry in .rel.dyn
281affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      if (isOutputPIC(pOutput, pLDInfo)) {
2825460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        // create .rel.dyn section if not exist
283affc150dc44fab1911775a49636d0ce85333b634Zonr Chang        if (NULL == m_pRelDyn)
2845460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao          createX86RelDyn(pLinker, pOutput);
2855460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        m_pRelDyn->reserveEntry(*m_pRelocFactory);
2865460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        // set Rel bit
2875460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        rsym->setReserved(rsym->reserved() | ReserveRel);
2885460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      }
2895460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      return;
2905460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
2915460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_386_GOTOFF:
2925460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_386_GOTPC:
2935460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      // A GOT section is needed
294affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      if (NULL == m_pGOT)
2955460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        createX86GOT(pLinker, pOutput);
2965460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      return;
2975460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
2985460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_386_PC32:
2995460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      return;
3005460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
3015460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    default:
302affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      fatal(diag::unsupported_relocation) << (int)pReloc.type()
303affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                          << "mclinker@googlegroups.com";
3045460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      break;
3055460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  } // end switch
3065460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
3075460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
3085460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaovoid X86GNULDBackend::scanGlobalReloc(Relocation& pReloc,
3095460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                      const LDSymbol& pInputSym,
3105460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                      MCLinker& pLinker,
3115460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                      const MCLDInfo& pLDInfo,
3125460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                      const Output& pOutput)
3135460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
3145460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // rsym - The relocation target symbol
3155460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  ResolveInfo* rsym = pReloc.symInfo();
3165460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
3175460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  switch(pReloc.type()) {
3185460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_386_32:
3195460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      // Absolute relocation type, symbol may needs PLT entry or
3205460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      // dynamic relocation entry
321affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      if (symbolNeedsPLT(*rsym, pLDInfo, pOutput)) {
3225460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        // create plt for this symbol if it does not have one
323affc150dc44fab1911775a49636d0ce85333b634Zonr Chang        if (!(rsym->reserved() & ReservePLT)){
3245460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao          // Create .got section if it dosen't exist
325affc150dc44fab1911775a49636d0ce85333b634Zonr Chang          if (NULL == m_pGOTPLT)
326affc150dc44fab1911775a49636d0ce85333b634Zonr Chang            createX86GOTPLT(pLinker, pOutput);
3275460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao          // create .plt and .rel.plt if not exist
328affc150dc44fab1911775a49636d0ce85333b634Zonr Chang          if (NULL == m_pPLT)
3295460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao            createX86PLTandRelPLT(pLinker, pOutput);
3305460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao          // Symbol needs PLT entry, we need to reserve a PLT entry
3315460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao          // and the corresponding GOT and dynamic relocation entry
3325460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao          // in .got and .rel.plt. (GOT entry will be reserved simultaneously
3335460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao          // when calling X86PLT->reserveEntry())
3345460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao          m_pPLT->reserveEntry();
3355460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao          m_pRelPLT->reserveEntry(*m_pRelocFactory);
3365460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao          // set PLT bit
3375460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao          rsym->setReserved(rsym->reserved() | ReservePLT);
3385460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        }
3395460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      }
3405460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
341affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      if (symbolNeedsDynRel(*rsym, (rsym->reserved() & ReservePLT),
342affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                            pLDInfo, pOutput, true)) {
3435460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        // symbol needs dynamic relocation entry, reserve an entry in .rel.dyn
3445460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        // create .rel.dyn section if not exist
345affc150dc44fab1911775a49636d0ce85333b634Zonr Chang        if (NULL == m_pRelDyn)
3465460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao          createX86RelDyn(pLinker, pOutput);
3475460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        m_pRelDyn->reserveEntry(*m_pRelocFactory);
348affc150dc44fab1911775a49636d0ce85333b634Zonr Chang        if (symbolNeedsCopyReloc(pLinker.getLayout(), pReloc, *rsym, pLDInfo,
349affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                          pOutput)) {
350affc150dc44fab1911775a49636d0ce85333b634Zonr Chang          LDSymbol& cpy_sym = defineSymbolforCopyReloc(pLinker, *rsym);
351affc150dc44fab1911775a49636d0ce85333b634Zonr Chang          addCopyReloc(*cpy_sym.resolveInfo());
352affc150dc44fab1911775a49636d0ce85333b634Zonr Chang        }
353affc150dc44fab1911775a49636d0ce85333b634Zonr Chang        else {
354affc150dc44fab1911775a49636d0ce85333b634Zonr Chang          // set Rel bit
355affc150dc44fab1911775a49636d0ce85333b634Zonr Chang          rsym->setReserved(rsym->reserved() | ReserveRel);
356affc150dc44fab1911775a49636d0ce85333b634Zonr Chang        }
3575460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      }
3585460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      return;
3595460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
3605460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_386_GOTOFF:
3615460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_386_GOTPC: {
3625460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      // A GOT section is needed
363affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      if (NULL == m_pGOT)
3645460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        createX86GOT(pLinker, pOutput);
3655460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      return;
3665460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    }
3675460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
3685460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_386_PLT32:
3695460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      // A PLT entry is needed when building shared library
3705460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
3715460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      // return if we already create plt for this symbol
372affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      if (rsym->reserved() & ReservePLT)
3735460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        return;
3745460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
3755460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      // if symbol is defined in the ouput file and it's not
3765460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      // preemptible, no need plt
377affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      if (rsym->isDefine() && !rsym->isDyn() &&
3785460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao         !isSymbolPreemptible(*rsym, pLDInfo, pOutput)) {
3795460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        return;
3805460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      }
3815460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
3825460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      // Create .got section if it dosen't exist
383affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      if (NULL == m_pGOTPLT)
384affc150dc44fab1911775a49636d0ce85333b634Zonr Chang         createX86GOTPLT(pLinker, pOutput);
3855460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      // create .plt and .rel.plt if not exist
386affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      if (NULL == m_pPLT)
3875460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao         createX86PLTandRelPLT(pLinker, pOutput);
3885460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      // Symbol needs PLT entry, we need to reserve a PLT entry
3895460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      // and the corresponding GOT and dynamic relocation entry
3905460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      // in .got and .rel.plt. (GOT entry will be reserved simultaneously
3915460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      // when calling X86PLT->reserveEntry())
3925460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      m_pPLT->reserveEntry();
3935460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      m_pRelPLT->reserveEntry(*m_pRelocFactory);
3945460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      // set PLT bit
3955460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      rsym->setReserved(rsym->reserved() | ReservePLT);
3965460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      return;
3975460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
3985460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_386_GOT32:
3995460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      // Symbol needs GOT entry, reserve entry in .got
4005460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      // return if we already create GOT for this symbol
401affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      if (rsym->reserved() & (ReserveGOT | GOTRel))
4025460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        return;
403affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      if (NULL == m_pGOT)
4045460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        createX86GOT(pLinker, pOutput);
4055460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      m_pGOT->reserveEntry();
4065460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      // If building shared object or the symbol is undefined, a dynamic
4075460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      // relocation is needed to relocate this GOT entry. Reserve an
4085460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      // entry in .rel.dyn
409affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      if (Output::DynObj == pOutput.type() || rsym->isUndef() || rsym->isDyn()) {
4105460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        // create .rel.dyn section if not exist
411affc150dc44fab1911775a49636d0ce85333b634Zonr Chang        if (NULL == m_pRelDyn)
4125460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao          createX86RelDyn(pLinker, pOutput);
4135460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        m_pRelDyn->reserveEntry(*m_pRelocFactory);
4145460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        // set GOTRel bit
4155460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        rsym->setReserved(rsym->reserved() | GOTRel);
4165460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        return;
4175460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      }
4185460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      // set GOT bit
4195460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      rsym->setReserved(rsym->reserved() | ReserveGOT);
4205460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      return;
4215460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
4225460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_386_PC32:
4235460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
424affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      if (symbolNeedsPLT(*rsym, pLDInfo, pOutput) &&
425affc150dc44fab1911775a49636d0ce85333b634Zonr Chang          pOutput.type() != Output::DynObj) {
426affc150dc44fab1911775a49636d0ce85333b634Zonr Chang        // create plt for this symbol if it does not have one
427affc150dc44fab1911775a49636d0ce85333b634Zonr Chang        if (!(rsym->reserved() & ReservePLT)){
428affc150dc44fab1911775a49636d0ce85333b634Zonr Chang          // Create .got section if it dosen't exist
429affc150dc44fab1911775a49636d0ce85333b634Zonr Chang          if (NULL == m_pGOTPLT)
430affc150dc44fab1911775a49636d0ce85333b634Zonr Chang            createX86GOTPLT(pLinker, pOutput);
431affc150dc44fab1911775a49636d0ce85333b634Zonr Chang          // create .plt and .rel.plt if not exist
432affc150dc44fab1911775a49636d0ce85333b634Zonr Chang          if (NULL == m_pPLT)
433affc150dc44fab1911775a49636d0ce85333b634Zonr Chang            createX86PLTandRelPLT(pLinker, pOutput);
434affc150dc44fab1911775a49636d0ce85333b634Zonr Chang          // Symbol needs PLT entry, we need to reserve a PLT entry
435affc150dc44fab1911775a49636d0ce85333b634Zonr Chang          // and the corresponding GOT and dynamic relocation entry
436affc150dc44fab1911775a49636d0ce85333b634Zonr Chang          // in .got and .rel.plt. (GOT entry will be reserved simultaneously
437affc150dc44fab1911775a49636d0ce85333b634Zonr Chang          // when calling X86PLT->reserveEntry())
438affc150dc44fab1911775a49636d0ce85333b634Zonr Chang          m_pPLT->reserveEntry();
439affc150dc44fab1911775a49636d0ce85333b634Zonr Chang          m_pRelPLT->reserveEntry(*m_pRelocFactory);
440affc150dc44fab1911775a49636d0ce85333b634Zonr Chang          // set PLT bit
441affc150dc44fab1911775a49636d0ce85333b634Zonr Chang          rsym->setReserved(rsym->reserved() | ReservePLT);
442affc150dc44fab1911775a49636d0ce85333b634Zonr Chang        }
443affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      }
444affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
445affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      if (symbolNeedsDynRel(*rsym, (rsym->reserved() & ReservePLT),
446affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                            pLDInfo, pOutput, false)) {
447affc150dc44fab1911775a49636d0ce85333b634Zonr Chang        // symbol needs dynamic relocation entry, reserve an entry in .rel.dyn
448affc150dc44fab1911775a49636d0ce85333b634Zonr Chang        // create .rel.dyn section if not exist
449affc150dc44fab1911775a49636d0ce85333b634Zonr Chang        if (NULL == m_pRelDyn)
450affc150dc44fab1911775a49636d0ce85333b634Zonr Chang          createX86RelDyn(pLinker, pOutput);
451affc150dc44fab1911775a49636d0ce85333b634Zonr Chang        m_pRelDyn->reserveEntry(*m_pRelocFactory);
452affc150dc44fab1911775a49636d0ce85333b634Zonr Chang        if (symbolNeedsCopyReloc(pLinker.getLayout(), pReloc, *rsym, pLDInfo,
453affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                          pOutput)) {
454affc150dc44fab1911775a49636d0ce85333b634Zonr Chang          LDSymbol& cpy_sym = defineSymbolforCopyReloc(pLinker, *rsym);
455affc150dc44fab1911775a49636d0ce85333b634Zonr Chang          addCopyReloc(*cpy_sym.resolveInfo());
456affc150dc44fab1911775a49636d0ce85333b634Zonr Chang        }
457affc150dc44fab1911775a49636d0ce85333b634Zonr Chang        else {
458affc150dc44fab1911775a49636d0ce85333b634Zonr Chang          // set Rel bit
459affc150dc44fab1911775a49636d0ce85333b634Zonr Chang          rsym->setReserved(rsym->reserved() | ReserveRel);
460affc150dc44fab1911775a49636d0ce85333b634Zonr Chang        }
461affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      }
462affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      return;
4635460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    default: {
464affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      fatal(diag::unsupported_relocation) << (int)pReloc.type()
465affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                          << "mclinker@googlegroups.com";
4665460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      break;
4675460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    }
4685460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  } // end switch
4695460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
4705460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
4715460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaovoid X86GNULDBackend::scanRelocation(Relocation& pReloc,
4725460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                     const LDSymbol& pInputSym,
4735460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                     MCLinker& pLinker,
4745460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                     const MCLDInfo& pLDInfo,
475affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                     const Output& pOutput,
476affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                     const LDSection& pSection)
4775460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
4785460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // rsym - The relocation target symbol
4795460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  ResolveInfo* rsym = pReloc.symInfo();
4805460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  assert(NULL != rsym && "ResolveInfo of relocation not set while scanRelocation");
4815460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
482affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  assert(NULL != pSection.getLink());
483affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  if (0 == (pSection.getLink()->flag() & llvm::ELF::SHF_ALLOC)) {
484affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    if (rsym->isLocal()) {
485affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      updateAddend(pReloc, pInputSym, pLinker.getLayout());
486affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    }
487affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    return;
488affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  }
489affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
4905460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // Scan relocation type to determine if an GOT/PLT/Dynamic Relocation
4915460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // entries should be created.
4925460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // FIXME: Below judgements concern only .so is generated as output
4935460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // FIXME: Below judgements concren nothing about TLS related relocation
4945460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
495affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  // A refernece to symbol _GLOBAL_OFFSET_TABLE_ implies that a .got.plt
496affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  // section is needed
497affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  if (NULL == m_pGOTPLT && NULL != m_pGOTSymbol) {
498affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    if (rsym == m_pGOTSymbol->resolveInfo()) {
499affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      createX86GOTPLT(pLinker, pOutput);
5005460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    }
5015460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
5025460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
5035460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // rsym is local
504affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  if (rsym->isLocal())
5055460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    scanLocalReloc(pReloc, pInputSym,  pLinker, pLDInfo, pOutput);
5065460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
5075460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // rsym is external
5085460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  else
5095460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    scanGlobalReloc(pReloc, pInputSym ,pLinker, pLDInfo, pOutput);
5105460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
5115460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
5125460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
5135460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaouint64_t X86GNULDBackend::emitSectionData(const Output& pOutput,
5145460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                          const LDSection& pSection,
5155460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                          const MCLDInfo& pInfo,
516affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                          const Layout& pLayout,
5175460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                          MemoryRegion& pRegion) const
5185460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
5195460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  assert(pRegion.size() && "Size of MemoryRegion is zero!");
5205460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
521affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  const ELFFileFormat* FileFormat = getOutputFormat(pOutput);
5225460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  assert(FileFormat &&
5235460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao         "ELFFileFormat is NULL in X86GNULDBackend::emitSectionData!");
5245460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
5255460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  unsigned int EntrySize = 0;
5265460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  uint64_t RegionSize = 0;
5275460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
5285460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  if (&pSection == &(FileFormat->getPLT())) {
5295460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    assert(m_pPLT && "emitSectionData failed, m_pPLT is NULL!");
5305460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
5315460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    unsigned char* buffer = pRegion.getBuffer();
5325460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
5335460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    m_pPLT->applyPLT0();
5345460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    m_pPLT->applyPLT1();
5355460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
5365460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    X86PLT::iterator it = m_pPLT->begin();
5375460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    unsigned int plt0_size = llvm::cast<X86PLT0>((*it)).getEntrySize();
5385460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
5395460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    memcpy(buffer, llvm::cast<X86PLT0>((*it)).getContent(), plt0_size);
5405460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    RegionSize += plt0_size;
5415460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    ++it;
5425460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
5435460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    X86PLT1* plt1 = 0;
5445460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    X86PLT::iterator ie = m_pPLT->end();
5455460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    while (it != ie) {
5465460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      plt1 = &(llvm::cast<X86PLT1>(*it));
5475460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      EntrySize = plt1->getEntrySize();
5485460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      memcpy(buffer + RegionSize, plt1->getContent(), EntrySize);
5495460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      RegionSize += EntrySize;
5505460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      ++it;
5515460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    }
5525460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
5535460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
5545460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  else if (&pSection == &(FileFormat->getGOT())) {
5555460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    assert(m_pGOT && "emitSectionData failed, m_pGOT is NULL!");
5565460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
5575460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    uint32_t* buffer = reinterpret_cast<uint32_t*>(pRegion.getBuffer());
5585460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
5595460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    GOTEntry* got = 0;
5605460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    EntrySize = m_pGOT->getEntrySize();
5615460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
5625460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    for (X86GOT::iterator it = m_pGOT->begin(),
5635460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao         ie = m_pGOT->end(); it != ie; ++it, ++buffer) {
5645460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      got = &(llvm::cast<GOTEntry>((*it)));
5655460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      *buffer = static_cast<uint32_t>(got->getContent());
5665460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      RegionSize += EntrySize;
5675460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    }
5685460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
5695460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
570affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  else if (&pSection == &(FileFormat->getGOTPLT())) {
571affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    assert(m_pGOTPLT && "emitSectionData failed, m_pGOTPLT is NULL!");
572affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    m_pGOTPLT->applyGOT0(FileFormat->getDynamic().addr());
573affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
574affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    uint32_t* buffer = reinterpret_cast<uint32_t*>(pRegion.getBuffer());
575affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
576affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    GOTEntry* got = 0;
577affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    EntrySize = m_pGOTPLT->getEntrySize();
5785460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
579affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    for (X86GOTPLT::iterator it = m_pGOTPLT->begin(),
580affc150dc44fab1911775a49636d0ce85333b634Zonr Chang         ie = m_pGOTPLT->end(); it != ie; ++it, ++buffer) {
581affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      got = &(llvm::cast<GOTEntry>((*it)));
582affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      *buffer = static_cast<uint32_t>(got->getContent());
583affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      RegionSize += EntrySize;
584affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    }
585affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  }
586affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
587affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  else {
588affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    fatal(diag::unrecognized_output_sectoin)
589affc150dc44fab1911775a49636d0ce85333b634Zonr Chang            << pSection.name()
590affc150dc44fab1911775a49636d0ce85333b634Zonr Chang            << "mclinker@googlegroups.com";
591affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  }
5925460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  return RegionSize;
5935460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
5945460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaouint32_t X86GNULDBackend::machine() const
5955460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
5965460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  return llvm::ELF::EM_386;
5975460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
5985460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
5995460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei LiaoX86GOT& X86GNULDBackend::getGOT()
6005460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
6015460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  assert(NULL != m_pGOT);
6025460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  return *m_pGOT;
6035460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
6045460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
6055460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaoconst X86GOT& X86GNULDBackend::getGOT() const
6065460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
6075460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  assert(NULL != m_pGOT);
6085460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  return *m_pGOT;
6095460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
6105460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
611affc150dc44fab1911775a49636d0ce85333b634Zonr ChangX86GOTPLT& X86GNULDBackend::getGOTPLT()
612affc150dc44fab1911775a49636d0ce85333b634Zonr Chang{
613affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  assert(NULL != m_pGOTPLT);
614affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  return *m_pGOTPLT;
615affc150dc44fab1911775a49636d0ce85333b634Zonr Chang}
616affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
617affc150dc44fab1911775a49636d0ce85333b634Zonr Changconst X86GOTPLT& X86GNULDBackend::getGOTPLT() const
618affc150dc44fab1911775a49636d0ce85333b634Zonr Chang{
619affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  assert(NULL != m_pGOTPLT);
620affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  return *m_pGOTPLT;
621affc150dc44fab1911775a49636d0ce85333b634Zonr Chang}
622affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
6235460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei LiaoX86PLT& X86GNULDBackend::getPLT()
6245460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
6255460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  assert(NULL != m_pPLT && "PLT section not exist");
6265460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  return *m_pPLT;
6275460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
6285460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
6295460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaoconst X86PLT& X86GNULDBackend::getPLT() const
6305460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
6315460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  assert(NULL != m_pPLT && "PLT section not exist");
6325460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  return *m_pPLT;
6335460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
6345460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
6355460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei LiaoOutputRelocSection& X86GNULDBackend::getRelDyn()
6365460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
6375460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  assert(NULL != m_pRelDyn && ".rel.dyn section not exist");
6385460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  return *m_pRelDyn;
6395460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
6405460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
6415460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaoconst OutputRelocSection& X86GNULDBackend::getRelDyn() const
6425460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
6435460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  assert(NULL != m_pRelDyn && ".rel.dyn section not exist");
6445460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  return *m_pRelDyn;
6455460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
6465460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
6475460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei LiaoOutputRelocSection& X86GNULDBackend::getRelPLT()
6485460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
6495460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  assert(NULL != m_pRelPLT && ".rel.plt section not exist");
6505460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  return *m_pRelPLT;
6515460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
6525460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
6535460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaoconst OutputRelocSection& X86GNULDBackend::getRelPLT() const
6545460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
6555460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  assert(NULL != m_pRelPLT && ".rel.plt section not exist");
6565460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  return *m_pRelPLT;
6575460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
6585460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
6595460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaounsigned int
6605460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei LiaoX86GNULDBackend::getTargetSectionOrder(const Output& pOutput,
661affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                       const LDSection& pSectHdr,
662affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                       const MCLDInfo& pInfo) const
6635460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
664affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  const ELFFileFormat* file_format = getOutputFormat(pOutput);
6655460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
666affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  if (&pSectHdr == &file_format->getGOT()) {
667affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    if (pInfo.options().hasNow())
668affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      return SHO_RELRO;
6695460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    return SHO_RELRO_LAST;
670affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  }
6715460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
672affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  if (&pSectHdr == &file_format->getGOTPLT()) {
673affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    if (pInfo.options().hasNow())
674affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      return SHO_RELRO;
6755460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    return SHO_NON_RELRO_FIRST;
676affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  }
6775460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
6785460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  if (&pSectHdr == &file_format->getPLT())
6795460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    return SHO_PLT;
6805460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
6815460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  return SHO_UNDEFINED;
6825460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
6835460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
6845460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaounsigned int X86GNULDBackend::bitclass() const
6855460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
6865460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  return 32;
6875460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
6885460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
6895460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaobool X86GNULDBackend::initTargetSectionMap(SectionMap& pSectionMap)
6905460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
6915460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  return true;
6925460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
6935460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
6945460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaovoid X86GNULDBackend::initTargetSections(MCLinker& pLinker)
6955460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
6965460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
6975460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
698affc150dc44fab1911775a49636d0ce85333b634Zonr Changvoid X86GNULDBackend::initTargetSymbols(MCLinker& pLinker, const Output& pOutput)
6995460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
7005460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // Define the symbol _GLOBAL_OFFSET_TABLE_ if there is a symbol with the
7015460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // same name in input
7025460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  m_pGOTSymbol = pLinker.defineSymbol<MCLinker::AsRefered, MCLinker::Resolve>(
7035460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                   "_GLOBAL_OFFSET_TABLE_",
7045460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                   false,
7055460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                   ResolveInfo::Object,
7065460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                   ResolveInfo::Define,
7075460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                   ResolveInfo::Local,
7085460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                   0x0,  // size
7095460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                   0x0,  // value
7105460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                   NULL, // FragRef
7115460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                   ResolveInfo::Hidden);
7125460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
7135460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
7145460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// finalizeSymbol - finalize the symbol value
715affc150dc44fab1911775a49636d0ce85333b634Zonr Changbool X86GNULDBackend::finalizeTargetSymbols(MCLinker& pLinker, const Output& pOutput)
716affc150dc44fab1911775a49636d0ce85333b634Zonr Chang{
7175460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  return true;
7185460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
7195460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
7205460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaonamespace mcld {
7215460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
7225460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao//===----------------------------------------------------------------------===//
7235460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// createX86LDBackend - the help funtion to create corresponding X86LDBackend
7245460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao///
7255460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei LiaoTargetLDBackend* createX86LDBackend(const llvm::Target& pTarget,
7265460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                    const std::string& pTriple)
7275460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
7285460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  Triple theTriple(pTriple);
7295460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  if (theTriple.isOSDarwin()) {
7305460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    assert(0 && "MachO linker is not supported yet");
7315460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    /**
7325460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    return new X86MachOLDBackend(createX86MachOArchiveReader,
7335460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                               createX86MachOObjectReader,
7345460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                               createX86MachOObjectWriter);
7355460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    **/
7365460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
7375460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  if (theTriple.isOSWindows()) {
7385460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    assert(0 && "COFF linker is not supported yet");
7395460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    /**
7405460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    return new X86COFFLDBackend(createX86COFFArchiveReader,
7415460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                               createX86COFFObjectReader,
7425460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                               createX86COFFObjectWriter);
7435460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    **/
7445460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
7455460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  return new X86GNULDBackend();
7465460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
7475460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
7485460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} // namespace of mcld
7495460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
7505460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao//=============================
7515460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao// Force static initialization.
7525460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaoextern "C" void LLVMInitializeX86LDBackend() {
7535460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // Register the linker backend
7545460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  mcld::TargetRegistry::RegisterTargetLDBackend(TheX86Target, createX86LDBackend);
7555460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
756