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