//===- ELFWriter.cpp ------------------------------------------------------===//
//
//                     The MCLinker Project
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#include <llvm/Support/ELF.h>
#include <llvm/Support/ErrorHandling.h>
#include <llvm/MC/MCAssembler.h>
#include <mcld/ADT/SizeTraits.h>
#include <mcld/Support/MemoryRegion.h>
#include <mcld/MC/MCLDInfo.h>
#include <mcld/MC/MCLinker.h>
#include <mcld/MC/MCRegionFragment.h>
#include <mcld/LD/ELFWriter.h>
#include <mcld/LD/LDSymbol.h>
#include <mcld/LD/LDSection.h>
#include <mcld/LD/Layout.h>
#include <mcld/LD/ELFSegment.h>
#include <mcld/LD/ELFSegmentFactory.h>
#include <mcld/Target/GNULDBackend.h>
#include <cstdlib>
#include <cstring>

using namespace llvm::ELF;
using namespace mcld;

/// writeELF32Header - write ELF header
void ELFWriter::writeELF32Header(const MCLDInfo& pLDInfo,
                                 const Layout& pLayout,
                                 const GNULDBackend& pBackend,
                                 Output& pOutput) const
{
    assert(pOutput.hasMemArea());

    // ELF header must start from 0x0
    MemoryRegion *region = pOutput.memArea()->request(0,
                                                      sizeof(Elf32_Ehdr));
    Elf32_Ehdr* header = (Elf32_Ehdr*)region->start();

    memcpy(header->e_ident, ElfMagic, EI_MAG3+1);

    header->e_ident[EI_CLASS]      = ELFCLASS32;
    header->e_ident[EI_DATA]       = pBackend.isLittleEndian()?
                                       ELFDATA2LSB : ELFDATA2MSB;
    header->e_ident[EI_VERSION]    = pBackend.ELFVersion();
    header->e_ident[EI_OSABI]      = pBackend.OSABI();
    header->e_ident[EI_ABIVERSION] = pBackend.ABIVersion();

    // FIXME: add processor-specific and core file types.
    switch(pOutput.type()) {
    case Output::Object:
      header->e_type = ET_REL;
      break;
    case Output::DynObj:
      header->e_type = ET_DYN;
      break;
    case Output::Exec:
      header->e_type = ET_EXEC;
      break;
    default:
      llvm::errs() << "unspported output file type: " << pOutput.type() << ".\n";
      header->e_type = ET_NONE;
    }
    header->e_machine   = pBackend.machine();
    header->e_version   = header->e_ident[EI_VERSION];
    header->e_entry     = getEntryPoint(pLDInfo, pLayout, pBackend, pOutput);
    header->e_phoff     = sizeof(Elf32_Ehdr);
    header->e_shoff     = getELF32LastStartOffset(pOutput);
    header->e_flags     = pBackend.flags();
    header->e_ehsize    = sizeof(Elf32_Ehdr);
    header->e_phentsize = sizeof(Elf32_Phdr);
    header->e_phnum     = pBackend.numOfSegments();
    header->e_shentsize = sizeof(Elf32_Shdr);
    header->e_shnum     = pOutput.context()->numOfSections();
    header->e_shstrndx  = pOutput.context()->getSectionIdx(".shstrtab");
}

/// writeELF64Header - write ELF header
void ELFWriter::writeELF64Header(const MCLDInfo& pLDInfo,
                                 const Layout& pLayout,
                                 const GNULDBackend& pBackend,
                                 Output& pOutput) const
{
    assert(pOutput.hasMemArea());

    // ELF header must start from 0x0
    MemoryRegion *region = pOutput.memArea()->request(0,
                                                      sizeof(Elf64_Ehdr));
    Elf64_Ehdr* header = (Elf64_Ehdr*)region->start();

    memcpy(header->e_ident, ElfMagic, EI_MAG3+1);

    header->e_ident[EI_CLASS]      = ELFCLASS64;
    header->e_ident[EI_DATA]       = pBackend.isLittleEndian()?
                                       ELFDATA2LSB : ELFDATA2MSB;
    header->e_ident[EI_VERSION]    = pBackend.ELFVersion();
    header->e_ident[EI_OSABI]      = pBackend.OSABI();
    header->e_ident[EI_ABIVERSION] = pBackend.ABIVersion();

    // FIXME: add processor-specific and core file types.
    switch(pOutput.type()) {
    case Output::Object:
      header->e_type = ET_REL;
      break;
    case Output::DynObj:
      header->e_type = ET_DYN;
      break;
    case Output::Exec:
      header->e_type = ET_EXEC;
      break;
    default:
      llvm::errs() << "unspported output file type: " << pOutput.type() << ".\n";
      header->e_type = ET_NONE;
    }
    header->e_machine   = pBackend.machine();
    header->e_version   = header->e_ident[EI_VERSION];
    header->e_entry     = getEntryPoint(pLDInfo, pLayout, pBackend, pOutput);
    header->e_phoff     = sizeof(Elf64_Ehdr);
    header->e_shoff     = getELF64LastStartOffset(pOutput);
    header->e_flags     = pBackend.flags();
    header->e_ehsize    = sizeof(Elf64_Ehdr);
    header->e_phentsize = sizeof(Elf64_Phdr);
    header->e_phnum     = pBackend.numOfSegments();
    header->e_shentsize = sizeof(Elf64_Shdr);
    header->e_shnum     = pOutput.context()->numOfSections();
    header->e_shstrndx  = pOutput.context()->getSectionIdx(".shstrtab");
}

/// getEntryPoint
uint64_t ELFWriter::getEntryPoint(const MCLDInfo& pLDInfo,
                                  const Layout& pLayout,
                                  const GNULDBackend& pBackend,
                                  const Output& pOutput) const
{

  llvm::StringRef entry_name;
  if (pLDInfo.options().hasEntry())
    entry_name = pLDInfo.options().entry();
  else
    entry_name = pBackend.entry();
  
  uint64_t result = 0x0;

  bool issue_warning = (pLDInfo.options().hasEntry()
                       && (pOutput.type() != Output::Object)
                       && (pOutput.type() != Output::DynObj));

  const LDSymbol* entry_symbol = pLDInfo.getNamePool().findSymbol(entry_name);

  // found the symbol
  if (NULL != entry_symbol) {
    if (entry_symbol->desc() != ResolveInfo::Define && issue_warning) {
      llvm::errs() << "WARNING: entry symbol '"
                   << entry_symbol->name()
                   << "' exists but is not defined.\n";
    }
    result = entry_symbol->value();
  }
  // not in the symbol pool
  else {
    // We should parse entry as a number.
    // @ref GNU ld manual, Options -e. e.g., -e 0x1000.
    char* endptr;
    result = strtoull(entry_name.data(), &endptr, 0);
    if (*endptr != '\0') {
      if (issue_warning) {
        llvm::errs() << "cannot find entry symbol '"
                     << entry_name.data()
                     << "'.\n";
      }
      result = 0x0;
    }
  }
  return result;
}

/// emitELF32SectionHeader - emit Elf32_Shdr
void
ELFWriter::emitELF32SectionHeader(Output& pOutput, MCLinker& pLinker) const
{
  // emit section header
  unsigned int sectNum = pOutput.context()->numOfSections();
  unsigned int header_size = sizeof(Elf32_Shdr) * sectNum;
  MemoryRegion* region = pOutput.memArea()->request(
                                   getELF32LastStartOffset(pOutput),
                                   header_size);
  Elf32_Shdr* shdr = (Elf32_Shdr*)region->start();

  // Iterate the SectionTable in LDContext
  unsigned int sectIdx = 0;
  unsigned int shstridx = 0; // NULL section has empty name
  for (; sectIdx < sectNum; ++sectIdx) {
    const LDSection *ld_sect = pOutput.context()->getSection(sectIdx);
    shdr[sectIdx].sh_name      = shstridx;
    shdr[sectIdx].sh_type      = ld_sect->type();
    shdr[sectIdx].sh_flags     = ld_sect->flag();
    shdr[sectIdx].sh_addr      = ld_sect->addr();
    shdr[sectIdx].sh_offset    = ld_sect->offset();
    shdr[sectIdx].sh_size      = ld_sect->size();
    shdr[sectIdx].sh_addralign = ld_sect->align();
    shdr[sectIdx].sh_entsize   = getELF32SectEntrySize(*ld_sect);
    shdr[sectIdx].sh_link      = getSectLink(*ld_sect, pOutput);
    shdr[sectIdx].sh_info      = getSectInfo(*ld_sect, pOutput);

    // adjust strshidx
    shstridx += ld_sect->name().size() + 1;
  }
}

/// emitELF64SectionHeader - emit Elf64_Shdr
void
ELFWriter::emitELF64SectionHeader(Output& pOutput, MCLinker& pLinker) const
{
  // emit section header
  unsigned int sectNum = pOutput.context()->numOfSections();
  unsigned int header_size = sizeof(Elf64_Shdr) * sectNum;
  MemoryRegion* region = pOutput.memArea()->request(
                                     getELF64LastStartOffset(pOutput),
                                     header_size);
  Elf64_Shdr* shdr = (Elf64_Shdr*)region->start();

  // Iterate the SectionTable in LDContext
  unsigned int sectIdx = 0;
  unsigned int shstridx = 0; // NULL section has empty name
  for (; sectIdx < sectNum; ++sectIdx) {
    const LDSection *ld_sect = pOutput.context()->getSection(sectIdx);
    shdr[sectIdx].sh_name      = shstridx;
    shdr[sectIdx].sh_type      = ld_sect->type();
    shdr[sectIdx].sh_flags     = ld_sect->flag();
    shdr[sectIdx].sh_addr      = ld_sect->addr();
    shdr[sectIdx].sh_offset    = ld_sect->offset();
    shdr[sectIdx].sh_size      = ld_sect->size();
    shdr[sectIdx].sh_addralign = (ld_sect->hasSectionData())?
                                   ld_sect->getSectionData()->getAlignment():
                                   0x0;

    shdr[sectIdx].sh_entsize   = getELF64SectEntrySize(*ld_sect);
    shdr[sectIdx].sh_link      = getSectLink(*ld_sect, pOutput);
    shdr[sectIdx].sh_info      = getSectInfo(*ld_sect, pOutput);

    // adjust strshidx
    shstridx += ld_sect->name().size() + 1;
  }
}


/// emitELF32ProgramHeader - emit Elf32_Phdr
void ELFWriter::emitELF32ProgramHeader(Output& pOutput,
                                       const GNULDBackend& pBackend) const
{
  assert(pOutput.hasMemArea());

  uint64_t start_offset, phdr_size;

  start_offset = sizeof(Elf32_Ehdr);
  phdr_size = sizeof(Elf32_Phdr);
  // Program header must start directly after ELF header
  MemoryRegion *region = pOutput.memArea()->request(start_offset,
                                          pBackend.numOfSegments() * phdr_size);

  Elf32_Phdr* phdr = (Elf32_Phdr*)region->start();

  // Iterate the elf segment table in GNULDBackend
  size_t index = 0;
  ELFSegmentFactory::const_iterator seg = pBackend.elfSegmentTable().begin(),
                                 segEnd = pBackend.elfSegmentTable().end();
  for (; seg != segEnd; ++seg, ++index) {
    phdr[index].p_type   = (*seg).type();
    phdr[index].p_flags  = (*seg).flag();
    phdr[index].p_offset = (*seg).offset();
    phdr[index].p_vaddr  = (*seg).vaddr();
    phdr[index].p_paddr  = (*seg).paddr();
    phdr[index].p_filesz = (*seg).filesz();
    phdr[index].p_memsz  = (*seg).memsz();
    phdr[index].p_align  = (*seg).align();
  }
}

/// emitELF64ProgramHeader - emit ElfR64Phdr
void ELFWriter::emitELF64ProgramHeader(Output& pOutput,
                                       const GNULDBackend& pBackend) const
{
  assert(pOutput.hasMemArea());

  uint64_t start_offset, phdr_size;

  start_offset = sizeof(Elf64_Ehdr);
  phdr_size = sizeof(Elf64_Phdr);
  // Program header must start directly after ELF header
  MemoryRegion *region = pOutput.memArea()->request(start_offset,
                                          pBackend.numOfSegments() * phdr_size);
  Elf64_Phdr* phdr = (Elf64_Phdr*)region->start();

  // Iterate the elf segment table in GNULDBackend
  size_t index = 0;
  ELFSegmentFactory::const_iterator seg = pBackend.elfSegmentTable().begin(),
                                 segEnd = pBackend.elfSegmentTable().end();
  for (; seg != segEnd; ++seg, ++index) {
    phdr[index].p_type   = (*seg).type();
    phdr[index].p_flags  = (*seg).flag();
    phdr[index].p_offset = (*seg).offset();
    phdr[index].p_vaddr  = (*seg).vaddr();
    phdr[index].p_paddr  = (*seg).paddr();
    phdr[index].p_filesz = (*seg).filesz();
    phdr[index].p_memsz  = (*seg).memsz();
    phdr[index].p_align  = (*seg).align();
  }
}

/// emitELF32ShStrTab - emit section string table
void ELFWriter::emitELF32ShStrTab(Output& pOutput, MCLinker& pLinker) const
{
  uint64_t shstroffset = getELF32LastStartOffset(pOutput);

  // get shstrtab
  LDSection& shstrtab = pLinker.getOrCreateOutputSectHdr(".shstrtab",
                                                         LDFileFormat::NamePool,
                                                         SHT_STRTAB,
                                                         0x0);
  if (0 != shstrtab.size())
    llvm::report_fatal_error(".shstrtab has been set.\n");

  // compute size
  unsigned int shstrsize = 0;
  LDContext::const_sect_iterator section, sectEnd = pOutput.context()->sectEnd();
  for (section = pOutput.context()->sectBegin(); section != sectEnd; ++section) {
    shstrsize += (*section)->name().size() + 1;
  }

  shstrtab.setSize(shstrsize);
  shstrtab.setOffset(shstroffset);

  // write out data
  MemoryRegion* region = pOutput.memArea()->request(shstrtab.offset(),
                                                    shstrtab.size());
  unsigned char* data = region->start();
  shstrsize = 0;
  for (section = pOutput.context()->sectBegin(); section != sectEnd; ++section) {
    strcpy((char*)(data + shstrsize), (*section)->name().c_str());
    shstrsize += (*section)->name().size() + 1;
  }

  shstrtab.setKind(LDFileFormat::NamePool);
  shstrtab.setType(llvm::ELF::SHT_STRTAB);
  shstrtab.setFlag(0x0);
  shstrtab.setAddr(0x0);
}


/// emitELF64ShStrTab - emit section string table
void ELFWriter::emitELF64ShStrTab(Output& pOutput, MCLinker& pLinker) const
{
  uint64_t shstroffset = getELF64LastStartOffset(pOutput);

  // get shstrtab
  LDSection& shstrtab = pLinker.getOrCreateOutputSectHdr(".shstrtab",
                                                         LDFileFormat::NamePool,
                                                         SHT_STRTAB,
                                                         0x0);
  if (0 != shstrtab.size())
    llvm::report_fatal_error(".shstrtab has been set.\n");

  // compute offset

  // compute size
  unsigned int shstrsize = 0;
  LDContext::const_sect_iterator section, sectEnd = pOutput.context()->sectEnd();
  for (section = pOutput.context()->sectBegin(); section != sectEnd; ++section) {
    shstrsize += (*section)->name().size() + 1;
  }

  shstrtab.setSize(shstrsize);
  shstrtab.setOffset(shstroffset);

  // write out data
  MemoryRegion* region = pOutput.memArea()->request(shstrtab.offset(),
                                                    shstrtab.size());
  unsigned char* data = region->start();
  shstrsize = 0;
  for (section = pOutput.context()->sectBegin(); section != sectEnd; ++section) {
    strcpy((char*)(data + shstrsize), (*section)->name().c_str());
    shstrsize += (*section)->name().size() + 1;
  }

  shstrtab.setKind(LDFileFormat::NamePool);
  shstrtab.setType(llvm::ELF::SHT_STRTAB);
  shstrtab.setFlag(0x0);
  shstrtab.setAddr(0x0);
}

/// emitSectionData
void
ELFWriter::emitSectionData(const Layout& pLayout,
                           const LDSection& pSection,
                           MemoryRegion& pRegion) const
{
  const llvm::MCSectionData* data = pSection.getSectionData();
  llvm::MCSectionData::const_iterator fragIter, fragEnd = data->end();
  size_t cur_offset = 0;
  for (fragIter = data->begin(); fragIter != fragEnd; ++fragIter) {
    size_t size = computeFragmentSize(pLayout, *fragIter);
    switch(fragIter->getKind()) {
      case llvm::MCFragment::FT_Region: {
        const MCRegionFragment& region_frag = llvm::cast<MCRegionFragment>(*fragIter);
        const uint8_t* from = region_frag.getRegion().start();
        memcpy(pRegion.getBuffer(cur_offset), from, size);
        break;
      }
      case llvm::MCFragment::FT_Align: {
        // TODO: emit values with different sizes (> 1 byte), and emit nops
        llvm::MCAlignFragment& align_frag = llvm::cast<llvm::MCAlignFragment>(*fragIter);
        uint64_t count = size / align_frag.getValueSize();
        switch (align_frag.getValueSize()) {
          case 1u:
            std::memset(pRegion.getBuffer(cur_offset),
                        align_frag.getValue(),
                        count);
            break;
          default:
            llvm::report_fatal_error("unsupported value size for align fragment emission yet.\n");
            break;
        }
        break;
      }
      case llvm::MCFragment::FT_Fill: {
        llvm::MCFillFragment& fill_frag = llvm::cast<llvm::MCFillFragment>(*fragIter);
        if (0 == size ||
            0 == fill_frag.getValueSize() ||
            0 == fill_frag.getSize()) {
          // ignore virtual fillment
          break;
        }

        uint64_t num_tiles = fill_frag.getSize() / fill_frag.getValueSize();
        for (uint64_t i = 0; i != num_tiles; ++i) {
          std::memset(pRegion.getBuffer(cur_offset),
                      fill_frag.getValue(),
                      fill_frag.getValueSize());
        }
        break;
      }
      case llvm::MCFragment::FT_Data:
      case llvm::MCFragment::FT_Inst:
      case llvm::MCFragment::FT_Org:
      case llvm::MCFragment::FT_Dwarf:
      case llvm::MCFragment::FT_DwarfFrame:
      case llvm::MCFragment::FT_LEB: {
        llvm::report_fatal_error("unsupported fragment yet.\n");
        break;
      }
      case llvm::MCFragment::FT_Reloc:
        llvm::report_fatal_error("relocation fragment should not be in a regular section.\n");
        break;
      case llvm::MCFragment::FT_Target:
        llvm::report_fatal_error("Target fragment should not be in a regular section.\n");
        break;
      default:
        llvm::report_fatal_error("invalid fragment should not be in a regular section.\n");
        break;
    }
    cur_offset += size;
  }
}

/// emitRelocation
void ELFWriter::emitRelocation(const Layout& pLayout,
                               const Output& pOutput,
                               const LDSection& pSection,
                               MemoryRegion& pRegion) const
{
  const llvm::MCSectionData* SectionData = pSection.getSectionData();
  assert(SectionData && "SectionData is NULL in emitRelocation!");

  if (pSection.type() == SHT_REL)
    emitRel(pLayout, pOutput, *SectionData, pRegion);
  else if (pSection.type() == SHT_RELA)
    emitRela(pLayout, pOutput, *SectionData, pRegion);
  else
    llvm::report_fatal_error("unsupported relocation section type!");
}


/// emitRel
void ELFWriter::emitRel(const Layout& pLayout,
                        const Output& pOutput,
                        const llvm::MCSectionData& pSectionData,
                        MemoryRegion& pRegion) const
{
  Elf32_Rel* rel = reinterpret_cast<Elf32_Rel*>(pRegion.start());

  Relocation* relocation = 0;
  MCFragmentRef* FragmentRef = 0;

  for (llvm::MCSectionData::const_iterator it = pSectionData.begin(),
       ie = pSectionData.end(); it != ie; ++it, ++rel) {

    relocation = &(llvm::cast<Relocation>(*it));
    FragmentRef = &(relocation->targetRef());

    if(pOutput.type() == Output::DynObj || pOutput.type() == Output::Exec) {
      rel->r_offset = static_cast<Elf32_Addr>(
                      llvm::cast<LDSection>(
                      FragmentRef->frag()->getParent()->getSection()).addr() +
                      pLayout.getOutputOffset(*FragmentRef));
    }
    else {
      rel->r_offset = static_cast<Elf32_Addr>(
                      llvm::cast<LDSection>(
                      FragmentRef->frag()->getParent()->getSection()).offset() +
                      pLayout.getOutputOffset(*FragmentRef));
    }

    Elf32_Word Index;
    if( relocation->symInfo() == NULL )
      Index = 0;
    else
      Index = static_cast<Elf32_Word>(
              f_Backend.getSymbolIdx(relocation->symInfo()->outSymbol()));

    rel->setSymbolAndType(Index, relocation->type());
  }
}

/// emitRela
void ELFWriter::emitRela(const Layout& pLayout,
                         const Output& pOutput,
                         const llvm::MCSectionData& pSectionData,
                         MemoryRegion& pRegion) const
{
  Elf32_Rela* rel = reinterpret_cast<Elf32_Rela*>(pRegion.start());

  Relocation* relocation = 0;
  MCFragmentRef* FragmentRef = 0;

  for (llvm::MCSectionData::const_iterator it = pSectionData.begin(),
       ie = pSectionData.end(); it != ie; ++it, ++rel) {

    relocation = &(llvm::cast<Relocation>(*it));
    FragmentRef = &(relocation->targetRef());

    if(pOutput.type() == Output::DynObj || pOutput.type() == Output::Exec) {
      rel->r_offset = static_cast<Elf32_Addr>(
                      llvm::cast<LDSection>(
                      FragmentRef->frag()->getParent()->getSection()).addr() +
                      pLayout.getOutputOffset(*FragmentRef));
    }
    else {
      rel->r_offset = static_cast<Elf32_Addr>(
                      llvm::cast<LDSection>(
                      FragmentRef->frag()->getParent()->getSection()).offset() +
                      pLayout.getOutputOffset(*FragmentRef));
    }

    Elf32_Word Index;
    if( relocation->symInfo() == NULL )
      Index = 0;
    else
      Index = static_cast<Elf32_Word>(
              f_Backend.getSymbolIdx(relocation->symInfo()->outSymbol()));

    rel->setSymbolAndType(Index, relocation->type());
    rel->r_addend = relocation->addend();
  }
}

/// getELF32SectEntrySize - compute Elf32_Shdr::sh_entsize
uint64_t ELFWriter::getELF32SectEntrySize(const LDSection& pSection) const
{
  if (llvm::ELF::SHT_DYNSYM == pSection.type() ||
      llvm::ELF::SHT_SYMTAB == pSection.type())
    return sizeof(llvm::ELF::Elf32_Sym);
  if (llvm::ELF::SHT_REL == pSection.type())
    return sizeof(llvm::ELF::Elf32_Rel);
  if (llvm::ELF::SHT_RELA == pSection.type())
    return sizeof(llvm::ELF::Elf32_Rela);
  if (llvm::ELF::SHT_HASH == pSection.type())
    return sizeof(llvm::ELF::Elf32_Word);
  if (llvm::ELF::SHT_DYNAMIC == pSection.type())
    return sizeof(llvm::ELF::Elf32_Dyn);
  return 0x0;
}

/// getELF64SectEntrySize - compute Elf64_Shdr::sh_entsize
uint64_t ELFWriter::getELF64SectEntrySize(const LDSection& pSection) const
{
  if (llvm::ELF::SHT_DYNSYM == pSection.type() ||
      llvm::ELF::SHT_SYMTAB == pSection.type())
    return sizeof(llvm::ELF::Elf64_Sym);
  if (llvm::ELF::SHT_REL == pSection.type())
    return sizeof(llvm::ELF::Elf64_Rel);
  if (llvm::ELF::SHT_RELA == pSection.type())
    return sizeof(llvm::ELF::Elf64_Rela);
  if (llvm::ELF::SHT_HASH == pSection.type())
    return sizeof(llvm::ELF::Elf64_Word);
  if (llvm::ELF::SHT_DYNAMIC == pSection.type())
    return sizeof(llvm::ELF::Elf64_Dyn);
  return 0x0;
}

/// getSectLink - compute ElfXX_Shdr::sh_link
uint64_t ELFWriter::getSectLink(const LDSection& pSection, const Output& pOutput) const
{
  const LDContext* context = pOutput.context();
  if (llvm::ELF::SHT_SYMTAB == pSection.type())
    return context->getSectionIdx(".strtab");
  if (llvm::ELF::SHT_DYNSYM == pSection.type())
    return context->getSectionIdx(".dynstr");
  if (llvm::ELF::SHT_DYNAMIC == pSection.type())
    return context->getSectionIdx(".dynstr");
  if (llvm::ELF::SHT_HASH == pSection.type())
    return context->getSectionIdx(".dynsym");
  if (llvm::ELF::SHT_REL == pSection.type() ||
      llvm::ELF::SHT_RELA == pSection.type()) {
    if (pOutput.type() == Output::Object)
      return context->getSectionIdx(".symtab");
    else
      return context->getSectionIdx(".dynsym");
  }
  return llvm::ELF::SHN_UNDEF;
}

/// getSectInfo - compute ElfXX_Shdr::sh_info
uint64_t ELFWriter::getSectInfo(const LDSection& pSection, const Output& pOutput) const
{
  const LDSection* info_link = pSection.getLink();
  if (NULL == info_link)
    return 0x0;
  return info_link->index();
}

/// getELF32LastStartOffset
uint64_t ELFWriter::getELF32LastStartOffset(const Output& pOutput) const
{
  LDSection* lastSect = pOutput.context()->getSectionTable().back();
  assert(lastSect != NULL);
  return Align<32>(lastSect->offset() + lastSect->size());
}

/// getELF64LastStartOffset
uint64_t ELFWriter::getELF64LastStartOffset(const Output& pOutput) const
{
  LDSection* lastSect = pOutput.context()->getSectionTable().back();
  assert(lastSect != NULL);
  return Align<64>(lastSect->offset() + lastSect->size());
}

