1 //===- ARMLDBackend.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 "ARM.h"
10 #include "ARMGNUInfo.h"
11 #include "ARMELFDynamic.h"
12 #include "ARMLDBackend.h"
13 #include "ARMRelocator.h"
14 #include "ARMToARMStub.h"
15 #include "ARMToTHMStub.h"
16 #include "THMToTHMStub.h"
17 #include "THMToARMStub.h"
18
19 #include <cstring>
20
21 #include <llvm/ADT/Triple.h>
22 #include <llvm/ADT/Twine.h>
23 #include <llvm/Support/ELF.h>
24 #include <llvm/Support/Casting.h>
25
26 #include <mcld/IRBuilder.h>
27 #include <mcld/LinkerConfig.h>
28 #include <mcld/Fragment/FillFragment.h>
29 #include <mcld/Fragment/AlignFragment.h>
30 #include <mcld/Fragment/RegionFragment.h>
31 #include <mcld/Support/MemoryRegion.h>
32 #include <mcld/Support/MemoryArea.h>
33 #include <mcld/Support/MsgHandling.h>
34 #include <mcld/Support/TargetRegistry.h>
35 #include <mcld/Fragment/Stub.h>
36 #include <mcld/LD/BranchIslandFactory.h>
37 #include <mcld/LD/StubFactory.h>
38 #include <mcld/Object/ObjectBuilder.h>
39 #include <mcld/Fragment/NullFragment.h>
40 #include <mcld/LD/LDContext.h>
41 #include <mcld/Target/GNUInfo.h>
42
43 using namespace mcld;
44
45 //===----------------------------------------------------------------------===//
46 // ARMGNULDBackend
47 //===----------------------------------------------------------------------===//
ARMGNULDBackend(const LinkerConfig & pConfig,GNUInfo * pInfo)48 ARMGNULDBackend::ARMGNULDBackend(const LinkerConfig& pConfig, GNUInfo* pInfo)
49 : GNULDBackend(pConfig, pInfo),
50 m_pRelocator(NULL),
51 m_pGOT(NULL),
52 m_pPLT(NULL),
53 m_pRelDyn(NULL),
54 m_pRelPLT(NULL),
55 m_pDynamic(NULL),
56 m_pGOTSymbol(NULL),
57 m_pEXIDXStart(NULL),
58 m_pEXIDXEnd(NULL),
59 m_pEXIDX(NULL),
60 m_pEXTAB(NULL),
61 m_pAttributes(NULL) {
62 }
63
~ARMGNULDBackend()64 ARMGNULDBackend::~ARMGNULDBackend()
65 {
66 delete m_pRelocator;
67 delete m_pGOT;
68 delete m_pPLT;
69 delete m_pRelDyn;
70 delete m_pRelPLT;
71 delete m_pDynamic;
72 }
73
initTargetSections(Module & pModule,ObjectBuilder & pBuilder)74 void ARMGNULDBackend::initTargetSections(Module& pModule, ObjectBuilder& pBuilder)
75 {
76 // FIXME: Currently we set exidx and extab to "Exception" and directly emit
77 // them from input
78 m_pEXIDX = pBuilder.CreateSection(".ARM.exidx",
79 LDFileFormat::Target,
80 llvm::ELF::SHT_ARM_EXIDX,
81 llvm::ELF::SHF_ALLOC | llvm::ELF::SHF_LINK_ORDER,
82 config().targets().bitclass() / 8);
83 m_pEXTAB = pBuilder.CreateSection(".ARM.extab",
84 LDFileFormat::Target,
85 llvm::ELF::SHT_PROGBITS,
86 llvm::ELF::SHF_ALLOC,
87 0x1);
88 m_pAttributes = pBuilder.CreateSection(".ARM.attributes",
89 LDFileFormat::Target,
90 llvm::ELF::SHT_ARM_ATTRIBUTES,
91 0x0,
92 0x1);
93
94 if (LinkerConfig::Object != config().codeGenType()) {
95 ELFFileFormat* file_format = getOutputFormat();
96
97 // initialize .got
98 LDSection& got = file_format->getGOT();
99 m_pGOT = new ARMGOT(got);
100
101 // initialize .plt
102 LDSection& plt = file_format->getPLT();
103 m_pPLT = new ARMPLT(plt, *m_pGOT);
104
105 // initialize .rel.plt
106 LDSection& relplt = file_format->getRelPlt();
107 relplt.setLink(&plt);
108 // create SectionData and ARMRelDynSection
109 m_pRelPLT = new OutputRelocSection(pModule, relplt);
110
111 // initialize .rel.dyn
112 LDSection& reldyn = file_format->getRelDyn();
113 m_pRelDyn = new OutputRelocSection(pModule, reldyn);
114 }
115 }
116
initTargetSymbols(IRBuilder & pBuilder,Module & pModule)117 void ARMGNULDBackend::initTargetSymbols(IRBuilder& pBuilder, Module& pModule)
118 {
119 // Define the symbol _GLOBAL_OFFSET_TABLE_ if there is a symbol with the
120 // same name in input
121 m_pGOTSymbol = pBuilder.AddSymbol<IRBuilder::AsReferred, IRBuilder::Resolve>(
122 "_GLOBAL_OFFSET_TABLE_",
123 ResolveInfo::Object,
124 ResolveInfo::Define,
125 ResolveInfo::Local,
126 0x0, // size
127 0x0, // value
128 FragmentRef::Null(),
129 ResolveInfo::Hidden);
130 if (NULL != m_pEXIDX && 0x0 != m_pEXIDX->size()) {
131 FragmentRef* exidx_start =
132 FragmentRef::Create(m_pEXIDX->getSectionData()->front(), 0x0);
133 FragmentRef* exidx_end =
134 FragmentRef::Create(m_pEXIDX->getSectionData()->front(),
135 m_pEXIDX->size());
136 m_pEXIDXStart =
137 pBuilder.AddSymbol<IRBuilder::AsReferred, IRBuilder::Resolve>(
138 "__exidx_start",
139 ResolveInfo::Object,
140 ResolveInfo::Define,
141 ResolveInfo::Local,
142 0x0, // size
143 0x0, // value
144 exidx_start, // FragRef
145 ResolveInfo::Default);
146
147 m_pEXIDXEnd =
148 pBuilder.AddSymbol<IRBuilder::AsReferred, IRBuilder::Resolve>(
149 "__exidx_end",
150 ResolveInfo::Object,
151 ResolveInfo::Define,
152 ResolveInfo::Local,
153 0x0, // size
154 0x0, // value
155 exidx_end, // FragRef
156 ResolveInfo::Default);
157 // change __exidx_start/_end to local dynamic category
158 if (NULL != m_pEXIDXStart)
159 pModule.getSymbolTable().changeLocalToDynamic(*m_pEXIDXStart);
160 if (NULL != m_pEXIDXEnd)
161 pModule.getSymbolTable().changeLocalToDynamic(*m_pEXIDXEnd);
162 } else {
163 m_pEXIDXStart =
164 pBuilder.AddSymbol<IRBuilder::AsReferred, IRBuilder::Resolve>(
165 "__exidx_start",
166 ResolveInfo::NoType,
167 ResolveInfo::Define,
168 ResolveInfo::Absolute,
169 0x0, // size
170 0x0, // value
171 FragmentRef::Null(),
172 ResolveInfo::Default);
173
174 m_pEXIDXEnd =
175 pBuilder.AddSymbol<IRBuilder::AsReferred, IRBuilder::Resolve>(
176 "__exidx_end",
177 ResolveInfo::NoType,
178 ResolveInfo::Define,
179 ResolveInfo::Absolute,
180 0x0, // size
181 0x0, // value
182 FragmentRef::Null(),
183 ResolveInfo::Default);
184 }
185 }
186
initRelocator()187 bool ARMGNULDBackend::initRelocator()
188 {
189 if (NULL == m_pRelocator) {
190 m_pRelocator = new ARMRelocator(*this);
191 }
192 return true;
193 }
194
getRelocator()195 Relocator* ARMGNULDBackend::getRelocator()
196 {
197 assert(NULL != m_pRelocator);
198 return m_pRelocator;
199 }
200
doPreLayout(IRBuilder & pBuilder)201 void ARMGNULDBackend::doPreLayout(IRBuilder& pBuilder)
202 {
203 // initialize .dynamic data
204 if (!config().isCodeStatic() && NULL == m_pDynamic)
205 m_pDynamic = new ARMELFDynamic(*this, config());
206
207 // set .got size
208 // when building shared object, the .got section is must
209 if (LinkerConfig::Object != config().codeGenType()) {
210 if (LinkerConfig::DynObj == config().codeGenType() ||
211 m_pGOT->hasGOT1() ||
212 NULL != m_pGOTSymbol) {
213 m_pGOT->finalizeSectionSize();
214 defineGOTSymbol(pBuilder);
215 }
216
217 // set .plt size
218 if (m_pPLT->hasPLT1())
219 m_pPLT->finalizeSectionSize();
220
221 ELFFileFormat* file_format = getOutputFormat();
222 // set .rel.dyn size
223 if (!m_pRelDyn->empty()) {
224 assert(!config().isCodeStatic() &&
225 "static linkage should not result in a dynamic relocation section");
226 file_format->getRelDyn().setSize(
227 m_pRelDyn->numOfRelocs() * getRelEntrySize());
228 }
229
230 // set .rel.plt size
231 if (!m_pRelPLT->empty()) {
232 assert(!config().isCodeStatic() &&
233 "static linkage should not result in a dynamic relocation section");
234 file_format->getRelPlt().setSize(
235 m_pRelPLT->numOfRelocs() * getRelEntrySize());
236 }
237 }
238 }
239
doPostLayout(Module & pModule,IRBuilder & pBuilder)240 void ARMGNULDBackend::doPostLayout(Module& pModule, IRBuilder& pBuilder)
241 {
242 const ELFFileFormat *file_format = getOutputFormat();
243
244 // apply PLT
245 if (file_format->hasPLT()) {
246 // Since we already have the size of LDSection PLT, m_pPLT should not be
247 // NULL.
248 assert(NULL != m_pPLT);
249 m_pPLT->applyPLT0();
250 m_pPLT->applyPLT1();
251 }
252
253 // apply GOT
254 if (file_format->hasGOT()) {
255 // Since we already have the size of GOT, m_pGOT should not be NULL.
256 assert(NULL != m_pGOT);
257 if (LinkerConfig::DynObj == config().codeGenType())
258 m_pGOT->applyGOT0(file_format->getDynamic().addr());
259 else {
260 // executable file and object file? should fill with zero.
261 m_pGOT->applyGOT0(0);
262 }
263 }
264 }
265
266 /// dynamic - the dynamic section of the target machine.
267 /// Use co-variant return type to return its own dynamic section.
dynamic()268 ARMELFDynamic& ARMGNULDBackend::dynamic()
269 {
270 assert(NULL != m_pDynamic);
271 return *m_pDynamic;
272 }
273
274 /// dynamic - the dynamic section of the target machine.
275 /// Use co-variant return type to return its own dynamic section.
dynamic() const276 const ARMELFDynamic& ARMGNULDBackend::dynamic() const
277 {
278 assert(NULL != m_pDynamic);
279 return *m_pDynamic;
280 }
281
defineGOTSymbol(IRBuilder & pBuilder)282 void ARMGNULDBackend::defineGOTSymbol(IRBuilder& pBuilder)
283 {
284 // define symbol _GLOBAL_OFFSET_TABLE_ when .got create
285 if (m_pGOTSymbol != NULL) {
286 pBuilder.AddSymbol<IRBuilder::Force, IRBuilder::Unresolve>(
287 "_GLOBAL_OFFSET_TABLE_",
288 ResolveInfo::Object,
289 ResolveInfo::Define,
290 ResolveInfo::Local,
291 0x0, // size
292 0x0, // value
293 FragmentRef::Create(*(m_pGOT->begin()), 0x0),
294 ResolveInfo::Hidden);
295 }
296 else {
297 m_pGOTSymbol = pBuilder.AddSymbol<IRBuilder::Force, IRBuilder::Resolve>(
298 "_GLOBAL_OFFSET_TABLE_",
299 ResolveInfo::Object,
300 ResolveInfo::Define,
301 ResolveInfo::Local,
302 0x0, // size
303 0x0, // value
304 FragmentRef::Create(*(m_pGOT->begin()), 0x0),
305 ResolveInfo::Hidden);
306 }
307
308 }
309
addCopyReloc(ResolveInfo & pSym)310 void ARMGNULDBackend::addCopyReloc(ResolveInfo& pSym)
311 {
312 Relocation& rel_entry = *m_pRelDyn->consumeEntry();
313 rel_entry.setType(llvm::ELF::R_ARM_COPY);
314 assert(pSym.outSymbol()->hasFragRef());
315 rel_entry.targetRef().assign(*pSym.outSymbol()->fragRef());
316 rel_entry.setSymInfo(&pSym);
317 }
318
319 /// defineSymbolForCopyReloc
320 /// For a symbol needing copy relocation, define a copy symbol in the BSS
321 /// section and all other reference to this symbol should refer to this
322 /// copy.
323 /// This is executed at scan relocation stage.
324 LDSymbol&
defineSymbolforCopyReloc(IRBuilder & pBuilder,const ResolveInfo & pSym)325 ARMGNULDBackend::defineSymbolforCopyReloc(IRBuilder& pBuilder,
326 const ResolveInfo& pSym)
327 {
328 // get or create corresponding BSS LDSection
329 LDSection* bss_sect_hdr = NULL;
330 ELFFileFormat* file_format = getOutputFormat();
331 if (ResolveInfo::ThreadLocal == pSym.type())
332 bss_sect_hdr = &file_format->getTBSS();
333 else
334 bss_sect_hdr = &file_format->getBSS();
335
336 // get or create corresponding BSS SectionData
337 SectionData* bss_data = NULL;
338 if (bss_sect_hdr->hasSectionData())
339 bss_data = bss_sect_hdr->getSectionData();
340 else
341 bss_data = IRBuilder::CreateSectionData(*bss_sect_hdr);
342
343 // Determine the alignment by the symbol value
344 // FIXME: here we use the largest alignment
345 uint32_t addralign = config().targets().bitclass() / 8;
346
347 // allocate space in BSS for the copy symbol
348 Fragment* frag = new FillFragment(0x0, 1, pSym.size());
349 uint64_t size = ObjectBuilder::AppendFragment(*frag,
350 *bss_data,
351 addralign);
352 bss_sect_hdr->setSize(bss_sect_hdr->size() + size);
353
354 // change symbol binding to Global if it's a weak symbol
355 ResolveInfo::Binding binding = (ResolveInfo::Binding)pSym.binding();
356 if (binding == ResolveInfo::Weak)
357 binding = ResolveInfo::Global;
358
359 // Define the copy symbol in the bss section and resolve it
360 LDSymbol* cpy_sym = pBuilder.AddSymbol<IRBuilder::Force, IRBuilder::Resolve>(
361 pSym.name(),
362 (ResolveInfo::Type)pSym.type(),
363 ResolveInfo::Define,
364 binding,
365 pSym.size(), // size
366 0x0, // value
367 FragmentRef::Create(*frag, 0x0),
368 (ResolveInfo::Visibility)pSym.other());
369
370 return *cpy_sym;
371 }
372
373 /// checkValidReloc - When we attempt to generate a dynamic relocation for
374 /// ouput file, check if the relocation is supported by dynamic linker.
checkValidReloc(Relocation & pReloc) const375 void ARMGNULDBackend::checkValidReloc(Relocation& pReloc) const
376 {
377 // If not PIC object, no relocation type is invalid
378 if (!config().isCodeIndep())
379 return;
380
381 switch(pReloc.type()) {
382 case llvm::ELF::R_ARM_RELATIVE:
383 case llvm::ELF::R_ARM_COPY:
384 case llvm::ELF::R_ARM_GLOB_DAT:
385 case llvm::ELF::R_ARM_JUMP_SLOT:
386 case llvm::ELF::R_ARM_ABS32:
387 case llvm::ELF::R_ARM_ABS32_NOI:
388 case llvm::ELF::R_ARM_PC24:
389 case llvm::ELF::R_ARM_TLS_DTPMOD32:
390 case llvm::ELF::R_ARM_TLS_DTPOFF32:
391 case llvm::ELF::R_ARM_TLS_TPOFF32:
392 break;
393
394 default:
395 error(diag::non_pic_relocation) << (int)pReloc.type()
396 << pReloc.symInfo()->name();
397 break;
398 }
399 }
400
401 void
scanLocalReloc(Relocation & pReloc,const LDSection & pSection)402 ARMGNULDBackend::scanLocalReloc(Relocation& pReloc, const LDSection& pSection)
403 {
404 // rsym - The relocation target symbol
405 ResolveInfo* rsym = pReloc.symInfo();
406
407 switch(pReloc.type()){
408
409 // Set R_ARM_TARGET1 to R_ARM_ABS32
410 // Ref: GNU gold 1.11 arm.cc, line 9892
411 // FIXME: R_ARM_TARGET1 should be set by option --target1-rel
412 // or --target1-rel
413 case llvm::ELF::R_ARM_TARGET1:
414 pReloc.setType(llvm::ELF::R_ARM_ABS32);
415 case llvm::ELF::R_ARM_ABS32:
416 case llvm::ELF::R_ARM_ABS32_NOI: {
417 // If buiding PIC object (shared library or PIC executable),
418 // a dynamic relocations with RELATIVE type to this location is needed.
419 // Reserve an entry in .rel.dyn
420 if (config().isCodeIndep()) {
421 m_pRelDyn->reserveEntry();
422 // set Rel bit
423 rsym->setReserved(rsym->reserved() | ReserveRel);
424 checkAndSetHasTextRel(*pSection.getLink());
425 }
426 return;
427 }
428
429 case llvm::ELF::R_ARM_ABS16:
430 case llvm::ELF::R_ARM_ABS12:
431 case llvm::ELF::R_ARM_THM_ABS5:
432 case llvm::ELF::R_ARM_ABS8:
433 case llvm::ELF::R_ARM_BASE_ABS:
434 case llvm::ELF::R_ARM_MOVW_ABS_NC:
435 case llvm::ELF::R_ARM_MOVT_ABS:
436 case llvm::ELF::R_ARM_THM_MOVW_ABS_NC:
437 case llvm::ELF::R_ARM_THM_MOVT_ABS: {
438 // PIC code should not contain these kinds of relocation
439 if (config().isCodeIndep()) {
440 error(diag::non_pic_relocation) << (int)pReloc.type()
441 << pReloc.symInfo()->name();
442 }
443 return;
444 }
445 case llvm::ELF::R_ARM_GOTOFF32:
446 case llvm::ELF::R_ARM_GOTOFF12: {
447 // FIXME: A GOT section is needed
448 return;
449 }
450
451 // Set R_ARM_TARGET2 to R_ARM_GOT_PREL
452 // Ref: GNU gold 1.11 arm.cc, line 9892
453 // FIXME: R_ARM_TARGET2 should be set by option --target2
454 case llvm::ELF::R_ARM_TARGET2:
455 pReloc.setType(llvm::ELF::R_ARM_GOT_PREL);
456 case llvm::ELF::R_ARM_GOT_BREL:
457 case llvm::ELF::R_ARM_GOT_PREL: {
458 // A GOT entry is needed for these relocation type.
459 // return if we already create GOT for this symbol
460 if (rsym->reserved() & (ReserveGOT | GOTRel))
461 return;
462 m_pGOT->reserveGOT();
463 // If building PIC object, a dynamic relocation with
464 // type RELATIVE is needed to relocate this GOT entry.
465 // Reserve an entry in .rel.dyn
466 if (config().isCodeIndep()) {
467 // create .rel.dyn section if not exist
468 m_pRelDyn->reserveEntry();
469 // set GOTRel bit
470 rsym->setReserved(rsym->reserved() | 0x4u);
471 return;
472 }
473 // set GOT bit
474 rsym->setReserved(rsym->reserved() | 0x2u);
475 return;
476 }
477
478 case llvm::ELF::R_ARM_BASE_PREL: {
479 // FIXME: Currently we only support R_ARM_BASE_PREL against
480 // symbol _GLOBAL_OFFSET_TABLE_
481 if (rsym != m_pGOTSymbol->resolveInfo())
482 fatal(diag::base_relocation) << (int)pReloc.type() << rsym->name()
483 << "mclinker@googlegroups.com";
484 return;
485 }
486 case llvm::ELF::R_ARM_COPY:
487 case llvm::ELF::R_ARM_GLOB_DAT:
488 case llvm::ELF::R_ARM_JUMP_SLOT:
489 case llvm::ELF::R_ARM_RELATIVE: {
490 // These are relocation type for dynamic linker, shold not
491 // appear in object file.
492 fatal(diag::dynamic_relocation) << (int)pReloc.type();
493 break;
494 }
495 default: {
496 break;
497 }
498 } // end switch
499 }
500
scanGlobalReloc(Relocation & pReloc,IRBuilder & pBuilder,const LDSection & pSection)501 void ARMGNULDBackend::scanGlobalReloc(Relocation& pReloc,
502 IRBuilder& pBuilder,
503 const LDSection& pSection)
504 {
505 // rsym - The relocation target symbol
506 ResolveInfo* rsym = pReloc.symInfo();
507
508 switch(pReloc.type()) {
509
510 // Set R_ARM_TARGET1 to R_ARM_ABS32
511 // Ref: GNU gold 1.11 arm.cc, line 9892
512 // FIXME: R_ARM_TARGET1 should be set by option --target1-rel
513 // or --target1-rel
514 case llvm::ELF::R_ARM_TARGET1:
515 pReloc.setType(llvm::ELF::R_ARM_ABS32);
516 case llvm::ELF::R_ARM_ABS32:
517 case llvm::ELF::R_ARM_ABS16:
518 case llvm::ELF::R_ARM_ABS12:
519 case llvm::ELF::R_ARM_THM_ABS5:
520 case llvm::ELF::R_ARM_ABS8:
521 case llvm::ELF::R_ARM_BASE_ABS:
522 case llvm::ELF::R_ARM_MOVW_ABS_NC:
523 case llvm::ELF::R_ARM_MOVT_ABS:
524 case llvm::ELF::R_ARM_THM_MOVW_ABS_NC:
525 case llvm::ELF::R_ARM_THM_MOVT_ABS:
526 case llvm::ELF::R_ARM_ABS32_NOI: {
527 // Absolute relocation type, symbol may needs PLT entry or
528 // dynamic relocation entry
529 if (symbolNeedsPLT(*rsym)) {
530 // create plt for this symbol if it does not have one
531 if (!(rsym->reserved() & ReservePLT)){
532 // Symbol needs PLT entry, we need to reserve a PLT entry
533 // and the corresponding GOT and dynamic relocation entry
534 // in .got and .rel.plt. (GOT entry will be reserved simultaneously
535 // when calling ARMPLT->reserveEntry())
536 m_pPLT->reserveEntry();
537 m_pRelPLT->reserveEntry();
538 // set PLT bit
539 rsym->setReserved(rsym->reserved() | ReservePLT);
540 }
541 }
542
543 if (symbolNeedsDynRel(*rsym, (rsym->reserved() & ReservePLT), true)) {
544 // symbol needs dynamic relocation entry, reserve an entry in .rel.dyn
545 m_pRelDyn->reserveEntry();
546 if (symbolNeedsCopyReloc(pReloc, *rsym)) {
547 LDSymbol& cpy_sym = defineSymbolforCopyReloc(pBuilder, *rsym);
548 addCopyReloc(*cpy_sym.resolveInfo());
549 }
550 else {
551 checkValidReloc(pReloc);
552 // set Rel bit
553 rsym->setReserved(rsym->reserved() | ReserveRel);
554 checkAndSetHasTextRel(*pSection.getLink());
555 }
556 }
557 return;
558 }
559
560 case llvm::ELF::R_ARM_GOTOFF32:
561 case llvm::ELF::R_ARM_GOTOFF12: {
562 // FIXME: A GOT section is needed
563 return;
564 }
565
566 case llvm::ELF::R_ARM_BASE_PREL:
567 case llvm::ELF::R_ARM_THM_MOVW_BREL_NC:
568 case llvm::ELF::R_ARM_THM_MOVW_BREL:
569 case llvm::ELF::R_ARM_THM_MOVT_BREL:
570 // FIXME: Currently we only support these relocations against
571 // symbol _GLOBAL_OFFSET_TABLE_
572 if (rsym != m_pGOTSymbol->resolveInfo()) {
573 fatal(diag::base_relocation) << (int)pReloc.type() << rsym->name()
574 << "mclinker@googlegroups.com";
575 }
576 case llvm::ELF::R_ARM_REL32:
577 case llvm::ELF::R_ARM_LDR_PC_G0:
578 case llvm::ELF::R_ARM_SBREL32:
579 case llvm::ELF::R_ARM_THM_PC8:
580 case llvm::ELF::R_ARM_MOVW_PREL_NC:
581 case llvm::ELF::R_ARM_MOVT_PREL:
582 case llvm::ELF::R_ARM_THM_MOVW_PREL_NC:
583 case llvm::ELF::R_ARM_THM_MOVT_PREL:
584 case llvm::ELF::R_ARM_THM_ALU_PREL_11_0:
585 case llvm::ELF::R_ARM_THM_PC12:
586 case llvm::ELF::R_ARM_REL32_NOI:
587 case llvm::ELF::R_ARM_ALU_PC_G0_NC:
588 case llvm::ELF::R_ARM_ALU_PC_G0:
589 case llvm::ELF::R_ARM_ALU_PC_G1_NC:
590 case llvm::ELF::R_ARM_ALU_PC_G1:
591 case llvm::ELF::R_ARM_ALU_PC_G2:
592 case llvm::ELF::R_ARM_LDR_PC_G1:
593 case llvm::ELF::R_ARM_LDR_PC_G2:
594 case llvm::ELF::R_ARM_LDRS_PC_G0:
595 case llvm::ELF::R_ARM_LDRS_PC_G1:
596 case llvm::ELF::R_ARM_LDRS_PC_G2:
597 case llvm::ELF::R_ARM_LDC_PC_G0:
598 case llvm::ELF::R_ARM_LDC_PC_G1:
599 case llvm::ELF::R_ARM_LDC_PC_G2:
600 case llvm::ELF::R_ARM_ALU_SB_G0_NC:
601 case llvm::ELF::R_ARM_ALU_SB_G0:
602 case llvm::ELF::R_ARM_ALU_SB_G1_NC:
603 case llvm::ELF::R_ARM_ALU_SB_G1:
604 case llvm::ELF::R_ARM_ALU_SB_G2:
605 case llvm::ELF::R_ARM_LDR_SB_G0:
606 case llvm::ELF::R_ARM_LDR_SB_G1:
607 case llvm::ELF::R_ARM_LDR_SB_G2:
608 case llvm::ELF::R_ARM_LDRS_SB_G0:
609 case llvm::ELF::R_ARM_LDRS_SB_G1:
610 case llvm::ELF::R_ARM_LDRS_SB_G2:
611 case llvm::ELF::R_ARM_LDC_SB_G0:
612 case llvm::ELF::R_ARM_LDC_SB_G1:
613 case llvm::ELF::R_ARM_LDC_SB_G2:
614 case llvm::ELF::R_ARM_MOVW_BREL_NC:
615 case llvm::ELF::R_ARM_MOVT_BREL:
616 case llvm::ELF::R_ARM_MOVW_BREL: {
617 // Relative addressing relocation, may needs dynamic relocation
618 if (symbolNeedsDynRel(*rsym, (rsym->reserved() & ReservePLT), false)) {
619 // symbol needs dynamic relocation entry, reserve an entry in .rel.dyn
620 m_pRelDyn->reserveEntry();
621 if (symbolNeedsCopyReloc(pReloc, *rsym)) {
622 LDSymbol& cpy_sym = defineSymbolforCopyReloc(pBuilder, *rsym);
623 addCopyReloc(*cpy_sym.resolveInfo());
624 }
625 else {
626 checkValidReloc(pReloc);
627 // set Rel bit
628 rsym->setReserved(rsym->reserved() | ReserveRel);
629 checkAndSetHasTextRel(*pSection.getLink());
630 }
631 }
632 return;
633 }
634
635 case llvm::ELF::R_ARM_THM_CALL:
636 case llvm::ELF::R_ARM_PLT32:
637 case llvm::ELF::R_ARM_CALL:
638 case llvm::ELF::R_ARM_JUMP24:
639 case llvm::ELF::R_ARM_THM_JUMP24:
640 case llvm::ELF::R_ARM_SBREL31:
641 case llvm::ELF::R_ARM_PREL31:
642 case llvm::ELF::R_ARM_THM_JUMP19:
643 case llvm::ELF::R_ARM_THM_JUMP6:
644 case llvm::ELF::R_ARM_THM_JUMP11:
645 case llvm::ELF::R_ARM_THM_JUMP8: {
646 // These are branch relocation (except PREL31)
647 // A PLT entry is needed when building shared library
648
649 // return if we already create plt for this symbol
650 if (rsym->reserved() & ReservePLT)
651 return;
652
653 // if the symbol's value can be decided at link time, then no need plt
654 if (symbolFinalValueIsKnown(*rsym))
655 return;
656
657 // if symbol is defined in the ouput file and it's not
658 // preemptible, no need plt
659 if (rsym->isDefine() && !rsym->isDyn() &&
660 !isSymbolPreemptible(*rsym)) {
661 return;
662 }
663
664 // Symbol needs PLT entry, we need to reserve a PLT entry
665 // and the corresponding GOT and dynamic relocation entry
666 // in .got and .rel.plt. (GOT entry will be reserved simultaneously
667 // when calling ARMPLT->reserveEntry())
668 m_pPLT->reserveEntry();
669 m_pRelPLT->reserveEntry();
670 // set PLT bit
671 rsym->setReserved(rsym->reserved() | ReservePLT);
672 return;
673 }
674
675 // Set R_ARM_TARGET2 to R_ARM_GOT_PREL
676 // Ref: GNU gold 1.11 arm.cc, line 9892
677 // FIXME: R_ARM_TARGET2 should be set by option --target2
678 case llvm::ELF::R_ARM_TARGET2:
679 pReloc.setType(llvm::ELF::R_ARM_GOT_PREL);
680 case llvm::ELF::R_ARM_GOT_BREL:
681 case llvm::ELF::R_ARM_GOT_ABS:
682 case llvm::ELF::R_ARM_GOT_PREL: {
683 // Symbol needs GOT entry, reserve entry in .got
684 // return if we already create GOT for this symbol
685 if (rsym->reserved() & (ReserveGOT | GOTRel))
686 return;
687 m_pGOT->reserveGOT();
688 // if the symbol cannot be fully resolved at link time, then we need a
689 // dynamic relocation
690 if (!symbolFinalValueIsKnown(*rsym)) {
691 m_pRelDyn->reserveEntry();
692 // set GOTRel bit
693 rsym->setReserved(rsym->reserved() | GOTRel);
694 return;
695 }
696 // set GOT bit
697 rsym->setReserved(rsym->reserved() | ReserveGOT);
698 return;
699 }
700
701 case llvm::ELF::R_ARM_COPY:
702 case llvm::ELF::R_ARM_GLOB_DAT:
703 case llvm::ELF::R_ARM_JUMP_SLOT:
704 case llvm::ELF::R_ARM_RELATIVE: {
705 // These are relocation type for dynamic linker, shold not
706 // appear in object file.
707 fatal(diag::dynamic_relocation) << (int)pReloc.type();
708 break;
709 }
710 default: {
711 break;
712 }
713 } // end switch
714 }
715
scanRelocation(Relocation & pReloc,IRBuilder & pBuilder,Module & pModule,LDSection & pSection)716 void ARMGNULDBackend::scanRelocation(Relocation& pReloc,
717 IRBuilder& pBuilder,
718 Module& pModule,
719 LDSection& pSection)
720 {
721 // rsym - The relocation target symbol
722 ResolveInfo* rsym = pReloc.symInfo();
723 assert(NULL != rsym && "ResolveInfo of relocation not set while scanRelocation");
724
725 pReloc.updateAddend();
726 assert(NULL != pSection.getLink());
727 if (0 == (pSection.getLink()->flag() & llvm::ELF::SHF_ALLOC))
728 return;
729
730 // Scan relocation type to determine if an GOT/PLT/Dynamic Relocation
731 // entries should be created.
732 // FIXME: Below judgements concern nothing about TLS related relocation
733
734 // rsym is local
735 if (rsym->isLocal())
736 scanLocalReloc(pReloc, pSection);
737
738 // rsym is external
739 else
740 scanGlobalReloc(pReloc, pBuilder, pSection);
741
742 // check if we shoule issue undefined reference for the relocation target
743 // symbol
744 if (rsym->isUndef() && !rsym->isDyn() && !rsym->isWeak() && !rsym->isNull())
745 fatal(diag::undefined_reference) << rsym->name();
746 }
747
emitSectionData(const LDSection & pSection,MemoryRegion & pRegion) const748 uint64_t ARMGNULDBackend::emitSectionData(const LDSection& pSection,
749 MemoryRegion& pRegion) const
750 {
751 assert(pRegion.size() && "Size of MemoryRegion is zero!");
752
753 const ELFFileFormat* file_format = getOutputFormat();
754
755 if (&pSection == m_pAttributes ||
756 &pSection == m_pEXIDX ||
757 &pSection == m_pEXTAB) {
758 // FIXME: Currently Emitting .ARM.attributes, .ARM.exidx, and .ARM.extab
759 // directly from the input file.
760 const SectionData* sect_data = pSection.getSectionData();
761 SectionData::const_iterator frag_iter, frag_end = sect_data->end();
762 uint8_t* out_offset = pRegion.start();
763 for (frag_iter = sect_data->begin(); frag_iter != frag_end; ++frag_iter) {
764 size_t size = frag_iter->size();
765 switch(frag_iter->getKind()) {
766 case Fragment::Fillment: {
767 const FillFragment& fill_frag =
768 llvm::cast<FillFragment>(*frag_iter);
769 if (0 == fill_frag.getValueSize()) {
770 // virtual fillment, ignore it.
771 break;
772 }
773
774 memset(out_offset, fill_frag.getValue(), fill_frag.size());
775 break;
776 }
777 case Fragment::Region: {
778 const RegionFragment& region_frag =
779 llvm::cast<RegionFragment>(*frag_iter);
780 const uint8_t* start = region_frag.getRegion().start();
781 memcpy(out_offset, start, size);
782 break;
783 }
784 case Fragment::Alignment: {
785 const AlignFragment& align_frag = llvm::cast<AlignFragment>(*frag_iter);
786 uint64_t count = size / align_frag.getValueSize();
787 switch (align_frag.getValueSize()) {
788 case 1u:
789 std::memset(out_offset, align_frag.getValue(), count);
790 break;
791 default:
792 llvm::report_fatal_error(
793 "unsupported value size for align fragment emission yet.\n");
794 break;
795 } // end switch
796 break;
797 }
798 case Fragment::Null: {
799 assert(0x0 == size);
800 break;
801 }
802 default:
803 llvm::report_fatal_error("unsupported fragment type.\n");
804 break;
805 } // end switch
806 out_offset += size;
807 } // end for
808 return pRegion.size();
809 } // end if
810
811 if (&pSection == &(file_format->getPLT())) {
812 assert(NULL != m_pPLT && "emitSectionData failed, m_pPLT is NULL!");
813 uint64_t result = m_pPLT->emit(pRegion);
814 return result;
815 }
816
817 if (&pSection == &(file_format->getGOT())) {
818 assert(NULL != m_pGOT && "emitSectionData failed, m_pGOT is NULL!");
819 uint64_t result = m_pGOT->emit(pRegion);
820 return result;
821 }
822 fatal(diag::unrecognized_output_sectoin)
823 << pSection.name()
824 << "mclinker@googlegroups.com";
825 return 0x0;
826 }
827
828 /// finalizeSymbol - finalize the symbol value
finalizeTargetSymbols()829 bool ARMGNULDBackend::finalizeTargetSymbols()
830 {
831 return true;
832 }
833
mergeSection(Module & pModule,LDSection & pSection)834 bool ARMGNULDBackend::mergeSection(Module& pModule, LDSection& pSection)
835 {
836 switch (pSection.type()) {
837 case llvm::ELF::SHT_ARM_ATTRIBUTES: {
838 // FIXME: (Luba)
839 // Handle ARM attributes in the right way.
840 // In current milestone, we goes through the shortcut.
841 // It reads input's ARM attributes and copies the first ARM attributes
842 // into the output file. The correct way is merge these sections, not
843 // just copy.
844 if (0 != m_pAttributes->size())
845 return true;
846
847 // First time we meet a ARM attributes section.
848 SectionData* sd = IRBuilder::CreateSectionData(*m_pAttributes);
849 ObjectBuilder::MoveSectionData(*pSection.getSectionData(), *sd);
850 return true;
851 }
852 default: {
853 ObjectBuilder builder(config(), pModule);
854 return builder.MergeSection(pSection);
855 }
856 } // end of switch
857 return true;
858 }
859
readSection(Input & pInput,SectionData & pSD)860 bool ARMGNULDBackend::readSection(Input& pInput, SectionData& pSD)
861 {
862 Fragment* frag = NULL;
863 uint32_t offset = pInput.fileOffset() + pSD.getSection().offset();
864 uint32_t size = pSD.getSection().size();
865
866 MemoryRegion* region = pInput.memArea()->request(offset, size);
867 if (NULL == region) {
868 // If the input section's size is zero, we got a NULL region.
869 // use a virtual fill fragment
870 frag = new FillFragment(0x0, 0, 0);
871 }
872 else {
873 frag = new RegionFragment(*region);
874 }
875
876 ObjectBuilder::AppendFragment(*frag, pSD);
877 return true;
878 }
879
getGOT()880 ARMGOT& ARMGNULDBackend::getGOT()
881 {
882 assert(NULL != m_pGOT && "GOT section not exist");
883 return *m_pGOT;
884 }
885
getGOT() const886 const ARMGOT& ARMGNULDBackend::getGOT() const
887 {
888 assert(NULL != m_pGOT && "GOT section not exist");
889 return *m_pGOT;
890 }
891
getPLT()892 ARMPLT& ARMGNULDBackend::getPLT()
893 {
894 assert(NULL != m_pPLT && "PLT section not exist");
895 return *m_pPLT;
896 }
897
getPLT() const898 const ARMPLT& ARMGNULDBackend::getPLT() const
899 {
900 assert(NULL != m_pPLT && "PLT section not exist");
901 return *m_pPLT;
902 }
903
getRelDyn()904 OutputRelocSection& ARMGNULDBackend::getRelDyn()
905 {
906 assert(NULL != m_pRelDyn && ".rel.dyn section not exist");
907 return *m_pRelDyn;
908 }
909
getRelDyn() const910 const OutputRelocSection& ARMGNULDBackend::getRelDyn() const
911 {
912 assert(NULL != m_pRelDyn && ".rel.dyn section not exist");
913 return *m_pRelDyn;
914 }
915
getRelPLT()916 OutputRelocSection& ARMGNULDBackend::getRelPLT()
917 {
918 assert(NULL != m_pRelPLT && ".rel.plt section not exist");
919 return *m_pRelPLT;
920 }
921
getRelPLT() const922 const OutputRelocSection& ARMGNULDBackend::getRelPLT() const
923 {
924 assert(NULL != m_pRelPLT && ".rel.plt section not exist");
925 return *m_pRelPLT;
926 }
927
928 unsigned int
getTargetSectionOrder(const LDSection & pSectHdr) const929 ARMGNULDBackend::getTargetSectionOrder(const LDSection& pSectHdr) const
930 {
931 const ELFFileFormat* file_format = getOutputFormat();
932
933 if (&pSectHdr == &file_format->getGOT()) {
934 if (config().options().hasNow())
935 return SHO_RELRO_LAST;
936 return SHO_DATA;
937 }
938
939 if (&pSectHdr == &file_format->getPLT())
940 return SHO_PLT;
941
942 if (&pSectHdr == m_pEXIDX || &pSectHdr == m_pEXTAB) {
943 // put ARM.exidx and ARM.extab in the same order of .eh_frame
944 return SHO_EXCEPTION;
945 }
946
947 return SHO_UNDEFINED;
948 }
949
950 /// doRelax
951 bool
doRelax(Module & pModule,IRBuilder & pBuilder,bool & pFinished)952 ARMGNULDBackend::doRelax(Module& pModule, IRBuilder& pBuilder, bool& pFinished)
953 {
954 assert(NULL != getStubFactory() && NULL != getBRIslandFactory());
955
956 bool isRelaxed = false;
957 ELFFileFormat* file_format = getOutputFormat();
958 // check branch relocs and create the related stubs if needed
959 Module::obj_iterator input, inEnd = pModule.obj_end();
960 for (input = pModule.obj_begin(); input != inEnd; ++input) {
961 LDContext::sect_iterator rs, rsEnd = (*input)->context()->relocSectEnd();
962 for (rs = (*input)->context()->relocSectBegin(); rs != rsEnd; ++rs) {
963 if (LDFileFormat::Ignore == (*rs)->kind() || !(*rs)->hasRelocData())
964 continue;
965 RelocData::iterator reloc, rEnd = (*rs)->getRelocData()->end();
966 for (reloc = (*rs)->getRelocData()->begin(); reloc != rEnd; ++reloc) {
967 Relocation* relocation = llvm::cast<Relocation>(reloc);
968
969 switch (relocation->type()) {
970 case llvm::ELF::R_ARM_CALL:
971 case llvm::ELF::R_ARM_JUMP24:
972 case llvm::ELF::R_ARM_PLT32:
973 case llvm::ELF::R_ARM_THM_CALL:
974 case llvm::ELF::R_ARM_THM_XPC22:
975 case llvm::ELF::R_ARM_THM_JUMP24:
976 case llvm::ELF::R_ARM_THM_JUMP19:
977 case llvm::ELF::R_ARM_V4BX: {
978 // calculate the possible symbol value
979 uint64_t sym_value = 0x0;
980 LDSymbol* symbol = relocation->symInfo()->outSymbol();
981 if (symbol->hasFragRef()) {
982 uint64_t value = symbol->fragRef()->getOutputOffset();
983 uint64_t addr =
984 symbol->fragRef()->frag()->getParent()->getSection().addr();
985 sym_value = addr + value;
986 }
987 if (relocation->symInfo()->isGlobal() &&
988 (relocation->symInfo()->reserved() & ReservePLT) != 0x0) {
989 // FIXME: we need to find out the address of the specific plt entry
990 assert(file_format->hasPLT());
991 sym_value = file_format->getPLT().addr();
992 }
993
994 Stub* stub = getStubFactory()->create(*relocation, // relocation
995 sym_value, // symbol value
996 pBuilder,
997 *getBRIslandFactory());
998 if (NULL != stub) {
999 // a stub symbol should be local
1000 assert(NULL != stub->symInfo() && stub->symInfo()->isLocal());
1001 LDSection& symtab = file_format->getSymTab();
1002 LDSection& strtab = file_format->getStrTab();
1003
1004 // increase the size of .symtab and .strtab if needed
1005 if (config().targets().is32Bits())
1006 symtab.setSize(symtab.size() + sizeof(llvm::ELF::Elf32_Sym));
1007 else
1008 symtab.setSize(symtab.size() + sizeof(llvm::ELF::Elf64_Sym));
1009 symtab.setInfo(symtab.getInfo() + 1);
1010 strtab.setSize(strtab.size() + stub->symInfo()->nameSize() + 1);
1011
1012 isRelaxed = true;
1013 }
1014 break;
1015 }
1016 default:
1017 break;
1018 } // end of switch
1019
1020 } // for all relocations
1021 } // for all relocation section
1022 } // for all inputs
1023
1024 // find the first fragment w/ invalid offset due to stub insertion
1025 Fragment* invalid = NULL;
1026 pFinished = true;
1027 for (BranchIslandFactory::iterator island = getBRIslandFactory()->begin(),
1028 island_end = getBRIslandFactory()->end(); island != island_end; ++island) {
1029 if ((*island).end() == file_format->getText().getSectionData()->end())
1030 break;
1031
1032 Fragment* exit = (*island).end();
1033 if (((*island).offset() + (*island).size()) > exit->getOffset()) {
1034 invalid = exit;
1035 pFinished = false;
1036 break;
1037 }
1038 }
1039
1040 // reset the offset of invalid fragments
1041 while (NULL != invalid) {
1042 invalid->setOffset(invalid->getPrevNode()->getOffset() +
1043 invalid->getPrevNode()->size());
1044 invalid = invalid->getNextNode();
1045 }
1046
1047 // reset the size of .text
1048 if (isRelaxed) {
1049 file_format->getText().setSize(
1050 file_format->getText().getSectionData()->back().getOffset() +
1051 file_format->getText().getSectionData()->back().size());
1052 }
1053 return isRelaxed;
1054 }
1055
1056 /// initTargetStubs
initTargetStubs()1057 bool ARMGNULDBackend::initTargetStubs()
1058 {
1059 if (NULL != getStubFactory()) {
1060 getStubFactory()->addPrototype(new ARMToARMStub(config().isCodeIndep()));
1061 getStubFactory()->addPrototype(new ARMToTHMStub(config().isCodeIndep()));
1062 getStubFactory()->addPrototype(new THMToTHMStub(config().isCodeIndep()));
1063 getStubFactory()->addPrototype(new THMToARMStub(config().isCodeIndep()));
1064 return true;
1065 }
1066 return false;
1067 }
1068
1069 /// doCreateProgramHdrs - backend can implement this function to create the
1070 /// target-dependent segments
doCreateProgramHdrs(Module & pModule)1071 void ARMGNULDBackend::doCreateProgramHdrs(Module& pModule)
1072 {
1073 if (NULL != m_pEXIDX && 0x0 != m_pEXIDX->size()) {
1074 // make PT_ARM_EXIDX
1075 ELFSegment* exidx_seg = elfSegmentTable().produce(llvm::ELF::PT_ARM_EXIDX,
1076 llvm::ELF::PF_R);
1077 exidx_seg->addSection(m_pEXIDX);
1078 }
1079 }
1080
1081 namespace mcld {
1082
1083 //===----------------------------------------------------------------------===//
1084 /// createARMLDBackend - the help funtion to create corresponding ARMLDBackend
1085 ///
createARMLDBackend(const llvm::Target & pTarget,const LinkerConfig & pConfig)1086 TargetLDBackend* createARMLDBackend(const llvm::Target& pTarget,
1087 const LinkerConfig& pConfig)
1088 {
1089 if (pConfig.targets().triple().isOSDarwin()) {
1090 assert(0 && "MachO linker is not supported yet");
1091 /**
1092 return new ARMMachOLDBackend(createARMMachOArchiveReader,
1093 createARMMachOObjectReader,
1094 createARMMachOObjectWriter);
1095 **/
1096 }
1097 if (pConfig.targets().triple().isOSWindows()) {
1098 assert(0 && "COFF linker is not supported yet");
1099 /**
1100 return new ARMCOFFLDBackend(createARMCOFFArchiveReader,
1101 createARMCOFFObjectReader,
1102 createARMCOFFObjectWriter);
1103 **/
1104 }
1105 return new ARMGNULDBackend(pConfig, new ARMGNUInfo(pConfig.targets().triple()));
1106 }
1107
1108 } // namespace of mcld
1109
1110 //===----------------------------------------------------------------------===//
1111 // Force static initialization.
1112 //===----------------------------------------------------------------------===//
MCLDInitializeARMLDBackend()1113 extern "C" void MCLDInitializeARMLDBackend() {
1114 // Register the linker backend
1115 mcld::TargetRegistry::RegisterTargetLDBackend(TheARMTarget, createARMLDBackend);
1116 mcld::TargetRegistry::RegisterTargetLDBackend(TheThumbTarget, createARMLDBackend);
1117 }
1118
1119