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