• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //===- ELFObjectWriter.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 <mcld/LD/ELFObjectWriter.h>
10 
11 #include <mcld/Module.h>
12 #include <mcld/LinkerConfig.h>
13 #include <mcld/LinkerScript.h>
14 #include <mcld/Target/GNULDBackend.h>
15 #include <mcld/Support/MsgHandling.h>
16 #include <mcld/ADT/SizeTraits.h>
17 #include <mcld/Fragment/AlignFragment.h>
18 #include <mcld/Fragment/FillFragment.h>
19 #include <mcld/Fragment/RegionFragment.h>
20 #include <mcld/Fragment/Stub.h>
21 #include <mcld/Fragment/NullFragment.h>
22 #include <mcld/LD/LDSymbol.h>
23 #include <mcld/LD/LDSection.h>
24 #include <mcld/LD/SectionData.h>
25 #include <mcld/LD/ELFSegment.h>
26 #include <mcld/LD/ELFSegmentFactory.h>
27 #include <mcld/LD/RelocData.h>
28 #include <mcld/LD/EhFrame.h>
29 #include <mcld/LD/ELFFileFormat.h>
30 #include <mcld/Target/GNUInfo.h>
31 
32 #include <llvm/Support/Errc.h>
33 #include <llvm/Support/ErrorHandling.h>
34 #include <llvm/Support/ELF.h>
35 #include <llvm/Support/Casting.h>
36 
37 using namespace llvm;
38 using namespace llvm::ELF;
39 using namespace mcld;
40 
41 //===----------------------------------------------------------------------===//
42 // ELFObjectWriter
43 //===----------------------------------------------------------------------===//
ELFObjectWriter(GNULDBackend & pBackend,const LinkerConfig & pConfig)44 ELFObjectWriter::ELFObjectWriter(GNULDBackend& pBackend,
45                                  const LinkerConfig& pConfig)
46   : ObjectWriter(), m_Backend(pBackend), m_Config(pConfig)
47 {
48 }
49 
~ELFObjectWriter()50 ELFObjectWriter::~ELFObjectWriter()
51 {
52 }
53 
writeSection(Module & pModule,FileOutputBuffer & pOutput,LDSection * section)54 void ELFObjectWriter::writeSection(Module& pModule,
55                                    FileOutputBuffer& pOutput, LDSection *section)
56 {
57   MemoryRegion region;
58   // Request output region
59   switch (section->kind()) {
60   case LDFileFormat::Note:
61     if (section->getSectionData() == NULL)
62       return;
63     // Fall through
64   case LDFileFormat::TEXT:
65   case LDFileFormat::DATA:
66   case LDFileFormat::Relocation:
67   case LDFileFormat::Target:
68   case LDFileFormat::Debug:
69   case LDFileFormat::GCCExceptTable:
70   case LDFileFormat::EhFrame: {
71     region = pOutput.request(section->offset(), section->size());
72     if (region.size() == 0) {
73       return;
74     }
75     break;
76   }
77   case LDFileFormat::Null:
78   case LDFileFormat::NamePool:
79   case LDFileFormat::BSS:
80   case LDFileFormat::MetaData:
81   case LDFileFormat::Version:
82   case LDFileFormat::EhFrameHdr:
83   case LDFileFormat::StackNote:
84     // Ignore these sections
85     return;
86   default:
87     llvm::errs() << "WARNING: unsupported section kind: "
88                  << section->kind()
89                  << " of section "
90                  << section->name()
91                  << ".\n";
92     return;
93   }
94 
95   // Write out sections with data
96   switch(section->kind()) {
97   case LDFileFormat::GCCExceptTable:
98   case LDFileFormat::TEXT:
99   case LDFileFormat::DATA:
100   case LDFileFormat::Debug:
101   case LDFileFormat::Note:
102     emitSectionData(*section, region);
103     break;
104   case LDFileFormat::EhFrame:
105     emitEhFrame(pModule, *section->getEhFrame(), region);
106     break;
107   case LDFileFormat::Relocation:
108     // sort relocation for the benefit of the dynamic linker.
109     target().sortRelocation(*section);
110 
111     emitRelocation(m_Config, *section, region);
112     break;
113   case LDFileFormat::Target:
114     target().emitSectionData(*section, region);
115     break;
116   default:
117     llvm_unreachable("invalid section kind");
118   }
119 }
120 
writeObject(Module & pModule,FileOutputBuffer & pOutput)121 std::error_code ELFObjectWriter::writeObject(Module& pModule,
122                                              FileOutputBuffer& pOutput)
123 {
124   bool is_dynobj = m_Config.codeGenType() == LinkerConfig::DynObj;
125   bool is_exec = m_Config.codeGenType() == LinkerConfig::Exec;
126   bool is_binary = m_Config.codeGenType() == LinkerConfig::Binary;
127   bool is_object = m_Config.codeGenType() == LinkerConfig::Object;
128 
129   assert(is_dynobj || is_exec || is_binary || is_object);
130 
131   if (is_dynobj || is_exec) {
132     // Allow backend to sort symbols before emitting
133     target().orderSymbolTable(pModule);
134 
135     // Write out the interpreter section: .interp
136     target().emitInterp(pOutput);
137 
138     // Write out name pool sections: .dynsym, .dynstr, .hash
139     target().emitDynNamePools(pModule, pOutput);
140   }
141 
142   if (is_object || is_dynobj || is_exec) {
143     // Write out name pool sections: .symtab, .strtab
144     target().emitRegNamePools(pModule, pOutput);
145   }
146 
147   if (is_binary) {
148     // Iterate over the loadable segments and write the corresponding sections
149     ELFSegmentFactory::iterator seg, segEnd = target().elfSegmentTable().end();
150 
151     for (seg = target().elfSegmentTable().begin(); seg != segEnd; ++seg) {
152       if (llvm::ELF::PT_LOAD == (*seg)->type()) {
153         ELFSegment::iterator sect, sectEnd = (*seg)->end();
154         for (sect = (*seg)->begin(); sect != sectEnd; ++sect)
155           writeSection(pModule, pOutput, *sect);
156       }
157     }
158   } else {
159     // Write out regular ELF sections
160     Module::iterator sect, sectEnd = pModule.end();
161     for (sect = pModule.begin(); sect != sectEnd; ++sect)
162       writeSection(pModule, pOutput, *sect);
163 
164     emitShStrTab(target().getOutputFormat()->getShStrTab(), pModule, pOutput);
165 
166     if (m_Config.targets().is32Bits()) {
167       // Write out ELF header
168       // Write out section header table
169       writeELFHeader<32>(m_Config, pModule, pOutput);
170       if (is_dynobj || is_exec)
171         emitProgramHeader<32>(pOutput);
172 
173       emitSectionHeader<32>(pModule, m_Config, pOutput);
174     }
175     else if (m_Config.targets().is64Bits()) {
176       // Write out ELF header
177       // Write out section header table
178       writeELFHeader<64>(m_Config, pModule, pOutput);
179       if (is_dynobj || is_exec)
180         emitProgramHeader<64>(pOutput);
181 
182       emitSectionHeader<64>(pModule, m_Config, pOutput);
183     }
184     else
185       return llvm::make_error_code(llvm::errc::function_not_supported);
186   }
187 
188   return std::error_code();
189 }
190 
191 // getOutputSize - count the final output size
getOutputSize(const Module & pModule) const192 size_t ELFObjectWriter::getOutputSize(const Module& pModule) const
193 {
194   if (m_Config.targets().is32Bits()) {
195     return getLastStartOffset<32>(pModule) +
196            sizeof(ELFSizeTraits<32>::Shdr) * pModule.size();
197   } else if (m_Config.targets().is64Bits()) {
198     return getLastStartOffset<64>(pModule) +
199            sizeof(ELFSizeTraits<64>::Shdr) * pModule.size();
200   } else {
201     assert(0 && "Invalid ELF Class");
202     return 0;
203   }
204 }
205 
206 // writeELFHeader - emit ElfXX_Ehdr
207 template<size_t SIZE>
writeELFHeader(const LinkerConfig & pConfig,const Module & pModule,FileOutputBuffer & pOutput) const208 void ELFObjectWriter::writeELFHeader(const LinkerConfig& pConfig,
209                                      const Module& pModule,
210                                      FileOutputBuffer& pOutput) const
211 {
212   typedef typename ELFSizeTraits<SIZE>::Ehdr ElfXX_Ehdr;
213   typedef typename ELFSizeTraits<SIZE>::Shdr ElfXX_Shdr;
214   typedef typename ELFSizeTraits<SIZE>::Phdr ElfXX_Phdr;
215 
216   // ELF header must start from 0x0
217   MemoryRegion region = pOutput.request(0, sizeof(ElfXX_Ehdr));
218   ElfXX_Ehdr* header = (ElfXX_Ehdr*)region.begin();
219 
220   memcpy(header->e_ident, ElfMagic, EI_MAG3+1);
221 
222   header->e_ident[EI_CLASS]      = (SIZE == 32) ? ELFCLASS32 : ELFCLASS64;
223   header->e_ident[EI_DATA]       = pConfig.targets().isLittleEndian()?
224                                        ELFDATA2LSB : ELFDATA2MSB;
225   header->e_ident[EI_VERSION]    = target().getInfo().ELFVersion();
226   header->e_ident[EI_OSABI]      = target().getInfo().OSABI();
227   header->e_ident[EI_ABIVERSION] = target().getInfo().ABIVersion();
228 
229   // FIXME: add processor-specific and core file types.
230   switch(pConfig.codeGenType()) {
231     case LinkerConfig::Object:
232       header->e_type = ET_REL;
233       break;
234     case LinkerConfig::DynObj:
235       header->e_type = ET_DYN;
236       break;
237     case LinkerConfig::Exec:
238       header->e_type = ET_EXEC;
239       break;
240     default:
241       llvm::errs() << "unspported output file type: " << pConfig.codeGenType() << ".\n";
242       header->e_type = ET_NONE;
243   }
244   header->e_machine   = target().getInfo().machine();
245   header->e_version   = header->e_ident[EI_VERSION];
246   header->e_entry     = getEntryPoint(pConfig, pModule);
247 
248   if (LinkerConfig::Object != pConfig.codeGenType())
249     header->e_phoff   = sizeof(ElfXX_Ehdr);
250   else
251     header->e_phoff   = 0x0;
252 
253   header->e_shoff     = getLastStartOffset<SIZE>(pModule);
254   header->e_flags     = target().getInfo().flags();
255   header->e_ehsize    = sizeof(ElfXX_Ehdr);
256   header->e_phentsize = sizeof(ElfXX_Phdr);
257   header->e_phnum     = target().elfSegmentTable().size();
258   header->e_shentsize = sizeof(ElfXX_Shdr);
259   header->e_shnum     = pModule.size();
260   header->e_shstrndx  = pModule.getSection(".shstrtab")->index();
261 }
262 
263 /// getEntryPoint
getEntryPoint(const LinkerConfig & pConfig,const Module & pModule) const264 uint64_t ELFObjectWriter::getEntryPoint(const LinkerConfig& pConfig,
265                                         const Module& pModule) const
266 {
267   llvm::StringRef entry_name = target().getEntry(pModule);
268   uint64_t result = 0x0;
269 
270   bool issue_warning = (pModule.getScript().hasEntry() &&
271                         LinkerConfig::Object != pConfig.codeGenType() &&
272                         LinkerConfig::DynObj != pConfig.codeGenType());
273 
274   const LDSymbol* entry_symbol = pModule.getNamePool().findSymbol(entry_name);
275 
276   // found the symbol
277   if (NULL != entry_symbol) {
278     if (entry_symbol->desc() != ResolveInfo::Define && issue_warning) {
279       llvm::errs() << "WARNING: entry symbol '"
280                    << entry_symbol->name()
281                    << "' exists but is not defined.\n";
282     }
283     result = entry_symbol->value();
284   }
285   // not in the symbol pool
286   else {
287     // We should parse entry as a number.
288     // @ref GNU ld manual, Options -e. e.g., -e 0x1000.
289     char* endptr;
290     result = strtoull(entry_name.data(), &endptr, 0);
291     if (*endptr != '\0') {
292       if (issue_warning) {
293         llvm::errs() << "cannot find entry symbol '"
294                      << entry_name.data()
295                      << "'.\n";
296       }
297       result = 0x0;
298     }
299   }
300   return result;
301 }
302 
303 // emitSectionHeader - emit ElfXX_Shdr
304 template<size_t SIZE>
emitSectionHeader(const Module & pModule,const LinkerConfig & pConfig,FileOutputBuffer & pOutput) const305 void ELFObjectWriter::emitSectionHeader(const Module& pModule,
306                                         const LinkerConfig& pConfig,
307                                         FileOutputBuffer& pOutput) const
308 {
309   typedef typename ELFSizeTraits<SIZE>::Shdr ElfXX_Shdr;
310 
311   // emit section header
312   unsigned int sectNum = pModule.size();
313   unsigned int header_size = sizeof(ElfXX_Shdr) * sectNum;
314   MemoryRegion region = pOutput.request(getLastStartOffset<SIZE>(pModule),
315                                         header_size);
316   ElfXX_Shdr* shdr = (ElfXX_Shdr*)region.begin();
317 
318   // Iterate the SectionTable in LDContext
319   unsigned int sectIdx = 0;
320   unsigned int shstridx = 0; // NULL section has empty name
321   for (; sectIdx < sectNum; ++sectIdx) {
322     const LDSection *ld_sect   = pModule.getSectionTable().at(sectIdx);
323     shdr[sectIdx].sh_name      = shstridx;
324     shdr[sectIdx].sh_type      = ld_sect->type();
325     shdr[sectIdx].sh_flags     = ld_sect->flag();
326     shdr[sectIdx].sh_addr      = ld_sect->addr();
327     shdr[sectIdx].sh_offset    = ld_sect->offset();
328     shdr[sectIdx].sh_size      = ld_sect->size();
329     shdr[sectIdx].sh_addralign = ld_sect->align();
330     shdr[sectIdx].sh_entsize   = getSectEntrySize<SIZE>(*ld_sect);
331     shdr[sectIdx].sh_link      = getSectLink(*ld_sect, pConfig);
332     shdr[sectIdx].sh_info      = getSectInfo(*ld_sect);
333 
334     // adjust strshidx
335     shstridx += ld_sect->name().size() + 1;
336   }
337 }
338 
339 // emitProgramHeader - emit ElfXX_Phdr
340 template<size_t SIZE>
emitProgramHeader(FileOutputBuffer & pOutput) const341 void ELFObjectWriter::emitProgramHeader(FileOutputBuffer& pOutput) const
342 {
343   typedef typename ELFSizeTraits<SIZE>::Ehdr ElfXX_Ehdr;
344   typedef typename ELFSizeTraits<SIZE>::Phdr ElfXX_Phdr;
345 
346   uint64_t start_offset, phdr_size;
347 
348   start_offset = sizeof(ElfXX_Ehdr);
349   phdr_size = sizeof(ElfXX_Phdr);
350   // Program header must start directly after ELF header
351   MemoryRegion region = pOutput.request(start_offset,
352       target().elfSegmentTable().size() * phdr_size);
353 
354   ElfXX_Phdr* phdr = (ElfXX_Phdr*)region.begin();
355 
356   // Iterate the elf segment table in GNULDBackend
357   size_t index = 0;
358   ELFSegmentFactory::const_iterator seg = target().elfSegmentTable().begin(),
359                                  segEnd = target().elfSegmentTable().end();
360   for (; seg != segEnd; ++seg, ++index) {
361     phdr[index].p_type   = (*seg)->type();
362     phdr[index].p_flags  = (*seg)->flag();
363     phdr[index].p_offset = (*seg)->offset();
364     phdr[index].p_vaddr  = (*seg)->vaddr();
365     phdr[index].p_paddr  = (*seg)->paddr();
366     phdr[index].p_filesz = (*seg)->filesz();
367     phdr[index].p_memsz  = (*seg)->memsz();
368     phdr[index].p_align  = (*seg)->align();
369   }
370 }
371 
372 /// emitShStrTab - emit section string table
373 void
emitShStrTab(const LDSection & pShStrTab,const Module & pModule,FileOutputBuffer & pOutput)374 ELFObjectWriter::emitShStrTab(const LDSection& pShStrTab,
375                               const Module& pModule,
376                               FileOutputBuffer& pOutput)
377 {
378   // write out data
379   MemoryRegion region = pOutput.request(pShStrTab.offset(), pShStrTab.size());
380   char* data = (char*)region.begin();
381   size_t shstrsize = 0;
382   Module::const_iterator section, sectEnd = pModule.end();
383   for (section = pModule.begin(); section != sectEnd; ++section) {
384     strcpy((char*)(data + shstrsize), (*section)->name().data());
385     shstrsize += (*section)->name().size() + 1;
386   }
387 }
388 
389 /// emitSectionData
390 void
emitSectionData(const LDSection & pSection,MemoryRegion & pRegion) const391 ELFObjectWriter::emitSectionData(const LDSection& pSection,
392                                  MemoryRegion& pRegion) const
393 {
394   const SectionData* sd = NULL;
395   switch (pSection.kind()) {
396     case LDFileFormat::Relocation:
397       assert(pSection.hasRelocData());
398       return;
399     case LDFileFormat::EhFrame:
400       assert(pSection.hasEhFrame());
401       sd = pSection.getEhFrame()->getSectionData();
402       break;
403     default:
404       assert(pSection.hasSectionData());
405       sd = pSection.getSectionData();
406       break;
407   }
408   emitSectionData(*sd, pRegion);
409 }
410 
411 /// emitEhFrame
emitEhFrame(Module & pModule,EhFrame & pFrame,MemoryRegion & pRegion) const412 void ELFObjectWriter::emitEhFrame(Module& pModule,
413                                   EhFrame& pFrame, MemoryRegion& pRegion) const
414 {
415   emitSectionData(*pFrame.getSectionData(), pRegion);
416 
417   // Patch FDE field (offset to CIE)
418   for (EhFrame::cie_iterator i = pFrame.cie_begin(), e = pFrame.cie_end();
419        i != e; ++i) {
420     EhFrame::CIE& cie = **i;
421     for (EhFrame::fde_iterator fi = cie.begin(), fe = cie.end();
422          fi != fe; ++fi) {
423       EhFrame::FDE& fde = **fi;
424       if (fde.getRecordType() == EhFrame::RECORD_GENERATED) {
425         // Patch PLT offset
426         LDSection* plt_sect = pModule.getSection(".plt");
427         assert (plt_sect && "We have no plt but have corresponding eh_frame?");
428         uint64_t plt_offset = plt_sect->offset();
429         // FDE entry for PLT is always 32-bit
430         uint64_t fde_offset = pFrame.getSection().offset() + fde.getOffset() +
431                               EhFrame::getDataStartOffset<32>();
432         int32_t offset = fde_offset - plt_offset;
433         if (plt_offset < fde_offset)
434           offset = -offset;
435         memcpy(pRegion.begin() + fde.getOffset() +
436                                  EhFrame::getDataStartOffset<32>(),
437                                  &offset, 4);
438         uint32_t size = plt_sect->size();
439         memcpy(pRegion.begin() + fde.getOffset() +
440                                  EhFrame::getDataStartOffset<32>() + 4,
441                                  &size, 4);
442       }
443       uint64_t fde_cie_ptr_offset = fde.getOffset() +
444                                     EhFrame::getDataStartOffset<32>() -
445                                     /*ID*/4;
446       uint64_t cie_start_offset = cie.getOffset();
447       int32_t offset = fde_cie_ptr_offset - cie_start_offset;
448       if (fde_cie_ptr_offset < cie_start_offset)
449         offset = -offset;
450       memcpy(pRegion.begin() + fde_cie_ptr_offset, &offset, 4);
451     } // for loop fde_iterator
452   } // for loop cie_iterator
453 }
454 
455 /// emitRelocation
emitRelocation(const LinkerConfig & pConfig,const LDSection & pSection,MemoryRegion & pRegion) const456 void ELFObjectWriter::emitRelocation(const LinkerConfig& pConfig,
457                                      const LDSection& pSection,
458                                      MemoryRegion& pRegion) const
459 {
460   const RelocData* sect_data = pSection.getRelocData();
461   assert(NULL != sect_data && "SectionData is NULL in emitRelocation!");
462 
463   if (pSection.type() == SHT_REL) {
464     if (pConfig.targets().is32Bits())
465       emitRel<32>(pConfig, *sect_data, pRegion);
466     else if (pConfig.targets().is64Bits())
467       emitRel<64>(pConfig, *sect_data, pRegion);
468     else {
469       fatal(diag::unsupported_bitclass) << pConfig.targets().triple().str()
470                                         << pConfig.targets().bitclass();
471     }
472   } else if (pSection.type() == SHT_RELA) {
473     if (pConfig.targets().is32Bits())
474       emitRela<32>(pConfig, *sect_data, pRegion);
475     else if (pConfig.targets().is64Bits())
476       emitRela<64>(pConfig, *sect_data, pRegion);
477     else {
478       fatal(diag::unsupported_bitclass) << pConfig.targets().triple().str()
479                                         << pConfig.targets().bitclass();
480     }
481   } else
482     llvm::report_fatal_error("unsupported relocation section type!");
483 }
484 
485 
486 // emitRel - emit ElfXX_Rel
487 template<size_t SIZE>
emitRel(const LinkerConfig & pConfig,const RelocData & pRelocData,MemoryRegion & pRegion) const488 void ELFObjectWriter::emitRel(const LinkerConfig& pConfig,
489                               const RelocData& pRelocData,
490                               MemoryRegion& pRegion) const
491 {
492   typedef typename ELFSizeTraits<SIZE>::Rel  ElfXX_Rel;
493   typedef typename ELFSizeTraits<SIZE>::Addr ElfXX_Addr;
494   typedef typename ELFSizeTraits<SIZE>::Word ElfXX_Word;
495 
496   ElfXX_Rel* rel = reinterpret_cast<ElfXX_Rel*>(pRegion.begin());
497 
498   const Relocation* relocation = 0;
499   const FragmentRef* frag_ref = 0;
500 
501   for (RelocData::const_iterator it = pRelocData.begin(),
502        ie = pRelocData.end(); it != ie; ++it, ++rel) {
503     ElfXX_Addr r_offset = 0;
504     ElfXX_Word r_sym = 0;
505 
506     relocation = &(llvm::cast<Relocation>(*it));
507     frag_ref = &(relocation->targetRef());
508 
509     if(LinkerConfig::DynObj == pConfig.codeGenType() ||
510        LinkerConfig::Exec == pConfig.codeGenType()) {
511       r_offset = static_cast<ElfXX_Addr>(
512                       frag_ref->frag()->getParent()->getSection().addr() +
513                       frag_ref->getOutputOffset());
514     }
515     else {
516       r_offset = static_cast<ElfXX_Addr>(frag_ref->getOutputOffset());
517     }
518 
519     if( relocation->symInfo() == NULL )
520       r_sym = 0;
521     else
522       r_sym = static_cast<ElfXX_Word>(
523               target().getSymbolIdx(relocation->symInfo()->outSymbol()));
524 
525     target().emitRelocation(*rel, relocation->type(), r_sym, r_offset);
526   }
527 }
528 
529 // emitRela - emit ElfXX_Rela
530 template<size_t SIZE>
emitRela(const LinkerConfig & pConfig,const RelocData & pRelocData,MemoryRegion & pRegion) const531 void ELFObjectWriter::emitRela(const LinkerConfig& pConfig,
532                                const RelocData& pRelocData,
533                                MemoryRegion& pRegion) const
534 {
535   typedef typename ELFSizeTraits<SIZE>::Rela ElfXX_Rela;
536   typedef typename ELFSizeTraits<SIZE>::Addr ElfXX_Addr;
537   typedef typename ELFSizeTraits<SIZE>::Word ElfXX_Word;
538 
539   ElfXX_Rela* rel = reinterpret_cast<ElfXX_Rela*>(pRegion.begin());
540 
541   const Relocation* relocation = 0;
542   const FragmentRef* frag_ref = 0;
543 
544   for (RelocData::const_iterator it = pRelocData.begin(),
545        ie = pRelocData.end(); it != ie; ++it, ++rel) {
546     ElfXX_Addr r_offset = 0;
547     ElfXX_Word r_sym = 0;
548 
549     relocation = &(llvm::cast<Relocation>(*it));
550     frag_ref = &(relocation->targetRef());
551 
552     if(LinkerConfig::DynObj == pConfig.codeGenType() ||
553        LinkerConfig::Exec == pConfig.codeGenType()) {
554       r_offset = static_cast<ElfXX_Addr>(
555                       frag_ref->frag()->getParent()->getSection().addr() +
556                       frag_ref->getOutputOffset());
557     }
558     else {
559       r_offset = static_cast<ElfXX_Addr>(frag_ref->getOutputOffset());
560     }
561 
562     if( relocation->symInfo() == NULL )
563       r_sym = 0;
564     else
565       r_sym = static_cast<ElfXX_Word>(
566               target().getSymbolIdx(relocation->symInfo()->outSymbol()));
567 
568     target().emitRelocation(*rel, relocation->type(),
569                             r_sym, r_offset, relocation->addend());
570   }
571 }
572 
573 
574 /// getSectEntrySize - compute ElfXX_Shdr::sh_entsize
575 template<size_t SIZE>
getSectEntrySize(const LDSection & pSection) const576 uint64_t ELFObjectWriter::getSectEntrySize(const LDSection& pSection) const
577 {
578   typedef typename ELFSizeTraits<SIZE>::Word ElfXX_Word;
579   typedef typename ELFSizeTraits<SIZE>::Sym  ElfXX_Sym;
580   typedef typename ELFSizeTraits<SIZE>::Rel  ElfXX_Rel;
581   typedef typename ELFSizeTraits<SIZE>::Rela ElfXX_Rela;
582   typedef typename ELFSizeTraits<SIZE>::Dyn  ElfXX_Dyn;
583 
584   if (llvm::ELF::SHT_DYNSYM == pSection.type() ||
585       llvm::ELF::SHT_SYMTAB == pSection.type())
586     return sizeof(ElfXX_Sym);
587   if (llvm::ELF::SHT_REL == pSection.type())
588     return sizeof(ElfXX_Rel);
589   if (llvm::ELF::SHT_RELA == pSection.type())
590     return sizeof(ElfXX_Rela);
591   if (llvm::ELF::SHT_HASH     == pSection.type() ||
592       llvm::ELF::SHT_GNU_HASH == pSection.type())
593     return sizeof(ElfXX_Word);
594   if (llvm::ELF::SHT_DYNAMIC == pSection.type())
595     return sizeof(ElfXX_Dyn);
596   // FIXME: We should get the entsize from input since the size of each
597   // character is specified in the section header's sh_entsize field.
598   // For example, traditional string is 0x1, UCS-2 is 0x2, ... and so on.
599   // Ref: http://www.sco.com/developers/gabi/2003-12-17/ch4.sheader.html
600   if (pSection.flag() & llvm::ELF::SHF_STRINGS)
601     return 0x1;
602   return 0x0;
603 }
604 
605 /// getSectLink - compute ElfXX_Shdr::sh_link
getSectLink(const LDSection & pSection,const LinkerConfig & pConfig) const606 uint64_t ELFObjectWriter::getSectLink(const LDSection& pSection,
607                                       const LinkerConfig& pConfig) const
608 {
609   if (llvm::ELF::SHT_SYMTAB == pSection.type())
610     return target().getOutputFormat()->getStrTab().index();
611   if (llvm::ELF::SHT_DYNSYM == pSection.type())
612     return target().getOutputFormat()->getDynStrTab().index();
613   if (llvm::ELF::SHT_DYNAMIC == pSection.type())
614     return target().getOutputFormat()->getDynStrTab().index();
615   if (llvm::ELF::SHT_HASH     == pSection.type() ||
616       llvm::ELF::SHT_GNU_HASH == pSection.type())
617     return target().getOutputFormat()->getDynSymTab().index();
618   if (llvm::ELF::SHT_REL == pSection.type() ||
619       llvm::ELF::SHT_RELA == pSection.type()) {
620     if (LinkerConfig::Object == pConfig.codeGenType())
621       return target().getOutputFormat()->getSymTab().index();
622     else
623       return target().getOutputFormat()->getDynSymTab().index();
624   }
625   // FIXME: currently we link ARM_EXIDX section to output text section here
626   if (llvm::ELF::SHT_ARM_EXIDX == pSection.type())
627     return target().getOutputFormat()->getText().index();
628   return llvm::ELF::SHN_UNDEF;
629 }
630 
631 /// getSectInfo - compute ElfXX_Shdr::sh_info
getSectInfo(const LDSection & pSection) const632 uint64_t ELFObjectWriter::getSectInfo(const LDSection& pSection) const
633 {
634   if (llvm::ELF::SHT_SYMTAB == pSection.type() ||
635       llvm::ELF::SHT_DYNSYM == pSection.type())
636     return pSection.getInfo();
637 
638   if (llvm::ELF::SHT_REL == pSection.type() ||
639       llvm::ELF::SHT_RELA == pSection.type()) {
640     const LDSection* info_link = pSection.getLink();
641     if (NULL != info_link)
642       return info_link->index();
643   }
644 
645   return 0x0;
646 }
647 
648 /// getLastStartOffset
649 template<>
getLastStartOffset(const Module & pModule) const650 uint64_t ELFObjectWriter::getLastStartOffset<32>(const Module& pModule) const
651 {
652   const LDSection* lastSect = pModule.back();
653   assert(lastSect != NULL);
654   return Align<32>(lastSect->offset() + lastSect->size());
655 }
656 
657 /// getLastStartOffset
658 template<>
getLastStartOffset(const Module & pModule) const659 uint64_t ELFObjectWriter::getLastStartOffset<64>(const Module& pModule) const
660 {
661   const LDSection* lastSect = pModule.back();
662   assert(lastSect != NULL);
663   return Align<64>(lastSect->offset() + lastSect->size());
664 }
665 
666 /// emitSectionData
emitSectionData(const SectionData & pSD,MemoryRegion & pRegion) const667 void ELFObjectWriter::emitSectionData(const SectionData& pSD,
668                                       MemoryRegion& pRegion) const
669 {
670   SectionData::const_iterator fragIter, fragEnd = pSD.end();
671   size_t cur_offset = 0;
672   for (fragIter = pSD.begin(); fragIter != fragEnd; ++fragIter) {
673     size_t size = fragIter->size();
674     switch(fragIter->getKind()) {
675       case Fragment::Region: {
676         const RegionFragment& region_frag = llvm::cast<RegionFragment>(*fragIter);
677         const char* from = region_frag.getRegion().begin();
678         memcpy(pRegion.begin() + cur_offset, from, size);
679         break;
680       }
681       case Fragment::Alignment: {
682         // TODO: emit values with different sizes (> 1 byte), and emit nops
683         const AlignFragment& align_frag = llvm::cast<AlignFragment>(*fragIter);
684         uint64_t count = size / align_frag.getValueSize();
685         switch (align_frag.getValueSize()) {
686           case 1u:
687             std::memset(pRegion.begin() + cur_offset,
688                         align_frag.getValue(),
689                         count);
690             break;
691           default:
692             llvm::report_fatal_error("unsupported value size for align fragment emission yet.\n");
693             break;
694         }
695         break;
696       }
697       case Fragment::Fillment: {
698         const FillFragment& fill_frag = llvm::cast<FillFragment>(*fragIter);
699         if (0 == size ||
700             0 == fill_frag.getValueSize() ||
701             0 == fill_frag.size()) {
702           // ignore virtual fillment
703           break;
704         }
705 
706         uint64_t num_tiles = fill_frag.size() / fill_frag.getValueSize();
707         for (uint64_t i = 0; i != num_tiles; ++i) {
708           std::memset(pRegion.begin() + cur_offset,
709                       fill_frag.getValue(),
710                       fill_frag.getValueSize());
711         }
712         break;
713       }
714       case Fragment::Stub: {
715         const Stub& stub_frag = llvm::cast<Stub>(*fragIter);
716         memcpy(pRegion.begin() + cur_offset, stub_frag.getContent(), size);
717         break;
718       }
719       case Fragment::Null: {
720         assert(0x0 == size);
721         break;
722       }
723       case Fragment::Target:
724         llvm::report_fatal_error("Target fragment should not be in a regular section.\n");
725         break;
726       default:
727         llvm::report_fatal_error("invalid fragment should not be in a regular section.\n");
728         break;
729     }
730     cur_offset += size;
731   }
732 }
733 
734