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