1//===- ELFWriter.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 <llvm/Support/ELF.h>
10#include <llvm/Support/ErrorHandling.h>
11#include <llvm/MC/MCAssembler.h>
12#include <mcld/ADT/SizeTraits.h>
13#include <mcld/Support/MemoryRegion.h>
14#include <mcld/MC/MCLDInfo.h>
15#include <mcld/MC/MCLinker.h>
16#include <mcld/MC/MCRegionFragment.h>
17#include <mcld/LD/ELFWriter.h>
18#include <mcld/LD/LDSymbol.h>
19#include <mcld/LD/LDSection.h>
20#include <mcld/LD/Layout.h>
21#include <mcld/Target/GNULDBackend.h>
22#include <cstdlib>
23#include <cstring>
24
25using namespace llvm::ELF;
26using namespace mcld;
27
28/// writeELF32Header - write ELF header
29void ELFWriter::writeELF32Header(const MCLDInfo& pLDInfo,
30                                 const Layout& pLayout,
31                                 const GNULDBackend& pBackend,
32                                 Output& pOutput) const
33{
34    assert(pOutput.hasMemArea());
35
36    // ELF header must start from 0x0
37    MemoryRegion *region = pOutput.memArea()->request(0,
38                                                      sizeof(Elf32_Ehdr));
39    Elf32_Ehdr* header = (Elf32_Ehdr*)region->start();
40
41    memcpy(header->e_ident, ElfMagic, EI_MAG3+1);
42
43    header->e_ident[EI_CLASS]      = ELFCLASS32;
44    header->e_ident[EI_DATA]       = pBackend.isLittleEndian()?
45                                       ELFDATA2LSB : ELFDATA2MSB;
46    header->e_ident[EI_VERSION]    = pBackend.ELFVersion();
47    header->e_ident[EI_OSABI]      = pBackend.OSABI();
48    header->e_ident[EI_ABIVERSION] = pBackend.ABIVersion();
49
50    // FIXME: add processor-specific and core file types.
51    switch(pOutput.type()) {
52    case Output::Object:
53      header->e_type = ET_REL;
54      break;
55    case Output::DynObj:
56      header->e_type = ET_DYN;
57      break;
58    case Output::Exec:
59      header->e_type = ET_EXEC;
60      break;
61    default:
62      llvm::errs() << "unspported output file type: " << pOutput.type() << ".\n";
63      header->e_type = ET_NONE;
64    }
65    header->e_machine   = pBackend.machine();
66    header->e_version   = header->e_ident[EI_VERSION];
67    header->e_entry     = getEntryPoint(pLDInfo, pLayout, pBackend, pOutput);
68    header->e_phoff     = sizeof(Elf32_Ehdr);
69    header->e_shoff     = getELF32LastStartOffset(pOutput);
70    header->e_flags     = pBackend.flags();
71    header->e_ehsize    = sizeof(Elf32_Ehdr);
72    header->e_phentsize = sizeof(Elf32_Phdr);
73    header->e_phnum     = pBackend.numOfSegments();
74    header->e_shentsize = sizeof(Elf32_Shdr);
75    header->e_shnum     = pOutput.context()->numOfSections();
76    header->e_shstrndx  = pOutput.context()->getSectionIdx(".shstrtab");
77}
78
79/// writeELF64Header - write ELF header
80void ELFWriter::writeELF64Header(const MCLDInfo& pLDInfo,
81                                 const Layout& pLayout,
82                                 const GNULDBackend& pBackend,
83                                 Output& pOutput) const
84{
85    assert(pOutput.hasMemArea());
86
87    // ELF header must start from 0x0
88    MemoryRegion *region = pOutput.memArea()->request(0,
89                                                      sizeof(Elf64_Ehdr));
90    Elf64_Ehdr* header = (Elf64_Ehdr*)region->start();
91
92    memcpy(header->e_ident, ElfMagic, EI_MAG3+1);
93
94    header->e_ident[EI_CLASS]      = ELFCLASS64;
95    header->e_ident[EI_DATA]       = pBackend.isLittleEndian()?
96                                       ELFDATA2LSB : ELFDATA2MSB;
97    header->e_ident[EI_VERSION]    = pBackend.ELFVersion();
98    header->e_ident[EI_OSABI]      = pBackend.OSABI();
99    header->e_ident[EI_ABIVERSION] = pBackend.ABIVersion();
100
101    // FIXME: add processor-specific and core file types.
102    switch(pOutput.type()) {
103    case Output::Object:
104      header->e_type = ET_REL;
105      break;
106    case Output::DynObj:
107      header->e_type = ET_DYN;
108      break;
109    case Output::Exec:
110      header->e_type = ET_EXEC;
111      break;
112    default:
113      llvm::errs() << "unspported output file type: " << pOutput.type() << ".\n";
114      header->e_type = ET_NONE;
115    }
116    header->e_machine   = pBackend.machine();
117    header->e_version   = header->e_ident[EI_VERSION];
118    header->e_entry     = getEntryPoint(pLDInfo, pLayout, pBackend, pOutput);
119    header->e_phoff     = sizeof(Elf64_Ehdr);
120    header->e_shoff     = getELF64LastStartOffset(pOutput);
121    header->e_flags     = pBackend.flags();
122    header->e_ehsize    = sizeof(Elf64_Ehdr);
123    header->e_phentsize = sizeof(Elf64_Phdr);
124    header->e_phnum     = pBackend.numOfSegments();
125    header->e_shentsize = sizeof(Elf64_Shdr);
126    header->e_shnum     = pOutput.context()->numOfSections();
127    header->e_shstrndx  = pOutput.context()->getSectionIdx(".shstrtab");
128}
129
130/// getEntryPoint
131uint64_t ELFWriter::getEntryPoint(const MCLDInfo& pLDInfo,
132                                  const Layout& pLayout,
133                                  const GNULDBackend& pBackend,
134                                  const Output& pOutput) const
135{
136
137  llvm::StringRef entry_name;
138  if (pLDInfo.options().hasEntry())
139    entry_name = pLDInfo.options().entry();
140  else
141    entry_name = pBackend.entry();
142
143  uint64_t result = 0x0;
144
145  bool issue_warning = (pLDInfo.options().hasEntry()
146                       && (pOutput.type() != Output::Object)
147                       && (pOutput.type() != Output::DynObj));
148
149  const LDSymbol* entry_symbol = pLDInfo.getStrSymPool().findSymbol(entry_name);
150
151  // found the symbol
152  if (NULL != entry_symbol) {
153    if (entry_symbol->desc() != ResolveInfo::Define && issue_warning) {
154      llvm::errs() << "WARNING: entry symbol '"
155                   << entry_symbol->name()
156                   << "' exists but is not defined.\n";
157    }
158    result = entry_symbol->value();
159  }
160  // not in the symbol pool
161  else {
162    // We should parse entry as a number.
163    // @ref GNU ld manual, Options -e. e.g., -e 0x1000.
164    char* endptr;
165    result = strtoull(entry_name.data(), &endptr, 0);
166    if (*endptr != '\0') {
167      if (issue_warning) {
168        llvm::errs() << "cannot find entry symbol '"
169                     << entry_name.data()
170                     << "'.\n";
171      }
172      result = 0x0;
173    }
174  }
175  return result;
176}
177
178/// emitELF32SectionHeader - emit Elf32_Shdr
179void
180ELFWriter::emitELF32SectionHeader(Output& pOutput, MCLinker& pLinker) const
181{
182  // emit section header
183  unsigned int sectNum = pOutput.context()->numOfSections();
184  unsigned int header_size = sizeof(Elf32_Shdr) * sectNum;
185  MemoryRegion* region = pOutput.memArea()->request(
186                                   getELF32LastStartOffset(pOutput),
187                                   header_size);
188  Elf32_Shdr* shdr = (Elf32_Shdr*)region->start();
189
190  // Iterate the SectionTable in LDContext
191  unsigned int sectIdx = 0;
192  unsigned int shstridx = 0; // NULL section has empty name
193  for (; sectIdx < sectNum; ++sectIdx) {
194    const LDSection *ld_sect = pOutput.context()->getSection(sectIdx);
195    shdr[sectIdx].sh_name      = shstridx;
196    shdr[sectIdx].sh_type      = ld_sect->type();
197    shdr[sectIdx].sh_flags     = ld_sect->flag();
198    shdr[sectIdx].sh_addr      = ld_sect->addr();
199    shdr[sectIdx].sh_offset    = ld_sect->offset();
200    shdr[sectIdx].sh_size      = ld_sect->size();
201    shdr[sectIdx].sh_addralign = ld_sect->align();
202    shdr[sectIdx].sh_entsize   = getELF32SectEntrySize(*ld_sect);
203    shdr[sectIdx].sh_link      = getSectLink(*ld_sect, pOutput);
204    shdr[sectIdx].sh_info      = getSectInfo(*ld_sect, pOutput);
205
206    // adjust strshidx
207    shstridx += ld_sect->name().size() + 1;
208  }
209}
210
211/// emitELF64SectionHeader - emit Elf64_Shdr
212void
213ELFWriter::emitELF64SectionHeader(Output& pOutput, MCLinker& pLinker) const
214{
215  // emit section header
216  unsigned int sectNum = pOutput.context()->numOfSections();
217  unsigned int header_size = sizeof(Elf64_Shdr) * sectNum;
218  MemoryRegion* region = pOutput.memArea()->request(
219                                     getELF64LastStartOffset(pOutput),
220                                     header_size);
221  Elf64_Shdr* shdr = (Elf64_Shdr*)region->start();
222
223  // Iterate the SectionTable in LDContext
224  unsigned int sectIdx = 0;
225  unsigned int shstridx = 0; // NULL section has empty name
226  for (; sectIdx < sectNum; ++sectIdx) {
227    const LDSection *ld_sect = pOutput.context()->getSection(sectIdx);
228    shdr[sectIdx].sh_name      = shstridx;
229    shdr[sectIdx].sh_type      = ld_sect->type();
230    shdr[sectIdx].sh_flags     = ld_sect->flag();
231    shdr[sectIdx].sh_addr      = ld_sect->addr();
232    shdr[sectIdx].sh_offset    = ld_sect->offset();
233    shdr[sectIdx].sh_size      = ld_sect->size();
234    shdr[sectIdx].sh_addralign = (ld_sect->hasSectionData())?
235                                   ld_sect->getSectionData()->getAlignment():
236                                   0x0;
237
238    shdr[sectIdx].sh_entsize   = getELF64SectEntrySize(*ld_sect);
239    shdr[sectIdx].sh_link      = getSectLink(*ld_sect, pOutput);
240    shdr[sectIdx].sh_info      = getSectInfo(*ld_sect, pOutput);
241
242    // adjust strshidx
243    shstridx += ld_sect->name().size() + 1;
244  }
245}
246
247/// emitELF32ShStrTab - emit section string table
248void ELFWriter::emitELF32ShStrTab(Output& pOutput, MCLinker& pLinker) const
249{
250  uint64_t shstroffset = getELF32LastStartOffset(pOutput);
251
252  // get shstrtab
253  LDSection& shstrtab = pLinker.getOrCreateOutputSectHdr(".shstrtab",
254                                                         LDFileFormat::NamePool,
255                                                         SHT_STRTAB,
256                                                         0x0);
257  if (0 != shstrtab.size())
258    llvm::report_fatal_error(".shstrtab has been set.\n");
259
260  // compute size
261  unsigned int shstrsize = 0;
262  LDContext::const_sect_iterator section, sectEnd = pOutput.context()->sectEnd();
263  for (section = pOutput.context()->sectBegin(); section != sectEnd; ++section) {
264    shstrsize += (*section)->name().size() + 1;
265  }
266
267  shstrtab.setSize(shstrsize);
268  shstrtab.setOffset(shstroffset);
269
270  // write out data
271  MemoryRegion* region = pOutput.memArea()->request(shstrtab.offset(),
272                                                    shstrtab.size());
273  unsigned char* data = region->start();
274  shstrsize = 0;
275  for (section = pOutput.context()->sectBegin(); section != sectEnd; ++section) {
276    strcpy((char*)(data + shstrsize), (*section)->name().c_str());
277    shstrsize += (*section)->name().size() + 1;
278  }
279
280  shstrtab.setKind(LDFileFormat::NamePool);
281  shstrtab.setType(llvm::ELF::SHT_STRTAB);
282  shstrtab.setFlag(0x0);
283  shstrtab.setAddr(0x0);
284}
285
286
287/// emitELF64ShStrTab - emit section string table
288void ELFWriter::emitELF64ShStrTab(Output& pOutput, MCLinker& pLinker) const
289{
290  uint64_t shstroffset = getELF64LastStartOffset(pOutput);
291
292  // get shstrtab
293  LDSection& shstrtab = pLinker.getOrCreateOutputSectHdr(".shstrtab",
294                                                         LDFileFormat::NamePool,
295                                                         SHT_STRTAB,
296                                                         0x0);
297  if (0 != shstrtab.size())
298    llvm::report_fatal_error(".shstrtab has been set.\n");
299
300  // compute offset
301
302  // compute size
303  unsigned int shstrsize = 0;
304  LDContext::const_sect_iterator section, sectEnd = pOutput.context()->sectEnd();
305  for (section = pOutput.context()->sectBegin(); section != sectEnd; ++section) {
306    shstrsize += (*section)->name().size() + 1;
307  }
308
309  shstrtab.setSize(shstrsize);
310  shstrtab.setOffset(shstroffset);
311
312  // write out data
313  MemoryRegion* region = pOutput.memArea()->request(shstrtab.offset(),
314                                                    shstrtab.size());
315  unsigned char* data = region->start();
316  shstrsize = 0;
317  for (section = pOutput.context()->sectBegin(); section != sectEnd; ++section) {
318    strcpy((char*)(data + shstrsize), (*section)->name().c_str());
319    shstrsize += (*section)->name().size() + 1;
320  }
321
322  shstrtab.setKind(LDFileFormat::NamePool);
323  shstrtab.setType(llvm::ELF::SHT_STRTAB);
324  shstrtab.setFlag(0x0);
325  shstrtab.setAddr(0x0);
326}
327
328/// emitSectionData
329void
330ELFWriter::emitSectionData(const Layout& pLayout,
331                           const LDSection& pSection,
332                           MemoryRegion& pRegion) const
333{
334  const llvm::MCSectionData* data = pSection.getSectionData();
335  llvm::MCSectionData::const_iterator fragIter, fragEnd = data->end();
336  size_t cur_offset = 0;
337  for (fragIter = data->begin(); fragIter != fragEnd; ++fragIter) {
338    size_t size = computeFragmentSize(pLayout, *fragIter);
339    switch(fragIter->getKind()) {
340      case llvm::MCFragment::FT_Region: {
341        const MCRegionFragment& region_frag = llvm::cast<MCRegionFragment>(*fragIter);
342        const uint8_t* from = region_frag.getRegion().start();
343        memcpy(pRegion.getBuffer(cur_offset), from, size);
344        break;
345      }
346      case llvm::MCFragment::FT_Align: {
347        // TODO: emit values with different sizes (> 1 byte), and emit nops
348        llvm::MCAlignFragment& align_frag = llvm::cast<llvm::MCAlignFragment>(*fragIter);
349        uint64_t count = size / align_frag.getValueSize();
350        switch (align_frag.getValueSize()) {
351          case 1u:
352            std::memset(pRegion.getBuffer(cur_offset),
353                        align_frag.getValue(),
354                        count);
355            break;
356          default:
357            llvm::report_fatal_error("unsupported value size for align fragment emission yet.\n");
358            break;
359        }
360        break;
361      }
362      case llvm::MCFragment::FT_Fill: {
363        llvm::MCFillFragment& fill_frag = llvm::cast<llvm::MCFillFragment>(*fragIter);
364        if (0 == size ||
365            0 == fill_frag.getValueSize() ||
366            0 == fill_frag.getSize()) {
367          // ignore virtual fillment
368          break;
369        }
370
371        uint64_t num_tiles = fill_frag.getSize() / fill_frag.getValueSize();
372        for (uint64_t i = 0; i != num_tiles; ++i) {
373          std::memset(pRegion.getBuffer(cur_offset),
374                      fill_frag.getValue(),
375                      fill_frag.getValueSize());
376        }
377        break;
378      }
379      case llvm::MCFragment::FT_Data:
380      case llvm::MCFragment::FT_Inst:
381      case llvm::MCFragment::FT_Org:
382      case llvm::MCFragment::FT_Dwarf:
383      case llvm::MCFragment::FT_DwarfFrame:
384      case llvm::MCFragment::FT_LEB: {
385        llvm::report_fatal_error("unsupported fragment yet.\n");
386        break;
387      }
388      case llvm::MCFragment::FT_Reloc:
389        llvm::report_fatal_error("relocation fragment should not be in a regular section.\n");
390        break;
391      case llvm::MCFragment::FT_Target:
392        llvm::report_fatal_error("Target fragment should not be in a regular section.\n");
393        break;
394      default:
395        llvm::report_fatal_error("invalid fragment should not be in a regular section.\n");
396        break;
397    }
398    cur_offset += size;
399  }
400}
401
402/// emitRelocation
403void ELFWriter::emitRelocation(const Layout& pLayout,
404                               const Output& pOutput,
405                               const LDSection& pSection,
406                               MemoryRegion& pRegion) const
407{
408  const llvm::MCSectionData* SectionData = pSection.getSectionData();
409  assert(SectionData && "SectionData is NULL in emitRelocation!");
410
411  if (pSection.type() == SHT_REL)
412    emitRel(pLayout, pOutput, *SectionData, pRegion);
413  else if (pSection.type() == SHT_RELA)
414    emitRela(pLayout, pOutput, *SectionData, pRegion);
415  else
416    llvm::report_fatal_error("unsupported relocation section type!");
417}
418
419
420/// emitRel
421void ELFWriter::emitRel(const Layout& pLayout,
422                        const Output& pOutput,
423                        const llvm::MCSectionData& pSectionData,
424                        MemoryRegion& pRegion) const
425{
426  Elf32_Rel* rel = reinterpret_cast<Elf32_Rel*>(pRegion.start());
427
428  Relocation* relocation = 0;
429  MCFragmentRef* FragmentRef = 0;
430
431  for (llvm::MCSectionData::const_iterator it = pSectionData.begin(),
432       ie = pSectionData.end(); it != ie; ++it, ++rel) {
433
434    relocation = &(llvm::cast<Relocation>(*it));
435    FragmentRef = &(relocation->targetRef());
436
437    if(pOutput.type() == Output::DynObj || pOutput.type() == Output::Exec) {
438      rel->r_offset = static_cast<Elf32_Addr>(
439                      llvm::cast<LDSection>(
440                      FragmentRef->frag()->getParent()->getSection()).addr() +
441                      pLayout.getOutputOffset(*FragmentRef));
442    }
443    else {
444      rel->r_offset = static_cast<Elf32_Addr>(
445                      llvm::cast<LDSection>(
446                      FragmentRef->frag()->getParent()->getSection()).offset() +
447                      pLayout.getOutputOffset(*FragmentRef));
448    }
449
450    Elf32_Word Index;
451    if( relocation->symInfo() == NULL )
452      Index = 0;
453    else
454      Index = static_cast<Elf32_Word>(
455              f_Backend.getSymbolIdx(relocation->symInfo()->outSymbol()));
456
457    rel->setSymbolAndType(Index, relocation->type());
458  }
459}
460
461/// emitRela
462void ELFWriter::emitRela(const Layout& pLayout,
463                         const Output& pOutput,
464                         const llvm::MCSectionData& pSectionData,
465                         MemoryRegion& pRegion) const
466{
467  Elf32_Rela* rel = reinterpret_cast<Elf32_Rela*>(pRegion.start());
468
469  Relocation* relocation = 0;
470  MCFragmentRef* FragmentRef = 0;
471
472  for (llvm::MCSectionData::const_iterator it = pSectionData.begin(),
473       ie = pSectionData.end(); it != ie; ++it, ++rel) {
474
475    relocation = &(llvm::cast<Relocation>(*it));
476    FragmentRef = &(relocation->targetRef());
477
478    if(pOutput.type() == Output::DynObj || pOutput.type() == Output::Exec) {
479      rel->r_offset = static_cast<Elf32_Addr>(
480                      llvm::cast<LDSection>(
481                      FragmentRef->frag()->getParent()->getSection()).addr() +
482                      pLayout.getOutputOffset(*FragmentRef));
483    }
484    else {
485      rel->r_offset = static_cast<Elf32_Addr>(
486                      llvm::cast<LDSection>(
487                      FragmentRef->frag()->getParent()->getSection()).offset() +
488                      pLayout.getOutputOffset(*FragmentRef));
489    }
490
491    Elf32_Word Index;
492    if( relocation->symInfo() == NULL )
493      Index = 0;
494    else
495      Index = static_cast<Elf32_Word>(
496              f_Backend.getSymbolIdx(relocation->symInfo()->outSymbol()));
497
498    rel->setSymbolAndType(Index, relocation->type());
499    rel->r_addend = relocation->addend();
500  }
501}
502
503/// getELF32SectEntrySize - compute Elf32_Shdr::sh_entsize
504uint64_t ELFWriter::getELF32SectEntrySize(const LDSection& pSection) const
505{
506  if (llvm::ELF::SHT_DYNSYM == pSection.type() ||
507      llvm::ELF::SHT_SYMTAB == pSection.type())
508    return sizeof(llvm::ELF::Elf32_Sym);
509  if (llvm::ELF::SHT_REL == pSection.type())
510    return sizeof(llvm::ELF::Elf32_Rel);
511  if (llvm::ELF::SHT_RELA == pSection.type())
512    return sizeof(llvm::ELF::Elf32_Rela);
513  if (llvm::ELF::SHT_HASH == pSection.type())
514    return sizeof(llvm::ELF::Elf32_Word);
515  if (llvm::ELF::SHT_DYNAMIC == pSection.type())
516    return sizeof(llvm::ELF::Elf32_Dyn);
517  return 0x0;
518}
519
520/// getELF64SectEntrySize - compute Elf64_Shdr::sh_entsize
521uint64_t ELFWriter::getELF64SectEntrySize(const LDSection& pSection) const
522{
523  if (llvm::ELF::SHT_DYNSYM == pSection.type() ||
524      llvm::ELF::SHT_SYMTAB == pSection.type())
525    return sizeof(llvm::ELF::Elf64_Sym);
526  if (llvm::ELF::SHT_REL == pSection.type())
527    return sizeof(llvm::ELF::Elf64_Rel);
528  if (llvm::ELF::SHT_RELA == pSection.type())
529    return sizeof(llvm::ELF::Elf64_Rela);
530  if (llvm::ELF::SHT_HASH == pSection.type())
531    return sizeof(llvm::ELF::Elf64_Word);
532  if (llvm::ELF::SHT_DYNAMIC == pSection.type())
533    return sizeof(llvm::ELF::Elf64_Dyn);
534  return 0x0;
535}
536
537/// getSectLink - compute ElfXX_Shdr::sh_link
538uint64_t ELFWriter::getSectLink(const LDSection& pSection, const Output& pOutput) const
539{
540  const LDContext* context = pOutput.context();
541  if (llvm::ELF::SHT_SYMTAB == pSection.type())
542    return context->getSectionIdx(".strtab");
543  if (llvm::ELF::SHT_DYNSYM == pSection.type())
544    return context->getSectionIdx(".dynstr");
545  if (llvm::ELF::SHT_DYNAMIC == pSection.type())
546    return context->getSectionIdx(".dynstr");
547  if (llvm::ELF::SHT_HASH == pSection.type())
548    return context->getSectionIdx(".dynsym");
549  if (llvm::ELF::SHT_REL == pSection.type() ||
550      llvm::ELF::SHT_RELA == pSection.type()) {
551    if (pOutput.type() == Output::Object)
552      return context->getSectionIdx(".symtab");
553    else
554      return context->getSectionIdx(".dynsym");
555  }
556  return llvm::ELF::SHN_UNDEF;
557}
558
559/// getSectInfo - compute ElfXX_Shdr::sh_info
560uint64_t ELFWriter::getSectInfo(const LDSection& pSection, const Output& pOutput) const
561{
562  const LDSection* info_link = pSection.getLink();
563  if (NULL == info_link)
564    return 0x0;
565  return info_link->index();
566}
567
568/// getELF32LastStartOffset
569uint64_t ELFWriter::getELF32LastStartOffset(const Output& pOutput) const
570{
571  LDSection* lastSect = pOutput.context()->getSectionTable().back();
572  assert(lastSect != NULL);
573  return Align<32>(lastSect->offset() + lastSect->size());
574}
575
576/// getELF64LastStartOffset
577uint64_t ELFWriter::getELF64LastStartOffset(const Output& pOutput) const
578{
579  LDSection* lastSect = pOutput.context()->getSectionTable().back();
580  assert(lastSect != NULL);
581  return Align<64>(lastSect->offset() + lastSect->size());
582}
583
584