//===-- ELFDump.cpp - ELF-specific dumper -----------------------*- 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
//
//===----------------------------------------------------------------------===//
///
/// \file
/// This file implements the ELF-specific dumper for llvm-objdump.
///
//===----------------------------------------------------------------------===//

#include "llvm-objdump.h"
#include "llvm/Demangle/Demangle.h"
#include "llvm/Object/ELFObjectFile.h"
#include "llvm/Support/Format.h"
#include "llvm/Support/MathExtras.h"
#include "llvm/Support/raw_ostream.h"

using namespace llvm::object;

namespace llvm {
template <class ELFT>
static Expected<StringRef> getDynamicStrTab(const ELFFile<ELFT> *Elf) {
  auto DynamicEntriesOrError = Elf->dynamicEntries();
  if (!DynamicEntriesOrError)
    return DynamicEntriesOrError.takeError();

  for (const typename ELFT::Dyn &Dyn : *DynamicEntriesOrError) {
    if (Dyn.d_tag == ELF::DT_STRTAB) {
      auto MappedAddrOrError = Elf->toMappedAddr(Dyn.getPtr());
      if (!MappedAddrOrError)
        consumeError(MappedAddrOrError.takeError());
      return StringRef(reinterpret_cast<const char *>(*MappedAddrOrError));
    }
  }

  // If the dynamic segment is not present, we fall back on the sections.
  auto SectionsOrError = Elf->sections();
  if (!SectionsOrError)
    return SectionsOrError.takeError();

  for (const typename ELFT::Shdr &Sec : *SectionsOrError) {
    if (Sec.sh_type == ELF::SHT_DYNSYM)
      return Elf->getStringTableForSymtab(Sec);
  }

  return createError("dynamic string table not found");
}

template <class ELFT>
static Error getRelocationValueString(const ELFObjectFile<ELFT> *Obj,
                                      const RelocationRef &RelRef,
                                      SmallVectorImpl<char> &Result) {
  const ELFFile<ELFT> &EF = *Obj->getELFFile();
  DataRefImpl Rel = RelRef.getRawDataRefImpl();
  auto SecOrErr = EF.getSection(Rel.d.a);
  if (!SecOrErr)
    return SecOrErr.takeError();

  int64_t Addend = 0;
  // If there is no Symbol associated with the relocation, we set the undef
  // boolean value to 'true'. This will prevent us from calling functions that
  // requires the relocation to be associated with a symbol.
  //
  // In SHT_REL case we would need to read the addend from section data.
  // GNU objdump does not do that and we just follow for simplicity atm.
  bool Undef = false;
  if ((*SecOrErr)->sh_type == ELF::SHT_RELA) {
    const typename ELFT::Rela *ERela = Obj->getRela(Rel);
    Addend = ERela->r_addend;
    Undef = ERela->getSymbol(false) == 0;
  } else if ((*SecOrErr)->sh_type != ELF::SHT_REL) {
    return make_error<BinaryError>();
  }

  // Default scheme is to print Target, as well as "+ <addend>" for nonzero
  // addend. Should be acceptable for all normal purposes.
  std::string FmtBuf;
  raw_string_ostream Fmt(FmtBuf);

  if (!Undef) {
    symbol_iterator SI = RelRef.getSymbol();
    const typename ELFT::Sym *Sym = Obj->getSymbol(SI->getRawDataRefImpl());
    if (Sym->getType() == ELF::STT_SECTION) {
      Expected<section_iterator> SymSI = SI->getSection();
      if (!SymSI)
        return SymSI.takeError();
      const typename ELFT::Shdr *SymSec =
          Obj->getSection((*SymSI)->getRawDataRefImpl());
      auto SecName = EF.getSectionName(SymSec);
      if (!SecName)
        return SecName.takeError();
      Fmt << *SecName;
    } else {
      Expected<StringRef> SymName = SI->getName();
      if (!SymName)
        return SymName.takeError();
      if (Demangle)
        Fmt << demangle(std::string(*SymName));
      else
        Fmt << *SymName;
    }
  } else {
    Fmt << "*ABS*";
  }
  if (Addend != 0) {
      Fmt << (Addend < 0
          ? "-"
          : "+") << format("0x%" PRIx64,
                          (Addend < 0 ? -(uint64_t)Addend : (uint64_t)Addend));
  }
  Fmt.flush();
  Result.append(FmtBuf.begin(), FmtBuf.end());
  return Error::success();
}

Error getELFRelocationValueString(const ELFObjectFileBase *Obj,
                                  const RelocationRef &Rel,
                                  SmallVectorImpl<char> &Result) {
  if (auto *ELF32LE = dyn_cast<ELF32LEObjectFile>(Obj))
    return getRelocationValueString(ELF32LE, Rel, Result);
  if (auto *ELF64LE = dyn_cast<ELF64LEObjectFile>(Obj))
    return getRelocationValueString(ELF64LE, Rel, Result);
  if (auto *ELF32BE = dyn_cast<ELF32BEObjectFile>(Obj))
    return getRelocationValueString(ELF32BE, Rel, Result);
  auto *ELF64BE = cast<ELF64BEObjectFile>(Obj);
  return getRelocationValueString(ELF64BE, Rel, Result);
}

template <class ELFT>
static uint64_t getSectionLMA(const ELFFile<ELFT> *Obj,
                              const object::ELFSectionRef &Sec) {
  auto PhdrRangeOrErr = Obj->program_headers();
  if (!PhdrRangeOrErr)
    report_fatal_error(toString(PhdrRangeOrErr.takeError()));

  // Search for a PT_LOAD segment containing the requested section. Use this
  // segment's p_addr to calculate the section's LMA.
  for (const typename ELFT::Phdr &Phdr : *PhdrRangeOrErr)
    if ((Phdr.p_type == ELF::PT_LOAD) && (Phdr.p_vaddr <= Sec.getAddress()) &&
        (Phdr.p_vaddr + Phdr.p_memsz > Sec.getAddress()))
      return Sec.getAddress() - Phdr.p_vaddr + Phdr.p_paddr;

  // Return section's VMA if it isn't in a PT_LOAD segment.
  return Sec.getAddress();
}

uint64_t getELFSectionLMA(const object::ELFSectionRef &Sec) {
  if (const auto *ELFObj = dyn_cast<ELF32LEObjectFile>(Sec.getObject()))
    return getSectionLMA(ELFObj->getELFFile(), Sec);
  else if (const auto *ELFObj = dyn_cast<ELF32BEObjectFile>(Sec.getObject()))
    return getSectionLMA(ELFObj->getELFFile(), Sec);
  else if (const auto *ELFObj = dyn_cast<ELF64LEObjectFile>(Sec.getObject()))
    return getSectionLMA(ELFObj->getELFFile(), Sec);
  const auto *ELFObj = cast<ELF64BEObjectFile>(Sec.getObject());
  return getSectionLMA(ELFObj->getELFFile(), Sec);
}

template <class ELFT>
void printDynamicSection(const ELFFile<ELFT> *Elf, StringRef Filename) {
  ArrayRef<typename ELFT::Dyn> DynamicEntries =
      unwrapOrError(Elf->dynamicEntries(), Filename);

  // Find the maximum tag name length to format the value column properly.
  size_t MaxLen = 0;
  for (const typename ELFT::Dyn &Dyn : DynamicEntries)
    MaxLen = std::max(MaxLen, Elf->getDynamicTagAsString(Dyn.d_tag).size());
  std::string TagFmt = "  %-" + std::to_string(MaxLen) + "s ";

  outs() << "Dynamic Section:\n";
  for (const typename ELFT::Dyn &Dyn : DynamicEntries) {
    if (Dyn.d_tag == ELF::DT_NULL)
      continue;

    std::string Str = Elf->getDynamicTagAsString(Dyn.d_tag);
    outs() << format(TagFmt.c_str(), Str.c_str());

    const char *Fmt =
        ELFT::Is64Bits ? "0x%016" PRIx64 "\n" : "0x%08" PRIx64 "\n";
    if (Dyn.d_tag == ELF::DT_NEEDED || Dyn.d_tag == ELF::DT_RPATH ||
        Dyn.d_tag == ELF::DT_RUNPATH || Dyn.d_tag == ELF::DT_SONAME ||
        Dyn.d_tag == ELF::DT_AUXILIARY || Dyn.d_tag == ELF::DT_FILTER) {
      Expected<StringRef> StrTabOrErr = getDynamicStrTab(Elf);
      if (StrTabOrErr) {
        const char *Data = StrTabOrErr.get().data();
        outs() << (Data + Dyn.d_un.d_val) << "\n";
        continue;
      }
      reportWarning(toString(StrTabOrErr.takeError()), Filename);
      consumeError(StrTabOrErr.takeError());
    }
    outs() << format(Fmt, (uint64_t)Dyn.d_un.d_val);
  }
}

template <class ELFT> void printProgramHeaders(const ELFFile<ELFT> *o) {
  outs() << "Program Header:\n";
  auto ProgramHeaderOrError = o->program_headers();
  if (!ProgramHeaderOrError)
    report_fatal_error(toString(ProgramHeaderOrError.takeError()));
  for (const typename ELFT::Phdr &Phdr : *ProgramHeaderOrError) {
    switch (Phdr.p_type) {
    case ELF::PT_DYNAMIC:
      outs() << " DYNAMIC ";
      break;
    case ELF::PT_GNU_EH_FRAME:
      outs() << "EH_FRAME ";
      break;
    case ELF::PT_GNU_RELRO:
      outs() << "   RELRO ";
      break;
    case ELF::PT_GNU_PROPERTY:
      outs() << "   PROPERTY ";
      break;
    case ELF::PT_GNU_STACK:
      outs() << "   STACK ";
      break;
    case ELF::PT_INTERP:
      outs() << "  INTERP ";
      break;
    case ELF::PT_LOAD:
      outs() << "    LOAD ";
      break;
    case ELF::PT_NOTE:
      outs() << "    NOTE ";
      break;
    case ELF::PT_OPENBSD_BOOTDATA:
      outs() << "    OPENBSD_BOOTDATA ";
      break;
    case ELF::PT_OPENBSD_RANDOMIZE:
      outs() << "    OPENBSD_RANDOMIZE ";
      break;
    case ELF::PT_OPENBSD_WXNEEDED:
      outs() << "    OPENBSD_WXNEEDED ";
      break;
    case ELF::PT_PHDR:
      outs() << "    PHDR ";
      break;
    case ELF::PT_TLS:
      outs() << "    TLS ";
      break;
    default:
      outs() << " UNKNOWN ";
    }

    const char *Fmt = ELFT::Is64Bits ? "0x%016" PRIx64 " " : "0x%08" PRIx64 " ";

    outs() << "off    " << format(Fmt, (uint64_t)Phdr.p_offset) << "vaddr "
           << format(Fmt, (uint64_t)Phdr.p_vaddr) << "paddr "
           << format(Fmt, (uint64_t)Phdr.p_paddr)
           << format("align 2**%u\n",
                     countTrailingZeros<uint64_t>(Phdr.p_align))
           << "         filesz " << format(Fmt, (uint64_t)Phdr.p_filesz)
           << "memsz " << format(Fmt, (uint64_t)Phdr.p_memsz) << "flags "
           << ((Phdr.p_flags & ELF::PF_R) ? "r" : "-")
           << ((Phdr.p_flags & ELF::PF_W) ? "w" : "-")
           << ((Phdr.p_flags & ELF::PF_X) ? "x" : "-") << "\n";
  }
  outs() << "\n";
}

template <class ELFT>
void printSymbolVersionDependency(ArrayRef<uint8_t> Contents,
                                  StringRef StrTab) {
  outs() << "Version References:\n";

  const uint8_t *Buf = Contents.data();
  while (Buf) {
    auto *Verneed = reinterpret_cast<const typename ELFT::Verneed *>(Buf);
    outs() << "  required from "
           << StringRef(StrTab.drop_front(Verneed->vn_file).data()) << ":\n";

    const uint8_t *BufAux = Buf + Verneed->vn_aux;
    while (BufAux) {
      auto *Vernaux = reinterpret_cast<const typename ELFT::Vernaux *>(BufAux);
      outs() << "    "
             << format("0x%08" PRIx32 " ", (uint32_t)Vernaux->vna_hash)
             << format("0x%02" PRIx16 " ", (uint16_t)Vernaux->vna_flags)
             << format("%02" PRIu16 " ", (uint16_t)Vernaux->vna_other)
             << StringRef(StrTab.drop_front(Vernaux->vna_name).data()) << '\n';
      BufAux = Vernaux->vna_next ? BufAux + Vernaux->vna_next : nullptr;
    }
    Buf = Verneed->vn_next ? Buf + Verneed->vn_next : nullptr;
  }
}

template <class ELFT>
void printSymbolVersionDefinition(const typename ELFT::Shdr &Shdr,
                                  ArrayRef<uint8_t> Contents,
                                  StringRef StrTab) {
  outs() << "Version definitions:\n";

  const uint8_t *Buf = Contents.data();
  uint32_t VerdefIndex = 1;
  // sh_info contains the number of entries in the SHT_GNU_verdef section. To
  // make the index column have consistent width, we should insert blank spaces
  // according to sh_info.
  uint16_t VerdefIndexWidth = std::to_string(Shdr.sh_info).size();
  while (Buf) {
    auto *Verdef = reinterpret_cast<const typename ELFT::Verdef *>(Buf);
    outs() << format_decimal(VerdefIndex++, VerdefIndexWidth) << " "
           << format("0x%02" PRIx16 " ", (uint16_t)Verdef->vd_flags)
           << format("0x%08" PRIx32 " ", (uint32_t)Verdef->vd_hash);

    const uint8_t *BufAux = Buf + Verdef->vd_aux;
    uint16_t VerdauxIndex = 0;
    while (BufAux) {
      auto *Verdaux = reinterpret_cast<const typename ELFT::Verdaux *>(BufAux);
      if (VerdauxIndex)
        outs() << std::string(VerdefIndexWidth + 17, ' ');
      outs() << StringRef(StrTab.drop_front(Verdaux->vda_name).data()) << '\n';
      BufAux = Verdaux->vda_next ? BufAux + Verdaux->vda_next : nullptr;
      ++VerdauxIndex;
    }
    Buf = Verdef->vd_next ? Buf + Verdef->vd_next : nullptr;
  }
}

template <class ELFT>
void printSymbolVersionInfo(const ELFFile<ELFT> *Elf, StringRef FileName) {
  ArrayRef<typename ELFT::Shdr> Sections =
      unwrapOrError(Elf->sections(), FileName);
  for (const typename ELFT::Shdr &Shdr : Sections) {
    if (Shdr.sh_type != ELF::SHT_GNU_verneed &&
        Shdr.sh_type != ELF::SHT_GNU_verdef)
      continue;

    ArrayRef<uint8_t> Contents =
        unwrapOrError(Elf->getSectionContents(&Shdr), FileName);
    const typename ELFT::Shdr *StrTabSec =
        unwrapOrError(Elf->getSection(Shdr.sh_link), FileName);
    StringRef StrTab = unwrapOrError(Elf->getStringTable(StrTabSec), FileName);

    if (Shdr.sh_type == ELF::SHT_GNU_verneed)
      printSymbolVersionDependency<ELFT>(Contents, StrTab);
    else
      printSymbolVersionDefinition<ELFT>(Shdr, Contents, StrTab);
  }
}

void printELFFileHeader(const object::ObjectFile *Obj) {
  if (const auto *ELFObj = dyn_cast<ELF32LEObjectFile>(Obj))
    printProgramHeaders(ELFObj->getELFFile());
  else if (const auto *ELFObj = dyn_cast<ELF32BEObjectFile>(Obj))
    printProgramHeaders(ELFObj->getELFFile());
  else if (const auto *ELFObj = dyn_cast<ELF64LEObjectFile>(Obj))
    printProgramHeaders(ELFObj->getELFFile());
  else if (const auto *ELFObj = dyn_cast<ELF64BEObjectFile>(Obj))
    printProgramHeaders(ELFObj->getELFFile());
}

void printELFDynamicSection(const object::ObjectFile *Obj) {
  if (const auto *ELFObj = dyn_cast<ELF32LEObjectFile>(Obj))
    printDynamicSection(ELFObj->getELFFile(), Obj->getFileName());
  else if (const auto *ELFObj = dyn_cast<ELF32BEObjectFile>(Obj))
    printDynamicSection(ELFObj->getELFFile(), Obj->getFileName());
  else if (const auto *ELFObj = dyn_cast<ELF64LEObjectFile>(Obj))
    printDynamicSection(ELFObj->getELFFile(), Obj->getFileName());
  else if (const auto *ELFObj = dyn_cast<ELF64BEObjectFile>(Obj))
    printDynamicSection(ELFObj->getELFFile(), Obj->getFileName());
}

void printELFSymbolVersionInfo(const object::ObjectFile *Obj) {
  if (const auto *ELFObj = dyn_cast<ELF32LEObjectFile>(Obj))
    printSymbolVersionInfo(ELFObj->getELFFile(), Obj->getFileName());
  else if (const auto *ELFObj = dyn_cast<ELF32BEObjectFile>(Obj))
    printSymbolVersionInfo(ELFObj->getELFFile(), Obj->getFileName());
  else if (const auto *ELFObj = dyn_cast<ELF64LEObjectFile>(Obj))
    printSymbolVersionInfo(ELFObj->getELFFile(), Obj->getFileName());
  else if (const auto *ELFObj = dyn_cast<ELF64BEObjectFile>(Obj))
    printSymbolVersionInfo(ELFObj->getELFFile(), Obj->getFileName());
}
} // namespace llvm
