//===-- 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;

  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> 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);
  const XCOFFObjectFile &Obj;
};
} // 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::printRelocations() {
  if (Obj.is64Bit())
    printRelocations<XCOFFSectionHeader64, XCOFFRelocation64>(Obj.sections64());
  else
    printRelocations<XCOFFSectionHeader32, XCOFFRelocation32>(Obj.sections32());
}

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
};

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,
                makeArrayRef(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),
              makeArrayRef(FileStringType));
  if (Obj.is64Bit()) {
    W.printEnum("Auxiliary Type", static_cast<uint8_t>(AuxEntPtr->AuxType),
                makeArrayRef(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(),
              makeArrayRef(CsectSymbolTypeClass));
  W.printEnum("StorageMappingClass",
              static_cast<uint8_t>(AuxEntRef.getStorageMappingClass()),
              makeArrayRef(CsectStorageMappingClass));

  if (Obj.is64Bit()) {
    W.printEnum("Auxiliary Type", static_cast<uint8_t>(XCOFF::AUX_CSECT),
                makeArrayRef(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),
              makeArrayRef(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),
              makeArrayRef(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),
              makeArrayRef(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),
                makeArrayRef(SymAuxType));
}

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
};

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),
                       None, 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(),
                makeArrayRef(CFileLangIdClass));
    W.printEnum("CPU Version ID", SymbolEntRef.getCPUTypeIddForCFile(),
                makeArrayRef(CFileCpuIdClass));
  } else
    W.printHex("Type", SymbolEntRef.getSymbolType());

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

  if (NumberOfAuxEntries == 0)
    return;

  auto checkNumOfAux = [=] {
    if (NumberOfAuxEntries > 1)
      reportUniqueWarning("the " +
                          enumToString(static_cast<uint8_t>(SymbolClass),
                                       makeArrayRef(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: {
    if (!SymbolEntRef.isFunction() && NumberOfAuxEntries > 1)
      reportUniqueWarning("the non-function " +
                          enumToString(static_cast<uint8_t>(SymbolClass),
                                       makeArrayRef(SymStorageClass)) +
                          " symbol at index " + Twine(SymbolIdx) +
                          " should have only 1 auxiliary entry, i.e. the CSECT "
                          "auxiliary entry");

    // 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()) ||
          !SymbolEntRef.isFunction())
        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, makeArrayRef(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
