1//===- X86Relocator.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 "X86Relocator.h"
10#include "X86RelocationFunctions.h"
11
12#include <mcld/LinkerConfig.h>
13#include <mcld/IRBuilder.h>
14#include <mcld/Support/MsgHandling.h>
15#include <mcld/LD/LDSymbol.h>
16#include <mcld/LD/ELFFileFormat.h>
17#include <mcld/LD/ELFSegmentFactory.h>
18#include <mcld/LD/ELFSegment.h>
19#include <mcld/Object/ObjectBuilder.h>
20
21#include <llvm/ADT/Twine.h>
22#include <llvm/Support/DataTypes.h>
23#include <llvm/Support/ELF.h>
24
25using namespace mcld;
26
27//===--------------------------------------------------------------------===//
28// X86_32 Relocation helper function
29//===--------------------------------------------------------------------===//
30/// helper_DynRel - Get an relocation entry in .rel.dyn
31static
32Relocation& helper_DynRel_init(ResolveInfo* pSym,
33                               Fragment& pFrag,
34                               uint64_t pOffset,
35                               Relocator::Type pType,
36                               X86_32Relocator& pParent)
37{
38  X86_32GNULDBackend& ld_backend = pParent.getTarget();
39  Relocation& rel_entry = *ld_backend.getRelDyn().create();
40  rel_entry.setType(pType);
41  rel_entry.targetRef().assign(pFrag, pOffset);
42  if (pType == llvm::ELF::R_386_RELATIVE || NULL == pSym)
43    rel_entry.setSymInfo(NULL);
44  else
45    rel_entry.setSymInfo(pSym);
46
47  return rel_entry;
48}
49
50/// helper_use_relative_reloc - Check if symbol ceuse relocation
51/// R_386_RELATIVE
52static bool
53helper_use_relative_reloc(const ResolveInfo& pSym,
54                          const X86_32Relocator& pFactory)
55
56{
57  // if symbol is dynamic or undefine or preemptible
58  if (pSym.isDyn() ||
59      pSym.isUndef() ||
60      pFactory.getTarget().isSymbolPreemptible(pSym))
61    return false;
62  return true;
63}
64
65static
66X86_32GOTEntry& helper_GOT_init(Relocation& pReloc,
67                                bool pHasRel,
68                                X86_32Relocator& pParent)
69{
70  // rsym - The relocation target symbol
71  ResolveInfo* rsym = pReloc.symInfo();
72  X86_32GNULDBackend& ld_backend = pParent.getTarget();
73  assert(NULL == pParent.getSymGOTMap().lookUp(*rsym));
74
75  X86_32GOTEntry* got_entry = ld_backend.getGOT().create();
76  pParent.getSymGOTMap().record(*rsym, *got_entry);
77
78  if (!pHasRel) {
79    // No corresponding dynamic relocation, initialize to the symbol value.
80    got_entry->setValue(X86Relocator::SymVal);
81  }
82  else {
83    // Initialize got_entry content and the corresponding dynamic relocation.
84    if (helper_use_relative_reloc(*rsym, pParent)) {
85      helper_DynRel_init(rsym, *got_entry, 0x0, llvm::ELF::R_386_RELATIVE,
86                                                                       pParent);
87      got_entry->setValue(X86Relocator::SymVal);
88    }
89    else {
90      helper_DynRel_init(rsym, *got_entry, 0x0, llvm::ELF::R_386_GLOB_DAT,
91                                                                       pParent);
92      got_entry->setValue(0x0);
93    }
94  }
95  return *got_entry;
96}
97
98static
99Relocator::Address helper_GOT_ORG(X86_32Relocator& pParent)
100{
101  return pParent.getTarget().getGOTPLT().addr();
102}
103
104static
105Relocator::Address helper_get_GOT_address(Relocation& pReloc,
106                                             X86_32Relocator& pParent)
107{
108  X86_32GOTEntry* got_entry = pParent.getSymGOTMap().lookUp(*pReloc.symInfo());
109  assert(NULL != got_entry);
110  return pParent.getTarget().getGOT().addr() + got_entry->getOffset();
111}
112
113static
114PLTEntryBase& helper_PLT_init(Relocation& pReloc, X86_32Relocator& pParent)
115{
116  // rsym - The relocation target symbol
117  ResolveInfo* rsym = pReloc.symInfo();
118  X86_32GNULDBackend& ld_backend = pParent.getTarget();
119  assert(NULL == pParent.getSymPLTMap().lookUp(*rsym));
120
121  PLTEntryBase* plt_entry = ld_backend.getPLT().create();
122  pParent.getSymPLTMap().record(*rsym, *plt_entry);
123
124  // initialize plt and the corresponding gotplt and dyn rel entry.
125  assert(NULL == pParent.getSymGOTPLTMap().lookUp(*rsym) &&
126         "PLT entry not exist, but GOTPLT entry exist!");
127  X86_32GOTEntry* gotplt_entry = ld_backend.getGOTPLT().create();
128  pParent.getSymGOTPLTMap().record(*rsym, *gotplt_entry);
129
130  // init the corresponding rel entry in .rel.plt
131  Relocation& rel_entry = *ld_backend.getRelPLT().create();
132  rel_entry.setType(llvm::ELF::R_386_JUMP_SLOT);
133  rel_entry.targetRef().assign(*gotplt_entry);
134  rel_entry.setSymInfo(rsym);
135  return *plt_entry;
136}
137
138static Relocator::Address
139helper_get_PLT_address(ResolveInfo& pSym, X86_32Relocator& pParent)
140{
141  PLTEntryBase* plt_entry = pParent.getSymPLTMap().lookUp(pSym);
142  assert(NULL != plt_entry);
143  return pParent.getTarget().getPLT().addr() + plt_entry->getOffset();
144}
145
146//===--------------------------------------------------------------------===//
147// X86_32 Relocation Functions and Tables
148//===--------------------------------------------------------------------===//
149DECL_X86_32_APPLY_RELOC_FUNCS
150
151/// the prototype of applying function
152typedef Relocator::Result (*X86_32ApplyFunctionType)(Relocation& pReloc,
153                                                     X86_32Relocator& pParent);
154
155// the table entry of applying functions
156struct X86_32ApplyFunctionTriple
157{
158  X86_32ApplyFunctionType func;
159  unsigned int type;
160  const char* name;
161  unsigned int size;
162};
163
164// declare the table of applying functions
165static const X86_32ApplyFunctionTriple X86_32ApplyFunctions[] = {
166  DECL_X86_32_APPLY_RELOC_FUNC_PTRS
167};
168
169//===--------------------------------------------------------------------===//
170// X86Relocator
171//===--------------------------------------------------------------------===//
172X86Relocator::X86Relocator(const LinkerConfig& pConfig)
173  : Relocator(pConfig) {
174}
175
176X86Relocator::~X86Relocator()
177{
178}
179
180void X86Relocator::scanRelocation(Relocation& pReloc,
181                                  IRBuilder& pLinker,
182                                  Module& pModule,
183                                  LDSection& pSection,
184                                  Input& pInput)
185{
186  if (LinkerConfig::Object == config().codeGenType())
187    return;
188  // rsym - The relocation target symbol
189  ResolveInfo* rsym = pReloc.symInfo();
190  assert(NULL != rsym &&
191         "ResolveInfo of relocation not set while scanRelocation");
192
193  assert(NULL != pSection.getLink());
194  if (0 == (pSection.getLink()->flag() & llvm::ELF::SHF_ALLOC))
195    return;
196
197  // Scan relocation type to determine if the GOT/PLT/Dynamic Relocation
198  // entries should be created.
199  if (rsym->isLocal()) // rsym is local
200    scanLocalReloc(pReloc, pLinker, pModule, pSection);
201  else // rsym is external
202    scanGlobalReloc(pReloc, pLinker, pModule, pSection);
203
204  // check if we should issue undefined reference for the relocation target
205  // symbol
206  if (rsym->isUndef() && !rsym->isDyn() && !rsym->isWeak() && !rsym->isNull())
207    issueUndefRef(pReloc, pSection, pInput);
208}
209
210void X86Relocator::addCopyReloc(ResolveInfo& pSym, X86GNULDBackend& pTarget)
211{
212  Relocation& rel_entry = *pTarget.getRelDyn().create();
213  rel_entry.setType(pTarget.getCopyRelType());
214  assert(pSym.outSymbol()->hasFragRef());
215  rel_entry.targetRef().assign(*pSym.outSymbol()->fragRef());
216  rel_entry.setSymInfo(&pSym);
217}
218
219/// defineSymbolforCopyReloc
220/// For a symbol needing copy relocation, define a copy symbol in the BSS
221/// section and all other reference to this symbol should refer to this
222/// copy.
223/// @note This is executed at `scan relocation' stage.
224LDSymbol& X86Relocator::defineSymbolforCopyReloc(IRBuilder& pBuilder,
225                                                 const ResolveInfo& pSym,
226                                                 X86GNULDBackend& pTarget)
227{
228  // get or create corresponding BSS LDSection
229  LDSection* bss_sect_hdr = NULL;
230  ELFFileFormat* file_format = pTarget.getOutputFormat();
231  if (ResolveInfo::ThreadLocal == pSym.type())
232    bss_sect_hdr = &file_format->getTBSS();
233  else
234    bss_sect_hdr = &file_format->getBSS();
235
236  // get or create corresponding BSS SectionData
237  assert(NULL != bss_sect_hdr);
238  SectionData* bss_section = NULL;
239  if (bss_sect_hdr->hasSectionData())
240    bss_section = bss_sect_hdr->getSectionData();
241  else
242    bss_section = IRBuilder::CreateSectionData(*bss_sect_hdr);
243
244  // Determine the alignment by the symbol value
245  // FIXME: here we use the largest alignment
246  uint32_t addralign = config().targets().bitclass() / 8;
247
248  // allocate space in BSS for the copy symbol
249  Fragment* frag = new FillFragment(0x0, 1, pSym.size());
250  uint64_t size = ObjectBuilder::AppendFragment(*frag,
251                                                *bss_section,
252                                                addralign);
253  bss_sect_hdr->setSize(bss_sect_hdr->size() + size);
254
255  // change symbol binding to Global if it's a weak symbol
256  ResolveInfo::Binding binding = (ResolveInfo::Binding)pSym.binding();
257  if (binding == ResolveInfo::Weak)
258    binding = ResolveInfo::Global;
259
260  // Define the copy symbol in the bss section and resolve it
261  LDSymbol* cpy_sym = pBuilder.AddSymbol<IRBuilder::Force, IRBuilder::Resolve>(
262                      pSym.name(),
263                      (ResolveInfo::Type)pSym.type(),
264                      ResolveInfo::Define,
265                      binding,
266                      pSym.size(),  // size
267                      0x0,          // value
268                      FragmentRef::Create(*frag, 0x0),
269                      (ResolveInfo::Visibility)pSym.other());
270
271  // output all other alias symbols if any
272  Module &pModule = pBuilder.getModule();
273  Module::AliasList* alias_list = pModule.getAliasList(pSym);
274  if (NULL!=alias_list) {
275    Module::alias_iterator it, it_e=alias_list->end();
276    for (it=alias_list->begin(); it!=it_e; ++it) {
277      const ResolveInfo* alias = *it;
278      if (alias!=&pSym && alias->isDyn()) {
279        pBuilder.AddSymbol<IRBuilder::Force, IRBuilder::Resolve>(
280                           alias->name(),
281                           (ResolveInfo::Type)alias->type(),
282                           ResolveInfo::Define,
283                           binding,
284                           alias->size(),  // size
285                           0x0,          // value
286                           FragmentRef::Create(*frag, 0x0),
287                           (ResolveInfo::Visibility)alias->other());
288      }
289    }
290  }
291
292  return *cpy_sym;
293}
294
295//===--------------------------------------------------------------------===//
296// X86_32Relocator
297//===--------------------------------------------------------------------===//
298X86_32Relocator::X86_32Relocator(X86_32GNULDBackend& pParent,
299                                 const LinkerConfig& pConfig)
300  : X86Relocator(pConfig), m_Target(pParent) {
301}
302
303Relocator::Result
304X86_32Relocator::applyRelocation(Relocation& pRelocation)
305{
306  Relocation::Type type = pRelocation.type();
307
308  if (type >= sizeof (X86_32ApplyFunctions) / sizeof (X86_32ApplyFunctions[0]) ) {
309    return Unknown;
310  }
311
312  // apply the relocation
313  return X86_32ApplyFunctions[type].func(pRelocation, *this);
314}
315
316const char* X86_32Relocator::getName(Relocation::Type pType) const
317{
318  return X86_32ApplyFunctions[pType].name;
319}
320
321Relocator::Size X86_32Relocator::getSize(Relocation::Type pType) const
322{
323  return X86_32ApplyFunctions[pType].size;;
324}
325
326bool
327X86_32Relocator::mayHaveFunctionPointerAccess(const Relocation& pReloc) const
328{
329  switch (pReloc.type()) {
330    case llvm::ELF::R_386_32:
331    case llvm::ELF::R_386_16:
332    case llvm::ELF::R_386_8:
333    case llvm::ELF::R_386_GOTOFF:
334    case llvm::ELF::R_386_GOT32: {
335      return true;
336    }
337    default: {
338      return false;
339    }
340  }
341}
342
343void X86_32Relocator::scanLocalReloc(Relocation& pReloc,
344                                     IRBuilder& pBuilder,
345                                     Module& pModule,
346                                     LDSection& pSection)
347{
348  // rsym - The relocation target symbol
349  ResolveInfo* rsym = pReloc.symInfo();
350
351  switch(pReloc.type()){
352
353    case llvm::ELF::R_386_32:
354      // If buiding PIC object (shared library or PIC executable),
355      // a dynamic relocations with RELATIVE type to this location is needed.
356      // Reserve an entry in .rel.dyn
357      if (config().isCodeIndep()) {
358        // set Rel bit
359        rsym->setReserved(rsym->reserved() | ReserveRel);
360        getTarget().checkAndSetHasTextRel(*pSection.getLink());
361        // set up the dyn rel directly
362        helper_DynRel_init(rsym,
363                           *pReloc.targetRef().frag(),
364                           pReloc.targetRef().offset(),
365                           llvm::ELF::R_386_RELATIVE,
366                           *this);
367      }
368      return;
369
370    case llvm::ELF::R_386_16:
371    case llvm::ELF::R_386_8:
372      // If buiding PIC object (shared library or PIC executable),
373      // a dynamic relocations with RELATIVE type to this location is needed.
374      // Reserve an entry in .rel.dyn
375      if (config().isCodeIndep()) {
376        // set up the dyn rel directly
377        helper_DynRel_init(rsym, *pReloc.targetRef().frag(),
378                            pReloc.targetRef().offset(), pReloc.type(), *this);
379        // set Rel bit
380        rsym->setReserved(rsym->reserved() | ReserveRel);
381        getTarget().checkAndSetHasTextRel(*pSection.getLink());
382      }
383      return;
384
385    case llvm::ELF::R_386_PLT32:
386      return;
387
388    case llvm::ELF::R_386_GOTOFF:
389    case llvm::ELF::R_386_GOTPC:
390      // FIXME: A GOT section is needed
391      return;
392
393    case llvm::ELF::R_386_GOT32:
394      // Symbol needs GOT entry, reserve entry in .got
395      // return if we already create GOT for this symbol
396      if (rsym->reserved() & ReserveGOT)
397        return;
398
399      // FIXME: check STT_GNU_IFUNC symbol
400
401      // If building shared object or the symbol is undefined, a dynamic
402      // relocation is needed to relocate this GOT entry. Reserve an
403      // entry in .rel.dyn
404      if (LinkerConfig::DynObj ==
405                   config().codeGenType() || rsym->isUndef() || rsym->isDyn()) {
406        helper_GOT_init(pReloc, true, *this);
407        // set GOT bit
408        rsym->setReserved(rsym->reserved() | ReserveGOT);
409        return;
410      }
411
412      // elsewhere if the GOT is used in statically linked binaries,
413      // the GOT entry is enough and no relocation is needed.
414      helper_GOT_init(pReloc, false, *this);
415      rsym->setReserved(rsym->reserved() | ReserveGOT);
416      return;
417
418    case llvm::ELF::R_386_PC32:
419    case llvm::ELF::R_386_PC16:
420    case llvm::ELF::R_386_PC8:
421      return;
422
423    case llvm::ELF::R_386_TLS_GD: {
424      // FIXME: no linker optimization for TLS relocation
425      if (rsym->reserved() & ReserveGOT)
426        return;
427
428      // define the section symbol for .tdata or .tbss
429      // the target symbol of the created dynamic relocation should be the
430      // section symbol of the section which this symbol defined. so we
431      // need to define that section symbol here
432      ELFFileFormat* file_format = getTarget().getOutputFormat();
433      const LDSection* sym_sect =
434               &rsym->outSymbol()->fragRef()->frag()->getParent()->getSection();
435      LDSymbol* sect_sym = NULL;
436      if (&file_format->getTData() == sym_sect) {
437        if (!getTarget().hasTDATASymbol()) {
438          sect_sym = pModule.getSectionSymbolSet().get(*sym_sect);
439          getTarget().setTDATASymbol(*sect_sym);
440        }
441      }
442      else if (&file_format->getTBSS() == sym_sect || rsym->isCommon()) {
443        if (!getTarget().hasTBSSSymbol()) {
444          sect_sym = pModule.getSectionSymbolSet().get(*sym_sect);
445          getTarget().setTBSSSymbol(*sect_sym);
446        }
447      }
448      else
449        error(diag::invalid_tls) << rsym->name() << sym_sect->name();
450
451      // set up a pair of got entries and a dyn rel
452      // set GOT bit
453      rsym->setReserved(rsym->reserved() | ReserveGOT);
454      X86_32GOTEntry* got_entry1 = getTarget().getGOT().create();
455      X86_32GOTEntry* got_entry2 = getTarget().getGOT().create();
456      getSymGOTMap().record(*rsym, *got_entry1, *got_entry2);
457      // set up value of got entries, the value of got_entry2 should be the
458      // symbol value, which has to be set during apply relocation
459      got_entry1->setValue(0x0);
460
461      // setup dyn rel for got_entry1
462      Relocation& rel_entry1 = helper_DynRel_init(rsym, *got_entry1, 0x0,
463                                        llvm::ELF::R_386_TLS_DTPMOD32, *this);
464      // for local tls symbol, add rel entry against the section symbol this
465      // symbol belong to (.tdata or .tbss)
466      rel_entry1.setSymInfo(sect_sym->resolveInfo());
467      return;
468    }
469    case llvm::ELF::R_386_TLS_LDM:
470      getTLSModuleID();
471      return;
472
473    case llvm::ELF::R_386_TLS_LDO_32:
474      return;
475
476    case llvm::ELF::R_386_TLS_IE: {
477      getTarget().setHasStaticTLS();
478
479      // if building shared object, a RELATIVE dynamic relocation is needed
480      if (LinkerConfig::DynObj == config().codeGenType()) {
481         helper_DynRel_init(rsym, *pReloc.targetRef().frag(),
482                                              pReloc.targetRef().offset(),
483                                              llvm::ELF::R_386_RELATIVE, *this);
484        rsym->setReserved(rsym->reserved() | ReserveRel);
485        getTarget().checkAndSetHasTextRel(*pSection.getLink());
486      }
487      else {
488        // for local sym, we can convert ie to le if not building shared object
489        convertTLSIEtoLE(pReloc, pSection);
490        return;
491      }
492
493      if (rsym->reserved() & ReserveGOT)
494        return;
495
496      // set up the got and the corresponding rel entry
497      X86_32GOTEntry* got_entry = getTarget().getGOT().create();
498      getSymGOTMap().record(*rsym, *got_entry);
499      got_entry->setValue(0x0);
500      helper_DynRel_init(rsym, *got_entry, 0x0, llvm::ELF::R_386_TLS_TPOFF,
501                                                                         *this);
502      // set GOT bit
503      rsym->setReserved(rsym->reserved() | ReserveGOT);
504      // add symbol to dyn sym table
505      getTarget().getRelDyn().addSymbolToDynSym(*rsym->outSymbol());
506      return;
507    }
508
509    case llvm::ELF::R_386_TLS_GOTIE: {
510      getTarget().setHasStaticTLS();
511      if (rsym->reserved() & ReserveGOT)
512        return;
513      // set up the got and the corresponding dyn rel
514      X86_32GOTEntry* got_entry = getTarget().getGOT().create();
515      getSymGOTMap().record(*rsym, *got_entry);
516      got_entry->setValue(0x0);
517      helper_DynRel_init(rsym, *got_entry, 0x0, llvm::ELF::R_386_TLS_TPOFF,
518                                                                        *this);
519      // set GOT bit
520      rsym->setReserved(rsym->reserved() | ReserveGOT);
521      getTarget().getRelDyn().addSymbolToDynSym(*rsym->outSymbol());
522      return;
523    }
524
525    case llvm::ELF::R_386_TLS_LE:
526    case llvm::ELF::R_386_TLS_LE_32:
527      getTarget().setHasStaticTLS();
528      // if buildint shared object, a dynamic relocation is needed
529      if (LinkerConfig::DynObj == config().codeGenType()) {
530        helper_DynRel_init(rsym,
531                           *pReloc.targetRef().frag(),
532                           pReloc.targetRef().offset(),
533                           llvm::ELF::R_386_TLS_TPOFF,
534                           *this);
535        rsym->setReserved(rsym->reserved() | ReserveRel);
536        getTarget().checkAndSetHasTextRel(*pSection.getLink());
537        // the target symbol of the dynamic relocation is rsym, so we need to
538        // emit it into .dynsym
539        assert(NULL != rsym->outSymbol());
540        getTarget().getRelDyn().addSymbolToDynSym(*rsym->outSymbol());
541      }
542      return;
543
544    default:
545      fatal(diag::unsupported_relocation) << (int)pReloc.type()
546                                          << "mclinker@googlegroups.com";
547      break;
548  } // end switch
549}
550
551void X86_32Relocator::scanGlobalReloc(Relocation& pReloc,
552                                      IRBuilder& pBuilder,
553                                      Module& pModule,
554                                      LDSection& pSection)
555{
556  // rsym - The relocation target symbol
557  ResolveInfo* rsym = pReloc.symInfo();
558
559  switch(pReloc.type()) {
560    case llvm::ELF::R_386_32:
561    case llvm::ELF::R_386_16:
562    case llvm::ELF::R_386_8:
563      // Absolute relocation type, symbol may needs PLT entry or
564      // dynamic relocation entry
565      if (getTarget().symbolNeedsPLT(*rsym)) {
566        // create plt for this symbol if it does not have one
567        if (!(rsym->reserved() & ReservePLT)){
568          // Symbol needs PLT entry, we need a PLT entry
569          // and the corresponding GOT and dynamic relocation entry
570          // in .got and .rel.plt.
571          helper_PLT_init(pReloc, *this);
572          // set PLT bit
573          rsym->setReserved(rsym->reserved() | ReservePLT);
574        }
575      }
576
577      if (getTarget().symbolNeedsDynRel(*rsym, (rsym->reserved() & ReservePLT),
578                                                                        true)) {
579        // symbol needs dynamic relocation entry, set up the dynrel entry
580        if (getTarget().symbolNeedsCopyReloc(pReloc, *rsym)) {
581          LDSymbol& cpy_sym = defineSymbolforCopyReloc(pBuilder, *rsym, getTarget());
582          addCopyReloc(*cpy_sym.resolveInfo(), getTarget());
583        }
584        else {
585          // set Rel bit and the dyn rel
586          rsym->setReserved(rsym->reserved() | ReserveRel);
587          getTarget().checkAndSetHasTextRel(*pSection.getLink());
588          if (llvm::ELF::R_386_32 == pReloc.type() &&
589              helper_use_relative_reloc(*rsym, *this))
590            helper_DynRel_init(rsym,
591                               *pReloc.targetRef().frag(),
592                               pReloc.targetRef().offset(),
593                               llvm::ELF::R_386_RELATIVE,
594                               *this);
595          else
596            helper_DynRel_init(rsym,
597                               *pReloc.targetRef().frag(),
598                               pReloc.targetRef().offset(),
599                               pReloc.type(),
600                               *this);
601        }
602      }
603      return;
604
605    case llvm::ELF::R_386_GOTOFF:
606    case llvm::ELF::R_386_GOTPC: {
607      // FIXME: A GOT section is needed
608      return;
609    }
610
611    case llvm::ELF::R_386_PLT32:
612      // A PLT entry is needed when building shared library
613
614      // return if we already create plt for this symbol
615      if (rsym->reserved() & ReservePLT)
616        return;
617
618      // if the symbol's value can be decided at link time, then no need plt
619      if (getTarget().symbolFinalValueIsKnown(*rsym))
620        return;
621
622      // if symbol is defined in the ouput file and it's not
623      // preemptible, no need plt
624      if (rsym->isDefine() && !rsym->isDyn() &&
625          !getTarget().isSymbolPreemptible(*rsym))
626        return;
627
628      // Symbol needs PLT entry, we need a PLT entry
629      // and the corresponding GOT and dynamic relocation entry
630      // in .got and .rel.plt
631      helper_PLT_init(pReloc, *this);
632      // set PLT bit
633      rsym->setReserved(rsym->reserved() | ReservePLT);
634      return;
635
636    case llvm::ELF::R_386_GOT32:
637      // Symbol needs GOT entry, reserve entry in .got
638      // return if we already create GOT for this symbol
639      if (rsym->reserved() & ReserveGOT)
640        return;
641      // If building shared object or the symbol is undefined, a dynamic
642      // relocation is needed to relocate this GOT entry. Reserve an
643      // entry in .rel.dyn
644      if (LinkerConfig::DynObj ==
645                   config().codeGenType() || rsym->isUndef() || rsym->isDyn())
646        helper_GOT_init(pReloc, true, *this);
647      else
648        helper_GOT_init(pReloc, false, *this);
649      // set GOT bit
650      rsym->setReserved(rsym->reserved() | ReserveGOT);
651      return;
652
653    case llvm::ELF::R_386_PC32:
654    case llvm::ELF::R_386_PC16:
655    case llvm::ELF::R_386_PC8:
656
657      if (getTarget().symbolNeedsPLT(*rsym) &&
658          LinkerConfig::DynObj != config().codeGenType()) {
659        // create plt for this symbol if it does not have one
660        if (!(rsym->reserved() & ReservePLT)){
661          // Symbol needs PLT entry, we need a PLT entry
662          // and the corresponding GOT and dynamic relocation entry
663          // in .got and .rel.plt.
664          // set PLT bit
665          helper_PLT_init(pReloc, *this);
666          rsym->setReserved(rsym->reserved() | ReservePLT);
667        }
668      }
669
670      if (getTarget().symbolNeedsDynRel(*rsym, (rsym->reserved() & ReservePLT),
671                                                                       false)) {
672        // symbol needs dynamic relocation entry, setup an entry in .rel.dyn
673        if (getTarget().symbolNeedsCopyReloc(pReloc, *rsym)) {
674          LDSymbol& cpy_sym = defineSymbolforCopyReloc(pBuilder, *rsym,
675                                                                   getTarget());
676          addCopyReloc(*cpy_sym.resolveInfo(), getTarget());
677        }
678        else {
679          // set Rel bit and the dyn rel
680          rsym->setReserved(rsym->reserved() | ReserveRel);
681          getTarget().checkAndSetHasTextRel(*pSection.getLink());
682          if (llvm::ELF::R_386_32 == pReloc.type() &&
683              helper_use_relative_reloc(*rsym, *this))
684            helper_DynRel_init(rsym,
685                               *pReloc.targetRef().frag(),
686                               pReloc.targetRef().offset(),
687                               llvm::ELF::R_386_RELATIVE,
688                               *this);
689          else
690            helper_DynRel_init(rsym,
691                               *pReloc.targetRef().frag(),
692                               pReloc.targetRef().offset(),
693                               pReloc.type(),
694                               *this);
695        }
696      }
697      return;
698
699    case llvm::ELF::R_386_TLS_GD: {
700      // FIXME: no linker optimization for TLS relocation
701      if (rsym->reserved() & ReserveGOT)
702        return;
703
704      // set up a pair of got entries and a pair of dyn rel
705      X86_32GOTEntry* got_entry1 = getTarget().getGOT().create();
706      X86_32GOTEntry* got_entry2 = getTarget().getGOT().create();
707      getSymGOTMap().record(*rsym, *got_entry1, *got_entry2);
708      got_entry1->setValue(0x0);
709      got_entry2->setValue(0x0);
710      // setup dyn rel for got entries against rsym
711      helper_DynRel_init(rsym, *got_entry1, 0x0,
712                                        llvm::ELF::R_386_TLS_DTPMOD32, *this);
713      helper_DynRel_init(rsym, *got_entry2, 0x0,
714                                        llvm::ELF::R_386_TLS_DTPOFF32, *this);
715
716      // add the rsym to dynamic symbol table
717      getTarget().getRelDyn().addSymbolToDynSym(*rsym->outSymbol());
718      // set GOT bit
719      rsym->setReserved(rsym->reserved() | ReserveGOT);
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      getTarget().setHasStaticTLS();
732      // if buildint shared object, a RELATIVE dynamic relocation is needed
733      if (LinkerConfig::DynObj == config().codeGenType()) {
734        helper_DynRel_init(rsym, *pReloc.targetRef().frag(),
735                                               pReloc.targetRef().offset(),
736                                               llvm::ELF::R_386_RELATIVE, *this);
737        rsym->setReserved(rsym->reserved() | ReserveRel);
738        getTarget().checkAndSetHasTextRel(*pSection.getLink());
739      } else {
740        // for global sym, we can convert ie to le if its final value is known
741        if (getTarget().symbolFinalValueIsKnown(*rsym)) {
742          convertTLSIEtoLE(pReloc, pSection);
743          return;
744        }
745      }
746      if (rsym->reserved() & ReserveGOT)
747        return;
748      // set up the got and the corresponding rel entry
749      X86_32GOTEntry* got_entry = getTarget().getGOT().create();
750      getSymGOTMap().record(*rsym, *got_entry);
751      got_entry->setValue(0x0);
752      helper_DynRel_init(rsym, *got_entry, 0x0, llvm::ELF::R_386_TLS_TPOFF,
753                                                                         *this);
754      // set GOT bit
755      rsym->setReserved(rsym->reserved() | ReserveGOT);
756      return;
757    }
758
759    case llvm::ELF::R_386_TLS_GOTIE: {
760      getTarget().setHasStaticTLS();
761      if (rsym->reserved() & ReserveGOT)
762        return;
763      // set up the got and the corresponding dyn rel
764      X86_32GOTEntry* got_entry = getTarget().getGOT().create();
765      getSymGOTMap().record(*rsym, *got_entry);
766      got_entry->setValue(0x0);
767      helper_DynRel_init(rsym, *got_entry, 0x0, llvm::ELF::R_386_TLS_TPOFF,
768                                                                        *this);
769      getTarget().getRelDyn().addSymbolToDynSym(*rsym->outSymbol());
770      // set GOT bit
771      rsym->setReserved(rsym->reserved() | ReserveGOT);
772      return;
773    }
774
775    case llvm::ELF::R_386_TLS_LE:
776    case llvm::ELF::R_386_TLS_LE_32:
777      getTarget().setHasStaticTLS();
778      // if buildint shared object, a dynamic relocation is needed
779      if (LinkerConfig::DynObj == config().codeGenType()) {
780        helper_DynRel_init(rsym,
781                           *pReloc.targetRef().frag(),
782                           pReloc.targetRef().offset(),
783                           llvm::ELF::R_386_TLS_TPOFF,
784                           *this);
785        getTarget().getRelDyn().addSymbolToDynSym(*rsym->outSymbol());
786        rsym->setReserved(rsym->reserved() | ReserveRel);
787        getTarget().checkAndSetHasTextRel(*pSection.getLink());
788      }
789      return;
790
791    default: {
792      fatal(diag::unsupported_relocation) << (int)pReloc.type()
793                                          << "mclinker@googlegroups.com";
794      break;
795    }
796  } // end switch
797}
798
799// Create a GOT entry for the TLS module index
800X86_32GOTEntry& X86_32Relocator::getTLSModuleID()
801{
802  static X86_32GOTEntry* got_entry = NULL;
803  if (NULL != got_entry)
804    return *got_entry;
805
806  // Allocate 2 got entries and 1 dynamic reloc for R_386_TLS_LDM
807  got_entry = getTarget().getGOT().create();
808  getTarget().getGOT().create()->setValue(0x0);
809
810  helper_DynRel_init(NULL, *got_entry, 0x0, llvm::ELF::R_386_TLS_DTPMOD32,
811                                                                          *this);
812  return *got_entry;
813}
814
815/// convert R_386_TLS_IE to R_386_TLS_LE
816void X86_32Relocator::convertTLSIEtoLE(Relocation& pReloc,
817                                       LDSection& pSection)
818{
819  assert(pReloc.type() == llvm::ELF::R_386_TLS_IE);
820  assert(NULL != pReloc.targetRef().frag());
821
822  // 1. create the new relocs
823  Relocation* reloc =
824    Relocation::Create(X86_32Relocator::R_386_TLS_OPT,
825                       *FragmentRef::Create(*pReloc.targetRef().frag(),
826                                            pReloc.targetRef().offset() - 1),
827                       0x0);
828  // FIXME: should we create a special symbol for the tls opt instead?
829  reloc->setSymInfo(pReloc.symInfo());
830
831  // 2. modify the opcodes to the appropriate ones
832  uint8_t* op =  (reinterpret_cast<uint8_t*>(&reloc->target()));
833  if (op[0] == 0xa1) {
834    op[0] = 0xb8;
835  } else {
836    // create the new reloc (move 1 byte forward).
837    reloc = Relocation::Create(X86_32Relocator::R_386_TLS_OPT,
838                               *FragmentRef::Create(*pReloc.targetRef().frag(),
839                                   pReloc.targetRef().offset() - 2),
840                               0x0);
841    reloc->setSymInfo(pReloc.symInfo());
842    op = (reinterpret_cast<uint8_t*>(&reloc->target()));
843    switch (op[0]) {
844      case 0x8b:
845        assert((op[1] & 0xc7) == 0x05);
846        op[0] = 0xc7;
847        op[1] = 0xc0 | ((op[1] >> 3) & 7);
848        break;
849      case 0x03:
850        assert((op[1] & 0xc7) == 0x05);
851        op[0] = 0x81;
852        op[1] = 0xc0 | ((op[1] >> 3) & 7);
853        break;
854      default:
855        assert(0);
856        break;
857    }
858  }
859
860  // 3. insert the new relocs "BEFORE" the original reloc.
861  assert(reloc != NULL);
862  pSection.getRelocData()->getRelocationList().insert(
863    RelocData::iterator(pReloc), reloc);
864
865  // 4. change the type of the original reloc
866  pReloc.setType(llvm::ELF::R_386_TLS_LE);
867}
868
869//================================================//
870// X86_32 Each relocation function implementation //
871//================================================//
872
873// R_386_NONE
874Relocator::Result none(Relocation& pReloc, X86_32Relocator& pParent)
875{
876  return Relocator::OK;
877}
878
879// R_386_32: S + A
880// R_386_16
881// R_386_8
882Relocator::Result abs(Relocation& pReloc, X86_32Relocator& pParent)
883{
884  ResolveInfo* rsym = pReloc.symInfo();
885  Relocator::DWord A = pReloc.target() + pReloc.addend();
886  Relocator::DWord S = pReloc.symValue();
887  bool has_dyn_rel = pParent.getTarget().symbolNeedsDynRel(
888                                  *rsym,
889                                  (rsym->reserved() & X86Relocator::ReservePLT),
890                                  true);
891
892
893  LDSection& target_sect = pReloc.targetRef().frag()->getParent()->getSection();
894  // If the flag of target section is not ALLOC, we will not scan this relocation
895  // but perform static relocation. (e.g., applying .debug section)
896  if (0x0 == (llvm::ELF::SHF_ALLOC & target_sect.flag())) {
897    pReloc.target() = S + A;
898    return Relocator::OK;
899  }
900
901  // An external symbol may need PLT and dynamic relocation
902  if (!rsym->isLocal()) {
903    if (rsym->reserved() & X86Relocator::ReservePLT) {
904      S = helper_get_PLT_address(*rsym, pParent);
905    }
906    // If we generate a dynamic relocation (except R_386_RELATIVE)
907    // for a place, we should not perform static relocation on it
908    // in order to keep the addend store in the place correct.
909    if (has_dyn_rel)
910      if (llvm::ELF::R_386_32 != pReloc.type() ||
911          (!helper_use_relative_reloc(*rsym, pParent)))
912        return Relocator::OK;
913  }
914
915  // perform static relocation
916  pReloc.target() = S + A;
917  return Relocator::OK;
918}
919
920// R_386_PC32: S + A - P
921// R_386_PC16
922// R_386_PC8
923Relocator::Result rel(Relocation& pReloc, X86_32Relocator& pParent)
924{
925  ResolveInfo* rsym = pReloc.symInfo();
926  Relocator::DWord A = pReloc.target() + pReloc.addend();
927  Relocator::DWord S = pReloc.symValue();
928  Relocator::DWord P = pReloc.place();
929  bool has_dyn_rel = pParent.getTarget().symbolNeedsDynRel(
930                                  *rsym,
931                                  (rsym->reserved() & X86Relocator::ReservePLT),
932                                  true);
933
934  LDSection& target_sect = pReloc.targetRef().frag()->getParent()->getSection();
935  // If the flag of target section is not ALLOC, we will not scan this relocation
936  // but perform static relocation. (e.g., applying .debug section)
937  if (0x0 == (llvm::ELF::SHF_ALLOC & target_sect.flag())) {
938    pReloc.target() = S + A - P;
939    return Relocator::OK;
940  }
941
942  // An external symbol may need PLT and dynamic relocation
943  if (!rsym->isLocal()) {
944    if (rsym->reserved() & X86Relocator::ReservePLT) {
945      S = helper_get_PLT_address(*rsym, pParent);
946      pReloc.target() = S + A - P;
947    }
948    if (has_dyn_rel)
949      if (!helper_use_relative_reloc(*rsym, pParent))
950        return Relocator::OK;
951  }
952
953   // perform static relocation
954  pReloc.target() = S + A - P;
955  return Relocator::OK;
956}
957
958// R_386_GOTOFF: S + A - GOT_ORG
959Relocator::Result gotoff32(Relocation& pReloc, X86_32Relocator& pParent)
960{
961  Relocator::DWord      A = pReloc.target() + pReloc.addend();
962  Relocator::Address GOT_ORG = helper_GOT_ORG(pParent);
963  Relocator::Address S = pReloc.symValue();
964
965  pReloc.target() = S + A - GOT_ORG;
966  return Relocator::OK;
967}
968
969// R_386_GOTPC: GOT_ORG + A - P
970Relocator::Result gotpc32(Relocation& pReloc, X86_32Relocator& pParent)
971{
972  Relocator::DWord      A       = pReloc.target() + pReloc.addend();
973  Relocator::Address GOT_ORG = helper_GOT_ORG(pParent);
974  // Apply relocation.
975  pReloc.target() = GOT_ORG + A - pReloc.place();
976  return Relocator::OK;
977}
978
979// R_386_GOT32: GOT(S) + A - GOT_ORG
980Relocator::Result got32(Relocation& pReloc, X86_32Relocator& pParent)
981{
982  ResolveInfo* rsym = pReloc.symInfo();
983  if (!(rsym->reserved() & (X86Relocator::ReserveGOT)))
984    return Relocator::BadReloc;
985
986  // set up got entry value if the got has no dyn rel or
987  // the dyn rel is RELATIVE
988  X86_32GOTEntry* got_entry = pParent.getSymGOTMap().lookUp(*pReloc.symInfo());
989  assert(NULL != got_entry);
990  if (got_entry->getValue() == X86Relocator::SymVal)
991    got_entry->setValue(pReloc.symValue());
992
993  Relocator::Address GOT_S   = helper_get_GOT_address(pReloc, pParent);
994  Relocator::DWord      A       = pReloc.target() + pReloc.addend();
995  Relocator::Address GOT_ORG = helper_GOT_ORG(pParent);
996  // Apply relocation.
997  pReloc.target() = GOT_S + A - GOT_ORG;
998  return Relocator::OK;
999}
1000
1001// R_386_PLT32: PLT(S) + A - P
1002Relocator::Result plt32(Relocation& pReloc, X86_32Relocator& pParent)
1003{
1004  // PLT_S depends on if there is a PLT entry.
1005  Relocator::Address PLT_S;
1006  if ((pReloc.symInfo()->reserved() & X86Relocator::ReservePLT))
1007    PLT_S = helper_get_PLT_address(*pReloc.symInfo(), pParent);
1008  else
1009    PLT_S = pReloc.symValue();
1010  Relocator::DWord      A = pReloc.target() + pReloc.addend();
1011  Relocator::Address P = pReloc.place();
1012  pReloc.target() = PLT_S + A - P;
1013  return Relocator::OK;
1014}
1015
1016// R_386_TLS_GD:
1017Relocator::Result tls_gd(Relocation& pReloc, X86_32Relocator& pParent)
1018{
1019  // global-dynamic
1020  ResolveInfo* rsym = pReloc.symInfo();
1021  // must reserve two pairs of got and dynamic relocation
1022  if (!(rsym->reserved() & X86Relocator::ReserveGOT))
1023    return Relocator::BadReloc;
1024
1025  ELFFileFormat* file_format = pParent.getTarget().getOutputFormat();
1026  // setup corresponding got and dynamic relocatio entries:
1027  // get first got entry, if there is already a got entry for rsym, then apply
1028  // this relocation to the got entry directly. If not, setup the corresponding
1029  // got and dyn relocation entries
1030  X86_32GOTEntry* got_entry1 = pParent.getSymGOTMap().lookUpFirstEntry(*rsym);
1031
1032  // set the got_entry2 value to symbol value
1033  if (rsym->isLocal())
1034     pParent.getSymGOTMap().lookUpSecondEntry(*rsym)->setValue(pReloc.symValue());
1035
1036  // perform relocation to the first got entry
1037  Relocator::DWord A = pReloc.target() + pReloc.addend();
1038  // GOT_OFF - the offset between the got_entry1 and _GLOBAL_OFFSET_TABLE (the
1039  // .got.plt section)
1040  Relocator::Address GOT_OFF =
1041     file_format->getGOT().addr() +
1042     got_entry1->getOffset() -
1043     file_format->getGOTPLT().addr();
1044  pReloc.target() = GOT_OFF + A;
1045  return Relocator::OK;
1046}
1047
1048// R_386_TLS_LDM
1049Relocator::Result tls_ldm(Relocation& pReloc, X86_32Relocator& pParent)
1050{
1051  // FIXME: no linker optimization for TLS relocation
1052  const X86_32GOTEntry& got_entry = pParent.getTLSModuleID();
1053
1054  // All GOT offsets are relative to the end of the GOT.
1055  X86Relocator::SWord GOT_S = got_entry.getOffset() -
1056                                      (pParent.getTarget().getGOTPLT().addr() -
1057                                       pParent.getTarget().getGOT().addr());
1058  Relocator::DWord A = pReloc.target() + pReloc.addend();
1059  pReloc.target() = GOT_S + A;
1060
1061  return Relocator::OK;
1062}
1063
1064// R_386_TLS_LDO_32
1065Relocator::Result tls_ldo_32(Relocation& pReloc, X86_32Relocator& pParent)
1066{
1067  // FIXME: no linker optimization for TLS relocation
1068  Relocator::DWord A = pReloc.target() + pReloc.addend();
1069  Relocator::Address S = pReloc.symValue();
1070  pReloc.target() = S + A;
1071  return Relocator::OK;
1072}
1073
1074// R_X86_TLS_IE
1075Relocator::Result tls_ie(Relocation& pReloc, X86_32Relocator& pParent)
1076{
1077  ResolveInfo* rsym = pReloc.symInfo();
1078  if (!(rsym->reserved() & X86Relocator::ReserveGOT)) {
1079     return Relocator::BadReloc;
1080  }
1081
1082  // set up the got and dynamic relocation entries if not exist
1083  X86_32GOTEntry* got_entry = pParent.getSymGOTMap().lookUp(*rsym);
1084  assert(NULL != got_entry);
1085  // perform relocation to the absolute address of got_entry
1086  Relocator::Address GOT_S =
1087                   pParent.getTarget().getGOT().addr() + got_entry->getOffset();
1088
1089  Relocator::DWord A = pReloc.target() + pReloc.addend();
1090  pReloc.target() = GOT_S + A;
1091
1092  return Relocator::OK;
1093}
1094
1095// R_386_TLS_GOTIE
1096Relocator::Result tls_gotie(Relocation& pReloc, X86_32Relocator& pParent)
1097{
1098  ResolveInfo* rsym = pReloc.symInfo();
1099  if (!(rsym->reserved() & X86Relocator::ReserveGOT)) {
1100     return Relocator::BadReloc;
1101  }
1102
1103  // set up the got and dynamic relocation entries if not exist
1104  X86_32GOTEntry* got_entry = pParent.getSymGOTMap().lookUp(*rsym);
1105  assert(NULL != got_entry);
1106
1107  // All GOT offsets are relative to the end of the GOT.
1108  X86Relocator::SWord GOT_S = got_entry->getOffset() -
1109    (pParent.getTarget().getGOTPLT().addr() - pParent.getTarget().getGOT().addr());
1110  Relocator::DWord A = pReloc.target() + pReloc.addend();
1111  pReloc.target() = GOT_S + A;
1112
1113  return Relocator::OK;
1114}
1115
1116// R_X86_TLS_LE
1117Relocator::Result tls_le(Relocation& pReloc, X86_32Relocator& pParent)
1118{
1119  if (pReloc.symInfo()->reserved() & X86Relocator::ReserveRel)
1120    return Relocator::OK;
1121
1122  // perform static relocation
1123  // get TLS segment
1124  ELFSegmentFactory::const_iterator tls_seg =
1125    pParent.getTarget().elfSegmentTable().find(llvm::ELF::PT_TLS,
1126                                               llvm::ELF::PF_R,
1127                                               0x0);
1128  assert(tls_seg != pParent.getTarget().elfSegmentTable().end());
1129  Relocator::DWord A = pReloc.target() + pReloc.addend();
1130  Relocator::Address S = pReloc.symValue();
1131  pReloc.target() = S + A - (*tls_seg)->memsz();
1132  return Relocator::OK;
1133}
1134
1135Relocator::Result unsupport(Relocation& pReloc, X86_32Relocator& pParent)
1136{
1137  return Relocator::Unsupport;
1138}
1139
1140//===--------------------------------------------------------------------===//
1141// X86_64 Relocation helper function
1142//===--------------------------------------------------------------------===//
1143/// helper_DynRel - Get an relocation entry in .rela.dyn
1144static
1145Relocation& helper_DynRel_init(ResolveInfo* pSym,
1146                               Fragment& pFrag,
1147                               uint64_t pOffset,
1148                               Relocator::Type pType,
1149                               X86_64Relocator& pParent)
1150{
1151  X86_64GNULDBackend& ld_backend = pParent.getTarget();
1152  Relocation& rel_entry = *ld_backend.getRelDyn().create();
1153  rel_entry.setType(pType);
1154  rel_entry.targetRef().assign(pFrag, pOffset);
1155  if (pType == llvm::ELF::R_X86_64_RELATIVE || NULL == pSym)
1156    rel_entry.setSymInfo(NULL);
1157  else
1158    rel_entry.setSymInfo(pSym);
1159
1160  return rel_entry;
1161}
1162
1163
1164/// helper_use_relative_reloc - Check if symbol can use relocation
1165/// R_X86_64_RELATIVE
1166static bool
1167helper_use_relative_reloc(const ResolveInfo& pSym,
1168                          const X86_64Relocator& pFactory)
1169
1170{
1171  // if symbol is dynamic or undefine or preemptible
1172  if (pSym.isDyn() ||
1173      pSym.isUndef() ||
1174      pFactory.getTarget().isSymbolPreemptible(pSym))
1175    return false;
1176  return true;
1177}
1178
1179static
1180X86_64GOTEntry& helper_GOT_init(Relocation& pReloc,
1181                                bool pHasRel,
1182                                X86_64Relocator& pParent)
1183{
1184  // rsym - The relocation target symbol
1185  ResolveInfo* rsym = pReloc.symInfo();
1186  X86_64GNULDBackend& ld_backend = pParent.getTarget();
1187  assert(NULL == pParent.getSymGOTMap().lookUp(*rsym));
1188
1189  X86_64GOTEntry* got_entry = ld_backend.getGOT().create();
1190  pParent.getSymGOTMap().record(*rsym, *got_entry);
1191
1192  // If we first get this GOT entry, we should initialize it.
1193  if (!pHasRel) {
1194    // No corresponding dynamic relocation, initialize to the symbol value.
1195    got_entry->setValue(X86Relocator::SymVal);
1196  }
1197  else {
1198    // Initialize got_entry content and the corresponding dynamic relocation.
1199    if (helper_use_relative_reloc(*rsym, pParent)) {
1200       Relocation& rel_entry = helper_DynRel_init(rsym, *got_entry, 0x0,
1201                                         llvm::ELF::R_X86_64_RELATIVE, pParent);
1202       rel_entry.setAddend(X86Relocator::SymVal);
1203       pParent.getRelRelMap().record(pReloc, rel_entry);
1204    }
1205    else {
1206       helper_DynRel_init(rsym, *got_entry, 0x0, llvm::ELF::R_X86_64_GLOB_DAT,
1207                                                                       pParent);
1208    }
1209    got_entry->setValue(0);
1210  }
1211  return *got_entry;
1212}
1213
1214static
1215Relocator::Address helper_GOT_ORG(X86_64Relocator& pParent)
1216{
1217  return pParent.getTarget().getGOT().addr();
1218}
1219
1220static
1221Relocator::Address helper_get_GOT_address(Relocation& pReloc,
1222                                          X86_64Relocator& pParent)
1223{
1224  X86_64GOTEntry* got_entry = pParent.getSymGOTMap().lookUp(*pReloc.symInfo());
1225  assert(NULL != got_entry);
1226  return got_entry->getOffset();
1227}
1228
1229static
1230Relocator::Address helper_get_PLT_address(ResolveInfo& pSym,
1231                                          X86_64Relocator& pParent)
1232{
1233  PLTEntryBase* plt_entry = pParent.getSymPLTMap().lookUp(pSym);
1234  assert(NULL != plt_entry);
1235  return pParent.getTarget().getPLT().addr() + plt_entry->getOffset();
1236}
1237
1238static
1239PLTEntryBase& helper_PLT_init(Relocation& pReloc, X86_64Relocator& pParent)
1240{
1241  // rsym - The relocation target symbol
1242  ResolveInfo* rsym = pReloc.symInfo();
1243  X86_64GNULDBackend& ld_backend = pParent.getTarget();
1244  assert(NULL == pParent.getSymPLTMap().lookUp(*rsym));
1245
1246  PLTEntryBase* plt_entry = ld_backend.getPLT().create();
1247  pParent.getSymPLTMap().record(*rsym, *plt_entry);
1248
1249  // initialize plt and the corresponding gotplt and dyn rel entry.
1250  assert(NULL == pParent.getSymGOTPLTMap().lookUp(*rsym) &&
1251         "PLT entry not exist, but DynRel entry exist!");
1252  X86_64GOTEntry* gotplt_entry = ld_backend.getGOTPLT().create();
1253  pParent.getSymGOTPLTMap().record(*rsym, *gotplt_entry);
1254
1255  // init the corresponding rel entry in .rel.plt
1256  Relocation& rel_entry = *ld_backend.getRelPLT().create();
1257  rel_entry.setType(llvm::ELF::R_X86_64_JUMP_SLOT);
1258  rel_entry.targetRef().assign(*gotplt_entry);
1259  rel_entry.setSymInfo(rsym);
1260  return *plt_entry;
1261}
1262
1263//===--------------------------------------------------------------------===//
1264// X86_64 Relocation Functions and Tables
1265//===--------------------------------------------------------------------===//
1266DECL_X86_64_APPLY_RELOC_FUNCS
1267
1268/// the prototype of applying function
1269typedef Relocator::Result (*X86_64ApplyFunctionType)(Relocation& pReloc,
1270                                                     X86_64Relocator& pParent);
1271
1272// the table entry of applying functions
1273struct X86_64ApplyFunctionTriple
1274{
1275  X86_64ApplyFunctionType func;
1276  unsigned int type;
1277  const char* name;
1278  unsigned int size;
1279};
1280
1281// declare the table of applying functions
1282static const X86_64ApplyFunctionTriple X86_64ApplyFunctions[] = {
1283  DECL_X86_64_APPLY_RELOC_FUNC_PTRS
1284};
1285
1286//===--------------------------------------------------------------------===//
1287// X86_64Relocator
1288//===--------------------------------------------------------------------===//
1289X86_64Relocator::X86_64Relocator(X86_64GNULDBackend& pParent,
1290                                 const LinkerConfig& pConfig)
1291  : X86Relocator(pConfig), m_Target(pParent) {
1292}
1293
1294Relocator::Result
1295X86_64Relocator::applyRelocation(Relocation& pRelocation)
1296{
1297  Relocation::Type type = pRelocation.type();
1298
1299  if (type >= sizeof (X86_64ApplyFunctions) / sizeof (X86_64ApplyFunctions[0]) ) {
1300    return Unknown;
1301  }
1302
1303  // apply the relocation
1304  return X86_64ApplyFunctions[type].func(pRelocation, *this);
1305}
1306
1307const char* X86_64Relocator::getName(Relocation::Type pType) const
1308{
1309  return X86_64ApplyFunctions[pType].name;
1310}
1311
1312Relocator::Size X86_64Relocator::getSize(Relocation::Type pType) const
1313{
1314  return X86_64ApplyFunctions[pType].size;
1315}
1316
1317bool
1318X86_64Relocator::mayHaveFunctionPointerAccess(const Relocation& pReloc) const
1319{
1320  bool possible_funcptr_reloc = false;
1321  switch (pReloc.type()) {
1322    case llvm::ELF::R_X86_64_64:
1323    case llvm::ELF::R_X86_64_32:
1324    case llvm::ELF::R_X86_64_32S:
1325    case llvm::ELF::R_X86_64_16:
1326    case llvm::ELF::R_X86_64_8:
1327    case llvm::ELF::R_X86_64_GOT64:
1328    case llvm::ELF::R_X86_64_GOT32:
1329    case llvm::ELF::R_X86_64_GOTPCREL64:
1330    case llvm::ELF::R_X86_64_GOTPCREL:
1331    case llvm::ELF::R_X86_64_GOTPLT64: {
1332      possible_funcptr_reloc = true;
1333      break;
1334    }
1335    default: {
1336      possible_funcptr_reloc = false;
1337      break;
1338    }
1339  }
1340
1341 if (pReloc.symInfo()->isGlobal()) {
1342    return (config().codeGenType() == LinkerConfig::DynObj) &&
1343           ((pReloc.symInfo()->visibility() != ResolveInfo::Default) ||
1344            possible_funcptr_reloc);
1345 } else {
1346    return (config().codeGenType() == LinkerConfig::DynObj) ||
1347           possible_funcptr_reloc;
1348 }
1349}
1350
1351void X86_64Relocator::scanLocalReloc(Relocation& pReloc,
1352                                     IRBuilder& pBuilder,
1353                                     Module& pModule,
1354                                     LDSection& pSection)
1355{
1356  // rsym - The relocation target symbol
1357  ResolveInfo* rsym = pReloc.symInfo();
1358
1359  switch(pReloc.type()){
1360    case llvm::ELF::R_X86_64_64:
1361      // If buiding PIC object (shared library or PIC executable),
1362      // a dynamic relocations with RELATIVE type to this location is needed.
1363      // Reserve an entry in .rela.dyn
1364      if (config().isCodeIndep()) {
1365        Relocation& reloc = helper_DynRel_init(rsym,
1366                                               *pReloc.targetRef().frag(),
1367                                               pReloc.targetRef().offset(),
1368                                               llvm::ELF::R_X86_64_RELATIVE,
1369                                               *this);
1370        getRelRelMap().record(pReloc, reloc);
1371        // set Rel bit
1372        rsym->setReserved(rsym->reserved() | ReserveRel);
1373        getTarget().checkAndSetHasTextRel(*pSection.getLink());
1374      }
1375      return;
1376
1377    case llvm::ELF::R_X86_64_32:
1378    case llvm::ELF::R_X86_64_16:
1379    case llvm::ELF::R_X86_64_8:
1380    case llvm::ELF::R_X86_64_32S:
1381      // If buiding PIC object (shared library or PIC executable),
1382      // a dynamic relocations with RELATIVE type to this location is needed.
1383      // Reserve an entry in .rela.dyn
1384      if (config().isCodeIndep()) {
1385        Relocation& reloc = helper_DynRel_init(rsym,
1386                                               *pReloc.targetRef().frag(),
1387                                               pReloc.targetRef().offset(),
1388                                               pReloc.type(),
1389                                               *this);
1390        getRelRelMap().record(pReloc, reloc);
1391        // set Rel bit
1392        rsym->setReserved(rsym->reserved() | ReserveRel);
1393        getTarget().checkAndSetHasTextRel(*pSection.getLink());
1394      }
1395      return;
1396
1397    case llvm::ELF::R_X86_64_PC32:
1398    case llvm::ELF::R_X86_64_PC16:
1399    case llvm::ELF::R_X86_64_PC8:
1400      return;
1401
1402    case llvm::ELF::R_X86_64_GOTPCREL:
1403      // Symbol needs GOT entry, reserve entry in .got
1404      // return if we already create GOT for this symbol
1405      if (rsym->reserved() & ReserveGOT)
1406        return;
1407
1408      // If building shared object or the symbol is undefined, a dynamic
1409      // relocation is needed to relocate this GOT entry. Reserve an
1410      // entry in .rela.dyn
1411      if (LinkerConfig::DynObj ==
1412                   config().codeGenType() || rsym->isUndef() || rsym->isDyn())
1413        helper_GOT_init(pReloc, true, *this);
1414      else
1415        helper_GOT_init(pReloc, false, *this);
1416      rsym->setReserved(rsym->reserved() | ReserveGOT);
1417      return;
1418
1419    default:
1420      fatal(diag::unsupported_relocation) << (int)pReloc.type()
1421                                          << "mclinker@googlegroups.com";
1422      break;
1423  } // end switch
1424}
1425
1426void X86_64Relocator::scanGlobalReloc(Relocation& pReloc,
1427                                      IRBuilder& pBuilder,
1428                                      Module& pModule,
1429                                      LDSection& pSection)
1430{
1431  // rsym - The relocation target symbol
1432  ResolveInfo* rsym = pReloc.symInfo();
1433
1434  switch(pReloc.type()) {
1435    case llvm::ELF::R_X86_64_64:
1436    case llvm::ELF::R_X86_64_32:
1437    case llvm::ELF::R_X86_64_16:
1438    case llvm::ELF::R_X86_64_8:
1439    case llvm::ELF::R_X86_64_32S:
1440      // Absolute relocation type, symbol may needs PLT entry or
1441      // dynamic relocation entry
1442      if (getTarget().symbolNeedsPLT(*rsym)) {
1443        // create plt for this symbol if it does not have one
1444        if (!(rsym->reserved() & ReservePLT)){
1445          // Symbol needs PLT entry, we need to reserve a PLT entry
1446          // and the corresponding GOT and dynamic relocation entry
1447          // in .got and .rela.plt.
1448          helper_PLT_init(pReloc, *this);
1449          // set PLT bit
1450          rsym->setReserved(rsym->reserved() | ReservePLT);
1451        }
1452      }
1453
1454      if (getTarget().symbolNeedsDynRel(*rsym, (rsym->reserved() & ReservePLT),
1455                                                                        true)) {
1456        // symbol needs dynamic relocation entry, set up the dynrel entry
1457        if (getTarget().symbolNeedsCopyReloc(pReloc, *rsym)) {
1458          LDSymbol& cpy_sym = defineSymbolforCopyReloc(pBuilder, *rsym, getTarget());
1459          addCopyReloc(*cpy_sym.resolveInfo(), getTarget());
1460        }
1461        else {
1462          // set Rel bit and the dyn rel
1463          rsym->setReserved(rsym->reserved() | ReserveRel);
1464          getTarget().checkAndSetHasTextRel(*pSection.getLink());
1465          if (llvm::ELF::R_386_32 == pReloc.type() &&
1466              helper_use_relative_reloc(*rsym, *this)) {
1467            Relocation& reloc = helper_DynRel_init(rsym,
1468                                                   *pReloc.targetRef().frag(),
1469                                                   pReloc.targetRef().offset(),
1470                                                   llvm::ELF::R_X86_64_RELATIVE,
1471                                                   *this);
1472            getRelRelMap().record(pReloc, reloc);
1473          }
1474          else {
1475            Relocation& reloc = helper_DynRel_init(rsym,
1476                                                   *pReloc.targetRef().frag(),
1477                                                   pReloc.targetRef().offset(),
1478                                                   pReloc.type(),
1479                                                   *this);
1480            getRelRelMap().record(pReloc, reloc);
1481          }
1482          getTarget().checkAndSetHasTextRel(*pSection.getLink());
1483        }
1484      }
1485      return;
1486
1487    case llvm::ELF::R_X86_64_GOTPCREL:
1488      // Symbol needs GOT entry, reserve entry in .got
1489      // return if we already create GOT for this symbol
1490      if (rsym->reserved() & ReserveGOT)
1491        return;
1492
1493      // If building shared object or the symbol is undefined, a dynamic
1494      // relocation is needed to relocate this GOT entry. Reserve an
1495      // entry in .rela.dyn
1496      if (LinkerConfig::DynObj ==
1497                   config().codeGenType() || rsym->isUndef() || rsym->isDyn())
1498        helper_GOT_init(pReloc, true, *this);
1499      else
1500        helper_GOT_init(pReloc, false, *this);
1501      // set GOT bit
1502      rsym->setReserved(rsym->reserved() | ReserveGOT);
1503      return;
1504
1505    case llvm::ELF::R_X86_64_PLT32:
1506      // A PLT entry is needed when building shared library
1507
1508      // return if we already create plt for this symbol
1509      if (rsym->reserved() & ReservePLT)
1510        return;
1511
1512      // if the symbol's value can be decided at link time, then no need plt
1513      if (getTarget().symbolFinalValueIsKnown(*rsym))
1514        return;
1515
1516      // if symbol is defined in the ouput file and it's not
1517      // preemptible, no need plt
1518      if (rsym->isDefine() && !rsym->isDyn() &&
1519         !getTarget().isSymbolPreemptible(*rsym)) {
1520        return;
1521      }
1522
1523      // Symbol needs PLT entry, we need a PLT entry
1524      // and the corresponding GOT and dynamic relocation entry
1525      // in .got and .rel.plt.
1526      helper_PLT_init(pReloc, *this);
1527      // set PLT bit
1528      rsym->setReserved(rsym->reserved() | ReservePLT);
1529      return;
1530
1531    case llvm::ELF::R_X86_64_PC32:
1532    case llvm::ELF::R_X86_64_PC16:
1533    case llvm::ELF::R_X86_64_PC8:
1534      if (getTarget().symbolNeedsPLT(*rsym) &&
1535          LinkerConfig::DynObj != config().codeGenType()) {
1536        // create plt for this symbol if it does not have one
1537        if (!(rsym->reserved() & ReservePLT)){
1538          // Symbol needs PLT entry, we need a PLT entry
1539          // and the corresponding GOT and dynamic relocation entry
1540          // in .got and .rel.plt.
1541          helper_PLT_init(pReloc, *this);
1542          // set PLT bit
1543          rsym->setReserved(rsym->reserved() | ReservePLT);
1544        }
1545      }
1546
1547      // Only PC relative relocation against dynamic symbol needs a
1548      // dynamic relocation.  Only dynamic copy relocation is allowed
1549      // and PC relative relocation will be resolved to the local copy.
1550      // All other dynamic relocations may lead to run-time relocation
1551      // overflow.
1552      if (getTarget().isDynamicSymbol(*rsym) &&
1553          getTarget().symbolNeedsDynRel(*rsym,
1554                                        (rsym->reserved() & ReservePLT),
1555                                        false) &&
1556        getTarget().symbolNeedsCopyReloc(pReloc, *rsym)) {
1557        LDSymbol& cpy_sym = defineSymbolforCopyReloc(pBuilder, *rsym, getTarget());
1558        addCopyReloc(*cpy_sym.resolveInfo(), getTarget());
1559      }
1560      return;
1561
1562    default:
1563      fatal(diag::unsupported_relocation) << (int)pReloc.type()
1564                                          << "mclinker@googlegroups.com";
1565      break;
1566  } // end switch
1567}
1568
1569// ===
1570//
1571// ===
1572// R_X86_64_NONE
1573Relocator::Result none(Relocation& pReloc, X86_64Relocator& pParent)
1574{
1575  return Relocator::OK;
1576}
1577
1578// R_X86_64_64: S + A
1579// R_X86_64_32:
1580// R_X86_64_16:
1581// R_X86_64_8
1582Relocator::Result abs(Relocation& pReloc, X86_64Relocator& pParent)
1583{
1584  ResolveInfo* rsym = pReloc.symInfo();
1585  Relocator::DWord A = pReloc.target() + pReloc.addend();
1586  Relocator::DWord S = pReloc.symValue();
1587  Relocation* dyn_rel = pParent.getRelRelMap().lookUp(pReloc);
1588  bool has_dyn_rel = (NULL != dyn_rel);
1589
1590  LDSection& target_sect = pReloc.targetRef().frag()->getParent()->getSection();
1591  // If the flag of target section is not ALLOC, we will not scan this relocation
1592  // but perform static relocation. (e.g., applying .debug section)
1593  if (0x0 == (llvm::ELF::SHF_ALLOC & target_sect.flag())) {
1594    pReloc.target() = S + A;
1595    return Relocator::OK;
1596  }
1597
1598  // A local symbol may need RELA Type dynamic relocation
1599  if (rsym->isLocal() && has_dyn_rel) {
1600    dyn_rel->setAddend(S + A);
1601    return Relocator::OK;
1602  }
1603
1604  // An external symbol may need PLT and dynamic relocation
1605  if (!rsym->isLocal()) {
1606    if (rsym->reserved() & X86Relocator::ReservePLT) {
1607      S = helper_get_PLT_address(*rsym, pParent);
1608    }
1609    // If we generate a dynamic relocation (except R_X86_64_RELATIVE)
1610    // for a place, we should not perform static relocation on it
1611    // in order to keep the addend store in the place correct.
1612    if (has_dyn_rel) {
1613      if (llvm::ELF::R_X86_64_64 == pReloc.type() &&
1614          helper_use_relative_reloc(*rsym, pParent)) {
1615        dyn_rel->setAddend(S + A);
1616      }
1617      else {
1618        dyn_rel->setAddend(A);
1619        return Relocator::OK;
1620      }
1621    }
1622  }
1623
1624  // perform static relocation
1625  pReloc.target() = S + A;
1626  return Relocator::OK;
1627}
1628
1629// R_X86_64_32S: S + A
1630Relocator::Result signed32(Relocation& pReloc, X86_64Relocator& pParent)
1631{
1632  ResolveInfo* rsym = pReloc.symInfo();
1633  Relocator::DWord A = pReloc.target() + pReloc.addend();
1634  Relocator::DWord S = pReloc.symValue();
1635
1636  // There should be no dynamic relocations for R_X86_64_32S.
1637  if (NULL != pParent.getRelRelMap().lookUp(pReloc))
1638    return Relocator::BadReloc;
1639
1640  LDSection& target_sect = pReloc.targetRef().frag()->getParent()->getSection();
1641  // If the flag of target section is not ALLOC, we will not scan this relocation
1642  // but perform static relocation. (e.g., applying .debug section)
1643  // An external symbol may need PLT and dynamic relocation
1644  if (0x0 != (llvm::ELF::SHF_ALLOC & target_sect.flag()) &&
1645      !rsym->isLocal() && rsym->reserved() & X86Relocator::ReservePLT)
1646    S = helper_get_PLT_address(*rsym, pParent);
1647
1648#if notyet
1649  // Check 32-bit signed overflow.
1650  Relocator::SWord V = S + A;
1651  if (V > INT64_C(0x7fffffff) || V < INT64_C(-0x80000000))
1652    return Relocator::Overflow;
1653#endif
1654
1655  // perform static relocation
1656  pReloc.target() = S + A;
1657  return Relocator::OK;
1658}
1659
1660// R_X86_64_GOTPCREL: GOT(S) + GOT_ORG + A - P
1661Relocator::Result gotpcrel(Relocation& pReloc, X86_64Relocator& pParent)
1662{
1663  if (!(pReloc.symInfo()->reserved() & X86Relocator::ReserveGOT)) {
1664    return Relocator::BadReloc;
1665  }
1666
1667  // set symbol value of the got entry if needed
1668  X86_64GOTEntry* got_entry = pParent.getSymGOTMap().lookUp(*pReloc.symInfo());
1669  if (X86Relocator::SymVal == got_entry->getValue())
1670    got_entry->setValue(pReloc.symValue());
1671
1672  // setup relocation addend if needed
1673  Relocation* dyn_rel = pParent.getRelRelMap().lookUp(pReloc);
1674  if ((NULL != dyn_rel) && (X86Relocator::SymVal == dyn_rel->addend())) {
1675    dyn_rel->setAddend(pReloc.symValue());
1676  }
1677
1678  Relocator::Address GOT_S   = helper_get_GOT_address(pReloc, pParent);
1679  Relocator::DWord      A    = pReloc.target() + pReloc.addend();
1680  Relocator::Address GOT_ORG = helper_GOT_ORG(pParent);
1681  // Apply relocation.
1682  pReloc.target() = GOT_S + GOT_ORG + A - pReloc.place();
1683  return Relocator::OK;
1684}
1685
1686// R_X86_64_PLT32: PLT(S) + A - P
1687Relocator::Result plt32(Relocation& pReloc, X86_64Relocator& pParent)
1688{
1689  // PLT_S depends on if there is a PLT entry.
1690  Relocator::Address PLT_S;
1691  if ((pReloc.symInfo()->reserved() & X86Relocator::ReservePLT))
1692    PLT_S = helper_get_PLT_address(*pReloc.symInfo(), pParent);
1693  else
1694    PLT_S = pReloc.symValue();
1695  Relocator::DWord   A = pReloc.target() + pReloc.addend();
1696  Relocator::Address P = pReloc.place();
1697  pReloc.target() = PLT_S + A - P;
1698  return Relocator::OK;
1699}
1700
1701// R_X86_64_PC32: S + A - P
1702// R_X86_64_PC16
1703// R_X86_64_PC8
1704Relocator::Result rel(Relocation& pReloc, X86_64Relocator& pParent)
1705{
1706  ResolveInfo* rsym = pReloc.symInfo();
1707  Relocator::DWord A = pReloc.target() + pReloc.addend();
1708  Relocator::DWord S = pReloc.symValue();
1709  Relocator::DWord P = pReloc.place();
1710
1711  LDSection& target_sect = pReloc.targetRef().frag()->getParent()->getSection();
1712  // If the flag of target section is not ALLOC, we will not scan this relocation
1713  // but perform static relocation. (e.g., applying .debug section)
1714  if (0x0 == (llvm::ELF::SHF_ALLOC & target_sect.flag())) {
1715    pReloc.target() = S + A - P;
1716    return Relocator::OK;
1717  }
1718
1719  // setup relocation addend if needed
1720  Relocation* dyn_rel = pParent.getRelRelMap().lookUp(pReloc);
1721  if ((NULL != dyn_rel) && (X86Relocator::SymVal == dyn_rel->addend())) {
1722    dyn_rel->setAddend(S);
1723  }
1724
1725  // An external symbol may need PLT and dynamic relocation
1726  if (!rsym->isLocal()) {
1727    if (rsym->reserved() & X86Relocator::ReservePLT) {
1728       S = helper_get_PLT_address(*rsym, pParent);
1729    }
1730    if (pParent.getTarget().symbolNeedsDynRel(
1731                              *rsym,
1732                              (rsym->reserved() & X86Relocator::ReservePLT),
1733                              false)) {
1734      return Relocator::Overflow;
1735    }
1736  }
1737
1738   // perform static relocation
1739  pReloc.target() = S + A - P;
1740  return Relocator::OK;
1741}
1742
1743Relocator::Result unsupport(Relocation& pReloc, X86_64Relocator& pParent)
1744{
1745  return Relocator::Unsupport;
1746}
1747