• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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