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
38namespace mcld {
39
40//===----------------------------------------------------------------------===//
41// ELFObjectWriter
42//===----------------------------------------------------------------------===//
43ELFObjectWriter::ELFObjectWriter(GNULDBackend& pBackend,
44                                 const LinkerConfig& pConfig)
45    : ObjectWriter(), m_Backend(pBackend), m_Config(pConfig) {
46}
47
48ELFObjectWriter::~ELFObjectWriter() {
49}
50
51void 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
119std::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
188size_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
202template <size_t SIZE>
203void 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
261uint64_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
297template <size_t SIZE>
298void 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
332template <size_t SIZE>
333void 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
364void 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
381void 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
401void 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
448void 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
477template <size_t SIZE>
478void 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
519template <size_t SIZE>
520void 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
562template <size_t SIZE>
563uint64_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
592uint64_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
617uint64_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
633template <>
634uint64_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
641template <>
642uint64_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
649void 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