//===-- 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 "ELFDump.h"

#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;
using namespace llvm::object;
using namespace llvm::objdump;

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 objdump::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 objdump::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>
static 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> static 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>
static 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>
static 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>
static 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 objdump::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 objdump::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 objdump::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());
}
