Index: llvm/include/llvm/BinaryFormat/Magic.h =================================================================== --- llvm/include/llvm/BinaryFormat/Magic.h +++ llvm/include/llvm/BinaryFormat/Magic.h @@ -44,6 +44,7 @@ coff_import_library, ///< COFF import library pecoff_executable, ///< PECOFF executable file windows_resource, ///< Windows compiled resource file (.res) + xcoff_object_32, ///< 32-bit XCOFF object file wasm_object, ///< WebAssembly Object file pdb, ///< Windows PDB debug info file }; Index: llvm/include/llvm/Object/Binary.h =================================================================== --- llvm/include/llvm/Object/Binary.h +++ llvm/include/llvm/Object/Binary.h @@ -48,6 +48,7 @@ // Object and children. ID_StartObjects, ID_COFF, + ID_XCOFF32, // AIX XCOFF 32-bit ID_ELF32L, // ELF 32-bit, little endian ID_ELF32B, // ELF 32-bit, big endian @@ -117,6 +118,8 @@ return TypeID == ID_COFF; } + bool isXCOFF() const { return TypeID == ID_XCOFF32; } + bool isWasm() const { return TypeID == ID_Wasm; } bool isCOFFImportFile() const { Index: llvm/include/llvm/Object/ObjectFile.h =================================================================== --- llvm/include/llvm/Object/ObjectFile.h +++ llvm/include/llvm/Object/ObjectFile.h @@ -364,6 +364,9 @@ createCOFFObjectFile(MemoryBufferRef Object); static Expected> + createXCOFFObjectFile(MemoryBufferRef Object); + + static Expected> createELFObjectFile(MemoryBufferRef Object); static Expected> Index: llvm/include/llvm/Object/XCOFFObjectFile.h =================================================================== --- /dev/null +++ llvm/include/llvm/Object/XCOFFObjectFile.h @@ -0,0 +1,109 @@ +//===- XCOFFObjectFile.h - XCOFF object file implementation -----*- 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 declares the XCOFFObjectFile class. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_OBJECT_XCOFFOBJECTFILE_H +#define LLVM_OBJECT_XCOFFOBJECTFILE_H + +#include "llvm/ADT/StringRef.h" +#include "llvm/ADT/iterator_range.h" +#include "llvm/BinaryFormat/Magic.h" +#include "llvm/MC/SubtargetFeature.h" +#include "llvm/Object/Binary.h" +#include "llvm/Object/Error.h" +#include "llvm/Object/ObjectFile.h" +#include "llvm/Object/SymbolicFile.h" +#include "llvm/Support/Casting.h" +#include "llvm/Support/Error.h" +#include "llvm/Support/FileSystem.h" +#include "llvm/Support/MemoryBuffer.h" +#include +#include +#include +#include + +namespace llvm { +namespace object { + +struct XCOFFFileHeader { + support::ubig16_t Magic; + support::ubig16_t NumberOfSections; + + // Unix time value, value of 0 indicates no timestamp. + // Negative values are reserved. + support::big32_t TimeStamp; + + support::ubig32_t SymbolTableOffset; // File offset to symbol table. + support::big32_t NumberOfSymTableEntries; + support::ubig16_t AuxHeaderSize; + support::ubig16_t Flags; +}; + +class XCOFFObjectFile : public ObjectFile { +private: + const XCOFFFileHeader *FileHdrPtr = nullptr; + +public: + void moveSymbolNext(DataRefImpl &Symb) const override; + uint32_t getSymbolFlags(DataRefImpl Symb) const override; + basic_symbol_iterator symbol_begin() const override; + basic_symbol_iterator symbol_end() const override; + + Expected getSymbolName(DataRefImpl Symb) const override; + Expected getSymbolAddress(DataRefImpl Symb) const override; + uint64_t getSymbolValueImpl(DataRefImpl Symb) const override; + uint64_t getCommonSymbolSizeImpl(DataRefImpl Symb) const override; + Expected getSymbolType(DataRefImpl Symb) const override; + Expected getSymbolSection(DataRefImpl Symb) const override; + + void moveSectionNext(DataRefImpl &Sec) const override; + std::error_code getSectionName(DataRefImpl Sec, + StringRef &Res) const override; + uint64_t getSectionAddress(DataRefImpl Sec) const override; + uint64_t getSectionIndex(DataRefImpl Sec) const override; + uint64_t getSectionSize(DataRefImpl Sec) const override; + std::error_code getSectionContents(DataRefImpl Sec, + StringRef &Res) const override; + uint64_t getSectionAlignment(DataRefImpl Sec) const override; + bool isSectionCompressed(DataRefImpl Sec) const override; + bool isSectionText(DataRefImpl Sec) const override; + bool isSectionData(DataRefImpl Sec) const override; + bool isSectionBSS(DataRefImpl Sec) const override; + + bool isSectionVirtual(DataRefImpl Sec) const override; + relocation_iterator section_rel_begin(DataRefImpl Sec) const override; + relocation_iterator section_rel_end(DataRefImpl Sec) const override; + + void moveRelocationNext(DataRefImpl &Rel) const override; + uint64_t getRelocationOffset(DataRefImpl Rel) const override; + symbol_iterator getRelocationSymbol(DataRefImpl Rel) const override; + uint64_t getRelocationType(DataRefImpl Rel) const override; + void getRelocationTypeName(DataRefImpl Rel, + SmallVectorImpl &Result) const override; + + section_iterator section_begin() const override; + section_iterator section_end() const override; + uint8_t getBytesInAddress() const override; + StringRef getFileFormatName() const override; + Triple::ArchType getArch() const override; + SubtargetFeatures getFeatures() const override; + bool isRelocatableObject() const override; + +public: + XCOFFObjectFile(MemoryBufferRef Object, std::error_code &EC); + + const XCOFFFileHeader *getFileHeader() const { return FileHdrPtr; } + +}; // XCOFFObjectFile + +} // namespace object +} // namespace llvm +#endif // LLVM_OBJECT_XCOFFOBJECTFILE_H Index: llvm/include/llvm/ObjectYAML/XCOFFYAML.h =================================================================== --- /dev/null +++ llvm/include/llvm/ObjectYAML/XCOFFYAML.h @@ -0,0 +1,50 @@ +//===----- XCOFFYAML.h - XCOFF YAMLIO implementation ------------*- 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 declares classes for handling the YAML representation of XCOFF. +// +//===----------------------------------------------------------------------===// +#ifndef LLVM_OBJECTYAML_XCOFFYAML_H +#define LLVM_OBJECTYAML_XCOFFYAML_H + +#include "llvm/ObjectYAML/YAML.h" +#include + +namespace llvm { + +namespace XCOFFYAML { + +struct FileHeader { + llvm::yaml::Hex16 Magic; + uint16_t NumberOfSections; + int32_t TimeStamp; + llvm::yaml::Hex32 SymbolTableOffset; // File offset to symbol table. + int32_t NumberOfSymTableEntries; + uint16_t AuxHeaderSize; + llvm::yaml::Hex16 Flags; +}; + +struct Object { + FileHeader Header; + Object(); +}; +} // namespace XCOFFYAML + +namespace yaml { + +template <> struct MappingTraits { + static void mapping(IO &IO, XCOFFYAML::FileHeader &H); +}; + +template <> struct MappingTraits { + static void mapping(IO &IO, XCOFFYAML::Object &Obj); +}; + +} // namespace yaml +} // namespace llvm +#endif // LLVM_OBJECTYAML_XCOFFYAML_H Index: llvm/lib/BinaryFormat/Magic.cpp =================================================================== --- llvm/lib/BinaryFormat/Magic.cpp +++ llvm/lib/BinaryFormat/Magic.cpp @@ -61,6 +61,13 @@ return file_magic::wasm_object; break; } + + case 0x01: + // XCOFF format + if (startswith(Magic, "\x01\xDF")) + return file_magic::xcoff_object_32; + break; + case 0xDE: // 0x0B17C0DE = BC wraper if (startswith(Magic, "\xDE\xC0\x17\x0B")) return file_magic::bitcode; Index: llvm/lib/Object/Binary.cpp =================================================================== --- llvm/lib/Object/Binary.cpp +++ llvm/lib/Object/Binary.cpp @@ -68,6 +68,7 @@ case file_magic::coff_import_library: case file_magic::pecoff_executable: case file_magic::bitcode: + case file_magic::xcoff_object_32: case file_magic::wasm_object: return ObjectFile::createSymbolicFile(Buffer, Type, Context); case file_magic::macho_universal_binary: Index: llvm/lib/Object/CMakeLists.txt =================================================================== --- llvm/lib/Object/CMakeLists.txt +++ llvm/lib/Object/CMakeLists.txt @@ -21,6 +21,7 @@ SymbolSize.cpp WasmObjectFile.cpp WindowsResource.cpp + XCOFFObjectFile.cpp ADDITIONAL_HEADER_DIRS ${LLVM_MAIN_INCLUDE_DIR}/llvm/Object Index: llvm/lib/Object/ObjectFile.cpp =================================================================== --- llvm/lib/Object/ObjectFile.cpp +++ llvm/lib/Object/ObjectFile.cpp @@ -150,6 +150,8 @@ case file_magic::coff_import_library: case file_magic::pecoff_executable: return createCOFFObjectFile(Object); + case file_magic::xcoff_object_32: + return createXCOFFObjectFile(Object); case file_magic::wasm_object: return createWasmObjectFile(Object); } Index: llvm/lib/Object/SymbolicFile.cpp =================================================================== --- llvm/lib/Object/SymbolicFile.cpp +++ llvm/lib/Object/SymbolicFile.cpp @@ -68,6 +68,7 @@ case file_magic::macho_dsym_companion: case file_magic::macho_kext_bundle: case file_magic::pecoff_executable: + case file_magic::xcoff_object_32: case file_magic::wasm_object: return ObjectFile::createObjectFile(Object, Type); case file_magic::coff_import_library: Index: llvm/lib/Object/XCOFFObjectFile.cpp =================================================================== --- /dev/null +++ llvm/lib/Object/XCOFFObjectFile.cpp @@ -0,0 +1,270 @@ +//===--- XCOFFObjectFile.cpp - XCOFF object file implementation -----------===// +// +// 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 defines the XCOFFObjectFile class. +// +//===----------------------------------------------------------------------===// + +#include "llvm/Object/XCOFFObjectFile.h" +#include "llvm/ADT/ArrayRef.h" +#include "llvm/Support/BinaryStreamReader.h" +#include "llvm/Support/Endian.h" +#include "llvm/Support/ErrorHandling.h" +#include "llvm/Support/MathExtras.h" +#include +#include + +namespace llvm { +namespace object { + +// Sets Obj unless any bytes in [addr, addr + size) fall outsize of m. +// Returns unexpected_eof on error. +template +static std::error_code getObject(const T *&Obj, MemoryBufferRef M, + const void *Ptr, + const uint64_t Size = sizeof(T)) { + uintptr_t Addr = uintptr_t(Ptr); + if (std::error_code EC = Binary::checkOffset(M, Addr, Size)) + return EC; + Obj = reinterpret_cast(Addr); + return std::error_code(); +} + +void XCOFFObjectFile::moveSymbolNext(DataRefImpl &Symb) const { + llvm_unreachable("Not yet implemented!"); + return; +} + +Expected XCOFFObjectFile::getSymbolName(DataRefImpl Symb) const { + StringRef Result; + llvm_unreachable("Not yet implemented!"); + return Result; +} + +Expected XCOFFObjectFile::getSymbolAddress(DataRefImpl Symb) const { + uint64_t Result = 0; + llvm_unreachable("Not yet implemented!"); + return Result; +} + +uint64_t XCOFFObjectFile::getSymbolValueImpl(DataRefImpl Symb) const { + uint64_t Result = 0; + llvm_unreachable("Not yet implemented!"); + return Result; +} + +uint64_t XCOFFObjectFile::getCommonSymbolSizeImpl(DataRefImpl Symb) const { + uint64_t Result = 0; + llvm_unreachable("Not yet implemented!"); + return Result; +} + +Expected +XCOFFObjectFile::getSymbolType(DataRefImpl Symb) const { + llvm_unreachable("Not yet implemented!"); + return SymbolRef::ST_Other; +} + +Expected +XCOFFObjectFile::getSymbolSection(DataRefImpl Symb) const { + llvm_unreachable("Not yet implemented!"); + return section_iterator(SectionRef()); +} + +void XCOFFObjectFile::moveSectionNext(DataRefImpl &Sec) const { + llvm_unreachable("Not yet implemented!"); + return; +} + +std::error_code XCOFFObjectFile::getSectionName(DataRefImpl Sec, + StringRef &Res) const { + llvm_unreachable("Not yet implemented!"); + return std::error_code(); +} + +uint64_t XCOFFObjectFile::getSectionAddress(DataRefImpl Sec) const { + uint64_t Result = 0; + llvm_unreachable("Not yet implemented!"); + return Result; +} + +uint64_t XCOFFObjectFile::getSectionIndex(DataRefImpl Sec) const { + uint64_t Result = 0; + llvm_unreachable("Not yet implemented!"); + return Result; +} + +uint64_t XCOFFObjectFile::getSectionSize(DataRefImpl Sec) const { + uint64_t Result = 0; + llvm_unreachable("Not yet implemented!"); + return Result; +} + +std::error_code XCOFFObjectFile::getSectionContents(DataRefImpl Sec, + StringRef &Res) const { + llvm_unreachable("Not yet implemented!"); + return std::error_code(); +} + +uint64_t XCOFFObjectFile::getSectionAlignment(DataRefImpl Sec) const { + uint64_t Result = 0; + llvm_unreachable("Not yet implemented!"); + return Result; +} + +bool XCOFFObjectFile::isSectionCompressed(DataRefImpl Sec) const { + bool ret = false; + llvm_unreachable("Not yet implemented!"); + return ret; +} + +bool XCOFFObjectFile::isSectionText(DataRefImpl Sec) const { + bool ret = false; + llvm_unreachable("Not yet implemented!"); + return ret; +} + +bool XCOFFObjectFile::isSectionData(DataRefImpl Sec) const { + bool ret = false; + llvm_unreachable("Not yet implemented!"); + return ret; +} + +bool XCOFFObjectFile::isSectionBSS(DataRefImpl Sec) const { + bool ret = false; + llvm_unreachable("Not yet implemented!"); + return ret; +} + +bool XCOFFObjectFile::isSectionVirtual(DataRefImpl Sec) const { + bool ret = false; + llvm_unreachable("Not yet implemented!"); + return ret; +} + +relocation_iterator XCOFFObjectFile::section_rel_begin(DataRefImpl Sec) const { + llvm_unreachable("Not yet implemented!"); + return relocation_iterator(RelocationRef()); +} + +relocation_iterator XCOFFObjectFile::section_rel_end(DataRefImpl Sec) const { + llvm_unreachable("Not yet implemented!"); + return relocation_iterator(RelocationRef()); +} + +void XCOFFObjectFile::moveRelocationNext(DataRefImpl &Rel) const { + llvm_unreachable("Not yet implemented!"); + return; +} + +uint64_t XCOFFObjectFile::getRelocationOffset(DataRefImpl Rel) const { + llvm_unreachable("Not yet implemented!"); + uint64_t Result = 0; + return Result; +} + +symbol_iterator XCOFFObjectFile::getRelocationSymbol(DataRefImpl Rel) const { + llvm_unreachable("Not yet implemented!"); + return symbol_iterator(SymbolRef()); +} + +uint64_t XCOFFObjectFile::getRelocationType(DataRefImpl Rel) const { + llvm_unreachable("Not yet implemented!"); + uint64_t Result = 0; + return Result; +} + +void XCOFFObjectFile::getRelocationTypeName( + DataRefImpl Rel, SmallVectorImpl &Result) const { + llvm_unreachable("Not yet implemented!"); + return; +} + +uint32_t XCOFFObjectFile::getSymbolFlags(DataRefImpl Symb) const { + uint32_t Result = 0; + llvm_unreachable("Not yet implemented!"); + return Result; +} + +basic_symbol_iterator XCOFFObjectFile::symbol_begin() const { + llvm_unreachable("Not yet implemented!"); + return basic_symbol_iterator(SymbolRef()); +} + +basic_symbol_iterator XCOFFObjectFile::symbol_end() const { + llvm_unreachable("Not yet implemented!"); + return basic_symbol_iterator(SymbolRef()); +} + +section_iterator XCOFFObjectFile::section_begin() const { + llvm_unreachable("Not yet implemented!"); + return section_iterator(SectionRef()); +} + +section_iterator XCOFFObjectFile::section_end() const { + llvm_unreachable("Not yet implemented!"); + return section_iterator(SectionRef()); +} + +uint8_t XCOFFObjectFile::getBytesInAddress() const { + uint8_t Result = 0; + llvm_unreachable("Not yet implemented!"); + return Result; +} + +StringRef XCOFFObjectFile::getFileFormatName() const { + llvm_unreachable("Not yet implemented!"); + return ""; +} + +Triple::ArchType XCOFFObjectFile::getArch() const { + llvm_unreachable("Not yet implemented!"); + return Triple::UnknownArch; +} + +SubtargetFeatures XCOFFObjectFile::getFeatures() const { + llvm_unreachable("Not yet implemented!"); + return SubtargetFeatures(); +} + +bool XCOFFObjectFile::isRelocatableObject() const { + bool Result = false; + llvm_unreachable("Not yet implemented!"); + return Result; +} + +XCOFFObjectFile::XCOFFObjectFile(MemoryBufferRef Object, std::error_code &EC) + : ObjectFile(Binary::ID_XCOFF32, Object) { + + // Current location within the file. + uint64_t CurPtr = 0; + + if ((EC = getObject(FileHdrPtr, Data, base() + CurPtr))) + return; +} + +Expected> +ObjectFile::createXCOFFObjectFile(MemoryBufferRef Object) { + StringRef Data = Object.getBuffer(); + file_magic Type = identify_magic(Data); + std::error_code EC; + std::unique_ptr Ret; + + if (Type == file_magic::xcoff_object_32) { + Ret.reset(new XCOFFObjectFile(Object, EC)); + } else { + llvm_unreachable("Encountered an unexpected binary file type!"); + } + + if (EC) + return errorCodeToError(EC); + return std::move(Ret); +} + +} // namespace object +} // namespace llvm Index: llvm/lib/ObjectYAML/CMakeLists.txt =================================================================== --- llvm/lib/ObjectYAML/CMakeLists.txt +++ llvm/lib/ObjectYAML/CMakeLists.txt @@ -11,5 +11,6 @@ MachOYAML.cpp ObjectYAML.cpp WasmYAML.cpp + XCOFFYAML.cpp YAML.cpp ) Index: llvm/lib/ObjectYAML/XCOFFYAML.cpp =================================================================== --- /dev/null +++ llvm/lib/ObjectYAML/XCOFFYAML.cpp @@ -0,0 +1,46 @@ +//===-- XCOFFYAML.cpp - XCOFF YAMLIO implementation -------------*- 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 defines classes for handling the YAML representation of XCOFF. +// +//===----------------------------------------------------------------------===// + +#include "llvm/ObjectYAML/XCOFFYAML.h" +#include "llvm/ObjectYAML/YAML.h" +#include "llvm/Support/YAMLTraits.h" +#include +#include + +namespace llvm { + +namespace XCOFFYAML { + +Object::Object() { memset(&Header, 0, sizeof(Header)); } + +} // namespace XCOFFYAML + +namespace yaml { + +void MappingTraits::mapping( + IO &IO, XCOFFYAML::FileHeader &FileHdr) { + IO.mapRequired("MagicNumber", FileHdr.Magic); + IO.mapRequired("NumberOfSections", FileHdr.NumberOfSections); + IO.mapRequired("CreationTime", FileHdr.TimeStamp); + IO.mapRequired("OffsetToSymbolTable", FileHdr.SymbolTableOffset); + IO.mapRequired("EntriesInSymbolTable", FileHdr.NumberOfSymTableEntries); + IO.mapRequired("AuxiliaryHeaderSize", FileHdr.AuxHeaderSize); + IO.mapRequired("Flags", FileHdr.Flags); +} + +void MappingTraits::mapping(IO &IO, XCOFFYAML::Object &Obj) { + IO.mapTag("!XCOFF", true); + IO.mapRequired("FileHeader", Obj.Header); +} + +} // namespace yaml +} // namespace llvm Index: llvm/test/tools/obj2yaml/aix_xcoff.test =================================================================== --- /dev/null +++ llvm/test/tools/obj2yaml/aix_xcoff.test @@ -0,0 +1,11 @@ +# RUN: obj2yaml %S/Inputs/aix_xcoff.o | FileCheck %s +# Test that we can parse the XCOFF object file correctly. +# CHECK: --- !XCOFF +# CHECK-NEXT: FileHeader: +# CHECK-NEXT: MagicNumber: 0x01DF +# CHECK-NEXT: NumberOfSections: 2 +# CHECK-NEXT: CreationTime: 1548692020 +# CHECK-NEXT: OffsetToSymbolTable: 0x00000108 +# CHECK-NEXT: EntriesInSymbolTable: 18 +# CHECK-NEXT: AuxiliaryHeaderSize: 0 +# CHECK-NEXT: Flags: 0x0000 Index: llvm/test/tools/obj2yaml/aix_xcoff_truncated_file_header.test =================================================================== --- /dev/null +++ llvm/test/tools/obj2yaml/aix_xcoff_truncated_file_header.test @@ -0,0 +1,2 @@ +# RUN: not obj2yaml %S/Inputs/aix_xcoff_truncated_file_header.o 2>&1 | FileCheck %s +# CHECK: The end of the file was unexpectedly encountered Index: llvm/tools/obj2yaml/CMakeLists.txt =================================================================== --- llvm/tools/obj2yaml/CMakeLists.txt +++ llvm/tools/obj2yaml/CMakeLists.txt @@ -13,6 +13,7 @@ dwarf2yaml.cpp elf2yaml.cpp macho2yaml.cpp + xcoff2yaml.cpp wasm2yaml.cpp Error.cpp ) Index: llvm/tools/obj2yaml/obj2yaml.h =================================================================== --- llvm/tools/obj2yaml/obj2yaml.h +++ llvm/tools/obj2yaml/obj2yaml.h @@ -14,6 +14,7 @@ #include "llvm/Object/COFF.h" #include "llvm/Object/Wasm.h" +#include "llvm/Object/XCOFFObjectFile.h" #include "llvm/Support/raw_ostream.h" #include @@ -23,6 +24,8 @@ const llvm::object::ObjectFile &Obj); std::error_code macho2yaml(llvm::raw_ostream &Out, const llvm::object::Binary &Obj); +std::error_code xcoff2yaml(llvm::raw_ostream &Out, + const llvm::object::XCOFFObjectFile &Obj); std::error_code wasm2yaml(llvm::raw_ostream &Out, const llvm::object::WasmObjectFile &Obj); Index: llvm/tools/obj2yaml/obj2yaml.cpp =================================================================== --- llvm/tools/obj2yaml/obj2yaml.cpp +++ llvm/tools/obj2yaml/obj2yaml.cpp @@ -19,6 +19,10 @@ static std::error_code dumpObject(const ObjectFile &Obj) { if (Obj.isCOFF()) return coff2yaml(outs(), cast(Obj)); + + if (Obj.isXCOFF()) + return xcoff2yaml(outs(), cast(Obj)); + if (Obj.isELF()) return elf2yaml(outs(), Obj); if (Obj.isWasm()) Index: llvm/tools/obj2yaml/xcoff2yaml.cpp =================================================================== --- /dev/null +++ llvm/tools/obj2yaml/xcoff2yaml.cpp @@ -0,0 +1,52 @@ +//===------ xcoff2yaml.cpp - XCOFF YAMLIO implementation --------*- 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 +// +//===----------------------------------------------------------------------===// + +#include "obj2yaml.h" +#include "llvm/Object/XCOFFObjectFile.h" +#include "llvm/ObjectYAML/XCOFFYAML.h" +#include "llvm/Support/YAMLTraits.h" + +using namespace llvm; +using namespace llvm::object; +namespace { + +class XCOFFDumper { + const object::XCOFFObjectFile &Obj; + XCOFFYAML::Object YAMLObj; + void dumpHeader(); + +public: + XCOFFDumper(const object::XCOFFObjectFile &obj); + XCOFFYAML::Object &getYAMLObj() { return YAMLObj; } +}; +} // namespace + +XCOFFDumper::XCOFFDumper(const object::XCOFFObjectFile &obj) : Obj(obj) { + dumpHeader(); +} + +void XCOFFDumper::dumpHeader() { + const XCOFFFileHeader *FileHdrPtr = Obj.getFileHeader(); + + YAMLObj.Header.Magic = FileHdrPtr->Magic; + YAMLObj.Header.NumberOfSections = FileHdrPtr->NumberOfSections; + YAMLObj.Header.TimeStamp = FileHdrPtr->TimeStamp; + YAMLObj.Header.SymbolTableOffset = FileHdrPtr->SymbolTableOffset; + YAMLObj.Header.NumberOfSymTableEntries = FileHdrPtr->NumberOfSymTableEntries; + YAMLObj.Header.AuxHeaderSize = FileHdrPtr->AuxHeaderSize; + YAMLObj.Header.Flags = FileHdrPtr->Flags; +} + +std::error_code xcoff2yaml(raw_ostream &Out, + const object::XCOFFObjectFile &Obj) { + XCOFFDumper Dumper(Obj); + yaml::Output Yout(Out); + Yout << Dumper.getYAMLObj(); + + return std::error_code(); +}