X86LDBackend.cpp revision 6f75755c9204b1d8817ae5a65a2f7e5af0ec3f70
1//===- X86LDBackend.cpp ---------------------------------------------------===//
2//
3//                     The MCLinker Project
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9#include "X86.h"
10#include "X86ELFDynamic.h"
11#include "X86LDBackend.h"
12#include "X86Relocator.h"
13#include "X86GNUInfo.h"
14
15#include <llvm/ADT/Triple.h>
16#include <llvm/Support/Casting.h>
17
18#include <mcld/LinkerConfig.h>
19#include <mcld/IRBuilder.h>
20#include <mcld/Fragment/FillFragment.h>
21#include <mcld/Fragment/RegionFragment.h>
22#include <mcld/Fragment/FragmentLinker.h>
23#include <mcld/Support/MemoryRegion.h>
24#include <mcld/Support/MsgHandling.h>
25#include <mcld/Support/TargetRegistry.h>
26#include <mcld/Object/ObjectBuilder.h>
27
28#include <cstring>
29
30using namespace mcld;
31
32//===----------------------------------------------------------------------===//
33// X86GNULDBackend
34//===----------------------------------------------------------------------===//
35X86GNULDBackend::X86GNULDBackend(const LinkerConfig& pConfig,
36				 GNUInfo* pInfo,
37				 Relocation::Type pCopyRel)
38  : GNULDBackend(pConfig, pInfo),
39    m_pRelocator(NULL),
40    m_pPLT(NULL),
41    m_pRelDyn(NULL),
42    m_pRelPLT(NULL),
43    m_pDynamic(NULL),
44    m_pGOTSymbol(NULL),
45    m_CopyRel(pCopyRel)
46{
47  Triple::ArchType arch = pConfig.targets().triple().getArch();
48  assert (arch == Triple::x86 || arch == Triple::x86_64);
49  if (arch == Triple::x86 ||
50      pConfig.targets().triple().getEnvironment() == Triple::GNUX32) {
51    m_RelEntrySize = 8;
52    m_RelaEntrySize = 12;
53    if (arch == Triple::x86)
54      m_PointerRel = llvm::ELF::R_386_32;
55    else
56      m_PointerRel = llvm::ELF::R_X86_64_32;
57  }
58  else {
59    m_RelEntrySize = 16;
60    m_RelaEntrySize = 24;
61    m_PointerRel = llvm::ELF::R_X86_64_64;
62  }
63}
64
65X86GNULDBackend::~X86GNULDBackend()
66{
67  delete m_pRelocator;
68  delete m_pPLT;
69  delete m_pRelDyn;
70  delete m_pRelPLT;
71  delete m_pDynamic;
72}
73
74Relocator* X86GNULDBackend::getRelocator()
75{
76  assert(NULL != m_pRelocator);
77  return m_pRelocator;
78}
79
80void X86GNULDBackend::doPreLayout(IRBuilder& pBuilder)
81{
82  // initialize .dynamic data
83  if (!config().isCodeStatic() && NULL == m_pDynamic)
84    m_pDynamic = new X86ELFDynamic(*this, config());
85
86  // set .got.plt and .got sizes
87  // when building shared object, the .got section is must
88  if (LinkerConfig::Object != config().codeGenType()) {
89    setGOTSectionSize(pBuilder);
90
91    // set .plt size
92    if (m_pPLT->hasPLT1())
93      m_pPLT->finalizeSectionSize();
94
95    // set .rel.dyn/.rela.dyn size
96    if (!m_pRelDyn->empty()) {
97      assert(!config().isCodeStatic() &&
98            "static linkage should not result in a dynamic relocation section");
99      setRelDynSize();
100    }
101    // set .rel.plt/.rela.plt size
102    if (!m_pRelPLT->empty()) {
103      assert(!config().isCodeStatic() &&
104            "static linkage should not result in a dynamic relocation section");
105      setRelPLTSize();
106    }
107  }
108}
109
110void X86GNULDBackend::doPostLayout(Module& pModule,
111                                   IRBuilder& pBuilder)
112{
113}
114
115/// dynamic - the dynamic section of the target machine.
116/// Use co-variant return type to return its own dynamic section.
117X86ELFDynamic& X86GNULDBackend::dynamic()
118{
119  assert(NULL != m_pDynamic);
120  return *m_pDynamic;
121}
122
123/// dynamic - the dynamic section of the target machine.
124/// Use co-variant return type to return its own dynamic section.
125const X86ELFDynamic& X86GNULDBackend::dynamic() const
126{
127  assert(NULL != m_pDynamic);
128  return *m_pDynamic;
129}
130
131void X86GNULDBackend::defineGOTSymbol(IRBuilder& pBuilder,
132				      Fragment& pFrag)
133{
134  // define symbol _GLOBAL_OFFSET_TABLE_
135  if (m_pGOTSymbol != NULL) {
136    pBuilder.AddSymbol<IRBuilder::Force, IRBuilder::Unresolve>(
137                     "_GLOBAL_OFFSET_TABLE_",
138                     ResolveInfo::Object,
139                     ResolveInfo::Define,
140                     ResolveInfo::Local,
141                     0x0, // size
142                     0x0, // value
143                     FragmentRef::Create(pFrag, 0x0),
144                     ResolveInfo::Hidden);
145  }
146  else {
147    m_pGOTSymbol = pBuilder.AddSymbol<IRBuilder::Force, IRBuilder::Resolve>(
148                     "_GLOBAL_OFFSET_TABLE_",
149                     ResolveInfo::Object,
150                     ResolveInfo::Define,
151                     ResolveInfo::Local,
152                     0x0, // size
153                     0x0, // value
154                     FragmentRef::Create(pFrag, 0x0),
155                     ResolveInfo::Hidden);
156  }
157}
158
159void X86GNULDBackend::addCopyReloc(ResolveInfo& pSym)
160{
161  Relocation& rel_entry = *m_pRelDyn->consumeEntry();
162  rel_entry.setType(m_CopyRel);
163  assert(pSym.outSymbol()->hasFragRef());
164  rel_entry.targetRef().assign(*pSym.outSymbol()->fragRef());
165  rel_entry.setSymInfo(&pSym);
166}
167
168/// defineSymbolforCopyReloc
169/// For a symbol needing copy relocation, define a copy symbol in the BSS
170/// section and all other reference to this symbol should refer to this
171/// copy.
172/// @note This is executed at `scan relocation' stage.
173LDSymbol& X86GNULDBackend::defineSymbolforCopyReloc(IRBuilder& pBuilder,
174                                                    const ResolveInfo& pSym)
175{
176  // get or create corresponding BSS LDSection
177  LDSection* bss_sect_hdr = NULL;
178  ELFFileFormat* file_format = getOutputFormat();
179  if (ResolveInfo::ThreadLocal == pSym.type())
180    bss_sect_hdr = &file_format->getTBSS();
181  else
182    bss_sect_hdr = &file_format->getBSS();
183
184  // get or create corresponding BSS SectionData
185  assert(NULL != bss_sect_hdr);
186  SectionData* bss_section = NULL;
187  if (bss_sect_hdr->hasSectionData())
188    bss_section = bss_sect_hdr->getSectionData();
189  else
190    bss_section = IRBuilder::CreateSectionData(*bss_sect_hdr);
191
192  // Determine the alignment by the symbol value
193  // FIXME: here we use the largest alignment
194  uint32_t addralign = config().targets().bitclass() / 8;
195
196  // allocate space in BSS for the copy symbol
197  Fragment* frag = new FillFragment(0x0, 1, pSym.size());
198  uint64_t size = ObjectBuilder::AppendFragment(*frag,
199                                                *bss_section,
200                                                addralign);
201  bss_sect_hdr->setSize(bss_sect_hdr->size() + size);
202
203  // change symbol binding to Global if it's a weak symbol
204  ResolveInfo::Binding binding = (ResolveInfo::Binding)pSym.binding();
205  if (binding == ResolveInfo::Weak)
206    binding = ResolveInfo::Global;
207
208  // Define the copy symbol in the bss section and resolve it
209  LDSymbol* cpy_sym = pBuilder.AddSymbol<IRBuilder::Force, IRBuilder::Resolve>(
210                      pSym.name(),
211                      (ResolveInfo::Type)pSym.type(),
212                      ResolveInfo::Define,
213                      binding,
214                      pSym.size(),  // size
215                      0x0,          // value
216                      FragmentRef::Create(*frag, 0x0),
217                      (ResolveInfo::Visibility)pSym.other());
218
219  return *cpy_sym;
220}
221
222void X86GNULDBackend::scanRelocation(Relocation& pReloc,
223                                     IRBuilder& pLinker,
224                                     Module& pModule,
225                                     LDSection& pSection)
226{
227  if (LinkerConfig::Object == config().codeGenType())
228    return;
229  // rsym - The relocation target symbol
230  ResolveInfo* rsym = pReloc.symInfo();
231  assert(NULL != rsym &&
232         "ResolveInfo of relocation not set while scanRelocation");
233
234  pReloc.updateAddend();
235  assert(NULL != pSection.getLink());
236  if (0 == (pSection.getLink()->flag() & llvm::ELF::SHF_ALLOC))
237    return;
238
239  // Scan relocation type to determine if the GOT/PLT/Dynamic Relocation
240  // entries should be created.
241  if (rsym->isLocal()) // rsym is local
242    scanLocalReloc(pReloc, pLinker, pModule, pSection);
243  else // rsym is external
244    scanGlobalReloc(pReloc, pLinker, pModule, pSection);
245
246  // check if we should issue undefined reference for the relocation target
247  // symbol
248  if (rsym->isUndef() && !rsym->isDyn() && !rsym->isWeak() && !rsym->isNull())
249    fatal(diag::undefined_reference) << rsym->name();
250}
251
252uint64_t X86GNULDBackend::emitSectionData(const LDSection& pSection,
253                                          MemoryRegion& pRegion) const
254{
255  assert(pRegion.size() && "Size of MemoryRegion is zero!");
256
257  const ELFFileFormat* FileFormat = getOutputFormat();
258  assert(FileFormat &&
259         "ELFFileFormat is NULL in X86GNULDBackend::emitSectionData!");
260
261  unsigned int EntrySize = 0;
262  uint64_t RegionSize = 0;
263
264  if (&pSection == &(FileFormat->getPLT())) {
265    assert(m_pPLT && "emitSectionData failed, m_pPLT is NULL!");
266
267    unsigned char* buffer = pRegion.getBuffer();
268
269    m_pPLT->applyPLT0();
270    m_pPLT->applyPLT1();
271    X86PLT::iterator it = m_pPLT->begin();
272    unsigned int plt0_size = llvm::cast<PLTEntryBase>((*it)).size();
273
274    memcpy(buffer, llvm::cast<PLTEntryBase>((*it)).getValue(), plt0_size);
275    RegionSize += plt0_size;
276    ++it;
277
278    PLTEntryBase* plt1 = 0;
279    X86PLT::iterator ie = m_pPLT->end();
280    while (it != ie) {
281      plt1 = &(llvm::cast<PLTEntryBase>(*it));
282      EntrySize = plt1->size();
283      memcpy(buffer + RegionSize, plt1->getValue(), EntrySize);
284      RegionSize += EntrySize;
285      ++it;
286    }
287  }
288
289  else if (&pSection == &(FileFormat->getGOT())) {
290    RegionSize += emitGOTSectionData(pRegion);
291  }
292
293  else if (&pSection == &(FileFormat->getGOTPLT())) {
294    RegionSize += emitGOTPLTSectionData(pRegion, FileFormat);
295  }
296
297  else {
298    fatal(diag::unrecognized_output_sectoin)
299            << pSection.name()
300            << "mclinker@googlegroups.com";
301  }
302  return RegionSize;
303}
304
305X86PLT& X86GNULDBackend::getPLT()
306{
307  assert(NULL != m_pPLT && "PLT section not exist");
308  return *m_pPLT;
309}
310
311const X86PLT& X86GNULDBackend::getPLT() const
312{
313  assert(NULL != m_pPLT && "PLT section not exist");
314  return *m_pPLT;
315}
316
317OutputRelocSection& X86GNULDBackend::getRelDyn()
318{
319  assert(NULL != m_pRelDyn && ".rel.dyn/.rela.dyn section not exist");
320  return *m_pRelDyn;
321}
322
323const OutputRelocSection& X86GNULDBackend::getRelDyn() const
324{
325  assert(NULL != m_pRelDyn && ".rel.dyn/.rela.dyn section not exist");
326  return *m_pRelDyn;
327}
328
329OutputRelocSection& X86GNULDBackend::getRelPLT()
330{
331  assert(NULL != m_pRelPLT && ".rel.plt/.rela.plt section not exist");
332  return *m_pRelPLT;
333}
334
335const OutputRelocSection& X86GNULDBackend::getRelPLT() const
336{
337  assert(NULL != m_pRelPLT && ".rel.plt/.rela.plt section not exist");
338  return *m_pRelPLT;
339}
340
341unsigned int
342X86GNULDBackend::getTargetSectionOrder(const LDSection& pSectHdr) const
343{
344  const ELFFileFormat* file_format = getOutputFormat();
345
346  if (&pSectHdr == &file_format->getGOT()) {
347    if (config().options().hasNow())
348      return SHO_RELRO;
349    return SHO_RELRO_LAST;
350  }
351
352  if (&pSectHdr == &file_format->getGOTPLT()) {
353    if (config().options().hasNow())
354      return SHO_RELRO;
355    return SHO_NON_RELRO_FIRST;
356  }
357
358  if (&pSectHdr == &file_format->getPLT())
359    return SHO_PLT;
360
361  return SHO_UNDEFINED;
362}
363
364void X86GNULDBackend::initTargetSymbols(IRBuilder& pBuilder, Module& pModule)
365{
366  if (LinkerConfig::Object != config().codeGenType()) {
367    // Define the symbol _GLOBAL_OFFSET_TABLE_ if there is a symbol with the
368    // same name in input
369    m_pGOTSymbol =
370      pBuilder.AddSymbol<IRBuilder::AsReferred, IRBuilder::Resolve>(
371                                                "_GLOBAL_OFFSET_TABLE_",
372                                                ResolveInfo::Object,
373                                                ResolveInfo::Define,
374                                                ResolveInfo::Local,
375                                                0x0,  // size
376                                                0x0,  // value
377                                                FragmentRef::Null(), // FragRef
378                                                ResolveInfo::Hidden);
379  }
380}
381
382/// finalizeSymbol - finalize the symbol value
383bool X86GNULDBackend::finalizeTargetSymbols()
384{
385  return true;
386}
387
388/// doCreateProgramHdrs - backend can implement this function to create the
389/// target-dependent segments
390void X86GNULDBackend::doCreateProgramHdrs(Module& pModule)
391{
392  // TODO
393}
394
395X86_32GNULDBackend::X86_32GNULDBackend(const LinkerConfig& pConfig,
396				       GNUInfo* pInfo)
397  : X86GNULDBackend(pConfig, pInfo, llvm::ELF::R_386_COPY),
398    m_pGOT (NULL),
399    m_pGOTPLT (NULL) {
400}
401
402X86_32GNULDBackend::~X86_32GNULDBackend()
403{
404  delete m_pGOT;
405  delete m_pGOTPLT;
406}
407
408bool X86_32GNULDBackend::initRelocator()
409{
410  if (NULL == m_pRelocator) {
411    m_pRelocator = new X86_32Relocator(*this);
412  }
413  return true;
414}
415
416void X86_32GNULDBackend::scanLocalReloc(Relocation& pReloc,
417					IRBuilder& pBuilder,
418					Module& pModule,
419					LDSection& pSection)
420{
421  // rsym - The relocation target symbol
422  ResolveInfo* rsym = pReloc.symInfo();
423
424  switch(pReloc.type()){
425
426    case llvm::ELF::R_386_32:
427    case llvm::ELF::R_386_16:
428    case llvm::ELF::R_386_8:
429      // If buiding PIC object (shared library or PIC executable),
430      // a dynamic relocations with RELATIVE type to this location is needed.
431      // Reserve an entry in .rel.dyn
432      if (config().isCodeIndep()) {
433        m_pRelDyn->reserveEntry();
434        // set Rel bit
435        rsym->setReserved(rsym->reserved() | ReserveRel);
436        checkAndSetHasTextRel(*pSection.getLink());
437      }
438      return;
439
440    case llvm::ELF::R_386_GOTOFF:
441    case llvm::ELF::R_386_GOTPC:
442      // FIXME: A GOT section is needed
443      return;
444
445    case llvm::ELF::R_386_GOT32:
446      // Symbol needs GOT entry, reserve entry in .got
447      // return if we already create GOT for this symbol
448      if (rsym->reserved() & (ReserveGOT | GOTRel))
449        return;
450      // FIXME: check STT_GNU_IFUNC symbol
451      m_pGOT->reserve();
452
453      // If the GOT is used in statically linked binaries,
454      // the GOT entry is enough and no relocation is needed.
455      if (config().isCodeStatic()) {
456        rsym->setReserved(rsym->reserved() | ReserveGOT);
457        return;
458      }
459      // If building shared object or the symbol is undefined, a dynamic
460      // relocation is needed to relocate this GOT entry. Reserve an
461      // entry in .rel.dyn
462      if (LinkerConfig::DynObj ==
463                   config().codeGenType() || rsym->isUndef() || rsym->isDyn()) {
464        m_pRelDyn->reserveEntry();
465        // set GOTRel bit
466        rsym->setReserved(rsym->reserved() | GOTRel);
467        return;
468      }
469      // set GOT bit
470      rsym->setReserved(rsym->reserved() | ReserveGOT);
471      return;
472
473    case llvm::ELF::R_386_PC32:
474    case llvm::ELF::R_386_PC16:
475    case llvm::ELF::R_386_PC8:
476      return;
477
478    case llvm::ELF::R_386_TLS_GD: {
479      // FIXME: no linker optimization for TLS relocation
480      if (rsym->reserved() & GOTRel)
481        return;
482      m_pGOT->reserve(2);
483      // reserve an rel entry
484      m_pRelDyn->reserveEntry();
485      // set GOTRel bit
486      rsym->setReserved(rsym->reserved() | GOTRel);
487      // define the section symbol for .tdata or .tbss
488      // the target symbol of the created dynamic relocation should be the
489      // section symbol of the section which this symbol defined. so we
490      // need to define that section symbol here
491      ELFFileFormat* file_format = getOutputFormat();
492      const LDSection* sym_sect =
493               &rsym->outSymbol()->fragRef()->frag()->getParent()->getSection();
494      if (&file_format->getTData() == sym_sect) {
495        if (NULL == f_pTDATA)
496          f_pTDATA = pModule.getSectionSymbolSet().get(*sym_sect);
497      }
498      else if (&file_format->getTBSS() == sym_sect || rsym->isCommon()) {
499        if (NULL == f_pTBSS)
500          f_pTBSS = pModule.getSectionSymbolSet().get(*sym_sect);
501      }
502      else
503        error(diag::invalid_tls) << rsym->name() << sym_sect->name();
504      return;
505    }
506
507    case llvm::ELF::R_386_TLS_LDM:
508      getTLSModuleID();
509      return;
510
511    case llvm::ELF::R_386_TLS_LDO_32:
512      return;
513
514    case llvm::ELF::R_386_TLS_IE:
515      setHasStaticTLS();
516      // if buildint shared object, a RELATIVE dynamic relocation is needed
517      if (LinkerConfig::DynObj == config().codeGenType()) {
518        m_pRelDyn->reserveEntry();
519        rsym->setReserved(rsym->reserved() | ReserveRel);
520        checkAndSetHasTextRel(*pSection.getLink());
521      } else {
522        // for local sym, we can convert ie to le if not building shared object
523        convertTLSIEtoLE(pReloc, pSection);
524        return;
525      }
526      if (rsym->reserved() & GOTRel)
527        return;
528      // reserve got and dyn relocation entries for tp-relative offset
529      m_pGOT->reserve();
530      m_pRelDyn->reserveEntry();
531      // set GOTRel bit
532      rsym->setReserved(rsym->reserved() | GOTRel);
533      m_pRelDyn->addSymbolToDynSym(*rsym->outSymbol());
534      return;
535
536    case llvm::ELF::R_386_TLS_GOTIE:
537      setHasStaticTLS();
538      if (rsym->reserved() & GOTRel)
539        return;
540      // reserve got and dyn relocation entries for tp-relative offset
541      m_pGOT->reserve();
542      m_pRelDyn->reserveEntry();
543      // set GOTRel bit
544      rsym->setReserved(rsym->reserved() | GOTRel);
545      m_pRelDyn->addSymbolToDynSym(*rsym->outSymbol());
546      return;
547
548    case llvm::ELF::R_386_TLS_LE:
549    case llvm::ELF::R_386_TLS_LE_32:
550      setHasStaticTLS();
551      // if buildint shared object, a dynamic relocation is needed
552      if (LinkerConfig::DynObj == config().codeGenType()) {
553        m_pRelDyn->reserveEntry();
554        rsym->setReserved(rsym->reserved() | ReserveRel);
555        checkAndSetHasTextRel(*pSection.getLink());
556        // the target symbol of the dynamic relocation is rsym, so we need to
557        // emit it into .dynsym
558        assert(NULL != rsym->outSymbol());
559        m_pRelDyn->addSymbolToDynSym(*rsym->outSymbol());
560      }
561      return;
562
563    default:
564      fatal(diag::unsupported_relocation) << (int)pReloc.type()
565                                          << "mclinker@googlegroups.com";
566      break;
567  } // end switch
568}
569
570void X86_32GNULDBackend::scanGlobalReloc(Relocation& pReloc,
571					 IRBuilder& pBuilder,
572					 Module& pModule,
573					 LDSection& pSection)
574{
575  // rsym - The relocation target symbol
576  ResolveInfo* rsym = pReloc.symInfo();
577
578  switch(pReloc.type()) {
579    case llvm::ELF::R_386_32:
580    case llvm::ELF::R_386_16:
581    case llvm::ELF::R_386_8:
582      // Absolute relocation type, symbol may needs PLT entry or
583      // dynamic relocation entry
584      if (symbolNeedsPLT(*rsym)) {
585        // create plt for this symbol if it does not have one
586        if (!(rsym->reserved() & ReservePLT)){
587          // Symbol needs PLT entry, we need to reserve a PLT entry
588          // and the corresponding GOT and dynamic relocation entry
589          // in .got and .rel.plt. (GOT entry will be reserved simultaneously
590          // when calling X86PLT->reserveEntry())
591          m_pPLT->reserveEntry();
592          m_pGOTPLT->reserve();
593          m_pRelPLT->reserveEntry();
594          // set PLT bit
595          rsym->setReserved(rsym->reserved() | ReservePLT);
596        }
597      }
598
599      if (symbolNeedsDynRel(*rsym, (rsym->reserved() & ReservePLT), true)) {
600        // symbol needs dynamic relocation entry, reserve an entry in .rel.dyn
601        m_pRelDyn->reserveEntry();
602        if (symbolNeedsCopyReloc(pReloc, *rsym)) {
603          LDSymbol& cpy_sym = defineSymbolforCopyReloc(pBuilder, *rsym);
604          addCopyReloc(*cpy_sym.resolveInfo());
605        }
606        else {
607          // set Rel bit
608          rsym->setReserved(rsym->reserved() | ReserveRel);
609          checkAndSetHasTextRel(pSection);
610        }
611      }
612      return;
613
614    case llvm::ELF::R_386_GOTOFF:
615    case llvm::ELF::R_386_GOTPC: {
616      // FIXME: A GOT section is needed
617      return;
618    }
619
620    case llvm::ELF::R_386_PLT32:
621      // A PLT entry is needed when building shared library
622
623      // return if we already create plt for this symbol
624      if (rsym->reserved() & ReservePLT)
625        return;
626
627      // if the symbol's value can be decided at link time, then no need plt
628      if (symbolFinalValueIsKnown(*rsym))
629        return;
630
631      // if symbol is defined in the ouput file and it's not
632      // preemptible, no need plt
633      if (rsym->isDefine() && !rsym->isDyn() &&
634         !isSymbolPreemptible(*rsym)) {
635        return;
636      }
637
638      // Symbol needs PLT entry, we need to reserve a PLT entry
639      // and the corresponding GOT and dynamic relocation entry
640      // in .got and .rel.plt. (GOT entry will be reserved simultaneously
641      // when calling X86PLT->reserveEntry())
642      m_pPLT->reserveEntry();
643      m_pGOTPLT->reserve();
644      m_pRelPLT->reserveEntry();
645      // set PLT bit
646      rsym->setReserved(rsym->reserved() | ReservePLT);
647      return;
648
649    case llvm::ELF::R_386_GOT32:
650      // Symbol needs GOT entry, reserve entry in .got
651      // return if we already create GOT for this symbol
652      if (rsym->reserved() & (ReserveGOT | GOTRel))
653        return;
654      m_pGOT->reserve();
655
656      // If the GOT is used in statically linked binaries,
657      // the GOT entry is enough and no relocation is needed.
658      if (config().isCodeStatic()) {
659        rsym->setReserved(rsym->reserved() | ReserveGOT);
660        return;
661      }
662      // If building shared object or the symbol is undefined, a dynamic
663      // relocation is needed to relocate this GOT entry. Reserve an
664      // entry in .rel.dyn
665      if (LinkerConfig::DynObj ==
666                   config().codeGenType() || rsym->isUndef() || rsym->isDyn()) {
667        m_pRelDyn->reserveEntry();
668        // set GOTRel bit
669        rsym->setReserved(rsym->reserved() | GOTRel);
670        return;
671      }
672      // set GOT bit
673      rsym->setReserved(rsym->reserved() | ReserveGOT);
674      return;
675
676    case llvm::ELF::R_386_PC32:
677    case llvm::ELF::R_386_PC16:
678    case llvm::ELF::R_386_PC8:
679
680      if (symbolNeedsPLT(*rsym) &&
681          LinkerConfig::DynObj != config().codeGenType()) {
682        // create plt for this symbol if it does not have one
683        if (!(rsym->reserved() & ReservePLT)){
684          // Symbol needs PLT entry, we need to reserve a PLT entry
685          // and the corresponding GOT and dynamic relocation entry
686          // in .got and .rel.plt. (GOT entry will be reserved simultaneously
687          // when calling X86PLT->reserveEntry())
688          m_pPLT->reserveEntry();
689          m_pGOTPLT->reserve();
690          m_pRelPLT->reserveEntry();
691          // set PLT bit
692          rsym->setReserved(rsym->reserved() | ReservePLT);
693        }
694      }
695
696      if (symbolNeedsDynRel(*rsym, (rsym->reserved() & ReservePLT), false)) {
697        // symbol needs dynamic relocation entry, reserve an entry in .rel.dyn
698        m_pRelDyn->reserveEntry();
699        if (symbolNeedsCopyReloc(pReloc, *rsym)) {
700          LDSymbol& cpy_sym = defineSymbolforCopyReloc(pBuilder, *rsym);
701          addCopyReloc(*cpy_sym.resolveInfo());
702        }
703        else {
704          // set Rel bit
705          rsym->setReserved(rsym->reserved() | ReserveRel);
706          checkAndSetHasTextRel(pSection);
707        }
708      }
709      return;
710
711    case llvm::ELF::R_386_TLS_GD: {
712      // FIXME: no linker optimization for TLS relocation
713      if (rsym->reserved() & GOTRel)
714        return;
715      // reserve two pairs of got entry and dynamic relocation
716      m_pGOT->reserve(2);
717      m_pRelDyn->reserveEntry(2);
718      // set GOTRel bit
719      rsym->setReserved(rsym->reserved() | GOTRel);
720      return;
721    }
722
723    case llvm::ELF::R_386_TLS_LDM:
724      getTLSModuleID();
725      return;
726
727    case llvm::ELF::R_386_TLS_LDO_32:
728      return;
729
730    case llvm::ELF::R_386_TLS_IE:
731      setHasStaticTLS();
732      // if buildint shared object, a RELATIVE dynamic relocation is needed
733      if (LinkerConfig::DynObj == config().codeGenType()) {
734        m_pRelDyn->reserveEntry();
735        rsym->setReserved(rsym->reserved() | ReserveRel);
736        checkAndSetHasTextRel(*pSection.getLink());
737      } else {
738        // for global sym, we can convert ie to le if its final value is known
739        if (symbolFinalValueIsKnown(*rsym)) {
740          convertTLSIEtoLE(pReloc, pSection);
741          return;
742        }
743      }
744      if (rsym->reserved() & GOTRel)
745        return;
746      // reserve got and dyn relocation entries for tp-relative offset
747      m_pGOT->reserve();
748      m_pRelDyn->reserveEntry();
749      // set GOTRel bit
750      rsym->setReserved(rsym->reserved() | GOTRel);
751      return;
752
753    case llvm::ELF::R_386_TLS_GOTIE:
754      setHasStaticTLS();
755      if (rsym->reserved() & GOTRel)
756        return;
757      // reserve got and dyn relocation entries for tp-relative offset
758      m_pGOT->reserve();
759      m_pRelDyn->reserveEntry();
760      // set GOTRel bit
761      rsym->setReserved(rsym->reserved() | GOTRel);
762      return;
763
764    case llvm::ELF::R_386_TLS_LE:
765    case llvm::ELF::R_386_TLS_LE_32:
766      setHasStaticTLS();
767      // if buildint shared object, a dynamic relocation is needed
768      if (LinkerConfig::DynObj == config().codeGenType()) {
769        m_pRelDyn->reserveEntry();
770        rsym->setReserved(rsym->reserved() | ReserveRel);
771        checkAndSetHasTextRel(*pSection.getLink());
772      }
773      return;
774
775    default: {
776      fatal(diag::unsupported_relocation) << (int)pReloc.type()
777                                          << "mclinker@googlegroups.com";
778      break;
779    }
780  } // end switch
781}
782
783void X86_32GNULDBackend::initTargetSections(Module& pModule,
784					    ObjectBuilder& pBuilder)
785{
786  if (LinkerConfig::Object != config().codeGenType()) {
787    ELFFileFormat* file_format = getOutputFormat();
788    // initialize .got
789    LDSection& got = file_format->getGOT();
790    m_pGOT = new X86_32GOT(got);
791
792    // initialize .got.plt
793    LDSection& gotplt = file_format->getGOTPLT();
794    m_pGOTPLT = new X86_32GOTPLT(gotplt);
795
796    // initialize .plt
797    LDSection& plt = file_format->getPLT();
798    m_pPLT = new X86_32PLT(plt,
799			   *m_pGOTPLT,
800			   config());
801
802    // initialize .rel.plt
803    LDSection& relplt = file_format->getRelPlt();
804    relplt.setLink(&plt);
805    m_pRelPLT = new OutputRelocSection(pModule, relplt);
806
807    // initialize .rel.dyn
808    LDSection& reldyn = file_format->getRelDyn();
809    m_pRelDyn = new OutputRelocSection(pModule, reldyn);
810
811  }
812}
813
814X86_32GOT& X86_32GNULDBackend::getGOT()
815{
816  assert(NULL != m_pGOT);
817  return *m_pGOT;
818}
819
820const X86_32GOT& X86_32GNULDBackend::getGOT() const
821{
822  assert(NULL != m_pGOT);
823  return *m_pGOT;
824}
825
826X86_32GOTPLT& X86_32GNULDBackend::getGOTPLT()
827{
828  assert(NULL != m_pGOTPLT);
829  return *m_pGOTPLT;
830}
831
832const X86_32GOTPLT& X86_32GNULDBackend::getGOTPLT() const
833{
834  assert(NULL != m_pGOTPLT);
835  return *m_pGOTPLT;
836}
837
838void X86_32GNULDBackend::setRelDynSize()
839{
840  ELFFileFormat* file_format = getOutputFormat();
841  file_format->getRelDyn().setSize
842    (m_pRelDyn->numOfRelocs() * getRelEntrySize());
843}
844
845void X86_32GNULDBackend::setRelPLTSize()
846{
847  ELFFileFormat* file_format = getOutputFormat();
848  file_format->getRelPlt().setSize
849    (m_pRelPLT->numOfRelocs() * getRelEntrySize());
850}
851
852void X86_32GNULDBackend::setGOTSectionSize(IRBuilder& pBuilder)
853{
854  // set .got.plt size
855  if (LinkerConfig::DynObj == config().codeGenType() ||
856      m_pGOTPLT->hasGOT1() ||
857      NULL != m_pGOTSymbol) {
858    m_pGOTPLT->finalizeSectionSize();
859    defineGOTSymbol(pBuilder, *(m_pGOTPLT->begin()));
860  }
861
862  // set .got size
863  if (!m_pGOT->empty())
864    m_pGOT->finalizeSectionSize();
865}
866
867uint64_t X86_32GNULDBackend::emitGOTSectionData(MemoryRegion& pRegion) const
868{
869  assert(m_pGOT && "emitGOTSectionData failed, m_pGOT is NULL!");
870
871  uint32_t* buffer = reinterpret_cast<uint32_t*>(pRegion.getBuffer());
872
873  X86_32GOTEntry* got = 0;
874  unsigned int EntrySize = X86_32GOTEntry::EntrySize;
875  uint64_t RegionSize = 0;
876
877  for (X86_32GOT::iterator it = m_pGOT->begin(),
878       ie = m_pGOT->end(); it != ie; ++it, ++buffer) {
879    got = &(llvm::cast<X86_32GOTEntry>((*it)));
880    *buffer = static_cast<uint32_t>(got->getValue());
881    RegionSize += EntrySize;
882  }
883
884  return RegionSize;
885}
886
887uint64_t X86_32GNULDBackend::emitGOTPLTSectionData(MemoryRegion& pRegion,
888						   const ELFFileFormat* FileFormat) const
889{
890  assert(m_pGOTPLT && "emitGOTPLTSectionData failed, m_pGOTPLT is NULL!");
891  m_pGOTPLT->applyGOT0(FileFormat->getDynamic().addr());
892  m_pGOTPLT->applyAllGOTPLT(*m_pPLT);
893
894  uint32_t* buffer = reinterpret_cast<uint32_t*>(pRegion.getBuffer());
895
896  X86_32GOTEntry* got = 0;
897  unsigned int EntrySize = X86_32GOTEntry::EntrySize;
898  uint64_t RegionSize = 0;
899
900  for (X86_32GOTPLT::iterator it = m_pGOTPLT->begin(),
901       ie = m_pGOTPLT->end(); it != ie; ++it, ++buffer) {
902    got = &(llvm::cast<X86_32GOTEntry>((*it)));
903    *buffer = static_cast<uint32_t>(got->getValue());
904    RegionSize += EntrySize;
905  }
906
907  return RegionSize;
908}
909
910/// convert R_386_TLS_IE to R_386_TLS_LE
911void X86_32GNULDBackend::convertTLSIEtoLE(Relocation& pReloc,
912					  LDSection& pSection)
913{
914  assert(pReloc.type() == llvm::ELF::R_386_TLS_IE);
915  assert(NULL != pReloc.targetRef().frag());
916
917  // 1. create the fragment references and new relocs
918  uint64_t off = pReloc.targetRef().offset();
919  if (off >= 4)
920    off -= 4;
921  else
922    off = 0;
923
924  FragmentRef* fragref = FragmentRef::Create(*pReloc.targetRef().frag(), off);
925  // TODO: add symbols for R_386_TLS_OPT relocs
926  Relocation* reloc = Relocation::Create(X86_32Relocator::R_386_TLS_OPT,
927                                         *fragref,
928                                         0x0);
929
930  // 2. modify the opcodes to the appropriate ones
931  uint8_t* op =  (reinterpret_cast<uint8_t*>(&reloc->target()));
932  off = pReloc.targetRef().offset() - reloc->targetRef().offset() - 1;
933  if (op[off] == 0xa1) {
934    op[off] = 0xb8;
935  } else {
936    switch (op[off - 1]) {
937      case 0x8b:
938        assert((op[off] & 0xc7) == 0x05);
939        op[off - 1] = 0xc7;
940        op[off]     = 0xc0 | ((op[off] >> 3) & 7);
941        break;
942      case 0x03:
943        assert((op[off] & 0xc7) == 0x05);
944        op[off - 1] = 0x81;
945        op[off]     = 0xc0 | ((op[off] >> 3) & 7);
946        break;
947      default:
948        assert(0);
949        break;
950    }
951  }
952
953  // 3. insert the new relocs "BEFORE" the original reloc.
954  pSection.getRelocData()->getRelocationList().insert(
955    RelocData::iterator(pReloc), reloc);
956
957  // 4. change the type of the original reloc
958  pReloc.setType(llvm::ELF::R_386_TLS_LE);
959}
960
961// Create a GOT entry for the TLS module index
962X86_32GOTEntry& X86_32GNULDBackend::getTLSModuleID()
963{
964  static X86_32GOTEntry* got_entry = NULL;
965  if (NULL != got_entry)
966    return *got_entry;
967
968  // Allocate 2 got entries and 1 dynamic reloc for R_386_TLS_LDM
969  m_pGOT->reserve(2);
970  got_entry = m_pGOT->consume();
971  m_pGOT->consume()->setValue(0x0);
972
973  m_pRelDyn->reserveEntry();
974  Relocation* rel_entry = m_pRelDyn->consumeEntry();
975  rel_entry->setType(llvm::ELF::R_386_TLS_DTPMOD32);
976  rel_entry->targetRef().assign(*got_entry, 0x0);
977  rel_entry->setSymInfo(NULL);
978
979  return *got_entry;
980}
981
982X86_64GNULDBackend::X86_64GNULDBackend(const LinkerConfig& pConfig,
983				       GNUInfo* pInfo)
984  : X86GNULDBackend(pConfig, pInfo, llvm::ELF::R_X86_64_COPY),
985    m_pGOT (NULL),
986    m_pGOTPLT (NULL) {
987}
988
989X86_64GNULDBackend::~X86_64GNULDBackend()
990{
991  delete m_pGOT;
992  delete m_pGOTPLT;
993}
994
995bool X86_64GNULDBackend::initRelocator()
996{
997  if (NULL == m_pRelocator) {
998    m_pRelocator = new X86_64Relocator(*this);
999  }
1000  return true;
1001}
1002
1003X86_64GOT& X86_64GNULDBackend::getGOT()
1004{
1005  assert(NULL != m_pGOT);
1006  return *m_pGOT;
1007}
1008
1009const X86_64GOT& X86_64GNULDBackend::getGOT() const
1010{
1011  assert(NULL != m_pGOT);
1012  return *m_pGOT;
1013}
1014
1015X86_64GOTPLT& X86_64GNULDBackend::getGOTPLT()
1016{
1017  assert(NULL != m_pGOTPLT);
1018  return *m_pGOTPLT;
1019}
1020
1021const X86_64GOTPLT& X86_64GNULDBackend::getGOTPLT() const
1022{
1023  assert(NULL != m_pGOTPLT);
1024  return *m_pGOTPLT;
1025}
1026
1027void X86_64GNULDBackend::setRelDynSize()
1028{
1029  ELFFileFormat* file_format = getOutputFormat();
1030  file_format->getRelaDyn().setSize
1031    (m_pRelDyn->numOfRelocs() * getRelaEntrySize());
1032}
1033
1034void X86_64GNULDBackend::setRelPLTSize()
1035{
1036  ELFFileFormat* file_format = getOutputFormat();
1037  file_format->getRelaPlt().setSize
1038    (m_pRelPLT->numOfRelocs() * getRelaEntrySize());
1039}
1040
1041void X86_64GNULDBackend::scanLocalReloc(Relocation& pReloc,
1042					IRBuilder& pBuilder,
1043					Module& pModule,
1044					LDSection& pSection)
1045{
1046  // rsym - The relocation target symbol
1047  ResolveInfo* rsym = pReloc.symInfo();
1048
1049  switch(pReloc.type()){
1050    case llvm::ELF::R_X86_64_64:
1051    case llvm::ELF::R_X86_64_32:
1052    case llvm::ELF::R_X86_64_16:
1053    case llvm::ELF::R_X86_64_8:
1054    case llvm::ELF::R_X86_64_32S:
1055      // If buiding PIC object (shared library or PIC executable),
1056      // a dynamic relocations with RELATIVE type to this location is needed.
1057      // Reserve an entry in .rela.dyn
1058      if (config().isCodeIndep()) {
1059        m_pRelDyn->reserveEntry();
1060        // set Rel bit
1061        rsym->setReserved(rsym->reserved() | ReserveRel);
1062        checkAndSetHasTextRel(*pSection.getLink());
1063      }
1064      return;
1065
1066    case llvm::ELF::R_X86_64_PC32:
1067    case llvm::ELF::R_X86_64_PC16:
1068    case llvm::ELF::R_X86_64_PC8:
1069      return;
1070
1071    case llvm::ELF::R_X86_64_GOTPCREL:
1072      // Symbol needs GOT entry, reserve entry in .got
1073      // return if we already create GOT for this symbol
1074      if (rsym->reserved() & (ReserveGOT | GOTRel))
1075        return;
1076      m_pGOT->reserve();
1077
1078      // If the GOT is used in statically linked binaries,
1079      // the GOT entry is enough and no relocation is needed.
1080      if (config().isCodeStatic()) {
1081        rsym->setReserved(rsym->reserved() | ReserveGOT);
1082        return;
1083      }
1084      // If building shared object or the symbol is undefined, a dynamic
1085      // relocation is needed to relocate this GOT entry. Reserve an
1086      // entry in .rela.dyn
1087      if (LinkerConfig::DynObj ==
1088                   config().codeGenType() || rsym->isUndef() || rsym->isDyn()) {
1089        m_pRelDyn->reserveEntry();
1090        // set GOTRel bit
1091        rsym->setReserved(rsym->reserved() | GOTRel);
1092        return;
1093      }
1094      // set GOT bit
1095      rsym->setReserved(rsym->reserved() | ReserveGOT);
1096      return;
1097
1098    default:
1099      fatal(diag::unsupported_relocation) << (int)pReloc.type()
1100                                          << "mclinker@googlegroups.com";
1101      break;
1102  } // end switch
1103}
1104
1105void X86_64GNULDBackend::scanGlobalReloc(Relocation& pReloc,
1106					 IRBuilder& pBuilder,
1107					 Module& pModule,
1108					 LDSection& pSection)
1109{
1110  // rsym - The relocation target symbol
1111  ResolveInfo* rsym = pReloc.symInfo();
1112
1113  switch(pReloc.type()) {
1114    case llvm::ELF::R_X86_64_64:
1115    case llvm::ELF::R_X86_64_32:
1116    case llvm::ELF::R_X86_64_16:
1117    case llvm::ELF::R_X86_64_8:
1118    case llvm::ELF::R_X86_64_32S:
1119      // Absolute relocation type, symbol may needs PLT entry or
1120      // dynamic relocation entry
1121      if (symbolNeedsPLT(*rsym)) {
1122        // create plt for this symbol if it does not have one
1123        if (!(rsym->reserved() & ReservePLT)){
1124          // Symbol needs PLT entry, we need to reserve a PLT entry
1125          // and the corresponding GOT and dynamic relocation entry
1126          // in .got and .rela.plt. (GOT entry will be reserved simultaneously
1127          // when calling X86PLT->reserveEntry())
1128          m_pPLT->reserveEntry();
1129          m_pGOTPLT->reserve();
1130          m_pRelPLT->reserveEntry();
1131          // set PLT bit
1132          rsym->setReserved(rsym->reserved() | ReservePLT);
1133        }
1134      }
1135
1136      if (symbolNeedsDynRel(*rsym, (rsym->reserved() & ReservePLT), true)) {
1137        // symbol needs dynamic relocation entry, reserve an entry in .rela.dyn
1138        m_pRelDyn->reserveEntry();
1139        if (symbolNeedsCopyReloc(pReloc, *rsym)) {
1140          LDSymbol& cpy_sym = defineSymbolforCopyReloc(pBuilder, *rsym);
1141          addCopyReloc(*cpy_sym.resolveInfo());
1142        }
1143        else {
1144          // set Rel bit
1145          rsym->setReserved(rsym->reserved() | ReserveRel);
1146	  checkAndSetHasTextRel(*pSection.getLink());
1147        }
1148      }
1149      return;
1150
1151    case llvm::ELF::R_X86_64_GOTPCREL:
1152      // Symbol needs GOT entry, reserve entry in .got
1153      // return if we already create GOT for this symbol
1154      if (rsym->reserved() & (ReserveGOT | GOTRel))
1155        return;
1156      m_pGOT->reserve();
1157
1158      // If the GOT is used in statically linked binaries,
1159      // the GOT entry is enough and no relocation is needed.
1160      if (config().isCodeStatic()) {
1161        rsym->setReserved(rsym->reserved() | ReserveGOT);
1162        return;
1163      }
1164      // If building shared object or the symbol is undefined, a dynamic
1165      // relocation is needed to relocate this GOT entry. Reserve an
1166      // entry in .rela.dyn
1167      if (LinkerConfig::DynObj ==
1168                   config().codeGenType() || rsym->isUndef() || rsym->isDyn()) {
1169        m_pRelDyn->reserveEntry();
1170        // set GOTRel bit
1171        rsym->setReserved(rsym->reserved() | GOTRel);
1172        return;
1173      }
1174      // set GOT bit
1175      rsym->setReserved(rsym->reserved() | ReserveGOT);
1176      return;
1177
1178    case llvm::ELF::R_X86_64_PLT32:
1179      // A PLT entry is needed when building shared library
1180
1181      // return if we already create plt for this symbol
1182      if (rsym->reserved() & ReservePLT)
1183        return;
1184
1185      // if the symbol's value can be decided at link time, then no need plt
1186      if (symbolFinalValueIsKnown(*rsym))
1187        return;
1188
1189      // if symbol is defined in the ouput file and it's not
1190      // preemptible, no need plt
1191      if (rsym->isDefine() && !rsym->isDyn() &&
1192         !isSymbolPreemptible(*rsym)) {
1193        return;
1194      }
1195
1196      // Symbol needs PLT entry, we need to reserve a PLT entry
1197      // and the corresponding GOT and dynamic relocation entry
1198      // in .got and .rel.plt. (GOT entry will be reserved simultaneously
1199      // when calling X86PLT->reserveEntry())
1200      m_pPLT->reserveEntry();
1201      m_pGOTPLT->reserve();
1202      m_pRelPLT->reserveEntry();
1203      // set PLT bit
1204      rsym->setReserved(rsym->reserved() | ReservePLT);
1205      return;
1206
1207    case llvm::ELF::R_X86_64_PC32:
1208    case llvm::ELF::R_X86_64_PC16:
1209    case llvm::ELF::R_X86_64_PC8:
1210      if (symbolNeedsPLT(*rsym) &&
1211          LinkerConfig::DynObj != config().codeGenType()) {
1212        // create plt for this symbol if it does not have one
1213        if (!(rsym->reserved() & ReservePLT)){
1214          // Symbol needs PLT entry, we need to reserve a PLT entry
1215          // and the corresponding GOT and dynamic relocation entry
1216          // in .got and .rel.plt. (GOT entry will be reserved simultaneously
1217          // when calling X86PLT->reserveEntry())
1218          m_pPLT->reserveEntry();
1219          m_pGOTPLT->reserve();
1220          m_pRelPLT->reserveEntry();
1221          // set PLT bit
1222          rsym->setReserved(rsym->reserved() | ReservePLT);
1223        }
1224      }
1225
1226      // Only PC relative relocation against dynamic symbol needs a
1227      // dynamic relocation.  Only dynamic copy relocation is allowed
1228      // and PC relative relocation will be resolved to the local copy.
1229      // All other dynamic relocations may lead to run-time relocation
1230      // overflow.
1231      if (isDynamicSymbol(*rsym) &&
1232	  symbolNeedsDynRel(*rsym, (rsym->reserved() & ReservePLT), false) &&
1233	  symbolNeedsCopyReloc(pReloc, *rsym)) {
1234        m_pRelDyn->reserveEntry();
1235	LDSymbol& cpy_sym = defineSymbolforCopyReloc(pBuilder, *rsym);
1236	addCopyReloc(*cpy_sym.resolveInfo());
1237      }
1238      return;
1239
1240    default:
1241      fatal(diag::unsupported_relocation) << (int)pReloc.type()
1242                                          << "mclinker@googlegroups.com";
1243      break;
1244  } // end switch
1245}
1246
1247void X86_64GNULDBackend::initTargetSections(Module& pModule,
1248					    ObjectBuilder& pBuilder)
1249{
1250  if (LinkerConfig::Object != config().codeGenType()) {
1251    ELFFileFormat* file_format = getOutputFormat();
1252    // initialize .got
1253    LDSection& got = file_format->getGOT();
1254    m_pGOT = new X86_64GOT(got);
1255
1256    // initialize .got.plt
1257    LDSection& gotplt = file_format->getGOTPLT();
1258    m_pGOTPLT = new X86_64GOTPLT(gotplt);
1259
1260    // initialize .plt
1261    LDSection& plt = file_format->getPLT();
1262    m_pPLT = new X86_64PLT(plt,
1263			   *m_pGOTPLT,
1264			   config());
1265
1266    // initialize .rela.plt
1267    LDSection& relplt = file_format->getRelaPlt();
1268    relplt.setLink(&plt);
1269    m_pRelPLT = new OutputRelocSection(pModule, relplt);
1270
1271    // initialize .rela.dyn
1272    LDSection& reldyn = file_format->getRelaDyn();
1273    m_pRelDyn = new OutputRelocSection(pModule, reldyn);
1274
1275  }
1276}
1277
1278void X86_64GNULDBackend::setGOTSectionSize(IRBuilder& pBuilder)
1279{
1280  // set .got.plt size
1281  if (LinkerConfig::DynObj == config().codeGenType() ||
1282      m_pGOTPLT->hasGOT1() ||
1283      NULL != m_pGOTSymbol) {
1284    m_pGOTPLT->finalizeSectionSize();
1285    defineGOTSymbol(pBuilder, *(m_pGOTPLT->begin()));
1286  }
1287
1288  // set .got size
1289  if (!m_pGOT->empty())
1290    m_pGOT->finalizeSectionSize();
1291}
1292
1293uint64_t X86_64GNULDBackend::emitGOTSectionData(MemoryRegion& pRegion) const
1294{
1295  assert(m_pGOT && "emitGOTSectionData failed, m_pGOT is NULL!");
1296
1297  uint64_t* buffer = reinterpret_cast<uint64_t*>(pRegion.getBuffer());
1298
1299  X86_64GOTEntry* got = 0;
1300  unsigned int EntrySize = X86_64GOTEntry::EntrySize;
1301  uint64_t RegionSize = 0;
1302
1303  for (X86_64GOT::iterator it = m_pGOT->begin(),
1304       ie = m_pGOT->end(); it != ie; ++it, ++buffer) {
1305    got = &(llvm::cast<X86_64GOTEntry>((*it)));
1306    *buffer = static_cast<uint64_t>(got->getValue());
1307    RegionSize += EntrySize;
1308  }
1309
1310  return RegionSize;
1311}
1312
1313uint64_t X86_64GNULDBackend::emitGOTPLTSectionData(MemoryRegion& pRegion,
1314						   const ELFFileFormat* FileFormat) const
1315{
1316  assert(m_pGOTPLT && "emitGOTPLTSectionData failed, m_pGOTPLT is NULL!");
1317  m_pGOTPLT->applyGOT0(FileFormat->getDynamic().addr());
1318  m_pGOTPLT->applyAllGOTPLT(*m_pPLT);
1319
1320  uint64_t* buffer = reinterpret_cast<uint64_t*>(pRegion.getBuffer());
1321
1322  X86_64GOTEntry* got = 0;
1323  unsigned int EntrySize = X86_64GOTEntry::EntrySize;
1324  uint64_t RegionSize = 0;
1325
1326  for (X86_64GOTPLT::iterator it = m_pGOTPLT->begin(),
1327       ie = m_pGOTPLT->end(); it != ie; ++it, ++buffer) {
1328    got = &(llvm::cast<X86_64GOTEntry>((*it)));
1329    *buffer = static_cast<uint64_t>(got->getValue());
1330    RegionSize += EntrySize;
1331  }
1332
1333  return RegionSize;
1334}
1335
1336namespace mcld {
1337
1338//===----------------------------------------------------------------------===//
1339/// createX86LDBackend - the help funtion to create corresponding X86LDBackend
1340///
1341TargetLDBackend* createX86LDBackend(const llvm::Target& pTarget,
1342                                    const LinkerConfig& pConfig)
1343{
1344  if (pConfig.targets().triple().isOSDarwin()) {
1345    assert(0 && "MachO linker is not supported yet");
1346    /**
1347    return new X86MachOLDBackend(createX86MachOArchiveReader,
1348                               createX86MachOObjectReader,
1349                               createX86MachOObjectWriter);
1350    **/
1351  }
1352  if (pConfig.targets().triple().isOSWindows()) {
1353    assert(0 && "COFF linker is not supported yet");
1354    /**
1355    return new X86COFFLDBackend(createX86COFFArchiveReader,
1356                               createX86COFFObjectReader,
1357                               createX86COFFObjectWriter);
1358    **/
1359  }
1360  Triple::ArchType arch = pConfig.targets().triple().getArch();
1361  if (arch == Triple::x86)
1362    return new X86_32GNULDBackend(pConfig,
1363				  new X86_32GNUInfo(pConfig.targets().triple()));
1364  assert (arch == Triple::x86_64);
1365  return new X86_64GNULDBackend(pConfig,
1366				new X86_64GNUInfo(pConfig.targets().triple()));
1367}
1368
1369} // namespace of mcld
1370
1371//===----------------------------------------------------------------------===//
1372// Force static initialization.
1373//===----------------------------------------------------------------------===//
1374extern "C" void MCLDInitializeX86LDBackend() {
1375  // Register the linker backend
1376  mcld::TargetRegistry::RegisterTargetLDBackend(TheX86_32Target, createX86LDBackend);
1377  mcld::TargetRegistry::RegisterTargetLDBackend(TheX86_64Target, createX86LDBackend);
1378}
1379