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