X86LDBackend.cpp revision 22add6ff3426df1a85089fe6a6e1597ee3b6f300
15460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao//===- X86LDBackend.cpp ---------------------------------------------------===//
25460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao//
35460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao//                     The MCLinker Project
45460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao//
55460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao// This file is distributed under the University of Illinois Open Source
65460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao// License. See LICENSE.TXT for details.
75460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao//
85460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao//===----------------------------------------------------------------------===//
95460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include "X86.h"
105460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include "X86ELFDynamic.h"
115460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include "X86LDBackend.h"
125460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include "X86RelocationFactory.h"
135460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
145460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include <llvm/ADT/Triple.h>
15cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao#include <llvm/Support/Casting.h>
16cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao
1722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao#include <mcld/LinkerConfig.h>
1822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao#include <mcld/IRBuilder.h>
1922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao#include <mcld/Fragment/FillFragment.h>
2022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao#include <mcld/Fragment/RegionFragment.h>
2122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao#include <mcld/Fragment/FragmentLinker.h>
22affc150dc44fab1911775a49636d0ce85333b634Zonr Chang#include <mcld/Support/MemoryRegion.h>
23affc150dc44fab1911775a49636d0ce85333b634Zonr Chang#include <mcld/Support/MsgHandling.h>
24affc150dc44fab1911775a49636d0ce85333b634Zonr Chang#include <mcld/Support/TargetRegistry.h>
2522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao#include <mcld/Object/ObjectBuilder.h>
265460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
275460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include <cstring>
285460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
295460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaousing namespace mcld;
305460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
3122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao//===----------------------------------------------------------------------===//
3222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao// X86GNULDBackend
3322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao//===----------------------------------------------------------------------===//
3422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei LiaoX86GNULDBackend::X86GNULDBackend(const LinkerConfig& pConfig)
3522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  : GNULDBackend(pConfig),
3622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    m_pRelocFactory(NULL),
375460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    m_pGOT(NULL),
385460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    m_pPLT(NULL),
39affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    m_pGOTPLT(NULL),
405460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    m_pRelDyn(NULL),
415460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    m_pRelPLT(NULL),
4267e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao    m_pDynamic(NULL),
4367e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao    m_pGOTSymbol(NULL) {
445460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
455460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
465460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei LiaoX86GNULDBackend::~X86GNULDBackend()
475460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
4822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  delete m_pRelocFactory;
4922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  delete m_pGOT;
5022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  delete m_pPLT;
5122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  delete m_pGOTPLT;
5222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  delete m_pRelDyn;
5322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  delete m_pRelPLT;
5422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-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
6322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaobool X86GNULDBackend::initRelocFactory(const FragmentLinker& pLinker)
645460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
655460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  if (NULL == m_pRelocFactory) {
665460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    m_pRelocFactory = new X86RelocationFactory(1024, *this);
6722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    m_pRelocFactory->setFragmentLinker(pLinker);
685460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
695460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  return true;
705460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
715460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
7222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaovoid X86GNULDBackend::doPreLayout(FragmentLinker& pLinker)
735460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
7422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  // set .got.plt size
7522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  // when building shared object, the .got section is must
7622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  if (LinkerConfig::Object != config().codeGenType()) {
7722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    if (LinkerConfig::DynObj == config().codeGenType() ||
7822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        m_pGOTPLT->hasGOT1() ||
7922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        NULL != m_pGOTSymbol) {
8022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      m_pGOTPLT->finalizeSectionSize();
8122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      defineGOTSymbol(pLinker);
8222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    }
8322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
8422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    // set .got size
8522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    if (!m_pGOT->empty())
8622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      m_pGOT->finalizeSectionSize();
8722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
8822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    // set .plt size
8922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    if (m_pPLT->hasPLT1())
9022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      m_pPLT->finalizeSectionSize();
9122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
9222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    // set .rel.dyn size
9322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    if (!m_pRelDyn->empty())
9422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      m_pRelDyn->finalizeSectionSize();
9522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
9622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    // set .rel.plt size
9722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    if (!m_pRelPLT->empty())
9822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      m_pRelPLT->finalizeSectionSize();
99affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  }
1005460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
1015460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
10222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaovoid X86GNULDBackend::doPostLayout(Module& pModule,
10322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                                   FragmentLinker& pLinker)
1045460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
1055460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
1065460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1075460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// dynamic - the dynamic section of the target machine.
1085460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// Use co-variant return type to return its own dynamic section.
1095460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei LiaoX86ELFDynamic& X86GNULDBackend::dynamic()
1105460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
1115460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  if (NULL == m_pDynamic)
1125460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    m_pDynamic = new X86ELFDynamic(*this);
1135460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1145460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  return *m_pDynamic;
1155460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
1165460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1175460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// dynamic - the dynamic section of the target machine.
1185460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// Use co-variant return type to return its own dynamic section.
1195460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaoconst X86ELFDynamic& X86GNULDBackend::dynamic() const
1205460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
1215460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  assert( NULL != m_pDynamic);
1225460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  return *m_pDynamic;
1235460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
1245460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
12522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaovoid X86GNULDBackend::defineGOTSymbol(FragmentLinker& pLinker)
1265460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
12722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  // define symbol _GLOBAL_OFFSET_TABLE_
128affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  if (m_pGOTSymbol != NULL) {
12922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    pLinker.defineSymbol<FragmentLinker::Force, FragmentLinker::Unresolve>(
1305460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                     "_GLOBAL_OFFSET_TABLE_",
1315460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                     false,
1325460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                     ResolveInfo::Object,
1335460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                     ResolveInfo::Define,
1345460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                     ResolveInfo::Local,
1355460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                     0x0, // size
1365460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                     0x0, // value
13722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                     FragmentRef::Create(*(m_pGOTPLT->begin()), 0x0),
1385460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                     ResolveInfo::Hidden);
1395460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
1405460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  else {
14122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    m_pGOTSymbol = pLinker.defineSymbol<FragmentLinker::Force, FragmentLinker::Resolve>(
1425460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                     "_GLOBAL_OFFSET_TABLE_",
1435460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                     false,
1445460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                     ResolveInfo::Object,
1455460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                     ResolveInfo::Define,
1465460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                     ResolveInfo::Local,
1475460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                     0x0, // size
1485460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                     0x0, // value
14922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                     FragmentRef::Create(*(m_pGOTPLT->begin()), 0x0),
1505460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                     ResolveInfo::Hidden);
1515460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
1525460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
1535460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
154affc150dc44fab1911775a49636d0ce85333b634Zonr Changvoid X86GNULDBackend::addCopyReloc(ResolveInfo& pSym)
1555460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
15622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  Relocation& rel_entry = *m_pRelDyn->consumeEntry();
157affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  rel_entry.setType(llvm::ELF::R_386_COPY);
158affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  assert(pSym.outSymbol()->hasFragRef());
159affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  rel_entry.targetRef().assign(*pSym.outSymbol()->fragRef());
160affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  rel_entry.setSymInfo(&pSym);
1615460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
1625460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
16322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// defineSymbolforCopyReloc
16422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// For a symbol needing copy relocation, define a copy symbol in the BSS
16522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// section and all other reference to this symbol should refer to this
16622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// copy.
16722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// @note This is executed at `scan relocation' stage.
16822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei LiaoLDSymbol& X86GNULDBackend::defineSymbolforCopyReloc(FragmentLinker& pLinker,
169affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                                    const ResolveInfo& pSym)
1705460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
171affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  // get or create corresponding BSS LDSection
172affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  LDSection* bss_sect_hdr = NULL;
17322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  ELFFileFormat* file_format = getOutputFormat();
17422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  if (ResolveInfo::ThreadLocal == pSym.type())
17522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    bss_sect_hdr = &file_format->getTBSS();
17622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  else
17722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    bss_sect_hdr = &file_format->getBSS();
1785460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
179cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao  // get or create corresponding BSS SectionData
180affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  assert(NULL != bss_sect_hdr);
18122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  SectionData* bss_section = NULL;
18222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  if (bss_sect_hdr->hasSectionData())
18322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    bss_section = bss_sect_hdr->getSectionData();
18422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  else
18522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    bss_section = IRBuilder::CreateSectionData(*bss_sect_hdr);
186affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
187affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  // Determine the alignment by the symbol value
188affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  // FIXME: here we use the largest alignment
189affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  uint32_t addralign = bitclass() / 8;
190affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
191affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  // allocate space in BSS for the copy symbol
192cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao  Fragment* frag = new FillFragment(0x0, 1, pSym.size());
19322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  uint64_t size = ObjectBuilder::AppendFragment(*frag,
19422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                                                *bss_section,
19522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                                                addralign);
196affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  bss_sect_hdr->setSize(bss_sect_hdr->size() + size);
197affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
198affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  // change symbol binding to Global if it's a weak symbol
199affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  ResolveInfo::Binding binding = (ResolveInfo::Binding)pSym.binding();
200affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  if (binding == ResolveInfo::Weak)
201affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    binding = ResolveInfo::Global;
202affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
203affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  // Define the copy symbol in the bss section and resolve it
20422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  LDSymbol* cpy_sym =
20522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao           pLinker.defineSymbol<FragmentLinker::Force, FragmentLinker::Resolve>(
206affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                      pSym.name(),
207affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                      false,
208affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                      (ResolveInfo::Type)pSym.type(),
209affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                      ResolveInfo::Define,
210affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                      binding,
211affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                      pSym.size(),  // size
212affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                      0x0,          // value
21322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                      FragmentRef::Create(*frag, 0x0),
214affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                      (ResolveInfo::Visibility)pSym.other());
215affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
216affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  return *cpy_sym;
2175460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
2185460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
2195460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaovoid X86GNULDBackend::scanLocalReloc(Relocation& pReloc,
22022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                                     FragmentLinker& pLinker,
22122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                                     Module& pModule,
22222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                                     const LDSection& pSection)
2235460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
2245460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // rsym - The relocation target symbol
2255460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  ResolveInfo* rsym = pReloc.symInfo();
2265460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
2275460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  switch(pReloc.type()){
2285460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
2295460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_386_32:
23022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    case llvm::ELF::R_386_16:
23122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    case llvm::ELF::R_386_8:
2325460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      // If buiding PIC object (shared library or PIC executable),
2335460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      // a dynamic relocations with RELATIVE type to this location is needed.
2345460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      // Reserve an entry in .rel.dyn
23522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      if (pLinker.isOutputPIC()) {
2365460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        m_pRelDyn->reserveEntry(*m_pRelocFactory);
2375460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        // set Rel bit
2385460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        rsym->setReserved(rsym->reserved() | ReserveRel);
2395460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      }
2405460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      return;
2415460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
2425460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_386_GOTOFF:
2435460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_386_GOTPC:
24422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      // FIXME: A GOT section is needed
24522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      return;
24622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
24722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    case llvm::ELF::R_386_GOT32:
24822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      // Symbol needs GOT entry, reserve entry in .got
24922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      // return if we already create GOT for this symbol
25022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      if (rsym->reserved() & (ReserveGOT | GOTRel))
25122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        return;
25222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      // FIXME: check STT_GNU_IFUNC symbol
25322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      m_pGOT->reserve();
25422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      // If building shared object or the symbol is undefined, a dynamic
25522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      // relocation is needed to relocate this GOT entry. Reserve an
25622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      // entry in .rel.dyn
25722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      if (LinkerConfig::DynObj ==
25822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                   config().codeGenType() || rsym->isUndef() || rsym->isDyn()) {
25922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        m_pRelDyn->reserveEntry(*m_pRelocFactory);
26022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        // set GOTRel bit
26122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        rsym->setReserved(rsym->reserved() | GOTRel);
26222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        return;
26322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      }
26422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      // set GOT bit
26522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      rsym->setReserved(rsym->reserved() | ReserveGOT);
2665460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      return;
2675460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
2685460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_386_PC32:
26922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    case llvm::ELF::R_386_PC16:
27022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    case llvm::ELF::R_386_PC8:
27122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      return;
27222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
27322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    case llvm::ELF::R_386_TLS_GD: {
27422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      // FIXME: no linker optimization for TLS relocation
27522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      if (rsym->reserved() & GOTRel)
27622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        return;
27722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      m_pGOT->reserve(2);
27822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      // reserve an rel entry
27922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      m_pRelDyn->reserveEntry(*m_pRelocFactory);
28022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      // set GOTRel bit
28122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      rsym->setReserved(rsym->reserved() | GOTRel);
28222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      // define the section symbol for .tdata or .tbss
28322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      // the target symbol of the created dynamic relocation should be the
28422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      // section symbol of the section which this symbol defined. so we
28522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      // need to define that section symbol here
28622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      ELFFileFormat* file_format = getOutputFormat();
28722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      const LDSection* sym_sect =
28822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao               &rsym->outSymbol()->fragRef()->frag()->getParent()->getSection();
28922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      if (&file_format->getTData() == sym_sect) {
29022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        if (NULL == f_pTDATA)
29122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao          f_pTDATA = pModule.getSectionSymbolSet().get(*sym_sect);
29222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      }
29322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      else if (&file_format->getTBSS() == sym_sect || rsym->isCommon()) {
29422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        if (NULL == f_pTBSS)
29522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao          f_pTBSS = pModule.getSectionSymbolSet().get(*sym_sect);
29622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      }
29722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      else
29822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        error(diag::invalid_tls) << rsym->name() << sym_sect->name();
29922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      return;
30022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    }
30122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
30222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    case llvm::ELF::R_386_TLS_LDM:
30322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      getTLSModuleID();
30422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      return;
30522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
30622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    case llvm::ELF::R_386_TLS_LDO_32:
30722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      return;
30822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
30922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    case llvm::ELF::R_386_TLS_IE:
31022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      setHasStaticTLS();
31122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      // if buildint shared object, a RELATIVE dynamic relocation is needed
31222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      if (LinkerConfig::DynObj == config().codeGenType()) {
31322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        m_pRelDyn->reserveEntry(*m_pRelocFactory);
31422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        rsym->setReserved(rsym->reserved() | ReserveRel);
31522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      }
31622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      if (rsym->reserved() & GOTRel)
31722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        return;
31822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      // reserve got and dyn relocation entries for tp-relative offset
31922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      m_pGOT->reserve();
32022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      m_pRelDyn->reserveEntry(*m_pRelocFactory);
32122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      // set GOTRel bit
32222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      rsym->setReserved(rsym->reserved() | GOTRel);
32322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      m_pRelDyn->addSymbolToDynSym(*rsym->outSymbol());
32422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      return;
32522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
32622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    case llvm::ELF::R_386_TLS_GOTIE:
32722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      setHasStaticTLS();
32822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      if (rsym->reserved() & GOTRel)
32922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        return;
33022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      // reserve got and dyn relocation entries for tp-relative offset
33122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      m_pGOT->reserve();
33222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      m_pRelDyn->reserveEntry(*m_pRelocFactory);
33322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      // set GOTRel bit
33422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      rsym->setReserved(rsym->reserved() | GOTRel);
33522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      m_pRelDyn->addSymbolToDynSym(*rsym->outSymbol());
33622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      return;
33722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
33822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    case llvm::ELF::R_386_TLS_LE:
33922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    case llvm::ELF::R_386_TLS_LE_32:
34022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      setHasStaticTLS();
34122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      // if buildint shared object, a dynamic relocation is needed
34222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      if (LinkerConfig::DynObj == config().codeGenType()) {
34322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        m_pRelDyn->reserveEntry(*m_pRelocFactory);
34422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        rsym->setReserved(rsym->reserved() | ReserveRel);
34522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        // the target symbol of the dynamic relocation is rsym, so we need to
34622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        // emit it into .dynsym
34722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        assert(NULL != rsym->outSymbol());
34822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        m_pRelDyn->addSymbolToDynSym(*rsym->outSymbol());
34922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      }
3505460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      return;
3515460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
3525460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    default:
353affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      fatal(diag::unsupported_relocation) << (int)pReloc.type()
354affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                          << "mclinker@googlegroups.com";
3555460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      break;
3565460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  } // end switch
3575460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
3585460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
3595460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaovoid X86GNULDBackend::scanGlobalReloc(Relocation& pReloc,
36022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                                      FragmentLinker& pLinker,
36122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                                      Module& pModule,
36222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                                      const LDSection& pSection)
3635460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
3645460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // rsym - The relocation target symbol
3655460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  ResolveInfo* rsym = pReloc.symInfo();
3665460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
3675460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  switch(pReloc.type()) {
3685460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_386_32:
36922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    case llvm::ELF::R_386_16:
37022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    case llvm::ELF::R_386_8:
3715460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      // Absolute relocation type, symbol may needs PLT entry or
3725460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      // dynamic relocation entry
37322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      if (symbolNeedsPLT(pLinker, *rsym)) {
3745460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        // create plt for this symbol if it does not have one
375affc150dc44fab1911775a49636d0ce85333b634Zonr Chang        if (!(rsym->reserved() & ReservePLT)){
3765460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao          // Symbol needs PLT entry, we need to reserve a PLT entry
3775460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao          // and the corresponding GOT and dynamic relocation entry
3785460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao          // in .got and .rel.plt. (GOT entry will be reserved simultaneously
3795460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao          // when calling X86PLT->reserveEntry())
3805460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao          m_pPLT->reserveEntry();
38122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao          m_pGOTPLT->reserve();
3825460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao          m_pRelPLT->reserveEntry(*m_pRelocFactory);
3835460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao          // set PLT bit
3845460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao          rsym->setReserved(rsym->reserved() | ReservePLT);
3855460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        }
3865460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      }
3875460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
38822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      if (symbolNeedsDynRel(pLinker, *rsym, (rsym->reserved() & ReservePLT),
38922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                                                                       true)) {
3905460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        // symbol needs dynamic relocation entry, reserve an entry in .rel.dyn
3915460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        m_pRelDyn->reserveEntry(*m_pRelocFactory);
39222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        if (symbolNeedsCopyReloc(pLinker, pReloc, *rsym)) {
393affc150dc44fab1911775a49636d0ce85333b634Zonr Chang          LDSymbol& cpy_sym = defineSymbolforCopyReloc(pLinker, *rsym);
394affc150dc44fab1911775a49636d0ce85333b634Zonr Chang          addCopyReloc(*cpy_sym.resolveInfo());
395affc150dc44fab1911775a49636d0ce85333b634Zonr Chang        }
396affc150dc44fab1911775a49636d0ce85333b634Zonr Chang        else {
397affc150dc44fab1911775a49636d0ce85333b634Zonr Chang          // set Rel bit
398affc150dc44fab1911775a49636d0ce85333b634Zonr Chang          rsym->setReserved(rsym->reserved() | ReserveRel);
399affc150dc44fab1911775a49636d0ce85333b634Zonr Chang        }
4005460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      }
4015460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      return;
4025460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
4035460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_386_GOTOFF:
4045460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_386_GOTPC: {
40522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      // FIXME: A GOT section is needed
4065460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      return;
4075460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    }
4085460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
4095460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_386_PLT32:
4105460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      // A PLT entry is needed when building shared library
4115460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
4125460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      // return if we already create plt for this symbol
413affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      if (rsym->reserved() & ReservePLT)
4145460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        return;
4155460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
41622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      // if the symbol's value can be decided at link time, then no need plt
41722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      if (symbolFinalValueIsKnown(pLinker, *rsym))
41822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        return;
41922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
4205460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      // if symbol is defined in the ouput file and it's not
4215460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      // preemptible, no need plt
422affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      if (rsym->isDefine() && !rsym->isDyn() &&
42322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao         !isSymbolPreemptible(*rsym)) {
4245460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        return;
4255460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      }
4265460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
4275460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      // Symbol needs PLT entry, we need to reserve a PLT entry
4285460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      // and the corresponding GOT and dynamic relocation entry
4295460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      // in .got and .rel.plt. (GOT entry will be reserved simultaneously
4305460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      // when calling X86PLT->reserveEntry())
4315460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      m_pPLT->reserveEntry();
43222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      m_pGOTPLT->reserve();
4335460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      m_pRelPLT->reserveEntry(*m_pRelocFactory);
4345460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      // set PLT bit
4355460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      rsym->setReserved(rsym->reserved() | ReservePLT);
4365460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      return;
4375460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
4385460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_386_GOT32:
4395460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      // Symbol needs GOT entry, reserve entry in .got
4405460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      // return if we already create GOT for this symbol
441affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      if (rsym->reserved() & (ReserveGOT | GOTRel))
4425460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        return;
44322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      m_pGOT->reserve();
4445460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      // If building shared object or the symbol is undefined, a dynamic
4455460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      // relocation is needed to relocate this GOT entry. Reserve an
4465460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      // entry in .rel.dyn
44722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      if (LinkerConfig::DynObj ==
44822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                   config().codeGenType() || rsym->isUndef() || rsym->isDyn()) {
4495460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        m_pRelDyn->reserveEntry(*m_pRelocFactory);
4505460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        // set GOTRel bit
4515460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        rsym->setReserved(rsym->reserved() | GOTRel);
4525460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        return;
4535460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      }
4545460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      // set GOT bit
4555460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      rsym->setReserved(rsym->reserved() | ReserveGOT);
4565460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      return;
4575460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
4585460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_386_PC32:
45922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    case llvm::ELF::R_386_PC16:
46022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    case llvm::ELF::R_386_PC8:
4615460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
46222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      if (symbolNeedsPLT(pLinker, *rsym) &&
46322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                               LinkerConfig::DynObj != config().codeGenType()) {
464affc150dc44fab1911775a49636d0ce85333b634Zonr Chang        // create plt for this symbol if it does not have one
465affc150dc44fab1911775a49636d0ce85333b634Zonr Chang        if (!(rsym->reserved() & ReservePLT)){
466affc150dc44fab1911775a49636d0ce85333b634Zonr Chang          // Symbol needs PLT entry, we need to reserve a PLT entry
467affc150dc44fab1911775a49636d0ce85333b634Zonr Chang          // and the corresponding GOT and dynamic relocation entry
468affc150dc44fab1911775a49636d0ce85333b634Zonr Chang          // in .got and .rel.plt. (GOT entry will be reserved simultaneously
469affc150dc44fab1911775a49636d0ce85333b634Zonr Chang          // when calling X86PLT->reserveEntry())
470affc150dc44fab1911775a49636d0ce85333b634Zonr Chang          m_pPLT->reserveEntry();
47122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao          m_pGOTPLT->reserve();
472affc150dc44fab1911775a49636d0ce85333b634Zonr Chang          m_pRelPLT->reserveEntry(*m_pRelocFactory);
473affc150dc44fab1911775a49636d0ce85333b634Zonr Chang          // set PLT bit
474affc150dc44fab1911775a49636d0ce85333b634Zonr Chang          rsym->setReserved(rsym->reserved() | ReservePLT);
475affc150dc44fab1911775a49636d0ce85333b634Zonr Chang        }
476affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      }
477affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
47822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      if (symbolNeedsDynRel(pLinker, *rsym, (rsym->reserved() & ReservePLT),
47922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                                                                      false)) {
480affc150dc44fab1911775a49636d0ce85333b634Zonr Chang        // symbol needs dynamic relocation entry, reserve an entry in .rel.dyn
481affc150dc44fab1911775a49636d0ce85333b634Zonr Chang        m_pRelDyn->reserveEntry(*m_pRelocFactory);
48222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        if (symbolNeedsCopyReloc(pLinker, pReloc, *rsym)) {
483affc150dc44fab1911775a49636d0ce85333b634Zonr Chang          LDSymbol& cpy_sym = defineSymbolforCopyReloc(pLinker, *rsym);
484affc150dc44fab1911775a49636d0ce85333b634Zonr Chang          addCopyReloc(*cpy_sym.resolveInfo());
485affc150dc44fab1911775a49636d0ce85333b634Zonr Chang        }
486affc150dc44fab1911775a49636d0ce85333b634Zonr Chang        else {
487affc150dc44fab1911775a49636d0ce85333b634Zonr Chang          // set Rel bit
488affc150dc44fab1911775a49636d0ce85333b634Zonr Chang          rsym->setReserved(rsym->reserved() | ReserveRel);
489affc150dc44fab1911775a49636d0ce85333b634Zonr Chang        }
490affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      }
491affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      return;
49222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
49322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    case llvm::ELF::R_386_TLS_GD: {
49422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      // FIXME: no linker optimization for TLS relocation
49522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      if (rsym->reserved() & GOTRel)
49622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        return;
49722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      // reserve two pairs of got entry and dynamic relocation
49822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      m_pGOT->reserve(2);
49922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      m_pRelDyn->reserveEntry(*m_pRelocFactory, 2);
50022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      // set GOTRel bit
50122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      rsym->setReserved(rsym->reserved() | GOTRel);
50222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      return;
50322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    }
50422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
50522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    case llvm::ELF::R_386_TLS_LDM:
50622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      getTLSModuleID();
50722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      return;
50822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
50922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    case llvm::ELF::R_386_TLS_LDO_32:
51022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      return;
51122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
51222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    case llvm::ELF::R_386_TLS_IE:
51322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      setHasStaticTLS();
51422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      // if buildint shared object, a RELATIVE dynamic relocation is needed
51522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      if (LinkerConfig::DynObj == config().codeGenType()) {
51622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        m_pRelDyn->reserveEntry(*m_pRelocFactory);
51722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        rsym->setReserved(rsym->reserved() | ReserveRel);
51822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      }
51922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      if (rsym->reserved() & GOTRel)
52022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        return;
52122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      // reserve got and dyn relocation entries for tp-relative offset
52222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      m_pGOT->reserve();
52322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      m_pRelDyn->reserveEntry(*m_pRelocFactory);
52422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      // set GOTRel bit
52522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      rsym->setReserved(rsym->reserved() | GOTRel);
52622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      return;
52722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
52822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    case llvm::ELF::R_386_TLS_GOTIE:
52922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      setHasStaticTLS();
53022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      if (rsym->reserved() & GOTRel)
53122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        return;
53222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      // reserve got and dyn relocation entries for tp-relative offset
53322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      m_pGOT->reserve();
53422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      m_pRelDyn->reserveEntry(*m_pRelocFactory);
53522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      // set GOTRel bit
53622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      rsym->setReserved(rsym->reserved() | GOTRel);
53722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      return;
53822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
53922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    case llvm::ELF::R_386_TLS_LE:
54022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    case llvm::ELF::R_386_TLS_LE_32:
54122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      setHasStaticTLS();
54222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      // if buildint shared object, a dynamic relocation is needed
54322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      if (LinkerConfig::DynObj == config().codeGenType()) {
54422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        m_pRelDyn->reserveEntry(*m_pRelocFactory);
54522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        rsym->setReserved(rsym->reserved() | ReserveRel);
54622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      }
54722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      return;
54822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
5495460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    default: {
550affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      fatal(diag::unsupported_relocation) << (int)pReloc.type()
551affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                          << "mclinker@googlegroups.com";
5525460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      break;
5535460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    }
5545460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  } // end switch
5555460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
5565460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
5575460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaovoid X86GNULDBackend::scanRelocation(Relocation& pReloc,
55822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                                     FragmentLinker& pLinker,
55922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                                     Module& pModule,
560affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                     const LDSection& pSection)
5615460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
56222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  if (LinkerConfig::Object == config().codeGenType())
56322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    return;
5645460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // rsym - The relocation target symbol
5655460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  ResolveInfo* rsym = pReloc.symInfo();
56622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  assert(NULL != rsym &&
56722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao         "ResolveInfo of relocation not set while scanRelocation");
5685460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
56922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  pReloc.updateAddend();
57022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  if (0 == (pSection.flag() & llvm::ELF::SHF_ALLOC))
571affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    return;
572affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
57322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  // Scan relocation type to determine if the GOT/PLT/Dynamic Relocation
5745460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // entries should be created.
57522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  if (rsym->isLocal()) // rsym is local
57622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    scanLocalReloc(pReloc, pLinker, pModule, pSection);
57722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  else // rsym is external
57822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    scanGlobalReloc(pReloc, pLinker, pModule, pSection);
57922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
58022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  // check if we shoule issue undefined reference for the relocation target
58122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  // symbol
58222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  if (rsym->isUndef() && !rsym->isDyn() && !rsym->isWeak())
58322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    fatal(diag::undefined_reference) << rsym->name();
58422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
58522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  if ((rsym->reserved() & ReserveRel) != 0x0) {
58622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    // set hasTextRelSection if needed
58722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    checkAndSetHasTextRel(pSection);
5885460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
5895460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
5905460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
59122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaouint64_t X86GNULDBackend::emitSectionData(const LDSection& pSection,
5925460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                          MemoryRegion& pRegion) const
5935460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
5945460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  assert(pRegion.size() && "Size of MemoryRegion is zero!");
5955460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
59622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  const ELFFileFormat* FileFormat = getOutputFormat();
5975460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  assert(FileFormat &&
5985460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao         "ELFFileFormat is NULL in X86GNULDBackend::emitSectionData!");
5995460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
6005460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  unsigned int EntrySize = 0;
6015460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  uint64_t RegionSize = 0;
6025460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
6035460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  if (&pSection == &(FileFormat->getPLT())) {
6045460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    assert(m_pPLT && "emitSectionData failed, m_pPLT is NULL!");
6055460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
6065460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    unsigned char* buffer = pRegion.getBuffer();
6075460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
6085460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    m_pPLT->applyPLT0();
6095460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    m_pPLT->applyPLT1();
6105460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    X86PLT::iterator it = m_pPLT->begin();
6115460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    unsigned int plt0_size = llvm::cast<X86PLT0>((*it)).getEntrySize();
6125460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
6135460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    memcpy(buffer, llvm::cast<X86PLT0>((*it)).getContent(), plt0_size);
6145460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    RegionSize += plt0_size;
6155460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    ++it;
6165460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
6175460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    X86PLT1* plt1 = 0;
6185460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    X86PLT::iterator ie = m_pPLT->end();
6195460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    while (it != ie) {
6205460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      plt1 = &(llvm::cast<X86PLT1>(*it));
6215460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      EntrySize = plt1->getEntrySize();
6225460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      memcpy(buffer + RegionSize, plt1->getContent(), EntrySize);
6235460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      RegionSize += EntrySize;
6245460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      ++it;
6255460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    }
6265460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
6275460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
6285460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  else if (&pSection == &(FileFormat->getGOT())) {
6295460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    assert(m_pGOT && "emitSectionData failed, m_pGOT is NULL!");
6305460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
6315460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    uint32_t* buffer = reinterpret_cast<uint32_t*>(pRegion.getBuffer());
6325460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
63322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    GOT::Entry* got = 0;
6345460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    EntrySize = m_pGOT->getEntrySize();
6355460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
6365460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    for (X86GOT::iterator it = m_pGOT->begin(),
6375460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao         ie = m_pGOT->end(); it != ie; ++it, ++buffer) {
63822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      got = &(llvm::cast<GOT::Entry>((*it)));
6395460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      *buffer = static_cast<uint32_t>(got->getContent());
6405460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      RegionSize += EntrySize;
6415460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    }
6425460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
6435460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
644affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  else if (&pSection == &(FileFormat->getGOTPLT())) {
645affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    assert(m_pGOTPLT && "emitSectionData failed, m_pGOTPLT is NULL!");
646affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    m_pGOTPLT->applyGOT0(FileFormat->getDynamic().addr());
64722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    m_pGOTPLT->applyAllGOTPLT(*m_pPLT);
648affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
649affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    uint32_t* buffer = reinterpret_cast<uint32_t*>(pRegion.getBuffer());
650affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
65122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    GOT::Entry* got = 0;
652affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    EntrySize = m_pGOTPLT->getEntrySize();
6535460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
654affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    for (X86GOTPLT::iterator it = m_pGOTPLT->begin(),
655affc150dc44fab1911775a49636d0ce85333b634Zonr Chang         ie = m_pGOTPLT->end(); it != ie; ++it, ++buffer) {
65622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      got = &(llvm::cast<GOT::Entry>((*it)));
657affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      *buffer = static_cast<uint32_t>(got->getContent());
658affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      RegionSize += EntrySize;
659affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    }
660affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  }
661affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
662affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  else {
663affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    fatal(diag::unrecognized_output_sectoin)
664affc150dc44fab1911775a49636d0ce85333b634Zonr Chang            << pSection.name()
665affc150dc44fab1911775a49636d0ce85333b634Zonr Chang            << "mclinker@googlegroups.com";
666affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  }
6675460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  return RegionSize;
6685460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
66922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
6705460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaouint32_t X86GNULDBackend::machine() const
6715460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
6725460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  return llvm::ELF::EM_386;
6735460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
6745460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
6755460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei LiaoX86GOT& X86GNULDBackend::getGOT()
6765460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
6775460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  assert(NULL != m_pGOT);
6785460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  return *m_pGOT;
6795460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
6805460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
6815460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaoconst X86GOT& X86GNULDBackend::getGOT() const
6825460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
6835460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  assert(NULL != m_pGOT);
6845460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  return *m_pGOT;
6855460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
6865460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
687affc150dc44fab1911775a49636d0ce85333b634Zonr ChangX86GOTPLT& X86GNULDBackend::getGOTPLT()
688affc150dc44fab1911775a49636d0ce85333b634Zonr Chang{
689affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  assert(NULL != m_pGOTPLT);
690affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  return *m_pGOTPLT;
691affc150dc44fab1911775a49636d0ce85333b634Zonr Chang}
692affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
693affc150dc44fab1911775a49636d0ce85333b634Zonr Changconst X86GOTPLT& X86GNULDBackend::getGOTPLT() const
694affc150dc44fab1911775a49636d0ce85333b634Zonr Chang{
695affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  assert(NULL != m_pGOTPLT);
696affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  return *m_pGOTPLT;
697affc150dc44fab1911775a49636d0ce85333b634Zonr Chang}
698affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
6995460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei LiaoX86PLT& X86GNULDBackend::getPLT()
7005460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
7015460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  assert(NULL != m_pPLT && "PLT section not exist");
7025460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  return *m_pPLT;
7035460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
7045460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
7055460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaoconst X86PLT& X86GNULDBackend::getPLT() const
7065460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
7075460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  assert(NULL != m_pPLT && "PLT section not exist");
7085460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  return *m_pPLT;
7095460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
7105460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
7115460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei LiaoOutputRelocSection& X86GNULDBackend::getRelDyn()
7125460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
7135460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  assert(NULL != m_pRelDyn && ".rel.dyn section not exist");
7145460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  return *m_pRelDyn;
7155460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
7165460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
7175460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaoconst OutputRelocSection& X86GNULDBackend::getRelDyn() const
7185460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
7195460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  assert(NULL != m_pRelDyn && ".rel.dyn section not exist");
7205460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  return *m_pRelDyn;
7215460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
7225460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
72322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao// Create a GOT entry for the TLS module index
72422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei LiaoGOT::Entry& X86GNULDBackend::getTLSModuleID()
72522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao{
72622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  static GOT::Entry* got_entry = NULL;
72722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  if (NULL != got_entry)
72822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    return *got_entry;
72922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
73022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  // Allocate 2 got entries and 1 dynamic reloc for R_386_TLS_LDM
73122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  m_pGOT->reserve(2);
73222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  got_entry = m_pGOT->consume();
73322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  m_pGOT->consume()->setContent(0x0);
73422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
73522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  m_pRelDyn->reserveEntry(*m_pRelocFactory);
73622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  Relocation* rel_entry = m_pRelDyn->consumeEntry();
73722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  rel_entry->setType(llvm::ELF::R_386_TLS_DTPMOD32);
73822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  rel_entry->targetRef().assign(*got_entry, 0x0);
73922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  rel_entry->setSymInfo(NULL);
74022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
74122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  return *got_entry;
74222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao}
74322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
7445460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei LiaoOutputRelocSection& X86GNULDBackend::getRelPLT()
7455460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
7465460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  assert(NULL != m_pRelPLT && ".rel.plt section not exist");
7475460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  return *m_pRelPLT;
7485460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
7495460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
7505460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaoconst OutputRelocSection& X86GNULDBackend::getRelPLT() const
7515460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
7525460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  assert(NULL != m_pRelPLT && ".rel.plt section not exist");
7535460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  return *m_pRelPLT;
7545460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
7555460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
7565460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaounsigned int
75722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei LiaoX86GNULDBackend::getTargetSectionOrder(const LDSection& pSectHdr) const
7585460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
75922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  const ELFFileFormat* file_format = getOutputFormat();
7605460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
761affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  if (&pSectHdr == &file_format->getGOT()) {
76222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    if (config().options().hasNow())
763affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      return SHO_RELRO;
7645460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    return SHO_RELRO_LAST;
765affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  }
7665460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
767affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  if (&pSectHdr == &file_format->getGOTPLT()) {
76822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    if (config().options().hasNow())
769affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      return SHO_RELRO;
7705460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    return SHO_NON_RELRO_FIRST;
771affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  }
7725460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
7735460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  if (&pSectHdr == &file_format->getPLT())
7745460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    return SHO_PLT;
7755460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
7765460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  return SHO_UNDEFINED;
7775460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
7785460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
7795460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaounsigned int X86GNULDBackend::bitclass() const
7805460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
7815460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  return 32;
7825460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
7835460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
78422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaovoid X86GNULDBackend::initTargetSections(Module& pModule, ObjectBuilder& pBuilder)
78522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao{
78622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  if (LinkerConfig::Object != config().codeGenType()) {
78722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    ELFFileFormat* file_format = getOutputFormat();
78822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    // initialize .got
78922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    LDSection& got = file_format->getGOT();
79022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    m_pGOT = new X86GOT(got);
79122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
79222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    // initialize .got.plt
79322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    LDSection& gotplt = file_format->getGOTPLT();
79422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    m_pGOTPLT = new X86GOTPLT(gotplt);
79522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
79622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    // initialize .plt
79722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    LDSection& plt = file_format->getPLT();
79822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    m_pPLT = new X86PLT(plt,
79922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                        *m_pGOTPLT,
80022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                        config());
80122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
80222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    // initialize .rel.plt
80322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    LDSection& relplt = file_format->getRelPlt();
80422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    relplt.setLink(&plt);
80522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    m_pRelPLT = new OutputRelocSection(pModule,
80622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                                       relplt,
80722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                                       getRelEntrySize());
80822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    // initialize .rel.dyn
80922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    LDSection& reldyn = file_format->getRelDyn();
81022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    m_pRelDyn = new OutputRelocSection(pModule,
81122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                                       reldyn,
81222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                                       getRelEntrySize());
81322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  }
8145460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
8155460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
81622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaovoid X86GNULDBackend::initTargetSymbols(FragmentLinker& pLinker)
81722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao{
81822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  if (LinkerConfig::Object != config().codeGenType()) {
81922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    // Define the symbol _GLOBAL_OFFSET_TABLE_ if there is a symbol with the
82022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    // same name in input
82122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    m_pGOTSymbol =
82222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      pLinker.defineSymbol<FragmentLinker::AsRefered,
82322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                           FragmentLinker::Resolve>("_GLOBAL_OFFSET_TABLE_",
82422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                                                    false,
82522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                                                    ResolveInfo::Object,
82622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                                                    ResolveInfo::Define,
82722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                                                    ResolveInfo::Local,
82822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                                                    0x0,  // size
82922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                                                    0x0,  // value
83022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                                                    FragmentRef::Null(), // FragRef
83122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                                                    ResolveInfo::Hidden);
83222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  }
8335460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
8345460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
83522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// finalizeSymbol - finalize the symbol value
83622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaobool X86GNULDBackend::finalizeTargetSymbols(FragmentLinker& pLinker)
8375460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
83822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  return true;
8395460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
8405460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
84122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// doCreateProgramHdrs - backend can implement this function to create the
84222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// target-dependent segments
84322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaovoid X86GNULDBackend::doCreateProgramHdrs(Module& pModule,
84422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                                          const FragmentLinker& pLinker)
845affc150dc44fab1911775a49636d0ce85333b634Zonr Chang{
84622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  // TODO
8475460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
8485460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
8495460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaonamespace mcld {
8505460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
8515460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao//===----------------------------------------------------------------------===//
8525460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// createX86LDBackend - the help funtion to create corresponding X86LDBackend
8535460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao///
8545460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei LiaoTargetLDBackend* createX86LDBackend(const llvm::Target& pTarget,
85522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                                    const LinkerConfig& pConfig)
8565460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
85722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  if (pConfig.triple().isOSDarwin()) {
8585460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    assert(0 && "MachO linker is not supported yet");
8595460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    /**
8605460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    return new X86MachOLDBackend(createX86MachOArchiveReader,
8615460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                               createX86MachOObjectReader,
8625460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                               createX86MachOObjectWriter);
8635460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    **/
8645460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
86522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  if (pConfig.triple().isOSWindows()) {
8665460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    assert(0 && "COFF linker is not supported yet");
8675460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    /**
8685460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    return new X86COFFLDBackend(createX86COFFArchiveReader,
8695460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                               createX86COFFObjectReader,
8705460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                               createX86COFFObjectWriter);
8715460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    **/
8725460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
87322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  return new X86GNULDBackend(pConfig);
8745460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
8755460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
8765460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} // namespace of mcld
8775460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
87822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao//===----------------------------------------------------------------------===//
8795460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao// Force static initialization.
88022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao//===----------------------------------------------------------------------===//
88122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaoextern "C" void MCLDInitializeX86LDBackend() {
8825460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // Register the linker backend
8835460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  mcld::TargetRegistry::RegisterTargetLDBackend(TheX86Target, createX86LDBackend);
8845460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
885