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