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