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