//===-- 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 "Error.h"
#include "ObjDumper.h"
#include "llvm-readobj.h"
#include "llvm/Object/XCOFFObjectFile.h"
#include "llvm/Support/ScopedPrinter.h"

using namespace llvm;
using namespace object;

namespace {

class XCOFFDumper : public ObjDumper {
  enum {
    SymbolTypeMask = 0x07,
    SymbolAlignmentMask = 0xF8,
    SymbolAlignmentBitOffset = 3
  };

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

  void printFileHeaders() override;
  void printSectionHeaders() override;
  void printRelocations() override;
  void printSymbols() override;
  void printDynamicSymbols() override;
  void printUnwindInfo() override;
  void printStackMap() const override;
  void printNeededLibraries() override;

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;
  void printFileAuxEnt(const XCOFFFileAuxEnt *AuxEntPtr);
  void printCsectAuxEnt32(const XCOFFCsectAuxEnt32 *AuxEntPtr);
  void printSectAuxEntForStat(const XCOFFSectAuxEntForStat *AuxEntPtr);
  void printSymbol(const SymbolRef &);

  // Least significant 3 bits are reserved.
  static constexpr unsigned SectionFlagsReservedMask = 0x7;

  // The low order 16 bits of section flags denotes the section type.
  static constexpr unsigned SectionFlagsTypeMask = 0xffffu;

  void printRelocations(ArrayRef<XCOFFSectionHeader32> Sections);
  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::printSectionHeaders() {
  if (Obj.is64Bit())
    printSectionHeaders(Obj.sections64());
  else
    printSectionHeaders(Obj.sections32());
}

void XCOFFDumper::printRelocations() {
  if (Obj.is64Bit())
    llvm_unreachable("64-bit relocation output not implemented!");
  else
    printRelocations(Obj.sections32());
}

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

void XCOFFDumper::printRelocations(ArrayRef<XCOFFSectionHeader32> Sections) {
  if (!opts::ExpandRelocs)
    report_fatal_error("Unexpanded relocation output not implemented.");

  ListScope LS(W, "Relocations");
  uint16_t Index = 0;
  for (const auto &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;
    auto Relocations = unwrapOrError(Obj.getFileName(), Obj.relocations(Sec));
    if (Relocations.empty())
      continue;

    W.startLine() << "Section (index: " << Index << ") " << Sec.getName()
                  << " {\n";
    for (auto Reloc : Relocations) {
      StringRef SymbolName = unwrapOrError(
          Obj.getFileName(), Obj.getSymbolNameByIndex(Reloc.SymbolIndex));

      DictScope RelocScope(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));
    }
    W.unindent();
    W.startLine() << "}\n";
  }
}

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

void XCOFFDumper::printFileAuxEnt(const XCOFFFileAuxEnt *AuxEntPtr) {
  if (Obj.is64Bit())
    report_fatal_error(
        "Printing for File Auxiliary Entry in 64-bit is unimplemented.");
  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));
}

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_TE)
#undef ECase
};

static 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::printCsectAuxEnt32(const XCOFFCsectAuxEnt32 *AuxEntPtr) {
  assert(!Obj.is64Bit() && "32-bit interface called on 64-bit object file.");

  DictScope SymDs(W, "CSECT Auxiliary Entry");
  W.printNumber("Index",
                Obj.getSymbolIndex(reinterpret_cast<uintptr_t>(AuxEntPtr)));
  if ((AuxEntPtr->SymbolAlignmentAndType & SymbolTypeMask) == XCOFF::XTY_LD)
    W.printNumber("ContainingCsectSymbolIndex", AuxEntPtr->SectionOrLength);
  else
    W.printNumber("SectionLen", AuxEntPtr->SectionOrLength);
  W.printHex("ParameterHashIndex", AuxEntPtr->ParameterHashIndex);
  W.printHex("TypeChkSectNum", AuxEntPtr->TypeChkSectNum);
  // Print out symbol alignment and type.
  W.printNumber("SymbolAlignmentLog2",
                (AuxEntPtr->SymbolAlignmentAndType & SymbolAlignmentMask) >>
                    SymbolAlignmentBitOffset);
  W.printEnum("SymbolType", AuxEntPtr->SymbolAlignmentAndType & SymbolTypeMask,
              makeArrayRef(CsectSymbolTypeClass));
  W.printEnum("StorageMappingClass",
              static_cast<uint8_t>(AuxEntPtr->StorageMappingClass),
              makeArrayRef(CsectStorageMappingClass));
  W.printHex("StabInfoIndex", AuxEntPtr->StabInfoIndex);
  W.printHex("StabSectNum", AuxEntPtr->StabSectNum);
}

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

static 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:
    return "Value (RelocatableAddress)";
  case XCOFF::C_FILE:
    return "Value (SymbolTableIndex)";
  case XCOFF::C_FCN:
  case XCOFF::C_BLOCK:
  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:
  case XCOFF::C_DWARF:
    assert(false && "This StorageClass for the symbol is not yet implemented.");
    return "";
  default:
    return "Value";
  }
}

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

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

void XCOFFDumper::printSymbol(const SymbolRef &S) {
  if (Obj.is64Bit())
    report_fatal_error("64-bit support is unimplemented.");

  DataRefImpl SymbolDRI = S.getRawDataRefImpl();
  const XCOFFSymbolEntry *SymbolEntPtr = Obj.toSymbolEntry(SymbolDRI);

  XCOFFSymbolRef XCOFFSymRef(SymbolDRI, &Obj);
  uint8_t NumberOfAuxEntries = XCOFFSymRef.getNumberOfAuxEntries();

  DictScope SymDs(W, "Symbol");

  StringRef SymbolName =
      unwrapOrError(Obj.getFileName(), Obj.getSymbolName(SymbolDRI));

  W.printNumber("Index",
                Obj.getSymbolIndex(reinterpret_cast<uintptr_t>(SymbolEntPtr)));
  W.printString("Name", SymbolName);
  W.printHex(GetSymbolValueName(SymbolEntPtr->StorageClass),
             SymbolEntPtr->Value);

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

  W.printString("Section", SectionName);
  if (XCOFFSymRef.getStorageClass() == XCOFF::C_FILE) {
    W.printEnum("Source Language ID",
                SymbolEntPtr->CFileLanguageIdAndTypeId.LanguageId,
                makeArrayRef(CFileLangIdClass));
    W.printEnum("CPU Version ID",
                SymbolEntPtr->CFileLanguageIdAndTypeId.CpuTypeId,
                makeArrayRef(CFileCpuIdClass));
  } else
    W.printHex("Type", SymbolEntPtr->SymbolType);

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

  if (NumberOfAuxEntries == 0)
    return;

  switch (XCOFFSymRef.getStorageClass()) {
  case XCOFF::C_FILE:
    // If the symbol is C_FILE and has auxiliary entries...
    for (int i = 1; i <= NumberOfAuxEntries; i++) {
      const XCOFFFileAuxEnt *FileAuxEntPtr =
          reinterpret_cast<const XCOFFFileAuxEnt *>(SymbolEntPtr + i);
#ifndef NDEBUG
      Obj.checkSymbolEntryPointer(reinterpret_cast<uintptr_t>(FileAuxEntPtr));
#endif
      printFileAuxEnt(FileAuxEntPtr);
    }
    break;
  case XCOFF::C_EXT:
  case XCOFF::C_WEAKEXT:
  case XCOFF::C_HIDEXT:
    // If the symbol is for a function, and it has more than 1 auxiliary entry,
    // then one of them must be function auxiliary entry which we do not
    // support yet.
    if (XCOFFSymRef.isFunction() && NumberOfAuxEntries >= 2)
      report_fatal_error("Function auxiliary entry printing is unimplemented.");

    // If there is more than 1 auxiliary entry, instead of printing out
    // error information, print out the raw Auxiliary entry from 1st till
    // the last - 1. The last one must be a CSECT Auxiliary Entry.
    for (int i = 1; i < NumberOfAuxEntries; i++) {
      W.startLine() << "!Unexpected raw auxiliary entry data:\n";
      W.startLine() << format_bytes(
          ArrayRef<uint8_t>(reinterpret_cast<const uint8_t *>(SymbolEntPtr + i),
                            XCOFF::SymbolTableEntrySize));
    }

    // The symbol's last auxiliary entry is a CSECT Auxiliary Entry.
    printCsectAuxEnt32(XCOFFSymRef.getXCOFFCsectAuxEnt32());
    break;
  case XCOFF::C_STAT:
    if (NumberOfAuxEntries > 1)
      report_fatal_error(
          "C_STAT symbol should not have more than 1 auxiliary entry.");

    const XCOFFSectAuxEntForStat *StatAuxEntPtr;
    StatAuxEntPtr =
        reinterpret_cast<const XCOFFSectAuxEntForStat *>(SymbolEntPtr + 1);
#ifndef NDEBUG
    Obj.checkSymbolEntryPointer(reinterpret_cast<uintptr_t>(StatAuxEntPtr));
#endif
    printSectAuxEntForStat(StatAuxEntPtr);
    break;
  case XCOFF::C_DWARF:
  case XCOFF::C_BLOCK:
  case XCOFF::C_FCN:
    report_fatal_error("Symbol table entry printing for this storage class "
                       "type is unimplemented.");
    break;
  default:
    for (int i = 1; i <= NumberOfAuxEntries; i++) {
      W.startLine() << "!Unexpected raw auxiliary entry data:\n";
      W.startLine() << format_bytes(
          ArrayRef<uint8_t>(reinterpret_cast<const uint8_t *>(SymbolEntPtr + i),
                            XCOFF::SymbolTableEntrySize));
    }
    break;
  }
}

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

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() {
  llvm_unreachable("Unimplemented functionality for XCOFFDumper");
}

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

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.Flags & SectionFlagsTypeMask;
    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;
    }
    // For now we just dump the section type portion of the flags.
    if (SectionType & SectionFlagsReservedMask)
      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::error_code createXCOFFDumper(const object::ObjectFile *Obj,
                                  ScopedPrinter &Writer,
                                  std::unique_ptr<ObjDumper> &Result) {
  const XCOFFObjectFile *XObj = dyn_cast<XCOFFObjectFile>(Obj);
  if (!XObj)
    return readobj_error::unsupported_obj_file_format;

  Result.reset(new XCOFFDumper(*XObj, Writer));
  return readobj_error::success;
}
} // namespace llvm
