//===-- 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(bool ExtraSymInfo) 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[80] = {};

    size_t BytesFormatted =
      strftime(FormattedTime, sizeof(FormattedTime), "%F %T", gmtime(&TimeDate));
    if (BytesFormatted)
      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_Fortran), 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(bool /*ExtraSymInfo*/) {
  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
