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
37using namespace llvm;
38using namespace llvm::ELF;
39using namespace mcld;
40
41//===----------------------------------------------------------------------===//
42// ELFObjectWriter
43//===----------------------------------------------------------------------===//
44ELFObjectWriter::ELFObjectWriter(GNULDBackend& pBackend,
45                                 const LinkerConfig& pConfig)
46  : ObjectWriter(), m_Backend(pBackend), m_Config(pConfig)
47{
48}
49
50ELFObjectWriter::~ELFObjectWriter()
51{
52}
53
54void 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
121std::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
192size_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
207template<size_t SIZE>
208void 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
264uint64_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
304template<size_t SIZE>
305void 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
340template<size_t SIZE>
341void 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
373void
374ELFObjectWriter::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
390void
391ELFObjectWriter::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
412void 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
456void 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
487template<size_t SIZE>
488void 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
530template<size_t SIZE>
531void 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
575template<size_t SIZE>
576uint64_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
606uint64_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
632uint64_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
649template<>
650uint64_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
658template<>
659uint64_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
667void 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