• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //===- ELFWriter.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 
10 #include <cstdlib>
11 #include <cstring>
12 
13 #include <llvm/Support/ELF.h>
14 #include <llvm/Support/Casting.h>
15 
16 #include <mcld/ADT/SizeTraits.h>
17 #include <mcld/MC/MCLDInfo.h>
18 #include <mcld/MC/MCLinker.h>
19 #include <mcld/LD/AlignFragment.h>
20 #include <mcld/LD/FillFragment.h>
21 #include <mcld/LD/RegionFragment.h>
22 #include <mcld/LD/ELFWriter.h>
23 #include <mcld/LD/LDSymbol.h>
24 #include <mcld/LD/LDSection.h>
25 #include <mcld/LD/Layout.h>
26 #include <mcld/LD/ELFSegment.h>
27 #include <mcld/LD/ELFSegmentFactory.h>
28 #include <mcld/Target/GNULDBackend.h>
29 #include <mcld/Support/MemoryRegion.h>
30 
31 using namespace llvm::ELF;
32 using namespace mcld;
33 
34 /// writeELF32Header - write ELF header
writeELF32Header(const MCLDInfo & pLDInfo,const Layout & pLayout,const GNULDBackend & pBackend,Output & pOutput) const35 void ELFWriter::writeELF32Header(const MCLDInfo& pLDInfo,
36                                  const Layout& pLayout,
37                                  const GNULDBackend& pBackend,
38                                  Output& pOutput) const
39 {
40     assert(pOutput.hasMemArea());
41 
42     // ELF header must start from 0x0
43     MemoryRegion *region = pOutput.memArea()->request(0,
44                                                       sizeof(Elf32_Ehdr));
45     Elf32_Ehdr* header = (Elf32_Ehdr*)region->start();
46 
47     memcpy(header->e_ident, ElfMagic, EI_MAG3+1);
48 
49     header->e_ident[EI_CLASS]      = ELFCLASS32;
50     header->e_ident[EI_DATA]       = pBackend.isLittleEndian()?
51                                        ELFDATA2LSB : ELFDATA2MSB;
52     header->e_ident[EI_VERSION]    = pBackend.ELFVersion();
53     header->e_ident[EI_OSABI]      = pBackend.OSABI();
54     header->e_ident[EI_ABIVERSION] = pBackend.ABIVersion();
55 
56     // FIXME: add processor-specific and core file types.
57     switch(pOutput.type()) {
58     case Output::Object:
59       header->e_type = ET_REL;
60       break;
61     case Output::DynObj:
62       header->e_type = ET_DYN;
63       break;
64     case Output::Exec:
65       header->e_type = ET_EXEC;
66       break;
67     default:
68       llvm::errs() << "unspported output file type: " << pOutput.type() << ".\n";
69       header->e_type = ET_NONE;
70     }
71     header->e_machine   = pBackend.machine();
72     header->e_version   = header->e_ident[EI_VERSION];
73     header->e_entry     = getEntryPoint(pLDInfo, pLayout, pBackend, pOutput);
74     header->e_phoff     = sizeof(Elf32_Ehdr);
75     header->e_shoff     = getELF32LastStartOffset(pOutput);
76     header->e_flags     = pBackend.flags();
77     header->e_ehsize    = sizeof(Elf32_Ehdr);
78     header->e_phentsize = sizeof(Elf32_Phdr);
79     header->e_phnum     = pBackend.numOfSegments();
80     header->e_shentsize = sizeof(Elf32_Shdr);
81     header->e_shnum     = pOutput.context()->numOfSections();
82     header->e_shstrndx  = pOutput.context()->getSectionIdx(".shstrtab");
83 }
84 
85 /// writeELF64Header - write ELF header
writeELF64Header(const MCLDInfo & pLDInfo,const Layout & pLayout,const GNULDBackend & pBackend,Output & pOutput) const86 void ELFWriter::writeELF64Header(const MCLDInfo& pLDInfo,
87                                  const Layout& pLayout,
88                                  const GNULDBackend& pBackend,
89                                  Output& pOutput) const
90 {
91     assert(pOutput.hasMemArea());
92 
93     // ELF header must start from 0x0
94     MemoryRegion *region = pOutput.memArea()->request(0,
95                                                       sizeof(Elf64_Ehdr));
96     Elf64_Ehdr* header = (Elf64_Ehdr*)region->start();
97 
98     memcpy(header->e_ident, ElfMagic, EI_MAG3+1);
99 
100     header->e_ident[EI_CLASS]      = ELFCLASS64;
101     header->e_ident[EI_DATA]       = pBackend.isLittleEndian()?
102                                        ELFDATA2LSB : ELFDATA2MSB;
103     header->e_ident[EI_VERSION]    = pBackend.ELFVersion();
104     header->e_ident[EI_OSABI]      = pBackend.OSABI();
105     header->e_ident[EI_ABIVERSION] = pBackend.ABIVersion();
106 
107     // FIXME: add processor-specific and core file types.
108     switch(pOutput.type()) {
109     case Output::Object:
110       header->e_type = ET_REL;
111       break;
112     case Output::DynObj:
113       header->e_type = ET_DYN;
114       break;
115     case Output::Exec:
116       header->e_type = ET_EXEC;
117       break;
118     default:
119       llvm::errs() << "unspported output file type: " << pOutput.type() << ".\n";
120       header->e_type = ET_NONE;
121     }
122     header->e_machine   = pBackend.machine();
123     header->e_version   = header->e_ident[EI_VERSION];
124     header->e_entry     = getEntryPoint(pLDInfo, pLayout, pBackend, pOutput);
125     header->e_phoff     = sizeof(Elf64_Ehdr);
126     header->e_shoff     = getELF64LastStartOffset(pOutput);
127     header->e_flags     = pBackend.flags();
128     header->e_ehsize    = sizeof(Elf64_Ehdr);
129     header->e_phentsize = sizeof(Elf64_Phdr);
130     header->e_phnum     = pBackend.numOfSegments();
131     header->e_shentsize = sizeof(Elf64_Shdr);
132     header->e_shnum     = pOutput.context()->numOfSections();
133     header->e_shstrndx  = pOutput.context()->getSectionIdx(".shstrtab");
134 }
135 
136 /// getEntryPoint
getEntryPoint(const MCLDInfo & pLDInfo,const Layout & pLayout,const GNULDBackend & pBackend,const Output & pOutput) const137 uint64_t ELFWriter::getEntryPoint(const MCLDInfo& pLDInfo,
138                                   const Layout& pLayout,
139                                   const GNULDBackend& pBackend,
140                                   const Output& pOutput) const
141 {
142 
143   llvm::StringRef entry_name;
144   if (pLDInfo.options().hasEntry())
145     entry_name = pLDInfo.options().entry();
146   else
147     entry_name = pBackend.entry();
148 
149   uint64_t result = 0x0;
150 
151   bool issue_warning = (pLDInfo.options().hasEntry()
152                        && (pOutput.type() != Output::Object)
153                        && (pOutput.type() != Output::DynObj));
154 
155   const LDSymbol* entry_symbol = pLDInfo.getNamePool().findSymbol(entry_name);
156 
157   // found the symbol
158   if (NULL != entry_symbol) {
159     if (entry_symbol->desc() != ResolveInfo::Define && issue_warning) {
160       llvm::errs() << "WARNING: entry symbol '"
161                    << entry_symbol->name()
162                    << "' exists but is not defined.\n";
163     }
164     result = entry_symbol->value();
165   }
166   // not in the symbol pool
167   else {
168     // We should parse entry as a number.
169     // @ref GNU ld manual, Options -e. e.g., -e 0x1000.
170     char* endptr;
171     result = strtoull(entry_name.data(), &endptr, 0);
172     if (*endptr != '\0') {
173       if (issue_warning) {
174         llvm::errs() << "cannot find entry symbol '"
175                      << entry_name.data()
176                      << "'.\n";
177       }
178       result = 0x0;
179     }
180   }
181   return result;
182 }
183 
184 /// emitELF32SectionHeader - emit Elf32_Shdr
185 void
emitELF32SectionHeader(Output & pOutput,MCLinker & pLinker) const186 ELFWriter::emitELF32SectionHeader(Output& pOutput, MCLinker& pLinker) const
187 {
188   // emit section header
189   unsigned int sectNum = pOutput.context()->numOfSections();
190   unsigned int header_size = sizeof(Elf32_Shdr) * sectNum;
191   MemoryRegion* region = pOutput.memArea()->request(
192                                    getELF32LastStartOffset(pOutput),
193                                    header_size);
194   Elf32_Shdr* shdr = (Elf32_Shdr*)region->start();
195 
196   // Iterate the SectionTable in LDContext
197   unsigned int sectIdx = 0;
198   unsigned int shstridx = 0; // NULL section has empty name
199   for (; sectIdx < sectNum; ++sectIdx) {
200     const LDSection *ld_sect = pOutput.context()->getSection(sectIdx);
201     shdr[sectIdx].sh_name      = shstridx;
202     shdr[sectIdx].sh_type      = ld_sect->type();
203     shdr[sectIdx].sh_flags     = ld_sect->flag();
204     shdr[sectIdx].sh_addr      = ld_sect->addr();
205     shdr[sectIdx].sh_offset    = ld_sect->offset();
206     shdr[sectIdx].sh_size      = ld_sect->size();
207     shdr[sectIdx].sh_addralign = ld_sect->align();
208     shdr[sectIdx].sh_entsize   = getELF32SectEntrySize(*ld_sect);
209     shdr[sectIdx].sh_link      = getSectLink(*ld_sect, pOutput);
210     shdr[sectIdx].sh_info      = getSectInfo(*ld_sect, pOutput);
211 
212     // adjust strshidx
213     shstridx += ld_sect->name().size() + 1;
214   }
215 }
216 
217 /// emitELF64SectionHeader - emit Elf64_Shdr
218 void
emitELF64SectionHeader(Output & pOutput,MCLinker & pLinker) const219 ELFWriter::emitELF64SectionHeader(Output& pOutput, MCLinker& pLinker) const
220 {
221   // emit section header
222   unsigned int sectNum = pOutput.context()->numOfSections();
223   unsigned int header_size = sizeof(Elf64_Shdr) * sectNum;
224   MemoryRegion* region = pOutput.memArea()->request(
225                                      getELF64LastStartOffset(pOutput),
226                                      header_size);
227   Elf64_Shdr* shdr = (Elf64_Shdr*)region->start();
228 
229   // Iterate the SectionTable in LDContext
230   unsigned int sectIdx = 0;
231   unsigned int shstridx = 0; // NULL section has empty name
232   for (; sectIdx < sectNum; ++sectIdx) {
233     const LDSection *ld_sect = pOutput.context()->getSection(sectIdx);
234     shdr[sectIdx].sh_name      = shstridx;
235     shdr[sectIdx].sh_type      = ld_sect->type();
236     shdr[sectIdx].sh_flags     = ld_sect->flag();
237     shdr[sectIdx].sh_addr      = ld_sect->addr();
238     shdr[sectIdx].sh_offset    = ld_sect->offset();
239     shdr[sectIdx].sh_size      = ld_sect->size();
240     shdr[sectIdx].sh_addralign = (ld_sect->hasSectionData())?
241                                    ld_sect->getSectionData()->getAlignment():
242                                    0x0;
243 
244     shdr[sectIdx].sh_entsize   = getELF64SectEntrySize(*ld_sect);
245     shdr[sectIdx].sh_link      = getSectLink(*ld_sect, pOutput);
246     shdr[sectIdx].sh_info      = getSectInfo(*ld_sect, pOutput);
247 
248     // adjust strshidx
249     shstridx += ld_sect->name().size() + 1;
250   }
251 }
252 
253 
254 /// emitELF32ProgramHeader - emit Elf32_Phdr
emitELF32ProgramHeader(Output & pOutput,const GNULDBackend & pBackend) const255 void ELFWriter::emitELF32ProgramHeader(Output& pOutput,
256                                        const GNULDBackend& pBackend) const
257 {
258   assert(pOutput.hasMemArea());
259 
260   uint64_t start_offset, phdr_size;
261 
262   start_offset = sizeof(Elf32_Ehdr);
263   phdr_size = sizeof(Elf32_Phdr);
264   // Program header must start directly after ELF header
265   MemoryRegion *region = pOutput.memArea()->request(start_offset,
266                                           pBackend.numOfSegments() * phdr_size);
267 
268   Elf32_Phdr* phdr = (Elf32_Phdr*)region->start();
269 
270   // Iterate the elf segment table in GNULDBackend
271   size_t index = 0;
272   ELFSegmentFactory::const_iterator seg = pBackend.elfSegmentTable().begin(),
273                                  segEnd = pBackend.elfSegmentTable().end();
274   for (; seg != segEnd; ++seg, ++index) {
275     phdr[index].p_type   = (*seg).type();
276     phdr[index].p_flags  = (*seg).flag();
277     phdr[index].p_offset = (*seg).offset();
278     phdr[index].p_vaddr  = (*seg).vaddr();
279     phdr[index].p_paddr  = (*seg).paddr();
280     phdr[index].p_filesz = (*seg).filesz();
281     phdr[index].p_memsz  = (*seg).memsz();
282     phdr[index].p_align  = (*seg).align();
283   }
284 }
285 
286 /// emitELF64ProgramHeader - emit ElfR64Phdr
emitELF64ProgramHeader(Output & pOutput,const GNULDBackend & pBackend) const287 void ELFWriter::emitELF64ProgramHeader(Output& pOutput,
288                                        const GNULDBackend& pBackend) const
289 {
290   assert(pOutput.hasMemArea());
291 
292   uint64_t start_offset, phdr_size;
293 
294   start_offset = sizeof(Elf64_Ehdr);
295   phdr_size = sizeof(Elf64_Phdr);
296   // Program header must start directly after ELF header
297   MemoryRegion *region = pOutput.memArea()->request(start_offset,
298                                           pBackend.numOfSegments() * phdr_size);
299   Elf64_Phdr* phdr = (Elf64_Phdr*)region->start();
300 
301   // Iterate the elf segment table in GNULDBackend
302   size_t index = 0;
303   ELFSegmentFactory::const_iterator seg = pBackend.elfSegmentTable().begin(),
304                                  segEnd = pBackend.elfSegmentTable().end();
305   for (; seg != segEnd; ++seg, ++index) {
306     phdr[index].p_type   = (*seg).type();
307     phdr[index].p_flags  = (*seg).flag();
308     phdr[index].p_offset = (*seg).offset();
309     phdr[index].p_vaddr  = (*seg).vaddr();
310     phdr[index].p_paddr  = (*seg).paddr();
311     phdr[index].p_filesz = (*seg).filesz();
312     phdr[index].p_memsz  = (*seg).memsz();
313     phdr[index].p_align  = (*seg).align();
314   }
315 }
316 
317 /// emitELF32ShStrTab - emit section string table
emitELF32ShStrTab(Output & pOutput,MCLinker & pLinker) const318 void ELFWriter::emitELF32ShStrTab(Output& pOutput, MCLinker& pLinker) const
319 {
320   uint64_t shstroffset = getELF32LastStartOffset(pOutput);
321 
322   // get shstrtab
323   LDSection& shstrtab = pLinker.getOrCreateOutputSectHdr(".shstrtab",
324                                                          LDFileFormat::NamePool,
325                                                          SHT_STRTAB,
326                                                          0x0);
327   if (0 != shstrtab.size())
328     llvm::report_fatal_error(".shstrtab has been set.\n");
329 
330   // compute size
331   unsigned int shstrsize = 0;
332   LDContext::const_sect_iterator section, sectEnd = pOutput.context()->sectEnd();
333   for (section = pOutput.context()->sectBegin(); section != sectEnd; ++section) {
334     shstrsize += (*section)->name().size() + 1;
335   }
336 
337   shstrtab.setSize(shstrsize);
338   shstrtab.setOffset(shstroffset);
339 
340   // write out data
341   MemoryRegion* region = pOutput.memArea()->request(shstrtab.offset(),
342                                                     shstrtab.size());
343   unsigned char* data = region->start();
344   shstrsize = 0;
345   for (section = pOutput.context()->sectBegin(); section != sectEnd; ++section) {
346     strcpy((char*)(data + shstrsize), (*section)->name().c_str());
347     shstrsize += (*section)->name().size() + 1;
348   }
349 
350   shstrtab.setKind(LDFileFormat::NamePool);
351   shstrtab.setType(llvm::ELF::SHT_STRTAB);
352   shstrtab.setFlag(0x0);
353   shstrtab.setAddr(0x0);
354 }
355 
356 
357 /// emitELF64ShStrTab - emit section string table
emitELF64ShStrTab(Output & pOutput,MCLinker & pLinker) const358 void ELFWriter::emitELF64ShStrTab(Output& pOutput, MCLinker& pLinker) const
359 {
360   uint64_t shstroffset = getELF64LastStartOffset(pOutput);
361 
362   // get shstrtab
363   LDSection& shstrtab = pLinker.getOrCreateOutputSectHdr(".shstrtab",
364                                                          LDFileFormat::NamePool,
365                                                          SHT_STRTAB,
366                                                          0x0);
367   if (0 != shstrtab.size())
368     llvm::report_fatal_error(".shstrtab has been set.\n");
369 
370   // compute offset
371 
372   // compute size
373   unsigned int shstrsize = 0;
374   LDContext::const_sect_iterator section, sectEnd = pOutput.context()->sectEnd();
375   for (section = pOutput.context()->sectBegin(); section != sectEnd; ++section) {
376     shstrsize += (*section)->name().size() + 1;
377   }
378 
379   shstrtab.setSize(shstrsize);
380   shstrtab.setOffset(shstroffset);
381 
382   // write out data
383   MemoryRegion* region = pOutput.memArea()->request(shstrtab.offset(),
384                                                     shstrtab.size());
385   unsigned char* data = region->start();
386   shstrsize = 0;
387   for (section = pOutput.context()->sectBegin(); section != sectEnd; ++section) {
388     strcpy((char*)(data + shstrsize), (*section)->name().c_str());
389     shstrsize += (*section)->name().size() + 1;
390   }
391 
392   shstrtab.setKind(LDFileFormat::NamePool);
393   shstrtab.setType(llvm::ELF::SHT_STRTAB);
394   shstrtab.setFlag(0x0);
395   shstrtab.setAddr(0x0);
396 }
397 
398 /// emitSectionData
399 void
emitSectionData(const Layout & pLayout,const LDSection & pSection,MemoryRegion & pRegion) const400 ELFWriter::emitSectionData(const Layout& pLayout,
401                            const LDSection& pSection,
402                            MemoryRegion& pRegion) const
403 {
404   const SectionData* data = pSection.getSectionData();
405   SectionData::const_iterator fragIter, fragEnd = data->end();
406   size_t cur_offset = 0;
407   for (fragIter = data->begin(); fragIter != fragEnd; ++fragIter) {
408     size_t size = computeFragmentSize(pLayout, *fragIter);
409     switch(fragIter->getKind()) {
410       case Fragment::Region: {
411         const RegionFragment& region_frag = llvm::cast<RegionFragment>(*fragIter);
412         const uint8_t* from = region_frag.getRegion().start();
413         memcpy(pRegion.getBuffer(cur_offset), from, size);
414         break;
415       }
416       case Fragment::Alignment: {
417         // TODO: emit values with different sizes (> 1 byte), and emit nops
418         AlignFragment& align_frag = llvm::cast<AlignFragment>(*fragIter);
419         uint64_t count = size / align_frag.getValueSize();
420         switch (align_frag.getValueSize()) {
421           case 1u:
422             std::memset(pRegion.getBuffer(cur_offset),
423                         align_frag.getValue(),
424                         count);
425             break;
426           default:
427             llvm::report_fatal_error("unsupported value size for align fragment emission yet.\n");
428             break;
429         }
430         break;
431       }
432       case Fragment::Fillment: {
433         FillFragment& fill_frag = llvm::cast<FillFragment>(*fragIter);
434         if (0 == size ||
435             0 == fill_frag.getValueSize() ||
436             0 == fill_frag.getSize()) {
437           // ignore virtual fillment
438           break;
439         }
440 
441         uint64_t num_tiles = fill_frag.getSize() / fill_frag.getValueSize();
442         for (uint64_t i = 0; i != num_tiles; ++i) {
443           std::memset(pRegion.getBuffer(cur_offset),
444                       fill_frag.getValue(),
445                       fill_frag.getValueSize());
446         }
447         break;
448       }
449       case Fragment::Relocation:
450         llvm::report_fatal_error("relocation fragment should not be in a regular section.\n");
451         break;
452       case Fragment::Target:
453         llvm::report_fatal_error("Target fragment should not be in a regular section.\n");
454         break;
455       default:
456         llvm::report_fatal_error("invalid fragment should not be in a regular section.\n");
457         break;
458     }
459     cur_offset += size;
460   }
461 }
462 
463 /// emitRelocation
emitRelocation(const Layout & pLayout,const Output & pOutput,const LDSection & pSection,MemoryRegion & pRegion) const464 void ELFWriter::emitRelocation(const Layout& pLayout,
465                                const Output& pOutput,
466                                const LDSection& pSection,
467                                MemoryRegion& pRegion) const
468 {
469   const SectionData* sect_data = pSection.getSectionData();
470   assert(NULL != sect_data && "SectionData is NULL in emitRelocation!");
471 
472   if (pSection.type() == SHT_REL)
473     emitRel(pLayout, pOutput, *sect_data, pRegion);
474   else if (pSection.type() == SHT_RELA)
475     emitRela(pLayout, pOutput, *sect_data, pRegion);
476   else
477     llvm::report_fatal_error("unsupported relocation section type!");
478 }
479 
480 
481 /// emitRel
emitRel(const Layout & pLayout,const Output & pOutput,const SectionData & pSectionData,MemoryRegion & pRegion) const482 void ELFWriter::emitRel(const Layout& pLayout,
483                         const Output& pOutput,
484                         const SectionData& pSectionData,
485                         MemoryRegion& pRegion) const
486 {
487   Elf32_Rel* rel = reinterpret_cast<Elf32_Rel*>(pRegion.start());
488 
489   Relocation* relocation = 0;
490   FragmentRef* frag_ref = 0;
491 
492   for (SectionData::const_iterator it = pSectionData.begin(),
493        ie = pSectionData.end(); it != ie; ++it, ++rel) {
494 
495     relocation = &(llvm::cast<Relocation>(*it));
496     frag_ref = &(relocation->targetRef());
497 
498     if(pOutput.type() == Output::DynObj || pOutput.type() == Output::Exec) {
499       rel->r_offset = static_cast<Elf32_Addr>(
500                       frag_ref->frag()->getParent()->getSection().addr() +
501                       pLayout.getOutputOffset(*frag_ref));
502     }
503     else {
504       rel->r_offset = static_cast<Elf32_Addr>(
505                       frag_ref->frag()->getParent()->getSection().offset() +
506                       pLayout.getOutputOffset(*frag_ref));
507     }
508 
509     Elf32_Word Index;
510     if( relocation->symInfo() == NULL )
511       Index = 0;
512     else
513       Index = static_cast<Elf32_Word>(
514               f_Backend.getSymbolIdx(relocation->symInfo()->outSymbol()));
515 
516     rel->setSymbolAndType(Index, relocation->type());
517   }
518 }
519 
520 /// emitRela
emitRela(const Layout & pLayout,const Output & pOutput,const SectionData & pSectionData,MemoryRegion & pRegion) const521 void ELFWriter::emitRela(const Layout& pLayout,
522                          const Output& pOutput,
523                          const SectionData& pSectionData,
524                          MemoryRegion& pRegion) const
525 {
526   Elf32_Rela* rel = reinterpret_cast<Elf32_Rela*>(pRegion.start());
527 
528   Relocation* relocation = 0;
529   FragmentRef* frag_ref = 0;
530 
531   for (SectionData::const_iterator it = pSectionData.begin(),
532        ie = pSectionData.end(); it != ie; ++it, ++rel) {
533 
534     relocation = &(llvm::cast<Relocation>(*it));
535     frag_ref = &(relocation->targetRef());
536 
537     if(pOutput.type() == Output::DynObj || pOutput.type() == Output::Exec) {
538       rel->r_offset = static_cast<Elf32_Addr>(
539                       frag_ref->frag()->getParent()->getSection().addr() +
540                       pLayout.getOutputOffset(*frag_ref));
541     }
542     else {
543       rel->r_offset = static_cast<Elf32_Addr>(
544                       frag_ref->frag()->getParent()->getSection().offset() +
545                       pLayout.getOutputOffset(*frag_ref));
546     }
547 
548     Elf32_Word Index;
549     if( relocation->symInfo() == NULL )
550       Index = 0;
551     else
552       Index = static_cast<Elf32_Word>(
553               f_Backend.getSymbolIdx(relocation->symInfo()->outSymbol()));
554 
555     rel->setSymbolAndType(Index, relocation->type());
556     rel->r_addend = relocation->addend();
557   }
558 }
559 
560 /// getELF32SectEntrySize - compute Elf32_Shdr::sh_entsize
getELF32SectEntrySize(const LDSection & pSection) const561 uint64_t ELFWriter::getELF32SectEntrySize(const LDSection& pSection) const
562 {
563   if (llvm::ELF::SHT_DYNSYM == pSection.type() ||
564       llvm::ELF::SHT_SYMTAB == pSection.type())
565     return sizeof(llvm::ELF::Elf32_Sym);
566   if (llvm::ELF::SHT_REL == pSection.type())
567     return sizeof(llvm::ELF::Elf32_Rel);
568   if (llvm::ELF::SHT_RELA == pSection.type())
569     return sizeof(llvm::ELF::Elf32_Rela);
570   if (llvm::ELF::SHT_HASH == pSection.type())
571     return sizeof(llvm::ELF::Elf32_Word);
572   if (llvm::ELF::SHT_DYNAMIC == pSection.type())
573     return sizeof(llvm::ELF::Elf32_Dyn);
574   return 0x0;
575 }
576 
577 /// getELF64SectEntrySize - compute Elf64_Shdr::sh_entsize
getELF64SectEntrySize(const LDSection & pSection) const578 uint64_t ELFWriter::getELF64SectEntrySize(const LDSection& pSection) const
579 {
580   if (llvm::ELF::SHT_DYNSYM == pSection.type() ||
581       llvm::ELF::SHT_SYMTAB == pSection.type())
582     return sizeof(llvm::ELF::Elf64_Sym);
583   if (llvm::ELF::SHT_REL == pSection.type())
584     return sizeof(llvm::ELF::Elf64_Rel);
585   if (llvm::ELF::SHT_RELA == pSection.type())
586     return sizeof(llvm::ELF::Elf64_Rela);
587   if (llvm::ELF::SHT_HASH == pSection.type())
588     return sizeof(llvm::ELF::Elf64_Word);
589   if (llvm::ELF::SHT_DYNAMIC == pSection.type())
590     return sizeof(llvm::ELF::Elf64_Dyn);
591   return 0x0;
592 }
593 
594 /// getSectLink - compute ElfXX_Shdr::sh_link
getSectLink(const LDSection & pSection,const Output & pOutput) const595 uint64_t ELFWriter::getSectLink(const LDSection& pSection, const Output& pOutput) const
596 {
597   const LDContext* context = pOutput.context();
598   if (llvm::ELF::SHT_SYMTAB == pSection.type())
599     return context->getSectionIdx(".strtab");
600   if (llvm::ELF::SHT_DYNSYM == pSection.type())
601     return context->getSectionIdx(".dynstr");
602   if (llvm::ELF::SHT_DYNAMIC == pSection.type())
603     return context->getSectionIdx(".dynstr");
604   if (llvm::ELF::SHT_HASH == pSection.type())
605     return context->getSectionIdx(".dynsym");
606   if (llvm::ELF::SHT_REL == pSection.type() ||
607       llvm::ELF::SHT_RELA == pSection.type()) {
608     if (pOutput.type() == Output::Object)
609       return context->getSectionIdx(".symtab");
610     else
611       return context->getSectionIdx(".dynsym");
612   }
613   return llvm::ELF::SHN_UNDEF;
614 }
615 
616 /// getSectInfo - compute ElfXX_Shdr::sh_info
getSectInfo(const LDSection & pSection,const Output & pOutput) const617 uint64_t ELFWriter::getSectInfo(const LDSection& pSection, const Output& pOutput) const
618 {
619   const LDSection* info_link = pSection.getLink();
620   if (NULL == info_link)
621     return 0x0;
622   return info_link->index();
623 }
624 
625 /// getELF32LastStartOffset
getELF32LastStartOffset(const Output & pOutput) const626 uint64_t ELFWriter::getELF32LastStartOffset(const Output& pOutput) const
627 {
628   LDSection* lastSect = pOutput.context()->getSectionTable().back();
629   assert(lastSect != NULL);
630   return Align<32>(lastSect->offset() + lastSect->size());
631 }
632 
633 /// getELF64LastStartOffset
getELF64LastStartOffset(const Output & pOutput) const634 uint64_t ELFWriter::getELF64LastStartOffset(const Output& pOutput) const
635 {
636   LDSection* lastSect = pOutput.context()->getSectionTable().back();
637   assert(lastSect != NULL);
638   return Align<64>(lastSect->offset() + lastSect->size());
639 }
640 
641