//===- ELFReader.cpp ------------------------------------------------------===//
//
//                     The MCLinker Project
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#include <mcld/LD/ELFReader.h>

#include <mcld/IRBuilder.h>
#include <mcld/Fragment/FillFragment.h>
#include <mcld/LD/EhFrame.h>
#include <mcld/LD/SectionData.h>
#include <mcld/Target/GNULDBackend.h>
#include <mcld/Support/MemoryRegion.h>
#include <mcld/Support/MsgHandling.h>
#include <mcld/Object/ObjectBuilder.h>

#include <cstring>

#include <llvm/ADT/StringRef.h>
#include <llvm/ADT/Twine.h>
#include <llvm/Support/ELF.h>
#include <llvm/Support/Host.h>

#include <iostream>

using namespace mcld;

//===----------------------------------------------------------------------===//
// ELFReader<32, true>
//===----------------------------------------------------------------------===//
/// constructor
ELFReader<32, true>::ELFReader(GNULDBackend& pBackend)
  : ELFReaderIF(pBackend) {
}

/// destructor
ELFReader<32, true>::~ELFReader()
{
}

/// isELF - is this a ELF file
bool ELFReader<32, true>::isELF(void* pELFHeader) const
{
  llvm::ELF::Elf32_Ehdr* hdr =
                          reinterpret_cast<llvm::ELF::Elf32_Ehdr*>(pELFHeader);
  if (0 == memcmp(llvm::ELF::ElfMagic, hdr, 4))
    return true;
  return false;
}

/// readRegularSection - read a regular section and create fragments.
bool
ELFReader<32, true>::readRegularSection(Input& pInput, SectionData& pSD) const
{
  uint32_t offset = pInput.fileOffset() + pSD.getSection().offset();
  uint32_t size = pSD.getSection().size();

  Fragment* frag = IRBuilder::CreateRegion(pInput, offset, size);
  ObjectBuilder::AppendFragment(*frag, pSD);
  return true;
}

/// readSymbols - read ELF symbols and create LDSymbol
bool ELFReader<32, true>::readSymbols(Input& pInput,
                                      IRBuilder& pBuilder,
                                      const MemoryRegion& pRegion,
                                      const char* pStrTab) const
{
  // get number of symbols
  size_t entsize = pRegion.size()/sizeof(llvm::ELF::Elf32_Sym);
  const llvm::ELF::Elf32_Sym* symtab =
                 reinterpret_cast<const llvm::ELF::Elf32_Sym*>(pRegion.start());

  uint32_t st_name  = 0x0;
  uint32_t st_value = 0x0;
  uint32_t st_size  = 0x0;
  uint8_t  st_info  = 0x0;
  uint8_t  st_other = 0x0;
  uint16_t st_shndx = 0x0;

  // skip the first NULL symbol
  pInput.context()->addSymbol(LDSymbol::Null());

  for (size_t idx = 1; idx < entsize; ++idx) {
    st_info  = symtab[idx].st_info;
    st_other = symtab[idx].st_other;

    if (llvm::sys::isLittleEndianHost()) {
      st_name  = symtab[idx].st_name;
      st_value = symtab[idx].st_value;
      st_size  = symtab[idx].st_size;
      st_shndx = symtab[idx].st_shndx;
    }
    else {
      st_name  = mcld::bswap32(symtab[idx].st_name);
      st_value = mcld::bswap32(symtab[idx].st_value);
      st_size  = mcld::bswap32(symtab[idx].st_size);
      st_shndx = mcld::bswap16(symtab[idx].st_shndx);
    }

    // If the section should not be included, set the st_shndx SHN_UNDEF
    // - A section in interrelated groups are not included.
    if (pInput.type() == Input::Object &&
        st_shndx < llvm::ELF::SHN_LORESERVE &&
        st_shndx != llvm::ELF::SHN_UNDEF) {
      if (NULL == pInput.context()->getSection(st_shndx))
        st_shndx = llvm::ELF::SHN_UNDEF;
    }

    // get ld_type
    ResolveInfo::Type ld_type = getSymType(st_info, st_shndx);

    // get ld_desc
    ResolveInfo::Desc ld_desc = getSymDesc(st_shndx, pInput);

    // get ld_binding
    ResolveInfo::Binding ld_binding = getSymBinding((st_info >> 4), st_shndx, st_other);

    // get ld_value - ld_value must be section relative.
    uint64_t ld_value = getSymValue(st_value, st_shndx, pInput);

    // get ld_vis
    ResolveInfo::Visibility ld_vis = getSymVisibility(st_other);

    // get section
    LDSection* section = NULL;
    if (st_shndx < llvm::ELF::SHN_LORESERVE) // including ABS and COMMON
      section = pInput.context()->getSection(st_shndx);

    // get ld_name
    std::string ld_name;
    if (ResolveInfo::Section == ld_type) {
      // Section symbol's st_name is the section index.
      assert(NULL != section && "get a invalid section");
      ld_name = section->name();
    }
    else {
      ld_name = std::string(pStrTab + st_name);
    }

    pBuilder.AddSymbol(pInput,
                       ld_name,
                       ld_type,
                       ld_desc,
                       ld_binding,
                       st_size,
                       ld_value,
                       section, ld_vis);
  } // end of for loop
  return true;
}

//===----------------------------------------------------------------------===//
// ELFReader::read relocations - read ELF rela and rel, and create Relocation
//===----------------------------------------------------------------------===//
/// ELFReader::readRela - read ELF rela and create Relocation
bool ELFReader<32, true>::readRela(Input& pInput,
                                   LDSection& pSection,
                                   const MemoryRegion& pRegion) const
{
  // get the number of rela
  size_t entsize = pRegion.size() / sizeof(llvm::ELF::Elf32_Rela);
  const llvm::ELF::Elf32_Rela* relaTab =
                reinterpret_cast<const llvm::ELF::Elf32_Rela*>(pRegion.start());

  for (size_t idx=0; idx < entsize; ++idx) {
    uint32_t r_offset = 0x0;
    uint32_t r_info   = 0x0;
    int32_t  r_addend = 0;
    if (llvm::sys::isLittleEndianHost()) {
      r_offset = relaTab[idx].r_offset;
      r_info   = relaTab[idx].r_info;
      r_addend = relaTab[idx].r_addend;
    }
    else {
      r_offset = mcld::bswap32(relaTab[idx].r_offset);
      r_info   = mcld::bswap32(relaTab[idx].r_info);
      r_addend = mcld::bswap32(relaTab[idx].r_addend);
    }

    uint8_t  r_type = static_cast<unsigned char>(r_info);
    uint32_t r_sym  = (r_info >> 8);
    LDSymbol* symbol = pInput.context()->getSymbol(r_sym);
    if (NULL == symbol) {
      fatal(diag::err_cannot_read_symbol) << r_sym << pInput.path();
    }

    IRBuilder::AddRelocation(pSection, r_type, *symbol, r_offset, r_addend);
  } // end of for
  return true;
}

/// readRel - read ELF rel and create Relocation
bool ELFReader<32, true>::readRel(Input& pInput,
                                  LDSection& pSection,
                                  const MemoryRegion& pRegion) const
{
  // get the number of rel
  size_t entsize = pRegion.size() / sizeof(llvm::ELF::Elf32_Rel);
  const llvm::ELF::Elf32_Rel* relTab =
                 reinterpret_cast<const llvm::ELF::Elf32_Rel*>(pRegion.start());

  for (size_t idx=0; idx < entsize; ++idx) {
    uint32_t r_offset = 0x0;
    uint32_t r_info   = 0x0;
    if (llvm::sys::isLittleEndianHost()) {
      r_offset = relTab[idx].r_offset;
      r_info   = relTab[idx].r_info;
    }
    else {
      r_offset = mcld::bswap32(relTab[idx].r_offset);
      r_info   = mcld::bswap32(relTab[idx].r_info);
    }

    uint8_t  r_type = static_cast<unsigned char>(r_info);
    uint32_t r_sym  = (r_info >> 8);

    LDSymbol* symbol = pInput.context()->getSymbol(r_sym);
    if (NULL == symbol) {
      fatal(diag::err_cannot_read_symbol) << r_sym << pInput.path();
    }

    IRBuilder::AddRelocation(pSection, r_type, *symbol, r_offset);
  } // end of for
  return true;
}

/// isMyEndian - is this ELF file in the same endian to me?
bool ELFReader<32, true>::isMyEndian(void* pELFHeader) const
{
  llvm::ELF::Elf32_Ehdr* hdr =
                          reinterpret_cast<llvm::ELF::Elf32_Ehdr*>(pELFHeader);

  return (hdr->e_ident[llvm::ELF::EI_DATA] == llvm::ELF::ELFDATA2LSB);
}

/// isMyMachine - is this ELF file generated for the same machine.
bool ELFReader<32, true>::isMyMachine(void* pELFHeader) const
{
  llvm::ELF::Elf32_Ehdr* hdr =
                          reinterpret_cast<llvm::ELF::Elf32_Ehdr*>(pELFHeader);

  if (llvm::sys::isLittleEndianHost())
    return (hdr->e_machine == target().getInfo().machine());
  return (mcld::bswap16(hdr->e_machine) == target().getInfo().machine());
}

/// fileType - return the file type
Input::Type ELFReader<32, true>::fileType(void* pELFHeader) const
{
  llvm::ELF::Elf32_Ehdr* hdr =
                          reinterpret_cast<llvm::ELF::Elf32_Ehdr*>(pELFHeader);
  uint32_t type = 0x0;
  if (llvm::sys::isLittleEndianHost())
    type = hdr->e_type;
  else
    type = mcld::bswap16(hdr->e_type);

  switch(type) {
  case llvm::ELF::ET_REL:
    return Input::Object;
  case llvm::ELF::ET_EXEC:
    return Input::Exec;
  case llvm::ELF::ET_DYN:
    return Input::DynObj;
  case llvm::ELF::ET_CORE:
    return Input::CoreFile;
  case llvm::ELF::ET_NONE:
  default:
    return Input::Unknown;
  }
}

/// readSectionHeaders - read ELF section header table and create LDSections
bool
ELFReader<32, true>::readSectionHeaders(Input& pInput, void* pELFHeader) const
{
  llvm::ELF::Elf32_Ehdr* ehdr =
                          reinterpret_cast<llvm::ELF::Elf32_Ehdr*>(pELFHeader);

  uint32_t shoff     = 0x0;
  uint16_t shentsize = 0x0;
  uint32_t shnum     = 0x0;
  uint32_t shstrtab  = 0x0;

  if (llvm::sys::isLittleEndianHost()) {
    shoff     = ehdr->e_shoff;
    shentsize = ehdr->e_shentsize;
    shnum     = ehdr->e_shnum;
    shstrtab  = ehdr->e_shstrndx;
  }
  else {
    shoff     = mcld::bswap32(ehdr->e_shoff);
    shentsize = mcld::bswap16(ehdr->e_shentsize);
    shnum     = mcld::bswap16(ehdr->e_shnum);
    shstrtab  = mcld::bswap16(ehdr->e_shstrndx);
  }

  // If the file has no section header table, e_shoff holds zero.
  if (0x0 == shoff)
    return true;

  llvm::ELF::Elf32_Shdr *shdr = NULL;
  MemoryRegion* shdr_region = NULL;
  uint32_t sh_name      = 0x0;
  uint32_t sh_type      = 0x0;
  uint32_t sh_flags     = 0x0;
  uint32_t sh_offset    = 0x0;
  uint32_t sh_size      = 0x0;
  uint32_t sh_link      = 0x0;
  uint32_t sh_info      = 0x0;
  uint32_t sh_addralign = 0x0;

  // if shnum and shstrtab overflow, the actual values are in the 1st shdr
  if (shnum == llvm::ELF::SHN_UNDEF || shstrtab == llvm::ELF::SHN_XINDEX) {
    shdr_region = pInput.memArea()->request(pInput.fileOffset() + shoff,
                                            shentsize);
    shdr = reinterpret_cast<llvm::ELF::Elf32_Shdr*>(shdr_region->start());

    if (llvm::sys::isLittleEndianHost()) {
      sh_size = shdr->sh_size;
      sh_link = shdr->sh_link;
    }
    else {
      sh_size = mcld::bswap32(shdr->sh_size);
      sh_link = mcld::bswap32(shdr->sh_link);
    }
    pInput.memArea()->release(shdr_region);

    if (shnum == llvm::ELF::SHN_UNDEF)
      shnum = sh_size;
    if (shstrtab == llvm::ELF::SHN_XINDEX)
      shstrtab = sh_link;

    shoff += shentsize;
  }

  shdr_region = pInput.memArea()->request(pInput.fileOffset() + shoff,
                                          shnum * shentsize);
  llvm::ELF::Elf32_Shdr * shdrTab =
    reinterpret_cast<llvm::ELF::Elf32_Shdr*>(shdr_region->start());

  // get .shstrtab first
  shdr = &shdrTab[shstrtab];
  if (llvm::sys::isLittleEndianHost()) {
    sh_offset = shdr->sh_offset;
    sh_size   = shdr->sh_size;
  }
  else {
    sh_offset = mcld::bswap32(shdr->sh_offset);
    sh_size   = mcld::bswap32(shdr->sh_size);
  }

  MemoryRegion* sect_name_region = pInput.memArea()->request(
                                      pInput.fileOffset() + sh_offset, sh_size);
  const char* sect_name =
                       reinterpret_cast<const char*>(sect_name_region->start());

  LinkInfoList link_info_list;

  // create all LDSections, including first NULL section.
  for (size_t idx = 0; idx < shnum; ++idx) {
    if (llvm::sys::isLittleEndianHost()) {
      sh_name      = shdrTab[idx].sh_name;
      sh_type      = shdrTab[idx].sh_type;
      sh_flags     = shdrTab[idx].sh_flags;
      sh_offset    = shdrTab[idx].sh_offset;
      sh_size      = shdrTab[idx].sh_size;
      sh_link      = shdrTab[idx].sh_link;
      sh_info      = shdrTab[idx].sh_info;
      sh_addralign = shdrTab[idx].sh_addralign;
    }
    else {
      sh_name      = mcld::bswap32(shdrTab[idx].sh_name);
      sh_type      = mcld::bswap32(shdrTab[idx].sh_type);
      sh_flags     = mcld::bswap32(shdrTab[idx].sh_flags);
      sh_offset    = mcld::bswap32(shdrTab[idx].sh_offset);
      sh_size      = mcld::bswap32(shdrTab[idx].sh_size);
      sh_link      = mcld::bswap32(shdrTab[idx].sh_link);
      sh_info      = mcld::bswap32(shdrTab[idx].sh_info);
      sh_addralign = mcld::bswap32(shdrTab[idx].sh_addralign);
    }

    LDSection* section = IRBuilder::CreateELFHeader(pInput,
                                                    sect_name+sh_name,
                                                    sh_type,
                                                    sh_flags,
                                                    sh_addralign);
    section->setSize(sh_size);
    section->setOffset(sh_offset);
    section->setInfo(sh_info);

    if (sh_link != 0x0 || sh_info != 0x0) {
      LinkInfo link_info = { section, sh_link, sh_info };
      link_info_list.push_back(link_info);
    }
  } // end of for

  // set up InfoLink
  LinkInfoList::iterator info, infoEnd = link_info_list.end();
  for (info = link_info_list.begin(); info != infoEnd; ++info) {
    if (LDFileFormat::NamePool == info->section->kind() ||
        LDFileFormat::Group == info->section->kind() ||
        LDFileFormat::Note == info->section->kind()) {
      info->section->setLink(pInput.context()->getSection(info->sh_link));
      continue;
    }
    if (LDFileFormat::Relocation == info->section->kind()) {
      info->section->setLink(pInput.context()->getSection(info->sh_info));
      continue;
    }
  }

  pInput.memArea()->release(shdr_region);
  pInput.memArea()->release(sect_name_region);

  return true;
}

/// readSignature - read a symbol from the given Input and index in symtab
/// This is used to get the signature of a group section.
ResolveInfo* ELFReader<32, true>::readSignature(Input& pInput,
                                                LDSection& pSymTab,
                                                uint32_t pSymIdx) const
{
  LDSection* symtab = &pSymTab;
  LDSection* strtab = symtab->getLink();
  assert(NULL != symtab && NULL != strtab);

  uint32_t offset = pInput.fileOffset() + symtab->offset() +
                      sizeof(llvm::ELF::Elf32_Sym) * pSymIdx;
  MemoryRegion* symbol_region =
                pInput.memArea()->request(offset, sizeof(llvm::ELF::Elf32_Sym));
  llvm::ELF::Elf32_Sym* entry =
                reinterpret_cast<llvm::ELF::Elf32_Sym*>(symbol_region->start());

  uint32_t st_name  = 0x0;
  uint8_t  st_info  = 0x0;
  uint8_t  st_other = 0x0;
  uint16_t st_shndx = 0x0;
  st_info  = entry->st_info;
  st_other = entry->st_other;
  if (llvm::sys::isLittleEndianHost()) {
    st_name  = entry->st_name;
    st_shndx = entry->st_shndx;
  }
  else {
    st_name  = mcld::bswap32(entry->st_name);
    st_shndx = mcld::bswap16(entry->st_shndx);
  }

  MemoryRegion* strtab_region = pInput.memArea()->request(
                       pInput.fileOffset() + strtab->offset(), strtab->size());

  // get ld_name
  llvm::StringRef ld_name(
                    reinterpret_cast<char*>(strtab_region->start() + st_name));

  ResolveInfo* result = ResolveInfo::Create(ld_name);
  result->setSource(pInput.type() == Input::DynObj);
  result->setType(static_cast<ResolveInfo::Type>(st_info & 0xF));
  result->setDesc(getSymDesc(st_shndx, pInput));
  result->setBinding(getSymBinding((st_info >> 4), st_shndx, st_other));
  result->setVisibility(getSymVisibility(st_other));

  // release regions
  pInput.memArea()->release(symbol_region);
  pInput.memArea()->release(strtab_region);

  return result;
}

/// readDynamic - read ELF .dynamic in input dynobj
bool ELFReader<32, true>::readDynamic(Input& pInput) const
{
  assert(pInput.type() == Input::DynObj);
  const LDSection* dynamic_sect = pInput.context()->getSection(".dynamic");
  if (NULL == dynamic_sect) {
    fatal(diag::err_cannot_read_section) << ".dynamic";
  }
  const LDSection* dynstr_sect = dynamic_sect->getLink();
  if (NULL == dynstr_sect) {
    fatal(diag::err_cannot_read_section) << ".dynstr";
  }

  MemoryRegion* dynamic_region = pInput.memArea()->request(
           pInput.fileOffset() + dynamic_sect->offset(), dynamic_sect->size());

  MemoryRegion* dynstr_region = pInput.memArea()->request(
             pInput.fileOffset() + dynstr_sect->offset(), dynstr_sect->size());

  assert(NULL != dynamic_region && NULL != dynstr_region);

  const llvm::ELF::Elf32_Dyn* dynamic =
    (llvm::ELF::Elf32_Dyn*) dynamic_region->start();
  const char* dynstr = (const char*) dynstr_region->start();
  bool hasSOName = false;
  size_t numOfEntries = dynamic_sect->size() / sizeof(llvm::ELF::Elf32_Dyn);

  for (size_t idx = 0; idx < numOfEntries; ++idx) {

    llvm::ELF::Elf32_Sword d_tag = 0x0;
    llvm::ELF::Elf32_Word d_val = 0x0;

    if (llvm::sys::isLittleEndianHost()) {
      d_tag = dynamic[idx].d_tag;
      d_val = dynamic[idx].d_un.d_val;
    } else {
      d_tag = mcld::bswap32(dynamic[idx].d_tag);
      d_val = mcld::bswap32(dynamic[idx].d_un.d_val);
    }

    switch (d_tag) {
      case llvm::ELF::DT_SONAME:
        assert(d_val < dynstr_sect->size());
        pInput.setName(sys::fs::Path(dynstr + d_val).filename().native());
        hasSOName = true;
        break;
      case llvm::ELF::DT_NEEDED:
        // TODO:
        break;
      case llvm::ELF::DT_NULL:
      default:
        break;
    }
  }

  // if there is no SONAME in .dynamic, then set it from input path
  if (!hasSOName)
    pInput.setName(pInput.path().filename().native());

  pInput.memArea()->release(dynamic_region);
  pInput.memArea()->release(dynstr_region);
  return true;
}

//===----------------------------------------------------------------------===//
// ELFReader<64, true>
//===----------------------------------------------------------------------===//
/// constructor
ELFReader<64, true>::ELFReader(GNULDBackend& pBackend)
  : ELFReaderIF(pBackend) {
}

/// destructor
ELFReader<64, true>::~ELFReader()
{
}

/// isELF - is this a ELF file
bool ELFReader<64, true>::isELF(void* pELFHeader) const
{
  llvm::ELF::Elf64_Ehdr* hdr =
                          reinterpret_cast<llvm::ELF::Elf64_Ehdr*>(pELFHeader);
  if (0 == memcmp(llvm::ELF::ElfMagic, hdr, 4))
    return true;
  return false;
}

/// readRegularSection - read a regular section and create fragments.
bool
ELFReader<64, true>::readRegularSection(Input& pInput, SectionData& pSD) const
{
  uint64_t offset = pInput.fileOffset() + pSD.getSection().offset();
  uint64_t size = pSD.getSection().size();

  Fragment* frag = IRBuilder::CreateRegion(pInput, offset, size);
  ObjectBuilder::AppendFragment(*frag, pSD);
  return true;
}

/// readSymbols - read ELF symbols and create LDSymbol
bool ELFReader<64, true>::readSymbols(Input& pInput,
                                      IRBuilder& pBuilder,
                                      const MemoryRegion& pRegion,
                                      const char* pStrTab) const
{
  // get number of symbols
  size_t entsize = pRegion.size()/sizeof(llvm::ELF::Elf64_Sym);
  const llvm::ELF::Elf64_Sym* symtab =
                 reinterpret_cast<const llvm::ELF::Elf64_Sym*>(pRegion.start());

  uint32_t st_name  = 0x0;
  uint64_t st_value = 0x0;
  uint64_t st_size  = 0x0;
  uint8_t  st_info  = 0x0;
  uint8_t  st_other = 0x0;
  uint16_t st_shndx = 0x0;

  // skip the first NULL symbol
  pInput.context()->addSymbol(LDSymbol::Null());

  for (size_t idx = 1; idx < entsize; ++idx) {
    st_info  = symtab[idx].st_info;
    st_other = symtab[idx].st_other;

    if (llvm::sys::isLittleEndianHost()) {
      st_name  = symtab[idx].st_name;
      st_value = symtab[idx].st_value;
      st_size  = symtab[idx].st_size;
      st_shndx = symtab[idx].st_shndx;
    }
    else {
      st_name  = mcld::bswap32(symtab[idx].st_name);
      st_value = mcld::bswap64(symtab[idx].st_value);
      st_size  = mcld::bswap64(symtab[idx].st_size);
      st_shndx = mcld::bswap16(symtab[idx].st_shndx);
    }

    // If the section should not be included, set the st_shndx SHN_UNDEF
    // - A section in interrelated groups are not included.
    if (pInput.type() == Input::Object &&
        st_shndx < llvm::ELF::SHN_LORESERVE &&
        st_shndx != llvm::ELF::SHN_UNDEF) {
      if (NULL == pInput.context()->getSection(st_shndx))
        st_shndx = llvm::ELF::SHN_UNDEF;
    }

    // get ld_type
    ResolveInfo::Type ld_type = getSymType(st_info, st_shndx);

    // get ld_desc
    ResolveInfo::Desc ld_desc = getSymDesc(st_shndx, pInput);

    // get ld_binding
    ResolveInfo::Binding ld_binding = getSymBinding((st_info >> 4), st_shndx, st_other);

    // get ld_value - ld_value must be section relative.
    uint64_t ld_value = getSymValue(st_value, st_shndx, pInput);

    // get ld_vis
    ResolveInfo::Visibility ld_vis = getSymVisibility(st_other);

    // get section
    LDSection* section = NULL;
    if (st_shndx < llvm::ELF::SHN_LORESERVE) // including ABS and COMMON
      section = pInput.context()->getSection(st_shndx);

    // get ld_name
    std::string ld_name;
    if (ResolveInfo::Section == ld_type) {
      // Section symbol's st_name is the section index.
      assert(NULL != section && "get a invalid section");
      ld_name = section->name();
    }
    else {
      ld_name = std::string(pStrTab + st_name);
    }

    pBuilder.AddSymbol(pInput,
                       ld_name,
                       ld_type,
                       ld_desc,
                       ld_binding,
                       st_size,
                       ld_value,
                       section, ld_vis);
  } // end of for loop
  return true;
}

//===----------------------------------------------------------------------===//
// ELFReader::read relocations - read ELF rela and rel, and create Relocation
//===----------------------------------------------------------------------===//
/// ELFReader::readRela - read ELF rela and create Relocation
bool ELFReader<64, true>::readRela(Input& pInput,
                                   LDSection& pSection,
                                   const MemoryRegion& pRegion) const
{
  // get the number of rela
  size_t entsize = pRegion.size() / sizeof(llvm::ELF::Elf64_Rela);
  const llvm::ELF::Elf64_Rela* relaTab =
                reinterpret_cast<const llvm::ELF::Elf64_Rela*>(pRegion.start());

  for (size_t idx=0; idx < entsize; ++idx) {
    uint64_t r_offset = 0x0;
    uint64_t r_info   = 0x0;
    int64_t  r_addend = 0;
    if (llvm::sys::isLittleEndianHost()) {
      r_offset = relaTab[idx].r_offset;
      r_info   = relaTab[idx].r_info;
      r_addend = relaTab[idx].r_addend;
    }
    else {
      r_offset = mcld::bswap64(relaTab[idx].r_offset);
      r_info   = mcld::bswap64(relaTab[idx].r_info);
      r_addend = mcld::bswap64(relaTab[idx].r_addend);
    }

    uint32_t  r_type = static_cast<uint32_t>(r_info);
    uint32_t r_sym  = (r_info >> 32);
    LDSymbol* symbol = pInput.context()->getSymbol(r_sym);
    if (NULL == symbol) {
      fatal(diag::err_cannot_read_symbol) << r_sym << pInput.path();
    }

    IRBuilder::AddRelocation(pSection, r_type, *symbol, r_offset, r_addend);
  } // end of for
  return true;
}

/// readRel - read ELF rel and create Relocation
bool ELFReader<64, true>::readRel(Input& pInput,
                                  LDSection& pSection,
                                  const MemoryRegion& pRegion) const
{
  // get the number of rel
  size_t entsize = pRegion.size() / sizeof(llvm::ELF::Elf64_Rel);
  const llvm::ELF::Elf64_Rel* relTab =
                 reinterpret_cast<const llvm::ELF::Elf64_Rel*>(pRegion.start());

  for (size_t idx=0; idx < entsize; ++idx) {
    uint64_t r_offset = 0x0;
    uint64_t r_info   = 0x0;
    if (llvm::sys::isLittleEndianHost()) {
      r_offset = relTab[idx].r_offset;
      r_info   = relTab[idx].r_info;
    }
    else {
      r_offset = mcld::bswap64(relTab[idx].r_offset);
      r_info   = mcld::bswap64(relTab[idx].r_info);
    }

    uint32_t  r_type = static_cast<uint32_t>(r_info);
    uint32_t r_sym  = (r_info >> 32);

    LDSymbol* symbol = pInput.context()->getSymbol(r_sym);
    if (NULL == symbol) {
      fatal(diag::err_cannot_read_symbol) << r_sym << pInput.path();
    }

    IRBuilder::AddRelocation(pSection, r_type, *symbol, r_offset);
  } // end of for
  return true;
}

/// isMyEndian - is this ELF file in the same endian to me?
bool ELFReader<64, true>::isMyEndian(void* pELFHeader) const
{
  llvm::ELF::Elf64_Ehdr* hdr =
                          reinterpret_cast<llvm::ELF::Elf64_Ehdr*>(pELFHeader);

  return (hdr->e_ident[llvm::ELF::EI_DATA] == llvm::ELF::ELFDATA2LSB);
}

/// isMyMachine - is this ELF file generated for the same machine.
bool ELFReader<64, true>::isMyMachine(void* pELFHeader) const
{
  llvm::ELF::Elf64_Ehdr* hdr =
                          reinterpret_cast<llvm::ELF::Elf64_Ehdr*>(pELFHeader);

  if (llvm::sys::isLittleEndianHost())
    return (hdr->e_machine == target().getInfo().machine());
  return (mcld::bswap16(hdr->e_machine) == target().getInfo().machine());
}

/// fileType - return the file type
Input::Type ELFReader<64, true>::fileType(void* pELFHeader) const
{
  llvm::ELF::Elf64_Ehdr* hdr =
                          reinterpret_cast<llvm::ELF::Elf64_Ehdr*>(pELFHeader);
  uint32_t type = 0x0;
  if (llvm::sys::isLittleEndianHost())
    type = hdr->e_type;
  else
    type = mcld::bswap16(hdr->e_type);

  switch(type) {
  case llvm::ELF::ET_REL:
    return Input::Object;
  case llvm::ELF::ET_EXEC:
    return Input::Exec;
  case llvm::ELF::ET_DYN:
    return Input::DynObj;
  case llvm::ELF::ET_CORE:
    return Input::CoreFile;
  case llvm::ELF::ET_NONE:
  default:
    return Input::Unknown;
  }
}

/// readSectionHeaders - read ELF section header table and create LDSections
bool
ELFReader<64, true>::readSectionHeaders(Input& pInput, void* pELFHeader) const
{
  llvm::ELF::Elf64_Ehdr* ehdr =
                          reinterpret_cast<llvm::ELF::Elf64_Ehdr*>(pELFHeader);

  uint64_t shoff     = 0x0;
  uint16_t shentsize = 0x0;
  uint32_t shnum     = 0x0;
  uint32_t shstrtab  = 0x0;

  if (llvm::sys::isLittleEndianHost()) {
    shoff     = ehdr->e_shoff;
    shentsize = ehdr->e_shentsize;
    shnum     = ehdr->e_shnum;
    shstrtab  = ehdr->e_shstrndx;
  }
  else {
    shoff     = mcld::bswap64(ehdr->e_shoff);
    shentsize = mcld::bswap16(ehdr->e_shentsize);
    shnum     = mcld::bswap16(ehdr->e_shnum);
    shstrtab  = mcld::bswap16(ehdr->e_shstrndx);
  }

  // If the file has no section header table, e_shoff holds zero.
  if (0x0 == shoff)
    return true;

  llvm::ELF::Elf64_Shdr *shdr = NULL;
  MemoryRegion* shdr_region = NULL;
  uint32_t sh_name      = 0x0;
  uint32_t sh_type      = 0x0;
  uint64_t sh_flags     = 0x0;
  uint64_t sh_offset    = 0x0;
  uint64_t sh_size      = 0x0;
  uint32_t sh_link      = 0x0;
  uint32_t sh_info      = 0x0;
  uint64_t sh_addralign = 0x0;

  // if shnum and shstrtab overflow, the actual values are in the 1st shdr
  if (shnum == llvm::ELF::SHN_UNDEF || shstrtab == llvm::ELF::SHN_XINDEX) {
    shdr_region = pInput.memArea()->request(pInput.fileOffset() + shoff,
                                            shentsize);
    shdr = reinterpret_cast<llvm::ELF::Elf64_Shdr*>(shdr_region->start());

    if (llvm::sys::isLittleEndianHost()) {
      sh_size = shdr->sh_size;
      sh_link = shdr->sh_link;
    }
    else {
      sh_size = mcld::bswap64(shdr->sh_size);
      sh_link = mcld::bswap32(shdr->sh_link);
    }
    pInput.memArea()->release(shdr_region);

    if (shnum == llvm::ELF::SHN_UNDEF)
      shnum = sh_size;
    if (shstrtab == llvm::ELF::SHN_XINDEX)
      shstrtab = sh_link;

    shoff += shentsize;
  }

  shdr_region = pInput.memArea()->request(pInput.fileOffset() + shoff,
                                          shnum * shentsize);
  llvm::ELF::Elf64_Shdr * shdrTab =
    reinterpret_cast<llvm::ELF::Elf64_Shdr*>(shdr_region->start());

  // get .shstrtab first
  shdr = &shdrTab[shstrtab];
  if (llvm::sys::isLittleEndianHost()) {
    sh_offset = shdr->sh_offset;
    sh_size   = shdr->sh_size;
  }
  else {
    sh_offset = mcld::bswap64(shdr->sh_offset);
    sh_size   = mcld::bswap64(shdr->sh_size);
  }

  MemoryRegion* sect_name_region = pInput.memArea()->request(
                                      pInput.fileOffset() + sh_offset, sh_size);
  const char* sect_name =
                       reinterpret_cast<const char*>(sect_name_region->start());

  LinkInfoList link_info_list;

  // create all LDSections, including first NULL section.
  for (size_t idx = 0; idx < shnum; ++idx) {
    if (llvm::sys::isLittleEndianHost()) {
      sh_name      = shdrTab[idx].sh_name;
      sh_type      = shdrTab[idx].sh_type;
      sh_flags     = shdrTab[idx].sh_flags;
      sh_offset    = shdrTab[idx].sh_offset;
      sh_size      = shdrTab[idx].sh_size;
      sh_link      = shdrTab[idx].sh_link;
      sh_info      = shdrTab[idx].sh_info;
      sh_addralign = shdrTab[idx].sh_addralign;
    }
    else {
      sh_name      = mcld::bswap32(shdrTab[idx].sh_name);
      sh_type      = mcld::bswap32(shdrTab[idx].sh_type);
      sh_flags     = mcld::bswap64(shdrTab[idx].sh_flags);
      sh_offset    = mcld::bswap64(shdrTab[idx].sh_offset);
      sh_size      = mcld::bswap64(shdrTab[idx].sh_size);
      sh_link      = mcld::bswap32(shdrTab[idx].sh_link);
      sh_info      = mcld::bswap32(shdrTab[idx].sh_info);
      sh_addralign = mcld::bswap64(shdrTab[idx].sh_addralign);
    }

    LDSection* section = IRBuilder::CreateELFHeader(pInput,
                                                    sect_name+sh_name,
                                                    sh_type,
                                                    sh_flags,
                                                    sh_addralign);
    section->setSize(sh_size);
    section->setOffset(sh_offset);
    section->setInfo(sh_info);

    if (sh_link != 0x0 || sh_info != 0x0) {
      LinkInfo link_info = { section, sh_link, sh_info };
      link_info_list.push_back(link_info);
    }
  } // end of for

  // set up InfoLink
  LinkInfoList::iterator info, infoEnd = link_info_list.end();
  for (info = link_info_list.begin(); info != infoEnd; ++info) {
    if (LDFileFormat::NamePool == info->section->kind() ||
        LDFileFormat::Group == info->section->kind() ||
        LDFileFormat::Note == info->section->kind()) {
      info->section->setLink(pInput.context()->getSection(info->sh_link));
      continue;
    }
    if (LDFileFormat::Relocation == info->section->kind()) {
      info->section->setLink(pInput.context()->getSection(info->sh_info));
      continue;
    }
  }

  pInput.memArea()->release(shdr_region);
  pInput.memArea()->release(sect_name_region);

  return true;
}

/// readSignature - read a symbol from the given Input and index in symtab
/// This is used to get the signature of a group section.
ResolveInfo* ELFReader<64, true>::readSignature(Input& pInput,
                                                LDSection& pSymTab,
                                                uint32_t pSymIdx) const
{
  LDSection* symtab = &pSymTab;
  LDSection* strtab = symtab->getLink();
  assert(NULL != symtab && NULL != strtab);

  uint64_t offset = pInput.fileOffset() + symtab->offset() +
                      sizeof(llvm::ELF::Elf64_Sym) * pSymIdx;
  MemoryRegion* symbol_region =
                pInput.memArea()->request(offset, sizeof(llvm::ELF::Elf64_Sym));
  llvm::ELF::Elf64_Sym* entry =
                reinterpret_cast<llvm::ELF::Elf64_Sym*>(symbol_region->start());

  uint32_t st_name  = 0x0;
  uint8_t  st_info  = 0x0;
  uint8_t  st_other = 0x0;
  uint16_t st_shndx = 0x0;
  st_info  = entry->st_info;
  st_other = entry->st_other;
  if (llvm::sys::isLittleEndianHost()) {
    st_name  = entry->st_name;
    st_shndx = entry->st_shndx;
  }
  else {
    st_name  = mcld::bswap32(entry->st_name);
    st_shndx = mcld::bswap16(entry->st_shndx);
  }

  MemoryRegion* strtab_region = pInput.memArea()->request(
                       pInput.fileOffset() + strtab->offset(), strtab->size());

  // get ld_name
  llvm::StringRef ld_name(
                    reinterpret_cast<char*>(strtab_region->start() + st_name));

  ResolveInfo* result = ResolveInfo::Create(ld_name);
  result->setSource(pInput.type() == Input::DynObj);
  result->setType(static_cast<ResolveInfo::Type>(st_info & 0xF));
  result->setDesc(getSymDesc(st_shndx, pInput));
  result->setBinding(getSymBinding((st_info >> 4), st_shndx, st_other));
  result->setVisibility(getSymVisibility(st_other));

  // release regions
  pInput.memArea()->release(symbol_region);
  pInput.memArea()->release(strtab_region);

  return result;
}

/// readDynamic - read ELF .dynamic in input dynobj
bool ELFReader<64, true>::readDynamic(Input& pInput) const
{
  assert(pInput.type() == Input::DynObj);
  const LDSection* dynamic_sect = pInput.context()->getSection(".dynamic");
  if (NULL == dynamic_sect) {
    fatal(diag::err_cannot_read_section) << ".dynamic";
  }
  const LDSection* dynstr_sect = dynamic_sect->getLink();
  if (NULL == dynstr_sect) {
    fatal(diag::err_cannot_read_section) << ".dynstr";
  }

  MemoryRegion* dynamic_region = pInput.memArea()->request(
           pInput.fileOffset() + dynamic_sect->offset(), dynamic_sect->size());

  MemoryRegion* dynstr_region = pInput.memArea()->request(
             pInput.fileOffset() + dynstr_sect->offset(), dynstr_sect->size());

  assert(NULL != dynamic_region && NULL != dynstr_region);

  const llvm::ELF::Elf64_Dyn* dynamic =
    (llvm::ELF::Elf64_Dyn*) dynamic_region->start();
  const char* dynstr = (const char*) dynstr_region->start();
  bool hasSOName = false;
  size_t numOfEntries = dynamic_sect->size() / sizeof(llvm::ELF::Elf64_Dyn);

  for (size_t idx = 0; idx < numOfEntries; ++idx) {

    llvm::ELF::Elf64_Sxword d_tag = 0x0;
    llvm::ELF::Elf64_Xword d_val = 0x0;

    if (llvm::sys::isLittleEndianHost()) {
      d_tag = dynamic[idx].d_tag;
      d_val = dynamic[idx].d_un.d_val;
    } else {
      d_tag = mcld::bswap64(dynamic[idx].d_tag);
      d_val = mcld::bswap64(dynamic[idx].d_un.d_val);
    }

    switch (d_tag) {
      case llvm::ELF::DT_SONAME:
        assert(d_val < dynstr_sect->size());
        pInput.setName(sys::fs::Path(dynstr + d_val).filename().native());
        hasSOName = true;
        break;
      case llvm::ELF::DT_NEEDED:
        // TODO:
        break;
      case llvm::ELF::DT_NULL:
      default:
        break;
    }
  }

  // if there is no SONAME in .dynamic, then set it from input path
  if (!hasSOName)
    pInput.setName(pInput.path().filename().native());

  pInput.memArea()->release(dynamic_region);
  pInput.memArea()->release(dynstr_region);
  return true;
}

