X86LDBackend.cpp revision 5460a1f25d9ddecb5c70667267d66d51af177a99
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>
165460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include <mcld/Support/MemoryRegion.h>
175460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include <mcld/Support/TargetRegistry.h>
185460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include <mcld/MC/MCLDInfo.h>
195460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include <mcld/MC/MCLDOutput.h>
205460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include <mcld/MC/MCLinker.h>
215460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include <mcld/LD/SectionMap.h>
225460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include <mcld/MC/MCRegionFragment.h>
235460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
245460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include <cstring>
255460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
265460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaousing namespace mcld;
275460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
285460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei LiaoX86GNULDBackend::X86GNULDBackend()
295460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  : m_pRelocFactory(NULL),
305460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    m_pGOT(NULL),
315460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    m_pPLT(NULL),
325460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    m_pRelDyn(NULL),
335460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    m_pRelPLT(NULL),
345460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    m_pDynamic(NULL) {
355460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
365460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
375460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei LiaoX86GNULDBackend::~X86GNULDBackend()
385460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
395460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  if (NULL != m_pRelocFactory)
405460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    delete m_pRelocFactory;
415460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  if (NULL != m_pGOT)
425460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    delete m_pGOT;
435460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  if (NULL != m_pPLT)
445460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    delete m_pPLT;
455460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  if (NULL !=m_pRelDyn)
465460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    delete m_pRelDyn;
475460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  if (NULL != m_pRelPLT)
485460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    delete m_pRelPLT;
495460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  if (NULL != m_pDynamic)
505460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    delete m_pDynamic;
515460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
525460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
535460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei LiaoRelocationFactory* X86GNULDBackend::getRelocFactory()
545460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
555460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  assert(NULL != m_pRelocFactory);
565460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  return m_pRelocFactory;
575460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
585460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
595460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaobool X86GNULDBackend::initRelocFactory(const MCLinker& pLinker)
605460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
615460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  if (NULL == m_pRelocFactory) {
625460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    m_pRelocFactory = new X86RelocationFactory(1024, *this);
635460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    m_pRelocFactory->setLayout(pLinker.getLayout());
645460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
655460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  return true;
665460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
675460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
685460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaovoid X86GNULDBackend::doPreLayout(const Output& pOutput,
695460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                  const MCLDInfo& pInfo,
705460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                  MCLinker& pLinker)
715460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
725460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // when building shared object, the .got section is needed
735460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  if(pOutput.type() == Output::DynObj && (NULL == m_pGOT))
745460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      createX86GOT(pLinker, pOutput);
755460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
765460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
775460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaovoid X86GNULDBackend::doPostLayout(const Output& pOutput,
785460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                   const MCLDInfo& pInfo,
795460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                   MCLinker& pLinker)
805460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
815460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // emit program headers
825460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  if(pOutput.type() == Output::DynObj || pOutput.type() == Output::Exec)
835460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    emitProgramHdrs(pLinker.getLDInfo().output());
845460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
855460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
865460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// dynamic - the dynamic section of the target machine.
875460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// Use co-variant return type to return its own dynamic section.
885460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei LiaoX86ELFDynamic& X86GNULDBackend::dynamic()
895460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
905460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  if (NULL == m_pDynamic)
915460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    m_pDynamic = new X86ELFDynamic(*this);
925460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
935460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  return *m_pDynamic;
945460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
955460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
965460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// dynamic - the dynamic section of the target machine.
975460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// Use co-variant return type to return its own dynamic section.
985460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaoconst X86ELFDynamic& X86GNULDBackend::dynamic() const
995460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
1005460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  assert( NULL != m_pDynamic);
1015460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  return *m_pDynamic;
1025460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
1035460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1045460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaovoid X86GNULDBackend::createX86GOT(MCLinker& pLinker, const Output& pOutput)
1055460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
1065460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // get .got LDSection and create MCSectionData
1075460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  ELFFileFormat* file_format = getOutputFormat(pOutput);
1085460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1095460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  LDSection& got = file_format->getGOT();
1105460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  m_pGOT = new X86GOT(got, pLinker.getOrCreateSectData(got));
1115460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1125460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // define symbol _GLOBAL_OFFSET_TABLE_ when .got create
1135460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  if( m_pGOTSymbol != NULL ) {
1145460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    pLinker.defineSymbol<MCLinker::Force, MCLinker::Unresolve>(
1155460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                     "_GLOBAL_OFFSET_TABLE_",
1165460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                     false,
1175460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                     ResolveInfo::Object,
1185460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                     ResolveInfo::Define,
1195460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                     ResolveInfo::Local,
1205460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                     0x0, // size
1215460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                     0x0, // value
1225460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                     pLinker.getLayout().getFragmentRef(*(m_pGOT->begin()), 0x0),
1235460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                     ResolveInfo::Hidden);
1245460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
1255460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  else {
1265460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    m_pGOTSymbol = pLinker.defineSymbol<MCLinker::Force, MCLinker::Resolve>(
1275460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                     "_GLOBAL_OFFSET_TABLE_",
1285460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                     false,
1295460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                     ResolveInfo::Object,
1305460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                     ResolveInfo::Define,
1315460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                     ResolveInfo::Local,
1325460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                     0x0, // size
1335460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                     0x0, // value
1345460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                     pLinker.getLayout().getFragmentRef(*(m_pGOT->begin()), 0x0),
1355460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                     ResolveInfo::Hidden);
1365460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
1375460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
1385460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1395460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaovoid X86GNULDBackend::createX86PLTandRelPLT(MCLinker& pLinker,
1405460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                            const Output& pOutput)
1415460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
1425460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  ELFFileFormat* file_format = getOutputFormat(pOutput);
1435460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1445460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  LDSection& plt = file_format->getPLT();
1455460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  LDSection& relplt = file_format->getRelPlt();
1465460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // create MCSectionData and X86PLT
1475460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  m_pPLT = new X86PLT(plt, pLinker.getOrCreateSectData(plt), *m_pGOT, pOutput);
1485460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1495460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // set info of .rel.plt to .plt
1505460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  relplt.setLink(&plt);
1515460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // create MCSectionData and X86RelDynSection
1525460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  m_pRelPLT = new OutputRelocSection(relplt,
1535460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                     pLinker.getOrCreateSectData(relplt),
1545460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                     8);
1555460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
1565460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1575460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaovoid X86GNULDBackend::createX86RelDyn(MCLinker& pLinker,
1585460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                      const Output& pOutput)
1595460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
1605460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // get .rel.dyn LDSection and create MCSectionData
1615460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  ELFFileFormat* file_format = getOutputFormat(pOutput);
1625460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1635460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  LDSection& reldyn = file_format->getRelDyn();
1645460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // create MCSectionData and X86RelDynSection
1655460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  m_pRelDyn = new OutputRelocSection(reldyn,
1665460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                     pLinker.getOrCreateSectData(reldyn),
1675460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                     8);
1685460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
1695460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1705460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei LiaoELFFileFormat* X86GNULDBackend::getOutputFormat(const Output& pOutput) const
1715460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
1725460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  switch (pOutput.type()) {
1735460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case Output::DynObj:
1745460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      return getDynObjFileFormat();
1755460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case Output::Exec:
1765460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      return getExecFileFormat();
1775460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    // FIXME: We do not support building .o now
1785460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case Output::Object:
1795460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    default:
1805460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      llvm::report_fatal_error(llvm::Twine("Unsupported output file format: ") +
1815460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                               llvm::Twine(pOutput.type()));
1825460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      return NULL;
1835460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
1845460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
1855460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1865460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaobool X86GNULDBackend::isSymbolNeedsPLT(const ResolveInfo& pSym,
1875460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                       const MCLDInfo& pLDInfo,
1885460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                       const Output& pOutput) const
1895460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
1905460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  return((Output::DynObj == pOutput.type())
1915460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao         &&(ResolveInfo::Function == pSym.type())
1925460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao         &&(pSym.isDyn() || pSym.isUndef() ||
1935460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao            isSymbolPreemptible(pSym, pLDInfo, pOutput))
1945460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        );
1955460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
1965460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1975460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaobool X86GNULDBackend::isSymbolNeedsDynRel(const ResolveInfo& pSym,
1985460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                          const Output& pOutput,
1995460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                          bool isAbsReloc) const
2005460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
2015460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  if(pSym.isUndef() && (pOutput.type()==Output::Exec))
2025460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    return false;
2035460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  if(pSym.isAbsolute())
2045460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    return false;
2055460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  if(pOutput.type()==Output::DynObj && isAbsReloc)
2065460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    return true;
2075460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  if(pSym.isDyn() || pSym.isUndef())
2085460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    return true;
2095460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
2105460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  return false;
2115460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
2125460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
2135460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaobool X86GNULDBackend::isSymbolPreemptible(const ResolveInfo& pSym,
2145460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                         const MCLDInfo& pLDInfo,
2155460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                         const Output& pOutput) const
2165460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
2175460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  if(pSym.other() != ResolveInfo::Default)
2185460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    return false;
2195460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
2205460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  if(pOutput.type() != Output::DynObj)
2215460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    return false;
2225460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
2235460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  if(pLDInfo.options().Bsymbolic())
2245460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    return false;
2255460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
2265460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  return true;
2275460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
2285460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
2295460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaovoid X86GNULDBackend::updateAddend(Relocation& pReloc,
2305460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                   const LDSymbol& pInputSym,
2315460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                   const Layout& pLayout) const
2325460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
2335460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // Update value keep in addend if we meet a section symbol
2345460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  if(pReloc.symInfo()->type() == ResolveInfo::Section) {
2355460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    pReloc.setAddend(pLayout.getOutputOffset(
2365460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                     *pInputSym.fragRef()) + pReloc.addend());
2375460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
2385460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
2395460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
2405460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaovoid X86GNULDBackend::scanLocalReloc(Relocation& pReloc,
2415460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                     const LDSymbol& pInputSym,
2425460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                     MCLinker& pLinker,
2435460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                     const MCLDInfo& pLDInfo,
2445460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                     const Output& pOutput)
2455460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
2465460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // rsym - The relocation target symbol
2475460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  ResolveInfo* rsym = pReloc.symInfo();
2485460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
2495460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  updateAddend(pReloc, pInputSym, pLinker.getLayout());
2505460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
2515460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  switch(pReloc.type()){
2525460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
2535460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_386_32:
2545460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      // If buiding PIC object (shared library or PIC executable),
2555460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      // a dynamic relocations with RELATIVE type to this location is needed.
2565460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      // Reserve an entry in .rel.dyn
2575460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      if(Output::DynObj == pOutput.type()) {
2585460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        // create .rel.dyn section if not exist
2595460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        if(NULL == m_pRelDyn)
2605460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao          createX86RelDyn(pLinker, pOutput);
2615460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        m_pRelDyn->reserveEntry(*m_pRelocFactory);
2625460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        // set Rel bit
2635460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        rsym->setReserved(rsym->reserved() | ReserveRel);
2645460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      }
2655460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      return;
2665460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
2675460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_386_GOTOFF:
2685460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_386_GOTPC:
2695460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      // A GOT section is needed
2705460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      if(NULL == m_pGOT)
2715460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        createX86GOT(pLinker, pOutput);
2725460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      return;
2735460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
2745460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_386_PC32:
2755460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      return;
2765460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
2775460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    default:
2785460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      llvm::report_fatal_error(llvm::Twine("unexpected reloc ") +
2795460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                               llvm::Twine((int) pReloc.type()) +
2805460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                               llvm::Twine(" in object file"));
2815460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      break;
2825460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  } // end switch
2835460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
2845460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
2855460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaovoid X86GNULDBackend::scanGlobalReloc(Relocation& pReloc,
2865460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                      const LDSymbol& pInputSym,
2875460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                      MCLinker& pLinker,
2885460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                      const MCLDInfo& pLDInfo,
2895460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                      const Output& pOutput)
2905460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
2915460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // rsym - The relocation target symbol
2925460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  ResolveInfo* rsym = pReloc.symInfo();
2935460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
2945460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  switch(pReloc.type()) {
2955460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_386_32:
2965460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      // Absolute relocation type, symbol may needs PLT entry or
2975460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      // dynamic relocation entry
2985460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      if(isSymbolNeedsPLT(*rsym, pLDInfo, pOutput)) {
2995460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        // create plt for this symbol if it does not have one
3005460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        if(!(rsym->reserved() & ReservePLT)){
3015460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao          // Create .got section if it dosen't exist
3025460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao          if(NULL == m_pGOT)
3035460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao             createX86GOT(pLinker, pOutput);
3045460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao          // create .plt and .rel.plt if not exist
3055460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao          if(NULL == m_pPLT)
3065460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao            createX86PLTandRelPLT(pLinker, pOutput);
3075460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao          // Symbol needs PLT entry, we need to reserve a PLT entry
3085460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao          // and the corresponding GOT and dynamic relocation entry
3095460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao          // in .got and .rel.plt. (GOT entry will be reserved simultaneously
3105460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao          // when calling X86PLT->reserveEntry())
3115460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao          m_pPLT->reserveEntry();
3125460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao          m_pRelPLT->reserveEntry(*m_pRelocFactory);
3135460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao          // set PLT bit
3145460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao          rsym->setReserved(rsym->reserved() | ReservePLT);
3155460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        }
3165460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      }
3175460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
3185460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      if(isSymbolNeedsDynRel(*rsym, pOutput, true)) {
3195460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        // symbol needs dynamic relocation entry, reserve an entry in .rel.dyn
3205460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        // create .rel.dyn section if not exist
3215460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        if(NULL == m_pRelDyn)
3225460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao          createX86RelDyn(pLinker, pOutput);
3235460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        m_pRelDyn->reserveEntry(*m_pRelocFactory);
3245460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        // set Rel bit
3255460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        rsym->setReserved(rsym->reserved() | ReserveRel);
3265460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      }
3275460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      return;
3285460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
3295460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_386_GOTOFF:
3305460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_386_GOTPC: {
3315460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      // A GOT section is needed
3325460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      if(NULL == m_pGOT)
3335460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        createX86GOT(pLinker, pOutput);
3345460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      return;
3355460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    }
3365460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
3375460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_386_PLT32:
3385460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      // A PLT entry is needed when building shared library
3395460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
3405460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      // return if we already create plt for this symbol
3415460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      if(rsym->reserved() & ReservePLT)
3425460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        return;
3435460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
3445460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      // if symbol is defined in the ouput file and it's not
3455460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      // preemptible, no need plt
3465460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      if(rsym->isDefine() && !rsym->isDyn() &&
3475460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao         !isSymbolPreemptible(*rsym, pLDInfo, pOutput)) {
3485460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        return;
3495460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      }
3505460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
3515460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      // Create .got section if it dosen't exist
3525460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      if(NULL == m_pGOT)
3535460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao         createX86GOT(pLinker, pOutput);
3545460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      // create .plt and .rel.plt if not exist
3555460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      if(NULL == m_pPLT)
3565460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao         createX86PLTandRelPLT(pLinker, pOutput);
3575460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      // Symbol needs PLT entry, we need to reserve a PLT entry
3585460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      // and the corresponding GOT and dynamic relocation entry
3595460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      // in .got and .rel.plt. (GOT entry will be reserved simultaneously
3605460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      // when calling X86PLT->reserveEntry())
3615460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      m_pPLT->reserveEntry();
3625460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      m_pRelPLT->reserveEntry(*m_pRelocFactory);
3635460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      // set PLT bit
3645460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      rsym->setReserved(rsym->reserved() | ReservePLT);
3655460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      return;
3665460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
3675460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_386_GOT32:
3685460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      // Symbol needs GOT entry, reserve entry in .got
3695460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      // return if we already create GOT for this symbol
3705460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      if(rsym->reserved() & (ReserveGOT | GOTRel))
3715460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        return;
3725460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      if(NULL == m_pGOT)
3735460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        createX86GOT(pLinker, pOutput);
3745460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      m_pGOT->reserveEntry();
3755460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      // If building shared object or the symbol is undefined, a dynamic
3765460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      // relocation is needed to relocate this GOT entry. Reserve an
3775460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      // entry in .rel.dyn
3785460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      if(Output::DynObj == pOutput.type() || rsym->isUndef() || rsym->isDyn()) {
3795460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        // create .rel.dyn section if not exist
3805460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        if(NULL == m_pRelDyn)
3815460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao          createX86RelDyn(pLinker, pOutput);
3825460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        m_pRelDyn->reserveEntry(*m_pRelocFactory);
3835460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        // set GOTRel bit
3845460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        rsym->setReserved(rsym->reserved() | GOTRel);
3855460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        return;
3865460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      }
3875460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      // set GOT bit
3885460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      rsym->setReserved(rsym->reserved() | ReserveGOT);
3895460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      return;
3905460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
3915460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_386_PC32:
3925460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      // We allow R_386_PC32 only if it isn't preemptible.  Otherwise
3935460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      // we will generate writable text section in output.
3945460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      if (!isSymbolPreemptible(*rsym, pLDInfo, pOutput))
3955460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao	return;
3965460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
3975460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    default: {
3985460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      llvm::report_fatal_error(llvm::Twine("Unexpected reloc ") +
3995460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                               llvm::Twine((int) pReloc.type()) +
4005460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                               llvm::Twine(" in object file"));
4015460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      break;
4025460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    }
4035460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  } // end switch
4045460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
4055460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
4065460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaovoid X86GNULDBackend::scanRelocation(Relocation& pReloc,
4075460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                     const LDSymbol& pInputSym,
4085460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                     MCLinker& pLinker,
4095460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                     const MCLDInfo& pLDInfo,
4105460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                     const Output& pOutput)
4115460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
4125460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // rsym - The relocation target symbol
4135460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  ResolveInfo* rsym = pReloc.symInfo();
4145460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  assert(NULL != rsym && "ResolveInfo of relocation not set while scanRelocation");
4155460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
4165460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // Scan relocation type to determine if an GOT/PLT/Dynamic Relocation
4175460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // entries should be created.
4185460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // FIXME: Below judgements concern only .so is generated as output
4195460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // FIXME: Below judgements concren nothing about TLS related relocation
4205460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
4215460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // A refernece to symbol _GLOBAL_OFFSET_TABLE_ implies that a .got section
4225460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // is needed
4235460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  if(NULL == m_pGOT && NULL != m_pGOTSymbol) {
4245460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    if(rsym == m_pGOTSymbol->resolveInfo()) {
4255460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      createX86GOT(pLinker, pOutput);
4265460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    }
4275460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
4285460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
4295460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // rsym is local
4305460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  if(rsym->isLocal())
4315460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    scanLocalReloc(pReloc, pInputSym,  pLinker, pLDInfo, pOutput);
4325460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
4335460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // rsym is external
4345460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  else
4355460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    scanGlobalReloc(pReloc, pInputSym ,pLinker, pLDInfo, pOutput);
4365460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
4375460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
4385460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
4395460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaouint64_t X86GNULDBackend::emitSectionData(const Output& pOutput,
4405460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                          const LDSection& pSection,
4415460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                          const MCLDInfo& pInfo,
4425460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                          MemoryRegion& pRegion) const
4435460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
4445460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  assert(pRegion.size() && "Size of MemoryRegion is zero!");
4455460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
4465460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  ELFFileFormat* FileFormat = getOutputFormat(pOutput);
4475460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  assert(FileFormat &&
4485460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao         "ELFFileFormat is NULL in X86GNULDBackend::emitSectionData!");
4495460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
4505460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  unsigned int EntrySize = 0;
4515460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  uint64_t RegionSize = 0;
4525460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
4535460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  if (&pSection == &(FileFormat->getPLT())) {
4545460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    assert(m_pPLT && "emitSectionData failed, m_pPLT is NULL!");
4555460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
4565460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    unsigned char* buffer = pRegion.getBuffer();
4575460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
4585460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    m_pPLT->applyPLT0();
4595460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    m_pPLT->applyPLT1();
4605460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
4615460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    X86PLT::iterator it = m_pPLT->begin();
4625460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    unsigned int plt0_size = llvm::cast<X86PLT0>((*it)).getEntrySize();
4635460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
4645460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    memcpy(buffer, llvm::cast<X86PLT0>((*it)).getContent(), plt0_size);
4655460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    RegionSize += plt0_size;
4665460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    ++it;
4675460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
4685460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    X86PLT1* plt1 = 0;
4695460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    X86PLT::iterator ie = m_pPLT->end();
4705460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    while (it != ie) {
4715460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      plt1 = &(llvm::cast<X86PLT1>(*it));
4725460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      EntrySize = plt1->getEntrySize();
4735460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      memcpy(buffer + RegionSize, plt1->getContent(), EntrySize);
4745460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      RegionSize += EntrySize;
4755460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      ++it;
4765460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    }
4775460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
4785460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
4795460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  else if (&pSection == &(FileFormat->getGOT())) {
4805460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    assert(m_pGOT && "emitSectionData failed, m_pGOT is NULL!");
4815460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
4825460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    m_pGOT->applyGOT0(FileFormat->getDynamic().addr());
4835460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
4845460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    uint32_t* buffer = reinterpret_cast<uint32_t*>(pRegion.getBuffer());
4855460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
4865460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    GOTEntry* got = 0;
4875460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    EntrySize = m_pGOT->getEntrySize();
4885460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
4895460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    for (X86GOT::iterator it = m_pGOT->begin(),
4905460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao         ie = m_pGOT->end(); it != ie; ++it, ++buffer) {
4915460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      got = &(llvm::cast<GOTEntry>((*it)));
4925460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      *buffer = static_cast<uint32_t>(got->getContent());
4935460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      RegionSize += EntrySize;
4945460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    }
4955460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
4965460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
4975460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  else
4985460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    llvm::report_fatal_error("unsupported section name "
4995460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                             + pSection.name() + " !");
5005460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
5015460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  return RegionSize;
5025460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
5035460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaouint32_t X86GNULDBackend::machine() const
5045460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
5055460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  return llvm::ELF::EM_386;
5065460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
5075460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
5085460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei LiaoX86GOT& X86GNULDBackend::getGOT()
5095460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
5105460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  assert(NULL != m_pGOT);
5115460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  return *m_pGOT;
5125460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
5135460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
5145460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaoconst X86GOT& X86GNULDBackend::getGOT() const
5155460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
5165460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  assert(NULL != m_pGOT);
5175460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  return *m_pGOT;
5185460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
5195460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
5205460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei LiaoX86PLT& X86GNULDBackend::getPLT()
5215460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
5225460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  assert(NULL != m_pPLT && "PLT section not exist");
5235460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  return *m_pPLT;
5245460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
5255460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
5265460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaoconst X86PLT& X86GNULDBackend::getPLT() const
5275460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
5285460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  assert(NULL != m_pPLT && "PLT section not exist");
5295460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  return *m_pPLT;
5305460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
5315460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
5325460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei LiaoOutputRelocSection& X86GNULDBackend::getRelDyn()
5335460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
5345460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  assert(NULL != m_pRelDyn && ".rel.dyn section not exist");
5355460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  return *m_pRelDyn;
5365460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
5375460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
5385460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaoconst OutputRelocSection& X86GNULDBackend::getRelDyn() const
5395460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
5405460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  assert(NULL != m_pRelDyn && ".rel.dyn section not exist");
5415460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  return *m_pRelDyn;
5425460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
5435460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
5445460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei LiaoOutputRelocSection& X86GNULDBackend::getRelPLT()
5455460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
5465460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  assert(NULL != m_pRelPLT && ".rel.plt section not exist");
5475460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  return *m_pRelPLT;
5485460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
5495460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
5505460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaoconst OutputRelocSection& X86GNULDBackend::getRelPLT() const
5515460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
5525460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  assert(NULL != m_pRelPLT && ".rel.plt section not exist");
5535460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  return *m_pRelPLT;
5545460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
5555460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
5565460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaounsigned int
5575460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei LiaoX86GNULDBackend::getTargetSectionOrder(const Output& pOutput,
5585460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                       const LDSection& pSectHdr) const
5595460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
5605460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  ELFFileFormat* file_format = getOutputFormat(pOutput);
5615460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
5625460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // FIXME: if command line option, "-z now", is given, we can let the order of
5635460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // .got and .got.plt be the same as RELRO sections
5645460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  if (&pSectHdr == &file_format->getGOT())
5655460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    return SHO_RELRO_LAST;
5665460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
5675460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  if (&pSectHdr == &file_format->getGOTPLT())
5685460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    return SHO_NON_RELRO_FIRST;
5695460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
5705460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  if (&pSectHdr == &file_format->getPLT())
5715460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    return SHO_PLT;
5725460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
5735460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  return SHO_UNDEFINED;
5745460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
5755460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
5765460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaounsigned int X86GNULDBackend::bitclass() const
5775460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
5785460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  return 32;
5795460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
5805460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
5815460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaobool X86GNULDBackend::initTargetSectionMap(SectionMap& pSectionMap)
5825460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
5835460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  return true;
5845460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
5855460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
5865460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaovoid X86GNULDBackend::initTargetSections(MCLinker& pLinker)
5875460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
5885460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
5895460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
5905460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaovoid X86GNULDBackend::initTargetSymbols(MCLinker& pLinker)
5915460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
5925460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // Define the symbol _GLOBAL_OFFSET_TABLE_ if there is a symbol with the
5935460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // same name in input
5945460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  m_pGOTSymbol = pLinker.defineSymbol<MCLinker::AsRefered, MCLinker::Resolve>(
5955460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                   "_GLOBAL_OFFSET_TABLE_",
5965460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                   false,
5975460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                   ResolveInfo::Object,
5985460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                   ResolveInfo::Define,
5995460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                   ResolveInfo::Local,
6005460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                   0x0,  // size
6015460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                   0x0,  // value
6025460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                   NULL, // FragRef
6035460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                   ResolveInfo::Hidden);
6045460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
6055460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
6065460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// finalizeSymbol - finalize the symbol value
6075460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// If the symbol's reserved field is not zero, MCLinker will call back this
6085460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// function to ask the final value of the symbol
6095460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaobool X86GNULDBackend::finalizeSymbol(LDSymbol& pSymbol) const
6105460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
6115460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  return false;
6125460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
6135460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
6145460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// allocateCommonSymbols - allocate common symbols in the corresponding
6155460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// sections.
6165460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// @refer Google gold linker: common.cc: 214
6175460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaobool
6185460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei LiaoX86GNULDBackend::allocateCommonSymbols(const MCLDInfo& pInfo, MCLinker& pLinker) const
6195460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
6205460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // SymbolCategory contains all symbols that must emit to the output files.
6215460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // We are not like Google gold linker, we don't remember symbols before symbol
6225460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // resolution. All symbols in SymbolCategory are already resolved. Therefore, we
6235460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // don't need to care about some symbols may be changed its category due to symbol
6245460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // resolution.
6255460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  SymbolCategory& symbol_list = pLinker.getOutputSymbols();
6265460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
6275460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  if (symbol_list.emptyCommons() && symbol_list.emptyLocals())
6285460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    return true;
6295460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
6305460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // addralign := max value of all common symbols
6315460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  uint64_t addralign = 0x0;
6325460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
6335460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // Due to the visibility, some common symbols may be forcefully local.
6345460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  SymbolCategory::iterator com_sym, com_end = symbol_list.localEnd();
6355460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  for (com_sym = symbol_list.localBegin(); com_sym != com_end; ++com_sym) {
6365460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    if (ResolveInfo::Common == (*com_sym)->desc()) {
6375460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      if ((*com_sym)->value() > addralign)
6385460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        addralign = (*com_sym)->value();
6395460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    }
6405460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
6415460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
6425460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // global common symbols.
6435460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  com_end = symbol_list.commonEnd();
6445460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  for (com_sym = symbol_list.commonBegin(); com_sym != com_end; ++com_sym) {
6455460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    if ((*com_sym)->value() > addralign)
6465460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      addralign = (*com_sym)->value();
6475460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
6485460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
6495460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // FIXME: If the order of common symbols is defined, then sort common symbols
6505460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // com_sym = symbol_list.commonBegin();
6515460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // std::sort(com_sym, com_end, some kind of order);
6525460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
6535460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // get or create corresponding BSS LDSection
6545460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  LDSection* bss_sect_hdr = NULL;
6555460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  if (ResolveInfo::ThreadLocal == (*com_sym)->type()) {
6565460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    bss_sect_hdr = &pLinker.getOrCreateOutputSectHdr(
6575460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                   ".tbss",
6585460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                   LDFileFormat::BSS,
6595460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                   llvm::ELF::SHT_NOBITS,
6605460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                   llvm::ELF::SHF_WRITE | llvm::ELF::SHF_ALLOC);
6615460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
6625460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  else {
6635460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    bss_sect_hdr = &pLinker.getOrCreateOutputSectHdr(".bss",
6645460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                   LDFileFormat::BSS,
6655460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                   llvm::ELF::SHT_NOBITS,
6665460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                   llvm::ELF::SHF_WRITE | llvm::ELF::SHF_ALLOC);
6675460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
6685460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
6695460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // get or create corresponding BSS MCSectionData
6705460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  assert(NULL != bss_sect_hdr);
6715460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  llvm::MCSectionData& bss_section = pLinker.getOrCreateSectData(*bss_sect_hdr);
6725460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
6735460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // allocate all common symbols
6745460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  uint64_t offset = bss_sect_hdr->size();
6755460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
6765460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // allocate all local common symbols
6775460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  com_end = symbol_list.localEnd();
6785460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  for (com_sym = symbol_list.localBegin(); com_sym != com_end; ++com_sym) {
6795460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    if (ResolveInfo::Common == (*com_sym)->desc()) {
6805460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      // We have to reset the description of the symbol here. When doing
6815460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      // incremental linking, the output relocatable object may have common
6825460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      // symbols. Therefore, we can not treat common symbols as normal symbols
6835460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      // when emitting the regular name pools. We must change the symbols'
6845460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      // description here.
6855460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      (*com_sym)->resolveInfo()->setDesc(ResolveInfo::Define);
6865460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      llvm::MCFragment* frag = new llvm::MCFillFragment(0x0, 1, (*com_sym)->size());
6875460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      (*com_sym)->setFragmentRef(new MCFragmentRef(*frag, 0));
6885460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      uint64_t size = pLinker.getLayout().appendFragment(*frag,
6895460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                                         bss_section,
6905460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                                         (*com_sym)->value());
6915460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      offset += size;
6925460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    }
6935460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
6945460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
6955460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // allocate all global common symbols
6965460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  com_end = symbol_list.commonEnd();
6975460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  for (com_sym = symbol_list.commonBegin(); com_sym != com_end; ++com_sym) {
6985460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    // We have to reset the description of the symbol here. When doing
6995460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    // incremental linking, the output relocatable object may have common
7005460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    // symbols. Therefore, we can not treat common symbols as normal symbols
7015460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    // when emitting the regular name pools. We must change the symbols'
7025460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    // description here.
7035460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    (*com_sym)->resolveInfo()->setDesc(ResolveInfo::Define);
7045460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    llvm::MCFragment* frag = new llvm::MCFillFragment(0x0, 1, (*com_sym)->size());
7055460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    (*com_sym)->setFragmentRef(new MCFragmentRef(*frag, 0));
7065460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    uint64_t size = pLinker.getLayout().appendFragment(*frag,
7075460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                                       bss_section,
7085460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                                       (*com_sym)->value());
7095460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    offset += size;
7105460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
7115460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
7125460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  bss_sect_hdr->setSize(offset);
7135460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  symbol_list.changeCommonsToGlobal();
7145460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  return true;
7155460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
7165460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
7175460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaonamespace mcld {
7185460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
7195460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao//===----------------------------------------------------------------------===//
7205460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// createX86LDBackend - the help funtion to create corresponding X86LDBackend
7215460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao///
7225460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei LiaoTargetLDBackend* createX86LDBackend(const llvm::Target& pTarget,
7235460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                    const std::string& pTriple)
7245460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
7255460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  Triple theTriple(pTriple);
7265460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  if (theTriple.isOSDarwin()) {
7275460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    assert(0 && "MachO linker is not supported yet");
7285460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    /**
7295460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    return new X86MachOLDBackend(createX86MachOArchiveReader,
7305460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                               createX86MachOObjectReader,
7315460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                               createX86MachOObjectWriter);
7325460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    **/
7335460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
7345460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  if (theTriple.isOSWindows()) {
7355460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    assert(0 && "COFF linker is not supported yet");
7365460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    /**
7375460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    return new X86COFFLDBackend(createX86COFFArchiveReader,
7385460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                               createX86COFFObjectReader,
7395460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                               createX86COFFObjectWriter);
7405460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    **/
7415460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
7425460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  return new X86GNULDBackend();
7435460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
7445460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
7455460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} // namespace of mcld
7465460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
7475460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao//=============================
7485460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao// Force static initialization.
7495460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaoextern "C" void LLVMInitializeX86LDBackend() {
7505460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // Register the linker backend
7515460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  mcld::TargetRegistry::RegisterTargetLDBackend(TheX86Target, createX86LDBackend);
7525460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
753