15460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao//===- ELFWriter.cpp ------------------------------------------------------===//
25460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao//
35460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao//                     The MCLinker Project
45460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao//
55460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao// This file is distributed under the University of Illinois Open Source
65460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao// License. See LICENSE.TXT for details.
75460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao//
85460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao//===----------------------------------------------------------------------===//
9cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao
10cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao#include <cstdlib>
11cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao#include <cstring>
12cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao
135460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include <llvm/Support/ELF.h>
14cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao#include <llvm/Support/Casting.h>
15cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao
165460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include <mcld/ADT/SizeTraits.h>
175460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include <mcld/MC/MCLDInfo.h>
185460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include <mcld/MC/MCLinker.h>
19cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao#include <mcld/LD/AlignFragment.h>
20cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao#include <mcld/LD/FillFragment.h>
21cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao#include <mcld/LD/RegionFragment.h>
225460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include <mcld/LD/ELFWriter.h>
235460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include <mcld/LD/LDSymbol.h>
245460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include <mcld/LD/LDSection.h>
255460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include <mcld/LD/Layout.h>
26affc150dc44fab1911775a49636d0ce85333b634Zonr Chang#include <mcld/LD/ELFSegment.h>
27affc150dc44fab1911775a49636d0ce85333b634Zonr Chang#include <mcld/LD/ELFSegmentFactory.h>
285460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include <mcld/Target/GNULDBackend.h>
29cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao#include <mcld/Support/MemoryRegion.h>
305460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
315460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaousing namespace llvm::ELF;
325460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaousing namespace mcld;
335460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
345460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// writeELF32Header - write ELF header
355460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaovoid ELFWriter::writeELF32Header(const MCLDInfo& pLDInfo,
365460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                 const Layout& pLayout,
375460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                 const GNULDBackend& pBackend,
385460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                 Output& pOutput) const
395460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
405460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    assert(pOutput.hasMemArea());
415460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
425460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    // ELF header must start from 0x0
435460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    MemoryRegion *region = pOutput.memArea()->request(0,
445460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                                      sizeof(Elf32_Ehdr));
455460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    Elf32_Ehdr* header = (Elf32_Ehdr*)region->start();
465460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
475460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    memcpy(header->e_ident, ElfMagic, EI_MAG3+1);
485460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
495460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    header->e_ident[EI_CLASS]      = ELFCLASS32;
505460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    header->e_ident[EI_DATA]       = pBackend.isLittleEndian()?
515460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                       ELFDATA2LSB : ELFDATA2MSB;
525460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    header->e_ident[EI_VERSION]    = pBackend.ELFVersion();
535460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    header->e_ident[EI_OSABI]      = pBackend.OSABI();
545460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    header->e_ident[EI_ABIVERSION] = pBackend.ABIVersion();
555460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
565460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    // FIXME: add processor-specific and core file types.
575460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    switch(pOutput.type()) {
585460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case Output::Object:
595460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      header->e_type = ET_REL;
605460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      break;
615460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case Output::DynObj:
625460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      header->e_type = ET_DYN;
635460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      break;
645460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case Output::Exec:
655460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      header->e_type = ET_EXEC;
665460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      break;
675460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    default:
685460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      llvm::errs() << "unspported output file type: " << pOutput.type() << ".\n";
695460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      header->e_type = ET_NONE;
705460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    }
715460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    header->e_machine   = pBackend.machine();
725460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    header->e_version   = header->e_ident[EI_VERSION];
735460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    header->e_entry     = getEntryPoint(pLDInfo, pLayout, pBackend, pOutput);
745460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    header->e_phoff     = sizeof(Elf32_Ehdr);
755460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    header->e_shoff     = getELF32LastStartOffset(pOutput);
765460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    header->e_flags     = pBackend.flags();
775460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    header->e_ehsize    = sizeof(Elf32_Ehdr);
785460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    header->e_phentsize = sizeof(Elf32_Phdr);
795460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    header->e_phnum     = pBackend.numOfSegments();
805460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    header->e_shentsize = sizeof(Elf32_Shdr);
815460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    header->e_shnum     = pOutput.context()->numOfSections();
825460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    header->e_shstrndx  = pOutput.context()->getSectionIdx(".shstrtab");
835460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
845460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
855460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// writeELF64Header - write ELF header
865460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaovoid ELFWriter::writeELF64Header(const MCLDInfo& pLDInfo,
875460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                 const Layout& pLayout,
885460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                 const GNULDBackend& pBackend,
895460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                 Output& pOutput) const
905460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
915460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    assert(pOutput.hasMemArea());
925460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
935460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    // ELF header must start from 0x0
945460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    MemoryRegion *region = pOutput.memArea()->request(0,
955460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                                      sizeof(Elf64_Ehdr));
965460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    Elf64_Ehdr* header = (Elf64_Ehdr*)region->start();
975460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
985460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    memcpy(header->e_ident, ElfMagic, EI_MAG3+1);
995460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1005460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    header->e_ident[EI_CLASS]      = ELFCLASS64;
1015460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    header->e_ident[EI_DATA]       = pBackend.isLittleEndian()?
1025460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                       ELFDATA2LSB : ELFDATA2MSB;
1035460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    header->e_ident[EI_VERSION]    = pBackend.ELFVersion();
1045460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    header->e_ident[EI_OSABI]      = pBackend.OSABI();
1055460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    header->e_ident[EI_ABIVERSION] = pBackend.ABIVersion();
1065460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1075460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    // FIXME: add processor-specific and core file types.
1085460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    switch(pOutput.type()) {
1095460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case Output::Object:
1105460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      header->e_type = ET_REL;
1115460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      break;
1125460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case Output::DynObj:
1135460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      header->e_type = ET_DYN;
1145460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      break;
1155460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case Output::Exec:
1165460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      header->e_type = ET_EXEC;
1175460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      break;
1185460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    default:
1195460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      llvm::errs() << "unspported output file type: " << pOutput.type() << ".\n";
1205460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      header->e_type = ET_NONE;
1215460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    }
1225460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    header->e_machine   = pBackend.machine();
1235460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    header->e_version   = header->e_ident[EI_VERSION];
1245460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    header->e_entry     = getEntryPoint(pLDInfo, pLayout, pBackend, pOutput);
1255460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    header->e_phoff     = sizeof(Elf64_Ehdr);
1265460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    header->e_shoff     = getELF64LastStartOffset(pOutput);
1275460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    header->e_flags     = pBackend.flags();
1285460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    header->e_ehsize    = sizeof(Elf64_Ehdr);
1295460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    header->e_phentsize = sizeof(Elf64_Phdr);
1305460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    header->e_phnum     = pBackend.numOfSegments();
1315460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    header->e_shentsize = sizeof(Elf64_Shdr);
1325460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    header->e_shnum     = pOutput.context()->numOfSections();
1335460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    header->e_shstrndx  = pOutput.context()->getSectionIdx(".shstrtab");
1345460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
1355460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1365460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// getEntryPoint
1375460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaouint64_t ELFWriter::getEntryPoint(const MCLDInfo& pLDInfo,
1385460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                  const Layout& pLayout,
1395460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                  const GNULDBackend& pBackend,
1405460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                  const Output& pOutput) const
1415460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
1425460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1435460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  llvm::StringRef entry_name;
1445460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  if (pLDInfo.options().hasEntry())
1455460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    entry_name = pLDInfo.options().entry();
1465460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  else
1475460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    entry_name = pBackend.entry();
1485460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1495460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  uint64_t result = 0x0;
1505460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1515460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  bool issue_warning = (pLDInfo.options().hasEntry()
1525460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                       && (pOutput.type() != Output::Object)
1535460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                       && (pOutput.type() != Output::DynObj));
1545460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
155affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  const LDSymbol* entry_symbol = pLDInfo.getNamePool().findSymbol(entry_name);
1565460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1575460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // found the symbol
1585460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  if (NULL != entry_symbol) {
1595460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    if (entry_symbol->desc() != ResolveInfo::Define && issue_warning) {
1605460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      llvm::errs() << "WARNING: entry symbol '"
1615460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                   << entry_symbol->name()
1625460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                   << "' exists but is not defined.\n";
1635460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    }
1645460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    result = entry_symbol->value();
1655460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
1665460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // not in the symbol pool
1675460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  else {
1685460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    // We should parse entry as a number.
1695460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    // @ref GNU ld manual, Options -e. e.g., -e 0x1000.
1705460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    char* endptr;
1715460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    result = strtoull(entry_name.data(), &endptr, 0);
1725460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    if (*endptr != '\0') {
1735460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      if (issue_warning) {
1745460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        llvm::errs() << "cannot find entry symbol '"
1755460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                     << entry_name.data()
1765460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                     << "'.\n";
1775460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      }
1785460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      result = 0x0;
1795460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    }
1805460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
1815460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  return result;
1825460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
1835460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1845460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// emitELF32SectionHeader - emit Elf32_Shdr
1855460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaovoid
1865460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei LiaoELFWriter::emitELF32SectionHeader(Output& pOutput, MCLinker& pLinker) const
1875460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
1885460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // emit section header
1895460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  unsigned int sectNum = pOutput.context()->numOfSections();
1905460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  unsigned int header_size = sizeof(Elf32_Shdr) * sectNum;
1915460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  MemoryRegion* region = pOutput.memArea()->request(
1925460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                   getELF32LastStartOffset(pOutput),
1935460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                   header_size);
1945460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  Elf32_Shdr* shdr = (Elf32_Shdr*)region->start();
1955460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1965460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // Iterate the SectionTable in LDContext
1975460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  unsigned int sectIdx = 0;
1985460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  unsigned int shstridx = 0; // NULL section has empty name
1995460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  for (; sectIdx < sectNum; ++sectIdx) {
2005460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    const LDSection *ld_sect = pOutput.context()->getSection(sectIdx);
2015460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    shdr[sectIdx].sh_name      = shstridx;
2025460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    shdr[sectIdx].sh_type      = ld_sect->type();
2035460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    shdr[sectIdx].sh_flags     = ld_sect->flag();
2045460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    shdr[sectIdx].sh_addr      = ld_sect->addr();
2055460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    shdr[sectIdx].sh_offset    = ld_sect->offset();
2065460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    shdr[sectIdx].sh_size      = ld_sect->size();
2075460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    shdr[sectIdx].sh_addralign = ld_sect->align();
2085460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    shdr[sectIdx].sh_entsize   = getELF32SectEntrySize(*ld_sect);
2095460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    shdr[sectIdx].sh_link      = getSectLink(*ld_sect, pOutput);
2105460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    shdr[sectIdx].sh_info      = getSectInfo(*ld_sect, pOutput);
2115460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
2125460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    // adjust strshidx
2135460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    shstridx += ld_sect->name().size() + 1;
2145460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
2155460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
2165460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
2175460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// emitELF64SectionHeader - emit Elf64_Shdr
2185460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaovoid
2195460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei LiaoELFWriter::emitELF64SectionHeader(Output& pOutput, MCLinker& pLinker) const
2205460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
2215460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // emit section header
2225460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  unsigned int sectNum = pOutput.context()->numOfSections();
2235460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  unsigned int header_size = sizeof(Elf64_Shdr) * sectNum;
2245460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  MemoryRegion* region = pOutput.memArea()->request(
2255460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                     getELF64LastStartOffset(pOutput),
2265460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                     header_size);
2275460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  Elf64_Shdr* shdr = (Elf64_Shdr*)region->start();
2285460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
2295460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // Iterate the SectionTable in LDContext
2305460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  unsigned int sectIdx = 0;
2315460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  unsigned int shstridx = 0; // NULL section has empty name
2325460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  for (; sectIdx < sectNum; ++sectIdx) {
2335460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    const LDSection *ld_sect = pOutput.context()->getSection(sectIdx);
2345460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    shdr[sectIdx].sh_name      = shstridx;
2355460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    shdr[sectIdx].sh_type      = ld_sect->type();
2365460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    shdr[sectIdx].sh_flags     = ld_sect->flag();
2375460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    shdr[sectIdx].sh_addr      = ld_sect->addr();
2385460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    shdr[sectIdx].sh_offset    = ld_sect->offset();
2395460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    shdr[sectIdx].sh_size      = ld_sect->size();
2405460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    shdr[sectIdx].sh_addralign = (ld_sect->hasSectionData())?
2415460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                   ld_sect->getSectionData()->getAlignment():
2425460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                   0x0;
2435460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
2445460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    shdr[sectIdx].sh_entsize   = getELF64SectEntrySize(*ld_sect);
2455460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    shdr[sectIdx].sh_link      = getSectLink(*ld_sect, pOutput);
2465460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    shdr[sectIdx].sh_info      = getSectInfo(*ld_sect, pOutput);
2475460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
2485460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    // adjust strshidx
2495460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    shstridx += ld_sect->name().size() + 1;
2505460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
2515460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
2525460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
253affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
254affc150dc44fab1911775a49636d0ce85333b634Zonr Chang/// emitELF32ProgramHeader - emit Elf32_Phdr
255affc150dc44fab1911775a49636d0ce85333b634Zonr Changvoid ELFWriter::emitELF32ProgramHeader(Output& pOutput,
256affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                       const GNULDBackend& pBackend) const
257affc150dc44fab1911775a49636d0ce85333b634Zonr Chang{
258affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  assert(pOutput.hasMemArea());
259affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
260affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  uint64_t start_offset, phdr_size;
261affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
262affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  start_offset = sizeof(Elf32_Ehdr);
263affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  phdr_size = sizeof(Elf32_Phdr);
264affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  // Program header must start directly after ELF header
265affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  MemoryRegion *region = pOutput.memArea()->request(start_offset,
266affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                          pBackend.numOfSegments() * phdr_size);
267affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
268affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  Elf32_Phdr* phdr = (Elf32_Phdr*)region->start();
269affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
270affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  // Iterate the elf segment table in GNULDBackend
271affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  size_t index = 0;
272affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  ELFSegmentFactory::const_iterator seg = pBackend.elfSegmentTable().begin(),
273affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                 segEnd = pBackend.elfSegmentTable().end();
274affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  for (; seg != segEnd; ++seg, ++index) {
275affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    phdr[index].p_type   = (*seg).type();
276affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    phdr[index].p_flags  = (*seg).flag();
277affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    phdr[index].p_offset = (*seg).offset();
278affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    phdr[index].p_vaddr  = (*seg).vaddr();
279affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    phdr[index].p_paddr  = (*seg).paddr();
280affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    phdr[index].p_filesz = (*seg).filesz();
281affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    phdr[index].p_memsz  = (*seg).memsz();
282affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    phdr[index].p_align  = (*seg).align();
283affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  }
284affc150dc44fab1911775a49636d0ce85333b634Zonr Chang}
285affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
286affc150dc44fab1911775a49636d0ce85333b634Zonr Chang/// emitELF64ProgramHeader - emit ElfR64Phdr
287affc150dc44fab1911775a49636d0ce85333b634Zonr Changvoid ELFWriter::emitELF64ProgramHeader(Output& pOutput,
288affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                       const GNULDBackend& pBackend) const
289affc150dc44fab1911775a49636d0ce85333b634Zonr Chang{
290affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  assert(pOutput.hasMemArea());
291affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
292affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  uint64_t start_offset, phdr_size;
293affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
294affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  start_offset = sizeof(Elf64_Ehdr);
295affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  phdr_size = sizeof(Elf64_Phdr);
296affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  // Program header must start directly after ELF header
297affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  MemoryRegion *region = pOutput.memArea()->request(start_offset,
298affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                          pBackend.numOfSegments() * phdr_size);
299affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  Elf64_Phdr* phdr = (Elf64_Phdr*)region->start();
300affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
301affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  // Iterate the elf segment table in GNULDBackend
302affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  size_t index = 0;
303affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  ELFSegmentFactory::const_iterator seg = pBackend.elfSegmentTable().begin(),
304affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                 segEnd = pBackend.elfSegmentTable().end();
305affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  for (; seg != segEnd; ++seg, ++index) {
306affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    phdr[index].p_type   = (*seg).type();
307affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    phdr[index].p_flags  = (*seg).flag();
308affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    phdr[index].p_offset = (*seg).offset();
309affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    phdr[index].p_vaddr  = (*seg).vaddr();
310affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    phdr[index].p_paddr  = (*seg).paddr();
311affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    phdr[index].p_filesz = (*seg).filesz();
312affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    phdr[index].p_memsz  = (*seg).memsz();
313affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    phdr[index].p_align  = (*seg).align();
314affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  }
315affc150dc44fab1911775a49636d0ce85333b634Zonr Chang}
316affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
3175460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// emitELF32ShStrTab - emit section string table
3185460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaovoid ELFWriter::emitELF32ShStrTab(Output& pOutput, MCLinker& pLinker) const
3195460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
3205460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  uint64_t shstroffset = getELF32LastStartOffset(pOutput);
3215460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
3225460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // get shstrtab
3235460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  LDSection& shstrtab = pLinker.getOrCreateOutputSectHdr(".shstrtab",
3245460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                                         LDFileFormat::NamePool,
3255460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                                         SHT_STRTAB,
3265460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                                         0x0);
3275460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  if (0 != shstrtab.size())
3285460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    llvm::report_fatal_error(".shstrtab has been set.\n");
3295460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
3305460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // compute size
3315460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  unsigned int shstrsize = 0;
3325460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  LDContext::const_sect_iterator section, sectEnd = pOutput.context()->sectEnd();
3335460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  for (section = pOutput.context()->sectBegin(); section != sectEnd; ++section) {
3345460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    shstrsize += (*section)->name().size() + 1;
3355460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
3365460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
3375460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  shstrtab.setSize(shstrsize);
3385460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  shstrtab.setOffset(shstroffset);
3395460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
3405460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // write out data
3415460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  MemoryRegion* region = pOutput.memArea()->request(shstrtab.offset(),
3425460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                                    shstrtab.size());
3435460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  unsigned char* data = region->start();
3445460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  shstrsize = 0;
3455460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  for (section = pOutput.context()->sectBegin(); section != sectEnd; ++section) {
3465460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    strcpy((char*)(data + shstrsize), (*section)->name().c_str());
3475460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    shstrsize += (*section)->name().size() + 1;
3485460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
3495460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
3505460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  shstrtab.setKind(LDFileFormat::NamePool);
3515460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  shstrtab.setType(llvm::ELF::SHT_STRTAB);
3525460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  shstrtab.setFlag(0x0);
3535460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  shstrtab.setAddr(0x0);
3545460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
3555460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
3565460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
3575460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// emitELF64ShStrTab - emit section string table
3585460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaovoid ELFWriter::emitELF64ShStrTab(Output& pOutput, MCLinker& pLinker) const
3595460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
3605460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  uint64_t shstroffset = getELF64LastStartOffset(pOutput);
3615460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
3625460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // get shstrtab
3635460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  LDSection& shstrtab = pLinker.getOrCreateOutputSectHdr(".shstrtab",
3645460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                                         LDFileFormat::NamePool,
3655460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                                         SHT_STRTAB,
3665460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                                         0x0);
3675460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  if (0 != shstrtab.size())
3685460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    llvm::report_fatal_error(".shstrtab has been set.\n");
3695460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
3705460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // compute offset
3715460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
3725460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // compute size
3735460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  unsigned int shstrsize = 0;
3745460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  LDContext::const_sect_iterator section, sectEnd = pOutput.context()->sectEnd();
3755460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  for (section = pOutput.context()->sectBegin(); section != sectEnd; ++section) {
3765460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    shstrsize += (*section)->name().size() + 1;
3775460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
3785460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
3795460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  shstrtab.setSize(shstrsize);
3805460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  shstrtab.setOffset(shstroffset);
3815460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
3825460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // write out data
3835460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  MemoryRegion* region = pOutput.memArea()->request(shstrtab.offset(),
3845460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                                    shstrtab.size());
3855460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  unsigned char* data = region->start();
3865460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  shstrsize = 0;
3875460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  for (section = pOutput.context()->sectBegin(); section != sectEnd; ++section) {
3885460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    strcpy((char*)(data + shstrsize), (*section)->name().c_str());
3895460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    shstrsize += (*section)->name().size() + 1;
3905460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
3915460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
3925460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  shstrtab.setKind(LDFileFormat::NamePool);
3935460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  shstrtab.setType(llvm::ELF::SHT_STRTAB);
3945460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  shstrtab.setFlag(0x0);
3955460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  shstrtab.setAddr(0x0);
3965460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
3975460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
3985460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// emitSectionData
3995460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaovoid
4005460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei LiaoELFWriter::emitSectionData(const Layout& pLayout,
4015460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                           const LDSection& pSection,
4025460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                           MemoryRegion& pRegion) const
4035460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
404cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao  const SectionData* data = pSection.getSectionData();
405cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao  SectionData::const_iterator fragIter, fragEnd = data->end();
4065460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  size_t cur_offset = 0;
4075460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  for (fragIter = data->begin(); fragIter != fragEnd; ++fragIter) {
4085460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    size_t size = computeFragmentSize(pLayout, *fragIter);
4095460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    switch(fragIter->getKind()) {
410cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao      case Fragment::Region: {
411cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao        const RegionFragment& region_frag = llvm::cast<RegionFragment>(*fragIter);
4125460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        const uint8_t* from = region_frag.getRegion().start();
4135460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        memcpy(pRegion.getBuffer(cur_offset), from, size);
4145460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        break;
4155460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      }
416cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao      case Fragment::Alignment: {
4175460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        // TODO: emit values with different sizes (> 1 byte), and emit nops
418cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao        AlignFragment& align_frag = llvm::cast<AlignFragment>(*fragIter);
4195460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        uint64_t count = size / align_frag.getValueSize();
4205460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        switch (align_frag.getValueSize()) {
4215460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao          case 1u:
4225460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao            std::memset(pRegion.getBuffer(cur_offset),
4235460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                        align_frag.getValue(),
4245460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                        count);
4255460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao            break;
4265460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao          default:
4275460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao            llvm::report_fatal_error("unsupported value size for align fragment emission yet.\n");
4285460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao            break;
4295460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        }
4305460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        break;
4315460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      }
432cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao      case Fragment::Fillment: {
433cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao        FillFragment& fill_frag = llvm::cast<FillFragment>(*fragIter);
4345460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        if (0 == size ||
4355460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao            0 == fill_frag.getValueSize() ||
4365460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao            0 == fill_frag.getSize()) {
4375460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao          // ignore virtual fillment
4385460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao          break;
4395460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        }
4405460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
4415460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        uint64_t num_tiles = fill_frag.getSize() / fill_frag.getValueSize();
4425460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        for (uint64_t i = 0; i != num_tiles; ++i) {
4435460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao          std::memset(pRegion.getBuffer(cur_offset),
4445460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                      fill_frag.getValue(),
4455460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                      fill_frag.getValueSize());
4465460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        }
4475460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        break;
4485460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      }
449cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao      case Fragment::Relocation:
4505460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        llvm::report_fatal_error("relocation fragment should not be in a regular section.\n");
4515460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        break;
452cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao      case Fragment::Target:
4535460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        llvm::report_fatal_error("Target fragment should not be in a regular section.\n");
4545460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        break;
4555460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      default:
4565460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        llvm::report_fatal_error("invalid fragment should not be in a regular section.\n");
4575460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        break;
4585460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    }
4595460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    cur_offset += size;
4605460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
4615460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
4625460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
4635460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// emitRelocation
4645460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaovoid ELFWriter::emitRelocation(const Layout& pLayout,
4655460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                               const Output& pOutput,
4665460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                               const LDSection& pSection,
4675460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                               MemoryRegion& pRegion) const
4685460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
469cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao  const SectionData* sect_data = pSection.getSectionData();
470cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao  assert(NULL != sect_data && "SectionData is NULL in emitRelocation!");
4715460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
4725460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  if (pSection.type() == SHT_REL)
473cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao    emitRel(pLayout, pOutput, *sect_data, pRegion);
4745460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  else if (pSection.type() == SHT_RELA)
475cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao    emitRela(pLayout, pOutput, *sect_data, pRegion);
4765460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  else
4775460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    llvm::report_fatal_error("unsupported relocation section type!");
4785460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
4795460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
4805460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
4815460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// emitRel
4825460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaovoid ELFWriter::emitRel(const Layout& pLayout,
4835460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                        const Output& pOutput,
484cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao                        const SectionData& pSectionData,
4855460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                        MemoryRegion& pRegion) const
4865460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
4875460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  Elf32_Rel* rel = reinterpret_cast<Elf32_Rel*>(pRegion.start());
4885460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
4895460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  Relocation* relocation = 0;
490cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao  FragmentRef* frag_ref = 0;
4915460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
492cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao  for (SectionData::const_iterator it = pSectionData.begin(),
4935460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao       ie = pSectionData.end(); it != ie; ++it, ++rel) {
4945460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
4955460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    relocation = &(llvm::cast<Relocation>(*it));
496cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao    frag_ref = &(relocation->targetRef());
4975460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
4985460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    if(pOutput.type() == Output::DynObj || pOutput.type() == Output::Exec) {
4995460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      rel->r_offset = static_cast<Elf32_Addr>(
500cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao                      frag_ref->frag()->getParent()->getSection().addr() +
501cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao                      pLayout.getOutputOffset(*frag_ref));
5025460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    }
5035460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    else {
5045460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      rel->r_offset = static_cast<Elf32_Addr>(
505cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao                      frag_ref->frag()->getParent()->getSection().offset() +
506cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao                      pLayout.getOutputOffset(*frag_ref));
5075460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    }
5085460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
5095460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    Elf32_Word Index;
5105460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    if( relocation->symInfo() == NULL )
5115460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      Index = 0;
5125460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    else
5135460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      Index = static_cast<Elf32_Word>(
5145460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao              f_Backend.getSymbolIdx(relocation->symInfo()->outSymbol()));
5155460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
5165460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    rel->setSymbolAndType(Index, relocation->type());
5175460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
5185460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
5195460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
5205460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// emitRela
5215460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaovoid ELFWriter::emitRela(const Layout& pLayout,
5225460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                         const Output& pOutput,
523cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao                         const SectionData& pSectionData,
5245460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                         MemoryRegion& pRegion) const
5255460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
5265460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  Elf32_Rela* rel = reinterpret_cast<Elf32_Rela*>(pRegion.start());
5275460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
5285460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  Relocation* relocation = 0;
529cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao  FragmentRef* frag_ref = 0;
5305460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
531cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao  for (SectionData::const_iterator it = pSectionData.begin(),
5325460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao       ie = pSectionData.end(); it != ie; ++it, ++rel) {
5335460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
5345460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    relocation = &(llvm::cast<Relocation>(*it));
535cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao    frag_ref = &(relocation->targetRef());
5365460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
5375460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    if(pOutput.type() == Output::DynObj || pOutput.type() == Output::Exec) {
5385460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      rel->r_offset = static_cast<Elf32_Addr>(
539cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao                      frag_ref->frag()->getParent()->getSection().addr() +
540cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao                      pLayout.getOutputOffset(*frag_ref));
5415460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    }
5425460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    else {
5435460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      rel->r_offset = static_cast<Elf32_Addr>(
544cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao                      frag_ref->frag()->getParent()->getSection().offset() +
545cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao                      pLayout.getOutputOffset(*frag_ref));
5465460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    }
5475460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
5485460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    Elf32_Word Index;
5495460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    if( relocation->symInfo() == NULL )
5505460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      Index = 0;
5515460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    else
5525460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      Index = static_cast<Elf32_Word>(
5535460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao              f_Backend.getSymbolIdx(relocation->symInfo()->outSymbol()));
5545460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
5555460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    rel->setSymbolAndType(Index, relocation->type());
5565460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    rel->r_addend = relocation->addend();
5575460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
5585460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
5595460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
5605460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// getELF32SectEntrySize - compute Elf32_Shdr::sh_entsize
5615460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaouint64_t ELFWriter::getELF32SectEntrySize(const LDSection& pSection) const
5625460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
5635460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  if (llvm::ELF::SHT_DYNSYM == pSection.type() ||
5645460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      llvm::ELF::SHT_SYMTAB == pSection.type())
5655460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    return sizeof(llvm::ELF::Elf32_Sym);
5665460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  if (llvm::ELF::SHT_REL == pSection.type())
5675460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    return sizeof(llvm::ELF::Elf32_Rel);
5685460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  if (llvm::ELF::SHT_RELA == pSection.type())
5695460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    return sizeof(llvm::ELF::Elf32_Rela);
5705460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  if (llvm::ELF::SHT_HASH == pSection.type())
5715460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    return sizeof(llvm::ELF::Elf32_Word);
5725460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  if (llvm::ELF::SHT_DYNAMIC == pSection.type())
5735460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    return sizeof(llvm::ELF::Elf32_Dyn);
5745460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  return 0x0;
5755460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
5765460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
5775460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// getELF64SectEntrySize - compute Elf64_Shdr::sh_entsize
5785460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaouint64_t ELFWriter::getELF64SectEntrySize(const LDSection& pSection) const
5795460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
5805460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  if (llvm::ELF::SHT_DYNSYM == pSection.type() ||
5815460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      llvm::ELF::SHT_SYMTAB == pSection.type())
5825460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    return sizeof(llvm::ELF::Elf64_Sym);
5835460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  if (llvm::ELF::SHT_REL == pSection.type())
5845460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    return sizeof(llvm::ELF::Elf64_Rel);
5855460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  if (llvm::ELF::SHT_RELA == pSection.type())
5865460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    return sizeof(llvm::ELF::Elf64_Rela);
5875460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  if (llvm::ELF::SHT_HASH == pSection.type())
5885460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    return sizeof(llvm::ELF::Elf64_Word);
5895460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  if (llvm::ELF::SHT_DYNAMIC == pSection.type())
5905460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    return sizeof(llvm::ELF::Elf64_Dyn);
5915460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  return 0x0;
5925460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
5935460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
5945460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// getSectLink - compute ElfXX_Shdr::sh_link
5955460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaouint64_t ELFWriter::getSectLink(const LDSection& pSection, const Output& pOutput) const
5965460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
5975460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  const LDContext* context = pOutput.context();
5985460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  if (llvm::ELF::SHT_SYMTAB == pSection.type())
5995460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    return context->getSectionIdx(".strtab");
6005460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  if (llvm::ELF::SHT_DYNSYM == pSection.type())
6015460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    return context->getSectionIdx(".dynstr");
6025460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  if (llvm::ELF::SHT_DYNAMIC == pSection.type())
6035460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    return context->getSectionIdx(".dynstr");
6045460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  if (llvm::ELF::SHT_HASH == pSection.type())
6055460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    return context->getSectionIdx(".dynsym");
6065460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  if (llvm::ELF::SHT_REL == pSection.type() ||
6075460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      llvm::ELF::SHT_RELA == pSection.type()) {
6085460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    if (pOutput.type() == Output::Object)
6095460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      return context->getSectionIdx(".symtab");
6105460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    else
6115460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      return context->getSectionIdx(".dynsym");
6125460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
6135460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  return llvm::ELF::SHN_UNDEF;
6145460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
6155460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
6165460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// getSectInfo - compute ElfXX_Shdr::sh_info
6175460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaouint64_t ELFWriter::getSectInfo(const LDSection& pSection, const Output& pOutput) const
6185460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
6195460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  const LDSection* info_link = pSection.getLink();
6205460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  if (NULL == info_link)
6215460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    return 0x0;
6225460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  return info_link->index();
6235460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
6245460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
6255460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// getELF32LastStartOffset
6265460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaouint64_t ELFWriter::getELF32LastStartOffset(const Output& pOutput) const
6275460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
6285460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  LDSection* lastSect = pOutput.context()->getSectionTable().back();
6295460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  assert(lastSect != NULL);
6305460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  return Align<32>(lastSect->offset() + lastSect->size());
6315460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
6325460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
6335460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// getELF64LastStartOffset
6345460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaouint64_t ELFWriter::getELF64LastStartOffset(const Output& pOutput) const
6355460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
6365460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  LDSection* lastSect = pOutput.context()->getSectionTable().back();
6375460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  assert(lastSect != NULL);
6385460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  return Align<64>(lastSect->offset() + lastSect->size());
6395460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
6405460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
641