//===- ELFDumper.cpp - ELF-specific dumper --------------------------------===//
//
// 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-readobj.
///
//===----------------------------------------------------------------------===//

#include "ARMEHABIPrinter.h"
#include "DwarfCFIEHPrinter.h"
#include "ObjDumper.h"
#include "StackMapPrinter.h"
#include "llvm-readobj.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/BitVector.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/DenseSet.h"
#include "llvm/ADT/MapVector.h"
#include "llvm/ADT/Optional.h"
#include "llvm/ADT/PointerIntPair.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/Twine.h"
#include "llvm/BinaryFormat/AMDGPUMetadataVerifier.h"
#include "llvm/BinaryFormat/ELF.h"
#include "llvm/BinaryFormat/MsgPackDocument.h"
#include "llvm/Demangle/Demangle.h"
#include "llvm/Object/Archive.h"
#include "llvm/Object/ELF.h"
#include "llvm/Object/ELFObjectFile.h"
#include "llvm/Object/ELFTypes.h"
#include "llvm/Object/Error.h"
#include "llvm/Object/ObjectFile.h"
#include "llvm/Object/RelocationResolver.h"
#include "llvm/Object/StackMapParser.h"
#include "llvm/Support/AMDGPUMetadata.h"
#include "llvm/Support/ARMAttributeParser.h"
#include "llvm/Support/ARMBuildAttributes.h"
#include "llvm/Support/Casting.h"
#include "llvm/Support/Compiler.h"
#include "llvm/Support/Endian.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/Format.h"
#include "llvm/Support/FormatVariadic.h"
#include "llvm/Support/FormattedStream.h"
#include "llvm/Support/LEB128.h"
#include "llvm/Support/MSP430AttributeParser.h"
#include "llvm/Support/MSP430Attributes.h"
#include "llvm/Support/MathExtras.h"
#include "llvm/Support/MipsABIFlags.h"
#include "llvm/Support/RISCVAttributeParser.h"
#include "llvm/Support/RISCVAttributes.h"
#include "llvm/Support/ScopedPrinter.h"
#include "llvm/Support/raw_ostream.h"
#include <algorithm>
#include <cinttypes>
#include <cstddef>
#include <cstdint>
#include <cstdlib>
#include <iterator>
#include <memory>
#include <string>
#include <system_error>
#include <vector>

using namespace llvm;
using namespace llvm::object;
using namespace ELF;

#define LLVM_READOBJ_ENUM_CASE(ns, enum)                                       \
  case ns::enum:                                                               \
    return #enum;

#define ENUM_ENT(enum, altName)                                                \
  { #enum, altName, ELF::enum }

#define ENUM_ENT_1(enum)                                                       \
  { #enum, #enum, ELF::enum }

namespace {

template <class ELFT> struct RelSymbol {
  RelSymbol(const typename ELFT::Sym *S, StringRef N)
      : Sym(S), Name(N.str()) {}
  const typename ELFT::Sym *Sym;
  std::string Name;
};

/// Represents a contiguous uniform range in the file. We cannot just create a
/// range directly because when creating one of these from the .dynamic table
/// the size, entity size and virtual address are different entries in arbitrary
/// order (DT_REL, DT_RELSZ, DT_RELENT for example).
struct DynRegionInfo {
  DynRegionInfo(const Binary &Owner, const ObjDumper &D)
      : Obj(&Owner), Dumper(&D) {}
  DynRegionInfo(const Binary &Owner, const ObjDumper &D, const uint8_t *A,
                uint64_t S, uint64_t ES)
      : Addr(A), Size(S), EntSize(ES), Obj(&Owner), Dumper(&D) {}

  /// Address in current address space.
  const uint8_t *Addr = nullptr;
  /// Size in bytes of the region.
  uint64_t Size = 0;
  /// Size of each entity in the region.
  uint64_t EntSize = 0;

  /// Owner object. Used for error reporting.
  const Binary *Obj;
  /// Dumper used for error reporting.
  const ObjDumper *Dumper;
  /// Error prefix. Used for error reporting to provide more information.
  std::string Context;
  /// Region size name. Used for error reporting.
  StringRef SizePrintName = "size";
  /// Entry size name. Used for error reporting. If this field is empty, errors
  /// will not mention the entry size.
  StringRef EntSizePrintName = "entry size";

  template <typename Type> ArrayRef<Type> getAsArrayRef() const {
    const Type *Start = reinterpret_cast<const Type *>(Addr);
    if (!Start)
      return {Start, Start};

    const uint64_t Offset =
        Addr - (const uint8_t *)Obj->getMemoryBufferRef().getBufferStart();
    const uint64_t ObjSize = Obj->getMemoryBufferRef().getBufferSize();

    if (Size > ObjSize - Offset) {
      Dumper->reportUniqueWarning(
          "unable to read data at 0x" + Twine::utohexstr(Offset) +
          " of size 0x" + Twine::utohexstr(Size) + " (" + SizePrintName +
          "): it goes past the end of the file of size 0x" +
          Twine::utohexstr(ObjSize));
      return {Start, Start};
    }

    if (EntSize == sizeof(Type) && (Size % EntSize == 0))
      return {Start, Start + (Size / EntSize)};

    std::string Msg;
    if (!Context.empty())
      Msg += Context + " has ";

    Msg += ("invalid " + SizePrintName + " (0x" + Twine::utohexstr(Size) + ")")
               .str();
    if (!EntSizePrintName.empty())
      Msg +=
          (" or " + EntSizePrintName + " (0x" + Twine::utohexstr(EntSize) + ")")
              .str();

    Dumper->reportUniqueWarning(Msg);
    return {Start, Start};
  }
};

struct GroupMember {
  StringRef Name;
  uint64_t Index;
};

struct GroupSection {
  StringRef Name;
  std::string Signature;
  uint64_t ShName;
  uint64_t Index;
  uint32_t Link;
  uint32_t Info;
  uint32_t Type;
  std::vector<GroupMember> Members;
};

namespace {

struct NoteType {
  uint32_t ID;
  StringRef Name;
};

} // namespace

template <class ELFT> class Relocation {
public:
  Relocation(const typename ELFT::Rel &R, bool IsMips64EL)
      : Type(R.getType(IsMips64EL)), Symbol(R.getSymbol(IsMips64EL)),
        Offset(R.r_offset), Info(R.r_info) {}

  Relocation(const typename ELFT::Rela &R, bool IsMips64EL)
      : Relocation((const typename ELFT::Rel &)R, IsMips64EL) {
    Addend = R.r_addend;
  }

  uint32_t Type;
  uint32_t Symbol;
  typename ELFT::uint Offset;
  typename ELFT::uint Info;
  Optional<int64_t> Addend;
};

template <class ELFT> class MipsGOTParser;

template <typename ELFT> class ELFDumper : public ObjDumper {
  LLVM_ELF_IMPORT_TYPES_ELFT(ELFT)

public:
  ELFDumper(const object::ELFObjectFile<ELFT> &ObjF, ScopedPrinter &Writer);

  void printUnwindInfo() override;
  void printNeededLibraries() override;
  void printHashTable() override;
  void printGnuHashTable() override;
  void printLoadName() override;
  void printVersionInfo() override;
  void printArchSpecificInfo() override;
  void printStackMap() const override;

  const object::ELFObjectFile<ELFT> &getElfObject() const { return ObjF; };

  std::string describe(const Elf_Shdr &Sec) const;

  unsigned getHashTableEntSize() const {
    // EM_S390 and ELF::EM_ALPHA platforms use 8-bytes entries in SHT_HASH
    // sections. This violates the ELF specification.
    if (Obj.getHeader().e_machine == ELF::EM_S390 ||
        Obj.getHeader().e_machine == ELF::EM_ALPHA)
      return 8;
    return 4;
  }

  Elf_Dyn_Range dynamic_table() const {
    // A valid .dynamic section contains an array of entries terminated
    // with a DT_NULL entry. However, sometimes the section content may
    // continue past the DT_NULL entry, so to dump the section correctly,
    // we first find the end of the entries by iterating over them.
    Elf_Dyn_Range Table = DynamicTable.template getAsArrayRef<Elf_Dyn>();

    size_t Size = 0;
    while (Size < Table.size())
      if (Table[Size++].getTag() == DT_NULL)
        break;

    return Table.slice(0, Size);
  }

  Elf_Sym_Range dynamic_symbols() const {
    if (!DynSymRegion)
      return Elf_Sym_Range();
    return DynSymRegion->template getAsArrayRef<Elf_Sym>();
  }

  const Elf_Shdr *findSectionByName(StringRef Name) const;

  StringRef getDynamicStringTable() const { return DynamicStringTable; }

protected:
  virtual void printVersionSymbolSection(const Elf_Shdr *Sec) = 0;
  virtual void printVersionDefinitionSection(const Elf_Shdr *Sec) = 0;
  virtual void printVersionDependencySection(const Elf_Shdr *Sec) = 0;

  void
  printDependentLibsHelper(function_ref<void(const Elf_Shdr &)> OnSectionStart,
                           function_ref<void(StringRef, uint64_t)> OnLibEntry);

  virtual void printRelRelaReloc(const Relocation<ELFT> &R,
                                 const RelSymbol<ELFT> &RelSym) = 0;
  virtual void printRelrReloc(const Elf_Relr &R) = 0;
  virtual void printDynamicRelocHeader(unsigned Type, StringRef Name,
                                       const DynRegionInfo &Reg) {}
  void printReloc(const Relocation<ELFT> &R, unsigned RelIndex,
                  const Elf_Shdr &Sec, const Elf_Shdr *SymTab);
  void printDynamicReloc(const Relocation<ELFT> &R);
  void printDynamicRelocationsHelper();
  void printRelocationsHelper(const Elf_Shdr &Sec);
  void forEachRelocationDo(
      const Elf_Shdr &Sec, bool RawRelr,
      llvm::function_ref<void(const Relocation<ELFT> &, unsigned,
                              const Elf_Shdr &, const Elf_Shdr *)>
          RelRelaFn,
      llvm::function_ref<void(const Elf_Relr &)> RelrFn);

  virtual void printSymtabMessage(const Elf_Shdr *Symtab, size_t Offset,
                                  bool NonVisibilityBitsUsed) const {};
  virtual void printSymbol(const Elf_Sym &Symbol, unsigned SymIndex,
                           DataRegion<Elf_Word> ShndxTable,
                           Optional<StringRef> StrTable, bool IsDynamic,
                           bool NonVisibilityBitsUsed) const = 0;

  virtual void printMipsABIFlags() = 0;
  virtual void printMipsGOT(const MipsGOTParser<ELFT> &Parser) = 0;
  virtual void printMipsPLT(const MipsGOTParser<ELFT> &Parser) = 0;

  Expected<ArrayRef<Elf_Versym>>
  getVersionTable(const Elf_Shdr &Sec, ArrayRef<Elf_Sym> *SymTab,
                  StringRef *StrTab, const Elf_Shdr **SymTabSec) const;
  StringRef getPrintableSectionName(const Elf_Shdr &Sec) const;

  std::vector<GroupSection> getGroups();

  // Returns the function symbol index for the given address. Matches the
  // symbol's section with FunctionSec when specified.
  // Returns None if no function symbol can be found for the address or in case
  // it is not defined in the specified section.
  SmallVector<uint32_t>
  getSymbolIndexesForFunctionAddress(uint64_t SymValue,
                                     Optional<const Elf_Shdr *> FunctionSec);
  bool printFunctionStackSize(uint64_t SymValue,
                              Optional<const Elf_Shdr *> FunctionSec,
                              const Elf_Shdr &StackSizeSec, DataExtractor Data,
                              uint64_t *Offset);
  void printStackSize(const Relocation<ELFT> &R, const Elf_Shdr &RelocSec,
                      unsigned Ndx, const Elf_Shdr *SymTab,
                      const Elf_Shdr *FunctionSec, const Elf_Shdr &StackSizeSec,
                      const RelocationResolver &Resolver, DataExtractor Data);
  virtual void printStackSizeEntry(uint64_t Size,
                                   ArrayRef<std::string> FuncNames) = 0;

  void printRelocatableStackSizes(std::function<void()> PrintHeader);
  void printNonRelocatableStackSizes(std::function<void()> PrintHeader);

  /// Retrieves sections with corresponding relocation sections based on
  /// IsMatch.
  void getSectionAndRelocations(
      std::function<bool(const Elf_Shdr &)> IsMatch,
      llvm::MapVector<const Elf_Shdr *, const Elf_Shdr *> &SecToRelocMap);

  const object::ELFObjectFile<ELFT> &ObjF;
  const ELFFile<ELFT> &Obj;
  StringRef FileName;

  Expected<DynRegionInfo> createDRI(uint64_t Offset, uint64_t Size,
                                    uint64_t EntSize) {
    if (Offset + Size < Offset || Offset + Size > Obj.getBufSize())
      return createError("offset (0x" + Twine::utohexstr(Offset) +
                         ") + size (0x" + Twine::utohexstr(Size) +
                         ") is greater than the file size (0x" +
                         Twine::utohexstr(Obj.getBufSize()) + ")");
    return DynRegionInfo(ObjF, *this, Obj.base() + Offset, Size, EntSize);
  }

  void printAttributes(unsigned, std::unique_ptr<ELFAttributeParser>,
                       support::endianness);
  void printMipsReginfo();
  void printMipsOptions();

  std::pair<const Elf_Phdr *, const Elf_Shdr *> findDynamic();
  void loadDynamicTable();
  void parseDynamicTable();

  Expected<StringRef> getSymbolVersion(const Elf_Sym &Sym,
                                       bool &IsDefault) const;
  Expected<SmallVector<Optional<VersionEntry>, 0> *> getVersionMap() const;

  DynRegionInfo DynRelRegion;
  DynRegionInfo DynRelaRegion;
  DynRegionInfo DynRelrRegion;
  DynRegionInfo DynPLTRelRegion;
  Optional<DynRegionInfo> DynSymRegion;
  DynRegionInfo DynSymTabShndxRegion;
  DynRegionInfo DynamicTable;
  StringRef DynamicStringTable;
  const Elf_Hash *HashTable = nullptr;
  const Elf_GnuHash *GnuHashTable = nullptr;
  const Elf_Shdr *DotSymtabSec = nullptr;
  const Elf_Shdr *DotDynsymSec = nullptr;
  const Elf_Shdr *DotAddrsigSec = nullptr;
  DenseMap<const Elf_Shdr *, ArrayRef<Elf_Word>> ShndxTables;
  Optional<uint64_t> SONameOffset;
  Optional<DenseMap<uint64_t, std::vector<uint32_t>>> AddressToIndexMap;

  const Elf_Shdr *SymbolVersionSection = nullptr;   // .gnu.version
  const Elf_Shdr *SymbolVersionNeedSection = nullptr; // .gnu.version_r
  const Elf_Shdr *SymbolVersionDefSection = nullptr; // .gnu.version_d

  std::string getFullSymbolName(const Elf_Sym &Symbol, unsigned SymIndex,
                                DataRegion<Elf_Word> ShndxTable,
                                Optional<StringRef> StrTable,
                                bool IsDynamic) const;
  Expected<unsigned>
  getSymbolSectionIndex(const Elf_Sym &Symbol, unsigned SymIndex,
                        DataRegion<Elf_Word> ShndxTable) const;
  Expected<StringRef> getSymbolSectionName(const Elf_Sym &Symbol,
                                           unsigned SectionIndex) const;
  std::string getStaticSymbolName(uint32_t Index) const;
  StringRef getDynamicString(uint64_t Value) const;

  void printSymbolsHelper(bool IsDynamic) const;
  std::string getDynamicEntry(uint64_t Type, uint64_t Value) const;

  Expected<RelSymbol<ELFT>> getRelocationTarget(const Relocation<ELFT> &R,
                                                const Elf_Shdr *SymTab) const;

  ArrayRef<Elf_Word> getShndxTable(const Elf_Shdr *Symtab) const;

private:
  mutable SmallVector<Optional<VersionEntry>, 0> VersionMap;
};

template <class ELFT>
std::string ELFDumper<ELFT>::describe(const Elf_Shdr &Sec) const {
  return ::describe(Obj, Sec);
}

namespace {

template <class ELFT> struct SymtabLink {
  typename ELFT::SymRange Symbols;
  StringRef StringTable;
  const typename ELFT::Shdr *SymTab;
};

// Returns the linked symbol table, symbols and associated string table for a
// given section.
template <class ELFT>
Expected<SymtabLink<ELFT>> getLinkAsSymtab(const ELFFile<ELFT> &Obj,
                                           const typename ELFT::Shdr &Sec,
                                           unsigned ExpectedType) {
  Expected<const typename ELFT::Shdr *> SymtabOrErr =
      Obj.getSection(Sec.sh_link);
  if (!SymtabOrErr)
    return createError("invalid section linked to " + describe(Obj, Sec) +
                       ": " + toString(SymtabOrErr.takeError()));

  if ((*SymtabOrErr)->sh_type != ExpectedType)
    return createError(
        "invalid section linked to " + describe(Obj, Sec) + ": expected " +
        object::getELFSectionTypeName(Obj.getHeader().e_machine, ExpectedType) +
        ", but got " +
        object::getELFSectionTypeName(Obj.getHeader().e_machine,
                                      (*SymtabOrErr)->sh_type));

  Expected<StringRef> StrTabOrErr = Obj.getLinkAsStrtab(**SymtabOrErr);
  if (!StrTabOrErr)
    return createError(
        "can't get a string table for the symbol table linked to " +
        describe(Obj, Sec) + ": " + toString(StrTabOrErr.takeError()));

  Expected<typename ELFT::SymRange> SymsOrErr = Obj.symbols(*SymtabOrErr);
  if (!SymsOrErr)
    return createError("unable to read symbols from the " + describe(Obj, Sec) +
                       ": " + toString(SymsOrErr.takeError()));

  return SymtabLink<ELFT>{*SymsOrErr, *StrTabOrErr, *SymtabOrErr};
}

} // namespace

template <class ELFT>
Expected<ArrayRef<typename ELFT::Versym>>
ELFDumper<ELFT>::getVersionTable(const Elf_Shdr &Sec, ArrayRef<Elf_Sym> *SymTab,
                                 StringRef *StrTab,
                                 const Elf_Shdr **SymTabSec) const {
  assert((!SymTab && !StrTab && !SymTabSec) || (SymTab && StrTab && SymTabSec));
  if (reinterpret_cast<uintptr_t>(Obj.base() + Sec.sh_offset) %
          sizeof(uint16_t) !=
      0)
    return createError("the " + describe(Sec) + " is misaligned");

  Expected<ArrayRef<Elf_Versym>> VersionsOrErr =
      Obj.template getSectionContentsAsArray<Elf_Versym>(Sec);
  if (!VersionsOrErr)
    return createError("cannot read content of " + describe(Sec) + ": " +
                       toString(VersionsOrErr.takeError()));

  Expected<SymtabLink<ELFT>> SymTabOrErr =
      getLinkAsSymtab(Obj, Sec, SHT_DYNSYM);
  if (!SymTabOrErr) {
    reportUniqueWarning(SymTabOrErr.takeError());
    return *VersionsOrErr;
  }

  if (SymTabOrErr->Symbols.size() != VersionsOrErr->size())
    reportUniqueWarning(describe(Sec) + ": the number of entries (" +
                        Twine(VersionsOrErr->size()) +
                        ") does not match the number of symbols (" +
                        Twine(SymTabOrErr->Symbols.size()) +
                        ") in the symbol table with index " +
                        Twine(Sec.sh_link));

  if (SymTab) {
    *SymTab = SymTabOrErr->Symbols;
    *StrTab = SymTabOrErr->StringTable;
    *SymTabSec = SymTabOrErr->SymTab;
  }
  return *VersionsOrErr;
}

template <class ELFT>
void ELFDumper<ELFT>::printSymbolsHelper(bool IsDynamic) const {
  Optional<StringRef> StrTable;
  size_t Entries = 0;
  Elf_Sym_Range Syms(nullptr, nullptr);
  const Elf_Shdr *SymtabSec = IsDynamic ? DotDynsymSec : DotSymtabSec;

  if (IsDynamic) {
    StrTable = DynamicStringTable;
    Syms = dynamic_symbols();
    Entries = Syms.size();
  } else if (DotSymtabSec) {
    if (Expected<StringRef> StrTableOrErr =
            Obj.getStringTableForSymtab(*DotSymtabSec))
      StrTable = *StrTableOrErr;
    else
      reportUniqueWarning(
          "unable to get the string table for the SHT_SYMTAB section: " +
          toString(StrTableOrErr.takeError()));

    if (Expected<Elf_Sym_Range> SymsOrErr = Obj.symbols(DotSymtabSec))
      Syms = *SymsOrErr;
    else
      reportUniqueWarning(
          "unable to read symbols from the SHT_SYMTAB section: " +
          toString(SymsOrErr.takeError()));
    Entries = DotSymtabSec->getEntityCount();
  }
  if (Syms.empty())
    return;

  // The st_other field has 2 logical parts. The first two bits hold the symbol
  // visibility (STV_*) and the remainder hold other platform-specific values.
  bool NonVisibilityBitsUsed =
      llvm::any_of(Syms, [](const Elf_Sym &S) { return S.st_other & ~0x3; });

  DataRegion<Elf_Word> ShndxTable =
      IsDynamic ? DataRegion<Elf_Word>(
                      (const Elf_Word *)this->DynSymTabShndxRegion.Addr,
                      this->getElfObject().getELFFile().end())
                : DataRegion<Elf_Word>(this->getShndxTable(SymtabSec));

  printSymtabMessage(SymtabSec, Entries, NonVisibilityBitsUsed);
  for (const Elf_Sym &Sym : Syms)
    printSymbol(Sym, &Sym - Syms.begin(), ShndxTable, StrTable, IsDynamic,
                NonVisibilityBitsUsed);
}

template <typename ELFT> class GNUELFDumper : public ELFDumper<ELFT> {
  formatted_raw_ostream &OS;

public:
  LLVM_ELF_IMPORT_TYPES_ELFT(ELFT)

  GNUELFDumper(const object::ELFObjectFile<ELFT> &ObjF, ScopedPrinter &Writer)
      : ELFDumper<ELFT>(ObjF, Writer),
        OS(static_cast<formatted_raw_ostream &>(Writer.getOStream())) {
    assert(&this->W.getOStream() == &llvm::fouts());
  }

  void printFileSummary(StringRef FileStr, ObjectFile &Obj,
                        ArrayRef<std::string> InputFilenames,
                        const Archive *A) override;
  void printFileHeaders() override;
  void printGroupSections() override;
  void printRelocations() override;
  void printSectionHeaders() override;
  void printSymbols(bool PrintSymbols, bool PrintDynamicSymbols) override;
  void printHashSymbols() override;
  void printSectionDetails() override;
  void printDependentLibs() override;
  void printDynamicTable() override;
  void printDynamicRelocations() override;
  void printSymtabMessage(const Elf_Shdr *Symtab, size_t Offset,
                          bool NonVisibilityBitsUsed) const override;
  void printProgramHeaders(bool PrintProgramHeaders,
                           cl::boolOrDefault PrintSectionMapping) override;
  void printVersionSymbolSection(const Elf_Shdr *Sec) override;
  void printVersionDefinitionSection(const Elf_Shdr *Sec) override;
  void printVersionDependencySection(const Elf_Shdr *Sec) override;
  void printHashHistograms() override;
  void printCGProfile() override;
  void printBBAddrMaps() override;
  void printAddrsig() override;
  void printNotes() override;
  void printELFLinkerOptions() override;
  void printStackSizes() override;

private:
  void printHashHistogram(const Elf_Hash &HashTable);
  void printGnuHashHistogram(const Elf_GnuHash &GnuHashTable);
  void printHashTableSymbols(const Elf_Hash &HashTable);
  void printGnuHashTableSymbols(const Elf_GnuHash &GnuHashTable);

  struct Field {
    std::string Str;
    unsigned Column;

    Field(StringRef S, unsigned Col) : Str(std::string(S)), Column(Col) {}
    Field(unsigned Col) : Column(Col) {}
  };

  template <typename T, typename TEnum>
  std::string printFlags(T Value, ArrayRef<EnumEntry<TEnum>> EnumValues,
                         TEnum EnumMask1 = {}, TEnum EnumMask2 = {},
                         TEnum EnumMask3 = {}) const {
    std::string Str;
    for (const EnumEntry<TEnum> &Flag : EnumValues) {
      if (Flag.Value == 0)
        continue;

      TEnum EnumMask{};
      if (Flag.Value & EnumMask1)
        EnumMask = EnumMask1;
      else if (Flag.Value & EnumMask2)
        EnumMask = EnumMask2;
      else if (Flag.Value & EnumMask3)
        EnumMask = EnumMask3;
      bool IsEnum = (Flag.Value & EnumMask) != 0;
      if ((!IsEnum && (Value & Flag.Value) == Flag.Value) ||
          (IsEnum && (Value & EnumMask) == Flag.Value)) {
        if (!Str.empty())
          Str += ", ";
        Str += Flag.AltName;
      }
    }
    return Str;
  }

  formatted_raw_ostream &printField(struct Field F) const {
    if (F.Column != 0)
      OS.PadToColumn(F.Column);
    OS << F.Str;
    OS.flush();
    return OS;
  }
  void printHashedSymbol(const Elf_Sym *Sym, unsigned SymIndex,
                         DataRegion<Elf_Word> ShndxTable, StringRef StrTable,
                         uint32_t Bucket);
  void printRelrReloc(const Elf_Relr &R) override;
  void printRelRelaReloc(const Relocation<ELFT> &R,
                         const RelSymbol<ELFT> &RelSym) override;
  void printSymbol(const Elf_Sym &Symbol, unsigned SymIndex,
                   DataRegion<Elf_Word> ShndxTable,
                   Optional<StringRef> StrTable, bool IsDynamic,
                   bool NonVisibilityBitsUsed) const override;
  void printDynamicRelocHeader(unsigned Type, StringRef Name,
                               const DynRegionInfo &Reg) override;

  std::string getSymbolSectionNdx(const Elf_Sym &Symbol, unsigned SymIndex,
                                  DataRegion<Elf_Word> ShndxTable) const;
  void printProgramHeaders() override;
  void printSectionMapping() override;
  void printGNUVersionSectionProlog(const typename ELFT::Shdr &Sec,
                                    const Twine &Label, unsigned EntriesNum);

  void printStackSizeEntry(uint64_t Size,
                           ArrayRef<std::string> FuncNames) override;

  void printMipsGOT(const MipsGOTParser<ELFT> &Parser) override;
  void printMipsPLT(const MipsGOTParser<ELFT> &Parser) override;
  void printMipsABIFlags() override;
};

template <typename ELFT> class LLVMELFDumper : public ELFDumper<ELFT> {
public:
  LLVM_ELF_IMPORT_TYPES_ELFT(ELFT)

  LLVMELFDumper(const object::ELFObjectFile<ELFT> &ObjF, ScopedPrinter &Writer)
      : ELFDumper<ELFT>(ObjF, Writer), W(Writer) {}

  void printFileHeaders() override;
  void printGroupSections() override;
  void printRelocations() override;
  void printSectionHeaders() override;
  void printSymbols(bool PrintSymbols, bool PrintDynamicSymbols) override;
  void printDependentLibs() override;
  void printDynamicTable() override;
  void printDynamicRelocations() override;
  void printProgramHeaders(bool PrintProgramHeaders,
                           cl::boolOrDefault PrintSectionMapping) override;
  void printVersionSymbolSection(const Elf_Shdr *Sec) override;
  void printVersionDefinitionSection(const Elf_Shdr *Sec) override;
  void printVersionDependencySection(const Elf_Shdr *Sec) override;
  void printHashHistograms() override;
  void printCGProfile() override;
  void printBBAddrMaps() override;
  void printAddrsig() override;
  void printNotes() override;
  void printELFLinkerOptions() override;
  void printStackSizes() override;

private:
  void printRelrReloc(const Elf_Relr &R) override;
  void printRelRelaReloc(const Relocation<ELFT> &R,
                         const RelSymbol<ELFT> &RelSym) override;

  void printSymbolSection(const Elf_Sym &Symbol, unsigned SymIndex,
                          DataRegion<Elf_Word> ShndxTable) const;
  void printSymbol(const Elf_Sym &Symbol, unsigned SymIndex,
                   DataRegion<Elf_Word> ShndxTable,
                   Optional<StringRef> StrTable, bool IsDynamic,
                   bool /*NonVisibilityBitsUsed*/) const override;
  void printProgramHeaders() override;
  void printSectionMapping() override {}
  void printStackSizeEntry(uint64_t Size,
                           ArrayRef<std::string> FuncNames) override;

  void printMipsGOT(const MipsGOTParser<ELFT> &Parser) override;
  void printMipsPLT(const MipsGOTParser<ELFT> &Parser) override;
  void printMipsABIFlags() override;

protected:
  ScopedPrinter &W;
};

// JSONELFDumper shares most of the same implementation as LLVMELFDumper except
// it uses a JSONScopedPrinter.
template <typename ELFT> class JSONELFDumper : public LLVMELFDumper<ELFT> {
public:
  LLVM_ELF_IMPORT_TYPES_ELFT(ELFT)

  JSONELFDumper(const object::ELFObjectFile<ELFT> &ObjF, ScopedPrinter &Writer)
      : LLVMELFDumper<ELFT>(ObjF, Writer) {}

  void printFileSummary(StringRef FileStr, ObjectFile &Obj,
                        ArrayRef<std::string> InputFilenames,
                        const Archive *A) override;

private:
  std::unique_ptr<DictScope> FileScope;
};

} // end anonymous namespace

namespace llvm {

template <class ELFT>
static std::unique_ptr<ObjDumper>
createELFDumper(const ELFObjectFile<ELFT> &Obj, ScopedPrinter &Writer) {
  if (opts::Output == opts::GNU)
    return std::make_unique<GNUELFDumper<ELFT>>(Obj, Writer);
  else if (opts::Output == opts::JSON)
    return std::make_unique<JSONELFDumper<ELFT>>(Obj, Writer);
  return std::make_unique<LLVMELFDumper<ELFT>>(Obj, Writer);
}

std::unique_ptr<ObjDumper> createELFDumper(const object::ELFObjectFileBase &Obj,
                                           ScopedPrinter &Writer) {
  // Little-endian 32-bit
  if (const ELF32LEObjectFile *ELFObj = dyn_cast<ELF32LEObjectFile>(&Obj))
    return createELFDumper(*ELFObj, Writer);

  // Big-endian 32-bit
  if (const ELF32BEObjectFile *ELFObj = dyn_cast<ELF32BEObjectFile>(&Obj))
    return createELFDumper(*ELFObj, Writer);

  // Little-endian 64-bit
  if (const ELF64LEObjectFile *ELFObj = dyn_cast<ELF64LEObjectFile>(&Obj))
    return createELFDumper(*ELFObj, Writer);

  // Big-endian 64-bit
  return createELFDumper(*cast<ELF64BEObjectFile>(&Obj), Writer);
}

} // end namespace llvm

template <class ELFT>
Expected<SmallVector<Optional<VersionEntry>, 0> *>
ELFDumper<ELFT>::getVersionMap() const {
  // If the VersionMap has already been loaded or if there is no dynamic symtab
  // or version table, there is nothing to do.
  if (!VersionMap.empty() || !DynSymRegion || !SymbolVersionSection)
    return &VersionMap;

  Expected<SmallVector<Optional<VersionEntry>, 0>> MapOrErr =
      Obj.loadVersionMap(SymbolVersionNeedSection, SymbolVersionDefSection);
  if (MapOrErr)
    VersionMap = *MapOrErr;
  else
    return MapOrErr.takeError();

  return &VersionMap;
}

template <typename ELFT>
Expected<StringRef> ELFDumper<ELFT>::getSymbolVersion(const Elf_Sym &Sym,
                                                      bool &IsDefault) const {
  // This is a dynamic symbol. Look in the GNU symbol version table.
  if (!SymbolVersionSection) {
    // No version table.
    IsDefault = false;
    return "";
  }

  assert(DynSymRegion && "DynSymRegion has not been initialised");
  // Determine the position in the symbol table of this entry.
  size_t EntryIndex = (reinterpret_cast<uintptr_t>(&Sym) -
                       reinterpret_cast<uintptr_t>(DynSymRegion->Addr)) /
                      sizeof(Elf_Sym);

  // Get the corresponding version index entry.
  Expected<const Elf_Versym *> EntryOrErr =
      Obj.template getEntry<Elf_Versym>(*SymbolVersionSection, EntryIndex);
  if (!EntryOrErr)
    return EntryOrErr.takeError();

  unsigned Version = (*EntryOrErr)->vs_index;
  if (Version == VER_NDX_LOCAL || Version == VER_NDX_GLOBAL) {
    IsDefault = false;
    return "";
  }

  Expected<SmallVector<Optional<VersionEntry>, 0> *> MapOrErr =
      getVersionMap();
  if (!MapOrErr)
    return MapOrErr.takeError();

  return Obj.getSymbolVersionByIndex(Version, IsDefault, **MapOrErr,
                                     Sym.st_shndx == ELF::SHN_UNDEF);
}

template <typename ELFT>
Expected<RelSymbol<ELFT>>
ELFDumper<ELFT>::getRelocationTarget(const Relocation<ELFT> &R,
                                     const Elf_Shdr *SymTab) const {
  if (R.Symbol == 0)
    return RelSymbol<ELFT>(nullptr, "");

  Expected<const Elf_Sym *> SymOrErr =
      Obj.template getEntry<Elf_Sym>(*SymTab, R.Symbol);
  if (!SymOrErr)
    return createError("unable to read an entry with index " + Twine(R.Symbol) +
                       " from " + describe(*SymTab) + ": " +
                       toString(SymOrErr.takeError()));
  const Elf_Sym *Sym = *SymOrErr;
  if (!Sym)
    return RelSymbol<ELFT>(nullptr, "");

  Expected<StringRef> StrTableOrErr = Obj.getStringTableForSymtab(*SymTab);
  if (!StrTableOrErr)
    return StrTableOrErr.takeError();

  const Elf_Sym *FirstSym =
      cantFail(Obj.template getEntry<Elf_Sym>(*SymTab, 0));
  std::string SymbolName =
      getFullSymbolName(*Sym, Sym - FirstSym, getShndxTable(SymTab),
                        *StrTableOrErr, SymTab->sh_type == SHT_DYNSYM);
  return RelSymbol<ELFT>(Sym, SymbolName);
}

template <typename ELFT>
ArrayRef<typename ELFT::Word>
ELFDumper<ELFT>::getShndxTable(const Elf_Shdr *Symtab) const {
  if (Symtab) {
    auto It = ShndxTables.find(Symtab);
    if (It != ShndxTables.end())
      return It->second;
  }
  return {};
}

static std::string maybeDemangle(StringRef Name) {
  return opts::Demangle ? demangle(std::string(Name)) : Name.str();
}

template <typename ELFT>
std::string ELFDumper<ELFT>::getStaticSymbolName(uint32_t Index) const {
  auto Warn = [&](Error E) -> std::string {
    reportUniqueWarning("unable to read the name of symbol with index " +
                        Twine(Index) + ": " + toString(std::move(E)));
    return "<?>";
  };

  Expected<const typename ELFT::Sym *> SymOrErr =
      Obj.getSymbol(DotSymtabSec, Index);
  if (!SymOrErr)
    return Warn(SymOrErr.takeError());

  Expected<StringRef> StrTabOrErr = Obj.getStringTableForSymtab(*DotSymtabSec);
  if (!StrTabOrErr)
    return Warn(StrTabOrErr.takeError());

  Expected<StringRef> NameOrErr = (*SymOrErr)->getName(*StrTabOrErr);
  if (!NameOrErr)
    return Warn(NameOrErr.takeError());
  return maybeDemangle(*NameOrErr);
}

template <typename ELFT>
std::string ELFDumper<ELFT>::getFullSymbolName(const Elf_Sym &Symbol,
                                               unsigned SymIndex,
                                               DataRegion<Elf_Word> ShndxTable,
                                               Optional<StringRef> StrTable,
                                               bool IsDynamic) const {
  if (!StrTable)
    return "<?>";

  std::string SymbolName;
  if (Expected<StringRef> NameOrErr = Symbol.getName(*StrTable)) {
    SymbolName = maybeDemangle(*NameOrErr);
  } else {
    reportUniqueWarning(NameOrErr.takeError());
    return "<?>";
  }

  if (SymbolName.empty() && Symbol.getType() == ELF::STT_SECTION) {
    Expected<unsigned> SectionIndex =
        getSymbolSectionIndex(Symbol, SymIndex, ShndxTable);
    if (!SectionIndex) {
      reportUniqueWarning(SectionIndex.takeError());
      return "<?>";
    }
    Expected<StringRef> NameOrErr = getSymbolSectionName(Symbol, *SectionIndex);
    if (!NameOrErr) {
      reportUniqueWarning(NameOrErr.takeError());
      return ("<section " + Twine(*SectionIndex) + ">").str();
    }
    return std::string(*NameOrErr);
  }

  if (!IsDynamic)
    return SymbolName;

  bool IsDefault;
  Expected<StringRef> VersionOrErr = getSymbolVersion(Symbol, IsDefault);
  if (!VersionOrErr) {
    reportUniqueWarning(VersionOrErr.takeError());
    return SymbolName + "@<corrupt>";
  }

  if (!VersionOrErr->empty()) {
    SymbolName += (IsDefault ? "@@" : "@");
    SymbolName += *VersionOrErr;
  }
  return SymbolName;
}

template <typename ELFT>
Expected<unsigned>
ELFDumper<ELFT>::getSymbolSectionIndex(const Elf_Sym &Symbol, unsigned SymIndex,
                                       DataRegion<Elf_Word> ShndxTable) const {
  unsigned Ndx = Symbol.st_shndx;
  if (Ndx == SHN_XINDEX)
    return object::getExtendedSymbolTableIndex<ELFT>(Symbol, SymIndex,
                                                     ShndxTable);
  if (Ndx != SHN_UNDEF && Ndx < SHN_LORESERVE)
    return Ndx;

  auto CreateErr = [&](const Twine &Name, Optional<unsigned> Offset = None) {
    std::string Desc;
    if (Offset)
      Desc = (Name + "+0x" + Twine::utohexstr(*Offset)).str();
    else
      Desc = Name.str();
    return createError(
        "unable to get section index for symbol with st_shndx = 0x" +
        Twine::utohexstr(Ndx) + " (" + Desc + ")");
  };

  if (Ndx >= ELF::SHN_LOPROC && Ndx <= ELF::SHN_HIPROC)
    return CreateErr("SHN_LOPROC", Ndx - ELF::SHN_LOPROC);
  if (Ndx >= ELF::SHN_LOOS && Ndx <= ELF::SHN_HIOS)
    return CreateErr("SHN_LOOS", Ndx - ELF::SHN_LOOS);
  if (Ndx == ELF::SHN_UNDEF)
    return CreateErr("SHN_UNDEF");
  if (Ndx == ELF::SHN_ABS)
    return CreateErr("SHN_ABS");
  if (Ndx == ELF::SHN_COMMON)
    return CreateErr("SHN_COMMON");
  return CreateErr("SHN_LORESERVE", Ndx - SHN_LORESERVE);
}

template <typename ELFT>
Expected<StringRef>
ELFDumper<ELFT>::getSymbolSectionName(const Elf_Sym &Symbol,
                                      unsigned SectionIndex) const {
  Expected<const Elf_Shdr *> SecOrErr = Obj.getSection(SectionIndex);
  if (!SecOrErr)
    return SecOrErr.takeError();
  return Obj.getSectionName(**SecOrErr);
}

template <class ELFO>
static const typename ELFO::Elf_Shdr *
findNotEmptySectionByAddress(const ELFO &Obj, StringRef FileName,
                             uint64_t Addr) {
  for (const typename ELFO::Elf_Shdr &Shdr : cantFail(Obj.sections()))
    if (Shdr.sh_addr == Addr && Shdr.sh_size > 0)
      return &Shdr;
  return nullptr;
}

const EnumEntry<unsigned> ElfClass[] = {
  {"None",   "none",   ELF::ELFCLASSNONE},
  {"32-bit", "ELF32",  ELF::ELFCLASS32},
  {"64-bit", "ELF64",  ELF::ELFCLASS64},
};

const EnumEntry<unsigned> ElfDataEncoding[] = {
  {"None",         "none",                          ELF::ELFDATANONE},
  {"LittleEndian", "2's complement, little endian", ELF::ELFDATA2LSB},
  {"BigEndian",    "2's complement, big endian",    ELF::ELFDATA2MSB},
};

const EnumEntry<unsigned> ElfObjectFileType[] = {
  {"None",         "NONE (none)",              ELF::ET_NONE},
  {"Relocatable",  "REL (Relocatable file)",   ELF::ET_REL},
  {"Executable",   "EXEC (Executable file)",   ELF::ET_EXEC},
  {"SharedObject", "DYN (Shared object file)", ELF::ET_DYN},
  {"Core",         "CORE (Core file)",         ELF::ET_CORE},
};

const EnumEntry<unsigned> ElfOSABI[] = {
  {"SystemV",      "UNIX - System V",      ELF::ELFOSABI_NONE},
  {"HPUX",         "UNIX - HP-UX",         ELF::ELFOSABI_HPUX},
  {"NetBSD",       "UNIX - NetBSD",        ELF::ELFOSABI_NETBSD},
  {"GNU/Linux",    "UNIX - GNU",           ELF::ELFOSABI_LINUX},
  {"GNU/Hurd",     "GNU/Hurd",             ELF::ELFOSABI_HURD},
  {"Solaris",      "UNIX - Solaris",       ELF::ELFOSABI_SOLARIS},
  {"AIX",          "UNIX - AIX",           ELF::ELFOSABI_AIX},
  {"IRIX",         "UNIX - IRIX",          ELF::ELFOSABI_IRIX},
  {"FreeBSD",      "UNIX - FreeBSD",       ELF::ELFOSABI_FREEBSD},
  {"TRU64",        "UNIX - TRU64",         ELF::ELFOSABI_TRU64},
  {"Modesto",      "Novell - Modesto",     ELF::ELFOSABI_MODESTO},
  {"OpenBSD",      "UNIX - OpenBSD",       ELF::ELFOSABI_OPENBSD},
  {"OpenVMS",      "VMS - OpenVMS",        ELF::ELFOSABI_OPENVMS},
  {"NSK",          "HP - Non-Stop Kernel", ELF::ELFOSABI_NSK},
  {"AROS",         "AROS",                 ELF::ELFOSABI_AROS},
  {"FenixOS",      "FenixOS",              ELF::ELFOSABI_FENIXOS},
  {"CloudABI",     "CloudABI",             ELF::ELFOSABI_CLOUDABI},
  {"Standalone",   "Standalone App",       ELF::ELFOSABI_STANDALONE}
};

const EnumEntry<unsigned> AMDGPUElfOSABI[] = {
  {"AMDGPU_HSA",    "AMDGPU - HSA",    ELF::ELFOSABI_AMDGPU_HSA},
  {"AMDGPU_PAL",    "AMDGPU - PAL",    ELF::ELFOSABI_AMDGPU_PAL},
  {"AMDGPU_MESA3D", "AMDGPU - MESA3D", ELF::ELFOSABI_AMDGPU_MESA3D}
};

const EnumEntry<unsigned> ARMElfOSABI[] = {
  {"ARM", "ARM", ELF::ELFOSABI_ARM}
};

const EnumEntry<unsigned> C6000ElfOSABI[] = {
  {"C6000_ELFABI", "Bare-metal C6000", ELF::ELFOSABI_C6000_ELFABI},
  {"C6000_LINUX",  "Linux C6000",      ELF::ELFOSABI_C6000_LINUX}
};

const EnumEntry<unsigned> ElfMachineType[] = {
  ENUM_ENT(EM_NONE,          "None"),
  ENUM_ENT(EM_M32,           "WE32100"),
  ENUM_ENT(EM_SPARC,         "Sparc"),
  ENUM_ENT(EM_386,           "Intel 80386"),
  ENUM_ENT(EM_68K,           "MC68000"),
  ENUM_ENT(EM_88K,           "MC88000"),
  ENUM_ENT(EM_IAMCU,         "EM_IAMCU"),
  ENUM_ENT(EM_860,           "Intel 80860"),
  ENUM_ENT(EM_MIPS,          "MIPS R3000"),
  ENUM_ENT(EM_S370,          "IBM System/370"),
  ENUM_ENT(EM_MIPS_RS3_LE,   "MIPS R3000 little-endian"),
  ENUM_ENT(EM_PARISC,        "HPPA"),
  ENUM_ENT(EM_VPP500,        "Fujitsu VPP500"),
  ENUM_ENT(EM_SPARC32PLUS,   "Sparc v8+"),
  ENUM_ENT(EM_960,           "Intel 80960"),
  ENUM_ENT(EM_PPC,           "PowerPC"),
  ENUM_ENT(EM_PPC64,         "PowerPC64"),
  ENUM_ENT(EM_S390,          "IBM S/390"),
  ENUM_ENT(EM_SPU,           "SPU"),
  ENUM_ENT(EM_V800,          "NEC V800 series"),
  ENUM_ENT(EM_FR20,          "Fujistsu FR20"),
  ENUM_ENT(EM_RH32,          "TRW RH-32"),
  ENUM_ENT(EM_RCE,           "Motorola RCE"),
  ENUM_ENT(EM_ARM,           "ARM"),
  ENUM_ENT(EM_ALPHA,         "EM_ALPHA"),
  ENUM_ENT(EM_SH,            "Hitachi SH"),
  ENUM_ENT(EM_SPARCV9,       "Sparc v9"),
  ENUM_ENT(EM_TRICORE,       "Siemens Tricore"),
  ENUM_ENT(EM_ARC,           "ARC"),
  ENUM_ENT(EM_H8_300,        "Hitachi H8/300"),
  ENUM_ENT(EM_H8_300H,       "Hitachi H8/300H"),
  ENUM_ENT(EM_H8S,           "Hitachi H8S"),
  ENUM_ENT(EM_H8_500,        "Hitachi H8/500"),
  ENUM_ENT(EM_IA_64,         "Intel IA-64"),
  ENUM_ENT(EM_MIPS_X,        "Stanford MIPS-X"),
  ENUM_ENT(EM_COLDFIRE,      "Motorola Coldfire"),
  ENUM_ENT(EM_68HC12,        "Motorola MC68HC12 Microcontroller"),
  ENUM_ENT(EM_MMA,           "Fujitsu Multimedia Accelerator"),
  ENUM_ENT(EM_PCP,           "Siemens PCP"),
  ENUM_ENT(EM_NCPU,          "Sony nCPU embedded RISC processor"),
  ENUM_ENT(EM_NDR1,          "Denso NDR1 microprocesspr"),
  ENUM_ENT(EM_STARCORE,      "Motorola Star*Core processor"),
  ENUM_ENT(EM_ME16,          "Toyota ME16 processor"),
  ENUM_ENT(EM_ST100,         "STMicroelectronics ST100 processor"),
  ENUM_ENT(EM_TINYJ,         "Advanced Logic Corp. TinyJ embedded processor"),
  ENUM_ENT(EM_X86_64,        "Advanced Micro Devices X86-64"),
  ENUM_ENT(EM_PDSP,          "Sony DSP processor"),
  ENUM_ENT(EM_PDP10,         "Digital Equipment Corp. PDP-10"),
  ENUM_ENT(EM_PDP11,         "Digital Equipment Corp. PDP-11"),
  ENUM_ENT(EM_FX66,          "Siemens FX66 microcontroller"),
  ENUM_ENT(EM_ST9PLUS,       "STMicroelectronics ST9+ 8/16 bit microcontroller"),
  ENUM_ENT(EM_ST7,           "STMicroelectronics ST7 8-bit microcontroller"),
  ENUM_ENT(EM_68HC16,        "Motorola MC68HC16 Microcontroller"),
  ENUM_ENT(EM_68HC11,        "Motorola MC68HC11 Microcontroller"),
  ENUM_ENT(EM_68HC08,        "Motorola MC68HC08 Microcontroller"),
  ENUM_ENT(EM_68HC05,        "Motorola MC68HC05 Microcontroller"),
  ENUM_ENT(EM_SVX,           "Silicon Graphics SVx"),
  ENUM_ENT(EM_ST19,          "STMicroelectronics ST19 8-bit microcontroller"),
  ENUM_ENT(EM_VAX,           "Digital VAX"),
  ENUM_ENT(EM_CRIS,          "Axis Communications 32-bit embedded processor"),
  ENUM_ENT(EM_JAVELIN,       "Infineon Technologies 32-bit embedded cpu"),
  ENUM_ENT(EM_FIREPATH,      "Element 14 64-bit DSP processor"),
  ENUM_ENT(EM_ZSP,           "LSI Logic's 16-bit DSP processor"),
  ENUM_ENT(EM_MMIX,          "Donald Knuth's educational 64-bit processor"),
  ENUM_ENT(EM_HUANY,         "Harvard Universitys's machine-independent object format"),
  ENUM_ENT(EM_PRISM,         "Vitesse Prism"),
  ENUM_ENT(EM_AVR,           "Atmel AVR 8-bit microcontroller"),
  ENUM_ENT(EM_FR30,          "Fujitsu FR30"),
  ENUM_ENT(EM_D10V,          "Mitsubishi D10V"),
  ENUM_ENT(EM_D30V,          "Mitsubishi D30V"),
  ENUM_ENT(EM_V850,          "NEC v850"),
  ENUM_ENT(EM_M32R,          "Renesas M32R (formerly Mitsubishi M32r)"),
  ENUM_ENT(EM_MN10300,       "Matsushita MN10300"),
  ENUM_ENT(EM_MN10200,       "Matsushita MN10200"),
  ENUM_ENT(EM_PJ,            "picoJava"),
  ENUM_ENT(EM_OPENRISC,      "OpenRISC 32-bit embedded processor"),
  ENUM_ENT(EM_ARC_COMPACT,   "EM_ARC_COMPACT"),
  ENUM_ENT(EM_XTENSA,        "Tensilica Xtensa Processor"),
  ENUM_ENT(EM_VIDEOCORE,     "Alphamosaic VideoCore processor"),
  ENUM_ENT(EM_TMM_GPP,       "Thompson Multimedia General Purpose Processor"),
  ENUM_ENT(EM_NS32K,         "National Semiconductor 32000 series"),
  ENUM_ENT(EM_TPC,           "Tenor Network TPC processor"),
  ENUM_ENT(EM_SNP1K,         "EM_SNP1K"),
  ENUM_ENT(EM_ST200,         "STMicroelectronics ST200 microcontroller"),
  ENUM_ENT(EM_IP2K,          "Ubicom IP2xxx 8-bit microcontrollers"),
  ENUM_ENT(EM_MAX,           "MAX Processor"),
  ENUM_ENT(EM_CR,            "National Semiconductor CompactRISC"),
  ENUM_ENT(EM_F2MC16,        "Fujitsu F2MC16"),
  ENUM_ENT(EM_MSP430,        "Texas Instruments msp430 microcontroller"),
  ENUM_ENT(EM_BLACKFIN,      "Analog Devices Blackfin"),
  ENUM_ENT(EM_SE_C33,        "S1C33 Family of Seiko Epson processors"),
  ENUM_ENT(EM_SEP,           "Sharp embedded microprocessor"),
  ENUM_ENT(EM_ARCA,          "Arca RISC microprocessor"),
  ENUM_ENT(EM_UNICORE,       "Unicore"),
  ENUM_ENT(EM_EXCESS,        "eXcess 16/32/64-bit configurable embedded CPU"),
  ENUM_ENT(EM_DXP,           "Icera Semiconductor Inc. Deep Execution Processor"),
  ENUM_ENT(EM_ALTERA_NIOS2,  "Altera Nios"),
  ENUM_ENT(EM_CRX,           "National Semiconductor CRX microprocessor"),
  ENUM_ENT(EM_XGATE,         "Motorola XGATE embedded processor"),
  ENUM_ENT(EM_C166,          "Infineon Technologies xc16x"),
  ENUM_ENT(EM_M16C,          "Renesas M16C"),
  ENUM_ENT(EM_DSPIC30F,      "Microchip Technology dsPIC30F Digital Signal Controller"),
  ENUM_ENT(EM_CE,            "Freescale Communication Engine RISC core"),
  ENUM_ENT(EM_M32C,          "Renesas M32C"),
  ENUM_ENT(EM_TSK3000,       "Altium TSK3000 core"),
  ENUM_ENT(EM_RS08,          "Freescale RS08 embedded processor"),
  ENUM_ENT(EM_SHARC,         "EM_SHARC"),
  ENUM_ENT(EM_ECOG2,         "Cyan Technology eCOG2 microprocessor"),
  ENUM_ENT(EM_SCORE7,        "SUNPLUS S+Core"),
  ENUM_ENT(EM_DSP24,         "New Japan Radio (NJR) 24-bit DSP Processor"),
  ENUM_ENT(EM_VIDEOCORE3,    "Broadcom VideoCore III processor"),
  ENUM_ENT(EM_LATTICEMICO32, "Lattice Mico32"),
  ENUM_ENT(EM_SE_C17,        "Seiko Epson C17 family"),
  ENUM_ENT(EM_TI_C6000,      "Texas Instruments TMS320C6000 DSP family"),
  ENUM_ENT(EM_TI_C2000,      "Texas Instruments TMS320C2000 DSP family"),
  ENUM_ENT(EM_TI_C5500,      "Texas Instruments TMS320C55x DSP family"),
  ENUM_ENT(EM_MMDSP_PLUS,    "STMicroelectronics 64bit VLIW Data Signal Processor"),
  ENUM_ENT(EM_CYPRESS_M8C,   "Cypress M8C microprocessor"),
  ENUM_ENT(EM_R32C,          "Renesas R32C series microprocessors"),
  ENUM_ENT(EM_TRIMEDIA,      "NXP Semiconductors TriMedia architecture family"),
  ENUM_ENT(EM_HEXAGON,       "Qualcomm Hexagon"),
  ENUM_ENT(EM_8051,          "Intel 8051 and variants"),
  ENUM_ENT(EM_STXP7X,        "STMicroelectronics STxP7x family"),
  ENUM_ENT(EM_NDS32,         "Andes Technology compact code size embedded RISC processor family"),
  ENUM_ENT(EM_ECOG1,         "Cyan Technology eCOG1 microprocessor"),
  // FIXME: Following EM_ECOG1X definitions is dead code since EM_ECOG1X has
  //        an identical number to EM_ECOG1.
  ENUM_ENT(EM_ECOG1X,        "Cyan Technology eCOG1X family"),
  ENUM_ENT(EM_MAXQ30,        "Dallas Semiconductor MAXQ30 Core microcontrollers"),
  ENUM_ENT(EM_XIMO16,        "New Japan Radio (NJR) 16-bit DSP Processor"),
  ENUM_ENT(EM_MANIK,         "M2000 Reconfigurable RISC Microprocessor"),
  ENUM_ENT(EM_CRAYNV2,       "Cray Inc. NV2 vector architecture"),
  ENUM_ENT(EM_RX,            "Renesas RX"),
  ENUM_ENT(EM_METAG,         "Imagination Technologies Meta processor architecture"),
  ENUM_ENT(EM_MCST_ELBRUS,   "MCST Elbrus general purpose hardware architecture"),
  ENUM_ENT(EM_ECOG16,        "Cyan Technology eCOG16 family"),
  ENUM_ENT(EM_CR16,          "National Semiconductor CompactRISC 16-bit processor"),
  ENUM_ENT(EM_ETPU,          "Freescale Extended Time Processing Unit"),
  ENUM_ENT(EM_SLE9X,         "Infineon Technologies SLE9X core"),
  ENUM_ENT(EM_L10M,          "EM_L10M"),
  ENUM_ENT(EM_K10M,          "EM_K10M"),
  ENUM_ENT(EM_AARCH64,       "AArch64"),
  ENUM_ENT(EM_AVR32,         "Atmel Corporation 32-bit microprocessor family"),
  ENUM_ENT(EM_STM8,          "STMicroeletronics STM8 8-bit microcontroller"),
  ENUM_ENT(EM_TILE64,        "Tilera TILE64 multicore architecture family"),
  ENUM_ENT(EM_TILEPRO,       "Tilera TILEPro multicore architecture family"),
  ENUM_ENT(EM_MICROBLAZE,    "Xilinx MicroBlaze 32-bit RISC soft processor core"),
  ENUM_ENT(EM_CUDA,          "NVIDIA CUDA architecture"),
  ENUM_ENT(EM_TILEGX,        "Tilera TILE-Gx multicore architecture family"),
  ENUM_ENT(EM_CLOUDSHIELD,   "EM_CLOUDSHIELD"),
  ENUM_ENT(EM_COREA_1ST,     "EM_COREA_1ST"),
  ENUM_ENT(EM_COREA_2ND,     "EM_COREA_2ND"),
  ENUM_ENT(EM_ARC_COMPACT2,  "EM_ARC_COMPACT2"),
  ENUM_ENT(EM_OPEN8,         "EM_OPEN8"),
  ENUM_ENT(EM_RL78,          "Renesas RL78"),
  ENUM_ENT(EM_VIDEOCORE5,    "Broadcom VideoCore V processor"),
  ENUM_ENT(EM_78KOR,         "EM_78KOR"),
  ENUM_ENT(EM_56800EX,       "EM_56800EX"),
  ENUM_ENT(EM_AMDGPU,        "EM_AMDGPU"),
  ENUM_ENT(EM_RISCV,         "RISC-V"),
  ENUM_ENT(EM_LANAI,         "EM_LANAI"),
  ENUM_ENT(EM_BPF,           "EM_BPF"),
  ENUM_ENT(EM_VE,            "NEC SX-Aurora Vector Engine"),
  ENUM_ENT(EM_LOONGARCH,     "LoongArch"),
};

const EnumEntry<unsigned> ElfSymbolBindings[] = {
    {"Local",  "LOCAL",  ELF::STB_LOCAL},
    {"Global", "GLOBAL", ELF::STB_GLOBAL},
    {"Weak",   "WEAK",   ELF::STB_WEAK},
    {"Unique", "UNIQUE", ELF::STB_GNU_UNIQUE}};

const EnumEntry<unsigned> ElfSymbolVisibilities[] = {
    {"DEFAULT",   "DEFAULT",   ELF::STV_DEFAULT},
    {"INTERNAL",  "INTERNAL",  ELF::STV_INTERNAL},
    {"HIDDEN",    "HIDDEN",    ELF::STV_HIDDEN},
    {"PROTECTED", "PROTECTED", ELF::STV_PROTECTED}};

const EnumEntry<unsigned> AMDGPUSymbolTypes[] = {
  { "AMDGPU_HSA_KERNEL",            ELF::STT_AMDGPU_HSA_KERNEL }
};

static const char *getGroupType(uint32_t Flag) {
  if (Flag & ELF::GRP_COMDAT)
    return "COMDAT";
  else
    return "(unknown)";
}

const EnumEntry<unsigned> ElfSectionFlags[] = {
  ENUM_ENT(SHF_WRITE,            "W"),
  ENUM_ENT(SHF_ALLOC,            "A"),
  ENUM_ENT(SHF_EXECINSTR,        "X"),
  ENUM_ENT(SHF_MERGE,            "M"),
  ENUM_ENT(SHF_STRINGS,          "S"),
  ENUM_ENT(SHF_INFO_LINK,        "I"),
  ENUM_ENT(SHF_LINK_ORDER,       "L"),
  ENUM_ENT(SHF_OS_NONCONFORMING, "O"),
  ENUM_ENT(SHF_GROUP,            "G"),
  ENUM_ENT(SHF_TLS,              "T"),
  ENUM_ENT(SHF_COMPRESSED,       "C"),
  ENUM_ENT(SHF_EXCLUDE,          "E"),
};

const EnumEntry<unsigned> ElfGNUSectionFlags[] = {
  ENUM_ENT(SHF_GNU_RETAIN, "R")
};

const EnumEntry<unsigned> ElfSolarisSectionFlags[] = {
  ENUM_ENT(SHF_SUNW_NODISCARD, "R")
};

const EnumEntry<unsigned> ElfXCoreSectionFlags[] = {
  ENUM_ENT(XCORE_SHF_CP_SECTION, ""),
  ENUM_ENT(XCORE_SHF_DP_SECTION, "")
};

const EnumEntry<unsigned> ElfARMSectionFlags[] = {
  ENUM_ENT(SHF_ARM_PURECODE, "y")
};

const EnumEntry<unsigned> ElfHexagonSectionFlags[] = {
  ENUM_ENT(SHF_HEX_GPREL, "")
};

const EnumEntry<unsigned> ElfMipsSectionFlags[] = {
  ENUM_ENT(SHF_MIPS_NODUPES, ""),
  ENUM_ENT(SHF_MIPS_NAMES,   ""),
  ENUM_ENT(SHF_MIPS_LOCAL,   ""),
  ENUM_ENT(SHF_MIPS_NOSTRIP, ""),
  ENUM_ENT(SHF_MIPS_GPREL,   ""),
  ENUM_ENT(SHF_MIPS_MERGE,   ""),
  ENUM_ENT(SHF_MIPS_ADDR,    ""),
  ENUM_ENT(SHF_MIPS_STRING,  "")
};

const EnumEntry<unsigned> ElfX86_64SectionFlags[] = {
  ENUM_ENT(SHF_X86_64_LARGE, "l")
};

static std::vector<EnumEntry<unsigned>>
getSectionFlagsForTarget(unsigned EOSAbi, unsigned EMachine) {
  std::vector<EnumEntry<unsigned>> Ret(std::begin(ElfSectionFlags),
                                       std::end(ElfSectionFlags));
  switch (EOSAbi) {
  case ELFOSABI_SOLARIS:
    Ret.insert(Ret.end(), std::begin(ElfSolarisSectionFlags),
               std::end(ElfSolarisSectionFlags));
    break;
  default:
    Ret.insert(Ret.end(), std::begin(ElfGNUSectionFlags),
               std::end(ElfGNUSectionFlags));
    break;
  }
  switch (EMachine) {
  case EM_ARM:
    Ret.insert(Ret.end(), std::begin(ElfARMSectionFlags),
               std::end(ElfARMSectionFlags));
    break;
  case EM_HEXAGON:
    Ret.insert(Ret.end(), std::begin(ElfHexagonSectionFlags),
               std::end(ElfHexagonSectionFlags));
    break;
  case EM_MIPS:
    Ret.insert(Ret.end(), std::begin(ElfMipsSectionFlags),
               std::end(ElfMipsSectionFlags));
    break;
  case EM_X86_64:
    Ret.insert(Ret.end(), std::begin(ElfX86_64SectionFlags),
               std::end(ElfX86_64SectionFlags));
    break;
  case EM_XCORE:
    Ret.insert(Ret.end(), std::begin(ElfXCoreSectionFlags),
               std::end(ElfXCoreSectionFlags));
    break;
  default:
    break;
  }
  return Ret;
}

static std::string getGNUFlags(unsigned EOSAbi, unsigned EMachine,
                               uint64_t Flags) {
  // Here we are trying to build the flags string in the same way as GNU does.
  // It is not that straightforward. Imagine we have sh_flags == 0x90000000.
  // SHF_EXCLUDE ("E") has a value of 0x80000000 and SHF_MASKPROC is 0xf0000000.
  // GNU readelf will not print "E" or "Ep" in this case, but will print just
  // "p". It only will print "E" when no other processor flag is set.
  std::string Str;
  bool HasUnknownFlag = false;
  bool HasOSFlag = false;
  bool HasProcFlag = false;
  std::vector<EnumEntry<unsigned>> FlagsList =
      getSectionFlagsForTarget(EOSAbi, EMachine);
  while (Flags) {
    // Take the least significant bit as a flag.
    uint64_t Flag = Flags & -Flags;
    Flags -= Flag;

    // Find the flag in the known flags list.
    auto I = llvm::find_if(FlagsList, [=](const EnumEntry<unsigned> &E) {
      // Flags with empty names are not printed in GNU style output.
      return E.Value == Flag && !E.AltName.empty();
    });
    if (I != FlagsList.end()) {
      Str += I->AltName;
      continue;
    }

    // If we did not find a matching regular flag, then we deal with an OS
    // specific flag, processor specific flag or an unknown flag.
    if (Flag & ELF::SHF_MASKOS) {
      HasOSFlag = true;
      Flags &= ~ELF::SHF_MASKOS;
    } else if (Flag & ELF::SHF_MASKPROC) {
      HasProcFlag = true;
      // Mask off all the processor-specific bits. This removes the SHF_EXCLUDE
      // bit if set so that it doesn't also get printed.
      Flags &= ~ELF::SHF_MASKPROC;
    } else {
      HasUnknownFlag = true;
    }
  }

  // "o", "p" and "x" are printed last.
  if (HasOSFlag)
    Str += "o";
  if (HasProcFlag)
    Str += "p";
  if (HasUnknownFlag)
    Str += "x";
  return Str;
}

static StringRef segmentTypeToString(unsigned Arch, unsigned Type) {
  // Check potentially overlapped processor-specific program header type.
  switch (Arch) {
  case ELF::EM_ARM:
    switch (Type) { LLVM_READOBJ_ENUM_CASE(ELF, PT_ARM_EXIDX); }
    break;
  case ELF::EM_MIPS:
  case ELF::EM_MIPS_RS3_LE:
    switch (Type) {
      LLVM_READOBJ_ENUM_CASE(ELF, PT_MIPS_REGINFO);
      LLVM_READOBJ_ENUM_CASE(ELF, PT_MIPS_RTPROC);
      LLVM_READOBJ_ENUM_CASE(ELF, PT_MIPS_OPTIONS);
      LLVM_READOBJ_ENUM_CASE(ELF, PT_MIPS_ABIFLAGS);
    }
    break;
  case ELF::EM_RISCV:
    switch (Type) { LLVM_READOBJ_ENUM_CASE(ELF, PT_RISCV_ATTRIBUTES); }
  }

  switch (Type) {
    LLVM_READOBJ_ENUM_CASE(ELF, PT_NULL);
    LLVM_READOBJ_ENUM_CASE(ELF, PT_LOAD);
    LLVM_READOBJ_ENUM_CASE(ELF, PT_DYNAMIC);
    LLVM_READOBJ_ENUM_CASE(ELF, PT_INTERP);
    LLVM_READOBJ_ENUM_CASE(ELF, PT_NOTE);
    LLVM_READOBJ_ENUM_CASE(ELF, PT_SHLIB);
    LLVM_READOBJ_ENUM_CASE(ELF, PT_PHDR);
    LLVM_READOBJ_ENUM_CASE(ELF, PT_TLS);

    LLVM_READOBJ_ENUM_CASE(ELF, PT_GNU_EH_FRAME);
    LLVM_READOBJ_ENUM_CASE(ELF, PT_SUNW_UNWIND);

    LLVM_READOBJ_ENUM_CASE(ELF, PT_GNU_STACK);
    LLVM_READOBJ_ENUM_CASE(ELF, PT_GNU_RELRO);
    LLVM_READOBJ_ENUM_CASE(ELF, PT_GNU_PROPERTY);

    LLVM_READOBJ_ENUM_CASE(ELF, PT_OPENBSD_RANDOMIZE);
    LLVM_READOBJ_ENUM_CASE(ELF, PT_OPENBSD_WXNEEDED);
    LLVM_READOBJ_ENUM_CASE(ELF, PT_OPENBSD_BOOTDATA);
  default:
    return "";
  }
}

static std::string getGNUPtType(unsigned Arch, unsigned Type) {
  StringRef Seg = segmentTypeToString(Arch, Type);
  if (Seg.empty())
    return std::string("<unknown>: ") + to_string(format_hex(Type, 1));

  // E.g. "PT_ARM_EXIDX" -> "EXIDX".
  if (Seg.consume_front("PT_ARM_"))
    return Seg.str();

  // E.g. "PT_MIPS_REGINFO" -> "REGINFO".
  if (Seg.consume_front("PT_MIPS_"))
    return Seg.str();

  // E.g. "PT_RISCV_ATTRIBUTES"
  if (Seg.consume_front("PT_RISCV_"))
    return Seg.str();

  // E.g. "PT_LOAD" -> "LOAD".
  assert(Seg.startswith("PT_"));
  return Seg.drop_front(3).str();
}

const EnumEntry<unsigned> ElfSegmentFlags[] = {
  LLVM_READOBJ_ENUM_ENT(ELF, PF_X),
  LLVM_READOBJ_ENUM_ENT(ELF, PF_W),
  LLVM_READOBJ_ENUM_ENT(ELF, PF_R)
};

const EnumEntry<unsigned> ElfHeaderMipsFlags[] = {
  ENUM_ENT(EF_MIPS_NOREORDER, "noreorder"),
  ENUM_ENT(EF_MIPS_PIC, "pic"),
  ENUM_ENT(EF_MIPS_CPIC, "cpic"),
  ENUM_ENT(EF_MIPS_ABI2, "abi2"),
  ENUM_ENT(EF_MIPS_32BITMODE, "32bitmode"),
  ENUM_ENT(EF_MIPS_FP64, "fp64"),
  ENUM_ENT(EF_MIPS_NAN2008, "nan2008"),
  ENUM_ENT(EF_MIPS_ABI_O32, "o32"),
  ENUM_ENT(EF_MIPS_ABI_O64, "o64"),
  ENUM_ENT(EF_MIPS_ABI_EABI32, "eabi32"),
  ENUM_ENT(EF_MIPS_ABI_EABI64, "eabi64"),
  ENUM_ENT(EF_MIPS_MACH_3900, "3900"),
  ENUM_ENT(EF_MIPS_MACH_4010, "4010"),
  ENUM_ENT(EF_MIPS_MACH_4100, "4100"),
  ENUM_ENT(EF_MIPS_MACH_4650, "4650"),
  ENUM_ENT(EF_MIPS_MACH_4120, "4120"),
  ENUM_ENT(EF_MIPS_MACH_4111, "4111"),
  ENUM_ENT(EF_MIPS_MACH_SB1, "sb1"),
  ENUM_ENT(EF_MIPS_MACH_OCTEON, "octeon"),
  ENUM_ENT(EF_MIPS_MACH_XLR, "xlr"),
  ENUM_ENT(EF_MIPS_MACH_OCTEON2, "octeon2"),
  ENUM_ENT(EF_MIPS_MACH_OCTEON3, "octeon3"),
  ENUM_ENT(EF_MIPS_MACH_5400, "5400"),
  ENUM_ENT(EF_MIPS_MACH_5900, "5900"),
  ENUM_ENT(EF_MIPS_MACH_5500, "5500"),
  ENUM_ENT(EF_MIPS_MACH_9000, "9000"),
  ENUM_ENT(EF_MIPS_MACH_LS2E, "loongson-2e"),
  ENUM_ENT(EF_MIPS_MACH_LS2F, "loongson-2f"),
  ENUM_ENT(EF_MIPS_MACH_LS3A, "loongson-3a"),
  ENUM_ENT(EF_MIPS_MICROMIPS, "micromips"),
  ENUM_ENT(EF_MIPS_ARCH_ASE_M16, "mips16"),
  ENUM_ENT(EF_MIPS_ARCH_ASE_MDMX, "mdmx"),
  ENUM_ENT(EF_MIPS_ARCH_1, "mips1"),
  ENUM_ENT(EF_MIPS_ARCH_2, "mips2"),
  ENUM_ENT(EF_MIPS_ARCH_3, "mips3"),
  ENUM_ENT(EF_MIPS_ARCH_4, "mips4"),
  ENUM_ENT(EF_MIPS_ARCH_5, "mips5"),
  ENUM_ENT(EF_MIPS_ARCH_32, "mips32"),
  ENUM_ENT(EF_MIPS_ARCH_64, "mips64"),
  ENUM_ENT(EF_MIPS_ARCH_32R2, "mips32r2"),
  ENUM_ENT(EF_MIPS_ARCH_64R2, "mips64r2"),
  ENUM_ENT(EF_MIPS_ARCH_32R6, "mips32r6"),
  ENUM_ENT(EF_MIPS_ARCH_64R6, "mips64r6")
};

const EnumEntry<unsigned> ElfHeaderAMDGPUFlagsABIVersion3[] = {
  LLVM_READOBJ_ENUM_ENT(ELF, EF_AMDGPU_MACH_NONE),
  LLVM_READOBJ_ENUM_ENT(ELF, EF_AMDGPU_MACH_R600_R600),
  LLVM_READOBJ_ENUM_ENT(ELF, EF_AMDGPU_MACH_R600_R630),
  LLVM_READOBJ_ENUM_ENT(ELF, EF_AMDGPU_MACH_R600_RS880),
  LLVM_READOBJ_ENUM_ENT(ELF, EF_AMDGPU_MACH_R600_RV670),
  LLVM_READOBJ_ENUM_ENT(ELF, EF_AMDGPU_MACH_R600_RV710),
  LLVM_READOBJ_ENUM_ENT(ELF, EF_AMDGPU_MACH_R600_RV730),
  LLVM_READOBJ_ENUM_ENT(ELF, EF_AMDGPU_MACH_R600_RV770),
  LLVM_READOBJ_ENUM_ENT(ELF, EF_AMDGPU_MACH_R600_CEDAR),
  LLVM_READOBJ_ENUM_ENT(ELF, EF_AMDGPU_MACH_R600_CYPRESS),
  LLVM_READOBJ_ENUM_ENT(ELF, EF_AMDGPU_MACH_R600_JUNIPER),
  LLVM_READOBJ_ENUM_ENT(ELF, EF_AMDGPU_MACH_R600_REDWOOD),
  LLVM_READOBJ_ENUM_ENT(ELF, EF_AMDGPU_MACH_R600_SUMO),
  LLVM_READOBJ_ENUM_ENT(ELF, EF_AMDGPU_MACH_R600_BARTS),
  LLVM_READOBJ_ENUM_ENT(ELF, EF_AMDGPU_MACH_R600_CAICOS),
  LLVM_READOBJ_ENUM_ENT(ELF, EF_AMDGPU_MACH_R600_CAYMAN),
  LLVM_READOBJ_ENUM_ENT(ELF, EF_AMDGPU_MACH_R600_TURKS),
  LLVM_READOBJ_ENUM_ENT(ELF, EF_AMDGPU_MACH_AMDGCN_GFX600),
  LLVM_READOBJ_ENUM_ENT(ELF, EF_AMDGPU_MACH_AMDGCN_GFX601),
  LLVM_READOBJ_ENUM_ENT(ELF, EF_AMDGPU_MACH_AMDGCN_GFX602),
  LLVM_READOBJ_ENUM_ENT(ELF, EF_AMDGPU_MACH_AMDGCN_GFX700),
  LLVM_READOBJ_ENUM_ENT(ELF, EF_AMDGPU_MACH_AMDGCN_GFX701),
  LLVM_READOBJ_ENUM_ENT(ELF, EF_AMDGPU_MACH_AMDGCN_GFX702),
  LLVM_READOBJ_ENUM_ENT(ELF, EF_AMDGPU_MACH_AMDGCN_GFX703),
  LLVM_READOBJ_ENUM_ENT(ELF, EF_AMDGPU_MACH_AMDGCN_GFX704),
  LLVM_READOBJ_ENUM_ENT(ELF, EF_AMDGPU_MACH_AMDGCN_GFX705),
  LLVM_READOBJ_ENUM_ENT(ELF, EF_AMDGPU_MACH_AMDGCN_GFX801),
  LLVM_READOBJ_ENUM_ENT(ELF, EF_AMDGPU_MACH_AMDGCN_GFX802),
  LLVM_READOBJ_ENUM_ENT(ELF, EF_AMDGPU_MACH_AMDGCN_GFX803),
  LLVM_READOBJ_ENUM_ENT(ELF, EF_AMDGPU_MACH_AMDGCN_GFX805),
  LLVM_READOBJ_ENUM_ENT(ELF, EF_AMDGPU_MACH_AMDGCN_GFX810),
  LLVM_READOBJ_ENUM_ENT(ELF, EF_AMDGPU_MACH_AMDGCN_GFX900),
  LLVM_READOBJ_ENUM_ENT(ELF, EF_AMDGPU_MACH_AMDGCN_GFX902),
  LLVM_READOBJ_ENUM_ENT(ELF, EF_AMDGPU_MACH_AMDGCN_GFX904),
  LLVM_READOBJ_ENUM_ENT(ELF, EF_AMDGPU_MACH_AMDGCN_GFX906),
  LLVM_READOBJ_ENUM_ENT(ELF, EF_AMDGPU_MACH_AMDGCN_GFX908),
  LLVM_READOBJ_ENUM_ENT(ELF, EF_AMDGPU_MACH_AMDGCN_GFX909),
  LLVM_READOBJ_ENUM_ENT(ELF, EF_AMDGPU_MACH_AMDGCN_GFX90A),
  LLVM_READOBJ_ENUM_ENT(ELF, EF_AMDGPU_MACH_AMDGCN_GFX90C),
  LLVM_READOBJ_ENUM_ENT(ELF, EF_AMDGPU_MACH_AMDGCN_GFX940),
  LLVM_READOBJ_ENUM_ENT(ELF, EF_AMDGPU_MACH_AMDGCN_GFX1010),
  LLVM_READOBJ_ENUM_ENT(ELF, EF_AMDGPU_MACH_AMDGCN_GFX1011),
  LLVM_READOBJ_ENUM_ENT(ELF, EF_AMDGPU_MACH_AMDGCN_GFX1012),
  LLVM_READOBJ_ENUM_ENT(ELF, EF_AMDGPU_MACH_AMDGCN_GFX1013),
  LLVM_READOBJ_ENUM_ENT(ELF, EF_AMDGPU_MACH_AMDGCN_GFX1030),
  LLVM_READOBJ_ENUM_ENT(ELF, EF_AMDGPU_MACH_AMDGCN_GFX1031),
  LLVM_READOBJ_ENUM_ENT(ELF, EF_AMDGPU_MACH_AMDGCN_GFX1032),
  LLVM_READOBJ_ENUM_ENT(ELF, EF_AMDGPU_MACH_AMDGCN_GFX1033),
  LLVM_READOBJ_ENUM_ENT(ELF, EF_AMDGPU_MACH_AMDGCN_GFX1034),
  LLVM_READOBJ_ENUM_ENT(ELF, EF_AMDGPU_MACH_AMDGCN_GFX1035),
  LLVM_READOBJ_ENUM_ENT(ELF, EF_AMDGPU_MACH_AMDGCN_GFX1036),
  LLVM_READOBJ_ENUM_ENT(ELF, EF_AMDGPU_MACH_AMDGCN_GFX1100),
  LLVM_READOBJ_ENUM_ENT(ELF, EF_AMDGPU_MACH_AMDGCN_GFX1101),
  LLVM_READOBJ_ENUM_ENT(ELF, EF_AMDGPU_MACH_AMDGCN_GFX1102),
  LLVM_READOBJ_ENUM_ENT(ELF, EF_AMDGPU_MACH_AMDGCN_GFX1103),
  LLVM_READOBJ_ENUM_ENT(ELF, EF_AMDGPU_FEATURE_XNACK_V3),
  LLVM_READOBJ_ENUM_ENT(ELF, EF_AMDGPU_FEATURE_SRAMECC_V3)
};

const EnumEntry<unsigned> ElfHeaderAMDGPUFlagsABIVersion4[] = {
  LLVM_READOBJ_ENUM_ENT(ELF, EF_AMDGPU_MACH_NONE),
  LLVM_READOBJ_ENUM_ENT(ELF, EF_AMDGPU_MACH_R600_R600),
  LLVM_READOBJ_ENUM_ENT(ELF, EF_AMDGPU_MACH_R600_R630),
  LLVM_READOBJ_ENUM_ENT(ELF, EF_AMDGPU_MACH_R600_RS880),
  LLVM_READOBJ_ENUM_ENT(ELF, EF_AMDGPU_MACH_R600_RV670),
  LLVM_READOBJ_ENUM_ENT(ELF, EF_AMDGPU_MACH_R600_RV710),
  LLVM_READOBJ_ENUM_ENT(ELF, EF_AMDGPU_MACH_R600_RV730),
  LLVM_READOBJ_ENUM_ENT(ELF, EF_AMDGPU_MACH_R600_RV770),
  LLVM_READOBJ_ENUM_ENT(ELF, EF_AMDGPU_MACH_R600_CEDAR),
  LLVM_READOBJ_ENUM_ENT(ELF, EF_AMDGPU_MACH_R600_CYPRESS),
  LLVM_READOBJ_ENUM_ENT(ELF, EF_AMDGPU_MACH_R600_JUNIPER),
  LLVM_READOBJ_ENUM_ENT(ELF, EF_AMDGPU_MACH_R600_REDWOOD),
  LLVM_READOBJ_ENUM_ENT(ELF, EF_AMDGPU_MACH_R600_SUMO),
  LLVM_READOBJ_ENUM_ENT(ELF, EF_AMDGPU_MACH_R600_BARTS),
  LLVM_READOBJ_ENUM_ENT(ELF, EF_AMDGPU_MACH_R600_CAICOS),
  LLVM_READOBJ_ENUM_ENT(ELF, EF_AMDGPU_MACH_R600_CAYMAN),
  LLVM_READOBJ_ENUM_ENT(ELF, EF_AMDGPU_MACH_R600_TURKS),
  LLVM_READOBJ_ENUM_ENT(ELF, EF_AMDGPU_MACH_AMDGCN_GFX600),
  LLVM_READOBJ_ENUM_ENT(ELF, EF_AMDGPU_MACH_AMDGCN_GFX601),
  LLVM_READOBJ_ENUM_ENT(ELF, EF_AMDGPU_MACH_AMDGCN_GFX602),
  LLVM_READOBJ_ENUM_ENT(ELF, EF_AMDGPU_MACH_AMDGCN_GFX700),
  LLVM_READOBJ_ENUM_ENT(ELF, EF_AMDGPU_MACH_AMDGCN_GFX701),
  LLVM_READOBJ_ENUM_ENT(ELF, EF_AMDGPU_MACH_AMDGCN_GFX702),
  LLVM_READOBJ_ENUM_ENT(ELF, EF_AMDGPU_MACH_AMDGCN_GFX703),
  LLVM_READOBJ_ENUM_ENT(ELF, EF_AMDGPU_MACH_AMDGCN_GFX704),
  LLVM_READOBJ_ENUM_ENT(ELF, EF_AMDGPU_MACH_AMDGCN_GFX705),
  LLVM_READOBJ_ENUM_ENT(ELF, EF_AMDGPU_MACH_AMDGCN_GFX801),
  LLVM_READOBJ_ENUM_ENT(ELF, EF_AMDGPU_MACH_AMDGCN_GFX802),
  LLVM_READOBJ_ENUM_ENT(ELF, EF_AMDGPU_MACH_AMDGCN_GFX803),
  LLVM_READOBJ_ENUM_ENT(ELF, EF_AMDGPU_MACH_AMDGCN_GFX805),
  LLVM_READOBJ_ENUM_ENT(ELF, EF_AMDGPU_MACH_AMDGCN_GFX810),
  LLVM_READOBJ_ENUM_ENT(ELF, EF_AMDGPU_MACH_AMDGCN_GFX900),
  LLVM_READOBJ_ENUM_ENT(ELF, EF_AMDGPU_MACH_AMDGCN_GFX902),
  LLVM_READOBJ_ENUM_ENT(ELF, EF_AMDGPU_MACH_AMDGCN_GFX904),
  LLVM_READOBJ_ENUM_ENT(ELF, EF_AMDGPU_MACH_AMDGCN_GFX906),
  LLVM_READOBJ_ENUM_ENT(ELF, EF_AMDGPU_MACH_AMDGCN_GFX908),
  LLVM_READOBJ_ENUM_ENT(ELF, EF_AMDGPU_MACH_AMDGCN_GFX909),
  LLVM_READOBJ_ENUM_ENT(ELF, EF_AMDGPU_MACH_AMDGCN_GFX90A),
  LLVM_READOBJ_ENUM_ENT(ELF, EF_AMDGPU_MACH_AMDGCN_GFX90C),
  LLVM_READOBJ_ENUM_ENT(ELF, EF_AMDGPU_MACH_AMDGCN_GFX940),
  LLVM_READOBJ_ENUM_ENT(ELF, EF_AMDGPU_MACH_AMDGCN_GFX1010),
  LLVM_READOBJ_ENUM_ENT(ELF, EF_AMDGPU_MACH_AMDGCN_GFX1011),
  LLVM_READOBJ_ENUM_ENT(ELF, EF_AMDGPU_MACH_AMDGCN_GFX1012),
  LLVM_READOBJ_ENUM_ENT(ELF, EF_AMDGPU_MACH_AMDGCN_GFX1013),
  LLVM_READOBJ_ENUM_ENT(ELF, EF_AMDGPU_MACH_AMDGCN_GFX1030),
  LLVM_READOBJ_ENUM_ENT(ELF, EF_AMDGPU_MACH_AMDGCN_GFX1031),
  LLVM_READOBJ_ENUM_ENT(ELF, EF_AMDGPU_MACH_AMDGCN_GFX1032),
  LLVM_READOBJ_ENUM_ENT(ELF, EF_AMDGPU_MACH_AMDGCN_GFX1033),
  LLVM_READOBJ_ENUM_ENT(ELF, EF_AMDGPU_MACH_AMDGCN_GFX1034),
  LLVM_READOBJ_ENUM_ENT(ELF, EF_AMDGPU_MACH_AMDGCN_GFX1035),
  LLVM_READOBJ_ENUM_ENT(ELF, EF_AMDGPU_MACH_AMDGCN_GFX1036),
  LLVM_READOBJ_ENUM_ENT(ELF, EF_AMDGPU_MACH_AMDGCN_GFX1100),
  LLVM_READOBJ_ENUM_ENT(ELF, EF_AMDGPU_MACH_AMDGCN_GFX1101),
  LLVM_READOBJ_ENUM_ENT(ELF, EF_AMDGPU_MACH_AMDGCN_GFX1102),
  LLVM_READOBJ_ENUM_ENT(ELF, EF_AMDGPU_MACH_AMDGCN_GFX1103),
  LLVM_READOBJ_ENUM_ENT(ELF, EF_AMDGPU_FEATURE_XNACK_ANY_V4),
  LLVM_READOBJ_ENUM_ENT(ELF, EF_AMDGPU_FEATURE_XNACK_OFF_V4),
  LLVM_READOBJ_ENUM_ENT(ELF, EF_AMDGPU_FEATURE_XNACK_ON_V4),
  LLVM_READOBJ_ENUM_ENT(ELF, EF_AMDGPU_FEATURE_SRAMECC_ANY_V4),
  LLVM_READOBJ_ENUM_ENT(ELF, EF_AMDGPU_FEATURE_SRAMECC_OFF_V4),
  LLVM_READOBJ_ENUM_ENT(ELF, EF_AMDGPU_FEATURE_SRAMECC_ON_V4)
};

const EnumEntry<unsigned> ElfHeaderRISCVFlags[] = {
  ENUM_ENT(EF_RISCV_RVC, "RVC"),
  ENUM_ENT(EF_RISCV_FLOAT_ABI_SINGLE, "single-float ABI"),
  ENUM_ENT(EF_RISCV_FLOAT_ABI_DOUBLE, "double-float ABI"),
  ENUM_ENT(EF_RISCV_FLOAT_ABI_QUAD, "quad-float ABI"),
  ENUM_ENT(EF_RISCV_RVE, "RVE"),
  ENUM_ENT(EF_RISCV_TSO, "TSO"),
};

const EnumEntry<unsigned> ElfHeaderAVRFlags[] = {
  LLVM_READOBJ_ENUM_ENT(ELF, EF_AVR_ARCH_AVR1),
  LLVM_READOBJ_ENUM_ENT(ELF, EF_AVR_ARCH_AVR2),
  LLVM_READOBJ_ENUM_ENT(ELF, EF_AVR_ARCH_AVR25),
  LLVM_READOBJ_ENUM_ENT(ELF, EF_AVR_ARCH_AVR3),
  LLVM_READOBJ_ENUM_ENT(ELF, EF_AVR_ARCH_AVR31),
  LLVM_READOBJ_ENUM_ENT(ELF, EF_AVR_ARCH_AVR35),
  LLVM_READOBJ_ENUM_ENT(ELF, EF_AVR_ARCH_AVR4),
  LLVM_READOBJ_ENUM_ENT(ELF, EF_AVR_ARCH_AVR5),
  LLVM_READOBJ_ENUM_ENT(ELF, EF_AVR_ARCH_AVR51),
  LLVM_READOBJ_ENUM_ENT(ELF, EF_AVR_ARCH_AVR6),
  LLVM_READOBJ_ENUM_ENT(ELF, EF_AVR_ARCH_AVRTINY),
  LLVM_READOBJ_ENUM_ENT(ELF, EF_AVR_ARCH_XMEGA1),
  LLVM_READOBJ_ENUM_ENT(ELF, EF_AVR_ARCH_XMEGA2),
  LLVM_READOBJ_ENUM_ENT(ELF, EF_AVR_ARCH_XMEGA3),
  LLVM_READOBJ_ENUM_ENT(ELF, EF_AVR_ARCH_XMEGA4),
  LLVM_READOBJ_ENUM_ENT(ELF, EF_AVR_ARCH_XMEGA5),
  LLVM_READOBJ_ENUM_ENT(ELF, EF_AVR_ARCH_XMEGA6),
  LLVM_READOBJ_ENUM_ENT(ELF, EF_AVR_ARCH_XMEGA7),
  ENUM_ENT(EF_AVR_LINKRELAX_PREPARED, "relaxable"),
};

const EnumEntry<unsigned> ElfHeaderLoongArchFlags[] = {
  ENUM_ENT(EF_LOONGARCH_BASE_ABI_ILP32S, "ILP32, SOFT-FLOAT"),
  ENUM_ENT(EF_LOONGARCH_BASE_ABI_ILP32F, "ILP32, SINGLE-FLOAT"),
  ENUM_ENT(EF_LOONGARCH_BASE_ABI_ILP32D, "ILP32, DOUBLE-FLOAT"),
  ENUM_ENT(EF_LOONGARCH_BASE_ABI_LP64S, "LP64, SOFT-FLOAT"),
  ENUM_ENT(EF_LOONGARCH_BASE_ABI_LP64F, "LP64, SINGLE-FLOAT"),
  ENUM_ENT(EF_LOONGARCH_BASE_ABI_LP64D, "LP64, DOUBLE-FLOAT"),
};


const EnumEntry<unsigned> ElfSymOtherFlags[] = {
  LLVM_READOBJ_ENUM_ENT(ELF, STV_INTERNAL),
  LLVM_READOBJ_ENUM_ENT(ELF, STV_HIDDEN),
  LLVM_READOBJ_ENUM_ENT(ELF, STV_PROTECTED)
};

const EnumEntry<unsigned> ElfMipsSymOtherFlags[] = {
  LLVM_READOBJ_ENUM_ENT(ELF, STO_MIPS_OPTIONAL),
  LLVM_READOBJ_ENUM_ENT(ELF, STO_MIPS_PLT),
  LLVM_READOBJ_ENUM_ENT(ELF, STO_MIPS_PIC),
  LLVM_READOBJ_ENUM_ENT(ELF, STO_MIPS_MICROMIPS)
};

const EnumEntry<unsigned> ElfAArch64SymOtherFlags[] = {
  LLVM_READOBJ_ENUM_ENT(ELF, STO_AARCH64_VARIANT_PCS)
};

const EnumEntry<unsigned> ElfMips16SymOtherFlags[] = {
  LLVM_READOBJ_ENUM_ENT(ELF, STO_MIPS_OPTIONAL),
  LLVM_READOBJ_ENUM_ENT(ELF, STO_MIPS_PLT),
  LLVM_READOBJ_ENUM_ENT(ELF, STO_MIPS_MIPS16)
};

const EnumEntry<unsigned> ElfRISCVSymOtherFlags[] = {
    LLVM_READOBJ_ENUM_ENT(ELF, STO_RISCV_VARIANT_CC)};

static const char *getElfMipsOptionsOdkType(unsigned Odk) {
  switch (Odk) {
  LLVM_READOBJ_ENUM_CASE(ELF, ODK_NULL);
  LLVM_READOBJ_ENUM_CASE(ELF, ODK_REGINFO);
  LLVM_READOBJ_ENUM_CASE(ELF, ODK_EXCEPTIONS);
  LLVM_READOBJ_ENUM_CASE(ELF, ODK_PAD);
  LLVM_READOBJ_ENUM_CASE(ELF, ODK_HWPATCH);
  LLVM_READOBJ_ENUM_CASE(ELF, ODK_FILL);
  LLVM_READOBJ_ENUM_CASE(ELF, ODK_TAGS);
  LLVM_READOBJ_ENUM_CASE(ELF, ODK_HWAND);
  LLVM_READOBJ_ENUM_CASE(ELF, ODK_HWOR);
  LLVM_READOBJ_ENUM_CASE(ELF, ODK_GP_GROUP);
  LLVM_READOBJ_ENUM_CASE(ELF, ODK_IDENT);
  LLVM_READOBJ_ENUM_CASE(ELF, ODK_PAGESIZE);
  default:
    return "Unknown";
  }
}

template <typename ELFT>
std::pair<const typename ELFT::Phdr *, const typename ELFT::Shdr *>
ELFDumper<ELFT>::findDynamic() {
  // Try to locate the PT_DYNAMIC header.
  const Elf_Phdr *DynamicPhdr = nullptr;
  if (Expected<ArrayRef<Elf_Phdr>> PhdrsOrErr = Obj.program_headers()) {
    for (const Elf_Phdr &Phdr : *PhdrsOrErr) {
      if (Phdr.p_type != ELF::PT_DYNAMIC)
        continue;
      DynamicPhdr = &Phdr;
      break;
    }
  } else {
    reportUniqueWarning(
        "unable to read program headers to locate the PT_DYNAMIC segment: " +
        toString(PhdrsOrErr.takeError()));
  }

  // Try to locate the .dynamic section in the sections header table.
  const Elf_Shdr *DynamicSec = nullptr;
  for (const Elf_Shdr &Sec : cantFail(Obj.sections())) {
    if (Sec.sh_type != ELF::SHT_DYNAMIC)
      continue;
    DynamicSec = &Sec;
    break;
  }

  if (DynamicPhdr && ((DynamicPhdr->p_offset + DynamicPhdr->p_filesz >
                       ObjF.getMemoryBufferRef().getBufferSize()) ||
                      (DynamicPhdr->p_offset + DynamicPhdr->p_filesz <
                       DynamicPhdr->p_offset))) {
    reportUniqueWarning(
        "PT_DYNAMIC segment offset (0x" +
        Twine::utohexstr(DynamicPhdr->p_offset) + ") + file size (0x" +
        Twine::utohexstr(DynamicPhdr->p_filesz) +
        ") exceeds the size of the file (0x" +
        Twine::utohexstr(ObjF.getMemoryBufferRef().getBufferSize()) + ")");
    // Don't use the broken dynamic header.
    DynamicPhdr = nullptr;
  }

  if (DynamicPhdr && DynamicSec) {
    if (DynamicSec->sh_addr + DynamicSec->sh_size >
            DynamicPhdr->p_vaddr + DynamicPhdr->p_memsz ||
        DynamicSec->sh_addr < DynamicPhdr->p_vaddr)
      reportUniqueWarning(describe(*DynamicSec) +
                          " is not contained within the "
                          "PT_DYNAMIC segment");

    if (DynamicSec->sh_addr != DynamicPhdr->p_vaddr)
      reportUniqueWarning(describe(*DynamicSec) + " is not at the start of "
                                                  "PT_DYNAMIC segment");
  }

  return std::make_pair(DynamicPhdr, DynamicSec);
}

template <typename ELFT>
void ELFDumper<ELFT>::loadDynamicTable() {
  const Elf_Phdr *DynamicPhdr;
  const Elf_Shdr *DynamicSec;
  std::tie(DynamicPhdr, DynamicSec) = findDynamic();
  if (!DynamicPhdr && !DynamicSec)
    return;

  DynRegionInfo FromPhdr(ObjF, *this);
  bool IsPhdrTableValid = false;
  if (DynamicPhdr) {
    // Use cantFail(), because p_offset/p_filesz fields of a PT_DYNAMIC are
    // validated in findDynamic() and so createDRI() is not expected to fail.
    FromPhdr = cantFail(createDRI(DynamicPhdr->p_offset, DynamicPhdr->p_filesz,
                                  sizeof(Elf_Dyn)));
    FromPhdr.SizePrintName = "PT_DYNAMIC size";
    FromPhdr.EntSizePrintName = "";
    IsPhdrTableValid = !FromPhdr.template getAsArrayRef<Elf_Dyn>().empty();
  }

  // Locate the dynamic table described in a section header.
  // Ignore sh_entsize and use the expected value for entry size explicitly.
  // This allows us to dump dynamic sections with a broken sh_entsize
  // field.
  DynRegionInfo FromSec(ObjF, *this);
  bool IsSecTableValid = false;
  if (DynamicSec) {
    Expected<DynRegionInfo> RegOrErr =
        createDRI(DynamicSec->sh_offset, DynamicSec->sh_size, sizeof(Elf_Dyn));
    if (RegOrErr) {
      FromSec = *RegOrErr;
      FromSec.Context = describe(*DynamicSec);
      FromSec.EntSizePrintName = "";
      IsSecTableValid = !FromSec.template getAsArrayRef<Elf_Dyn>().empty();
    } else {
      reportUniqueWarning("unable to read the dynamic table from " +
                          describe(*DynamicSec) + ": " +
                          toString(RegOrErr.takeError()));
    }
  }

  // When we only have information from one of the SHT_DYNAMIC section header or
  // PT_DYNAMIC program header, just use that.
  if (!DynamicPhdr || !DynamicSec) {
    if ((DynamicPhdr && IsPhdrTableValid) || (DynamicSec && IsSecTableValid)) {
      DynamicTable = DynamicPhdr ? FromPhdr : FromSec;
      parseDynamicTable();
    } else {
      reportUniqueWarning("no valid dynamic table was found");
    }
    return;
  }

  // At this point we have tables found from the section header and from the
  // dynamic segment. Usually they match, but we have to do sanity checks to
  // verify that.

  if (FromPhdr.Addr != FromSec.Addr)
    reportUniqueWarning("SHT_DYNAMIC section header and PT_DYNAMIC "
                        "program header disagree about "
                        "the location of the dynamic table");

  if (!IsPhdrTableValid && !IsSecTableValid) {
    reportUniqueWarning("no valid dynamic table was found");
    return;
  }

  // Information in the PT_DYNAMIC program header has priority over the
  // information in a section header.
  if (IsPhdrTableValid) {
    if (!IsSecTableValid)
      reportUniqueWarning(
          "SHT_DYNAMIC dynamic table is invalid: PT_DYNAMIC will be used");
    DynamicTable = FromPhdr;
  } else {
    reportUniqueWarning(
        "PT_DYNAMIC dynamic table is invalid: SHT_DYNAMIC will be used");
    DynamicTable = FromSec;
  }

  parseDynamicTable();
}

template <typename ELFT>
ELFDumper<ELFT>::ELFDumper(const object::ELFObjectFile<ELFT> &O,
                           ScopedPrinter &Writer)
    : ObjDumper(Writer, O.getFileName()), ObjF(O), Obj(O.getELFFile()),
      FileName(O.getFileName()), DynRelRegion(O, *this),
      DynRelaRegion(O, *this), DynRelrRegion(O, *this),
      DynPLTRelRegion(O, *this), DynSymTabShndxRegion(O, *this),
      DynamicTable(O, *this) {
  if (!O.IsContentValid())
    return;

  typename ELFT::ShdrRange Sections = cantFail(Obj.sections());
  for (const Elf_Shdr &Sec : Sections) {
    switch (Sec.sh_type) {
    case ELF::SHT_SYMTAB:
      if (!DotSymtabSec)
        DotSymtabSec = &Sec;
      break;
    case ELF::SHT_DYNSYM:
      if (!DotDynsymSec)
        DotDynsymSec = &Sec;

      if (!DynSymRegion) {
        Expected<DynRegionInfo> RegOrErr =
            createDRI(Sec.sh_offset, Sec.sh_size, Sec.sh_entsize);
        if (RegOrErr) {
          DynSymRegion = *RegOrErr;
          DynSymRegion->Context = describe(Sec);

          if (Expected<StringRef> E = Obj.getStringTableForSymtab(Sec))
            DynamicStringTable = *E;
          else
            reportUniqueWarning("unable to get the string table for the " +
                                describe(Sec) + ": " + toString(E.takeError()));
        } else {
          reportUniqueWarning("unable to read dynamic symbols from " +
                              describe(Sec) + ": " +
                              toString(RegOrErr.takeError()));
        }
      }
      break;
    case ELF::SHT_SYMTAB_SHNDX: {
      uint32_t SymtabNdx = Sec.sh_link;
      if (SymtabNdx >= Sections.size()) {
        reportUniqueWarning(
            "unable to get the associated symbol table for " + describe(Sec) +
            ": sh_link (" + Twine(SymtabNdx) +
            ") is greater than or equal to the total number of sections (" +
            Twine(Sections.size()) + ")");
        continue;
      }

      if (Expected<ArrayRef<Elf_Word>> ShndxTableOrErr =
              Obj.getSHNDXTable(Sec)) {
        if (!ShndxTables.insert({&Sections[SymtabNdx], *ShndxTableOrErr})
                 .second)
          reportUniqueWarning(
              "multiple SHT_SYMTAB_SHNDX sections are linked to " +
              describe(Sec));
      } else {
        reportUniqueWarning(ShndxTableOrErr.takeError());
      }
      break;
    }
    case ELF::SHT_GNU_versym:
      if (!SymbolVersionSection)
        SymbolVersionSection = &Sec;
      break;
    case ELF::SHT_GNU_verdef:
      if (!SymbolVersionDefSection)
        SymbolVersionDefSection = &Sec;
      break;
    case ELF::SHT_GNU_verneed:
      if (!SymbolVersionNeedSection)
        SymbolVersionNeedSection = &Sec;
      break;
    case ELF::SHT_LLVM_ADDRSIG:
      if (!DotAddrsigSec)
        DotAddrsigSec = &Sec;
      break;
    }
  }

  loadDynamicTable();
}

template <typename ELFT> void ELFDumper<ELFT>::parseDynamicTable() {
  auto toMappedAddr = [&](uint64_t Tag, uint64_t VAddr) -> const uint8_t * {
    auto MappedAddrOrError = Obj.toMappedAddr(VAddr, [&](const Twine &Msg) {
      this->reportUniqueWarning(Msg);
      return Error::success();
    });
    if (!MappedAddrOrError) {
      this->reportUniqueWarning("unable to parse DT_" +
                                Obj.getDynamicTagAsString(Tag) + ": " +
                                llvm::toString(MappedAddrOrError.takeError()));
      return nullptr;
    }
    return MappedAddrOrError.get();
  };

  const char *StringTableBegin = nullptr;
  uint64_t StringTableSize = 0;
  Optional<DynRegionInfo> DynSymFromTable;
  for (const Elf_Dyn &Dyn : dynamic_table()) {
    switch (Dyn.d_tag) {
    case ELF::DT_HASH:
      HashTable = reinterpret_cast<const Elf_Hash *>(
          toMappedAddr(Dyn.getTag(), Dyn.getPtr()));
      break;
    case ELF::DT_GNU_HASH:
      GnuHashTable = reinterpret_cast<const Elf_GnuHash *>(
          toMappedAddr(Dyn.getTag(), Dyn.getPtr()));
      break;
    case ELF::DT_STRTAB:
      StringTableBegin = reinterpret_cast<const char *>(
          toMappedAddr(Dyn.getTag(), Dyn.getPtr()));
      break;
    case ELF::DT_STRSZ:
      StringTableSize = Dyn.getVal();
      break;
    case ELF::DT_SYMTAB: {
      // If we can't map the DT_SYMTAB value to an address (e.g. when there are
      // no program headers), we ignore its value.
      if (const uint8_t *VA = toMappedAddr(Dyn.getTag(), Dyn.getPtr())) {
        DynSymFromTable.emplace(ObjF, *this);
        DynSymFromTable->Addr = VA;
        DynSymFromTable->EntSize = sizeof(Elf_Sym);
        DynSymFromTable->EntSizePrintName = "";
      }
      break;
    }
    case ELF::DT_SYMENT: {
      uint64_t Val = Dyn.getVal();
      if (Val != sizeof(Elf_Sym))
        this->reportUniqueWarning("DT_SYMENT value of 0x" +
                                  Twine::utohexstr(Val) +
                                  " is not the size of a symbol (0x" +
                                  Twine::utohexstr(sizeof(Elf_Sym)) + ")");
      break;
    }
    case ELF::DT_RELA:
      DynRelaRegion.Addr = toMappedAddr(Dyn.getTag(), Dyn.getPtr());
      break;
    case ELF::DT_RELASZ:
      DynRelaRegion.Size = Dyn.getVal();
      DynRelaRegion.SizePrintName = "DT_RELASZ value";
      break;
    case ELF::DT_RELAENT:
      DynRelaRegion.EntSize = Dyn.getVal();
      DynRelaRegion.EntSizePrintName = "DT_RELAENT value";
      break;
    case ELF::DT_SONAME:
      SONameOffset = Dyn.getVal();
      break;
    case ELF::DT_REL:
      DynRelRegion.Addr = toMappedAddr(Dyn.getTag(), Dyn.getPtr());
      break;
    case ELF::DT_RELSZ:
      DynRelRegion.Size = Dyn.getVal();
      DynRelRegion.SizePrintName = "DT_RELSZ value";
      break;
    case ELF::DT_RELENT:
      DynRelRegion.EntSize = Dyn.getVal();
      DynRelRegion.EntSizePrintName = "DT_RELENT value";
      break;
    case ELF::DT_RELR:
    case ELF::DT_ANDROID_RELR:
      DynRelrRegion.Addr = toMappedAddr(Dyn.getTag(), Dyn.getPtr());
      break;
    case ELF::DT_RELRSZ:
    case ELF::DT_ANDROID_RELRSZ:
      DynRelrRegion.Size = Dyn.getVal();
      DynRelrRegion.SizePrintName = Dyn.d_tag == ELF::DT_RELRSZ
                                        ? "DT_RELRSZ value"
                                        : "DT_ANDROID_RELRSZ value";
      break;
    case ELF::DT_RELRENT:
    case ELF::DT_ANDROID_RELRENT:
      DynRelrRegion.EntSize = Dyn.getVal();
      DynRelrRegion.EntSizePrintName = Dyn.d_tag == ELF::DT_RELRENT
                                           ? "DT_RELRENT value"
                                           : "DT_ANDROID_RELRENT value";
      break;
    case ELF::DT_PLTREL:
      if (Dyn.getVal() == DT_REL)
        DynPLTRelRegion.EntSize = sizeof(Elf_Rel);
      else if (Dyn.getVal() == DT_RELA)
        DynPLTRelRegion.EntSize = sizeof(Elf_Rela);
      else
        reportUniqueWarning(Twine("unknown DT_PLTREL value of ") +
                            Twine((uint64_t)Dyn.getVal()));
      DynPLTRelRegion.EntSizePrintName = "PLTREL entry size";
      break;
    case ELF::DT_JMPREL:
      DynPLTRelRegion.Addr = toMappedAddr(Dyn.getTag(), Dyn.getPtr());
      break;
    case ELF::DT_PLTRELSZ:
      DynPLTRelRegion.Size = Dyn.getVal();
      DynPLTRelRegion.SizePrintName = "DT_PLTRELSZ value";
      break;
    case ELF::DT_SYMTAB_SHNDX:
      DynSymTabShndxRegion.Addr = toMappedAddr(Dyn.getTag(), Dyn.getPtr());
      DynSymTabShndxRegion.EntSize = sizeof(Elf_Word);
      break;
    }
  }

  if (StringTableBegin) {
    const uint64_t FileSize = Obj.getBufSize();
    const uint64_t Offset = (const uint8_t *)StringTableBegin - Obj.base();
    if (StringTableSize > FileSize - Offset)
      reportUniqueWarning(
          "the dynamic string table at 0x" + Twine::utohexstr(Offset) +
          " goes past the end of the file (0x" + Twine::utohexstr(FileSize) +
          ") with DT_STRSZ = 0x" + Twine::utohexstr(StringTableSize));
    else
      DynamicStringTable = StringRef(StringTableBegin, StringTableSize);
  }

  const bool IsHashTableSupported = getHashTableEntSize() == 4;
  if (DynSymRegion) {
    // Often we find the information about the dynamic symbol table
    // location in the SHT_DYNSYM section header. However, the value in
    // DT_SYMTAB has priority, because it is used by dynamic loaders to
    // locate .dynsym at runtime. The location we find in the section header
    // and the location we find here should match.
    if (DynSymFromTable && DynSymFromTable->Addr != DynSymRegion->Addr)
      reportUniqueWarning(
          createError("SHT_DYNSYM section header and DT_SYMTAB disagree about "
                      "the location of the dynamic symbol table"));

    // According to the ELF gABI: "The number of symbol table entries should
    // equal nchain". Check to see if the DT_HASH hash table nchain value
    // conflicts with the number of symbols in the dynamic symbol table
    // according to the section header.
    if (HashTable && IsHashTableSupported) {
      if (DynSymRegion->EntSize == 0)
        reportUniqueWarning("SHT_DYNSYM section has sh_entsize == 0");
      else if (HashTable->nchain != DynSymRegion->Size / DynSymRegion->EntSize)
        reportUniqueWarning(
            "hash table nchain (" + Twine(HashTable->nchain) +
            ") differs from symbol count derived from SHT_DYNSYM section "
            "header (" +
            Twine(DynSymRegion->Size / DynSymRegion->EntSize) + ")");
    }
  }

  // Delay the creation of the actual dynamic symbol table until now, so that
  // checks can always be made against the section header-based properties,
  // without worrying about tag order.
  if (DynSymFromTable) {
    if (!DynSymRegion) {
      DynSymRegion = DynSymFromTable;
    } else {
      DynSymRegion->Addr = DynSymFromTable->Addr;
      DynSymRegion->EntSize = DynSymFromTable->EntSize;
      DynSymRegion->EntSizePrintName = DynSymFromTable->EntSizePrintName;
    }
  }

  // Derive the dynamic symbol table size from the DT_HASH hash table, if
  // present.
  if (HashTable && IsHashTableSupported && DynSymRegion) {
    const uint64_t FileSize = Obj.getBufSize();
    const uint64_t DerivedSize =
        (uint64_t)HashTable->nchain * DynSymRegion->EntSize;
    const uint64_t Offset = (const uint8_t *)DynSymRegion->Addr - Obj.base();
    if (DerivedSize > FileSize - Offset)
      reportUniqueWarning(
          "the size (0x" + Twine::utohexstr(DerivedSize) +
          ") of the dynamic symbol table at 0x" + Twine::utohexstr(Offset) +
          ", derived from the hash table, goes past the end of the file (0x" +
          Twine::utohexstr(FileSize) + ") and will be ignored");
    else
      DynSymRegion->Size = HashTable->nchain * DynSymRegion->EntSize;
  }
}

template <typename ELFT> void ELFDumper<ELFT>::printVersionInfo() {
  // Dump version symbol section.
  printVersionSymbolSection(SymbolVersionSection);

  // Dump version definition section.
  printVersionDefinitionSection(SymbolVersionDefSection);

  // Dump version dependency section.
  printVersionDependencySection(SymbolVersionNeedSection);
}

#define LLVM_READOBJ_DT_FLAG_ENT(prefix, enum)                                 \
  { #enum, prefix##_##enum }

const EnumEntry<unsigned> ElfDynamicDTFlags[] = {
  LLVM_READOBJ_DT_FLAG_ENT(DF, ORIGIN),
  LLVM_READOBJ_DT_FLAG_ENT(DF, SYMBOLIC),
  LLVM_READOBJ_DT_FLAG_ENT(DF, TEXTREL),
  LLVM_READOBJ_DT_FLAG_ENT(DF, BIND_NOW),
  LLVM_READOBJ_DT_FLAG_ENT(DF, STATIC_TLS)
};

const EnumEntry<unsigned> ElfDynamicDTFlags1[] = {
  LLVM_READOBJ_DT_FLAG_ENT(DF_1, NOW),
  LLVM_READOBJ_DT_FLAG_ENT(DF_1, GLOBAL),
  LLVM_READOBJ_DT_FLAG_ENT(DF_1, GROUP),
  LLVM_READOBJ_DT_FLAG_ENT(DF_1, NODELETE),
  LLVM_READOBJ_DT_FLAG_ENT(DF_1, LOADFLTR),
  LLVM_READOBJ_DT_FLAG_ENT(DF_1, INITFIRST),
  LLVM_READOBJ_DT_FLAG_ENT(DF_1, NOOPEN),
  LLVM_READOBJ_DT_FLAG_ENT(DF_1, ORIGIN),
  LLVM_READOBJ_DT_FLAG_ENT(DF_1, DIRECT),
  LLVM_READOBJ_DT_FLAG_ENT(DF_1, TRANS),
  LLVM_READOBJ_DT_FLAG_ENT(DF_1, INTERPOSE),
  LLVM_READOBJ_DT_FLAG_ENT(DF_1, NODEFLIB),
  LLVM_READOBJ_DT_FLAG_ENT(DF_1, NODUMP),
  LLVM_READOBJ_DT_FLAG_ENT(DF_1, CONFALT),
  LLVM_READOBJ_DT_FLAG_ENT(DF_1, ENDFILTEE),
  LLVM_READOBJ_DT_FLAG_ENT(DF_1, DISPRELDNE),
  LLVM_READOBJ_DT_FLAG_ENT(DF_1, DISPRELPND),
  LLVM_READOBJ_DT_FLAG_ENT(DF_1, NODIRECT),
  LLVM_READOBJ_DT_FLAG_ENT(DF_1, IGNMULDEF),
  LLVM_READOBJ_DT_FLAG_ENT(DF_1, NOKSYMS),
  LLVM_READOBJ_DT_FLAG_ENT(DF_1, NOHDR),
  LLVM_READOBJ_DT_FLAG_ENT(DF_1, EDITED),
  LLVM_READOBJ_DT_FLAG_ENT(DF_1, NORELOC),
  LLVM_READOBJ_DT_FLAG_ENT(DF_1, SYMINTPOSE),
  LLVM_READOBJ_DT_FLAG_ENT(DF_1, GLOBAUDIT),
  LLVM_READOBJ_DT_FLAG_ENT(DF_1, SINGLETON),
  LLVM_READOBJ_DT_FLAG_ENT(DF_1, PIE),
};

const EnumEntry<unsigned> ElfDynamicDTMipsFlags[] = {
  LLVM_READOBJ_DT_FLAG_ENT(RHF, NONE),
  LLVM_READOBJ_DT_FLAG_ENT(RHF, QUICKSTART),
  LLVM_READOBJ_DT_FLAG_ENT(RHF, NOTPOT),
  LLVM_READOBJ_DT_FLAG_ENT(RHS, NO_LIBRARY_REPLACEMENT),
  LLVM_READOBJ_DT_FLAG_ENT(RHF, NO_MOVE),
  LLVM_READOBJ_DT_FLAG_ENT(RHF, SGI_ONLY),
  LLVM_READOBJ_DT_FLAG_ENT(RHF, GUARANTEE_INIT),
  LLVM_READOBJ_DT_FLAG_ENT(RHF, DELTA_C_PLUS_PLUS),
  LLVM_READOBJ_DT_FLAG_ENT(RHF, GUARANTEE_START_INIT),
  LLVM_READOBJ_DT_FLAG_ENT(RHF, PIXIE),
  LLVM_READOBJ_DT_FLAG_ENT(RHF, DEFAULT_DELAY_LOAD),
  LLVM_READOBJ_DT_FLAG_ENT(RHF, REQUICKSTART),
  LLVM_READOBJ_DT_FLAG_ENT(RHF, REQUICKSTARTED),
  LLVM_READOBJ_DT_FLAG_ENT(RHF, CORD),
  LLVM_READOBJ_DT_FLAG_ENT(RHF, NO_UNRES_UNDEF),
  LLVM_READOBJ_DT_FLAG_ENT(RHF, RLD_ORDER_SAFE)
};

#undef LLVM_READOBJ_DT_FLAG_ENT

template <typename T, typename TFlag>
void printFlags(T Value, ArrayRef<EnumEntry<TFlag>> Flags, raw_ostream &OS) {
  SmallVector<EnumEntry<TFlag>, 10> SetFlags;
  for (const EnumEntry<TFlag> &Flag : Flags)
    if (Flag.Value != 0 && (Value & Flag.Value) == Flag.Value)
      SetFlags.push_back(Flag);

  for (const EnumEntry<TFlag> &Flag : SetFlags)
    OS << Flag.Name << " ";
}

template <class ELFT>
const typename ELFT::Shdr *
ELFDumper<ELFT>::findSectionByName(StringRef Name) const {
  for (const Elf_Shdr &Shdr : cantFail(Obj.sections())) {
    if (Expected<StringRef> NameOrErr = Obj.getSectionName(Shdr)) {
      if (*NameOrErr == Name)
        return &Shdr;
    } else {
      reportUniqueWarning("unable to read the name of " + describe(Shdr) +
                          ": " + toString(NameOrErr.takeError()));
    }
  }
  return nullptr;
}

template <class ELFT>
std::string ELFDumper<ELFT>::getDynamicEntry(uint64_t Type,
                                             uint64_t Value) const {
  auto FormatHexValue = [](uint64_t V) {
    std::string Str;
    raw_string_ostream OS(Str);
    const char *ConvChar =
        (opts::Output == opts::GNU) ? "0x%" PRIx64 : "0x%" PRIX64;
    OS << format(ConvChar, V);
    return OS.str();
  };

  auto FormatFlags = [](uint64_t V,
                        llvm::ArrayRef<llvm::EnumEntry<unsigned int>> Array) {
    std::string Str;
    raw_string_ostream OS(Str);
    printFlags(V, Array, OS);
    return OS.str();
  };

  // Handle custom printing of architecture specific tags
  switch (Obj.getHeader().e_machine) {
  case EM_AARCH64:
    switch (Type) {
    case DT_AARCH64_BTI_PLT:
    case DT_AARCH64_PAC_PLT:
    case DT_AARCH64_VARIANT_PCS:
      return std::to_string(Value);
    default:
      break;
    }
    break;
  case EM_HEXAGON:
    switch (Type) {
    case DT_HEXAGON_VER:
      return std::to_string(Value);
    case DT_HEXAGON_SYMSZ:
    case DT_HEXAGON_PLT:
      return FormatHexValue(Value);
    default:
      break;
    }
    break;
  case EM_MIPS:
    switch (Type) {
    case DT_MIPS_RLD_VERSION:
    case DT_MIPS_LOCAL_GOTNO:
    case DT_MIPS_SYMTABNO:
    case DT_MIPS_UNREFEXTNO:
      return std::to_string(Value);
    case DT_MIPS_TIME_STAMP:
    case DT_MIPS_ICHECKSUM:
    case DT_MIPS_IVERSION:
    case DT_MIPS_BASE_ADDRESS:
    case DT_MIPS_MSYM:
    case DT_MIPS_CONFLICT:
    case DT_MIPS_LIBLIST:
    case DT_MIPS_CONFLICTNO:
    case DT_MIPS_LIBLISTNO:
    case DT_MIPS_GOTSYM:
    case DT_MIPS_HIPAGENO:
    case DT_MIPS_RLD_MAP:
    case DT_MIPS_DELTA_CLASS:
    case DT_MIPS_DELTA_CLASS_NO:
    case DT_MIPS_DELTA_INSTANCE:
    case DT_MIPS_DELTA_RELOC:
    case DT_MIPS_DELTA_RELOC_NO:
    case DT_MIPS_DELTA_SYM:
    case DT_MIPS_DELTA_SYM_NO:
    case DT_MIPS_DELTA_CLASSSYM:
    case DT_MIPS_DELTA_CLASSSYM_NO:
    case DT_MIPS_CXX_FLAGS:
    case DT_MIPS_PIXIE_INIT:
    case DT_MIPS_SYMBOL_LIB:
    case DT_MIPS_LOCALPAGE_GOTIDX:
    case DT_MIPS_LOCAL_GOTIDX:
    case DT_MIPS_HIDDEN_GOTIDX:
    case DT_MIPS_PROTECTED_GOTIDX:
    case DT_MIPS_OPTIONS:
    case DT_MIPS_INTERFACE:
    case DT_MIPS_DYNSTR_ALIGN:
    case DT_MIPS_INTERFACE_SIZE:
    case DT_MIPS_RLD_TEXT_RESOLVE_ADDR:
    case DT_MIPS_PERF_SUFFIX:
    case DT_MIPS_COMPACT_SIZE:
    case DT_MIPS_GP_VALUE:
    case DT_MIPS_AUX_DYNAMIC:
    case DT_MIPS_PLTGOT:
    case DT_MIPS_RWPLT:
    case DT_MIPS_RLD_MAP_REL:
    case DT_MIPS_XHASH:
      return FormatHexValue(Value);
    case DT_MIPS_FLAGS:
      return FormatFlags(Value, makeArrayRef(ElfDynamicDTMipsFlags));
    default:
      break;
    }
    break;
  default:
    break;
  }

  switch (Type) {
  case DT_PLTREL:
    if (Value == DT_REL)
      return "REL";
    if (Value == DT_RELA)
      return "RELA";
    LLVM_FALLTHROUGH;
  case DT_PLTGOT:
  case DT_HASH:
  case DT_STRTAB:
  case DT_SYMTAB:
  case DT_RELA:
  case DT_INIT:
  case DT_FINI:
  case DT_REL:
  case DT_JMPREL:
  case DT_INIT_ARRAY:
  case DT_FINI_ARRAY:
  case DT_PREINIT_ARRAY:
  case DT_DEBUG:
  case DT_VERDEF:
  case DT_VERNEED:
  case DT_VERSYM:
  case DT_GNU_HASH:
  case DT_NULL:
    return FormatHexValue(Value);
  case DT_RELACOUNT:
  case DT_RELCOUNT:
  case DT_VERDEFNUM:
  case DT_VERNEEDNUM:
    return std::to_string(Value);
  case DT_PLTRELSZ:
  case DT_RELASZ:
  case DT_RELAENT:
  case DT_STRSZ:
  case DT_SYMENT:
  case DT_RELSZ:
  case DT_RELENT:
  case DT_INIT_ARRAYSZ:
  case DT_FINI_ARRAYSZ:
  case DT_PREINIT_ARRAYSZ:
  case DT_RELRSZ:
  case DT_RELRENT:
  case DT_ANDROID_RELSZ:
  case DT_ANDROID_RELASZ:
    return std::to_string(Value) + " (bytes)";
  case DT_NEEDED:
  case DT_SONAME:
  case DT_AUXILIARY:
  case DT_USED:
  case DT_FILTER:
  case DT_RPATH:
  case DT_RUNPATH: {
    const std::map<uint64_t, const char *> TagNames = {
        {DT_NEEDED, "Shared library"},       {DT_SONAME, "Library soname"},
        {DT_AUXILIARY, "Auxiliary library"}, {DT_USED, "Not needed object"},
        {DT_FILTER, "Filter library"},       {DT_RPATH, "Library rpath"},
        {DT_RUNPATH, "Library runpath"},
    };

    return (Twine(TagNames.at(Type)) + ": [" + getDynamicString(Value) + "]")
        .str();
  }
  case DT_FLAGS:
    return FormatFlags(Value, makeArrayRef(ElfDynamicDTFlags));
  case DT_FLAGS_1:
    return FormatFlags(Value, makeArrayRef(ElfDynamicDTFlags1));
  default:
    return FormatHexValue(Value);
  }
}

template <class ELFT>
StringRef ELFDumper<ELFT>::getDynamicString(uint64_t Value) const {
  if (DynamicStringTable.empty() && !DynamicStringTable.data()) {
    reportUniqueWarning("string table was not found");
    return "<?>";
  }

  auto WarnAndReturn = [this](const Twine &Msg, uint64_t Offset) {
    reportUniqueWarning("string table at offset 0x" + Twine::utohexstr(Offset) +
                        Msg);
    return "<?>";
  };

  const uint64_t FileSize = Obj.getBufSize();
  const uint64_t Offset =
      (const uint8_t *)DynamicStringTable.data() - Obj.base();
  if (DynamicStringTable.size() > FileSize - Offset)
    return WarnAndReturn(" with size 0x" +
                             Twine::utohexstr(DynamicStringTable.size()) +
                             " goes past the end of the file (0x" +
                             Twine::utohexstr(FileSize) + ")",
                         Offset);

  if (Value >= DynamicStringTable.size())
    return WarnAndReturn(
        ": unable to read the string at 0x" + Twine::utohexstr(Offset + Value) +
            ": it goes past the end of the table (0x" +
            Twine::utohexstr(Offset + DynamicStringTable.size()) + ")",
        Offset);

  if (DynamicStringTable.back() != '\0')
    return WarnAndReturn(": unable to read the string at 0x" +
                             Twine::utohexstr(Offset + Value) +
                             ": the string table is not null-terminated",
                         Offset);

  return DynamicStringTable.data() + Value;
}

template <class ELFT> void ELFDumper<ELFT>::printUnwindInfo() {
  DwarfCFIEH::PrinterContext<ELFT> Ctx(W, ObjF);
  Ctx.printUnwindInformation();
}

// The namespace is needed to fix the compilation with GCC older than 7.0+.
namespace {
template <> void ELFDumper<ELF32LE>::printUnwindInfo() {
  if (Obj.getHeader().e_machine == EM_ARM) {
    ARM::EHABI::PrinterContext<ELF32LE> Ctx(W, Obj, ObjF.getFileName(),
                                            DotSymtabSec);
    Ctx.PrintUnwindInformation();
  }
  DwarfCFIEH::PrinterContext<ELF32LE> Ctx(W, ObjF);
  Ctx.printUnwindInformation();
}
} // namespace

template <class ELFT> void ELFDumper<ELFT>::printNeededLibraries() {
  ListScope D(W, "NeededLibraries");

  std::vector<StringRef> Libs;
  for (const auto &Entry : dynamic_table())
    if (Entry.d_tag == ELF::DT_NEEDED)
      Libs.push_back(getDynamicString(Entry.d_un.d_val));

  llvm::sort(Libs);

  for (StringRef L : Libs)
    W.startLine() << L << "\n";
}

template <class ELFT>
static Error checkHashTable(const ELFDumper<ELFT> &Dumper,
                            const typename ELFT::Hash *H,
                            bool *IsHeaderValid = nullptr) {
  const ELFFile<ELFT> &Obj = Dumper.getElfObject().getELFFile();
  const uint64_t SecOffset = (const uint8_t *)H - Obj.base();
  if (Dumper.getHashTableEntSize() == 8) {
    auto It = llvm::find_if(ElfMachineType, [&](const EnumEntry<unsigned> &E) {
      return E.Value == Obj.getHeader().e_machine;
    });
    if (IsHeaderValid)
      *IsHeaderValid = false;
    return createError("the hash table at 0x" + Twine::utohexstr(SecOffset) +
                       " is not supported: it contains non-standard 8 "
                       "byte entries on " +
                       It->AltName + " platform");
  }

  auto MakeError = [&](const Twine &Msg = "") {
    return createError("the hash table at offset 0x" +
                       Twine::utohexstr(SecOffset) +
                       " goes past the end of the file (0x" +
                       Twine::utohexstr(Obj.getBufSize()) + ")" + Msg);
  };

  // Each SHT_HASH section starts from two 32-bit fields: nbucket and nchain.
  const unsigned HeaderSize = 2 * sizeof(typename ELFT::Word);

  if (IsHeaderValid)
    *IsHeaderValid = Obj.getBufSize() - SecOffset >= HeaderSize;

  if (Obj.getBufSize() - SecOffset < HeaderSize)
    return MakeError();

  if (Obj.getBufSize() - SecOffset - HeaderSize <
      ((uint64_t)H->nbucket + H->nchain) * sizeof(typename ELFT::Word))
    return MakeError(", nbucket = " + Twine(H->nbucket) +
                     ", nchain = " + Twine(H->nchain));
  return Error::success();
}

template <class ELFT>
static Error checkGNUHashTable(const ELFFile<ELFT> &Obj,
                               const typename ELFT::GnuHash *GnuHashTable,
                               bool *IsHeaderValid = nullptr) {
  const uint8_t *TableData = reinterpret_cast<const uint8_t *>(GnuHashTable);
  assert(TableData >= Obj.base() && TableData < Obj.base() + Obj.getBufSize() &&
         "GnuHashTable must always point to a location inside the file");

  uint64_t TableOffset = TableData - Obj.base();
  if (IsHeaderValid)
    *IsHeaderValid = TableOffset + /*Header size:*/ 16 < Obj.getBufSize();
  if (TableOffset + 16 + (uint64_t)GnuHashTable->nbuckets * 4 +
          (uint64_t)GnuHashTable->maskwords * sizeof(typename ELFT::Off) >=
      Obj.getBufSize())
    return createError("unable to dump the SHT_GNU_HASH "
                       "section at 0x" +
                       Twine::utohexstr(TableOffset) +
                       ": it goes past the end of the file");
  return Error::success();
}

template <typename ELFT> void ELFDumper<ELFT>::printHashTable() {
  DictScope D(W, "HashTable");
  if (!HashTable)
    return;

  bool IsHeaderValid;
  Error Err = checkHashTable(*this, HashTable, &IsHeaderValid);
  if (IsHeaderValid) {
    W.printNumber("Num Buckets", HashTable->nbucket);
    W.printNumber("Num Chains", HashTable->nchain);
  }

  if (Err) {
    reportUniqueWarning(std::move(Err));
    return;
  }

  W.printList("Buckets", HashTable->buckets());
  W.printList("Chains", HashTable->chains());
}

template <class ELFT>
static Expected<ArrayRef<typename ELFT::Word>>
getGnuHashTableChains(Optional<DynRegionInfo> DynSymRegion,
                      const typename ELFT::GnuHash *GnuHashTable) {
  if (!DynSymRegion)
    return createError("no dynamic symbol table found");

  ArrayRef<typename ELFT::Sym> DynSymTable =
      DynSymRegion->template getAsArrayRef<typename ELFT::Sym>();
  size_t NumSyms = DynSymTable.size();
  if (!NumSyms)
    return createError("the dynamic symbol table is empty");

  if (GnuHashTable->symndx < NumSyms)
    return GnuHashTable->values(NumSyms);

  // A normal empty GNU hash table section produced by linker might have
  // symndx set to the number of dynamic symbols + 1 (for the zero symbol)
  // and have dummy null values in the Bloom filter and in the buckets
  // vector (or no values at all). It happens because the value of symndx is not
  // important for dynamic loaders when the GNU hash table is empty. They just
  // skip the whole object during symbol lookup. In such cases, the symndx value
  // is irrelevant and we should not report a warning.
  ArrayRef<typename ELFT::Word> Buckets = GnuHashTable->buckets();
  if (!llvm::all_of(Buckets, [](typename ELFT::Word V) { return V == 0; }))
    return createError(
        "the first hashed symbol index (" + Twine(GnuHashTable->symndx) +
        ") is greater than or equal to the number of dynamic symbols (" +
        Twine(NumSyms) + ")");
  // There is no way to represent an array of (dynamic symbols count - symndx)
  // length.
  return ArrayRef<typename ELFT::Word>();
}

template <typename ELFT>
void ELFDumper<ELFT>::printGnuHashTable() {
  DictScope D(W, "GnuHashTable");
  if (!GnuHashTable)
    return;

  bool IsHeaderValid;
  Error Err = checkGNUHashTable<ELFT>(Obj, GnuHashTable, &IsHeaderValid);
  if (IsHeaderValid) {
    W.printNumber("Num Buckets", GnuHashTable->nbuckets);
    W.printNumber("First Hashed Symbol Index", GnuHashTable->symndx);
    W.printNumber("Num Mask Words", GnuHashTable->maskwords);
    W.printNumber("Shift Count", GnuHashTable->shift2);
  }

  if (Err) {
    reportUniqueWarning(std::move(Err));
    return;
  }

  ArrayRef<typename ELFT::Off> BloomFilter = GnuHashTable->filter();
  W.printHexList("Bloom Filter", BloomFilter);

  ArrayRef<Elf_Word> Buckets = GnuHashTable->buckets();
  W.printList("Buckets", Buckets);

  Expected<ArrayRef<Elf_Word>> Chains =
      getGnuHashTableChains<ELFT>(DynSymRegion, GnuHashTable);
  if (!Chains) {
    reportUniqueWarning("unable to dump 'Values' for the SHT_GNU_HASH "
                        "section: " +
                        toString(Chains.takeError()));
    return;
  }

  W.printHexList("Values", *Chains);
}

template <typename ELFT> void ELFDumper<ELFT>::printLoadName() {
  StringRef SOName = "<Not found>";
  if (SONameOffset)
    SOName = getDynamicString(*SONameOffset);
  W.printString("LoadName", SOName);
}

template <class ELFT> void ELFDumper<ELFT>::printArchSpecificInfo() {
  switch (Obj.getHeader().e_machine) {
  case EM_ARM:
    if (Obj.isLE())
      printAttributes(ELF::SHT_ARM_ATTRIBUTES,
                      std::make_unique<ARMAttributeParser>(&W),
                      support::little);
    else
      reportUniqueWarning("attribute printing not implemented for big-endian "
                          "ARM objects");
    break;
  case EM_RISCV:
    if (Obj.isLE())
      printAttributes(ELF::SHT_RISCV_ATTRIBUTES,
                      std::make_unique<RISCVAttributeParser>(&W),
                      support::little);
    else
      reportUniqueWarning("attribute printing not implemented for big-endian "
                          "RISC-V objects");
    break;
  case EM_MSP430:
    printAttributes(ELF::SHT_MSP430_ATTRIBUTES,
                    std::make_unique<MSP430AttributeParser>(&W),
                    support::little);
    break;
  case EM_MIPS: {
    printMipsABIFlags();
    printMipsOptions();
    printMipsReginfo();
    MipsGOTParser<ELFT> Parser(*this);
    if (Error E = Parser.findGOT(dynamic_table(), dynamic_symbols()))
      reportUniqueWarning(std::move(E));
    else if (!Parser.isGotEmpty())
      printMipsGOT(Parser);

    if (Error E = Parser.findPLT(dynamic_table()))
      reportUniqueWarning(std::move(E));
    else if (!Parser.isPltEmpty())
      printMipsPLT(Parser);
    break;
  }
  default:
    break;
  }
}

template <class ELFT>
void ELFDumper<ELFT>::printAttributes(
    unsigned AttrShType, std::unique_ptr<ELFAttributeParser> AttrParser,
    support::endianness Endianness) {
  assert((AttrShType != ELF::SHT_NULL) && AttrParser &&
         "Incomplete ELF attribute implementation");
  DictScope BA(W, "BuildAttributes");
  for (const Elf_Shdr &Sec : cantFail(Obj.sections())) {
    if (Sec.sh_type != AttrShType)
      continue;

    ArrayRef<uint8_t> Contents;
    if (Expected<ArrayRef<uint8_t>> ContentOrErr =
            Obj.getSectionContents(Sec)) {
      Contents = *ContentOrErr;
      if (Contents.empty()) {
        reportUniqueWarning("the " + describe(Sec) + " is empty");
        continue;
      }
    } else {
      reportUniqueWarning("unable to read the content of the " + describe(Sec) +
                          ": " + toString(ContentOrErr.takeError()));
      continue;
    }

    W.printHex("FormatVersion", Contents[0]);

    if (Error E = AttrParser->parse(Contents, Endianness))
      reportUniqueWarning("unable to dump attributes from the " +
                          describe(Sec) + ": " + toString(std::move(E)));
  }
}

namespace {

template <class ELFT> class MipsGOTParser {
public:
  LLVM_ELF_IMPORT_TYPES_ELFT(ELFT)
  using Entry = typename ELFT::Addr;
  using Entries = ArrayRef<Entry>;

  const bool IsStatic;
  const ELFFile<ELFT> &Obj;
  const ELFDumper<ELFT> &Dumper;

  MipsGOTParser(const ELFDumper<ELFT> &D);
  Error findGOT(Elf_Dyn_Range DynTable, Elf_Sym_Range DynSyms);
  Error findPLT(Elf_Dyn_Range DynTable);

  bool isGotEmpty() const { return GotEntries.empty(); }
  bool isPltEmpty() const { return PltEntries.empty(); }

  uint64_t getGp() const;

  const Entry *getGotLazyResolver() const;
  const Entry *getGotModulePointer() const;
  const Entry *getPltLazyResolver() const;
  const Entry *getPltModulePointer() const;

  Entries getLocalEntries() const;
  Entries getGlobalEntries() const;
  Entries getOtherEntries() const;
  Entries getPltEntries() const;

  uint64_t getGotAddress(const Entry * E) const;
  int64_t getGotOffset(const Entry * E) const;
  const Elf_Sym *getGotSym(const Entry *E) const;

  uint64_t getPltAddress(const Entry * E) const;
  const Elf_Sym *getPltSym(const Entry *E) const;

  StringRef getPltStrTable() const { return PltStrTable; }
  const Elf_Shdr *getPltSymTable() const { return PltSymTable; }

private:
  const Elf_Shdr *GotSec;
  size_t LocalNum;
  size_t GlobalNum;

  const Elf_Shdr *PltSec;
  const Elf_Shdr *PltRelSec;
  const Elf_Shdr *PltSymTable;
  StringRef FileName;

  Elf_Sym_Range GotDynSyms;
  StringRef PltStrTable;

  Entries GotEntries;
  Entries PltEntries;
};

} // end anonymous namespace

template <class ELFT>
MipsGOTParser<ELFT>::MipsGOTParser(const ELFDumper<ELFT> &D)
    : IsStatic(D.dynamic_table().empty()), Obj(D.getElfObject().getELFFile()),
      Dumper(D), GotSec(nullptr), LocalNum(0), GlobalNum(0), PltSec(nullptr),
      PltRelSec(nullptr), PltSymTable(nullptr),
      FileName(D.getElfObject().getFileName()) {}

template <class ELFT>
Error MipsGOTParser<ELFT>::findGOT(Elf_Dyn_Range DynTable,
                                   Elf_Sym_Range DynSyms) {
  // See "Global Offset Table" in Chapter 5 in the following document
  // for detailed GOT description.
  // ftp://www.linux-mips.org/pub/linux/mips/doc/ABI/mipsabi.pdf

  // Find static GOT secton.
  if (IsStatic) {
    GotSec = Dumper.findSectionByName(".got");
    if (!GotSec)
      return Error::success();

    ArrayRef<uint8_t> Content =
        unwrapOrError(FileName, Obj.getSectionContents(*GotSec));
    GotEntries = Entries(reinterpret_cast<const Entry *>(Content.data()),
                         Content.size() / sizeof(Entry));
    LocalNum = GotEntries.size();
    return Error::success();
  }

  // Lookup dynamic table tags which define the GOT layout.
  Optional<uint64_t> DtPltGot;
  Optional<uint64_t> DtLocalGotNum;
  Optional<uint64_t> DtGotSym;
  for (const auto &Entry : DynTable) {
    switch (Entry.getTag()) {
    case ELF::DT_PLTGOT:
      DtPltGot = Entry.getVal();
      break;
    case ELF::DT_MIPS_LOCAL_GOTNO:
      DtLocalGotNum = Entry.getVal();
      break;
    case ELF::DT_MIPS_GOTSYM:
      DtGotSym = Entry.getVal();
      break;
    }
  }

  if (!DtPltGot && !DtLocalGotNum && !DtGotSym)
    return Error::success();

  if (!DtPltGot)
    return createError("cannot find PLTGOT dynamic tag");
  if (!DtLocalGotNum)
    return createError("cannot find MIPS_LOCAL_GOTNO dynamic tag");
  if (!DtGotSym)
    return createError("cannot find MIPS_GOTSYM dynamic tag");

  size_t DynSymTotal = DynSyms.size();
  if (*DtGotSym > DynSymTotal)
    return createError("DT_MIPS_GOTSYM value (" + Twine(*DtGotSym) +
                       ") exceeds the number of dynamic symbols (" +
                       Twine(DynSymTotal) + ")");

  GotSec = findNotEmptySectionByAddress(Obj, FileName, *DtPltGot);
  if (!GotSec)
    return createError("there is no non-empty GOT section at 0x" +
                       Twine::utohexstr(*DtPltGot));

  LocalNum = *DtLocalGotNum;
  GlobalNum = DynSymTotal - *DtGotSym;

  ArrayRef<uint8_t> Content =
      unwrapOrError(FileName, Obj.getSectionContents(*GotSec));
  GotEntries = Entries(reinterpret_cast<const Entry *>(Content.data()),
                       Content.size() / sizeof(Entry));
  GotDynSyms = DynSyms.drop_front(*DtGotSym);

  return Error::success();
}

template <class ELFT>
Error MipsGOTParser<ELFT>::findPLT(Elf_Dyn_Range DynTable) {
  // Lookup dynamic table tags which define the PLT layout.
  Optional<uint64_t> DtMipsPltGot;
  Optional<uint64_t> DtJmpRel;
  for (const auto &Entry : DynTable) {
    switch (Entry.getTag()) {
    case ELF::DT_MIPS_PLTGOT:
      DtMipsPltGot = Entry.getVal();
      break;
    case ELF::DT_JMPREL:
      DtJmpRel = Entry.getVal();
      break;
    }
  }

  if (!DtMipsPltGot && !DtJmpRel)
    return Error::success();

  // Find PLT section.
  if (!DtMipsPltGot)
    return createError("cannot find MIPS_PLTGOT dynamic tag");
  if (!DtJmpRel)
    return createError("cannot find JMPREL dynamic tag");

  PltSec = findNotEmptySectionByAddress(Obj, FileName, *DtMipsPltGot);
  if (!PltSec)
    return createError("there is no non-empty PLTGOT section at 0x" +
                       Twine::utohexstr(*DtMipsPltGot));

  PltRelSec = findNotEmptySectionByAddress(Obj, FileName, *DtJmpRel);
  if (!PltRelSec)
    return createError("there is no non-empty RELPLT section at 0x" +
                       Twine::utohexstr(*DtJmpRel));

  if (Expected<ArrayRef<uint8_t>> PltContentOrErr =
          Obj.getSectionContents(*PltSec))
    PltEntries =
        Entries(reinterpret_cast<const Entry *>(PltContentOrErr->data()),
                PltContentOrErr->size() / sizeof(Entry));
  else
    return createError("unable to read PLTGOT section content: " +
                       toString(PltContentOrErr.takeError()));

  if (Expected<const Elf_Shdr *> PltSymTableOrErr =
          Obj.getSection(PltRelSec->sh_link))
    PltSymTable = *PltSymTableOrErr;
  else
    return createError("unable to get a symbol table linked to the " +
                       describe(Obj, *PltRelSec) + ": " +
                       toString(PltSymTableOrErr.takeError()));

  if (Expected<StringRef> StrTabOrErr =
          Obj.getStringTableForSymtab(*PltSymTable))
    PltStrTable = *StrTabOrErr;
  else
    return createError("unable to get a string table for the " +
                       describe(Obj, *PltSymTable) + ": " +
                       toString(StrTabOrErr.takeError()));

  return Error::success();
}

template <class ELFT> uint64_t MipsGOTParser<ELFT>::getGp() const {
  return GotSec->sh_addr + 0x7ff0;
}

template <class ELFT>
const typename MipsGOTParser<ELFT>::Entry *
MipsGOTParser<ELFT>::getGotLazyResolver() const {
  return LocalNum > 0 ? &GotEntries[0] : nullptr;
}

template <class ELFT>
const typename MipsGOTParser<ELFT>::Entry *
MipsGOTParser<ELFT>::getGotModulePointer() const {
  if (LocalNum < 2)
    return nullptr;
  const Entry &E = GotEntries[1];
  if ((E >> (sizeof(Entry) * 8 - 1)) == 0)
    return nullptr;
  return &E;
}

template <class ELFT>
typename MipsGOTParser<ELFT>::Entries
MipsGOTParser<ELFT>::getLocalEntries() const {
  size_t Skip = getGotModulePointer() ? 2 : 1;
  if (LocalNum - Skip <= 0)
    return Entries();
  return GotEntries.slice(Skip, LocalNum - Skip);
}

template <class ELFT>
typename MipsGOTParser<ELFT>::Entries
MipsGOTParser<ELFT>::getGlobalEntries() const {
  if (GlobalNum == 0)
    return Entries();
  return GotEntries.slice(LocalNum, GlobalNum);
}

template <class ELFT>
typename MipsGOTParser<ELFT>::Entries
MipsGOTParser<ELFT>::getOtherEntries() const {
  size_t OtherNum = GotEntries.size() - LocalNum - GlobalNum;
  if (OtherNum == 0)
    return Entries();
  return GotEntries.slice(LocalNum + GlobalNum, OtherNum);
}

template <class ELFT>
uint64_t MipsGOTParser<ELFT>::getGotAddress(const Entry *E) const {
  int64_t Offset = std::distance(GotEntries.data(), E) * sizeof(Entry);
  return GotSec->sh_addr + Offset;
}

template <class ELFT>
int64_t MipsGOTParser<ELFT>::getGotOffset(const Entry *E) const {
  int64_t Offset = std::distance(GotEntries.data(), E) * sizeof(Entry);
  return Offset - 0x7ff0;
}

template <class ELFT>
const typename MipsGOTParser<ELFT>::Elf_Sym *
MipsGOTParser<ELFT>::getGotSym(const Entry *E) const {
  int64_t Offset = std::distance(GotEntries.data(), E);
  return &GotDynSyms[Offset - LocalNum];
}

template <class ELFT>
const typename MipsGOTParser<ELFT>::Entry *
MipsGOTParser<ELFT>::getPltLazyResolver() const {
  return PltEntries.empty() ? nullptr : &PltEntries[0];
}

template <class ELFT>
const typename MipsGOTParser<ELFT>::Entry *
MipsGOTParser<ELFT>::getPltModulePointer() const {
  return PltEntries.size() < 2 ? nullptr : &PltEntries[1];
}

template <class ELFT>
typename MipsGOTParser<ELFT>::Entries
MipsGOTParser<ELFT>::getPltEntries() const {
  if (PltEntries.size() <= 2)
    return Entries();
  return PltEntries.slice(2, PltEntries.size() - 2);
}

template <class ELFT>
uint64_t MipsGOTParser<ELFT>::getPltAddress(const Entry *E) const {
  int64_t Offset = std::distance(PltEntries.data(), E) * sizeof(Entry);
  return PltSec->sh_addr + Offset;
}

template <class ELFT>
const typename MipsGOTParser<ELFT>::Elf_Sym *
MipsGOTParser<ELFT>::getPltSym(const Entry *E) const {
  int64_t Offset = std::distance(getPltEntries().data(), E);
  if (PltRelSec->sh_type == ELF::SHT_REL) {
    Elf_Rel_Range Rels = unwrapOrError(FileName, Obj.rels(*PltRelSec));
    return unwrapOrError(FileName,
                         Obj.getRelocationSymbol(Rels[Offset], PltSymTable));
  } else {
    Elf_Rela_Range Rels = unwrapOrError(FileName, Obj.relas(*PltRelSec));
    return unwrapOrError(FileName,
                         Obj.getRelocationSymbol(Rels[Offset], PltSymTable));
  }
}

const EnumEntry<unsigned> ElfMipsISAExtType[] = {
  {"None",                    Mips::AFL_EXT_NONE},
  {"Broadcom SB-1",           Mips::AFL_EXT_SB1},
  {"Cavium Networks Octeon",  Mips::AFL_EXT_OCTEON},
  {"Cavium Networks Octeon2", Mips::AFL_EXT_OCTEON2},
  {"Cavium Networks OcteonP", Mips::AFL_EXT_OCTEONP},
  {"Cavium Networks Octeon3", Mips::AFL_EXT_OCTEON3},
  {"LSI R4010",               Mips::AFL_EXT_4010},
  {"Loongson 2E",             Mips::AFL_EXT_LOONGSON_2E},
  {"Loongson 2F",             Mips::AFL_EXT_LOONGSON_2F},
  {"Loongson 3A",             Mips::AFL_EXT_LOONGSON_3A},
  {"MIPS R4650",              Mips::AFL_EXT_4650},
  {"MIPS R5900",              Mips::AFL_EXT_5900},
  {"MIPS R10000",             Mips::AFL_EXT_10000},
  {"NEC VR4100",              Mips::AFL_EXT_4100},
  {"NEC VR4111/VR4181",       Mips::AFL_EXT_4111},
  {"NEC VR4120",              Mips::AFL_EXT_4120},
  {"NEC VR5400",              Mips::AFL_EXT_5400},
  {"NEC VR5500",              Mips::AFL_EXT_5500},
  {"RMI Xlr",                 Mips::AFL_EXT_XLR},
  {"Toshiba R3900",           Mips::AFL_EXT_3900}
};

const EnumEntry<unsigned> ElfMipsASEFlags[] = {
  {"DSP",                Mips::AFL_ASE_DSP},
  {"DSPR2",              Mips::AFL_ASE_DSPR2},
  {"Enhanced VA Scheme", Mips::AFL_ASE_EVA},
  {"MCU",                Mips::AFL_ASE_MCU},
  {"MDMX",               Mips::AFL_ASE_MDMX},
  {"MIPS-3D",            Mips::AFL_ASE_MIPS3D},
  {"MT",                 Mips::AFL_ASE_MT},
  {"SmartMIPS",          Mips::AFL_ASE_SMARTMIPS},
  {"VZ",                 Mips::AFL_ASE_VIRT},
  {"MSA",                Mips::AFL_ASE_MSA},
  {"MIPS16",             Mips::AFL_ASE_MIPS16},
  {"microMIPS",          Mips::AFL_ASE_MICROMIPS},
  {"XPA",                Mips::AFL_ASE_XPA},
  {"CRC",                Mips::AFL_ASE_CRC},
  {"GINV",               Mips::AFL_ASE_GINV},
};

const EnumEntry<unsigned> ElfMipsFpABIType[] = {
  {"Hard or soft float",                  Mips::Val_GNU_MIPS_ABI_FP_ANY},
  {"Hard float (double precision)",       Mips::Val_GNU_MIPS_ABI_FP_DOUBLE},
  {"Hard float (single precision)",       Mips::Val_GNU_MIPS_ABI_FP_SINGLE},
  {"Soft float",                          Mips::Val_GNU_MIPS_ABI_FP_SOFT},
  {"Hard float (MIPS32r2 64-bit FPU 12 callee-saved)",
   Mips::Val_GNU_MIPS_ABI_FP_OLD_64},
  {"Hard float (32-bit CPU, Any FPU)",    Mips::Val_GNU_MIPS_ABI_FP_XX},
  {"Hard float (32-bit CPU, 64-bit FPU)", Mips::Val_GNU_MIPS_ABI_FP_64},
  {"Hard float compat (32-bit CPU, 64-bit FPU)",
   Mips::Val_GNU_MIPS_ABI_FP_64A}
};

static const EnumEntry<unsigned> ElfMipsFlags1[] {
  {"ODDSPREG", Mips::AFL_FLAGS1_ODDSPREG},
};

static int getMipsRegisterSize(uint8_t Flag) {
  switch (Flag) {
  case Mips::AFL_REG_NONE:
    return 0;
  case Mips::AFL_REG_32:
    return 32;
  case Mips::AFL_REG_64:
    return 64;
  case Mips::AFL_REG_128:
    return 128;
  default:
    return -1;
  }
}

template <class ELFT>
static void printMipsReginfoData(ScopedPrinter &W,
                                 const Elf_Mips_RegInfo<ELFT> &Reginfo) {
  W.printHex("GP", Reginfo.ri_gp_value);
  W.printHex("General Mask", Reginfo.ri_gprmask);
  W.printHex("Co-Proc Mask0", Reginfo.ri_cprmask[0]);
  W.printHex("Co-Proc Mask1", Reginfo.ri_cprmask[1]);
  W.printHex("Co-Proc Mask2", Reginfo.ri_cprmask[2]);
  W.printHex("Co-Proc Mask3", Reginfo.ri_cprmask[3]);
}

template <class ELFT> void ELFDumper<ELFT>::printMipsReginfo() {
  const Elf_Shdr *RegInfoSec = findSectionByName(".reginfo");
  if (!RegInfoSec) {
    W.startLine() << "There is no .reginfo section in the file.\n";
    return;
  }

  Expected<ArrayRef<uint8_t>> ContentsOrErr =
      Obj.getSectionContents(*RegInfoSec);
  if (!ContentsOrErr) {
    this->reportUniqueWarning(
        "unable to read the content of the .reginfo section (" +
        describe(*RegInfoSec) + "): " + toString(ContentsOrErr.takeError()));
    return;
  }

  if (ContentsOrErr->size() < sizeof(Elf_Mips_RegInfo<ELFT>)) {
    this->reportUniqueWarning("the .reginfo section has an invalid size (0x" +
                              Twine::utohexstr(ContentsOrErr->size()) + ")");
    return;
  }

  DictScope GS(W, "MIPS RegInfo");
  printMipsReginfoData(W, *reinterpret_cast<const Elf_Mips_RegInfo<ELFT> *>(
                              ContentsOrErr->data()));
}

template <class ELFT>
static Expected<const Elf_Mips_Options<ELFT> *>
readMipsOptions(const uint8_t *SecBegin, ArrayRef<uint8_t> &SecData,
                bool &IsSupported) {
  if (SecData.size() < sizeof(Elf_Mips_Options<ELFT>))
    return createError("the .MIPS.options section has an invalid size (0x" +
                       Twine::utohexstr(SecData.size()) + ")");

  const Elf_Mips_Options<ELFT> *O =
      reinterpret_cast<const Elf_Mips_Options<ELFT> *>(SecData.data());
  const uint8_t Size = O->size;
  if (Size > SecData.size()) {
    const uint64_t Offset = SecData.data() - SecBegin;
    const uint64_t SecSize = Offset + SecData.size();
    return createError("a descriptor of size 0x" + Twine::utohexstr(Size) +
                       " at offset 0x" + Twine::utohexstr(Offset) +
                       " goes past the end of the .MIPS.options "
                       "section of size 0x" +
                       Twine::utohexstr(SecSize));
  }

  IsSupported = O->kind == ODK_REGINFO;
  const size_t ExpectedSize =
      sizeof(Elf_Mips_Options<ELFT>) + sizeof(Elf_Mips_RegInfo<ELFT>);

  if (IsSupported)
    if (Size < ExpectedSize)
      return createError(
          "a .MIPS.options entry of kind " +
          Twine(getElfMipsOptionsOdkType(O->kind)) +
          " has an invalid size (0x" + Twine::utohexstr(Size) +
          "), the expected size is 0x" + Twine::utohexstr(ExpectedSize));

  SecData = SecData.drop_front(Size);
  return O;
}

template <class ELFT> void ELFDumper<ELFT>::printMipsOptions() {
  const Elf_Shdr *MipsOpts = findSectionByName(".MIPS.options");
  if (!MipsOpts) {
    W.startLine() << "There is no .MIPS.options section in the file.\n";
    return;
  }

  DictScope GS(W, "MIPS Options");

  ArrayRef<uint8_t> Data =
      unwrapOrError(ObjF.getFileName(), Obj.getSectionContents(*MipsOpts));
  const uint8_t *const SecBegin = Data.begin();
  while (!Data.empty()) {
    bool IsSupported;
    Expected<const Elf_Mips_Options<ELFT> *> OptsOrErr =
        readMipsOptions<ELFT>(SecBegin, Data, IsSupported);
    if (!OptsOrErr) {
      reportUniqueWarning(OptsOrErr.takeError());
      break;
    }

    unsigned Kind = (*OptsOrErr)->kind;
    const char *Type = getElfMipsOptionsOdkType(Kind);
    if (!IsSupported) {
      W.startLine() << "Unsupported MIPS options tag: " << Type << " (" << Kind
                    << ")\n";
      continue;
    }

    DictScope GS(W, Type);
    if (Kind == ODK_REGINFO)
      printMipsReginfoData(W, (*OptsOrErr)->getRegInfo());
    else
      llvm_unreachable("unexpected .MIPS.options section descriptor kind");
  }
}

template <class ELFT> void ELFDumper<ELFT>::printStackMap() const {
  const Elf_Shdr *StackMapSection = findSectionByName(".llvm_stackmaps");
  if (!StackMapSection)
    return;

  auto Warn = [&](Error &&E) {
    this->reportUniqueWarning("unable to read the stack map from " +
                              describe(*StackMapSection) + ": " +
                              toString(std::move(E)));
  };

  Expected<ArrayRef<uint8_t>> ContentOrErr =
      Obj.getSectionContents(*StackMapSection);
  if (!ContentOrErr) {
    Warn(ContentOrErr.takeError());
    return;
  }

  if (Error E = StackMapParser<ELFT::TargetEndianness>::validateHeader(
          *ContentOrErr)) {
    Warn(std::move(E));
    return;
  }

  prettyPrintStackMap(W, StackMapParser<ELFT::TargetEndianness>(*ContentOrErr));
}

template <class ELFT>
void ELFDumper<ELFT>::printReloc(const Relocation<ELFT> &R, unsigned RelIndex,
                                 const Elf_Shdr &Sec, const Elf_Shdr *SymTab) {
  Expected<RelSymbol<ELFT>> Target = getRelocationTarget(R, SymTab);
  if (!Target)
    reportUniqueWarning("unable to print relocation " + Twine(RelIndex) +
                        " in " + describe(Sec) + ": " +
                        toString(Target.takeError()));
  else
    printRelRelaReloc(R, *Target);
}

static inline void printFields(formatted_raw_ostream &OS, StringRef Str1,
                               StringRef Str2) {
  OS.PadToColumn(2u);
  OS << Str1;
  OS.PadToColumn(37u);
  OS << Str2 << "\n";
  OS.flush();
}

template <class ELFT>
static std::string getSectionHeadersNumString(const ELFFile<ELFT> &Obj,
                                              StringRef FileName) {
  const typename ELFT::Ehdr &ElfHeader = Obj.getHeader();
  if (ElfHeader.e_shnum != 0)
    return to_string(ElfHeader.e_shnum);

  Expected<ArrayRef<typename ELFT::Shdr>> ArrOrErr = Obj.sections();
  if (!ArrOrErr) {
    // In this case we can ignore an error, because we have already reported a
    // warning about the broken section header table earlier.
    consumeError(ArrOrErr.takeError());
    return "<?>";
  }

  if (ArrOrErr->empty())
    return "0";
  return "0 (" + to_string((*ArrOrErr)[0].sh_size) + ")";
}

template <class ELFT>
static std::string getSectionHeaderTableIndexString(const ELFFile<ELFT> &Obj,
                                                    StringRef FileName) {
  const typename ELFT::Ehdr &ElfHeader = Obj.getHeader();
  if (ElfHeader.e_shstrndx != SHN_XINDEX)
    return to_string(ElfHeader.e_shstrndx);

  Expected<ArrayRef<typename ELFT::Shdr>> ArrOrErr = Obj.sections();
  if (!ArrOrErr) {
    // In this case we can ignore an error, because we have already reported a
    // warning about the broken section header table earlier.
    consumeError(ArrOrErr.takeError());
    return "<?>";
  }

  if (ArrOrErr->empty())
    return "65535 (corrupt: out of range)";
  return to_string(ElfHeader.e_shstrndx) + " (" +
         to_string((*ArrOrErr)[0].sh_link) + ")";
}

static const EnumEntry<unsigned> *getObjectFileEnumEntry(unsigned Type) {
  auto It = llvm::find_if(ElfObjectFileType, [&](const EnumEntry<unsigned> &E) {
    return E.Value == Type;
  });
  if (It != makeArrayRef(ElfObjectFileType).end())
    return It;
  return nullptr;
}

template <class ELFT>
void GNUELFDumper<ELFT>::printFileSummary(StringRef FileStr, ObjectFile &Obj,
                                          ArrayRef<std::string> InputFilenames,
                                          const Archive *A) {
  if (InputFilenames.size() > 1 || A) {
    this->W.startLine() << "\n";
    this->W.printString("File", FileStr);
  }
}

template <class ELFT> void GNUELFDumper<ELFT>::printFileHeaders() {
  const Elf_Ehdr &e = this->Obj.getHeader();
  OS << "ELF Header:\n";
  OS << "  Magic:  ";
  std::string Str;
  for (int i = 0; i < ELF::EI_NIDENT; i++)
    OS << format(" %02x", static_cast<int>(e.e_ident[i]));
  OS << "\n";
  Str = enumToString(e.e_ident[ELF::EI_CLASS], makeArrayRef(ElfClass));
  printFields(OS, "Class:", Str);
  Str = enumToString(e.e_ident[ELF::EI_DATA], makeArrayRef(ElfDataEncoding));
  printFields(OS, "Data:", Str);
  OS.PadToColumn(2u);
  OS << "Version:";
  OS.PadToColumn(37u);
  OS << utohexstr(e.e_ident[ELF::EI_VERSION]);
  if (e.e_version == ELF::EV_CURRENT)
    OS << " (current)";
  OS << "\n";
  Str = enumToString(e.e_ident[ELF::EI_OSABI], makeArrayRef(ElfOSABI));
  printFields(OS, "OS/ABI:", Str);
  printFields(OS,
              "ABI Version:", std::to_string(e.e_ident[ELF::EI_ABIVERSION]));

  if (const EnumEntry<unsigned> *E = getObjectFileEnumEntry(e.e_type)) {
    Str = E->AltName.str();
  } else {
    if (e.e_type >= ET_LOPROC)
      Str = "Processor Specific: (" + utohexstr(e.e_type, /*LowerCase=*/true) + ")";
    else if (e.e_type >= ET_LOOS)
      Str = "OS Specific: (" + utohexstr(e.e_type, /*LowerCase=*/true) + ")";
    else
      Str = "<unknown>: " + utohexstr(e.e_type, /*LowerCase=*/true);
  }
  printFields(OS, "Type:", Str);

  Str = enumToString(e.e_machine, makeArrayRef(ElfMachineType));
  printFields(OS, "Machine:", Str);
  Str = "0x" + utohexstr(e.e_version);
  printFields(OS, "Version:", Str);
  Str = "0x" + utohexstr(e.e_entry);
  printFields(OS, "Entry point address:", Str);
  Str = to_string(e.e_phoff) + " (bytes into file)";
  printFields(OS, "Start of program headers:", Str);
  Str = to_string(e.e_shoff) + " (bytes into file)";
  printFields(OS, "Start of section headers:", Str);
  std::string ElfFlags;
  if (e.e_machine == EM_MIPS)
    ElfFlags =
        printFlags(e.e_flags, makeArrayRef(ElfHeaderMipsFlags),
                   unsigned(ELF::EF_MIPS_ARCH), unsigned(ELF::EF_MIPS_ABI),
                   unsigned(ELF::EF_MIPS_MACH));
  else if (e.e_machine == EM_RISCV)
    ElfFlags = printFlags(e.e_flags, makeArrayRef(ElfHeaderRISCVFlags));
  else if (e.e_machine == EM_AVR)
    ElfFlags = printFlags(e.e_flags, makeArrayRef(ElfHeaderAVRFlags),
                          unsigned(ELF::EF_AVR_ARCH_MASK));
  else if (e.e_machine == EM_LOONGARCH)
    ElfFlags = printFlags(e.e_flags, makeArrayRef(ElfHeaderLoongArchFlags),
                          unsigned(ELF::EF_LOONGARCH_BASE_ABI_MASK));
  Str = "0x" + utohexstr(e.e_flags);
  if (!ElfFlags.empty())
    Str = Str + ", " + ElfFlags;
  printFields(OS, "Flags:", Str);
  Str = to_string(e.e_ehsize) + " (bytes)";
  printFields(OS, "Size of this header:", Str);
  Str = to_string(e.e_phentsize) + " (bytes)";
  printFields(OS, "Size of program headers:", Str);
  Str = to_string(e.e_phnum);
  printFields(OS, "Number of program headers:", Str);
  Str = to_string(e.e_shentsize) + " (bytes)";
  printFields(OS, "Size of section headers:", Str);
  Str = getSectionHeadersNumString(this->Obj, this->FileName);
  printFields(OS, "Number of section headers:", Str);
  Str = getSectionHeaderTableIndexString(this->Obj, this->FileName);
  printFields(OS, "Section header string table index:", Str);
}

template <class ELFT> std::vector<GroupSection> ELFDumper<ELFT>::getGroups() {
  auto GetSignature = [&](const Elf_Sym &Sym, unsigned SymNdx,
                          const Elf_Shdr &Symtab) -> StringRef {
    Expected<StringRef> StrTableOrErr = Obj.getStringTableForSymtab(Symtab);
    if (!StrTableOrErr) {
      reportUniqueWarning("unable to get the string table for " +
                          describe(Symtab) + ": " +
                          toString(StrTableOrErr.takeError()));
      return "<?>";
    }

    StringRef Strings = *StrTableOrErr;
    if (Sym.st_name >= Strings.size()) {
      reportUniqueWarning("unable to get the name of the symbol with index " +
                          Twine(SymNdx) + ": st_name (0x" +
                          Twine::utohexstr(Sym.st_name) +
                          ") is past the end of the string table of size 0x" +
                          Twine::utohexstr(Strings.size()));
      return "<?>";
    }

    return StrTableOrErr->data() + Sym.st_name;
  };

  std::vector<GroupSection> Ret;
  uint64_t I = 0;
  for (const Elf_Shdr &Sec : cantFail(Obj.sections())) {
    ++I;
    if (Sec.sh_type != ELF::SHT_GROUP)
      continue;

    StringRef Signature = "<?>";
    if (Expected<const Elf_Shdr *> SymtabOrErr = Obj.getSection(Sec.sh_link)) {
      if (Expected<const Elf_Sym *> SymOrErr =
              Obj.template getEntry<Elf_Sym>(**SymtabOrErr, Sec.sh_info))
        Signature = GetSignature(**SymOrErr, Sec.sh_info, **SymtabOrErr);
      else
        reportUniqueWarning("unable to get the signature symbol for " +
                            describe(Sec) + ": " +
                            toString(SymOrErr.takeError()));
    } else {
      reportUniqueWarning("unable to get the symbol table for " +
                          describe(Sec) + ": " +
                          toString(SymtabOrErr.takeError()));
    }

    ArrayRef<Elf_Word> Data;
    if (Expected<ArrayRef<Elf_Word>> ContentsOrErr =
            Obj.template getSectionContentsAsArray<Elf_Word>(Sec)) {
      if (ContentsOrErr->empty())
        reportUniqueWarning("unable to read the section group flag from the " +
                            describe(Sec) + ": the section is empty");
      else
        Data = *ContentsOrErr;
    } else {
      reportUniqueWarning("unable to get the content of the " + describe(Sec) +
                          ": " + toString(ContentsOrErr.takeError()));
    }

    Ret.push_back({getPrintableSectionName(Sec),
                   maybeDemangle(Signature),
                   Sec.sh_name,
                   I - 1,
                   Sec.sh_link,
                   Sec.sh_info,
                   Data.empty() ? Elf_Word(0) : Data[0],
                   {}});

    if (Data.empty())
      continue;

    std::vector<GroupMember> &GM = Ret.back().Members;
    for (uint32_t Ndx : Data.slice(1)) {
      if (Expected<const Elf_Shdr *> SecOrErr = Obj.getSection(Ndx)) {
        GM.push_back({getPrintableSectionName(**SecOrErr), Ndx});
      } else {
        reportUniqueWarning("unable to get the section with index " +
                            Twine(Ndx) + " when dumping the " + describe(Sec) +
                            ": " + toString(SecOrErr.takeError()));
        GM.push_back({"<?>", Ndx});
      }
    }
  }
  return Ret;
}

static DenseMap<uint64_t, const GroupSection *>
mapSectionsToGroups(ArrayRef<GroupSection> Groups) {
  DenseMap<uint64_t, const GroupSection *> Ret;
  for (const GroupSection &G : Groups)
    for (const GroupMember &GM : G.Members)
      Ret.insert({GM.Index, &G});
  return Ret;
}

template <class ELFT> void GNUELFDumper<ELFT>::printGroupSections() {
  std::vector<GroupSection> V = this->getGroups();
  DenseMap<uint64_t, const GroupSection *> Map = mapSectionsToGroups(V);
  for (const GroupSection &G : V) {
    OS << "\n"
       << getGroupType(G.Type) << " group section ["
       << format_decimal(G.Index, 5) << "] `" << G.Name << "' [" << G.Signature
       << "] contains " << G.Members.size() << " sections:\n"
       << "   [Index]    Name\n";
    for (const GroupMember &GM : G.Members) {
      const GroupSection *MainGroup = Map[GM.Index];
      if (MainGroup != &G)
        this->reportUniqueWarning(
            "section with index " + Twine(GM.Index) +
            ", included in the group section with index " +
            Twine(MainGroup->Index) +
            ", was also found in the group section with index " +
            Twine(G.Index));
      OS << "   [" << format_decimal(GM.Index, 5) << "]   " << GM.Name << "\n";
    }
  }

  if (V.empty())
    OS << "There are no section groups in this file.\n";
}

template <class ELFT>
void GNUELFDumper<ELFT>::printRelrReloc(const Elf_Relr &R) {
  OS << to_string(format_hex_no_prefix(R, ELFT::Is64Bits ? 16 : 8)) << "\n";
}

template <class ELFT>
void GNUELFDumper<ELFT>::printRelRelaReloc(const Relocation<ELFT> &R,
                                           const RelSymbol<ELFT> &RelSym) {
  // First two fields are bit width dependent. The rest of them are fixed width.
  unsigned Bias = ELFT::Is64Bits ? 8 : 0;
  Field Fields[5] = {0, 10 + Bias, 19 + 2 * Bias, 42 + 2 * Bias, 53 + 2 * Bias};
  unsigned Width = ELFT::Is64Bits ? 16 : 8;

  Fields[0].Str = to_string(format_hex_no_prefix(R.Offset, Width));
  Fields[1].Str = to_string(format_hex_no_prefix(R.Info, Width));

  SmallString<32> RelocName;
  this->Obj.getRelocationTypeName(R.Type, RelocName);
  Fields[2].Str = RelocName.c_str();

  if (RelSym.Sym)
    Fields[3].Str =
        to_string(format_hex_no_prefix(RelSym.Sym->getValue(), Width));

  Fields[4].Str = std::string(RelSym.Name);
  for (const Field &F : Fields)
    printField(F);

  std::string Addend;
  if (Optional<int64_t> A = R.Addend) {
    int64_t RelAddend = *A;
    if (!RelSym.Name.empty()) {
      if (RelAddend < 0) {
        Addend = " - ";
        RelAddend = std::abs(RelAddend);
      } else {
        Addend = " + ";
      }
    }
    Addend += utohexstr(RelAddend, /*LowerCase=*/true);
  }
  OS << Addend << "\n";
}

template <class ELFT>
static void printRelocHeaderFields(formatted_raw_ostream &OS, unsigned SType) {
  bool IsRela = SType == ELF::SHT_RELA || SType == ELF::SHT_ANDROID_RELA;
  bool IsRelr = SType == ELF::SHT_RELR || SType == ELF::SHT_ANDROID_RELR;
  if (ELFT::Is64Bits)
    OS << "    ";
  else
    OS << " ";
  if (IsRelr && opts::RawRelr)
    OS << "Data  ";
  else
    OS << "Offset";
  if (ELFT::Is64Bits)
    OS << "             Info             Type"
       << "               Symbol's Value  Symbol's Name";
  else
    OS << "     Info    Type                Sym. Value  Symbol's Name";
  if (IsRela)
    OS << " + Addend";
  OS << "\n";
}

template <class ELFT>
void GNUELFDumper<ELFT>::printDynamicRelocHeader(unsigned Type, StringRef Name,
                                                 const DynRegionInfo &Reg) {
  uint64_t Offset = Reg.Addr - this->Obj.base();
  OS << "\n'" << Name.str().c_str() << "' relocation section at offset 0x"
     << utohexstr(Offset, /*LowerCase=*/true) << " contains " << Reg.Size << " bytes:\n";
  printRelocHeaderFields<ELFT>(OS, Type);
}

template <class ELFT>
static bool isRelocationSec(const typename ELFT::Shdr &Sec) {
  return Sec.sh_type == ELF::SHT_REL || Sec.sh_type == ELF::SHT_RELA ||
         Sec.sh_type == ELF::SHT_RELR || Sec.sh_type == ELF::SHT_ANDROID_REL ||
         Sec.sh_type == ELF::SHT_ANDROID_RELA ||
         Sec.sh_type == ELF::SHT_ANDROID_RELR;
}

template <class ELFT> void GNUELFDumper<ELFT>::printRelocations() {
  auto GetEntriesNum = [&](const Elf_Shdr &Sec) -> Expected<size_t> {
    // Android's packed relocation section needs to be unpacked first
    // to get the actual number of entries.
    if (Sec.sh_type == ELF::SHT_ANDROID_REL ||
        Sec.sh_type == ELF::SHT_ANDROID_RELA) {
      Expected<std::vector<typename ELFT::Rela>> RelasOrErr =
          this->Obj.android_relas(Sec);
      if (!RelasOrErr)
        return RelasOrErr.takeError();
      return RelasOrErr->size();
    }

    if (!opts::RawRelr && (Sec.sh_type == ELF::SHT_RELR ||
                           Sec.sh_type == ELF::SHT_ANDROID_RELR)) {
      Expected<Elf_Relr_Range> RelrsOrErr = this->Obj.relrs(Sec);
      if (!RelrsOrErr)
        return RelrsOrErr.takeError();
      return this->Obj.decode_relrs(*RelrsOrErr).size();
    }

    return Sec.getEntityCount();
  };

  bool HasRelocSections = false;
  for (const Elf_Shdr &Sec : cantFail(this->Obj.sections())) {
    if (!isRelocationSec<ELFT>(Sec))
      continue;
    HasRelocSections = true;

    std::string EntriesNum = "<?>";
    if (Expected<size_t> NumOrErr = GetEntriesNum(Sec))
      EntriesNum = std::to_string(*NumOrErr);
    else
      this->reportUniqueWarning("unable to get the number of relocations in " +
                                this->describe(Sec) + ": " +
                                toString(NumOrErr.takeError()));

    uintX_t Offset = Sec.sh_offset;
    StringRef Name = this->getPrintableSectionName(Sec);
    OS << "\nRelocation section '" << Name << "' at offset 0x"
       << utohexstr(Offset, /*LowerCase=*/true) << " contains " << EntriesNum
       << " entries:\n";
    printRelocHeaderFields<ELFT>(OS, Sec.sh_type);
    this->printRelocationsHelper(Sec);
  }
  if (!HasRelocSections)
    OS << "\nThere are no relocations in this file.\n";
}

// Print the offset of a particular section from anyone of the ranges:
// [SHT_LOOS, SHT_HIOS], [SHT_LOPROC, SHT_HIPROC], [SHT_LOUSER, SHT_HIUSER].
// If 'Type' does not fall within any of those ranges, then a string is
// returned as '<unknown>' followed by the type value.
static std::string getSectionTypeOffsetString(unsigned Type) {
  if (Type >= SHT_LOOS && Type <= SHT_HIOS)
    return "LOOS+0x" + utohexstr(Type - SHT_LOOS);
  else if (Type >= SHT_LOPROC && Type <= SHT_HIPROC)
    return "LOPROC+0x" + utohexstr(Type - SHT_LOPROC);
  else if (Type >= SHT_LOUSER && Type <= SHT_HIUSER)
    return "LOUSER+0x" + utohexstr(Type - SHT_LOUSER);
  return "0x" + utohexstr(Type) + ": <unknown>";
}

static std::string getSectionTypeString(unsigned Machine, unsigned Type) {
  StringRef Name = getELFSectionTypeName(Machine, Type);

  // Handle SHT_GNU_* type names.
  if (Name.consume_front("SHT_GNU_")) {
    if (Name == "HASH")
      return "GNU_HASH";
    // E.g. SHT_GNU_verneed -> VERNEED.
    return Name.upper();
  }

  if (Name == "SHT_SYMTAB_SHNDX")
    return "SYMTAB SECTION INDICES";

  if (Name.consume_front("SHT_"))
    return Name.str();
  return getSectionTypeOffsetString(Type);
}

static void printSectionDescription(formatted_raw_ostream &OS,
                                    unsigned EMachine) {
  OS << "Key to Flags:\n";
  OS << "  W (write), A (alloc), X (execute), M (merge), S (strings), I "
        "(info),\n";
  OS << "  L (link order), O (extra OS processing required), G (group), T "
        "(TLS),\n";
  OS << "  C (compressed), x (unknown), o (OS specific), E (exclude),\n";
  OS << "  R (retain)";

  if (EMachine == EM_X86_64)
    OS << ", l (large)";
  else if (EMachine == EM_ARM)
    OS << ", y (purecode)";

  OS << ", p (processor specific)\n";
}

template <class ELFT> void GNUELFDumper<ELFT>::printSectionHeaders() {
  unsigned Bias = ELFT::Is64Bits ? 0 : 8;
  ArrayRef<Elf_Shdr> Sections = cantFail(this->Obj.sections());
  OS << "There are " << to_string(Sections.size())
     << " section headers, starting at offset "
     << "0x" << utohexstr(this->Obj.getHeader().e_shoff, /*LowerCase=*/true) << ":\n\n";
  OS << "Section Headers:\n";
  Field Fields[11] = {
      {"[Nr]", 2},        {"Name", 7},        {"Type", 25},
      {"Address", 41},    {"Off", 58 - Bias}, {"Size", 65 - Bias},
      {"ES", 72 - Bias},  {"Flg", 75 - Bias}, {"Lk", 79 - Bias},
      {"Inf", 82 - Bias}, {"Al", 86 - Bias}};
  for (const Field &F : Fields)
    printField(F);
  OS << "\n";

  StringRef SecStrTable;
  if (Expected<StringRef> SecStrTableOrErr =
          this->Obj.getSectionStringTable(Sections, this->WarningHandler))
    SecStrTable = *SecStrTableOrErr;
  else
    this->reportUniqueWarning(SecStrTableOrErr.takeError());

  size_t SectionIndex = 0;
  for (const Elf_Shdr &Sec : Sections) {
    Fields[0].Str = to_string(SectionIndex);
    if (SecStrTable.empty())
      Fields[1].Str = "<no-strings>";
    else
      Fields[1].Str = std::string(unwrapOrError<StringRef>(
          this->FileName, this->Obj.getSectionName(Sec, SecStrTable)));
    Fields[2].Str =
        getSectionTypeString(this->Obj.getHeader().e_machine, Sec.sh_type);
    Fields[3].Str =
        to_string(format_hex_no_prefix(Sec.sh_addr, ELFT::Is64Bits ? 16 : 8));
    Fields[4].Str = to_string(format_hex_no_prefix(Sec.sh_offset, 6));
    Fields[5].Str = to_string(format_hex_no_prefix(Sec.sh_size, 6));
    Fields[6].Str = to_string(format_hex_no_prefix(Sec.sh_entsize, 2));
    Fields[7].Str = getGNUFlags(this->Obj.getHeader().e_ident[ELF::EI_OSABI],
                                this->Obj.getHeader().e_machine, Sec.sh_flags);
    Fields[8].Str = to_string(Sec.sh_link);
    Fields[9].Str = to_string(Sec.sh_info);
    Fields[10].Str = to_string(Sec.sh_addralign);

    OS.PadToColumn(Fields[0].Column);
    OS << "[" << right_justify(Fields[0].Str, 2) << "]";
    for (int i = 1; i < 7; i++)
      printField(Fields[i]);
    OS.PadToColumn(Fields[7].Column);
    OS << right_justify(Fields[7].Str, 3);
    OS.PadToColumn(Fields[8].Column);
    OS << right_justify(Fields[8].Str, 2);
    OS.PadToColumn(Fields[9].Column);
    OS << right_justify(Fields[9].Str, 3);
    OS.PadToColumn(Fields[10].Column);
    OS << right_justify(Fields[10].Str, 2);
    OS << "\n";
    ++SectionIndex;
  }
  printSectionDescription(OS, this->Obj.getHeader().e_machine);
}

template <class ELFT>
void GNUELFDumper<ELFT>::printSymtabMessage(const Elf_Shdr *Symtab,
                                            size_t Entries,
                                            bool NonVisibilityBitsUsed) const {
  StringRef Name;
  if (Symtab)
    Name = this->getPrintableSectionName(*Symtab);
  if (!Name.empty())
    OS << "\nSymbol table '" << Name << "'";
  else
    OS << "\nSymbol table for image";
  OS << " contains " << Entries << " entries:\n";

  if (ELFT::Is64Bits)
    OS << "   Num:    Value          Size Type    Bind   Vis";
  else
    OS << "   Num:    Value  Size Type    Bind   Vis";

  if (NonVisibilityBitsUsed)
    OS << "             ";
  OS << "       Ndx Name\n";
}

template <class ELFT>
std::string
GNUELFDumper<ELFT>::getSymbolSectionNdx(const Elf_Sym &Symbol,
                                        unsigned SymIndex,
                                        DataRegion<Elf_Word> ShndxTable) const {
  unsigned SectionIndex = Symbol.st_shndx;
  switch (SectionIndex) {
  case ELF::SHN_UNDEF:
    return "UND";
  case ELF::SHN_ABS:
    return "ABS";
  case ELF::SHN_COMMON:
    return "COM";
  case ELF::SHN_XINDEX: {
    Expected<uint32_t> IndexOrErr =
        object::getExtendedSymbolTableIndex<ELFT>(Symbol, SymIndex, ShndxTable);
    if (!IndexOrErr) {
      assert(Symbol.st_shndx == SHN_XINDEX &&
             "getExtendedSymbolTableIndex should only fail due to an invalid "
             "SHT_SYMTAB_SHNDX table/reference");
      this->reportUniqueWarning(IndexOrErr.takeError());
      return "RSV[0xffff]";
    }
    return to_string(format_decimal(*IndexOrErr, 3));
  }
  default:
    // Find if:
    // Processor specific
    if (SectionIndex >= ELF::SHN_LOPROC && SectionIndex <= ELF::SHN_HIPROC)
      return std::string("PRC[0x") +
             to_string(format_hex_no_prefix(SectionIndex, 4)) + "]";
    // OS specific
    if (SectionIndex >= ELF::SHN_LOOS && SectionIndex <= ELF::SHN_HIOS)
      return std::string("OS[0x") +
             to_string(format_hex_no_prefix(SectionIndex, 4)) + "]";
    // Architecture reserved:
    if (SectionIndex >= ELF::SHN_LORESERVE &&
        SectionIndex <= ELF::SHN_HIRESERVE)
      return std::string("RSV[0x") +
             to_string(format_hex_no_prefix(SectionIndex, 4)) + "]";
    // A normal section with an index
    return to_string(format_decimal(SectionIndex, 3));
  }
}

template <class ELFT>
void GNUELFDumper<ELFT>::printSymbol(const Elf_Sym &Symbol, unsigned SymIndex,
                                     DataRegion<Elf_Word> ShndxTable,
                                     Optional<StringRef> StrTable,
                                     bool IsDynamic,
                                     bool NonVisibilityBitsUsed) const {
  unsigned Bias = ELFT::Is64Bits ? 8 : 0;
  Field Fields[8] = {0,         8,         17 + Bias, 23 + Bias,
                     31 + Bias, 38 + Bias, 48 + Bias, 51 + Bias};
  Fields[0].Str = to_string(format_decimal(SymIndex, 6)) + ":";
  Fields[1].Str =
      to_string(format_hex_no_prefix(Symbol.st_value, ELFT::Is64Bits ? 16 : 8));
  Fields[2].Str = to_string(format_decimal(Symbol.st_size, 5));

  unsigned char SymbolType = Symbol.getType();
  if (this->Obj.getHeader().e_machine == ELF::EM_AMDGPU &&
      SymbolType >= ELF::STT_LOOS && SymbolType < ELF::STT_HIOS)
    Fields[3].Str = enumToString(SymbolType, makeArrayRef(AMDGPUSymbolTypes));
  else
    Fields[3].Str = enumToString(SymbolType, makeArrayRef(ElfSymbolTypes));

  Fields[4].Str =
      enumToString(Symbol.getBinding(), makeArrayRef(ElfSymbolBindings));
  Fields[5].Str =
      enumToString(Symbol.getVisibility(), makeArrayRef(ElfSymbolVisibilities));

  if (Symbol.st_other & ~0x3) {
    if (this->Obj.getHeader().e_machine == ELF::EM_AARCH64) {
      uint8_t Other = Symbol.st_other & ~0x3;
      if (Other & STO_AARCH64_VARIANT_PCS) {
        Other &= ~STO_AARCH64_VARIANT_PCS;
        Fields[5].Str += " [VARIANT_PCS";
        if (Other != 0)
          Fields[5].Str.append(" | " + utohexstr(Other, /*LowerCase=*/true));
        Fields[5].Str.append("]");
      }
    } else if (this->Obj.getHeader().e_machine == ELF::EM_RISCV) {
      uint8_t Other = Symbol.st_other & ~0x3;
      if (Other & STO_RISCV_VARIANT_CC) {
        Other &= ~STO_RISCV_VARIANT_CC;
        Fields[5].Str += " [VARIANT_CC";
        if (Other != 0)
          Fields[5].Str.append(" | " + utohexstr(Other, /*LowerCase=*/true));
        Fields[5].Str.append("]");
      }
    } else {
      Fields[5].Str +=
          " [<other: " + to_string(format_hex(Symbol.st_other, 2)) + ">]";
    }
  }

  Fields[6].Column += NonVisibilityBitsUsed ? 13 : 0;
  Fields[6].Str = getSymbolSectionNdx(Symbol, SymIndex, ShndxTable);

  Fields[7].Str = this->getFullSymbolName(Symbol, SymIndex, ShndxTable,
                                          StrTable, IsDynamic);
  for (const Field &Entry : Fields)
    printField(Entry);
  OS << "\n";
}

template <class ELFT>
void GNUELFDumper<ELFT>::printHashedSymbol(const Elf_Sym *Symbol,
                                           unsigned SymIndex,
                                           DataRegion<Elf_Word> ShndxTable,
                                           StringRef StrTable,
                                           uint32_t Bucket) {
  unsigned Bias = ELFT::Is64Bits ? 8 : 0;
  Field Fields[9] = {0,         6,         11,        20 + Bias, 25 + Bias,
                     34 + Bias, 41 + Bias, 49 + Bias, 53 + Bias};
  Fields[0].Str = to_string(format_decimal(SymIndex, 5));
  Fields[1].Str = to_string(format_decimal(Bucket, 3)) + ":";

  Fields[2].Str = to_string(
      format_hex_no_prefix(Symbol->st_value, ELFT::Is64Bits ? 16 : 8));
  Fields[3].Str = to_string(format_decimal(Symbol->st_size, 5));

  unsigned char SymbolType = Symbol->getType();
  if (this->Obj.getHeader().e_machine == ELF::EM_AMDGPU &&
      SymbolType >= ELF::STT_LOOS && SymbolType < ELF::STT_HIOS)
    Fields[4].Str = enumToString(SymbolType, makeArrayRef(AMDGPUSymbolTypes));
  else
    Fields[4].Str = enumToString(SymbolType, makeArrayRef(ElfSymbolTypes));

  Fields[5].Str =
      enumToString(Symbol->getBinding(), makeArrayRef(ElfSymbolBindings));
  Fields[6].Str = enumToString(Symbol->getVisibility(),
                               makeArrayRef(ElfSymbolVisibilities));
  Fields[7].Str = getSymbolSectionNdx(*Symbol, SymIndex, ShndxTable);
  Fields[8].Str =
      this->getFullSymbolName(*Symbol, SymIndex, ShndxTable, StrTable, true);

  for (const Field &Entry : Fields)
    printField(Entry);
  OS << "\n";
}

template <class ELFT>
void GNUELFDumper<ELFT>::printSymbols(bool PrintSymbols,
                                      bool PrintDynamicSymbols) {
  if (!PrintSymbols && !PrintDynamicSymbols)
    return;
  // GNU readelf prints both the .dynsym and .symtab with --symbols.
  this->printSymbolsHelper(true);
  if (PrintSymbols)
    this->printSymbolsHelper(false);
}

template <class ELFT>
void GNUELFDumper<ELFT>::printHashTableSymbols(const Elf_Hash &SysVHash) {
  if (this->DynamicStringTable.empty())
    return;

  if (ELFT::Is64Bits)
    OS << "  Num Buc:    Value          Size   Type   Bind Vis      Ndx Name";
  else
    OS << "  Num Buc:    Value  Size   Type   Bind Vis      Ndx Name";
  OS << "\n";

  Elf_Sym_Range DynSyms = this->dynamic_symbols();
  const Elf_Sym *FirstSym = DynSyms.empty() ? nullptr : &DynSyms[0];
  if (!FirstSym) {
    this->reportUniqueWarning(
        Twine("unable to print symbols for the .hash table: the "
              "dynamic symbol table ") +
        (this->DynSymRegion ? "is empty" : "was not found"));
    return;
  }

  DataRegion<Elf_Word> ShndxTable(
      (const Elf_Word *)this->DynSymTabShndxRegion.Addr, this->Obj.end());
  auto Buckets = SysVHash.buckets();
  auto Chains = SysVHash.chains();
  for (uint32_t Buc = 0; Buc < SysVHash.nbucket; Buc++) {
    if (Buckets[Buc] == ELF::STN_UNDEF)
      continue;
    BitVector Visited(SysVHash.nchain);
    for (uint32_t Ch = Buckets[Buc]; Ch < SysVHash.nchain; Ch = Chains[Ch]) {
      if (Ch == ELF::STN_UNDEF)
        break;

      if (Visited[Ch]) {
        this->reportUniqueWarning(".hash section is invalid: bucket " +
                                  Twine(Ch) +
                                  ": a cycle was detected in the linked chain");
        break;
      }

      printHashedSymbol(FirstSym + Ch, Ch, ShndxTable, this->DynamicStringTable,
                        Buc);
      Visited[Ch] = true;
    }
  }
}

template <class ELFT>
void GNUELFDumper<ELFT>::printGnuHashTableSymbols(const Elf_GnuHash &GnuHash) {
  if (this->DynamicStringTable.empty())
    return;

  Elf_Sym_Range DynSyms = this->dynamic_symbols();
  const Elf_Sym *FirstSym = DynSyms.empty() ? nullptr : &DynSyms[0];
  if (!FirstSym) {
    this->reportUniqueWarning(
        Twine("unable to print symbols for the .gnu.hash table: the "
              "dynamic symbol table ") +
        (this->DynSymRegion ? "is empty" : "was not found"));
    return;
  }

  auto GetSymbol = [&](uint64_t SymIndex,
                       uint64_t SymsTotal) -> const Elf_Sym * {
    if (SymIndex >= SymsTotal) {
      this->reportUniqueWarning(
          "unable to print hashed symbol with index " + Twine(SymIndex) +
          ", which is greater than or equal to the number of dynamic symbols "
          "(" +
          Twine::utohexstr(SymsTotal) + ")");
      return nullptr;
    }
    return FirstSym + SymIndex;
  };

  Expected<ArrayRef<Elf_Word>> ValuesOrErr =
      getGnuHashTableChains<ELFT>(this->DynSymRegion, &GnuHash);
  ArrayRef<Elf_Word> Values;
  if (!ValuesOrErr)
    this->reportUniqueWarning("unable to get hash values for the SHT_GNU_HASH "
                              "section: " +
                              toString(ValuesOrErr.takeError()));
  else
    Values = *ValuesOrErr;

  DataRegion<Elf_Word> ShndxTable(
      (const Elf_Word *)this->DynSymTabShndxRegion.Addr, this->Obj.end());
  ArrayRef<Elf_Word> Buckets = GnuHash.buckets();
  for (uint32_t Buc = 0; Buc < GnuHash.nbuckets; Buc++) {
    if (Buckets[Buc] == ELF::STN_UNDEF)
      continue;
    uint32_t Index = Buckets[Buc];
    // Print whole chain.
    while (true) {
      uint32_t SymIndex = Index++;
      if (const Elf_Sym *Sym = GetSymbol(SymIndex, DynSyms.size()))
        printHashedSymbol(Sym, SymIndex, ShndxTable, this->DynamicStringTable,
                          Buc);
      else
        break;

      if (SymIndex < GnuHash.symndx) {
        this->reportUniqueWarning(
            "unable to read the hash value for symbol with index " +
            Twine(SymIndex) +
            ", which is less than the index of the first hashed symbol (" +
            Twine(GnuHash.symndx) + ")");
        break;
      }

       // Chain ends at symbol with stopper bit.
      if ((Values[SymIndex - GnuHash.symndx] & 1) == 1)
        break;
    }
  }
}

template <class ELFT> void GNUELFDumper<ELFT>::printHashSymbols() {
  if (this->HashTable) {
    OS << "\n Symbol table of .hash for image:\n";
    if (Error E = checkHashTable<ELFT>(*this, this->HashTable))
      this->reportUniqueWarning(std::move(E));
    else
      printHashTableSymbols(*this->HashTable);
  }

  // Try printing the .gnu.hash table.
  if (this->GnuHashTable) {
    OS << "\n Symbol table of .gnu.hash for image:\n";
    if (ELFT::Is64Bits)
      OS << "  Num Buc:    Value          Size   Type   Bind Vis      Ndx Name";
    else
      OS << "  Num Buc:    Value  Size   Type   Bind Vis      Ndx Name";
    OS << "\n";

    if (Error E = checkGNUHashTable<ELFT>(this->Obj, this->GnuHashTable))
      this->reportUniqueWarning(std::move(E));
    else
      printGnuHashTableSymbols(*this->GnuHashTable);
  }
}

template <class ELFT> void GNUELFDumper<ELFT>::printSectionDetails() {
  ArrayRef<Elf_Shdr> Sections = cantFail(this->Obj.sections());
  OS << "There are " << to_string(Sections.size())
     << " section headers, starting at offset "
     << "0x" << utohexstr(this->Obj.getHeader().e_shoff, /*LowerCase=*/true) << ":\n\n";

  OS << "Section Headers:\n";

  auto PrintFields = [&](ArrayRef<Field> V) {
    for (const Field &F : V)
      printField(F);
    OS << "\n";
  };

  PrintFields({{"[Nr]", 2}, {"Name", 7}});

  constexpr bool Is64 = ELFT::Is64Bits;
  PrintFields({{"Type", 7},
               {Is64 ? "Address" : "Addr", 23},
               {"Off", Is64 ? 40 : 32},
               {"Size", Is64 ? 47 : 39},
               {"ES", Is64 ? 54 : 46},
               {"Lk", Is64 ? 59 : 51},
               {"Inf", Is64 ? 62 : 54},
               {"Al", Is64 ? 66 : 57}});
  PrintFields({{"Flags", 7}});

  StringRef SecStrTable;
  if (Expected<StringRef> SecStrTableOrErr =
          this->Obj.getSectionStringTable(Sections, this->WarningHandler))
    SecStrTable = *SecStrTableOrErr;
  else
    this->reportUniqueWarning(SecStrTableOrErr.takeError());

  size_t SectionIndex = 0;
  const unsigned AddrSize = Is64 ? 16 : 8;
  for (const Elf_Shdr &S : Sections) {
    StringRef Name = "<?>";
    if (Expected<StringRef> NameOrErr =
            this->Obj.getSectionName(S, SecStrTable))
      Name = *NameOrErr;
    else
      this->reportUniqueWarning(NameOrErr.takeError());

    OS.PadToColumn(2);
    OS << "[" << right_justify(to_string(SectionIndex), 2) << "]";
    PrintFields({{Name, 7}});
    PrintFields(
        {{getSectionTypeString(this->Obj.getHeader().e_machine, S.sh_type), 7},
         {to_string(format_hex_no_prefix(S.sh_addr, AddrSize)), 23},
         {to_string(format_hex_no_prefix(S.sh_offset, 6)), Is64 ? 39 : 32},
         {to_string(format_hex_no_prefix(S.sh_size, 6)), Is64 ? 47 : 39},
         {to_string(format_hex_no_prefix(S.sh_entsize, 2)), Is64 ? 54 : 46},
         {to_string(S.sh_link), Is64 ? 59 : 51},
         {to_string(S.sh_info), Is64 ? 63 : 55},
         {to_string(S.sh_addralign), Is64 ? 66 : 58}});

    OS.PadToColumn(7);
    OS << "[" << to_string(format_hex_no_prefix(S.sh_flags, AddrSize)) << "]: ";

    DenseMap<unsigned, StringRef> FlagToName = {
        {SHF_WRITE, "WRITE"},           {SHF_ALLOC, "ALLOC"},
        {SHF_EXECINSTR, "EXEC"},        {SHF_MERGE, "MERGE"},
        {SHF_STRINGS, "STRINGS"},       {SHF_INFO_LINK, "INFO LINK"},
        {SHF_LINK_ORDER, "LINK ORDER"}, {SHF_OS_NONCONFORMING, "OS NONCONF"},
        {SHF_GROUP, "GROUP"},           {SHF_TLS, "TLS"},
        {SHF_COMPRESSED, "COMPRESSED"}, {SHF_EXCLUDE, "EXCLUDE"}};

    uint64_t Flags = S.sh_flags;
    uint64_t UnknownFlags = 0;
    ListSeparator LS;
    while (Flags) {
      // Take the least significant bit as a flag.
      uint64_t Flag = Flags & -Flags;
      Flags -= Flag;

      auto It = FlagToName.find(Flag);
      if (It != FlagToName.end())
        OS << LS << It->second;
      else
        UnknownFlags |= Flag;
    }

    auto PrintUnknownFlags = [&](uint64_t Mask, StringRef Name) {
      uint64_t FlagsToPrint = UnknownFlags & Mask;
      if (!FlagsToPrint)
        return;

      OS << LS << Name << " ("
         << to_string(format_hex_no_prefix(FlagsToPrint, AddrSize)) << ")";
      UnknownFlags &= ~Mask;
    };

    PrintUnknownFlags(SHF_MASKOS, "OS");
    PrintUnknownFlags(SHF_MASKPROC, "PROC");
    PrintUnknownFlags(uint64_t(-1), "UNKNOWN");

    OS << "\n";
    ++SectionIndex;
  }
}

static inline std::string printPhdrFlags(unsigned Flag) {
  std::string Str;
  Str = (Flag & PF_R) ? "R" : " ";
  Str += (Flag & PF_W) ? "W" : " ";
  Str += (Flag & PF_X) ? "E" : " ";
  return Str;
}

template <class ELFT>
static bool checkTLSSections(const typename ELFT::Phdr &Phdr,
                             const typename ELFT::Shdr &Sec) {
  if (Sec.sh_flags & ELF::SHF_TLS) {
    // .tbss must only be shown in the PT_TLS segment.
    if (Sec.sh_type == ELF::SHT_NOBITS)
      return Phdr.p_type == ELF::PT_TLS;

    // SHF_TLS sections are only shown in PT_TLS, PT_LOAD or PT_GNU_RELRO
    // segments.
    return (Phdr.p_type == ELF::PT_TLS) || (Phdr.p_type == ELF::PT_LOAD) ||
           (Phdr.p_type == ELF::PT_GNU_RELRO);
  }

  // PT_TLS must only have SHF_TLS sections.
  return Phdr.p_type != ELF::PT_TLS;
}

template <class ELFT>
static bool checkOffsets(const typename ELFT::Phdr &Phdr,
                         const typename ELFT::Shdr &Sec) {
  // SHT_NOBITS sections don't need to have an offset inside the segment.
  if (Sec.sh_type == ELF::SHT_NOBITS)
    return true;

  if (Sec.sh_offset < Phdr.p_offset)
    return false;

  // Only non-empty sections can be at the end of a segment.
  if (Sec.sh_size == 0)
    return (Sec.sh_offset + 1 <= Phdr.p_offset + Phdr.p_filesz);
  return Sec.sh_offset + Sec.sh_size <= Phdr.p_offset + Phdr.p_filesz;
}

// Check that an allocatable section belongs to a virtual address
// space of a segment.
template <class ELFT>
static bool checkVMA(const typename ELFT::Phdr &Phdr,
                     const typename ELFT::Shdr &Sec) {
  if (!(Sec.sh_flags & ELF::SHF_ALLOC))
    return true;

  if (Sec.sh_addr < Phdr.p_vaddr)
    return false;

  bool IsTbss =
      (Sec.sh_type == ELF::SHT_NOBITS) && ((Sec.sh_flags & ELF::SHF_TLS) != 0);
  // .tbss is special, it only has memory in PT_TLS and has NOBITS properties.
  bool IsTbssInNonTLS = IsTbss && Phdr.p_type != ELF::PT_TLS;
  // Only non-empty sections can be at the end of a segment.
  if (Sec.sh_size == 0 || IsTbssInNonTLS)
    return Sec.sh_addr + 1 <= Phdr.p_vaddr + Phdr.p_memsz;
  return Sec.sh_addr + Sec.sh_size <= Phdr.p_vaddr + Phdr.p_memsz;
}

template <class ELFT>
static bool checkPTDynamic(const typename ELFT::Phdr &Phdr,
                           const typename ELFT::Shdr &Sec) {
  if (Phdr.p_type != ELF::PT_DYNAMIC || Phdr.p_memsz == 0 || Sec.sh_size != 0)
    return true;

  // We get here when we have an empty section. Only non-empty sections can be
  // at the start or at the end of PT_DYNAMIC.
  // Is section within the phdr both based on offset and VMA?
  bool CheckOffset = (Sec.sh_type == ELF::SHT_NOBITS) ||
                     (Sec.sh_offset > Phdr.p_offset &&
                      Sec.sh_offset < Phdr.p_offset + Phdr.p_filesz);
  bool CheckVA = !(Sec.sh_flags & ELF::SHF_ALLOC) ||
                 (Sec.sh_addr > Phdr.p_vaddr && Sec.sh_addr < Phdr.p_memsz);
  return CheckOffset && CheckVA;
}

template <class ELFT>
void GNUELFDumper<ELFT>::printProgramHeaders(
    bool PrintProgramHeaders, cl::boolOrDefault PrintSectionMapping) {
  if (PrintProgramHeaders)
    printProgramHeaders();

  // Display the section mapping along with the program headers, unless
  // -section-mapping is explicitly set to false.
  if (PrintSectionMapping != cl::BOU_FALSE)
    printSectionMapping();
}

template <class ELFT> void GNUELFDumper<ELFT>::printProgramHeaders() {
  unsigned Bias = ELFT::Is64Bits ? 8 : 0;
  const Elf_Ehdr &Header = this->Obj.getHeader();
  Field Fields[8] = {2,         17,        26,        37 + Bias,
                     48 + Bias, 56 + Bias, 64 + Bias, 68 + Bias};
  OS << "\nElf file type is "
     << enumToString(Header.e_type, makeArrayRef(ElfObjectFileType)) << "\n"
     << "Entry point " << format_hex(Header.e_entry, 3) << "\n"
     << "There are " << Header.e_phnum << " program headers,"
     << " starting at offset " << Header.e_phoff << "\n\n"
     << "Program Headers:\n";
  if (ELFT::Is64Bits)
    OS << "  Type           Offset   VirtAddr           PhysAddr         "
       << "  FileSiz  MemSiz   Flg Align\n";
  else
    OS << "  Type           Offset   VirtAddr   PhysAddr   FileSiz "
       << "MemSiz  Flg Align\n";

  unsigned Width = ELFT::Is64Bits ? 18 : 10;
  unsigned SizeWidth = ELFT::Is64Bits ? 8 : 7;

  Expected<ArrayRef<Elf_Phdr>> PhdrsOrErr = this->Obj.program_headers();
  if (!PhdrsOrErr) {
    this->reportUniqueWarning("unable to dump program headers: " +
                              toString(PhdrsOrErr.takeError()));
    return;
  }

  for (const Elf_Phdr &Phdr : *PhdrsOrErr) {
    Fields[0].Str = getGNUPtType(Header.e_machine, Phdr.p_type);
    Fields[1].Str = to_string(format_hex(Phdr.p_offset, 8));
    Fields[2].Str = to_string(format_hex(Phdr.p_vaddr, Width));
    Fields[3].Str = to_string(format_hex(Phdr.p_paddr, Width));
    Fields[4].Str = to_string(format_hex(Phdr.p_filesz, SizeWidth));
    Fields[5].Str = to_string(format_hex(Phdr.p_memsz, SizeWidth));
    Fields[6].Str = printPhdrFlags(Phdr.p_flags);
    Fields[7].Str = to_string(format_hex(Phdr.p_align, 1));
    for (const Field &F : Fields)
      printField(F);
    if (Phdr.p_type == ELF::PT_INTERP) {
      OS << "\n";
      auto ReportBadInterp = [&](const Twine &Msg) {
        this->reportUniqueWarning(
            "unable to read program interpreter name at offset 0x" +
            Twine::utohexstr(Phdr.p_offset) + ": " + Msg);
      };

      if (Phdr.p_offset >= this->Obj.getBufSize()) {
        ReportBadInterp("it goes past the end of the file (0x" +
                        Twine::utohexstr(this->Obj.getBufSize()) + ")");
        continue;
      }

      const char *Data =
          reinterpret_cast<const char *>(this->Obj.base()) + Phdr.p_offset;
      size_t MaxSize = this->Obj.getBufSize() - Phdr.p_offset;
      size_t Len = strnlen(Data, MaxSize);
      if (Len == MaxSize) {
        ReportBadInterp("it is not null-terminated");
        continue;
      }

      OS << "      [Requesting program interpreter: ";
      OS << StringRef(Data, Len) << "]";
    }
    OS << "\n";
  }
}

template <class ELFT> void GNUELFDumper<ELFT>::printSectionMapping() {
  OS << "\n Section to Segment mapping:\n  Segment Sections...\n";
  DenseSet<const Elf_Shdr *> BelongsToSegment;
  int Phnum = 0;

  Expected<ArrayRef<Elf_Phdr>> PhdrsOrErr = this->Obj.program_headers();
  if (!PhdrsOrErr) {
    this->reportUniqueWarning(
        "can't read program headers to build section to segment mapping: " +
        toString(PhdrsOrErr.takeError()));
    return;
  }

  for (const Elf_Phdr &Phdr : *PhdrsOrErr) {
    std::string Sections;
    OS << format("   %2.2d     ", Phnum++);
    // Check if each section is in a segment and then print mapping.
    for (const Elf_Shdr &Sec : cantFail(this->Obj.sections())) {
      if (Sec.sh_type == ELF::SHT_NULL)
        continue;

      // readelf additionally makes sure it does not print zero sized sections
      // at end of segments and for PT_DYNAMIC both start and end of section
      // .tbss must only be shown in PT_TLS section.
      if (checkTLSSections<ELFT>(Phdr, Sec) && checkOffsets<ELFT>(Phdr, Sec) &&
          checkVMA<ELFT>(Phdr, Sec) && checkPTDynamic<ELFT>(Phdr, Sec)) {
        Sections +=
            unwrapOrError(this->FileName, this->Obj.getSectionName(Sec)).str() +
            " ";
        BelongsToSegment.insert(&Sec);
      }
    }
    OS << Sections << "\n";
    OS.flush();
  }

  // Display sections that do not belong to a segment.
  std::string Sections;
  for (const Elf_Shdr &Sec : cantFail(this->Obj.sections())) {
    if (BelongsToSegment.find(&Sec) == BelongsToSegment.end())
      Sections +=
          unwrapOrError(this->FileName, this->Obj.getSectionName(Sec)).str() +
          ' ';
  }
  if (!Sections.empty()) {
    OS << "   None  " << Sections << '\n';
    OS.flush();
  }
}

namespace {

template <class ELFT>
RelSymbol<ELFT> getSymbolForReloc(const ELFDumper<ELFT> &Dumper,
                                  const Relocation<ELFT> &Reloc) {
  using Elf_Sym = typename ELFT::Sym;
  auto WarnAndReturn = [&](const Elf_Sym *Sym,
                           const Twine &Reason) -> RelSymbol<ELFT> {
    Dumper.reportUniqueWarning(
        "unable to get name of the dynamic symbol with index " +
        Twine(Reloc.Symbol) + ": " + Reason);
    return {Sym, "<corrupt>"};
  };

  ArrayRef<Elf_Sym> Symbols = Dumper.dynamic_symbols();
  const Elf_Sym *FirstSym = Symbols.begin();
  if (!FirstSym)
    return WarnAndReturn(nullptr, "no dynamic symbol table found");

  // We might have an object without a section header. In this case the size of
  // Symbols is zero, because there is no way to know the size of the dynamic
  // table. We should allow this case and not print a warning.
  if (!Symbols.empty() && Reloc.Symbol >= Symbols.size())
    return WarnAndReturn(
        nullptr,
        "index is greater than or equal to the number of dynamic symbols (" +
            Twine(Symbols.size()) + ")");

  const ELFFile<ELFT> &Obj = Dumper.getElfObject().getELFFile();
  const uint64_t FileSize = Obj.getBufSize();
  const uint64_t SymOffset = ((const uint8_t *)FirstSym - Obj.base()) +
                             (uint64_t)Reloc.Symbol * sizeof(Elf_Sym);
  if (SymOffset + sizeof(Elf_Sym) > FileSize)
    return WarnAndReturn(nullptr, "symbol at 0x" + Twine::utohexstr(SymOffset) +
                                      " goes past the end of the file (0x" +
                                      Twine::utohexstr(FileSize) + ")");

  const Elf_Sym *Sym = FirstSym + Reloc.Symbol;
  Expected<StringRef> ErrOrName = Sym->getName(Dumper.getDynamicStringTable());
  if (!ErrOrName)
    return WarnAndReturn(Sym, toString(ErrOrName.takeError()));

  return {Sym == FirstSym ? nullptr : Sym, maybeDemangle(*ErrOrName)};
}
} // namespace

template <class ELFT>
static size_t getMaxDynamicTagSize(const ELFFile<ELFT> &Obj,
                                   typename ELFT::DynRange Tags) {
  size_t Max = 0;
  for (const typename ELFT::Dyn &Dyn : Tags)
    Max = std::max(Max, Obj.getDynamicTagAsString(Dyn.d_tag).size());
  return Max;
}

template <class ELFT> void GNUELFDumper<ELFT>::printDynamicTable() {
  Elf_Dyn_Range Table = this->dynamic_table();
  if (Table.empty())
    return;

  OS << "Dynamic section at offset "
     << format_hex(reinterpret_cast<const uint8_t *>(this->DynamicTable.Addr) -
                       this->Obj.base(),
                   1)
     << " contains " << Table.size() << " entries:\n";

  // The type name is surrounded with round brackets, hence add 2.
  size_t MaxTagSize = getMaxDynamicTagSize(this->Obj, Table) + 2;
  // The "Name/Value" column should be indented from the "Type" column by N
  // spaces, where N = MaxTagSize - length of "Type" (4) + trailing
  // space (1) = 3.
  OS << "  Tag" + std::string(ELFT::Is64Bits ? 16 : 8, ' ') + "Type"
     << std::string(MaxTagSize - 3, ' ') << "Name/Value\n";

  std::string ValueFmt = " %-" + std::to_string(MaxTagSize) + "s ";
  for (auto Entry : Table) {
    uintX_t Tag = Entry.getTag();
    std::string Type =
        std::string("(") + this->Obj.getDynamicTagAsString(Tag) + ")";
    std::string Value = this->getDynamicEntry(Tag, Entry.getVal());
    OS << "  " << format_hex(Tag, ELFT::Is64Bits ? 18 : 10)
       << format(ValueFmt.c_str(), Type.c_str()) << Value << "\n";
  }
}

template <class ELFT> void GNUELFDumper<ELFT>::printDynamicRelocations() {
  this->printDynamicRelocationsHelper();
}

template <class ELFT>
void ELFDumper<ELFT>::printDynamicReloc(const Relocation<ELFT> &R) {
  printRelRelaReloc(R, getSymbolForReloc(*this, R));
}

template <class ELFT>
void ELFDumper<ELFT>::printRelocationsHelper(const Elf_Shdr &Sec) {
  this->forEachRelocationDo(
      Sec, opts::RawRelr,
      [&](const Relocation<ELFT> &R, unsigned Ndx, const Elf_Shdr &Sec,
          const Elf_Shdr *SymTab) { printReloc(R, Ndx, Sec, SymTab); },
      [&](const Elf_Relr &R) { printRelrReloc(R); });
}

template <class ELFT> void ELFDumper<ELFT>::printDynamicRelocationsHelper() {
  const bool IsMips64EL = this->Obj.isMips64EL();
  if (this->DynRelaRegion.Size > 0) {
    printDynamicRelocHeader(ELF::SHT_RELA, "RELA", this->DynRelaRegion);
    for (const Elf_Rela &Rela :
         this->DynRelaRegion.template getAsArrayRef<Elf_Rela>())
      printDynamicReloc(Relocation<ELFT>(Rela, IsMips64EL));
  }

  if (this->DynRelRegion.Size > 0) {
    printDynamicRelocHeader(ELF::SHT_REL, "REL", this->DynRelRegion);
    for (const Elf_Rel &Rel :
         this->DynRelRegion.template getAsArrayRef<Elf_Rel>())
      printDynamicReloc(Relocation<ELFT>(Rel, IsMips64EL));
  }

  if (this->DynRelrRegion.Size > 0) {
    printDynamicRelocHeader(ELF::SHT_REL, "RELR", this->DynRelrRegion);
    Elf_Relr_Range Relrs =
        this->DynRelrRegion.template getAsArrayRef<Elf_Relr>();
    for (const Elf_Rel &Rel : Obj.decode_relrs(Relrs))
      printDynamicReloc(Relocation<ELFT>(Rel, IsMips64EL));
  }

  if (this->DynPLTRelRegion.Size) {
    if (this->DynPLTRelRegion.EntSize == sizeof(Elf_Rela)) {
      printDynamicRelocHeader(ELF::SHT_RELA, "PLT", this->DynPLTRelRegion);
      for (const Elf_Rela &Rela :
           this->DynPLTRelRegion.template getAsArrayRef<Elf_Rela>())
        printDynamicReloc(Relocation<ELFT>(Rela, IsMips64EL));
    } else {
      printDynamicRelocHeader(ELF::SHT_REL, "PLT", this->DynPLTRelRegion);
      for (const Elf_Rel &Rel :
           this->DynPLTRelRegion.template getAsArrayRef<Elf_Rel>())
        printDynamicReloc(Relocation<ELFT>(Rel, IsMips64EL));
    }
  }
}

template <class ELFT>
void GNUELFDumper<ELFT>::printGNUVersionSectionProlog(
    const typename ELFT::Shdr &Sec, const Twine &Label, unsigned EntriesNum) {
  // Don't inline the SecName, because it might report a warning to stderr and
  // corrupt the output.
  StringRef SecName = this->getPrintableSectionName(Sec);
  OS << Label << " section '" << SecName << "' "
     << "contains " << EntriesNum << " entries:\n";

  StringRef LinkedSecName = "<corrupt>";
  if (Expected<const typename ELFT::Shdr *> LinkedSecOrErr =
          this->Obj.getSection(Sec.sh_link))
    LinkedSecName = this->getPrintableSectionName(**LinkedSecOrErr);
  else
    this->reportUniqueWarning("invalid section linked to " +
                              this->describe(Sec) + ": " +
                              toString(LinkedSecOrErr.takeError()));

  OS << " Addr: " << format_hex_no_prefix(Sec.sh_addr, 16)
     << "  Offset: " << format_hex(Sec.sh_offset, 8)
     << "  Link: " << Sec.sh_link << " (" << LinkedSecName << ")\n";
}

template <class ELFT>
void GNUELFDumper<ELFT>::printVersionSymbolSection(const Elf_Shdr *Sec) {
  if (!Sec)
    return;

  printGNUVersionSectionProlog(*Sec, "Version symbols",
                               Sec->sh_size / sizeof(Elf_Versym));
  Expected<ArrayRef<Elf_Versym>> VerTableOrErr =
      this->getVersionTable(*Sec, /*SymTab=*/nullptr,
                            /*StrTab=*/nullptr, /*SymTabSec=*/nullptr);
  if (!VerTableOrErr) {
    this->reportUniqueWarning(VerTableOrErr.takeError());
    return;
  }

  SmallVector<Optional<VersionEntry>, 0> *VersionMap = nullptr;
  if (Expected<SmallVector<Optional<VersionEntry>, 0> *> MapOrErr =
          this->getVersionMap())
    VersionMap = *MapOrErr;
  else
    this->reportUniqueWarning(MapOrErr.takeError());

  ArrayRef<Elf_Versym> VerTable = *VerTableOrErr;
  std::vector<StringRef> Versions;
  for (size_t I = 0, E = VerTable.size(); I < E; ++I) {
    unsigned Ndx = VerTable[I].vs_index;
    if (Ndx == VER_NDX_LOCAL || Ndx == VER_NDX_GLOBAL) {
      Versions.emplace_back(Ndx == VER_NDX_LOCAL ? "*local*" : "*global*");
      continue;
    }

    if (!VersionMap) {
      Versions.emplace_back("<corrupt>");
      continue;
    }

    bool IsDefault;
    Expected<StringRef> NameOrErr = this->Obj.getSymbolVersionByIndex(
        Ndx, IsDefault, *VersionMap, /*IsSymHidden=*/None);
    if (!NameOrErr) {
      this->reportUniqueWarning("unable to get a version for entry " +
                                Twine(I) + " of " + this->describe(*Sec) +
                                ": " + toString(NameOrErr.takeError()));
      Versions.emplace_back("<corrupt>");
      continue;
    }
    Versions.emplace_back(*NameOrErr);
  }

  // readelf prints 4 entries per line.
  uint64_t Entries = VerTable.size();
  for (uint64_t VersymRow = 0; VersymRow < Entries; VersymRow += 4) {
    OS << "  " << format_hex_no_prefix(VersymRow, 3) << ":";
    for (uint64_t I = 0; (I < 4) && (I + VersymRow) < Entries; ++I) {
      unsigned Ndx = VerTable[VersymRow + I].vs_index;
      OS << format("%4x%c", Ndx & VERSYM_VERSION,
                   Ndx & VERSYM_HIDDEN ? 'h' : ' ');
      OS << left_justify("(" + std::string(Versions[VersymRow + I]) + ")", 13);
    }
    OS << '\n';
  }
  OS << '\n';
}

static std::string versionFlagToString(unsigned Flags) {
  if (Flags == 0)
    return "none";

  std::string Ret;
  auto AddFlag = [&Ret, &Flags](unsigned Flag, StringRef Name) {
    if (!(Flags & Flag))
      return;
    if (!Ret.empty())
      Ret += " | ";
    Ret += Name;
    Flags &= ~Flag;
  };

  AddFlag(VER_FLG_BASE, "BASE");
  AddFlag(VER_FLG_WEAK, "WEAK");
  AddFlag(VER_FLG_INFO, "INFO");
  AddFlag(~0, "<unknown>");
  return Ret;
}

template <class ELFT>
void GNUELFDumper<ELFT>::printVersionDefinitionSection(const Elf_Shdr *Sec) {
  if (!Sec)
    return;

  printGNUVersionSectionProlog(*Sec, "Version definition", Sec->sh_info);

  Expected<std::vector<VerDef>> V = this->Obj.getVersionDefinitions(*Sec);
  if (!V) {
    this->reportUniqueWarning(V.takeError());
    return;
  }

  for (const VerDef &Def : *V) {
    OS << format("  0x%04x: Rev: %u  Flags: %s  Index: %u  Cnt: %u  Name: %s\n",
                 Def.Offset, Def.Version,
                 versionFlagToString(Def.Flags).c_str(), Def.Ndx, Def.Cnt,
                 Def.Name.data());
    unsigned I = 0;
    for (const VerdAux &Aux : Def.AuxV)
      OS << format("  0x%04x: Parent %u: %s\n", Aux.Offset, ++I,
                   Aux.Name.data());
  }

  OS << '\n';
}

template <class ELFT>
void GNUELFDumper<ELFT>::printVersionDependencySection(const Elf_Shdr *Sec) {
  if (!Sec)
    return;

  unsigned VerneedNum = Sec->sh_info;
  printGNUVersionSectionProlog(*Sec, "Version needs", VerneedNum);

  Expected<std::vector<VerNeed>> V =
      this->Obj.getVersionDependencies(*Sec, this->WarningHandler);
  if (!V) {
    this->reportUniqueWarning(V.takeError());
    return;
  }

  for (const VerNeed &VN : *V) {
    OS << format("  0x%04x: Version: %u  File: %s  Cnt: %u\n", VN.Offset,
                 VN.Version, VN.File.data(), VN.Cnt);
    for (const VernAux &Aux : VN.AuxV)
      OS << format("  0x%04x:   Name: %s  Flags: %s  Version: %u\n", Aux.Offset,
                   Aux.Name.data(), versionFlagToString(Aux.Flags).c_str(),
                   Aux.Other);
  }
  OS << '\n';
}

template <class ELFT>
void GNUELFDumper<ELFT>::printHashHistogram(const Elf_Hash &HashTable) {
  size_t NBucket = HashTable.nbucket;
  size_t NChain = HashTable.nchain;
  ArrayRef<Elf_Word> Buckets = HashTable.buckets();
  ArrayRef<Elf_Word> Chains = HashTable.chains();
  size_t TotalSyms = 0;
  // If hash table is correct, we have at least chains with 0 length
  size_t MaxChain = 1;
  size_t CumulativeNonZero = 0;

  if (NChain == 0 || NBucket == 0)
    return;

  std::vector<size_t> ChainLen(NBucket, 0);
  // Go over all buckets and and note chain lengths of each bucket (total
  // unique chain lengths).
  for (size_t B = 0; B < NBucket; B++) {
    BitVector Visited(NChain);
    for (size_t C = Buckets[B]; C < NChain; C = Chains[C]) {
      if (C == ELF::STN_UNDEF)
        break;
      if (Visited[C]) {
        this->reportUniqueWarning(".hash section is invalid: bucket " +
                                  Twine(C) +
                                  ": a cycle was detected in the linked chain");
        break;
      }
      Visited[C] = true;
      if (MaxChain <= ++ChainLen[B])
        MaxChain++;
    }
    TotalSyms += ChainLen[B];
  }

  if (!TotalSyms)
    return;

  std::vector<size_t> Count(MaxChain, 0);
  // Count how long is the chain for each bucket
  for (size_t B = 0; B < NBucket; B++)
    ++Count[ChainLen[B]];
  // Print Number of buckets with each chain lengths and their cumulative
  // coverage of the symbols
  OS << "Histogram for bucket list length (total of " << NBucket
     << " buckets)\n"
     << " Length  Number     % of total  Coverage\n";
  for (size_t I = 0; I < MaxChain; I++) {
    CumulativeNonZero += Count[I] * I;
    OS << format("%7lu  %-10lu (%5.1f%%)     %5.1f%%\n", I, Count[I],
                 (Count[I] * 100.0) / NBucket,
                 (CumulativeNonZero * 100.0) / TotalSyms);
  }
}

template <class ELFT>
void GNUELFDumper<ELFT>::printGnuHashHistogram(
    const Elf_GnuHash &GnuHashTable) {
  Expected<ArrayRef<Elf_Word>> ChainsOrErr =
      getGnuHashTableChains<ELFT>(this->DynSymRegion, &GnuHashTable);
  if (!ChainsOrErr) {
    this->reportUniqueWarning("unable to print the GNU hash table histogram: " +
                              toString(ChainsOrErr.takeError()));
    return;
  }

  ArrayRef<Elf_Word> Chains = *ChainsOrErr;
  size_t Symndx = GnuHashTable.symndx;
  size_t TotalSyms = 0;
  size_t MaxChain = 1;
  size_t CumulativeNonZero = 0;

  size_t NBucket = GnuHashTable.nbuckets;
  if (Chains.empty() || NBucket == 0)
    return;

  ArrayRef<Elf_Word> Buckets = GnuHashTable.buckets();
  std::vector<size_t> ChainLen(NBucket, 0);
  for (size_t B = 0; B < NBucket; B++) {
    if (!Buckets[B])
      continue;
    size_t Len = 1;
    for (size_t C = Buckets[B] - Symndx;
         C < Chains.size() && (Chains[C] & 1) == 0; C++)
      if (MaxChain < ++Len)
        MaxChain++;
    ChainLen[B] = Len;
    TotalSyms += Len;
  }
  MaxChain++;

  if (!TotalSyms)
    return;

  std::vector<size_t> Count(MaxChain, 0);
  for (size_t B = 0; B < NBucket; B++)
    ++Count[ChainLen[B]];
  // Print Number of buckets with each chain lengths and their cumulative
  // coverage of the symbols
  OS << "Histogram for `.gnu.hash' bucket list length (total of " << NBucket
     << " buckets)\n"
     << " Length  Number     % of total  Coverage\n";
  for (size_t I = 0; I < MaxChain; I++) {
    CumulativeNonZero += Count[I] * I;
    OS << format("%7lu  %-10lu (%5.1f%%)     %5.1f%%\n", I, Count[I],
                 (Count[I] * 100.0) / NBucket,
                 (CumulativeNonZero * 100.0) / TotalSyms);
  }
}

// Hash histogram shows statistics of how efficient the hash was for the
// dynamic symbol table. The table shows the number of hash buckets for
// different lengths of chains as an absolute number and percentage of the total
// buckets, and the cumulative coverage of symbols for each set of buckets.
template <class ELFT> void GNUELFDumper<ELFT>::printHashHistograms() {
  // Print histogram for the .hash section.
  if (this->HashTable) {
    if (Error E = checkHashTable<ELFT>(*this, this->HashTable))
      this->reportUniqueWarning(std::move(E));
    else
      printHashHistogram(*this->HashTable);
  }

  // Print histogram for the .gnu.hash section.
  if (this->GnuHashTable) {
    if (Error E = checkGNUHashTable<ELFT>(this->Obj, this->GnuHashTable))
      this->reportUniqueWarning(std::move(E));
    else
      printGnuHashHistogram(*this->GnuHashTable);
  }
}

template <class ELFT> void GNUELFDumper<ELFT>::printCGProfile() {
  OS << "GNUStyle::printCGProfile not implemented\n";
}

template <class ELFT> void GNUELFDumper<ELFT>::printBBAddrMaps() {
  OS << "GNUStyle::printBBAddrMaps not implemented\n";
}

static Expected<std::vector<uint64_t>> toULEB128Array(ArrayRef<uint8_t> Data) {
  std::vector<uint64_t> Ret;
  const uint8_t *Cur = Data.begin();
  const uint8_t *End = Data.end();
  while (Cur != End) {
    unsigned Size;
    const char *Err;
    Ret.push_back(decodeULEB128(Cur, &Size, End, &Err));
    if (Err)
      return createError(Err);
    Cur += Size;
  }
  return Ret;
}

template <class ELFT>
static Expected<std::vector<uint64_t>>
decodeAddrsigSection(const ELFFile<ELFT> &Obj, const typename ELFT::Shdr &Sec) {
  Expected<ArrayRef<uint8_t>> ContentsOrErr = Obj.getSectionContents(Sec);
  if (!ContentsOrErr)
    return ContentsOrErr.takeError();

  if (Expected<std::vector<uint64_t>> SymsOrErr =
          toULEB128Array(*ContentsOrErr))
    return *SymsOrErr;
  else
    return createError("unable to decode " + describe(Obj, Sec) + ": " +
                       toString(SymsOrErr.takeError()));
}

template <class ELFT> void GNUELFDumper<ELFT>::printAddrsig() {
  if (!this->DotAddrsigSec)
    return;

  Expected<std::vector<uint64_t>> SymsOrErr =
      decodeAddrsigSection(this->Obj, *this->DotAddrsigSec);
  if (!SymsOrErr) {
    this->reportUniqueWarning(SymsOrErr.takeError());
    return;
  }

  StringRef Name = this->getPrintableSectionName(*this->DotAddrsigSec);
  OS << "\nAddress-significant symbols section '" << Name << "'"
     << " contains " << SymsOrErr->size() << " entries:\n";
  OS << "   Num: Name\n";

  Field Fields[2] = {0, 8};
  size_t SymIndex = 0;
  for (uint64_t Sym : *SymsOrErr) {
    Fields[0].Str = to_string(format_decimal(++SymIndex, 6)) + ":";
    Fields[1].Str = this->getStaticSymbolName(Sym);
    for (const Field &Entry : Fields)
      printField(Entry);
    OS << "\n";
  }
}

template <typename ELFT>
static std::string getGNUProperty(uint32_t Type, uint32_t DataSize,
                                  ArrayRef<uint8_t> Data) {
  std::string str;
  raw_string_ostream OS(str);
  uint32_t PrData;
  auto DumpBit = [&](uint32_t Flag, StringRef Name) {
    if (PrData & Flag) {
      PrData &= ~Flag;
      OS << Name;
      if (PrData)
        OS << ", ";
    }
  };

  switch (Type) {
  default:
    OS << format("<application-specific type 0x%x>", Type);
    return OS.str();
  case GNU_PROPERTY_STACK_SIZE: {
    OS << "stack size: ";
    if (DataSize == sizeof(typename ELFT::uint))
      OS << formatv("{0:x}",
                    (uint64_t)(*(const typename ELFT::Addr *)Data.data()));
    else
      OS << format("<corrupt length: 0x%x>", DataSize);
    return OS.str();
  }
  case GNU_PROPERTY_NO_COPY_ON_PROTECTED:
    OS << "no copy on protected";
    if (DataSize)
      OS << format(" <corrupt length: 0x%x>", DataSize);
    return OS.str();
  case GNU_PROPERTY_AARCH64_FEATURE_1_AND:
  case GNU_PROPERTY_X86_FEATURE_1_AND:
    OS << ((Type == GNU_PROPERTY_AARCH64_FEATURE_1_AND) ? "aarch64 feature: "
                                                        : "x86 feature: ");
    if (DataSize != 4) {
      OS << format("<corrupt length: 0x%x>", DataSize);
      return OS.str();
    }
    PrData = support::endian::read32<ELFT::TargetEndianness>(Data.data());
    if (PrData == 0) {
      OS << "<None>";
      return OS.str();
    }
    if (Type == GNU_PROPERTY_AARCH64_FEATURE_1_AND) {
      DumpBit(GNU_PROPERTY_AARCH64_FEATURE_1_BTI, "BTI");
      DumpBit(GNU_PROPERTY_AARCH64_FEATURE_1_PAC, "PAC");
    } else {
      DumpBit(GNU_PROPERTY_X86_FEATURE_1_IBT, "IBT");
      DumpBit(GNU_PROPERTY_X86_FEATURE_1_SHSTK, "SHSTK");
    }
    if (PrData)
      OS << format("<unknown flags: 0x%x>", PrData);
    return OS.str();
  case GNU_PROPERTY_X86_FEATURE_2_NEEDED:
  case GNU_PROPERTY_X86_FEATURE_2_USED:
    OS << "x86 feature "
       << (Type == GNU_PROPERTY_X86_FEATURE_2_NEEDED ? "needed: " : "used: ");
    if (DataSize != 4) {
      OS << format("<corrupt length: 0x%x>", DataSize);
      return OS.str();
    }
    PrData = support::endian::read32<ELFT::TargetEndianness>(Data.data());
    if (PrData == 0) {
      OS << "<None>";
      return OS.str();
    }
    DumpBit(GNU_PROPERTY_X86_FEATURE_2_X86, "x86");
    DumpBit(GNU_PROPERTY_X86_FEATURE_2_X87, "x87");
    DumpBit(GNU_PROPERTY_X86_FEATURE_2_MMX, "MMX");
    DumpBit(GNU_PROPERTY_X86_FEATURE_2_XMM, "XMM");
    DumpBit(GNU_PROPERTY_X86_FEATURE_2_YMM, "YMM");
    DumpBit(GNU_PROPERTY_X86_FEATURE_2_ZMM, "ZMM");
    DumpBit(GNU_PROPERTY_X86_FEATURE_2_FXSR, "FXSR");
    DumpBit(GNU_PROPERTY_X86_FEATURE_2_XSAVE, "XSAVE");
    DumpBit(GNU_PROPERTY_X86_FEATURE_2_XSAVEOPT, "XSAVEOPT");
    DumpBit(GNU_PROPERTY_X86_FEATURE_2_XSAVEC, "XSAVEC");
    if (PrData)
      OS << format("<unknown flags: 0x%x>", PrData);
    return OS.str();
  case GNU_PROPERTY_X86_ISA_1_NEEDED:
  case GNU_PROPERTY_X86_ISA_1_USED:
    OS << "x86 ISA "
       << (Type == GNU_PROPERTY_X86_ISA_1_NEEDED ? "needed: " : "used: ");
    if (DataSize != 4) {
      OS << format("<corrupt length: 0x%x>", DataSize);
      return OS.str();
    }
    PrData = support::endian::read32<ELFT::TargetEndianness>(Data.data());
    if (PrData == 0) {
      OS << "<None>";
      return OS.str();
    }
    DumpBit(GNU_PROPERTY_X86_ISA_1_BASELINE, "x86-64-baseline");
    DumpBit(GNU_PROPERTY_X86_ISA_1_V2, "x86-64-v2");
    DumpBit(GNU_PROPERTY_X86_ISA_1_V3, "x86-64-v3");
    DumpBit(GNU_PROPERTY_X86_ISA_1_V4, "x86-64-v4");
    if (PrData)
      OS << format("<unknown flags: 0x%x>", PrData);
    return OS.str();
  }
}

template <typename ELFT>
static SmallVector<std::string, 4> getGNUPropertyList(ArrayRef<uint8_t> Arr) {
  using Elf_Word = typename ELFT::Word;

  SmallVector<std::string, 4> Properties;
  while (Arr.size() >= 8) {
    uint32_t Type = *reinterpret_cast<const Elf_Word *>(Arr.data());
    uint32_t DataSize = *reinterpret_cast<const Elf_Word *>(Arr.data() + 4);
    Arr = Arr.drop_front(8);

    // Take padding size into account if present.
    uint64_t PaddedSize = alignTo(DataSize, sizeof(typename ELFT::uint));
    std::string str;
    raw_string_ostream OS(str);
    if (Arr.size() < PaddedSize) {
      OS << format("<corrupt type (0x%x) datasz: 0x%x>", Type, DataSize);
      Properties.push_back(OS.str());
      break;
    }
    Properties.push_back(
        getGNUProperty<ELFT>(Type, DataSize, Arr.take_front(PaddedSize)));
    Arr = Arr.drop_front(PaddedSize);
  }

  if (!Arr.empty())
    Properties.push_back("<corrupted GNU_PROPERTY_TYPE_0>");

  return Properties;
}

struct GNUAbiTag {
  std::string OSName;
  std::string ABI;
  bool IsValid;
};

template <typename ELFT> static GNUAbiTag getGNUAbiTag(ArrayRef<uint8_t> Desc) {
  typedef typename ELFT::Word Elf_Word;

  ArrayRef<Elf_Word> Words(reinterpret_cast<const Elf_Word *>(Desc.begin()),
                           reinterpret_cast<const Elf_Word *>(Desc.end()));

  if (Words.size() < 4)
    return {"", "", /*IsValid=*/false};

  static const char *OSNames[] = {
      "Linux", "Hurd", "Solaris", "FreeBSD", "NetBSD", "Syllable", "NaCl",
  };
  StringRef OSName = "Unknown";
  if (Words[0] < array_lengthof(OSNames))
    OSName = OSNames[Words[0]];
  uint32_t Major = Words[1], Minor = Words[2], Patch = Words[3];
  std::string str;
  raw_string_ostream ABI(str);
  ABI << Major << "." << Minor << "." << Patch;
  return {std::string(OSName), ABI.str(), /*IsValid=*/true};
}

static std::string getGNUBuildId(ArrayRef<uint8_t> Desc) {
  std::string str;
  raw_string_ostream OS(str);
  for (uint8_t B : Desc)
    OS << format_hex_no_prefix(B, 2);
  return OS.str();
}

static StringRef getDescAsStringRef(ArrayRef<uint8_t> Desc) {
  return StringRef(reinterpret_cast<const char *>(Desc.data()), Desc.size());
}

template <typename ELFT>
static bool printGNUNote(raw_ostream &OS, uint32_t NoteType,
                         ArrayRef<uint8_t> Desc) {
  // Return true if we were able to pretty-print the note, false otherwise.
  switch (NoteType) {
  default:
    return false;
  case ELF::NT_GNU_ABI_TAG: {
    const GNUAbiTag &AbiTag = getGNUAbiTag<ELFT>(Desc);
    if (!AbiTag.IsValid)
      OS << "    <corrupt GNU_ABI_TAG>";
    else
      OS << "    OS: " << AbiTag.OSName << ", ABI: " << AbiTag.ABI;
    break;
  }
  case ELF::NT_GNU_BUILD_ID: {
    OS << "    Build ID: " << getGNUBuildId(Desc);
    break;
  }
  case ELF::NT_GNU_GOLD_VERSION:
    OS << "    Version: " << getDescAsStringRef(Desc);
    break;
  case ELF::NT_GNU_PROPERTY_TYPE_0:
    OS << "    Properties:";
    for (const std::string &Property : getGNUPropertyList<ELFT>(Desc))
      OS << "    " << Property << "\n";
    break;
  }
  OS << '\n';
  return true;
}

using AndroidNoteProperties = std::vector<std::pair<StringRef, std::string>>;
static AndroidNoteProperties getAndroidNoteProperties(uint32_t NoteType,
                                                      ArrayRef<uint8_t> Desc) {
  AndroidNoteProperties Props;
  switch (NoteType) {
  case ELF::NT_ANDROID_TYPE_MEMTAG:
    if (Desc.empty()) {
      Props.emplace_back("Invalid .note.android.memtag", "");
      return Props;
    }

    switch (Desc[0] & NT_MEMTAG_LEVEL_MASK) {
    case NT_MEMTAG_LEVEL_NONE:
      Props.emplace_back("Tagging Mode", "NONE");
      break;
    case NT_MEMTAG_LEVEL_ASYNC:
      Props.emplace_back("Tagging Mode", "ASYNC");
      break;
    case NT_MEMTAG_LEVEL_SYNC:
      Props.emplace_back("Tagging Mode", "SYNC");
      break;
    default:
      Props.emplace_back(
          "Tagging Mode",
          ("Unknown (" + Twine::utohexstr(Desc[0] & NT_MEMTAG_LEVEL_MASK) + ")")
              .str());
      break;
    }
    Props.emplace_back("Heap",
                       (Desc[0] & NT_MEMTAG_HEAP) ? "Enabled" : "Disabled");
    Props.emplace_back("Stack",
                       (Desc[0] & NT_MEMTAG_STACK) ? "Enabled" : "Disabled");
    break;
  default:
    return Props;
  }
  return Props;
}

static bool printAndroidNote(raw_ostream &OS, uint32_t NoteType,
                             ArrayRef<uint8_t> Desc) {
  // Return true if we were able to pretty-print the note, false otherwise.
  AndroidNoteProperties Props = getAndroidNoteProperties(NoteType, Desc);
  if (Props.empty())
    return false;
  for (const auto &KV : Props)
    OS << "    " << KV.first << ": " << KV.second << '\n';
  OS << '\n';
  return true;
}

template <typename ELFT>
static bool printLLVMOMPOFFLOADNote(raw_ostream &OS, uint32_t NoteType,
                                    ArrayRef<uint8_t> Desc) {
  switch (NoteType) {
  default:
    return false;
  case ELF::NT_LLVM_OPENMP_OFFLOAD_VERSION:
    OS << "    Version: " << getDescAsStringRef(Desc);
    break;
  case ELF::NT_LLVM_OPENMP_OFFLOAD_PRODUCER:
    OS << "    Producer: " << getDescAsStringRef(Desc);
    break;
  case ELF::NT_LLVM_OPENMP_OFFLOAD_PRODUCER_VERSION:
    OS << "    Producer version: " << getDescAsStringRef(Desc);
    break;
  }
  OS << '\n';
  return true;
}

const EnumEntry<unsigned> FreeBSDFeatureCtlFlags[] = {
    {"ASLR_DISABLE", NT_FREEBSD_FCTL_ASLR_DISABLE},
    {"PROTMAX_DISABLE", NT_FREEBSD_FCTL_PROTMAX_DISABLE},
    {"STKGAP_DISABLE", NT_FREEBSD_FCTL_STKGAP_DISABLE},
    {"WXNEEDED", NT_FREEBSD_FCTL_WXNEEDED},
    {"LA48", NT_FREEBSD_FCTL_LA48},
    {"ASG_DISABLE", NT_FREEBSD_FCTL_ASG_DISABLE},
};

struct FreeBSDNote {
  std::string Type;
  std::string Value;
};

template <typename ELFT>
static Optional<FreeBSDNote>
getFreeBSDNote(uint32_t NoteType, ArrayRef<uint8_t> Desc, bool IsCore) {
  if (IsCore)
    return None; // No pretty-printing yet.
  switch (NoteType) {
  case ELF::NT_FREEBSD_ABI_TAG:
    if (Desc.size() != 4)
      return None;
    return FreeBSDNote{
        "ABI tag",
        utostr(support::endian::read32<ELFT::TargetEndianness>(Desc.data()))};
  case ELF::NT_FREEBSD_ARCH_TAG:
    return FreeBSDNote{"Arch tag", toStringRef(Desc).str()};
  case ELF::NT_FREEBSD_FEATURE_CTL: {
    if (Desc.size() != 4)
      return None;
    unsigned Value =
        support::endian::read32<ELFT::TargetEndianness>(Desc.data());
    std::string FlagsStr;
    raw_string_ostream OS(FlagsStr);
    printFlags(Value, makeArrayRef(FreeBSDFeatureCtlFlags), OS);
    if (OS.str().empty())
      OS << "0x" << utohexstr(Value);
    else
      OS << "(0x" << utohexstr(Value) << ")";
    return FreeBSDNote{"Feature flags", OS.str()};
  }
  default:
    return None;
  }
}

struct AMDNote {
  std::string Type;
  std::string Value;
};

template <typename ELFT>
static AMDNote getAMDNote(uint32_t NoteType, ArrayRef<uint8_t> Desc) {
  switch (NoteType) {
  default:
    return {"", ""};
  case ELF::NT_AMD_HSA_CODE_OBJECT_VERSION: {
    struct CodeObjectVersion {
      uint32_t MajorVersion;
      uint32_t MinorVersion;
    };
    if (Desc.size() != sizeof(CodeObjectVersion))
      return {"AMD HSA Code Object Version",
              "Invalid AMD HSA Code Object Version"};
    std::string VersionString;
    raw_string_ostream StrOS(VersionString);
    auto Version = reinterpret_cast<const CodeObjectVersion *>(Desc.data());
    StrOS << "[Major: " << Version->MajorVersion
          << ", Minor: " << Version->MinorVersion << "]";
    return {"AMD HSA Code Object Version", VersionString};
  }
  case ELF::NT_AMD_HSA_HSAIL: {
    struct HSAILProperties {
      uint32_t HSAILMajorVersion;
      uint32_t HSAILMinorVersion;
      uint8_t Profile;
      uint8_t MachineModel;
      uint8_t DefaultFloatRound;
    };
    if (Desc.size() != sizeof(HSAILProperties))
      return {"AMD HSA HSAIL Properties", "Invalid AMD HSA HSAIL Properties"};
    auto Properties = reinterpret_cast<const HSAILProperties *>(Desc.data());
    std::string HSAILPropetiesString;
    raw_string_ostream StrOS(HSAILPropetiesString);
    StrOS << "[HSAIL Major: " << Properties->HSAILMajorVersion
          << ", HSAIL Minor: " << Properties->HSAILMinorVersion
          << ", Profile: " << uint32_t(Properties->Profile)
          << ", Machine Model: " << uint32_t(Properties->MachineModel)
          << ", Default Float Round: "
          << uint32_t(Properties->DefaultFloatRound) << "]";
    return {"AMD HSA HSAIL Properties", HSAILPropetiesString};
  }
  case ELF::NT_AMD_HSA_ISA_VERSION: {
    struct IsaVersion {
      uint16_t VendorNameSize;
      uint16_t ArchitectureNameSize;
      uint32_t Major;
      uint32_t Minor;
      uint32_t Stepping;
    };
    if (Desc.size() < sizeof(IsaVersion))
      return {"AMD HSA ISA Version", "Invalid AMD HSA ISA Version"};
    auto Isa = reinterpret_cast<const IsaVersion *>(Desc.data());
    if (Desc.size() < sizeof(IsaVersion) +
                          Isa->VendorNameSize + Isa->ArchitectureNameSize ||
        Isa->VendorNameSize == 0 || Isa->ArchitectureNameSize == 0)
      return {"AMD HSA ISA Version", "Invalid AMD HSA ISA Version"};
    std::string IsaString;
    raw_string_ostream StrOS(IsaString);
    StrOS << "[Vendor: "
          << StringRef((const char*)Desc.data() + sizeof(IsaVersion), Isa->VendorNameSize - 1)
          << ", Architecture: "
          << StringRef((const char*)Desc.data() + sizeof(IsaVersion) + Isa->VendorNameSize,
                       Isa->ArchitectureNameSize - 1)
          << ", Major: " << Isa->Major << ", Minor: " << Isa->Minor
          << ", Stepping: " << Isa->Stepping << "]";
    return {"AMD HSA ISA Version", IsaString};
  }
  case ELF::NT_AMD_HSA_METADATA: {
    if (Desc.size() == 0)
      return {"AMD HSA Metadata", ""};
    return {
        "AMD HSA Metadata",
        std::string(reinterpret_cast<const char *>(Desc.data()), Desc.size() - 1)};
  }
  case ELF::NT_AMD_HSA_ISA_NAME: {
    if (Desc.size() == 0)
      return {"AMD HSA ISA Name", ""};
    return {
        "AMD HSA ISA Name",
        std::string(reinterpret_cast<const char *>(Desc.data()), Desc.size())};
  }
  case ELF::NT_AMD_PAL_METADATA: {
    struct PALMetadata {
      uint32_t Key;
      uint32_t Value;
    };
    if (Desc.size() % sizeof(PALMetadata) != 0)
      return {"AMD PAL Metadata", "Invalid AMD PAL Metadata"};
    auto Isa = reinterpret_cast<const PALMetadata *>(Desc.data());
    std::string MetadataString;
    raw_string_ostream StrOS(MetadataString);
    for (size_t I = 0, E = Desc.size() / sizeof(PALMetadata); I < E; ++I) {
      StrOS << "[" << Isa[I].Key << ": " << Isa[I].Value << "]";
    }
    return {"AMD PAL Metadata", MetadataString};
  }
  }
}

struct AMDGPUNote {
  std::string Type;
  std::string Value;
};

template <typename ELFT>
static AMDGPUNote getAMDGPUNote(uint32_t NoteType, ArrayRef<uint8_t> Desc) {
  switch (NoteType) {
  default:
    return {"", ""};
  case ELF::NT_AMDGPU_METADATA: {
    StringRef MsgPackString =
        StringRef(reinterpret_cast<const char *>(Desc.data()), Desc.size());
    msgpack::Document MsgPackDoc;
    if (!MsgPackDoc.readFromBlob(MsgPackString, /*Multi=*/false))
      return {"", ""};

    AMDGPU::HSAMD::V3::MetadataVerifier Verifier(true);
    std::string MetadataString;
    if (!Verifier.verify(MsgPackDoc.getRoot()))
      MetadataString = "Invalid AMDGPU Metadata\n";

    raw_string_ostream StrOS(MetadataString);
    if (MsgPackDoc.getRoot().isScalar()) {
      // TODO: passing a scalar root to toYAML() asserts:
      // (PolymorphicTraits<T>::getKind(Val) != NodeKind::Scalar &&
      //    "plain scalar documents are not supported")
      // To avoid this crash we print the raw data instead.
      return {"", ""};
    }
    MsgPackDoc.toYAML(StrOS);
    return {"AMDGPU Metadata", StrOS.str()};
  }
  }
}

struct CoreFileMapping {
  uint64_t Start, End, Offset;
  StringRef Filename;
};

struct CoreNote {
  uint64_t PageSize;
  std::vector<CoreFileMapping> Mappings;
};

static Expected<CoreNote> readCoreNote(DataExtractor Desc) {
  // Expected format of the NT_FILE note description:
  // 1. # of file mappings (call it N)
  // 2. Page size
  // 3. N (start, end, offset) triples
  // 4. N packed filenames (null delimited)
  // Each field is an Elf_Addr, except for filenames which are char* strings.

  CoreNote Ret;
  const int Bytes = Desc.getAddressSize();

  if (!Desc.isValidOffsetForAddress(2))
    return createError("the note of size 0x" + Twine::utohexstr(Desc.size()) +
                       " is too short, expected at least 0x" +
                       Twine::utohexstr(Bytes * 2));
  if (Desc.getData().back() != 0)
    return createError("the note is not NUL terminated");

  uint64_t DescOffset = 0;
  uint64_t FileCount = Desc.getAddress(&DescOffset);
  Ret.PageSize = Desc.getAddress(&DescOffset);

  if (!Desc.isValidOffsetForAddress(3 * FileCount * Bytes))
    return createError("unable to read file mappings (found " +
                       Twine(FileCount) + "): the note of size 0x" +
                       Twine::utohexstr(Desc.size()) + " is too short");

  uint64_t FilenamesOffset = 0;
  DataExtractor Filenames(
      Desc.getData().drop_front(DescOffset + 3 * FileCount * Bytes),
      Desc.isLittleEndian(), Desc.getAddressSize());

  Ret.Mappings.resize(FileCount);
  size_t I = 0;
  for (CoreFileMapping &Mapping : Ret.Mappings) {
    ++I;
    if (!Filenames.isValidOffsetForDataOfSize(FilenamesOffset, 1))
      return createError(
          "unable to read the file name for the mapping with index " +
          Twine(I) + ": the note of size 0x" + Twine::utohexstr(Desc.size()) +
          " is truncated");
    Mapping.Start = Desc.getAddress(&DescOffset);
    Mapping.End = Desc.getAddress(&DescOffset);
    Mapping.Offset = Desc.getAddress(&DescOffset);
    Mapping.Filename = Filenames.getCStrRef(&FilenamesOffset);
  }

  return Ret;
}

template <typename ELFT>
static void printCoreNote(raw_ostream &OS, const CoreNote &Note) {
  // Length of "0x<address>" string.
  const int FieldWidth = ELFT::Is64Bits ? 18 : 10;

  OS << "    Page size: " << format_decimal(Note.PageSize, 0) << '\n';
  OS << "    " << right_justify("Start", FieldWidth) << "  "
     << right_justify("End", FieldWidth) << "  "
     << right_justify("Page Offset", FieldWidth) << '\n';
  for (const CoreFileMapping &Mapping : Note.Mappings) {
    OS << "    " << format_hex(Mapping.Start, FieldWidth) << "  "
       << format_hex(Mapping.End, FieldWidth) << "  "
       << format_hex(Mapping.Offset, FieldWidth) << "\n        "
       << Mapping.Filename << '\n';
  }
}

const NoteType GenericNoteTypes[] = {
    {ELF::NT_VERSION, "NT_VERSION (version)"},
    {ELF::NT_ARCH, "NT_ARCH (architecture)"},
    {ELF::NT_GNU_BUILD_ATTRIBUTE_OPEN, "OPEN"},
    {ELF::NT_GNU_BUILD_ATTRIBUTE_FUNC, "func"},
};

const NoteType GNUNoteTypes[] = {
    {ELF::NT_GNU_ABI_TAG, "NT_GNU_ABI_TAG (ABI version tag)"},
    {ELF::NT_GNU_HWCAP, "NT_GNU_HWCAP (DSO-supplied software HWCAP info)"},
    {ELF::NT_GNU_BUILD_ID, "NT_GNU_BUILD_ID (unique build ID bitstring)"},
    {ELF::NT_GNU_GOLD_VERSION, "NT_GNU_GOLD_VERSION (gold version)"},
    {ELF::NT_GNU_PROPERTY_TYPE_0, "NT_GNU_PROPERTY_TYPE_0 (property note)"},
};

const NoteType FreeBSDCoreNoteTypes[] = {
    {ELF::NT_FREEBSD_THRMISC, "NT_THRMISC (thrmisc structure)"},
    {ELF::NT_FREEBSD_PROCSTAT_PROC, "NT_PROCSTAT_PROC (proc data)"},
    {ELF::NT_FREEBSD_PROCSTAT_FILES, "NT_PROCSTAT_FILES (files data)"},
    {ELF::NT_FREEBSD_PROCSTAT_VMMAP, "NT_PROCSTAT_VMMAP (vmmap data)"},
    {ELF::NT_FREEBSD_PROCSTAT_GROUPS, "NT_PROCSTAT_GROUPS (groups data)"},
    {ELF::NT_FREEBSD_PROCSTAT_UMASK, "NT_PROCSTAT_UMASK (umask data)"},
    {ELF::NT_FREEBSD_PROCSTAT_RLIMIT, "NT_PROCSTAT_RLIMIT (rlimit data)"},
    {ELF::NT_FREEBSD_PROCSTAT_OSREL, "NT_PROCSTAT_OSREL (osreldate data)"},
    {ELF::NT_FREEBSD_PROCSTAT_PSSTRINGS,
     "NT_PROCSTAT_PSSTRINGS (ps_strings data)"},
    {ELF::NT_FREEBSD_PROCSTAT_AUXV, "NT_PROCSTAT_AUXV (auxv data)"},
};

const NoteType FreeBSDNoteTypes[] = {
    {ELF::NT_FREEBSD_ABI_TAG, "NT_FREEBSD_ABI_TAG (ABI version tag)"},
    {ELF::NT_FREEBSD_NOINIT_TAG, "NT_FREEBSD_NOINIT_TAG (no .init tag)"},
    {ELF::NT_FREEBSD_ARCH_TAG, "NT_FREEBSD_ARCH_TAG (architecture tag)"},
    {ELF::NT_FREEBSD_FEATURE_CTL,
     "NT_FREEBSD_FEATURE_CTL (FreeBSD feature control)"},
};

const NoteType NetBSDCoreNoteTypes[] = {
    {ELF::NT_NETBSDCORE_PROCINFO,
     "NT_NETBSDCORE_PROCINFO (procinfo structure)"},
    {ELF::NT_NETBSDCORE_AUXV, "NT_NETBSDCORE_AUXV (ELF auxiliary vector data)"},
    {ELF::NT_NETBSDCORE_LWPSTATUS, "PT_LWPSTATUS (ptrace_lwpstatus structure)"},
};

const NoteType OpenBSDCoreNoteTypes[] = {
    {ELF::NT_OPENBSD_PROCINFO, "NT_OPENBSD_PROCINFO (procinfo structure)"},
    {ELF::NT_OPENBSD_AUXV, "NT_OPENBSD_AUXV (ELF auxiliary vector data)"},
    {ELF::NT_OPENBSD_REGS, "NT_OPENBSD_REGS (regular registers)"},
    {ELF::NT_OPENBSD_FPREGS, "NT_OPENBSD_FPREGS (floating point registers)"},
    {ELF::NT_OPENBSD_WCOOKIE, "NT_OPENBSD_WCOOKIE (window cookie)"},
};

const NoteType AMDNoteTypes[] = {
    {ELF::NT_AMD_HSA_CODE_OBJECT_VERSION,
     "NT_AMD_HSA_CODE_OBJECT_VERSION (AMD HSA Code Object Version)"},
    {ELF::NT_AMD_HSA_HSAIL, "NT_AMD_HSA_HSAIL (AMD HSA HSAIL Properties)"},
    {ELF::NT_AMD_HSA_ISA_VERSION, "NT_AMD_HSA_ISA_VERSION (AMD HSA ISA Version)"},
    {ELF::NT_AMD_HSA_METADATA, "NT_AMD_HSA_METADATA (AMD HSA Metadata)"},
    {ELF::NT_AMD_HSA_ISA_NAME, "NT_AMD_HSA_ISA_NAME (AMD HSA ISA Name)"},
    {ELF::NT_AMD_PAL_METADATA, "NT_AMD_PAL_METADATA (AMD PAL Metadata)"},
};

const NoteType AMDGPUNoteTypes[] = {
    {ELF::NT_AMDGPU_METADATA, "NT_AMDGPU_METADATA (AMDGPU Metadata)"},
};

const NoteType LLVMOMPOFFLOADNoteTypes[] = {
    {ELF::NT_LLVM_OPENMP_OFFLOAD_VERSION,
     "NT_LLVM_OPENMP_OFFLOAD_VERSION (image format version)"},
    {ELF::NT_LLVM_OPENMP_OFFLOAD_PRODUCER,
     "NT_LLVM_OPENMP_OFFLOAD_PRODUCER (producing toolchain)"},
    {ELF::NT_LLVM_OPENMP_OFFLOAD_PRODUCER_VERSION,
     "NT_LLVM_OPENMP_OFFLOAD_PRODUCER_VERSION (producing toolchain version)"},
};

const NoteType AndroidNoteTypes[] = {
    {ELF::NT_ANDROID_TYPE_IDENT, "NT_ANDROID_TYPE_IDENT"},
    {ELF::NT_ANDROID_TYPE_KUSER, "NT_ANDROID_TYPE_KUSER"},
    {ELF::NT_ANDROID_TYPE_MEMTAG,
     "NT_ANDROID_TYPE_MEMTAG (Android memory tagging information)"},
};

const NoteType CoreNoteTypes[] = {
    {ELF::NT_PRSTATUS, "NT_PRSTATUS (prstatus structure)"},
    {ELF::NT_FPREGSET, "NT_FPREGSET (floating point registers)"},
    {ELF::NT_PRPSINFO, "NT_PRPSINFO (prpsinfo structure)"},
    {ELF::NT_TASKSTRUCT, "NT_TASKSTRUCT (task structure)"},
    {ELF::NT_AUXV, "NT_AUXV (auxiliary vector)"},
    {ELF::NT_PSTATUS, "NT_PSTATUS (pstatus structure)"},
    {ELF::NT_FPREGS, "NT_FPREGS (floating point registers)"},
    {ELF::NT_PSINFO, "NT_PSINFO (psinfo structure)"},
    {ELF::NT_LWPSTATUS, "NT_LWPSTATUS (lwpstatus_t structure)"},
    {ELF::NT_LWPSINFO, "NT_LWPSINFO (lwpsinfo_t structure)"},
    {ELF::NT_WIN32PSTATUS, "NT_WIN32PSTATUS (win32_pstatus structure)"},

    {ELF::NT_PPC_VMX, "NT_PPC_VMX (ppc Altivec registers)"},
    {ELF::NT_PPC_VSX, "NT_PPC_VSX (ppc VSX registers)"},
    {ELF::NT_PPC_TAR, "NT_PPC_TAR (ppc TAR register)"},
    {ELF::NT_PPC_PPR, "NT_PPC_PPR (ppc PPR register)"},
    {ELF::NT_PPC_DSCR, "NT_PPC_DSCR (ppc DSCR register)"},
    {ELF::NT_PPC_EBB, "NT_PPC_EBB (ppc EBB registers)"},
    {ELF::NT_PPC_PMU, "NT_PPC_PMU (ppc PMU registers)"},
    {ELF::NT_PPC_TM_CGPR, "NT_PPC_TM_CGPR (ppc checkpointed GPR registers)"},
    {ELF::NT_PPC_TM_CFPR,
     "NT_PPC_TM_CFPR (ppc checkpointed floating point registers)"},
    {ELF::NT_PPC_TM_CVMX,
     "NT_PPC_TM_CVMX (ppc checkpointed Altivec registers)"},
    {ELF::NT_PPC_TM_CVSX, "NT_PPC_TM_CVSX (ppc checkpointed VSX registers)"},
    {ELF::NT_PPC_TM_SPR, "NT_PPC_TM_SPR (ppc TM special purpose registers)"},
    {ELF::NT_PPC_TM_CTAR, "NT_PPC_TM_CTAR (ppc checkpointed TAR register)"},
    {ELF::NT_PPC_TM_CPPR, "NT_PPC_TM_CPPR (ppc checkpointed PPR register)"},
    {ELF::NT_PPC_TM_CDSCR, "NT_PPC_TM_CDSCR (ppc checkpointed DSCR register)"},

    {ELF::NT_386_TLS, "NT_386_TLS (x86 TLS information)"},
    {ELF::NT_386_IOPERM, "NT_386_IOPERM (x86 I/O permissions)"},
    {ELF::NT_X86_XSTATE, "NT_X86_XSTATE (x86 XSAVE extended state)"},

    {ELF::NT_S390_HIGH_GPRS, "NT_S390_HIGH_GPRS (s390 upper register halves)"},
    {ELF::NT_S390_TIMER, "NT_S390_TIMER (s390 timer register)"},
    {ELF::NT_S390_TODCMP, "NT_S390_TODCMP (s390 TOD comparator register)"},
    {ELF::NT_S390_TODPREG, "NT_S390_TODPREG (s390 TOD programmable register)"},
    {ELF::NT_S390_CTRS, "NT_S390_CTRS (s390 control registers)"},
    {ELF::NT_S390_PREFIX, "NT_S390_PREFIX (s390 prefix register)"},
    {ELF::NT_S390_LAST_BREAK,
     "NT_S390_LAST_BREAK (s390 last breaking event address)"},
    {ELF::NT_S390_SYSTEM_CALL,
     "NT_S390_SYSTEM_CALL (s390 system call restart data)"},
    {ELF::NT_S390_TDB, "NT_S390_TDB (s390 transaction diagnostic block)"},
    {ELF::NT_S390_VXRS_LOW,
     "NT_S390_VXRS_LOW (s390 vector registers 0-15 upper half)"},
    {ELF::NT_S390_VXRS_HIGH, "NT_S390_VXRS_HIGH (s390 vector registers 16-31)"},
    {ELF::NT_S390_GS_CB, "NT_S390_GS_CB (s390 guarded-storage registers)"},
    {ELF::NT_S390_GS_BC,
     "NT_S390_GS_BC (s390 guarded-storage broadcast control)"},

    {ELF::NT_ARM_VFP, "NT_ARM_VFP (arm VFP registers)"},
    {ELF::NT_ARM_TLS, "NT_ARM_TLS (AArch TLS registers)"},
    {ELF::NT_ARM_HW_BREAK,
     "NT_ARM_HW_BREAK (AArch hardware breakpoint registers)"},
    {ELF::NT_ARM_HW_WATCH,
     "NT_ARM_HW_WATCH (AArch hardware watchpoint registers)"},

    {ELF::NT_FILE, "NT_FILE (mapped files)"},
    {ELF::NT_PRXFPREG, "NT_PRXFPREG (user_xfpregs structure)"},
    {ELF::NT_SIGINFO, "NT_SIGINFO (siginfo_t data)"},
};

template <class ELFT>
StringRef getNoteTypeName(const typename ELFT::Note &Note, unsigned ELFType) {
  uint32_t Type = Note.getType();
  auto FindNote = [&](ArrayRef<NoteType> V) -> StringRef {
    for (const NoteType &N : V)
      if (N.ID == Type)
        return N.Name;
    return "";
  };

  StringRef Name = Note.getName();
  if (Name == "GNU")
    return FindNote(GNUNoteTypes);
  if (Name == "FreeBSD") {
    if (ELFType == ELF::ET_CORE) {
      // FreeBSD also places the generic core notes in the FreeBSD namespace.
      StringRef Result = FindNote(FreeBSDCoreNoteTypes);
      if (!Result.empty())
        return Result;
      return FindNote(CoreNoteTypes);
    } else {
      return FindNote(FreeBSDNoteTypes);
    }
  }
  if (ELFType == ELF::ET_CORE && Name.startswith("NetBSD-CORE")) {
    StringRef Result = FindNote(NetBSDCoreNoteTypes);
    if (!Result.empty())
      return Result;
    return FindNote(CoreNoteTypes);
  }
  if (ELFType == ELF::ET_CORE && Name.startswith("OpenBSD")) {
    // OpenBSD also places the generic core notes in the OpenBSD namespace.
    StringRef Result = FindNote(OpenBSDCoreNoteTypes);
    if (!Result.empty())
      return Result;
    return FindNote(CoreNoteTypes);
  }
  if (Name == "AMD")
    return FindNote(AMDNoteTypes);
  if (Name == "AMDGPU")
    return FindNote(AMDGPUNoteTypes);
  if (Name == "LLVMOMPOFFLOAD")
    return FindNote(LLVMOMPOFFLOADNoteTypes);
  if (Name == "Android")
    return FindNote(AndroidNoteTypes);

  if (ELFType == ELF::ET_CORE)
    return FindNote(CoreNoteTypes);
  return FindNote(GenericNoteTypes);
}

template <class ELFT>
static void printNotesHelper(
    const ELFDumper<ELFT> &Dumper,
    llvm::function_ref<void(Optional<StringRef>, typename ELFT::Off,
                            typename ELFT::Addr)>
        StartNotesFn,
    llvm::function_ref<Error(const typename ELFT::Note &, bool)> ProcessNoteFn,
    llvm::function_ref<void()> FinishNotesFn) {
  const ELFFile<ELFT> &Obj = Dumper.getElfObject().getELFFile();
  bool IsCoreFile = Obj.getHeader().e_type == ELF::ET_CORE;

  ArrayRef<typename ELFT::Shdr> Sections = cantFail(Obj.sections());
  if (!IsCoreFile && !Sections.empty()) {
    for (const typename ELFT::Shdr &S : Sections) {
      if (S.sh_type != SHT_NOTE)
        continue;
      StartNotesFn(expectedToOptional(Obj.getSectionName(S)), S.sh_offset,
                   S.sh_size);
      Error Err = Error::success();
      size_t I = 0;
      for (const typename ELFT::Note Note : Obj.notes(S, Err)) {
        if (Error E = ProcessNoteFn(Note, IsCoreFile))
          Dumper.reportUniqueWarning(
              "unable to read note with index " + Twine(I) + " from the " +
              describe(Obj, S) + ": " + toString(std::move(E)));
        ++I;
      }
      if (Err)
        Dumper.reportUniqueWarning("unable to read notes from the " +
                                   describe(Obj, S) + ": " +
                                   toString(std::move(Err)));
      FinishNotesFn();
    }
    return;
  }

  Expected<ArrayRef<typename ELFT::Phdr>> PhdrsOrErr = Obj.program_headers();
  if (!PhdrsOrErr) {
    Dumper.reportUniqueWarning(
        "unable to read program headers to locate the PT_NOTE segment: " +
        toString(PhdrsOrErr.takeError()));
    return;
  }

  for (size_t I = 0, E = (*PhdrsOrErr).size(); I != E; ++I) {
    const typename ELFT::Phdr &P = (*PhdrsOrErr)[I];
    if (P.p_type != PT_NOTE)
      continue;
    StartNotesFn(/*SecName=*/None, P.p_offset, P.p_filesz);
    Error Err = Error::success();
    size_t Index = 0;
    for (const typename ELFT::Note Note : Obj.notes(P, Err)) {
      if (Error E = ProcessNoteFn(Note, IsCoreFile))
        Dumper.reportUniqueWarning("unable to read note with index " +
                                   Twine(Index) +
                                   " from the PT_NOTE segment with index " +
                                   Twine(I) + ": " + toString(std::move(E)));
      ++Index;
    }
    if (Err)
      Dumper.reportUniqueWarning(
          "unable to read notes from the PT_NOTE segment with index " +
          Twine(I) + ": " + toString(std::move(Err)));
    FinishNotesFn();
  }
}

template <class ELFT> void GNUELFDumper<ELFT>::printNotes() {
  bool IsFirstHeader = true;
  auto PrintHeader = [&](Optional<StringRef> SecName,
                         const typename ELFT::Off Offset,
                         const typename ELFT::Addr Size) {
    // Print a newline between notes sections to match GNU readelf.
    if (!IsFirstHeader) {
      OS << '\n';
    } else {
      IsFirstHeader = false;
    }

    OS << "Displaying notes found ";

    if (SecName)
      OS << "in: " << *SecName << "\n";
    else
      OS << "at file offset " << format_hex(Offset, 10) << " with length "
         << format_hex(Size, 10) << ":\n";

    OS << "  Owner                Data size \tDescription\n";
  };

  auto ProcessNote = [&](const Elf_Note &Note, bool IsCore) -> Error {
    StringRef Name = Note.getName();
    ArrayRef<uint8_t> Descriptor = Note.getDesc();
    Elf_Word Type = Note.getType();

    // Print the note owner/type.
    OS << "  " << left_justify(Name, 20) << ' '
       << format_hex(Descriptor.size(), 10) << '\t';

    StringRef NoteType =
        getNoteTypeName<ELFT>(Note, this->Obj.getHeader().e_type);
    if (!NoteType.empty())
      OS << NoteType << '\n';
    else
      OS << "Unknown note type: (" << format_hex(Type, 10) << ")\n";

    // Print the description, or fallback to printing raw bytes for unknown
    // owners/if we fail to pretty-print the contents.
    if (Name == "GNU") {
      if (printGNUNote<ELFT>(OS, Type, Descriptor))
        return Error::success();
    } else if (Name == "FreeBSD") {
      if (Optional<FreeBSDNote> N =
              getFreeBSDNote<ELFT>(Type, Descriptor, IsCore)) {
        OS << "    " << N->Type << ": " << N->Value << '\n';
        return Error::success();
      }
    } else if (Name == "AMD") {
      const AMDNote N = getAMDNote<ELFT>(Type, Descriptor);
      if (!N.Type.empty()) {
        OS << "    " << N.Type << ":\n        " << N.Value << '\n';
        return Error::success();
      }
    } else if (Name == "AMDGPU") {
      const AMDGPUNote N = getAMDGPUNote<ELFT>(Type, Descriptor);
      if (!N.Type.empty()) {
        OS << "    " << N.Type << ":\n        " << N.Value << '\n';
        return Error::success();
      }
    } else if (Name == "LLVMOMPOFFLOAD") {
      if (printLLVMOMPOFFLOADNote<ELFT>(OS, Type, Descriptor))
        return Error::success();
    } else if (Name == "CORE") {
      if (Type == ELF::NT_FILE) {
        DataExtractor DescExtractor(Descriptor,
                                    ELFT::TargetEndianness == support::little,
                                    sizeof(Elf_Addr));
        if (Expected<CoreNote> NoteOrErr = readCoreNote(DescExtractor)) {
          printCoreNote<ELFT>(OS, *NoteOrErr);
          return Error::success();
        } else {
          return NoteOrErr.takeError();
        }
      }
    } else if (Name == "Android") {
      if (printAndroidNote(OS, Type, Descriptor))
        return Error::success();
    }
    if (!Descriptor.empty()) {
      OS << "   description data:";
      for (uint8_t B : Descriptor)
        OS << " " << format("%02x", B);
      OS << '\n';
    }
    return Error::success();
  };

  printNotesHelper(*this, PrintHeader, ProcessNote, []() {});
}

template <class ELFT> void GNUELFDumper<ELFT>::printELFLinkerOptions() {
  OS << "printELFLinkerOptions not implemented!\n";
}

template <class ELFT>
void ELFDumper<ELFT>::printDependentLibsHelper(
    function_ref<void(const Elf_Shdr &)> OnSectionStart,
    function_ref<void(StringRef, uint64_t)> OnLibEntry) {
  auto Warn = [this](unsigned SecNdx, StringRef Msg) {
    this->reportUniqueWarning("SHT_LLVM_DEPENDENT_LIBRARIES section at index " +
                              Twine(SecNdx) + " is broken: " + Msg);
  };

  unsigned I = -1;
  for (const Elf_Shdr &Shdr : cantFail(Obj.sections())) {
    ++I;
    if (Shdr.sh_type != ELF::SHT_LLVM_DEPENDENT_LIBRARIES)
      continue;

    OnSectionStart(Shdr);

    Expected<ArrayRef<uint8_t>> ContentsOrErr = Obj.getSectionContents(Shdr);
    if (!ContentsOrErr) {
      Warn(I, toString(ContentsOrErr.takeError()));
      continue;
    }

    ArrayRef<uint8_t> Contents = *ContentsOrErr;
    if (!Contents.empty() && Contents.back() != 0) {
      Warn(I, "the content is not null-terminated");
      continue;
    }

    for (const uint8_t *I = Contents.begin(), *E = Contents.end(); I < E;) {
      StringRef Lib((const char *)I);
      OnLibEntry(Lib, I - Contents.begin());
      I += Lib.size() + 1;
    }
  }
}

template <class ELFT>
void ELFDumper<ELFT>::forEachRelocationDo(
    const Elf_Shdr &Sec, bool RawRelr,
    llvm::function_ref<void(const Relocation<ELFT> &, unsigned,
                            const Elf_Shdr &, const Elf_Shdr *)>
        RelRelaFn,
    llvm::function_ref<void(const Elf_Relr &)> RelrFn) {
  auto Warn = [&](Error &&E,
                  const Twine &Prefix = "unable to read relocations from") {
    this->reportUniqueWarning(Prefix + " " + describe(Sec) + ": " +
                              toString(std::move(E)));
  };

  // SHT_RELR/SHT_ANDROID_RELR sections do not have an associated symbol table.
  // For them we should not treat the value of the sh_link field as an index of
  // a symbol table.
  const Elf_Shdr *SymTab;
  if (Sec.sh_type != ELF::SHT_RELR && Sec.sh_type != ELF::SHT_ANDROID_RELR) {
    Expected<const Elf_Shdr *> SymTabOrErr = Obj.getSection(Sec.sh_link);
    if (!SymTabOrErr) {
      Warn(SymTabOrErr.takeError(), "unable to locate a symbol table for");
      return;
    }
    SymTab = *SymTabOrErr;
  }

  unsigned RelNdx = 0;
  const bool IsMips64EL = this->Obj.isMips64EL();
  switch (Sec.sh_type) {
  case ELF::SHT_REL:
    if (Expected<Elf_Rel_Range> RangeOrErr = Obj.rels(Sec)) {
      for (const Elf_Rel &R : *RangeOrErr)
        RelRelaFn(Relocation<ELFT>(R, IsMips64EL), RelNdx++, Sec, SymTab);
    } else {
      Warn(RangeOrErr.takeError());
    }
    break;
  case ELF::SHT_RELA:
    if (Expected<Elf_Rela_Range> RangeOrErr = Obj.relas(Sec)) {
      for (const Elf_Rela &R : *RangeOrErr)
        RelRelaFn(Relocation<ELFT>(R, IsMips64EL), RelNdx++, Sec, SymTab);
    } else {
      Warn(RangeOrErr.takeError());
    }
    break;
  case ELF::SHT_RELR:
  case ELF::SHT_ANDROID_RELR: {
    Expected<Elf_Relr_Range> RangeOrErr = Obj.relrs(Sec);
    if (!RangeOrErr) {
      Warn(RangeOrErr.takeError());
      break;
    }
    if (RawRelr) {
      for (const Elf_Relr &R : *RangeOrErr)
        RelrFn(R);
      break;
    }

    for (const Elf_Rel &R : Obj.decode_relrs(*RangeOrErr))
      RelRelaFn(Relocation<ELFT>(R, IsMips64EL), RelNdx++, Sec,
                /*SymTab=*/nullptr);
    break;
  }
  case ELF::SHT_ANDROID_REL:
  case ELF::SHT_ANDROID_RELA:
    if (Expected<std::vector<Elf_Rela>> RelasOrErr = Obj.android_relas(Sec)) {
      for (const Elf_Rela &R : *RelasOrErr)
        RelRelaFn(Relocation<ELFT>(R, IsMips64EL), RelNdx++, Sec, SymTab);
    } else {
      Warn(RelasOrErr.takeError());
    }
    break;
  }
}

template <class ELFT>
StringRef ELFDumper<ELFT>::getPrintableSectionName(const Elf_Shdr &Sec) const {
  StringRef Name = "<?>";
  if (Expected<StringRef> SecNameOrErr =
          Obj.getSectionName(Sec, this->WarningHandler))
    Name = *SecNameOrErr;
  else
    this->reportUniqueWarning("unable to get the name of " + describe(Sec) +
                              ": " + toString(SecNameOrErr.takeError()));
  return Name;
}

template <class ELFT> void GNUELFDumper<ELFT>::printDependentLibs() {
  bool SectionStarted = false;
  struct NameOffset {
    StringRef Name;
    uint64_t Offset;
  };
  std::vector<NameOffset> SecEntries;
  NameOffset Current;
  auto PrintSection = [&]() {
    OS << "Dependent libraries section " << Current.Name << " at offset "
       << format_hex(Current.Offset, 1) << " contains " << SecEntries.size()
       << " entries:\n";
    for (NameOffset Entry : SecEntries)
      OS << "  [" << format("%6" PRIx64, Entry.Offset) << "]  " << Entry.Name
         << "\n";
    OS << "\n";
    SecEntries.clear();
  };

  auto OnSectionStart = [&](const Elf_Shdr &Shdr) {
    if (SectionStarted)
      PrintSection();
    SectionStarted = true;
    Current.Offset = Shdr.sh_offset;
    Current.Name = this->getPrintableSectionName(Shdr);
  };
  auto OnLibEntry = [&](StringRef Lib, uint64_t Offset) {
    SecEntries.push_back(NameOffset{Lib, Offset});
  };

  this->printDependentLibsHelper(OnSectionStart, OnLibEntry);
  if (SectionStarted)
    PrintSection();
}

template <class ELFT>
SmallVector<uint32_t> ELFDumper<ELFT>::getSymbolIndexesForFunctionAddress(
    uint64_t SymValue, Optional<const Elf_Shdr *> FunctionSec) {
  SmallVector<uint32_t> SymbolIndexes;
  if (!this->AddressToIndexMap) {
    // Populate the address to index map upon the first invocation of this
    // function.
    this->AddressToIndexMap.emplace();
    if (this->DotSymtabSec) {
      if (Expected<Elf_Sym_Range> SymsOrError =
              Obj.symbols(this->DotSymtabSec)) {
        uint32_t Index = (uint32_t)-1;
        for (const Elf_Sym &Sym : *SymsOrError) {
          ++Index;

          if (Sym.st_shndx == ELF::SHN_UNDEF || Sym.getType() != ELF::STT_FUNC)
            continue;

          Expected<uint64_t> SymAddrOrErr =
              ObjF.toSymbolRef(this->DotSymtabSec, Index).getAddress();
          if (!SymAddrOrErr) {
            std::string Name = this->getStaticSymbolName(Index);
            reportUniqueWarning("unable to get address of symbol '" + Name +
                                "': " + toString(SymAddrOrErr.takeError()));
            return SymbolIndexes;
          }

          (*this->AddressToIndexMap)[*SymAddrOrErr].push_back(Index);
        }
      } else {
        reportUniqueWarning("unable to read the symbol table: " +
                            toString(SymsOrError.takeError()));
      }
    }
  }

  auto Symbols = this->AddressToIndexMap->find(SymValue);
  if (Symbols == this->AddressToIndexMap->end())
    return SymbolIndexes;

  for (uint32_t Index : Symbols->second) {
    // Check if the symbol is in the right section. FunctionSec == None
    // means "any section".
    if (FunctionSec) {
      const Elf_Sym &Sym = *cantFail(Obj.getSymbol(this->DotSymtabSec, Index));
      if (Expected<const Elf_Shdr *> SecOrErr =
              Obj.getSection(Sym, this->DotSymtabSec,
                             this->getShndxTable(this->DotSymtabSec))) {
        if (*FunctionSec != *SecOrErr)
          continue;
      } else {
        std::string Name = this->getStaticSymbolName(Index);
        // Note: it is impossible to trigger this error currently, it is
        // untested.
        reportUniqueWarning("unable to get section of symbol '" + Name +
                            "': " + toString(SecOrErr.takeError()));
        return SymbolIndexes;
      }
    }

    SymbolIndexes.push_back(Index);
  }

  return SymbolIndexes;
}

template <class ELFT>
bool ELFDumper<ELFT>::printFunctionStackSize(
    uint64_t SymValue, Optional<const Elf_Shdr *> FunctionSec,
    const Elf_Shdr &StackSizeSec, DataExtractor Data, uint64_t *Offset) {
  SmallVector<uint32_t> FuncSymIndexes =
      this->getSymbolIndexesForFunctionAddress(SymValue, FunctionSec);
  if (FuncSymIndexes.empty())
    reportUniqueWarning(
        "could not identify function symbol for stack size entry in " +
        describe(StackSizeSec));

  // Extract the size. The expectation is that Offset is pointing to the right
  // place, i.e. past the function address.
  Error Err = Error::success();
  uint64_t StackSize = Data.getULEB128(Offset, &Err);
  if (Err) {
    reportUniqueWarning("could not extract a valid stack size from " +
                        describe(StackSizeSec) + ": " +
                        toString(std::move(Err)));
    return false;
  }

  if (FuncSymIndexes.empty()) {
    printStackSizeEntry(StackSize, {"?"});
  } else {
    SmallVector<std::string> FuncSymNames;
    for (uint32_t Index : FuncSymIndexes)
      FuncSymNames.push_back(this->getStaticSymbolName(Index));
    printStackSizeEntry(StackSize, FuncSymNames);
  }

  return true;
}

template <class ELFT>
void GNUELFDumper<ELFT>::printStackSizeEntry(uint64_t Size,
                                             ArrayRef<std::string> FuncNames) {
  OS.PadToColumn(2);
  OS << format_decimal(Size, 11);
  OS.PadToColumn(18);

  OS << join(FuncNames.begin(), FuncNames.end(), ", ") << "\n";
}

template <class ELFT>
void ELFDumper<ELFT>::printStackSize(const Relocation<ELFT> &R,
                                     const Elf_Shdr &RelocSec, unsigned Ndx,
                                     const Elf_Shdr *SymTab,
                                     const Elf_Shdr *FunctionSec,
                                     const Elf_Shdr &StackSizeSec,
                                     const RelocationResolver &Resolver,
                                     DataExtractor Data) {
  // This function ignores potentially erroneous input, unless it is directly
  // related to stack size reporting.
  const Elf_Sym *Sym = nullptr;
  Expected<RelSymbol<ELFT>> TargetOrErr = this->getRelocationTarget(R, SymTab);
  if (!TargetOrErr)
    reportUniqueWarning("unable to get the target of relocation with index " +
                        Twine(Ndx) + " in " + describe(RelocSec) + ": " +
                        toString(TargetOrErr.takeError()));
  else
    Sym = TargetOrErr->Sym;

  uint64_t RelocSymValue = 0;
  if (Sym) {
    Expected<const Elf_Shdr *> SectionOrErr =
        this->Obj.getSection(*Sym, SymTab, this->getShndxTable(SymTab));
    if (!SectionOrErr) {
      reportUniqueWarning(
          "cannot identify the section for relocation symbol '" +
          (*TargetOrErr).Name + "': " + toString(SectionOrErr.takeError()));
    } else if (*SectionOrErr != FunctionSec) {
      reportUniqueWarning("relocation symbol '" + (*TargetOrErr).Name +
                          "' is not in the expected section");
      // Pretend that the symbol is in the correct section and report its
      // stack size anyway.
      FunctionSec = *SectionOrErr;
    }

    RelocSymValue = Sym->st_value;
  }

  uint64_t Offset = R.Offset;
  if (!Data.isValidOffsetForDataOfSize(Offset, sizeof(Elf_Addr) + 1)) {
    reportUniqueWarning("found invalid relocation offset (0x" +
                        Twine::utohexstr(Offset) + ") into " +
                        describe(StackSizeSec) +
                        " while trying to extract a stack size entry");
    return;
  }

  uint64_t SymValue = Resolver(R.Type, Offset, RelocSymValue,
                               Data.getAddress(&Offset), R.Addend.value_or(0));
  this->printFunctionStackSize(SymValue, FunctionSec, StackSizeSec, Data,
                               &Offset);
}

template <class ELFT>
void ELFDumper<ELFT>::printNonRelocatableStackSizes(
    std::function<void()> PrintHeader) {
  // This function ignores potentially erroneous input, unless it is directly
  // related to stack size reporting.
  for (const Elf_Shdr &Sec : cantFail(Obj.sections())) {
    if (this->getPrintableSectionName(Sec) != ".stack_sizes")
      continue;
    PrintHeader();
    ArrayRef<uint8_t> Contents =
        unwrapOrError(this->FileName, Obj.getSectionContents(Sec));
    DataExtractor Data(Contents, Obj.isLE(), sizeof(Elf_Addr));
    uint64_t Offset = 0;
    while (Offset < Contents.size()) {
      // The function address is followed by a ULEB representing the stack
      // size. Check for an extra byte before we try to process the entry.
      if (!Data.isValidOffsetForDataOfSize(Offset, sizeof(Elf_Addr) + 1)) {
        reportUniqueWarning(
            describe(Sec) +
            " ended while trying to extract a stack size entry");
        break;
      }
      uint64_t SymValue = Data.getAddress(&Offset);
      if (!printFunctionStackSize(SymValue, /*FunctionSec=*/None, Sec, Data,
                                  &Offset))
        break;
    }
  }
}

template <class ELFT>
void ELFDumper<ELFT>::getSectionAndRelocations(
    std::function<bool(const Elf_Shdr &)> IsMatch,
    llvm::MapVector<const Elf_Shdr *, const Elf_Shdr *> &SecToRelocMap) {
  for (const Elf_Shdr &Sec : cantFail(Obj.sections())) {
    if (IsMatch(Sec))
      if (SecToRelocMap.insert(std::make_pair(&Sec, (const Elf_Shdr *)nullptr))
              .second)
        continue;

    if (Sec.sh_type != ELF::SHT_RELA && Sec.sh_type != ELF::SHT_REL)
      continue;

    Expected<const Elf_Shdr *> RelSecOrErr = Obj.getSection(Sec.sh_info);
    if (!RelSecOrErr) {
      reportUniqueWarning(describe(Sec) +
                          ": failed to get a relocated section: " +
                          toString(RelSecOrErr.takeError()));
      continue;
    }
    const Elf_Shdr *ContentsSec = *RelSecOrErr;
    if (IsMatch(*ContentsSec))
      SecToRelocMap[ContentsSec] = &Sec;
  }
}

template <class ELFT>
void ELFDumper<ELFT>::printRelocatableStackSizes(
    std::function<void()> PrintHeader) {
  // Build a map between stack size sections and their corresponding relocation
  // sections.
  llvm::MapVector<const Elf_Shdr *, const Elf_Shdr *> StackSizeRelocMap;
  auto IsMatch = [&](const Elf_Shdr &Sec) -> bool {
    StringRef SectionName;
    if (Expected<StringRef> NameOrErr = Obj.getSectionName(Sec))
      SectionName = *NameOrErr;
    else
      consumeError(NameOrErr.takeError());

    return SectionName == ".stack_sizes";
  };
  getSectionAndRelocations(IsMatch, StackSizeRelocMap);

  for (const auto &StackSizeMapEntry : StackSizeRelocMap) {
    PrintHeader();
    const Elf_Shdr *StackSizesELFSec = StackSizeMapEntry.first;
    const Elf_Shdr *RelocSec = StackSizeMapEntry.second;

    // Warn about stack size sections without a relocation section.
    if (!RelocSec) {
      reportWarning(createError(".stack_sizes (" + describe(*StackSizesELFSec) +
                                ") does not have a corresponding "
                                "relocation section"),
                    FileName);
      continue;
    }

    // A .stack_sizes section header's sh_link field is supposed to point
    // to the section that contains the functions whose stack sizes are
    // described in it.
    const Elf_Shdr *FunctionSec = unwrapOrError(
        this->FileName, Obj.getSection(StackSizesELFSec->sh_link));

    SupportsRelocation IsSupportedFn;
    RelocationResolver Resolver;
    std::tie(IsSupportedFn, Resolver) = getRelocationResolver(this->ObjF);
    ArrayRef<uint8_t> Contents =
        unwrapOrError(this->FileName, Obj.getSectionContents(*StackSizesELFSec));
    DataExtractor Data(Contents, Obj.isLE(), sizeof(Elf_Addr));

    forEachRelocationDo(
        *RelocSec, /*RawRelr=*/false,
        [&](const Relocation<ELFT> &R, unsigned Ndx, const Elf_Shdr &Sec,
            const Elf_Shdr *SymTab) {
          if (!IsSupportedFn || !IsSupportedFn(R.Type)) {
            reportUniqueWarning(
                describe(*RelocSec) +
                " contains an unsupported relocation with index " + Twine(Ndx) +
                ": " + Obj.getRelocationTypeName(R.Type));
            return;
          }

          this->printStackSize(R, *RelocSec, Ndx, SymTab, FunctionSec,
                               *StackSizesELFSec, Resolver, Data);
        },
        [](const Elf_Relr &) {
          llvm_unreachable("can't get here, because we only support "
                           "SHT_REL/SHT_RELA sections");
        });
  }
}

template <class ELFT>
void GNUELFDumper<ELFT>::printStackSizes() {
  bool HeaderHasBeenPrinted = false;
  auto PrintHeader = [&]() {
    if (HeaderHasBeenPrinted)
      return;
    OS << "\nStack Sizes:\n";
    OS.PadToColumn(9);
    OS << "Size";
    OS.PadToColumn(18);
    OS << "Functions\n";
    HeaderHasBeenPrinted = true;
  };

  // For non-relocatable objects, look directly for sections whose name starts
  // with .stack_sizes and process the contents.
  if (this->Obj.getHeader().e_type == ELF::ET_REL)
    this->printRelocatableStackSizes(PrintHeader);
  else
    this->printNonRelocatableStackSizes(PrintHeader);
}

template <class ELFT>
void GNUELFDumper<ELFT>::printMipsGOT(const MipsGOTParser<ELFT> &Parser) {
  size_t Bias = ELFT::Is64Bits ? 8 : 0;
  auto PrintEntry = [&](const Elf_Addr *E, StringRef Purpose) {
    OS.PadToColumn(2);
    OS << format_hex_no_prefix(Parser.getGotAddress(E), 8 + Bias);
    OS.PadToColumn(11 + Bias);
    OS << format_decimal(Parser.getGotOffset(E), 6) << "(gp)";
    OS.PadToColumn(22 + Bias);
    OS << format_hex_no_prefix(*E, 8 + Bias);
    OS.PadToColumn(31 + 2 * Bias);
    OS << Purpose << "\n";
  };

  OS << (Parser.IsStatic ? "Static GOT:\n" : "Primary GOT:\n");
  OS << " Canonical gp value: "
     << format_hex_no_prefix(Parser.getGp(), 8 + Bias) << "\n\n";

  OS << " Reserved entries:\n";
  if (ELFT::Is64Bits)
    OS << "           Address     Access          Initial Purpose\n";
  else
    OS << "   Address     Access  Initial Purpose\n";
  PrintEntry(Parser.getGotLazyResolver(), "Lazy resolver");
  if (Parser.getGotModulePointer())
    PrintEntry(Parser.getGotModulePointer(), "Module pointer (GNU extension)");

  if (!Parser.getLocalEntries().empty()) {
    OS << "\n";
    OS << " Local entries:\n";
    if (ELFT::Is64Bits)
      OS << "           Address     Access          Initial\n";
    else
      OS << "   Address     Access  Initial\n";
    for (auto &E : Parser.getLocalEntries())
      PrintEntry(&E, "");
  }

  if (Parser.IsStatic)
    return;

  if (!Parser.getGlobalEntries().empty()) {
    OS << "\n";
    OS << " Global entries:\n";
    if (ELFT::Is64Bits)
      OS << "           Address     Access          Initial         Sym.Val."
         << " Type    Ndx Name\n";
    else
      OS << "   Address     Access  Initial Sym.Val. Type    Ndx Name\n";

    DataRegion<Elf_Word> ShndxTable(
        (const Elf_Word *)this->DynSymTabShndxRegion.Addr, this->Obj.end());
    for (auto &E : Parser.getGlobalEntries()) {
      const Elf_Sym &Sym = *Parser.getGotSym(&E);
      const Elf_Sym &FirstSym = this->dynamic_symbols()[0];
      std::string SymName = this->getFullSymbolName(
          Sym, &Sym - &FirstSym, ShndxTable, this->DynamicStringTable, false);

      OS.PadToColumn(2);
      OS << to_string(format_hex_no_prefix(Parser.getGotAddress(&E), 8 + Bias));
      OS.PadToColumn(11 + Bias);
      OS << to_string(format_decimal(Parser.getGotOffset(&E), 6)) + "(gp)";
      OS.PadToColumn(22 + Bias);
      OS << to_string(format_hex_no_prefix(E, 8 + Bias));
      OS.PadToColumn(31 + 2 * Bias);
      OS << to_string(format_hex_no_prefix(Sym.st_value, 8 + Bias));
      OS.PadToColumn(40 + 3 * Bias);
      OS << enumToString(Sym.getType(), makeArrayRef(ElfSymbolTypes));
      OS.PadToColumn(48 + 3 * Bias);
      OS << getSymbolSectionNdx(Sym, &Sym - this->dynamic_symbols().begin(),
                                ShndxTable);
      OS.PadToColumn(52 + 3 * Bias);
      OS << SymName << "\n";
    }
  }

  if (!Parser.getOtherEntries().empty())
    OS << "\n Number of TLS and multi-GOT entries "
       << Parser.getOtherEntries().size() << "\n";
}

template <class ELFT>
void GNUELFDumper<ELFT>::printMipsPLT(const MipsGOTParser<ELFT> &Parser) {
  size_t Bias = ELFT::Is64Bits ? 8 : 0;
  auto PrintEntry = [&](const Elf_Addr *E, StringRef Purpose) {
    OS.PadToColumn(2);
    OS << format_hex_no_prefix(Parser.getPltAddress(E), 8 + Bias);
    OS.PadToColumn(11 + Bias);
    OS << format_hex_no_prefix(*E, 8 + Bias);
    OS.PadToColumn(20 + 2 * Bias);
    OS << Purpose << "\n";
  };

  OS << "PLT GOT:\n\n";

  OS << " Reserved entries:\n";
  OS << "   Address  Initial Purpose\n";
  PrintEntry(Parser.getPltLazyResolver(), "PLT lazy resolver");
  if (Parser.getPltModulePointer())
    PrintEntry(Parser.getPltModulePointer(), "Module pointer");

  if (!Parser.getPltEntries().empty()) {
    OS << "\n";
    OS << " Entries:\n";
    OS << "   Address  Initial Sym.Val. Type    Ndx Name\n";
    DataRegion<Elf_Word> ShndxTable(
        (const Elf_Word *)this->DynSymTabShndxRegion.Addr, this->Obj.end());
    for (auto &E : Parser.getPltEntries()) {
      const Elf_Sym &Sym = *Parser.getPltSym(&E);
      const Elf_Sym &FirstSym = *cantFail(
          this->Obj.template getEntry<Elf_Sym>(*Parser.getPltSymTable(), 0));
      std::string SymName = this->getFullSymbolName(
          Sym, &Sym - &FirstSym, ShndxTable, this->DynamicStringTable, false);

      OS.PadToColumn(2);
      OS << to_string(format_hex_no_prefix(Parser.getPltAddress(&E), 8 + Bias));
      OS.PadToColumn(11 + Bias);
      OS << to_string(format_hex_no_prefix(E, 8 + Bias));
      OS.PadToColumn(20 + 2 * Bias);
      OS << to_string(format_hex_no_prefix(Sym.st_value, 8 + Bias));
      OS.PadToColumn(29 + 3 * Bias);
      OS << enumToString(Sym.getType(), makeArrayRef(ElfSymbolTypes));
      OS.PadToColumn(37 + 3 * Bias);
      OS << getSymbolSectionNdx(Sym, &Sym - this->dynamic_symbols().begin(),
                                ShndxTable);
      OS.PadToColumn(41 + 3 * Bias);
      OS << SymName << "\n";
    }
  }
}

template <class ELFT>
Expected<const Elf_Mips_ABIFlags<ELFT> *>
getMipsAbiFlagsSection(const ELFDumper<ELFT> &Dumper) {
  const typename ELFT::Shdr *Sec = Dumper.findSectionByName(".MIPS.abiflags");
  if (Sec == nullptr)
    return nullptr;

  constexpr StringRef ErrPrefix = "unable to read the .MIPS.abiflags section: ";
  Expected<ArrayRef<uint8_t>> DataOrErr =
      Dumper.getElfObject().getELFFile().getSectionContents(*Sec);
  if (!DataOrErr)
    return createError(ErrPrefix + toString(DataOrErr.takeError()));

  if (DataOrErr->size() != sizeof(Elf_Mips_ABIFlags<ELFT>))
    return createError(ErrPrefix + "it has a wrong size (" +
        Twine(DataOrErr->size()) + ")");
  return reinterpret_cast<const Elf_Mips_ABIFlags<ELFT> *>(DataOrErr->data());
}

template <class ELFT> void GNUELFDumper<ELFT>::printMipsABIFlags() {
  const Elf_Mips_ABIFlags<ELFT> *Flags = nullptr;
  if (Expected<const Elf_Mips_ABIFlags<ELFT> *> SecOrErr =
          getMipsAbiFlagsSection(*this))
    Flags = *SecOrErr;
  else
    this->reportUniqueWarning(SecOrErr.takeError());
  if (!Flags)
    return;

  OS << "MIPS ABI Flags Version: " << Flags->version << "\n\n";
  OS << "ISA: MIPS" << int(Flags->isa_level);
  if (Flags->isa_rev > 1)
    OS << "r" << int(Flags->isa_rev);
  OS << "\n";
  OS << "GPR size: " << getMipsRegisterSize(Flags->gpr_size) << "\n";
  OS << "CPR1 size: " << getMipsRegisterSize(Flags->cpr1_size) << "\n";
  OS << "CPR2 size: " << getMipsRegisterSize(Flags->cpr2_size) << "\n";
  OS << "FP ABI: "
     << enumToString(Flags->fp_abi, makeArrayRef(ElfMipsFpABIType)) << "\n";
  OS << "ISA Extension: "
     << enumToString(Flags->isa_ext, makeArrayRef(ElfMipsISAExtType)) << "\n";
  if (Flags->ases == 0)
    OS << "ASEs: None\n";
  else
    // FIXME: Print each flag on a separate line.
    OS << "ASEs: " << printFlags(Flags->ases, makeArrayRef(ElfMipsASEFlags))
       << "\n";
  OS << "FLAGS 1: " << format_hex_no_prefix(Flags->flags1, 8, false) << "\n";
  OS << "FLAGS 2: " << format_hex_no_prefix(Flags->flags2, 8, false) << "\n";
  OS << "\n";
}

template <class ELFT> void LLVMELFDumper<ELFT>::printFileHeaders() {
  const Elf_Ehdr &E = this->Obj.getHeader();
  {
    DictScope D(W, "ElfHeader");
    {
      DictScope D(W, "Ident");
      W.printBinary("Magic", makeArrayRef(E.e_ident).slice(ELF::EI_MAG0, 4));
      W.printEnum("Class", E.e_ident[ELF::EI_CLASS], makeArrayRef(ElfClass));
      W.printEnum("DataEncoding", E.e_ident[ELF::EI_DATA],
                  makeArrayRef(ElfDataEncoding));
      W.printNumber("FileVersion", E.e_ident[ELF::EI_VERSION]);

      auto OSABI = makeArrayRef(ElfOSABI);
      if (E.e_ident[ELF::EI_OSABI] >= ELF::ELFOSABI_FIRST_ARCH &&
          E.e_ident[ELF::EI_OSABI] <= ELF::ELFOSABI_LAST_ARCH) {
        switch (E.e_machine) {
        case ELF::EM_AMDGPU:
          OSABI = makeArrayRef(AMDGPUElfOSABI);
          break;
        case ELF::EM_ARM:
          OSABI = makeArrayRef(ARMElfOSABI);
          break;
        case ELF::EM_TI_C6000:
          OSABI = makeArrayRef(C6000ElfOSABI);
          break;
        }
      }
      W.printEnum("OS/ABI", E.e_ident[ELF::EI_OSABI], OSABI);
      W.printNumber("ABIVersion", E.e_ident[ELF::EI_ABIVERSION]);
      W.printBinary("Unused", makeArrayRef(E.e_ident).slice(ELF::EI_PAD));
    }

    std::string TypeStr;
    if (const EnumEntry<unsigned> *Ent = getObjectFileEnumEntry(E.e_type)) {
      TypeStr = Ent->Name.str();
    } else {
      if (E.e_type >= ET_LOPROC)
        TypeStr = "Processor Specific";
      else if (E.e_type >= ET_LOOS)
        TypeStr = "OS Specific";
      else
        TypeStr = "Unknown";
    }
    W.printString("Type", TypeStr + " (0x" + utohexstr(E.e_type) + ")");

    W.printEnum("Machine", E.e_machine, makeArrayRef(ElfMachineType));
    W.printNumber("Version", E.e_version);
    W.printHex("Entry", E.e_entry);
    W.printHex("ProgramHeaderOffset", E.e_phoff);
    W.printHex("SectionHeaderOffset", E.e_shoff);
    if (E.e_machine == EM_MIPS)
      W.printFlags("Flags", E.e_flags, makeArrayRef(ElfHeaderMipsFlags),
                   unsigned(ELF::EF_MIPS_ARCH), unsigned(ELF::EF_MIPS_ABI),
                   unsigned(ELF::EF_MIPS_MACH));
    else if (E.e_machine == EM_AMDGPU) {
      switch (E.e_ident[ELF::EI_ABIVERSION]) {
      default:
        W.printHex("Flags", E.e_flags);
        break;
      case 0:
        // ELFOSABI_AMDGPU_PAL, ELFOSABI_AMDGPU_MESA3D support *_V3 flags.
        LLVM_FALLTHROUGH;
      case ELF::ELFABIVERSION_AMDGPU_HSA_V3:
        W.printFlags("Flags", E.e_flags,
                     makeArrayRef(ElfHeaderAMDGPUFlagsABIVersion3),
                     unsigned(ELF::EF_AMDGPU_MACH));
        break;
      case ELF::ELFABIVERSION_AMDGPU_HSA_V4:
      case ELF::ELFABIVERSION_AMDGPU_HSA_V5:
        W.printFlags("Flags", E.e_flags,
                     makeArrayRef(ElfHeaderAMDGPUFlagsABIVersion4),
                     unsigned(ELF::EF_AMDGPU_MACH),
                     unsigned(ELF::EF_AMDGPU_FEATURE_XNACK_V4),
                     unsigned(ELF::EF_AMDGPU_FEATURE_SRAMECC_V4));
        break;
      }
    } else if (E.e_machine == EM_RISCV)
      W.printFlags("Flags", E.e_flags, makeArrayRef(ElfHeaderRISCVFlags));
    else if (E.e_machine == EM_AVR)
      W.printFlags("Flags", E.e_flags, makeArrayRef(ElfHeaderAVRFlags),
                   unsigned(ELF::EF_AVR_ARCH_MASK));
    else if (E.e_machine == EM_LOONGARCH)
      W.printFlags("Flags", E.e_flags, makeArrayRef(ElfHeaderLoongArchFlags),
                   unsigned(ELF::EF_LOONGARCH_BASE_ABI_MASK));
    else
      W.printFlags("Flags", E.e_flags);
    W.printNumber("HeaderSize", E.e_ehsize);
    W.printNumber("ProgramHeaderEntrySize", E.e_phentsize);
    W.printNumber("ProgramHeaderCount", E.e_phnum);
    W.printNumber("SectionHeaderEntrySize", E.e_shentsize);
    W.printString("SectionHeaderCount",
                  getSectionHeadersNumString(this->Obj, this->FileName));
    W.printString("StringTableSectionIndex",
                  getSectionHeaderTableIndexString(this->Obj, this->FileName));
  }
}

template <class ELFT> void LLVMELFDumper<ELFT>::printGroupSections() {
  DictScope Lists(W, "Groups");
  std::vector<GroupSection> V = this->getGroups();
  DenseMap<uint64_t, const GroupSection *> Map = mapSectionsToGroups(V);
  for (const GroupSection &G : V) {
    DictScope D(W, "Group");
    W.printNumber("Name", G.Name, G.ShName);
    W.printNumber("Index", G.Index);
    W.printNumber("Link", G.Link);
    W.printNumber("Info", G.Info);
    W.printHex("Type", getGroupType(G.Type), G.Type);
    W.startLine() << "Signature: " << G.Signature << "\n";

    ListScope L(W, "Section(s) in group");
    for (const GroupMember &GM : G.Members) {
      const GroupSection *MainGroup = Map[GM.Index];
      if (MainGroup != &G)
        this->reportUniqueWarning(
            "section with index " + Twine(GM.Index) +
            ", included in the group section with index " +
            Twine(MainGroup->Index) +
            ", was also found in the group section with index " +
            Twine(G.Index));
      W.startLine() << GM.Name << " (" << GM.Index << ")\n";
    }
  }

  if (V.empty())
    W.startLine() << "There are no group sections in the file.\n";
}

template <class ELFT> void LLVMELFDumper<ELFT>::printRelocations() {
  ListScope D(W, "Relocations");

  for (const Elf_Shdr &Sec : cantFail(this->Obj.sections())) {
    if (!isRelocationSec<ELFT>(Sec))
      continue;

    StringRef Name = this->getPrintableSectionName(Sec);
    unsigned SecNdx = &Sec - &cantFail(this->Obj.sections()).front();
    W.startLine() << "Section (" << SecNdx << ") " << Name << " {\n";
    W.indent();
    this->printRelocationsHelper(Sec);
    W.unindent();
    W.startLine() << "}\n";
  }
}

template <class ELFT>
void LLVMELFDumper<ELFT>::printRelrReloc(const Elf_Relr &R) {
  W.startLine() << W.hex(R) << "\n";
}

template <class ELFT>
void LLVMELFDumper<ELFT>::printRelRelaReloc(const Relocation<ELFT> &R,
                                            const RelSymbol<ELFT> &RelSym) {
  StringRef SymbolName = RelSym.Name;
  SmallString<32> RelocName;
  this->Obj.getRelocationTypeName(R.Type, RelocName);

  if (opts::ExpandRelocs) {
    DictScope Group(W, "Relocation");
    W.printHex("Offset", R.Offset);
    W.printNumber("Type", RelocName, R.Type);
    W.printNumber("Symbol", !SymbolName.empty() ? SymbolName : "-", R.Symbol);
    if (R.Addend)
      W.printHex("Addend", (uintX_t)*R.Addend);
  } else {
    raw_ostream &OS = W.startLine();
    OS << W.hex(R.Offset) << " " << RelocName << " "
       << (!SymbolName.empty() ? SymbolName : "-");
    if (R.Addend)
      OS << " " << W.hex((uintX_t)*R.Addend);
    OS << "\n";
  }
}

template <class ELFT> void LLVMELFDumper<ELFT>::printSectionHeaders() {
  ListScope SectionsD(W, "Sections");

  int SectionIndex = -1;
  std::vector<EnumEntry<unsigned>> FlagsList =
      getSectionFlagsForTarget(this->Obj.getHeader().e_ident[ELF::EI_OSABI],
                               this->Obj.getHeader().e_machine);
  for (const Elf_Shdr &Sec : cantFail(this->Obj.sections())) {
    DictScope SectionD(W, "Section");
    W.printNumber("Index", ++SectionIndex);
    W.printNumber("Name", this->getPrintableSectionName(Sec), Sec.sh_name);
    W.printHex("Type",
               object::getELFSectionTypeName(this->Obj.getHeader().e_machine,
                                             Sec.sh_type),
               Sec.sh_type);
    W.printFlags("Flags", Sec.sh_flags, makeArrayRef(FlagsList));
    W.printHex("Address", Sec.sh_addr);
    W.printHex("Offset", Sec.sh_offset);
    W.printNumber("Size", Sec.sh_size);
    W.printNumber("Link", Sec.sh_link);
    W.printNumber("Info", Sec.sh_info);
    W.printNumber("AddressAlignment", Sec.sh_addralign);
    W.printNumber("EntrySize", Sec.sh_entsize);

    if (opts::SectionRelocations) {
      ListScope D(W, "Relocations");
      this->printRelocationsHelper(Sec);
    }

    if (opts::SectionSymbols) {
      ListScope D(W, "Symbols");
      if (this->DotSymtabSec) {
        StringRef StrTable = unwrapOrError(
            this->FileName,
            this->Obj.getStringTableForSymtab(*this->DotSymtabSec));
        ArrayRef<Elf_Word> ShndxTable = this->getShndxTable(this->DotSymtabSec);

        typename ELFT::SymRange Symbols = unwrapOrError(
            this->FileName, this->Obj.symbols(this->DotSymtabSec));
        for (const Elf_Sym &Sym : Symbols) {
          const Elf_Shdr *SymSec = unwrapOrError(
              this->FileName,
              this->Obj.getSection(Sym, this->DotSymtabSec, ShndxTable));
          if (SymSec == &Sec)
            printSymbol(Sym, &Sym - &Symbols[0], ShndxTable, StrTable, false,
                        false);
        }
      }
    }

    if (opts::SectionData && Sec.sh_type != ELF::SHT_NOBITS) {
      ArrayRef<uint8_t> Data =
          unwrapOrError(this->FileName, this->Obj.getSectionContents(Sec));
      W.printBinaryBlock(
          "SectionData",
          StringRef(reinterpret_cast<const char *>(Data.data()), Data.size()));
    }
  }
}

template <class ELFT>
void LLVMELFDumper<ELFT>::printSymbolSection(
    const Elf_Sym &Symbol, unsigned SymIndex,
    DataRegion<Elf_Word> ShndxTable) const {
  auto GetSectionSpecialType = [&]() -> Optional<StringRef> {
    if (Symbol.isUndefined())
      return StringRef("Undefined");
    if (Symbol.isProcessorSpecific())
      return StringRef("Processor Specific");
    if (Symbol.isOSSpecific())
      return StringRef("Operating System Specific");
    if (Symbol.isAbsolute())
      return StringRef("Absolute");
    if (Symbol.isCommon())
      return StringRef("Common");
    if (Symbol.isReserved() && Symbol.st_shndx != SHN_XINDEX)
      return StringRef("Reserved");
    return None;
  };

  if (Optional<StringRef> Type = GetSectionSpecialType()) {
    W.printHex("Section", *Type, Symbol.st_shndx);
    return;
  }

  Expected<unsigned> SectionIndex =
      this->getSymbolSectionIndex(Symbol, SymIndex, ShndxTable);
  if (!SectionIndex) {
    assert(Symbol.st_shndx == SHN_XINDEX &&
           "getSymbolSectionIndex should only fail due to an invalid "
           "SHT_SYMTAB_SHNDX table/reference");
    this->reportUniqueWarning(SectionIndex.takeError());
    W.printHex("Section", "Reserved", SHN_XINDEX);
    return;
  }

  Expected<StringRef> SectionName =
      this->getSymbolSectionName(Symbol, *SectionIndex);
  if (!SectionName) {
    // Don't report an invalid section name if the section headers are missing.
    // In such situations, all sections will be "invalid".
    if (!this->ObjF.sections().empty())
      this->reportUniqueWarning(SectionName.takeError());
    else
      consumeError(SectionName.takeError());
    W.printHex("Section", "<?>", *SectionIndex);
  } else {
    W.printHex("Section", *SectionName, *SectionIndex);
  }
}

template <class ELFT>
void LLVMELFDumper<ELFT>::printSymbol(const Elf_Sym &Symbol, unsigned SymIndex,
                                      DataRegion<Elf_Word> ShndxTable,
                                      Optional<StringRef> StrTable,
                                      bool IsDynamic,
                                      bool /*NonVisibilityBitsUsed*/) const {
  std::string FullSymbolName = this->getFullSymbolName(
      Symbol, SymIndex, ShndxTable, StrTable, IsDynamic);
  unsigned char SymbolType = Symbol.getType();

  DictScope D(W, "Symbol");
  W.printNumber("Name", FullSymbolName, Symbol.st_name);
  W.printHex("Value", Symbol.st_value);
  W.printNumber("Size", Symbol.st_size);
  W.printEnum("Binding", Symbol.getBinding(), makeArrayRef(ElfSymbolBindings));
  if (this->Obj.getHeader().e_machine == ELF::EM_AMDGPU &&
      SymbolType >= ELF::STT_LOOS && SymbolType < ELF::STT_HIOS)
    W.printEnum("Type", SymbolType, makeArrayRef(AMDGPUSymbolTypes));
  else
    W.printEnum("Type", SymbolType, makeArrayRef(ElfSymbolTypes));
  if (Symbol.st_other == 0)
    // Usually st_other flag is zero. Do not pollute the output
    // by flags enumeration in that case.
    W.printNumber("Other", 0);
  else {
    std::vector<EnumEntry<unsigned>> SymOtherFlags(std::begin(ElfSymOtherFlags),
                                                   std::end(ElfSymOtherFlags));
    if (this->Obj.getHeader().e_machine == EM_MIPS) {
      // Someones in their infinite wisdom decided to make STO_MIPS_MIPS16
      // flag overlapped with other ST_MIPS_xxx flags. So consider both
      // cases separately.
      if ((Symbol.st_other & STO_MIPS_MIPS16) == STO_MIPS_MIPS16)
        SymOtherFlags.insert(SymOtherFlags.end(),
                             std::begin(ElfMips16SymOtherFlags),
                             std::end(ElfMips16SymOtherFlags));
      else
        SymOtherFlags.insert(SymOtherFlags.end(),
                             std::begin(ElfMipsSymOtherFlags),
                             std::end(ElfMipsSymOtherFlags));
    } else if (this->Obj.getHeader().e_machine == EM_AARCH64) {
      SymOtherFlags.insert(SymOtherFlags.end(),
                           std::begin(ElfAArch64SymOtherFlags),
                           std::end(ElfAArch64SymOtherFlags));
    } else if (this->Obj.getHeader().e_machine == EM_RISCV) {
      SymOtherFlags.insert(SymOtherFlags.end(),
                           std::begin(ElfRISCVSymOtherFlags),
                           std::end(ElfRISCVSymOtherFlags));
    }
    W.printFlags("Other", Symbol.st_other, makeArrayRef(SymOtherFlags), 0x3u);
  }
  printSymbolSection(Symbol, SymIndex, ShndxTable);
}

template <class ELFT>
void LLVMELFDumper<ELFT>::printSymbols(bool PrintSymbols,
                                       bool PrintDynamicSymbols) {
  if (PrintSymbols) {
    ListScope Group(W, "Symbols");
    this->printSymbolsHelper(false);
  }
  if (PrintDynamicSymbols) {
    ListScope Group(W, "DynamicSymbols");
    this->printSymbolsHelper(true);
  }
}

template <class ELFT> void LLVMELFDumper<ELFT>::printDynamicTable() {
  Elf_Dyn_Range Table = this->dynamic_table();
  if (Table.empty())
    return;

  W.startLine() << "DynamicSection [ (" << Table.size() << " entries)\n";

  size_t MaxTagSize = getMaxDynamicTagSize(this->Obj, Table);
  // The "Name/Value" column should be indented from the "Type" column by N
  // spaces, where N = MaxTagSize - length of "Type" (4) + trailing
  // space (1) = -3.
  W.startLine() << "  Tag" << std::string(ELFT::Is64Bits ? 16 : 8, ' ')
                << "Type" << std::string(MaxTagSize - 3, ' ') << "Name/Value\n";

  std::string ValueFmt = "%-" + std::to_string(MaxTagSize) + "s ";
  for (auto Entry : Table) {
    uintX_t Tag = Entry.getTag();
    std::string Value = this->getDynamicEntry(Tag, Entry.getVal());
    W.startLine() << "  " << format_hex(Tag, ELFT::Is64Bits ? 18 : 10, true)
                  << " "
                  << format(ValueFmt.c_str(),
                            this->Obj.getDynamicTagAsString(Tag).c_str())
                  << Value << "\n";
  }
  W.startLine() << "]\n";
}

template <class ELFT> void LLVMELFDumper<ELFT>::printDynamicRelocations() {
  W.startLine() << "Dynamic Relocations {\n";
  W.indent();
  this->printDynamicRelocationsHelper();
  W.unindent();
  W.startLine() << "}\n";
}

template <class ELFT>
void LLVMELFDumper<ELFT>::printProgramHeaders(
    bool PrintProgramHeaders, cl::boolOrDefault PrintSectionMapping) {
  if (PrintProgramHeaders)
    printProgramHeaders();
  if (PrintSectionMapping == cl::BOU_TRUE)
    printSectionMapping();
}

template <class ELFT> void LLVMELFDumper<ELFT>::printProgramHeaders() {
  ListScope L(W, "ProgramHeaders");

  Expected<ArrayRef<Elf_Phdr>> PhdrsOrErr = this->Obj.program_headers();
  if (!PhdrsOrErr) {
    this->reportUniqueWarning("unable to dump program headers: " +
                              toString(PhdrsOrErr.takeError()));
    return;
  }

  for (const Elf_Phdr &Phdr : *PhdrsOrErr) {
    DictScope P(W, "ProgramHeader");
    StringRef Type =
        segmentTypeToString(this->Obj.getHeader().e_machine, Phdr.p_type);

    W.printHex("Type", Type.empty() ? "Unknown" : Type, Phdr.p_type);
    W.printHex("Offset", Phdr.p_offset);
    W.printHex("VirtualAddress", Phdr.p_vaddr);
    W.printHex("PhysicalAddress", Phdr.p_paddr);
    W.printNumber("FileSize", Phdr.p_filesz);
    W.printNumber("MemSize", Phdr.p_memsz);
    W.printFlags("Flags", Phdr.p_flags, makeArrayRef(ElfSegmentFlags));
    W.printNumber("Alignment", Phdr.p_align);
  }
}

template <class ELFT>
void LLVMELFDumper<ELFT>::printVersionSymbolSection(const Elf_Shdr *Sec) {
  ListScope SS(W, "VersionSymbols");
  if (!Sec)
    return;

  StringRef StrTable;
  ArrayRef<Elf_Sym> Syms;
  const Elf_Shdr *SymTabSec;
  Expected<ArrayRef<Elf_Versym>> VerTableOrErr =
      this->getVersionTable(*Sec, &Syms, &StrTable, &SymTabSec);
  if (!VerTableOrErr) {
    this->reportUniqueWarning(VerTableOrErr.takeError());
    return;
  }

  if (StrTable.empty() || Syms.empty() || Syms.size() != VerTableOrErr->size())
    return;

  ArrayRef<Elf_Word> ShNdxTable = this->getShndxTable(SymTabSec);
  for (size_t I = 0, E = Syms.size(); I < E; ++I) {
    DictScope S(W, "Symbol");
    W.printNumber("Version", (*VerTableOrErr)[I].vs_index & VERSYM_VERSION);
    W.printString("Name",
                  this->getFullSymbolName(Syms[I], I, ShNdxTable, StrTable,
                                          /*IsDynamic=*/true));
  }
}

const EnumEntry<unsigned> SymVersionFlags[] = {
    {"Base", "BASE", VER_FLG_BASE},
    {"Weak", "WEAK", VER_FLG_WEAK},
    {"Info", "INFO", VER_FLG_INFO}};

template <class ELFT>
void LLVMELFDumper<ELFT>::printVersionDefinitionSection(const Elf_Shdr *Sec) {
  ListScope SD(W, "VersionDefinitions");
  if (!Sec)
    return;

  Expected<std::vector<VerDef>> V = this->Obj.getVersionDefinitions(*Sec);
  if (!V) {
    this->reportUniqueWarning(V.takeError());
    return;
  }

  for (const VerDef &D : *V) {
    DictScope Def(W, "Definition");
    W.printNumber("Version", D.Version);
    W.printFlags("Flags", D.Flags, makeArrayRef(SymVersionFlags));
    W.printNumber("Index", D.Ndx);
    W.printNumber("Hash", D.Hash);
    W.printString("Name", D.Name.c_str());
    W.printList(
        "Predecessors", D.AuxV,
        [](raw_ostream &OS, const VerdAux &Aux) { OS << Aux.Name.c_str(); });
  }
}

template <class ELFT>
void LLVMELFDumper<ELFT>::printVersionDependencySection(const Elf_Shdr *Sec) {
  ListScope SD(W, "VersionRequirements");
  if (!Sec)
    return;

  Expected<std::vector<VerNeed>> V =
      this->Obj.getVersionDependencies(*Sec, this->WarningHandler);
  if (!V) {
    this->reportUniqueWarning(V.takeError());
    return;
  }

  for (const VerNeed &VN : *V) {
    DictScope Entry(W, "Dependency");
    W.printNumber("Version", VN.Version);
    W.printNumber("Count", VN.Cnt);
    W.printString("FileName", VN.File.c_str());

    ListScope L(W, "Entries");
    for (const VernAux &Aux : VN.AuxV) {
      DictScope Entry(W, "Entry");
      W.printNumber("Hash", Aux.Hash);
      W.printFlags("Flags", Aux.Flags, makeArrayRef(SymVersionFlags));
      W.printNumber("Index", Aux.Other);
      W.printString("Name", Aux.Name.c_str());
    }
  }
}

template <class ELFT> void LLVMELFDumper<ELFT>::printHashHistograms() {
  W.startLine() << "Hash Histogram not implemented!\n";
}

// Returns true if rel/rela section exists, and populates SymbolIndices.
// Otherwise returns false.
template <class ELFT>
static bool getSymbolIndices(const typename ELFT::Shdr *CGRelSection,
                             const ELFFile<ELFT> &Obj,
                             const LLVMELFDumper<ELFT> *Dumper,
                             SmallVector<uint32_t, 128> &SymbolIndices) {
  if (!CGRelSection) {
    Dumper->reportUniqueWarning(
        "relocation section for a call graph section doesn't exist");
    return false;
  }

  if (CGRelSection->sh_type == SHT_REL) {
    typename ELFT::RelRange CGProfileRel;
    Expected<typename ELFT::RelRange> CGProfileRelOrError =
        Obj.rels(*CGRelSection);
    if (!CGProfileRelOrError) {
      Dumper->reportUniqueWarning("unable to load relocations for "
                                  "SHT_LLVM_CALL_GRAPH_PROFILE section: " +
                                  toString(CGProfileRelOrError.takeError()));
      return false;
    }

    CGProfileRel = *CGProfileRelOrError;
    for (const typename ELFT::Rel &Rel : CGProfileRel)
      SymbolIndices.push_back(Rel.getSymbol(Obj.isMips64EL()));
  } else {
    // MC unconditionally produces SHT_REL, but GNU strip/objcopy may convert
    // the format to SHT_RELA
    // (https://sourceware.org/bugzilla/show_bug.cgi?id=28035)
    typename ELFT::RelaRange CGProfileRela;
    Expected<typename ELFT::RelaRange> CGProfileRelaOrError =
        Obj.relas(*CGRelSection);
    if (!CGProfileRelaOrError) {
      Dumper->reportUniqueWarning("unable to load relocations for "
                                  "SHT_LLVM_CALL_GRAPH_PROFILE section: " +
                                  toString(CGProfileRelaOrError.takeError()));
      return false;
    }

    CGProfileRela = *CGProfileRelaOrError;
    for (const typename ELFT::Rela &Rela : CGProfileRela)
      SymbolIndices.push_back(Rela.getSymbol(Obj.isMips64EL()));
  }

  return true;
}

template <class ELFT> void LLVMELFDumper<ELFT>::printCGProfile() {
  llvm::MapVector<const Elf_Shdr *, const Elf_Shdr *> SecToRelocMap;

  auto IsMatch = [](const Elf_Shdr &Sec) -> bool {
    return Sec.sh_type == ELF::SHT_LLVM_CALL_GRAPH_PROFILE;
  };
  this->getSectionAndRelocations(IsMatch, SecToRelocMap);

  for (const auto &CGMapEntry : SecToRelocMap) {
    const Elf_Shdr *CGSection = CGMapEntry.first;
    const Elf_Shdr *CGRelSection = CGMapEntry.second;

    Expected<ArrayRef<Elf_CGProfile>> CGProfileOrErr =
        this->Obj.template getSectionContentsAsArray<Elf_CGProfile>(*CGSection);
    if (!CGProfileOrErr) {
      this->reportUniqueWarning(
          "unable to load the SHT_LLVM_CALL_GRAPH_PROFILE section: " +
          toString(CGProfileOrErr.takeError()));
      return;
    }

    SmallVector<uint32_t, 128> SymbolIndices;
    bool UseReloc =
        getSymbolIndices<ELFT>(CGRelSection, this->Obj, this, SymbolIndices);
    if (UseReloc && SymbolIndices.size() != CGProfileOrErr->size() * 2) {
      this->reportUniqueWarning(
          "number of from/to pairs does not match number of frequencies");
      UseReloc = false;
    }

    ListScope L(W, "CGProfile");
    for (uint32_t I = 0, Size = CGProfileOrErr->size(); I != Size; ++I) {
      const Elf_CGProfile &CGPE = (*CGProfileOrErr)[I];
      DictScope D(W, "CGProfileEntry");
      if (UseReloc) {
        uint32_t From = SymbolIndices[I * 2];
        uint32_t To = SymbolIndices[I * 2 + 1];
        W.printNumber("From", this->getStaticSymbolName(From), From);
        W.printNumber("To", this->getStaticSymbolName(To), To);
      }
      W.printNumber("Weight", CGPE.cgp_weight);
    }
  }
}

template <class ELFT> void LLVMELFDumper<ELFT>::printBBAddrMaps() {
  bool IsRelocatable = this->Obj.getHeader().e_type == ELF::ET_REL;
  for (const Elf_Shdr &Sec : cantFail(this->Obj.sections())) {
    if (Sec.sh_type != SHT_LLVM_BB_ADDR_MAP &&
        Sec.sh_type != SHT_LLVM_BB_ADDR_MAP_V0) {
      continue;
    }
    Optional<const Elf_Shdr *> FunctionSec = None;
    if (IsRelocatable)
      FunctionSec =
          unwrapOrError(this->FileName, this->Obj.getSection(Sec.sh_link));
    ListScope L(W, "BBAddrMap");
    Expected<std::vector<BBAddrMap>> BBAddrMapOrErr =
        this->Obj.decodeBBAddrMap(Sec);
    if (!BBAddrMapOrErr) {
      this->reportUniqueWarning("unable to dump " + this->describe(Sec) + ": " +
                                toString(BBAddrMapOrErr.takeError()));
      continue;
    }
    for (const BBAddrMap &AM : *BBAddrMapOrErr) {
      DictScope D(W, "Function");
      W.printHex("At", AM.Addr);
      SmallVector<uint32_t> FuncSymIndex =
          this->getSymbolIndexesForFunctionAddress(AM.Addr, FunctionSec);
      std::string FuncName = "<?>";
      if (FuncSymIndex.empty())
        this->reportUniqueWarning(
            "could not identify function symbol for address (0x" +
            Twine::utohexstr(AM.Addr) + ") in " + this->describe(Sec));
      else
        FuncName = this->getStaticSymbolName(FuncSymIndex.front());
      W.printString("Name", FuncName);

      ListScope L(W, "BB entries");
      for (const BBAddrMap::BBEntry &BBE : AM.BBEntries) {
        DictScope L(W);
        W.printHex("Offset", BBE.Offset);
        W.printHex("Size", BBE.Size);
        W.printBoolean("HasReturn", BBE.HasReturn);
        W.printBoolean("HasTailCall", BBE.HasTailCall);
        W.printBoolean("IsEHPad", BBE.IsEHPad);
        W.printBoolean("CanFallThrough", BBE.CanFallThrough);
      }
    }
  }
}

template <class ELFT> void LLVMELFDumper<ELFT>::printAddrsig() {
  ListScope L(W, "Addrsig");
  if (!this->DotAddrsigSec)
    return;

  Expected<std::vector<uint64_t>> SymsOrErr =
      decodeAddrsigSection(this->Obj, *this->DotAddrsigSec);
  if (!SymsOrErr) {
    this->reportUniqueWarning(SymsOrErr.takeError());
    return;
  }

  for (uint64_t Sym : *SymsOrErr)
    W.printNumber("Sym", this->getStaticSymbolName(Sym), Sym);
}

template <typename ELFT>
static bool printGNUNoteLLVMStyle(uint32_t NoteType, ArrayRef<uint8_t> Desc,
                                  ScopedPrinter &W) {
  // Return true if we were able to pretty-print the note, false otherwise.
  switch (NoteType) {
  default:
    return false;
  case ELF::NT_GNU_ABI_TAG: {
    const GNUAbiTag &AbiTag = getGNUAbiTag<ELFT>(Desc);
    if (!AbiTag.IsValid) {
      W.printString("ABI", "<corrupt GNU_ABI_TAG>");
      return false;
    } else {
      W.printString("OS", AbiTag.OSName);
      W.printString("ABI", AbiTag.ABI);
    }
    break;
  }
  case ELF::NT_GNU_BUILD_ID: {
    W.printString("Build ID", getGNUBuildId(Desc));
    break;
  }
  case ELF::NT_GNU_GOLD_VERSION:
    W.printString("Version", getDescAsStringRef(Desc));
    break;
  case ELF::NT_GNU_PROPERTY_TYPE_0:
    ListScope D(W, "Property");
    for (const std::string &Property : getGNUPropertyList<ELFT>(Desc))
      W.printString(Property);
    break;
  }
  return true;
}

static bool printAndroidNoteLLVMStyle(uint32_t NoteType, ArrayRef<uint8_t> Desc,
                                      ScopedPrinter &W) {
  // Return true if we were able to pretty-print the note, false otherwise.
  AndroidNoteProperties Props = getAndroidNoteProperties(NoteType, Desc);
  if (Props.empty())
    return false;
  for (const auto &KV : Props)
    W.printString(KV.first, KV.second);
  return true;
}

template <typename ELFT>
static bool printLLVMOMPOFFLOADNoteLLVMStyle(uint32_t NoteType,
                                             ArrayRef<uint8_t> Desc,
                                             ScopedPrinter &W) {
  switch (NoteType) {
  default:
    return false;
  case ELF::NT_LLVM_OPENMP_OFFLOAD_VERSION:
    W.printString("Version", getDescAsStringRef(Desc));
    break;
  case ELF::NT_LLVM_OPENMP_OFFLOAD_PRODUCER:
    W.printString("Producer", getDescAsStringRef(Desc));
    break;
  case ELF::NT_LLVM_OPENMP_OFFLOAD_PRODUCER_VERSION:
    W.printString("Producer version", getDescAsStringRef(Desc));
    break;
  }
  return true;
}

static void printCoreNoteLLVMStyle(const CoreNote &Note, ScopedPrinter &W) {
  W.printNumber("Page Size", Note.PageSize);
  for (const CoreFileMapping &Mapping : Note.Mappings) {
    ListScope D(W, "Mapping");
    W.printHex("Start", Mapping.Start);
    W.printHex("End", Mapping.End);
    W.printHex("Offset", Mapping.Offset);
    W.printString("Filename", Mapping.Filename);
  }
}

template <class ELFT> void LLVMELFDumper<ELFT>::printNotes() {
  ListScope L(W, "Notes");

  std::unique_ptr<DictScope> NoteScope;
  auto StartNotes = [&](Optional<StringRef> SecName,
                        const typename ELFT::Off Offset,
                        const typename ELFT::Addr Size) {
    NoteScope = std::make_unique<DictScope>(W, "NoteSection");
    W.printString("Name", SecName ? *SecName : "<?>");
    W.printHex("Offset", Offset);
    W.printHex("Size", Size);
  };

  auto EndNotes = [&] { NoteScope.reset(); };

  auto ProcessNote = [&](const Elf_Note &Note, bool IsCore) -> Error {
    DictScope D2(W, "Note");
    StringRef Name = Note.getName();
    ArrayRef<uint8_t> Descriptor = Note.getDesc();
    Elf_Word Type = Note.getType();

    // Print the note owner/type.
    W.printString("Owner", Name);
    W.printHex("Data size", Descriptor.size());

    StringRef NoteType =
        getNoteTypeName<ELFT>(Note, this->Obj.getHeader().e_type);
    if (!NoteType.empty())
      W.printString("Type", NoteType);
    else
      W.printString("Type",
                    "Unknown (" + to_string(format_hex(Type, 10)) + ")");

    // Print the description, or fallback to printing raw bytes for unknown
    // owners/if we fail to pretty-print the contents.
    if (Name == "GNU") {
      if (printGNUNoteLLVMStyle<ELFT>(Type, Descriptor, W))
        return Error::success();
    } else if (Name == "FreeBSD") {
      if (Optional<FreeBSDNote> N =
              getFreeBSDNote<ELFT>(Type, Descriptor, IsCore)) {
        W.printString(N->Type, N->Value);
        return Error::success();
      }
    } else if (Name == "AMD") {
      const AMDNote N = getAMDNote<ELFT>(Type, Descriptor);
      if (!N.Type.empty()) {
        W.printString(N.Type, N.Value);
        return Error::success();
      }
    } else if (Name == "AMDGPU") {
      const AMDGPUNote N = getAMDGPUNote<ELFT>(Type, Descriptor);
      if (!N.Type.empty()) {
        W.printString(N.Type, N.Value);
        return Error::success();
      }
    } else if (Name == "LLVMOMPOFFLOAD") {
      if (printLLVMOMPOFFLOADNoteLLVMStyle<ELFT>(Type, Descriptor, W))
        return Error::success();
    } else if (Name == "CORE") {
      if (Type == ELF::NT_FILE) {
        DataExtractor DescExtractor(Descriptor,
                                    ELFT::TargetEndianness == support::little,
                                    sizeof(Elf_Addr));
        if (Expected<CoreNote> N = readCoreNote(DescExtractor)) {
          printCoreNoteLLVMStyle(*N, W);
          return Error::success();
        } else {
          return N.takeError();
        }
      }
    } else if (Name == "Android") {
      if (printAndroidNoteLLVMStyle(Type, Descriptor, W))
        return Error::success();
    }
    if (!Descriptor.empty()) {
      W.printBinaryBlock("Description data", Descriptor);
    }
    return Error::success();
  };

  printNotesHelper(*this, StartNotes, ProcessNote, EndNotes);
}

template <class ELFT> void LLVMELFDumper<ELFT>::printELFLinkerOptions() {
  ListScope L(W, "LinkerOptions");

  unsigned I = -1;
  for (const Elf_Shdr &Shdr : cantFail(this->Obj.sections())) {
    ++I;
    if (Shdr.sh_type != ELF::SHT_LLVM_LINKER_OPTIONS)
      continue;

    Expected<ArrayRef<uint8_t>> ContentsOrErr =
        this->Obj.getSectionContents(Shdr);
    if (!ContentsOrErr) {
      this->reportUniqueWarning("unable to read the content of the "
                                "SHT_LLVM_LINKER_OPTIONS section: " +
                                toString(ContentsOrErr.takeError()));
      continue;
    }
    if (ContentsOrErr->empty())
      continue;

    if (ContentsOrErr->back() != 0) {
      this->reportUniqueWarning("SHT_LLVM_LINKER_OPTIONS section at index " +
                                Twine(I) +
                                " is broken: the "
                                "content is not null-terminated");
      continue;
    }

    SmallVector<StringRef, 16> Strings;
    toStringRef(ContentsOrErr->drop_back()).split(Strings, '\0');
    if (Strings.size() % 2 != 0) {
      this->reportUniqueWarning(
          "SHT_LLVM_LINKER_OPTIONS section at index " + Twine(I) +
          " is broken: an incomplete "
          "key-value pair was found. The last possible key was: \"" +
          Strings.back() + "\"");
      continue;
    }

    for (size_t I = 0; I < Strings.size(); I += 2)
      W.printString(Strings[I], Strings[I + 1]);
  }
}

template <class ELFT> void LLVMELFDumper<ELFT>::printDependentLibs() {
  ListScope L(W, "DependentLibs");
  this->printDependentLibsHelper(
      [](const Elf_Shdr &) {},
      [this](StringRef Lib, uint64_t) { W.printString(Lib); });
}

template <class ELFT> void LLVMELFDumper<ELFT>::printStackSizes() {
  ListScope L(W, "StackSizes");
  if (this->Obj.getHeader().e_type == ELF::ET_REL)
    this->printRelocatableStackSizes([]() {});
  else
    this->printNonRelocatableStackSizes([]() {});
}

template <class ELFT>
void LLVMELFDumper<ELFT>::printStackSizeEntry(uint64_t Size,
                                              ArrayRef<std::string> FuncNames) {
  DictScope D(W, "Entry");
  W.printList("Functions", FuncNames);
  W.printHex("Size", Size);
}

template <class ELFT>
void LLVMELFDumper<ELFT>::printMipsGOT(const MipsGOTParser<ELFT> &Parser) {
  auto PrintEntry = [&](const Elf_Addr *E) {
    W.printHex("Address", Parser.getGotAddress(E));
    W.printNumber("Access", Parser.getGotOffset(E));
    W.printHex("Initial", *E);
  };

  DictScope GS(W, Parser.IsStatic ? "Static GOT" : "Primary GOT");

  W.printHex("Canonical gp value", Parser.getGp());
  {
    ListScope RS(W, "Reserved entries");
    {
      DictScope D(W, "Entry");
      PrintEntry(Parser.getGotLazyResolver());
      W.printString("Purpose", StringRef("Lazy resolver"));
    }

    if (Parser.getGotModulePointer()) {
      DictScope D(W, "Entry");
      PrintEntry(Parser.getGotModulePointer());
      W.printString("Purpose", StringRef("Module pointer (GNU extension)"));
    }
  }
  {
    ListScope LS(W, "Local entries");
    for (auto &E : Parser.getLocalEntries()) {
      DictScope D(W, "Entry");
      PrintEntry(&E);
    }
  }

  if (Parser.IsStatic)
    return;

  {
    ListScope GS(W, "Global entries");
    for (auto &E : Parser.getGlobalEntries()) {
      DictScope D(W, "Entry");

      PrintEntry(&E);

      const Elf_Sym &Sym = *Parser.getGotSym(&E);
      W.printHex("Value", Sym.st_value);
      W.printEnum("Type", Sym.getType(), makeArrayRef(ElfSymbolTypes));

      const unsigned SymIndex = &Sym - this->dynamic_symbols().begin();
      DataRegion<Elf_Word> ShndxTable(
          (const Elf_Word *)this->DynSymTabShndxRegion.Addr, this->Obj.end());
      printSymbolSection(Sym, SymIndex, ShndxTable);

      std::string SymName = this->getFullSymbolName(
          Sym, SymIndex, ShndxTable, this->DynamicStringTable, true);
      W.printNumber("Name", SymName, Sym.st_name);
    }
  }

  W.printNumber("Number of TLS and multi-GOT entries",
                uint64_t(Parser.getOtherEntries().size()));
}

template <class ELFT>
void LLVMELFDumper<ELFT>::printMipsPLT(const MipsGOTParser<ELFT> &Parser) {
  auto PrintEntry = [&](const Elf_Addr *E) {
    W.printHex("Address", Parser.getPltAddress(E));
    W.printHex("Initial", *E);
  };

  DictScope GS(W, "PLT GOT");

  {
    ListScope RS(W, "Reserved entries");
    {
      DictScope D(W, "Entry");
      PrintEntry(Parser.getPltLazyResolver());
      W.printString("Purpose", StringRef("PLT lazy resolver"));
    }

    if (auto E = Parser.getPltModulePointer()) {
      DictScope D(W, "Entry");
      PrintEntry(E);
      W.printString("Purpose", StringRef("Module pointer"));
    }
  }
  {
    ListScope LS(W, "Entries");
    DataRegion<Elf_Word> ShndxTable(
        (const Elf_Word *)this->DynSymTabShndxRegion.Addr, this->Obj.end());
    for (auto &E : Parser.getPltEntries()) {
      DictScope D(W, "Entry");
      PrintEntry(&E);

      const Elf_Sym &Sym = *Parser.getPltSym(&E);
      W.printHex("Value", Sym.st_value);
      W.printEnum("Type", Sym.getType(), makeArrayRef(ElfSymbolTypes));
      printSymbolSection(Sym, &Sym - this->dynamic_symbols().begin(),
                         ShndxTable);

      const Elf_Sym *FirstSym = cantFail(
          this->Obj.template getEntry<Elf_Sym>(*Parser.getPltSymTable(), 0));
      std::string SymName = this->getFullSymbolName(
          Sym, &Sym - FirstSym, ShndxTable, Parser.getPltStrTable(), true);
      W.printNumber("Name", SymName, Sym.st_name);
    }
  }
}

template <class ELFT> void LLVMELFDumper<ELFT>::printMipsABIFlags() {
  const Elf_Mips_ABIFlags<ELFT> *Flags;
  if (Expected<const Elf_Mips_ABIFlags<ELFT> *> SecOrErr =
          getMipsAbiFlagsSection(*this)) {
    Flags = *SecOrErr;
    if (!Flags) {
      W.startLine() << "There is no .MIPS.abiflags section in the file.\n";
      return;
    }
  } else {
    this->reportUniqueWarning(SecOrErr.takeError());
    return;
  }

  raw_ostream &OS = W.getOStream();
  DictScope GS(W, "MIPS ABI Flags");

  W.printNumber("Version", Flags->version);
  W.startLine() << "ISA: ";
  if (Flags->isa_rev <= 1)
    OS << format("MIPS%u", Flags->isa_level);
  else
    OS << format("MIPS%ur%u", Flags->isa_level, Flags->isa_rev);
  OS << "\n";
  W.printEnum("ISA Extension", Flags->isa_ext, makeArrayRef(ElfMipsISAExtType));
  W.printFlags("ASEs", Flags->ases, makeArrayRef(ElfMipsASEFlags));
  W.printEnum("FP ABI", Flags->fp_abi, makeArrayRef(ElfMipsFpABIType));
  W.printNumber("GPR size", getMipsRegisterSize(Flags->gpr_size));
  W.printNumber("CPR1 size", getMipsRegisterSize(Flags->cpr1_size));
  W.printNumber("CPR2 size", getMipsRegisterSize(Flags->cpr2_size));
  W.printFlags("Flags 1", Flags->flags1, makeArrayRef(ElfMipsFlags1));
  W.printHex("Flags 2", Flags->flags2);
}

template <class ELFT>
void JSONELFDumper<ELFT>::printFileSummary(StringRef FileStr, ObjectFile &Obj,
                                           ArrayRef<std::string> InputFilenames,
                                           const Archive *A) {
  FileScope = std::make_unique<DictScope>(this->W, FileStr);
  DictScope D(this->W, "FileSummary");
  this->W.printString("File", FileStr);
  this->W.printString("Format", Obj.getFileFormatName());
  this->W.printString("Arch", Triple::getArchTypeName(Obj.getArch()));
  this->W.printString(
      "AddressSize",
      std::string(formatv("{0}bit", 8 * Obj.getBytesInAddress())));
  this->printLoadName();
}
