//===------ utils/elf2yaml.cpp - obj2yaml conversion tool -------*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#include "Error.h"
#include "llvm/ADT/DenseSet.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/Object/ELFObjectFile.h"
#include "llvm/ObjectYAML/ELFYAML.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/YAMLTraits.h"

using namespace llvm;

namespace {

template <class ELFT>
class ELFDumper {
  typedef object::Elf_Sym_Impl<ELFT> Elf_Sym;
  typedef typename ELFT::Shdr Elf_Shdr;
  typedef typename ELFT::Word Elf_Word;
  typedef typename ELFT::Rel Elf_Rel;
  typedef typename ELFT::Rela Elf_Rela;

  ArrayRef<Elf_Shdr> Sections;

  // If the file has multiple sections with the same name, we add a
  // suffix to make them unique.
  unsigned Suffix = 0;
  DenseSet<StringRef> UsedSectionNames;
  std::vector<std::string> SectionNames;
  Expected<StringRef> getUniquedSectionName(const Elf_Shdr *Sec);
  Expected<StringRef> getSymbolName(const Elf_Sym *Sym, StringRef StrTable,
                                    const Elf_Shdr *SymTab);

  const object::ELFFile<ELFT> &Obj;
  ArrayRef<Elf_Word> ShndxTable;

  std::error_code dumpSymbols(const Elf_Shdr *Symtab,
                              ELFYAML::LocalGlobalWeakSymbols &Symbols);
  std::error_code dumpSymbol(const Elf_Sym *Sym, const Elf_Shdr *SymTab,
                             StringRef StrTable, ELFYAML::Symbol &S);
  std::error_code dumpCommonSection(const Elf_Shdr *Shdr, ELFYAML::Section &S);
  std::error_code dumpCommonRelocationSection(const Elf_Shdr *Shdr,
                                              ELFYAML::RelocationSection &S);
  template <class RelT>
  std::error_code dumpRelocation(const RelT *Rel, const Elf_Shdr *SymTab,
                                 ELFYAML::Relocation &R);

  ErrorOr<ELFYAML::RelocationSection *> dumpRelocSection(const Elf_Shdr *Shdr);
  ErrorOr<ELFYAML::RawContentSection *>
  dumpContentSection(const Elf_Shdr *Shdr);
  ErrorOr<ELFYAML::NoBitsSection *> dumpNoBitsSection(const Elf_Shdr *Shdr);
  ErrorOr<ELFYAML::Group *> dumpGroup(const Elf_Shdr *Shdr);
  ErrorOr<ELFYAML::MipsABIFlags *> dumpMipsABIFlags(const Elf_Shdr *Shdr);

public:
  ELFDumper(const object::ELFFile<ELFT> &O);
  ErrorOr<ELFYAML::Object *> dump();
};

}

template <class ELFT>
ELFDumper<ELFT>::ELFDumper(const object::ELFFile<ELFT> &O)
    : Obj(O) {}

template <class ELFT>
Expected<StringRef>
ELFDumper<ELFT>::getUniquedSectionName(const Elf_Shdr *Sec) {
  unsigned SecIndex = Sec - &Sections[0];
  assert(&Sections[SecIndex] == Sec);
  if (!SectionNames[SecIndex].empty())
    return SectionNames[SecIndex];

  auto NameOrErr = Obj.getSectionName(Sec);
  if (!NameOrErr)
    return NameOrErr;
  StringRef Name = *NameOrErr;
  std::string &Ret = SectionNames[SecIndex];
  Ret = Name;
  while (!UsedSectionNames.insert(Ret).second)
    Ret = (Name + to_string(++Suffix)).str();
  return Ret;
}

template <class ELFT>
Expected<StringRef> ELFDumper<ELFT>::getSymbolName(const Elf_Sym *Sym,
                                                   StringRef StrTable,
                                                   const Elf_Shdr *SymTab) {
  Expected<StringRef> SymbolNameOrErr = Sym->getName(StrTable);
  if (!SymbolNameOrErr)
    return SymbolNameOrErr;
  StringRef Name = *SymbolNameOrErr;
  if (Name.empty() && Sym->getType() == ELF::STT_SECTION) {
    auto ShdrOrErr = Obj.getSection(Sym, SymTab, ShndxTable);
    if (!ShdrOrErr)
      return ShdrOrErr.takeError();
    return getUniquedSectionName(*ShdrOrErr);
  }
  return Name;
}

template <class ELFT> ErrorOr<ELFYAML::Object *> ELFDumper<ELFT>::dump() {
  auto Y = make_unique<ELFYAML::Object>();

  // Dump header
  Y->Header.Class = ELFYAML::ELF_ELFCLASS(Obj.getHeader()->getFileClass());
  Y->Header.Data = ELFYAML::ELF_ELFDATA(Obj.getHeader()->getDataEncoding());
  Y->Header.OSABI = Obj.getHeader()->e_ident[ELF::EI_OSABI];
  Y->Header.ABIVersion = Obj.getHeader()->e_ident[ELF::EI_ABIVERSION];
  Y->Header.Type = Obj.getHeader()->e_type;
  Y->Header.Machine = Obj.getHeader()->e_machine;
  Y->Header.Flags = Obj.getHeader()->e_flags;
  Y->Header.Entry = Obj.getHeader()->e_entry;

  const Elf_Shdr *Symtab = nullptr;
  const Elf_Shdr *DynSymtab = nullptr;

  // Dump sections
  auto SectionsOrErr = Obj.sections();
  if (!SectionsOrErr)
    return errorToErrorCode(SectionsOrErr.takeError());
  Sections = *SectionsOrErr;
  SectionNames.resize(Sections.size());
  for (const Elf_Shdr &Sec : Sections) {
    switch (Sec.sh_type) {
    case ELF::SHT_NULL:
    case ELF::SHT_STRTAB:
      // Do not dump these sections.
      break;
    case ELF::SHT_SYMTAB:
      Symtab = &Sec;
      break;
    case ELF::SHT_DYNSYM:
      DynSymtab = &Sec;
      break;
    case ELF::SHT_SYMTAB_SHNDX: {
      auto TableOrErr = Obj.getSHNDXTable(Sec);
      if (!TableOrErr)
        return errorToErrorCode(TableOrErr.takeError());
      ShndxTable = *TableOrErr;
      break;
    }
    case ELF::SHT_REL:
    case ELF::SHT_RELA: {
      ErrorOr<ELFYAML::RelocationSection *> S = dumpRelocSection(&Sec);
      if (std::error_code EC = S.getError())
        return EC;
      Y->Sections.push_back(std::unique_ptr<ELFYAML::Section>(S.get()));
      break;
    }
    case ELF::SHT_GROUP: {
      ErrorOr<ELFYAML::Group *> G = dumpGroup(&Sec);
      if (std::error_code EC = G.getError())
        return EC;
      Y->Sections.push_back(std::unique_ptr<ELFYAML::Section>(G.get()));
      break;
    }
    case ELF::SHT_MIPS_ABIFLAGS: {
      ErrorOr<ELFYAML::MipsABIFlags *> G = dumpMipsABIFlags(&Sec);
      if (std::error_code EC = G.getError())
        return EC;
      Y->Sections.push_back(std::unique_ptr<ELFYAML::Section>(G.get()));
      break;
    }
    case ELF::SHT_NOBITS: {
      ErrorOr<ELFYAML::NoBitsSection *> S = dumpNoBitsSection(&Sec);
      if (std::error_code EC = S.getError())
        return EC;
      Y->Sections.push_back(std::unique_ptr<ELFYAML::Section>(S.get()));
      break;
    }
    default: {
      ErrorOr<ELFYAML::RawContentSection *> S = dumpContentSection(&Sec);
      if (std::error_code EC = S.getError())
        return EC;
      Y->Sections.push_back(std::unique_ptr<ELFYAML::Section>(S.get()));
    }
    }
  }

  if (auto EC = dumpSymbols(Symtab, Y->Symbols))
    return EC;
  if (auto EC = dumpSymbols(DynSymtab, Y->DynamicSymbols))
    return EC;

  return Y.release();
}

template <class ELFT>
std::error_code
ELFDumper<ELFT>::dumpSymbols(const Elf_Shdr *Symtab,
                             ELFYAML::LocalGlobalWeakSymbols &Symbols) {
  if (!Symtab)
    return std::error_code();

  auto StrTableOrErr = Obj.getStringTableForSymtab(*Symtab);
  if (!StrTableOrErr)
    return errorToErrorCode(StrTableOrErr.takeError());
  StringRef StrTable = *StrTableOrErr;

  auto SymtabOrErr = Obj.symbols(Symtab);
  if (!SymtabOrErr)
    return errorToErrorCode(SymtabOrErr.takeError());

  bool IsFirstSym = true;
  for (const auto &Sym : *SymtabOrErr) {
    if (IsFirstSym) {
      IsFirstSym = false;
      continue;
    }

    ELFYAML::Symbol S;
    if (auto EC = dumpSymbol(&Sym, Symtab, StrTable, S))
      return EC;

    switch (Sym.getBinding()) {
    case ELF::STB_LOCAL:
      Symbols.Local.push_back(S);
      break;
    case ELF::STB_GLOBAL:
      Symbols.Global.push_back(S);
      break;
    case ELF::STB_WEAK:
      Symbols.Weak.push_back(S);
      break;
    default:
      llvm_unreachable("Unknown ELF symbol binding");
    }
  }

  return std::error_code();
}

template <class ELFT>
std::error_code
ELFDumper<ELFT>::dumpSymbol(const Elf_Sym *Sym, const Elf_Shdr *SymTab,
                            StringRef StrTable, ELFYAML::Symbol &S) {
  S.Type = Sym->getType();
  S.Value = Sym->st_value;
  S.Size = Sym->st_size;
  S.Other = Sym->st_other;

  Expected<StringRef> SymbolNameOrErr = getSymbolName(Sym, StrTable, SymTab);
  if (!SymbolNameOrErr)
    return errorToErrorCode(SymbolNameOrErr.takeError());
  S.Name = SymbolNameOrErr.get();

  auto ShdrOrErr = Obj.getSection(Sym, SymTab, ShndxTable);
  if (!ShdrOrErr)
    return errorToErrorCode(ShdrOrErr.takeError());
  const Elf_Shdr *Shdr = *ShdrOrErr;
  if (!Shdr)
    return obj2yaml_error::success;

  auto NameOrErr = getUniquedSectionName(Shdr);
  if (!NameOrErr)
    return errorToErrorCode(NameOrErr.takeError());
  S.Section = NameOrErr.get();

  return obj2yaml_error::success;
}

template <class ELFT>
template <class RelT>
std::error_code ELFDumper<ELFT>::dumpRelocation(const RelT *Rel,
                                                const Elf_Shdr *SymTab,
                                                ELFYAML::Relocation &R) {
  R.Type = Rel->getType(Obj.isMips64EL());
  R.Offset = Rel->r_offset;
  R.Addend = 0;

  auto SymOrErr = Obj.getRelocationSymbol(Rel, SymTab);
  if (!SymOrErr)
    return errorToErrorCode(SymOrErr.takeError());
  const Elf_Sym *Sym = *SymOrErr;
  auto StrTabSec = Obj.getSection(SymTab->sh_link);
  if (!StrTabSec)
    return errorToErrorCode(StrTabSec.takeError());
  auto StrTabOrErr = Obj.getStringTable(*StrTabSec);
  if (!StrTabOrErr)
    return errorToErrorCode(StrTabOrErr.takeError());
  StringRef StrTab = *StrTabOrErr;

  if (Sym) {
    Expected<StringRef> NameOrErr = getSymbolName(Sym, StrTab, SymTab);
    if (!NameOrErr)
      return errorToErrorCode(NameOrErr.takeError());
    R.Symbol = NameOrErr.get();
  } else {
    // We have some edge cases of relocations without a symbol associated,
    // e.g. an object containing the invalid (according to the System V
    // ABI) R_X86_64_NONE reloc. Create a symbol with an empty name instead
    // of crashing.
    R.Symbol = "";
  }

  return obj2yaml_error::success;
}

template <class ELFT>
std::error_code ELFDumper<ELFT>::dumpCommonSection(const Elf_Shdr *Shdr,
                                                   ELFYAML::Section &S) {
  S.Type = Shdr->sh_type;
  S.Flags = Shdr->sh_flags;
  S.Address = Shdr->sh_addr;
  S.AddressAlign = Shdr->sh_addralign;
  if (Shdr->sh_entsize)
    S.EntSize = static_cast<llvm::yaml::Hex64>(Shdr->sh_entsize);

  auto NameOrErr = getUniquedSectionName(Shdr);
  if (!NameOrErr)
    return errorToErrorCode(NameOrErr.takeError());
  S.Name = NameOrErr.get();

  if (Shdr->sh_link != ELF::SHN_UNDEF) {
    auto LinkSection = Obj.getSection(Shdr->sh_link);
    if (LinkSection.takeError())
      return errorToErrorCode(LinkSection.takeError());
    NameOrErr = getUniquedSectionName(*LinkSection);
    if (!NameOrErr)
      return errorToErrorCode(NameOrErr.takeError());
    S.Link = NameOrErr.get();
  }

  return obj2yaml_error::success;
}

template <class ELFT>
std::error_code
ELFDumper<ELFT>::dumpCommonRelocationSection(const Elf_Shdr *Shdr,
                                             ELFYAML::RelocationSection &S) {
  if (std::error_code EC = dumpCommonSection(Shdr, S))
    return EC;

  auto InfoSection = Obj.getSection(Shdr->sh_info);
  if (!InfoSection)
    return errorToErrorCode(InfoSection.takeError());

  auto NameOrErr = getUniquedSectionName(*InfoSection);
  if (!NameOrErr)
    return errorToErrorCode(NameOrErr.takeError());
  S.Info = NameOrErr.get();

  return obj2yaml_error::success;
}

template <class ELFT>
ErrorOr<ELFYAML::RelocationSection *>
ELFDumper<ELFT>::dumpRelocSection(const Elf_Shdr *Shdr) {
  auto S = make_unique<ELFYAML::RelocationSection>();
  if (std::error_code EC = dumpCommonRelocationSection(Shdr, *S))
    return EC;

  auto SymTabOrErr = Obj.getSection(Shdr->sh_link);
  if (!SymTabOrErr)
    return errorToErrorCode(SymTabOrErr.takeError());
  const Elf_Shdr *SymTab = *SymTabOrErr;

  if (Shdr->sh_type == ELF::SHT_REL) {
    auto Rels = Obj.rels(Shdr);
    if (!Rels)
      return errorToErrorCode(Rels.takeError());
    for (const Elf_Rel &Rel : *Rels) {
      ELFYAML::Relocation R;
      if (std::error_code EC = dumpRelocation(&Rel, SymTab, R))
        return EC;
      S->Relocations.push_back(R);
    }
  } else {
    auto Rels = Obj.relas(Shdr);
    if (!Rels)
      return errorToErrorCode(Rels.takeError());
    for (const Elf_Rela &Rel : *Rels) {
      ELFYAML::Relocation R;
      if (std::error_code EC = dumpRelocation(&Rel, SymTab, R))
        return EC;
      R.Addend = Rel.r_addend;
      S->Relocations.push_back(R);
    }
  }

  return S.release();
}

template <class ELFT>
ErrorOr<ELFYAML::RawContentSection *>
ELFDumper<ELFT>::dumpContentSection(const Elf_Shdr *Shdr) {
  auto S = make_unique<ELFYAML::RawContentSection>();

  if (std::error_code EC = dumpCommonSection(Shdr, *S))
    return EC;

  auto ContentOrErr = Obj.getSectionContents(Shdr);
  if (!ContentOrErr)
    return errorToErrorCode(ContentOrErr.takeError());
  S->Content = yaml::BinaryRef(ContentOrErr.get());
  S->Size = S->Content.binary_size();

  return S.release();
}

template <class ELFT>
ErrorOr<ELFYAML::NoBitsSection *>
ELFDumper<ELFT>::dumpNoBitsSection(const Elf_Shdr *Shdr) {
  auto S = make_unique<ELFYAML::NoBitsSection>();

  if (std::error_code EC = dumpCommonSection(Shdr, *S))
    return EC;
  S->Size = Shdr->sh_size;

  return S.release();
}

template <class ELFT>
ErrorOr<ELFYAML::Group *> ELFDumper<ELFT>::dumpGroup(const Elf_Shdr *Shdr) {
  auto S = make_unique<ELFYAML::Group>();

  if (std::error_code EC = dumpCommonSection(Shdr, *S))
    return EC;
  // Get sh_info which is the signature.
  auto SymtabOrErr = Obj.getSection(Shdr->sh_link);
  if (!SymtabOrErr)
    return errorToErrorCode(SymtabOrErr.takeError());
  const Elf_Shdr *Symtab = *SymtabOrErr;
  auto SymOrErr = Obj.getSymbol(Symtab, Shdr->sh_info);
  if (!SymOrErr)
    return errorToErrorCode(SymOrErr.takeError());
  const Elf_Sym *symbol = *SymOrErr;
  auto StrTabOrErr = Obj.getStringTableForSymtab(*Symtab);
  if (!StrTabOrErr)
    return errorToErrorCode(StrTabOrErr.takeError());
  StringRef StrTab = *StrTabOrErr;
  auto sectionContents = Obj.getSectionContents(Shdr);
  if (!sectionContents)
    return errorToErrorCode(sectionContents.takeError());
  Expected<StringRef> symbolName = getSymbolName(symbol, StrTab, Symtab);
  if (!symbolName)
    return errorToErrorCode(symbolName.takeError());
  S->Info = *symbolName;
  const Elf_Word *groupMembers =
      reinterpret_cast<const Elf_Word *>(sectionContents->data());
  const long count = (Shdr->sh_size) / sizeof(Elf_Word);
  ELFYAML::SectionOrType s;
  for (int i = 0; i < count; i++) {
    if (groupMembers[i] == llvm::ELF::GRP_COMDAT) {
      s.sectionNameOrType = "GRP_COMDAT";
    } else {
      auto sHdr = Obj.getSection(groupMembers[i]);
      if (!sHdr)
        return errorToErrorCode(sHdr.takeError());
      auto sectionName = getUniquedSectionName(*sHdr);
      if (!sectionName)
        return errorToErrorCode(sectionName.takeError());
      s.sectionNameOrType = *sectionName;
    }
    S->Members.push_back(s);
  }
  return S.release();
}

template <class ELFT>
ErrorOr<ELFYAML::MipsABIFlags *>
ELFDumper<ELFT>::dumpMipsABIFlags(const Elf_Shdr *Shdr) {
  assert(Shdr->sh_type == ELF::SHT_MIPS_ABIFLAGS &&
         "Section type is not SHT_MIPS_ABIFLAGS");
  auto S = make_unique<ELFYAML::MipsABIFlags>();
  if (std::error_code EC = dumpCommonSection(Shdr, *S))
    return EC;

  auto ContentOrErr = Obj.getSectionContents(Shdr);
  if (!ContentOrErr)
    return errorToErrorCode(ContentOrErr.takeError());

  auto *Flags = reinterpret_cast<const object::Elf_Mips_ABIFlags<ELFT> *>(
      ContentOrErr.get().data());
  S->Version = Flags->version;
  S->ISALevel = Flags->isa_level;
  S->ISARevision = Flags->isa_rev;
  S->GPRSize = Flags->gpr_size;
  S->CPR1Size = Flags->cpr1_size;
  S->CPR2Size = Flags->cpr2_size;
  S->FpABI = Flags->fp_abi;
  S->ISAExtension = Flags->isa_ext;
  S->ASEs = Flags->ases;
  S->Flags1 = Flags->flags1;
  S->Flags2 = Flags->flags2;
  return S.release();
}

template <class ELFT>
static std::error_code elf2yaml(raw_ostream &Out,
                                const object::ELFFile<ELFT> &Obj) {
  ELFDumper<ELFT> Dumper(Obj);
  ErrorOr<ELFYAML::Object *> YAMLOrErr = Dumper.dump();
  if (std::error_code EC = YAMLOrErr.getError())
    return EC;

  std::unique_ptr<ELFYAML::Object> YAML(YAMLOrErr.get());
  yaml::Output Yout(Out);
  Yout << *YAML;

  return std::error_code();
}

std::error_code elf2yaml(raw_ostream &Out, const object::ObjectFile &Obj) {
  if (const auto *ELFObj = dyn_cast<object::ELF32LEObjectFile>(&Obj))
    return elf2yaml(Out, *ELFObj->getELFFile());

  if (const auto *ELFObj = dyn_cast<object::ELF32BEObjectFile>(&Obj))
    return elf2yaml(Out, *ELFObj->getELFFile());

  if (const auto *ELFObj = dyn_cast<object::ELF64LEObjectFile>(&Obj))
    return elf2yaml(Out, *ELFObj->getELFFile());

  if (const auto *ELFObj = dyn_cast<object::ELF64BEObjectFile>(&Obj))
    return elf2yaml(Out, *ELFObj->getELFFile());

  return obj2yaml_error::unsupported_obj_file_format;
}
