//===-- XCOFFDumper.cpp - XCOFF dumping utility -----------------*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// This file implements an XCOFF specific dumper for llvm-readobj.
//
//===----------------------------------------------------------------------===//

#include "ObjDumper.h"
#include "llvm-readobj.h"
#include "llvm/Object/XCOFFObjectFile.h"
#include "llvm/Support/FormattedStream.h"
#include "llvm/Support/ScopedPrinter.h"

#include <ctime>

using namespace llvm;
using namespace object;

namespace {

class XCOFFDumper : public ObjDumper {

public:
  XCOFFDumper(const XCOFFObjectFile &Obj, ScopedPrinter &Writer)
      : ObjDumper(Writer, Obj.getFileName()), Obj(Obj) {}

  void printFileHeaders() override;
  void printAuxiliaryHeader() override;
  void printSectionHeaders() override;
  void printRelocations() override;
  void printSymbols() override;
  void printDynamicSymbols() override;
  void printUnwindInfo() override;
  void printStackMap() const override;
  void printNeededLibraries() override;
  void printStringTable() override;
  void printExceptionSection() override;
  void printLoaderSection(bool PrintHeader, bool PrintSymbols,
                          bool PrintRelocations) override;

  ScopedPrinter &getScopedPrinter() const { return W; }

private:
  template <typename T> void printSectionHeaders(ArrayRef<T> Sections);
  template <typename T> void printGenericSectionHeader(T &Sec) const;
  template <typename T> void printOverflowSectionHeader(T &Sec) const;
  template <typename T>
  void printExceptionSectionEntry(const T &ExceptionSectEnt) const;
  template <typename T> void printExceptionSectionEntries() const;
  template <typename T> const T *getAuxEntPtr(uintptr_t AuxAddress);
  void printFileAuxEnt(const XCOFFFileAuxEnt *AuxEntPtr);
  void printCsectAuxEnt(XCOFFCsectAuxRef AuxEntRef);
  void printSectAuxEntForStat(const XCOFFSectAuxEntForStat *AuxEntPtr);
  void printExceptionAuxEnt(const XCOFFExceptionAuxEnt *AuxEntPtr);
  void printFunctionAuxEnt(const XCOFFFunctionAuxEnt32 *AuxEntPtr);
  void printFunctionAuxEnt(const XCOFFFunctionAuxEnt64 *AuxEntPtr);
  void printBlockAuxEnt(const XCOFFBlockAuxEnt32 *AuxEntPtr);
  void printBlockAuxEnt(const XCOFFBlockAuxEnt64 *AuxEntPtr);
  template <typename T> void printSectAuxEntForDWARF(const T *AuxEntPtr);
  void printSymbol(const SymbolRef &);
  template <typename RelTy> void printRelocation(RelTy Reloc);
  template <typename Shdr, typename RelTy>
  void printRelocations(ArrayRef<Shdr> Sections);
  void printAuxiliaryHeader(const XCOFFAuxiliaryHeader32 *AuxHeader);
  void printAuxiliaryHeader(const XCOFFAuxiliaryHeader64 *AuxHeader);
  void printLoaderSectionHeader(uintptr_t LoaderSectAddr);
  void printLoaderSectionSymbols(uintptr_t LoaderSectAddr);
  template <typename LoaderSectionSymbolEntry, typename LoaderSectionHeader>
  void printLoaderSectionSymbolsHelper(uintptr_t LoaderSectAddr);
  template <typename LoadSectionRelocTy>
  void printLoaderSectionRelocationEntry(LoadSectionRelocTy *LoaderSecRelEntPtr,
                                         StringRef SymbolName);
  void printLoaderSectionRelocationEntries(uintptr_t LoaderSectAddr);
  template <typename LoaderSectionHeader, typename LoaderSectionSymbolEntry,
            typename LoaderSectionRelocationEntry>
  void printLoaderSectionRelocationEntriesHelper(uintptr_t LoaderSectAddr);

  const XCOFFObjectFile &Obj;
  const static int32_t FirstSymIdxOfLoaderSec = 3;
};
} // anonymous namespace

void XCOFFDumper::printFileHeaders() {
  DictScope DS(W, "FileHeader");
  W.printHex("Magic", Obj.getMagic());
  W.printNumber("NumberOfSections", Obj.getNumberOfSections());

  // Negative timestamp values are reserved for future use.
  int32_t TimeStamp = Obj.getTimeStamp();
  if (TimeStamp > 0) {
    // This handling of the time stamp assumes that the host system's time_t is
    // compatible with AIX time_t. If a platform is not compatible, the lit
    // tests will let us know.
    time_t TimeDate = TimeStamp;

    char FormattedTime[21] = {};
    size_t BytesWritten =
        strftime(FormattedTime, 21, "%Y-%m-%dT%H:%M:%SZ", gmtime(&TimeDate));
    if (BytesWritten)
      W.printHex("TimeStamp", FormattedTime, TimeStamp);
    else
      W.printHex("Timestamp", TimeStamp);
  } else {
    W.printHex("TimeStamp", TimeStamp == 0 ? "None" : "Reserved Value",
               TimeStamp);
  }

  // The number of symbol table entries is an unsigned value in 64-bit objects
  // and a signed value (with negative values being 'reserved') in 32-bit
  // objects.
  if (Obj.is64Bit()) {
    W.printHex("SymbolTableOffset", Obj.getSymbolTableOffset64());
    W.printNumber("SymbolTableEntries", Obj.getNumberOfSymbolTableEntries64());
  } else {
    W.printHex("SymbolTableOffset", Obj.getSymbolTableOffset32());
    int32_t SymTabEntries = Obj.getRawNumberOfSymbolTableEntries32();
    if (SymTabEntries >= 0)
      W.printNumber("SymbolTableEntries", SymTabEntries);
    else
      W.printHex("SymbolTableEntries", "Reserved Value", SymTabEntries);
  }

  W.printHex("OptionalHeaderSize", Obj.getOptionalHeaderSize());
  W.printHex("Flags", Obj.getFlags());

  // TODO FIXME Add support for the auxiliary header (if any) once
  // XCOFFObjectFile has the necessary support.
}

void XCOFFDumper::printAuxiliaryHeader() {
  DictScope DS(W, "AuxiliaryHeader");

  if (Obj.is64Bit())
    printAuxiliaryHeader(Obj.auxiliaryHeader64());
  else
    printAuxiliaryHeader(Obj.auxiliaryHeader32());
}

void XCOFFDumper::printSectionHeaders() {
  if (Obj.is64Bit())
    printSectionHeaders(Obj.sections64());
  else
    printSectionHeaders(Obj.sections32());
}

void XCOFFDumper::printLoaderSection(bool PrintHeader, bool PrintSymbols,
                                     bool PrintRelocations) {
  DictScope DS(W, "Loader Section");
  Expected<uintptr_t> LoaderSectionAddrOrError =
      Obj.getSectionFileOffsetToRawData(XCOFF::STYP_LOADER);
  if (!LoaderSectionAddrOrError) {
    reportUniqueWarning(LoaderSectionAddrOrError.takeError());
    return;
  }
  uintptr_t LoaderSectionAddr = LoaderSectionAddrOrError.get();

  if (LoaderSectionAddr == 0)
    return;

  W.indent();
  if (PrintHeader)
    printLoaderSectionHeader(LoaderSectionAddr);

  if (PrintSymbols)
    printLoaderSectionSymbols(LoaderSectionAddr);

  if (PrintRelocations)
    printLoaderSectionRelocationEntries(LoaderSectionAddr);

  W.unindent();
}

void XCOFFDumper::printLoaderSectionHeader(uintptr_t LoaderSectionAddr) {
  DictScope DS(W, "Loader Section Header");

  auto PrintLoadSecHeaderCommon = [&](const auto *LDHeader) {
    W.printNumber("Version", LDHeader->Version);
    W.printNumber("NumberOfSymbolEntries", LDHeader->NumberOfSymTabEnt);
    W.printNumber("NumberOfRelocationEntries", LDHeader->NumberOfRelTabEnt);
    W.printNumber("LengthOfImportFileIDStringTable",
                  LDHeader->LengthOfImpidStrTbl);
    W.printNumber("NumberOfImportFileIDs", LDHeader->NumberOfImpid);
    W.printHex("OffsetToImportFileIDs", LDHeader->OffsetToImpid);
    W.printNumber("LengthOfStringTable", LDHeader->LengthOfStrTbl);
    W.printHex("OffsetToStringTable", LDHeader->OffsetToStrTbl);
  };

  if (Obj.is64Bit()) {
    const LoaderSectionHeader64 *LoaderSec64 =
        reinterpret_cast<const LoaderSectionHeader64 *>(LoaderSectionAddr);
    PrintLoadSecHeaderCommon(LoaderSec64);
    W.printHex("OffsetToSymbolTable", LoaderSec64->OffsetToSymTbl);
    W.printHex("OffsetToRelocationEntries", LoaderSec64->OffsetToRelEnt);
  } else {
    const LoaderSectionHeader32 *LoaderSec32 =
        reinterpret_cast<const LoaderSectionHeader32 *>(LoaderSectionAddr);
    PrintLoadSecHeaderCommon(LoaderSec32);
  }
}

const EnumEntry<XCOFF::StorageClass> SymStorageClass[] = {
#define ECase(X)                                                               \
  { #X, XCOFF::X }
    ECase(C_NULL),  ECase(C_AUTO),    ECase(C_EXT),     ECase(C_STAT),
    ECase(C_REG),   ECase(C_EXTDEF),  ECase(C_LABEL),   ECase(C_ULABEL),
    ECase(C_MOS),   ECase(C_ARG),     ECase(C_STRTAG),  ECase(C_MOU),
    ECase(C_UNTAG), ECase(C_TPDEF),   ECase(C_USTATIC), ECase(C_ENTAG),
    ECase(C_MOE),   ECase(C_REGPARM), ECase(C_FIELD),   ECase(C_BLOCK),
    ECase(C_FCN),   ECase(C_EOS),     ECase(C_FILE),    ECase(C_LINE),
    ECase(C_ALIAS), ECase(C_HIDDEN),  ECase(C_HIDEXT),  ECase(C_BINCL),
    ECase(C_EINCL), ECase(C_INFO),    ECase(C_WEAKEXT), ECase(C_DWARF),
    ECase(C_GSYM),  ECase(C_LSYM),    ECase(C_PSYM),    ECase(C_RSYM),
    ECase(C_RPSYM), ECase(C_STSYM),   ECase(C_TCSYM),   ECase(C_BCOMM),
    ECase(C_ECOML), ECase(C_ECOMM),   ECase(C_DECL),    ECase(C_ENTRY),
    ECase(C_FUN),   ECase(C_BSTAT),   ECase(C_ESTAT),   ECase(C_GTLS),
    ECase(C_STTLS), ECase(C_EFCN)
#undef ECase
};

template <typename LoaderSectionSymbolEntry, typename LoaderSectionHeader>
void XCOFFDumper::printLoaderSectionSymbolsHelper(uintptr_t LoaderSectionAddr) {
  const LoaderSectionHeader *LoadSecHeader =
      reinterpret_cast<const LoaderSectionHeader *>(LoaderSectionAddr);
  const LoaderSectionSymbolEntry *LoadSecSymEntPtr =
      reinterpret_cast<LoaderSectionSymbolEntry *>(
          LoaderSectionAddr + uintptr_t(LoadSecHeader->getOffsetToSymTbl()));

  for (uint32_t i = 0; i < LoadSecHeader->NumberOfSymTabEnt;
       ++i, ++LoadSecSymEntPtr) {
    if (Error E = Binary::checkOffset(
            Obj.getMemoryBufferRef(),
            LoaderSectionAddr + uintptr_t(LoadSecHeader->getOffsetToSymTbl()) +
                (i * sizeof(LoaderSectionSymbolEntry)),
            sizeof(LoaderSectionSymbolEntry))) {
      reportUniqueWarning(std::move(E));
      return;
    }

    Expected<StringRef> SymbolNameOrErr =
        LoadSecSymEntPtr->getSymbolName(LoadSecHeader);
    if (!SymbolNameOrErr) {
      reportUniqueWarning(SymbolNameOrErr.takeError());
      return;
    }

    DictScope DS(W, "Symbol");
    W.printString("Name", SymbolNameOrErr.get());
    W.printHex("Virtual Address", LoadSecSymEntPtr->Value);
    W.printNumber("SectionNum", LoadSecSymEntPtr->SectionNumber);
    W.printHex("SymbolType", LoadSecSymEntPtr->SymbolType);
    W.printEnum("StorageClass",
                static_cast<uint8_t>(LoadSecSymEntPtr->StorageClass),
                ArrayRef(SymStorageClass));
    W.printHex("ImportFileID", LoadSecSymEntPtr->ImportFileID);
    W.printNumber("ParameterTypeCheck", LoadSecSymEntPtr->ParameterTypeCheck);
  }
}

void XCOFFDumper::printLoaderSectionSymbols(uintptr_t LoaderSectionAddr) {
  DictScope DS(W, "Loader Section Symbols");
  if (Obj.is64Bit())
    printLoaderSectionSymbolsHelper<LoaderSectionSymbolEntry64,
                                    LoaderSectionHeader64>(LoaderSectionAddr);
  else
    printLoaderSectionSymbolsHelper<LoaderSectionSymbolEntry32,
                                    LoaderSectionHeader32>(LoaderSectionAddr);
}

const EnumEntry<XCOFF::RelocationType> RelocationTypeNameclass[] = {
#define ECase(X)                                                               \
  { #X, XCOFF::X }
    ECase(R_POS),    ECase(R_RL),     ECase(R_RLA),    ECase(R_NEG),
    ECase(R_REL),    ECase(R_TOC),    ECase(R_TRL),    ECase(R_TRLA),
    ECase(R_GL),     ECase(R_TCL),    ECase(R_REF),    ECase(R_BA),
    ECase(R_BR),     ECase(R_RBA),    ECase(R_RBR),    ECase(R_TLS),
    ECase(R_TLS_IE), ECase(R_TLS_LD), ECase(R_TLS_LE), ECase(R_TLSM),
    ECase(R_TLSML),  ECase(R_TOCU),   ECase(R_TOCL)
#undef ECase
};

// From the XCOFF specification: there are five implicit external symbols, one
// each for the .text, .data, .bss, .tdata, and .tbss sections. These symbols
// are referenced from the relocation table entries using symbol table index
// values 0, 1, 2, -1, and -2, respectively.
static const char *getImplicitLoaderSectionSymName(int SymIndx) {
  switch (SymIndx) {
  default:
    return "Unkown Symbol Name";
  case -2:
    return ".tbss";
  case -1:
    return ".tdata";
  case 0:
    return ".text";
  case 1:
    return ".data";
  case 2:
    return ".bss";
  }
}

template <typename LoadSectionRelocTy>
void XCOFFDumper::printLoaderSectionRelocationEntry(
    LoadSectionRelocTy *LoaderSecRelEntPtr, StringRef SymbolName) {
  uint16_t Type = LoaderSecRelEntPtr->Type;
  if (opts::ExpandRelocs) {
    DictScope DS(W, "Relocation");
    auto IsRelocationSigned = [](uint8_t Info) {
      return Info & XCOFF::XR_SIGN_INDICATOR_MASK;
    };
    auto IsFixupIndicated = [](uint8_t Info) {
      return Info & XCOFF::XR_FIXUP_INDICATOR_MASK;
    };
    auto GetRelocatedLength = [](uint8_t Info) {
      // The relocation encodes the bit length being relocated minus 1. Add
      // back
      //   the 1 to get the actual length being relocated.
      return (Info & XCOFF::XR_BIASED_LENGTH_MASK) + 1;
    };

    uint8_t Info = Type >> 8;
    W.printHex("Virtual Address", LoaderSecRelEntPtr->VirtualAddr);
    W.printNumber("Symbol", SymbolName, LoaderSecRelEntPtr->SymbolIndex);
    W.printString("IsSigned", IsRelocationSigned(Info) ? "Yes" : "No");
    W.printNumber("FixupBitValue", IsFixupIndicated(Info) ? 1 : 0);
    W.printNumber("Length", GetRelocatedLength(Info));
    W.printEnum("Type", static_cast<uint8_t>(Type),
                ArrayRef(RelocationTypeNameclass));
    W.printNumber("SectionNumber", LoaderSecRelEntPtr->SectionNum);
  } else {
    W.startLine() << format_hex(LoaderSecRelEntPtr->VirtualAddr,
                                Obj.is64Bit() ? 18 : 10)
                  << " " << format_hex(Type, 6) << " ("
                  << XCOFF::getRelocationTypeString(
                         static_cast<XCOFF::RelocationType>(Type))
                  << ")" << format_decimal(LoaderSecRelEntPtr->SectionNum, 8)
                  << "    " << SymbolName << " ("
                  << LoaderSecRelEntPtr->SymbolIndex << ")\n";
  }
}

template <typename LoaderSectionHeader, typename LoaderSectionSymbolEntry,
          typename LoaderSectionRelocationEntry>
void XCOFFDumper::printLoaderSectionRelocationEntriesHelper(
    uintptr_t LoaderSectionAddr) {
  const LoaderSectionHeader *LoaderSec =
      reinterpret_cast<const LoaderSectionHeader *>(LoaderSectionAddr);
  const LoaderSectionRelocationEntry *LoaderSecRelEntPtr =
      reinterpret_cast<const LoaderSectionRelocationEntry *>(
          LoaderSectionAddr + uintptr_t(LoaderSec->getOffsetToRelEnt()));

  if (!opts::ExpandRelocs)
    W.startLine() << center_justify("Vaddr", Obj.is64Bit() ? 18 : 10)
                  << center_justify("Type", 15) << right_justify("SecNum", 8)
                  << center_justify("SymbolName (Index) ", 24) << "\n";

  for (uint32_t i = 0; i < LoaderSec->NumberOfRelTabEnt;
       ++i, ++LoaderSecRelEntPtr) {
    StringRef SymbolName;
    if (LoaderSecRelEntPtr->SymbolIndex >= FirstSymIdxOfLoaderSec) {
      // Because there are implicit symbol index values (-2, -1, 0, 1, 2),
      // LoaderSecRelEnt.SymbolIndex - FirstSymIdxOfLoaderSec will get the
      // real symbol from the symbol table.
      const uint64_t SymOffset =
          (LoaderSecRelEntPtr->SymbolIndex - FirstSymIdxOfLoaderSec) *
          sizeof(LoaderSectionSymbolEntry);
      const LoaderSectionSymbolEntry *LoaderSecRelSymEntPtr =
          reinterpret_cast<LoaderSectionSymbolEntry *>(
              LoaderSectionAddr + uintptr_t(LoaderSec->getOffsetToSymTbl()) +
              SymOffset);

      Expected<StringRef> SymbolNameOrErr =
          LoaderSecRelSymEntPtr->getSymbolName(LoaderSec);
      if (!SymbolNameOrErr) {
        reportUniqueWarning(SymbolNameOrErr.takeError());
        return;
      }
      SymbolName = SymbolNameOrErr.get();
    } else
      SymbolName =
          getImplicitLoaderSectionSymName(LoaderSecRelEntPtr->SymbolIndex);

    printLoaderSectionRelocationEntry(LoaderSecRelEntPtr, SymbolName);
  }
}

void XCOFFDumper::printLoaderSectionRelocationEntries(
    uintptr_t LoaderSectionAddr) {
  DictScope DS(W, "Loader Section Relocations");

  if (Obj.is64Bit())
    printLoaderSectionRelocationEntriesHelper<LoaderSectionHeader64,
                                              LoaderSectionSymbolEntry64,
                                              LoaderSectionRelocationEntry64>(
        LoaderSectionAddr);
  else
    printLoaderSectionRelocationEntriesHelper<LoaderSectionHeader32,
                                              LoaderSectionSymbolEntry32,
                                              LoaderSectionRelocationEntry32>(
        LoaderSectionAddr);
}

template <typename T>
void XCOFFDumper::printExceptionSectionEntry(const T &ExceptionSectEnt) const {
  if (ExceptionSectEnt.getReason())
    W.printHex("Trap Instr Addr", ExceptionSectEnt.getTrapInstAddr());
  else {
    uint32_t SymIdx = ExceptionSectEnt.getSymbolIndex();
    Expected<StringRef> ErrOrSymbolName = Obj.getSymbolNameByIndex(SymIdx);
    if (Error E = ErrOrSymbolName.takeError()) {
      reportUniqueWarning(std::move(E));
      return;
    }
    StringRef SymName = *ErrOrSymbolName;

    W.printNumber("Symbol", SymName, SymIdx);
  }
  W.printNumber("LangID", ExceptionSectEnt.getLangID());
  W.printNumber("Reason", ExceptionSectEnt.getReason());
}

template <typename T> void XCOFFDumper::printExceptionSectionEntries() const {
  Expected<ArrayRef<T>> ExceptSectEntsOrErr = Obj.getExceptionEntries<T>();
  if (Error E = ExceptSectEntsOrErr.takeError()) {
    reportUniqueWarning(std::move(E));
    return;
  }
  ArrayRef<T> ExceptSectEnts = *ExceptSectEntsOrErr;

  DictScope DS(W, "Exception section");
  if (ExceptSectEnts.empty())
    return;
  for (auto &Ent : ExceptSectEnts)
    printExceptionSectionEntry(Ent);
}

void XCOFFDumper::printExceptionSection() {
  if (Obj.is64Bit())
    printExceptionSectionEntries<ExceptionSectionEntry64>();
  else
    printExceptionSectionEntries<ExceptionSectionEntry32>();
}

void XCOFFDumper::printRelocations() {
  if (Obj.is64Bit())
    printRelocations<XCOFFSectionHeader64, XCOFFRelocation64>(Obj.sections64());
  else
    printRelocations<XCOFFSectionHeader32, XCOFFRelocation32>(Obj.sections32());
}

template <typename RelTy> void XCOFFDumper::printRelocation(RelTy Reloc) {
  Expected<StringRef> ErrOrSymbolName =
      Obj.getSymbolNameByIndex(Reloc.SymbolIndex);
  if (Error E = ErrOrSymbolName.takeError()) {
    reportUniqueWarning(std::move(E));
    return;
  }
  StringRef SymbolName = *ErrOrSymbolName;
  StringRef RelocName = XCOFF::getRelocationTypeString(Reloc.Type);
  if (opts::ExpandRelocs) {
    DictScope Group(W, "Relocation");
    W.printHex("Virtual Address", Reloc.VirtualAddress);
    W.printNumber("Symbol", SymbolName, Reloc.SymbolIndex);
    W.printString("IsSigned", Reloc.isRelocationSigned() ? "Yes" : "No");
    W.printNumber("FixupBitValue", Reloc.isFixupIndicated() ? 1 : 0);
    W.printNumber("Length", Reloc.getRelocatedLength());
    W.printEnum("Type", (uint8_t)Reloc.Type, ArrayRef(RelocationTypeNameclass));
  } else {
    raw_ostream &OS = W.startLine();
    OS << W.hex(Reloc.VirtualAddress) << " " << RelocName << " " << SymbolName
       << "(" << Reloc.SymbolIndex << ") " << W.hex(Reloc.Info) << "\n";
  }
}

template <typename Shdr, typename RelTy>
void XCOFFDumper::printRelocations(ArrayRef<Shdr> Sections) {
  ListScope LS(W, "Relocations");
  uint16_t Index = 0;
  for (const Shdr &Sec : Sections) {
    ++Index;
    // Only the .text, .data, .tdata, and STYP_DWARF sections have relocation.
    if (Sec.Flags != XCOFF::STYP_TEXT && Sec.Flags != XCOFF::STYP_DATA &&
        Sec.Flags != XCOFF::STYP_TDATA && Sec.Flags != XCOFF::STYP_DWARF)
      continue;
    Expected<ArrayRef<RelTy>> ErrOrRelocations = Obj.relocations<Shdr, RelTy>(Sec);
    if (Error E = ErrOrRelocations.takeError()) {
      reportUniqueWarning(std::move(E));
      continue;
    }

    const ArrayRef<RelTy> Relocations = *ErrOrRelocations;
    if (Relocations.empty())
      continue;

    W.startLine() << "Section (index: " << Index << ") " << Sec.getName()
                  << " {\n";
    W.indent();

    for (const RelTy Reloc : Relocations)
      printRelocation(Reloc);

    W.unindent();
    W.startLine() << "}\n";
  }
}

const EnumEntry<XCOFF::CFileStringType> FileStringType[] = {
#define ECase(X)                                                               \
  { #X, XCOFF::X }
    ECase(XFT_FN), ECase(XFT_CT), ECase(XFT_CV), ECase(XFT_CD)
#undef ECase
};

const EnumEntry<XCOFF::SymbolAuxType> SymAuxType[] = {
#define ECase(X)                                                               \
  { #X, XCOFF::X }
    ECase(AUX_EXCEPT), ECase(AUX_FCN), ECase(AUX_SYM), ECase(AUX_FILE),
    ECase(AUX_CSECT),  ECase(AUX_SECT)
#undef ECase
};

void XCOFFDumper::printFileAuxEnt(const XCOFFFileAuxEnt *AuxEntPtr) {
  assert((!Obj.is64Bit() || AuxEntPtr->AuxType == XCOFF::AUX_FILE) &&
         "Mismatched auxiliary type!");
  StringRef FileName =
      unwrapOrError(Obj.getFileName(), Obj.getCFileName(AuxEntPtr));
  DictScope SymDs(W, "File Auxiliary Entry");
  W.printNumber("Index",
                Obj.getSymbolIndex(reinterpret_cast<uintptr_t>(AuxEntPtr)));
  W.printString("Name", FileName);
  W.printEnum("Type", static_cast<uint8_t>(AuxEntPtr->Type),
              ArrayRef(FileStringType));
  if (Obj.is64Bit()) {
    W.printEnum("Auxiliary Type", static_cast<uint8_t>(AuxEntPtr->AuxType),
                ArrayRef(SymAuxType));
  }
}

static const EnumEntry<XCOFF::StorageMappingClass> CsectStorageMappingClass[] =
    {
#define ECase(X)                                                               \
  { #X, XCOFF::X }
        ECase(XMC_PR), ECase(XMC_RO), ECase(XMC_DB),   ECase(XMC_GL),
        ECase(XMC_XO), ECase(XMC_SV), ECase(XMC_SV64), ECase(XMC_SV3264),
        ECase(XMC_TI), ECase(XMC_TB), ECase(XMC_RW),   ECase(XMC_TC0),
        ECase(XMC_TC), ECase(XMC_TD), ECase(XMC_DS),   ECase(XMC_UA),
        ECase(XMC_BS), ECase(XMC_UC), ECase(XMC_TL),   ECase(XMC_UL),
        ECase(XMC_TE)
#undef ECase
};

const EnumEntry<XCOFF::SymbolType> CsectSymbolTypeClass[] = {
#define ECase(X)                                                               \
  { #X, XCOFF::X }
    ECase(XTY_ER), ECase(XTY_SD), ECase(XTY_LD), ECase(XTY_CM)
#undef ECase
};

void XCOFFDumper::printCsectAuxEnt(XCOFFCsectAuxRef AuxEntRef) {
  assert((!Obj.is64Bit() || AuxEntRef.getAuxType64() == XCOFF::AUX_CSECT) &&
         "Mismatched auxiliary type!");

  DictScope SymDs(W, "CSECT Auxiliary Entry");
  W.printNumber("Index", Obj.getSymbolIndex(AuxEntRef.getEntryAddress()));
  W.printNumber(AuxEntRef.isLabel() ? "ContainingCsectSymbolIndex"
                                    : "SectionLen",
                AuxEntRef.getSectionOrLength());
  W.printHex("ParameterHashIndex", AuxEntRef.getParameterHashIndex());
  W.printHex("TypeChkSectNum", AuxEntRef.getTypeChkSectNum());
  // Print out symbol alignment and type.
  W.printNumber("SymbolAlignmentLog2", AuxEntRef.getAlignmentLog2());
  W.printEnum("SymbolType", AuxEntRef.getSymbolType(),
              ArrayRef(CsectSymbolTypeClass));
  W.printEnum("StorageMappingClass",
              static_cast<uint8_t>(AuxEntRef.getStorageMappingClass()),
              ArrayRef(CsectStorageMappingClass));

  if (Obj.is64Bit()) {
    W.printEnum("Auxiliary Type", static_cast<uint8_t>(XCOFF::AUX_CSECT),
                ArrayRef(SymAuxType));
  } else {
    W.printHex("StabInfoIndex", AuxEntRef.getStabInfoIndex32());
    W.printHex("StabSectNum", AuxEntRef.getStabSectNum32());
  }
}

void XCOFFDumper::printSectAuxEntForStat(
    const XCOFFSectAuxEntForStat *AuxEntPtr) {
  assert(!Obj.is64Bit() && "32-bit interface called on 64-bit object file.");

  DictScope SymDs(W, "Sect Auxiliary Entry For Stat");
  W.printNumber("Index",
                Obj.getSymbolIndex(reinterpret_cast<uintptr_t>(AuxEntPtr)));
  W.printNumber("SectionLength", AuxEntPtr->SectionLength);

  // Unlike the corresponding fields in the section header, NumberOfRelocEnt
  // and NumberOfLineNum do not handle values greater than 65535.
  W.printNumber("NumberOfRelocEnt", AuxEntPtr->NumberOfRelocEnt);
  W.printNumber("NumberOfLineNum", AuxEntPtr->NumberOfLineNum);
}

void XCOFFDumper::printExceptionAuxEnt(const XCOFFExceptionAuxEnt *AuxEntPtr) {
  assert(Obj.is64Bit() && "64-bit interface called on 32-bit object file.");

  DictScope SymDs(W, "Exception Auxiliary Entry");
  W.printNumber("Index",
                Obj.getSymbolIndex(reinterpret_cast<uintptr_t>(AuxEntPtr)));
  W.printHex("OffsetToExceptionTable", AuxEntPtr->OffsetToExceptionTbl);
  W.printHex("SizeOfFunction", AuxEntPtr->SizeOfFunction);
  W.printNumber("SymbolIndexOfNextBeyond", AuxEntPtr->SymIdxOfNextBeyond);
  W.printEnum("Auxiliary Type", static_cast<uint8_t>(AuxEntPtr->AuxType),
              ArrayRef(SymAuxType));
}

void XCOFFDumper::printFunctionAuxEnt(const XCOFFFunctionAuxEnt32 *AuxEntPtr) {
  assert(!Obj.is64Bit() && "32-bit interface called on 64-bit object file.");

  DictScope SymDs(W, "Function Auxiliary Entry");
  W.printNumber("Index",
                Obj.getSymbolIndex(reinterpret_cast<uintptr_t>(AuxEntPtr)));
  W.printHex("OffsetToExceptionTable", AuxEntPtr->OffsetToExceptionTbl);
  W.printHex("SizeOfFunction", AuxEntPtr->SizeOfFunction);
  W.printHex("PointerToLineNum", AuxEntPtr->PtrToLineNum);
  W.printNumber("SymbolIndexOfNextBeyond", AuxEntPtr->SymIdxOfNextBeyond);
}

void XCOFFDumper::printFunctionAuxEnt(const XCOFFFunctionAuxEnt64 *AuxEntPtr) {
  assert(Obj.is64Bit() && "64-bit interface called on 32-bit object file.");

  DictScope SymDs(W, "Function Auxiliary Entry");
  W.printNumber("Index",
                Obj.getSymbolIndex(reinterpret_cast<uintptr_t>(AuxEntPtr)));
  W.printHex("SizeOfFunction", AuxEntPtr->SizeOfFunction);
  W.printHex("PointerToLineNum", AuxEntPtr->PtrToLineNum);
  W.printNumber("SymbolIndexOfNextBeyond", AuxEntPtr->SymIdxOfNextBeyond);
  W.printEnum("Auxiliary Type", static_cast<uint8_t>(AuxEntPtr->AuxType),
              ArrayRef(SymAuxType));
}

void XCOFFDumper::printBlockAuxEnt(const XCOFFBlockAuxEnt32 *AuxEntPtr) {
  assert(!Obj.is64Bit() && "32-bit interface called on 64-bit object file.");

  DictScope SymDs(W, "Block Auxiliary Entry");
  W.printNumber("Index",
                Obj.getSymbolIndex(reinterpret_cast<uintptr_t>(AuxEntPtr)));
  W.printHex("LineNumber (High 2 Bytes)", AuxEntPtr->LineNumHi);
  W.printHex("LineNumber (Low 2 Bytes)", AuxEntPtr->LineNumLo);
}

void XCOFFDumper::printBlockAuxEnt(const XCOFFBlockAuxEnt64 *AuxEntPtr) {
  assert(Obj.is64Bit() && "64-bit interface called on 32-bit object file.");

  DictScope SymDs(W, "Block Auxiliary Entry");
  W.printNumber("Index",
                Obj.getSymbolIndex(reinterpret_cast<uintptr_t>(AuxEntPtr)));
  W.printHex("LineNumber", AuxEntPtr->LineNum);
  W.printEnum("Auxiliary Type", static_cast<uint8_t>(AuxEntPtr->AuxType),
              ArrayRef(SymAuxType));
}

template <typename T>
void XCOFFDumper::printSectAuxEntForDWARF(const T *AuxEntPtr) {
  DictScope SymDs(W, "Sect Auxiliary Entry For DWARF");
  W.printNumber("Index",
                Obj.getSymbolIndex(reinterpret_cast<uintptr_t>(AuxEntPtr)));
  W.printHex("LengthOfSectionPortion", AuxEntPtr->LengthOfSectionPortion);
  W.printNumber("NumberOfRelocEntries", AuxEntPtr->NumberOfRelocEnt);
  if (Obj.is64Bit())
    W.printEnum("Auxiliary Type", static_cast<uint8_t>(XCOFF::AUX_SECT),
                ArrayRef(SymAuxType));
}

static StringRef GetSymbolValueName(XCOFF::StorageClass SC) {
  switch (SC) {
  case XCOFF::C_EXT:
  case XCOFF::C_WEAKEXT:
  case XCOFF::C_HIDEXT:
  case XCOFF::C_STAT:
  case XCOFF::C_FCN:
  case XCOFF::C_BLOCK:
    return "Value (RelocatableAddress)";
  case XCOFF::C_FILE:
    return "Value (SymbolTableIndex)";
  case XCOFF::C_DWARF:
    return "Value (OffsetInDWARF)";
  case XCOFF::C_FUN:
  case XCOFF::C_STSYM:
  case XCOFF::C_BINCL:
  case XCOFF::C_EINCL:
  case XCOFF::C_INFO:
  case XCOFF::C_BSTAT:
  case XCOFF::C_LSYM:
  case XCOFF::C_PSYM:
  case XCOFF::C_RPSYM:
  case XCOFF::C_RSYM:
  case XCOFF::C_ECOML:
    assert(false && "This StorageClass for the symbol is not yet implemented.");
    return "";
  default:
    return "Value";
  }
}

const EnumEntry<XCOFF::CFileLangId> CFileLangIdClass[] = {
#define ECase(X)                                                               \
  { #X, XCOFF::X }
    ECase(TB_C), ECase(TB_CPLUSPLUS)
#undef ECase
};

const EnumEntry<XCOFF::CFileCpuId> CFileCpuIdClass[] = {
#define ECase(X)                                                               \
  { #X, XCOFF::X }
    ECase(TCPU_PPC64), ECase(TCPU_COM), ECase(TCPU_970)
#undef ECase
};

template <typename T> const T *XCOFFDumper::getAuxEntPtr(uintptr_t AuxAddress) {
  const T *AuxEntPtr = reinterpret_cast<const T *>(AuxAddress);
  Obj.checkSymbolEntryPointer(reinterpret_cast<uintptr_t>(AuxEntPtr));
  return AuxEntPtr;
}

static void printUnexpectedRawAuxEnt(ScopedPrinter &W, uintptr_t AuxAddress) {
  W.startLine() << "!Unexpected raw auxiliary entry data:\n";
  W.startLine() << format_bytes(
                       ArrayRef<uint8_t>(
                           reinterpret_cast<const uint8_t *>(AuxAddress),
                           XCOFF::SymbolTableEntrySize),
                       std::nullopt, XCOFF::SymbolTableEntrySize)
                << "\n";
}

void XCOFFDumper::printSymbol(const SymbolRef &S) {
  DataRefImpl SymbolDRI = S.getRawDataRefImpl();
  XCOFFSymbolRef SymbolEntRef = Obj.toSymbolRef(SymbolDRI);

  uint8_t NumberOfAuxEntries = SymbolEntRef.getNumberOfAuxEntries();

  DictScope SymDs(W, "Symbol");

  StringRef SymbolName =
      unwrapOrError(Obj.getFileName(), SymbolEntRef.getName());

  uint32_t SymbolIdx = Obj.getSymbolIndex(SymbolEntRef.getEntryAddress());
  XCOFF::StorageClass SymbolClass = SymbolEntRef.getStorageClass();

  W.printNumber("Index", SymbolIdx);
  W.printString("Name", SymbolName);
  W.printHex(GetSymbolValueName(SymbolClass), SymbolEntRef.getValue());

  StringRef SectionName =
      unwrapOrError(Obj.getFileName(), Obj.getSymbolSectionName(SymbolEntRef));

  W.printString("Section", SectionName);
  if (SymbolClass == XCOFF::C_FILE) {
    W.printEnum("Source Language ID", SymbolEntRef.getLanguageIdForCFile(),
                ArrayRef(CFileLangIdClass));
    W.printEnum("CPU Version ID", SymbolEntRef.getCPUTypeIddForCFile(),
                ArrayRef(CFileCpuIdClass));
  } else
    W.printHex("Type", SymbolEntRef.getSymbolType());

  W.printEnum("StorageClass", static_cast<uint8_t>(SymbolClass),
              ArrayRef(SymStorageClass));
  W.printNumber("NumberOfAuxEntries", NumberOfAuxEntries);

  if (NumberOfAuxEntries == 0)
    return;

  auto checkNumOfAux = [=] {
    if (NumberOfAuxEntries > 1)
      reportUniqueWarning("the " +
                          enumToString(static_cast<uint8_t>(SymbolClass),
                                       ArrayRef(SymStorageClass)) +
                          " symbol at index " + Twine(SymbolIdx) +
                          " should not have more than 1 "
                          "auxiliary entry");
  };

  switch (SymbolClass) {
  case XCOFF::C_FILE:
    // If the symbol is C_FILE and has auxiliary entries...
    for (int I = 1; I <= NumberOfAuxEntries; I++) {
      uintptr_t AuxAddress = XCOFFObjectFile::getAdvancedSymbolEntryAddress(
          SymbolEntRef.getEntryAddress(), I);

      if (Obj.is64Bit() &&
          *Obj.getSymbolAuxType(AuxAddress) != XCOFF::SymbolAuxType::AUX_FILE) {
        printUnexpectedRawAuxEnt(W, AuxAddress);
        continue;
      }

      const XCOFFFileAuxEnt *FileAuxEntPtr =
          getAuxEntPtr<XCOFFFileAuxEnt>(AuxAddress);
      printFileAuxEnt(FileAuxEntPtr);
    }
    break;
  case XCOFF::C_EXT:
  case XCOFF::C_WEAKEXT:
  case XCOFF::C_HIDEXT: {
    // For 32-bit objects, print the function auxiliary symbol table entry. The
    // last one must be a CSECT auxiliary entry.
    // For 64-bit objects, both a function auxiliary entry and an exception
    // auxiliary entry may appear, print them in the loop and skip printing the
    // CSECT auxiliary entry, which will be printed outside the loop.
    for (int I = 1; I <= NumberOfAuxEntries; I++) {
      if (I == NumberOfAuxEntries && !Obj.is64Bit())
        break;

      uintptr_t AuxAddress = XCOFFObjectFile::getAdvancedSymbolEntryAddress(
          SymbolEntRef.getEntryAddress(), I);

      if (Obj.is64Bit()) {
        XCOFF::SymbolAuxType Type = *Obj.getSymbolAuxType(AuxAddress);
        if (Type == XCOFF::SymbolAuxType::AUX_CSECT)
          continue;
        if (Type == XCOFF::SymbolAuxType::AUX_FCN) {
          const XCOFFFunctionAuxEnt64 *AuxEntPtr =
              getAuxEntPtr<XCOFFFunctionAuxEnt64>(AuxAddress);
          printFunctionAuxEnt(AuxEntPtr);
        } else if (Type == XCOFF::SymbolAuxType::AUX_EXCEPT) {
          const XCOFFExceptionAuxEnt *AuxEntPtr =
              getAuxEntPtr<XCOFFExceptionAuxEnt>(AuxAddress);
          printExceptionAuxEnt(AuxEntPtr);
        } else {
          printUnexpectedRawAuxEnt(W, AuxAddress);
        }
      } else {
        const XCOFFFunctionAuxEnt32 *AuxEntPtr =
            getAuxEntPtr<XCOFFFunctionAuxEnt32>(AuxAddress);
        printFunctionAuxEnt(AuxEntPtr);
      }
    }

    // Print the CSECT auxiliary entry.
    auto ErrOrCsectAuxRef = SymbolEntRef.getXCOFFCsectAuxRef();
    if (!ErrOrCsectAuxRef)
      reportUniqueWarning(ErrOrCsectAuxRef.takeError());
    else
      printCsectAuxEnt(*ErrOrCsectAuxRef);

    break;
  }
  case XCOFF::C_STAT: {
    checkNumOfAux();

    const XCOFFSectAuxEntForStat *StatAuxEntPtr =
        getAuxEntPtr<XCOFFSectAuxEntForStat>(
            XCOFFObjectFile::getAdvancedSymbolEntryAddress(
                SymbolEntRef.getEntryAddress(), 1));
    printSectAuxEntForStat(StatAuxEntPtr);
    break;
  }
  case XCOFF::C_DWARF: {
    checkNumOfAux();

    uintptr_t AuxAddress = XCOFFObjectFile::getAdvancedSymbolEntryAddress(
        SymbolEntRef.getEntryAddress(), 1);

    if (Obj.is64Bit()) {
      const XCOFFSectAuxEntForDWARF64 *AuxEntPtr =
          getAuxEntPtr<XCOFFSectAuxEntForDWARF64>(AuxAddress);
      printSectAuxEntForDWARF<XCOFFSectAuxEntForDWARF64>(AuxEntPtr);
    } else {
      const XCOFFSectAuxEntForDWARF32 *AuxEntPtr =
          getAuxEntPtr<XCOFFSectAuxEntForDWARF32>(AuxAddress);
      printSectAuxEntForDWARF<XCOFFSectAuxEntForDWARF32>(AuxEntPtr);
    }
    break;
  }
  case XCOFF::C_BLOCK:
  case XCOFF::C_FCN: {
    checkNumOfAux();

    uintptr_t AuxAddress = XCOFFObjectFile::getAdvancedSymbolEntryAddress(
        SymbolEntRef.getEntryAddress(), 1);

    if (Obj.is64Bit()) {
      const XCOFFBlockAuxEnt64 *AuxEntPtr =
          getAuxEntPtr<XCOFFBlockAuxEnt64>(AuxAddress);
      printBlockAuxEnt(AuxEntPtr);
    } else {
      const XCOFFBlockAuxEnt32 *AuxEntPtr =
          getAuxEntPtr<XCOFFBlockAuxEnt32>(AuxAddress);
      printBlockAuxEnt(AuxEntPtr);
    }
    break;
  }
  default:
    for (int i = 1; i <= NumberOfAuxEntries; i++) {
      printUnexpectedRawAuxEnt(W,
                               XCOFFObjectFile::getAdvancedSymbolEntryAddress(
                                   SymbolEntRef.getEntryAddress(), i));
    }
    break;
  }
}

void XCOFFDumper::printSymbols() {
  ListScope Group(W, "Symbols");
  for (const SymbolRef &S : Obj.symbols())
    printSymbol(S);
}

void XCOFFDumper::printStringTable() {
  DictScope DS(W, "StringTable");
  StringRef StrTable = Obj.getStringTable();
  uint32_t StrTabSize = StrTable.size();
  W.printNumber("Length", StrTabSize);
  // Print strings from the fifth byte, since the first four bytes contain the
  // length (in bytes) of the string table (including the length field).
  if (StrTabSize > 4)
    printAsStringList(StrTable, 4);
}

void XCOFFDumper::printDynamicSymbols() {
  llvm_unreachable("Unimplemented functionality for XCOFFDumper");
}

void XCOFFDumper::printUnwindInfo() {
  llvm_unreachable("Unimplemented functionality for XCOFFDumper");
}

void XCOFFDumper::printStackMap() const {
  llvm_unreachable("Unimplemented functionality for XCOFFDumper");
}

void XCOFFDumper::printNeededLibraries() {
  ListScope D(W, "NeededLibraries");
  auto ImportFilesOrError = Obj.getImportFileTable();
  if (!ImportFilesOrError) {
    reportUniqueWarning(ImportFilesOrError.takeError());
    return;
  }

  StringRef ImportFileTable = ImportFilesOrError.get();
  const char *CurrentStr = ImportFileTable.data();
  const char *TableEnd = ImportFileTable.end();
  // Default column width for names is 13 even if no names are that long.
  size_t BaseWidth = 13;

  // Get the max width of BASE columns.
  for (size_t StrIndex = 0; CurrentStr < TableEnd; ++StrIndex) {
    size_t CurrentLen = strlen(CurrentStr);
    CurrentStr += strlen(CurrentStr) + 1;
    if (StrIndex % 3 == 1)
      BaseWidth = std::max(BaseWidth, CurrentLen);
  }

  auto &OS = static_cast<formatted_raw_ostream &>(W.startLine());
  // Each entry consists of 3 strings: the path_name, base_name and
  // archive_member_name. The first entry is a default LIBPATH value and other
  // entries have no path_name. We just dump the base_name and
  // archive_member_name here.
  OS << left_justify("BASE", BaseWidth)  << " MEMBER\n";
  CurrentStr = ImportFileTable.data();
  for (size_t StrIndex = 0; CurrentStr < TableEnd;
       ++StrIndex, CurrentStr += strlen(CurrentStr) + 1) {
    if (StrIndex >= 3 && StrIndex % 3 != 0) {
      if (StrIndex % 3 == 1)
        OS << "  " << left_justify(CurrentStr, BaseWidth) << " ";
      else
        OS << CurrentStr << "\n";
    }
  }
}

const EnumEntry<XCOFF::SectionTypeFlags> SectionTypeFlagsNames[] = {
#define ECase(X)                                                               \
  { #X, XCOFF::X }
    ECase(STYP_PAD),    ECase(STYP_DWARF), ECase(STYP_TEXT),
    ECase(STYP_DATA),   ECase(STYP_BSS),   ECase(STYP_EXCEPT),
    ECase(STYP_INFO),   ECase(STYP_TDATA), ECase(STYP_TBSS),
    ECase(STYP_LOADER), ECase(STYP_DEBUG), ECase(STYP_TYPCHK),
    ECase(STYP_OVRFLO)
#undef ECase
};

template <typename T>
void XCOFFDumper::printOverflowSectionHeader(T &Sec) const {
  if (Obj.is64Bit()) {
    reportWarning(make_error<StringError>("An 64-bit XCOFF object file may not "
                                          "contain an overflow section header.",
                                          object_error::parse_failed),
                  Obj.getFileName());
  }

  W.printString("Name", Sec.getName());
  W.printNumber("NumberOfRelocations", Sec.PhysicalAddress);
  W.printNumber("NumberOfLineNumbers", Sec.VirtualAddress);
  W.printHex("Size", Sec.SectionSize);
  W.printHex("RawDataOffset", Sec.FileOffsetToRawData);
  W.printHex("RelocationPointer", Sec.FileOffsetToRelocationInfo);
  W.printHex("LineNumberPointer", Sec.FileOffsetToLineNumberInfo);
  W.printNumber("IndexOfSectionOverflowed", Sec.NumberOfRelocations);
  W.printNumber("IndexOfSectionOverflowed", Sec.NumberOfLineNumbers);
}

template <typename T>
void XCOFFDumper::printGenericSectionHeader(T &Sec) const {
  W.printString("Name", Sec.getName());
  W.printHex("PhysicalAddress", Sec.PhysicalAddress);
  W.printHex("VirtualAddress", Sec.VirtualAddress);
  W.printHex("Size", Sec.SectionSize);
  W.printHex("RawDataOffset", Sec.FileOffsetToRawData);
  W.printHex("RelocationPointer", Sec.FileOffsetToRelocationInfo);
  W.printHex("LineNumberPointer", Sec.FileOffsetToLineNumberInfo);
  W.printNumber("NumberOfRelocations", Sec.NumberOfRelocations);
  W.printNumber("NumberOfLineNumbers", Sec.NumberOfLineNumbers);
}

enum PrintStyle { Hex, Number };
template <typename T, typename V>
static void printAuxMemberHelper(PrintStyle Style, const char *MemberName,
                                 const T &Member, const V *AuxHeader,
                                 uint16_t AuxSize, uint16_t &PartialFieldOffset,
                                 const char *&PartialFieldName,
                                 ScopedPrinter &W) {
  ptrdiff_t Offset = reinterpret_cast<const char *>(&Member) -
                     reinterpret_cast<const char *>(AuxHeader);
  if (Offset + sizeof(Member) <= AuxSize)
    Style == Hex ? W.printHex(MemberName, Member)
                 : W.printNumber(MemberName, Member);
  else if (Offset < AuxSize) {
    PartialFieldOffset = Offset;
    PartialFieldName = MemberName;
  }
}

template <class T>
void checkAndPrintAuxHeaderParseError(const char *PartialFieldName,
                                      uint16_t PartialFieldOffset,
                                      uint16_t AuxSize, T &AuxHeader,
                                      XCOFFDumper *Dumper) {
  if (PartialFieldOffset < AuxSize) {
    Dumper->reportUniqueWarning(Twine("only partial field for ") +
                                PartialFieldName + " at offset (" +
                                Twine(PartialFieldOffset) + ")");
    Dumper->getScopedPrinter().printBinary(
        "Raw data", "",
        ArrayRef<uint8_t>(reinterpret_cast<const uint8_t *>(&AuxHeader) +
                              PartialFieldOffset,
                          AuxSize - PartialFieldOffset));
  } else if (sizeof(AuxHeader) < AuxSize)
    Dumper->getScopedPrinter().printBinary(
        "Extra raw data", "",
        ArrayRef<uint8_t>(reinterpret_cast<const uint8_t *>(&AuxHeader) +
                              sizeof(AuxHeader),
                          AuxSize - sizeof(AuxHeader)));
}

void XCOFFDumper::printAuxiliaryHeader(
    const XCOFFAuxiliaryHeader32 *AuxHeader) {
  if (AuxHeader == nullptr)
    return;
  uint16_t AuxSize = Obj.getOptionalHeaderSize();
  uint16_t PartialFieldOffset = AuxSize;
  const char *PartialFieldName = nullptr;

  auto PrintAuxMember = [&](PrintStyle Style, const char *MemberName,
                            auto &Member) {
    printAuxMemberHelper(Style, MemberName, Member, AuxHeader, AuxSize,
                         PartialFieldOffset, PartialFieldName, W);
  };

  PrintAuxMember(Hex, "Magic", AuxHeader->AuxMagic);
  PrintAuxMember(Hex, "Version", AuxHeader->Version);
  PrintAuxMember(Hex, "Size of .text section", AuxHeader->TextSize);
  PrintAuxMember(Hex, "Size of .data section", AuxHeader->InitDataSize);
  PrintAuxMember(Hex, "Size of .bss section", AuxHeader->BssDataSize);
  PrintAuxMember(Hex, "Entry point address", AuxHeader->EntryPointAddr);
  PrintAuxMember(Hex, ".text section start address", AuxHeader->TextStartAddr);
  PrintAuxMember(Hex, ".data section start address", AuxHeader->DataStartAddr);
  PrintAuxMember(Hex, "TOC anchor address", AuxHeader->TOCAnchorAddr);
  PrintAuxMember(Number, "Section number of entryPoint",
                 AuxHeader->SecNumOfEntryPoint);
  PrintAuxMember(Number, "Section number of .text", AuxHeader->SecNumOfText);
  PrintAuxMember(Number, "Section number of .data", AuxHeader->SecNumOfData);
  PrintAuxMember(Number, "Section number of TOC", AuxHeader->SecNumOfTOC);
  PrintAuxMember(Number, "Section number of loader data",
                 AuxHeader->SecNumOfLoader);
  PrintAuxMember(Number, "Section number of .bss", AuxHeader->SecNumOfBSS);
  PrintAuxMember(Hex, "Maxium alignment of .text", AuxHeader->MaxAlignOfText);
  PrintAuxMember(Hex, "Maxium alignment of .data", AuxHeader->MaxAlignOfData);
  PrintAuxMember(Hex, "Module type", AuxHeader->ModuleType);
  PrintAuxMember(Hex, "CPU type of objects", AuxHeader->CpuFlag);
  PrintAuxMember(Hex, "(Reserved)", AuxHeader->CpuType);
  PrintAuxMember(Hex, "Maximum stack size", AuxHeader->MaxStackSize);
  PrintAuxMember(Hex, "Maximum data size", AuxHeader->MaxDataSize);
  PrintAuxMember(Hex, "Reserved for debugger", AuxHeader->ReservedForDebugger);
  PrintAuxMember(Hex, "Text page size", AuxHeader->TextPageSize);
  PrintAuxMember(Hex, "Data page size", AuxHeader->DataPageSize);
  PrintAuxMember(Hex, "Stack page size", AuxHeader->StackPageSize);
  if (offsetof(XCOFFAuxiliaryHeader32, FlagAndTDataAlignment) +
          sizeof(XCOFFAuxiliaryHeader32::FlagAndTDataAlignment) <=
      AuxSize) {
    W.printHex("Flag", AuxHeader->getFlag());
    W.printHex("Alignment of thread-local storage",
               AuxHeader->getTDataAlignment());
  }

  PrintAuxMember(Number, "Section number for .tdata", AuxHeader->SecNumOfTData);
  PrintAuxMember(Number, "Section number for .tbss", AuxHeader->SecNumOfTBSS);

  checkAndPrintAuxHeaderParseError(PartialFieldName, PartialFieldOffset,
                                   AuxSize, *AuxHeader, this);
}

void XCOFFDumper::printAuxiliaryHeader(
    const XCOFFAuxiliaryHeader64 *AuxHeader) {
  if (AuxHeader == nullptr)
    return;
  uint16_t AuxSize = Obj.getOptionalHeaderSize();
  uint16_t PartialFieldOffset = AuxSize;
  const char *PartialFieldName = nullptr;

  auto PrintAuxMember = [&](PrintStyle Style, const char *MemberName,
                            auto &Member) {
    printAuxMemberHelper(Style, MemberName, Member, AuxHeader, AuxSize,
                         PartialFieldOffset, PartialFieldName, W);
  };

  PrintAuxMember(Hex, "Magic", AuxHeader->AuxMagic);
  PrintAuxMember(Hex, "Version", AuxHeader->Version);
  PrintAuxMember(Hex, "Reserved for debugger", AuxHeader->ReservedForDebugger);
  PrintAuxMember(Hex, ".text section start address", AuxHeader->TextStartAddr);
  PrintAuxMember(Hex, ".data section start address", AuxHeader->DataStartAddr);
  PrintAuxMember(Hex, "TOC anchor address", AuxHeader->TOCAnchorAddr);
  PrintAuxMember(Number, "Section number of entryPoint",
                 AuxHeader->SecNumOfEntryPoint);
  PrintAuxMember(Number, "Section number of .text", AuxHeader->SecNumOfText);
  PrintAuxMember(Number, "Section number of .data", AuxHeader->SecNumOfData);
  PrintAuxMember(Number, "Section number of TOC", AuxHeader->SecNumOfTOC);
  PrintAuxMember(Number, "Section number of loader data",
                 AuxHeader->SecNumOfLoader);
  PrintAuxMember(Number, "Section number of .bss", AuxHeader->SecNumOfBSS);
  PrintAuxMember(Hex, "Maxium alignment of .text", AuxHeader->MaxAlignOfText);
  PrintAuxMember(Hex, "Maxium alignment of .data", AuxHeader->MaxAlignOfData);
  PrintAuxMember(Hex, "Module type", AuxHeader->ModuleType);
  PrintAuxMember(Hex, "CPU type of objects", AuxHeader->CpuFlag);
  PrintAuxMember(Hex, "(Reserved)", AuxHeader->CpuType);
  PrintAuxMember(Hex, "Text page size", AuxHeader->TextPageSize);
  PrintAuxMember(Hex, "Data page size", AuxHeader->DataPageSize);
  PrintAuxMember(Hex, "Stack page size", AuxHeader->StackPageSize);
  if (offsetof(XCOFFAuxiliaryHeader64, FlagAndTDataAlignment) +
          sizeof(XCOFFAuxiliaryHeader64::FlagAndTDataAlignment) <=
      AuxSize) {
    W.printHex("Flag", AuxHeader->getFlag());
    W.printHex("Alignment of thread-local storage",
               AuxHeader->getTDataAlignment());
  }
  PrintAuxMember(Hex, "Size of .text section", AuxHeader->TextSize);
  PrintAuxMember(Hex, "Size of .data section", AuxHeader->InitDataSize);
  PrintAuxMember(Hex, "Size of .bss section", AuxHeader->BssDataSize);
  PrintAuxMember(Hex, "Entry point address", AuxHeader->EntryPointAddr);
  PrintAuxMember(Hex, "Maximum stack size", AuxHeader->MaxStackSize);
  PrintAuxMember(Hex, "Maximum data size", AuxHeader->MaxDataSize);
  PrintAuxMember(Number, "Section number for .tdata", AuxHeader->SecNumOfTData);
  PrintAuxMember(Number, "Section number for .tbss", AuxHeader->SecNumOfTBSS);
  PrintAuxMember(Hex, "Additional flags 64-bit XCOFF", AuxHeader->XCOFF64Flag);

  checkAndPrintAuxHeaderParseError(PartialFieldName, PartialFieldOffset,
                                   AuxSize, *AuxHeader, this);
}

template <typename T>
void XCOFFDumper::printSectionHeaders(ArrayRef<T> Sections) {
  ListScope Group(W, "Sections");

  uint16_t Index = 1;
  for (const T &Sec : Sections) {
    DictScope SecDS(W, "Section");

    W.printNumber("Index", Index++);
    uint16_t SectionType = Sec.getSectionType();
    switch (SectionType) {
    case XCOFF::STYP_OVRFLO:
      printOverflowSectionHeader(Sec);
      break;
    case XCOFF::STYP_LOADER:
    case XCOFF::STYP_EXCEPT:
    case XCOFF::STYP_TYPCHK:
      // TODO The interpretation of loader, exception and type check section
      // headers are different from that of generic section headers. We will
      // implement them later. We interpret them as generic section headers for
      // now.
    default:
      printGenericSectionHeader(Sec);
      break;
    }
    if (Sec.isReservedSectionType())
      W.printHex("Flags", "Reserved", SectionType);
    else
      W.printEnum("Type", SectionType, ArrayRef(SectionTypeFlagsNames));
  }

  if (opts::SectionRelocations)
    report_fatal_error("Dumping section relocations is unimplemented");

  if (opts::SectionSymbols)
    report_fatal_error("Dumping symbols is unimplemented");

  if (opts::SectionData)
    report_fatal_error("Dumping section data is unimplemented");
}

namespace llvm {
std::unique_ptr<ObjDumper>
createXCOFFDumper(const object::XCOFFObjectFile &XObj, ScopedPrinter &Writer) {
  return std::make_unique<XCOFFDumper>(XObj, Writer);
}
} // namespace llvm
