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