diff --git a/llvm/include/llvm/Object/XCOFFObjectFile.h b/llvm/include/llvm/Object/XCOFFObjectFile.h --- a/llvm/include/llvm/Object/XCOFFObjectFile.h +++ b/llvm/include/llvm/Object/XCOFFObjectFile.h @@ -301,9 +301,6 @@ const void *SymbolTblPtr = nullptr; XCOFFStringTable StringTable = {0, nullptr}; - const XCOFFFileHeader32 *fileHeader32() const; - const XCOFFFileHeader64 *fileHeader64() const; - const XCOFFSectionHeader32 *sectionHeaderTable32() const; const XCOFFSectionHeader64 *sectionHeaderTable64() const; template const T *sectionHeaderTable() const; @@ -408,6 +405,8 @@ XCOFFSymbolRef toSymbolRef(DataRefImpl Ref) const; // File header related interfaces. + const XCOFFFileHeader32 *fileHeader32() const; + const XCOFFFileHeader64 *fileHeader64() const; uint16_t getMagic() const; uint16_t getNumberOfSections() const; int32_t getTimeStamp() const; @@ -531,6 +530,9 @@ Entry32 = reinterpret_cast(SymEntDataRef.p); } + const XCOFFSymbolEntry32 *getSymbol32() { return Entry32; } + const XCOFFSymbolEntry64 *getSymbol64() { return Entry64; } + uint64_t getValue() const { return Entry32 ? getValue32() : getValue64(); } uint32_t getValue32() const { return Entry32->Value; } diff --git a/llvm/test/tools/llvm-objcopy/XCOFF/basic-copy.test b/llvm/test/tools/llvm-objcopy/XCOFF/basic-copy.test --- a/llvm/test/tools/llvm-objcopy/XCOFF/basic-copy.test +++ b/llvm/test/tools/llvm-objcopy/XCOFF/basic-copy.test @@ -0,0 +1,36 @@ +# RUN: yaml2obj %s -o %t +# RUN: llvm-objcopy %t %t2 +# RUN: cmp %t %t2 + +--- !XCOFF +FileHeader: + MagicNumber: 0x1DF +Sections: + - Flags: [ STYP_DATA ] + - Name: .text + Flags: [ STYP_TEXT ] + SectionData: "123456" + - Name: .data + Flags: [ STYP_DATA ] + SectionData: "067891" + Relocations: + - Type: 0x02 +Symbols: + - Name: .file + Section: N_DEBUG + Type: 0x3 + StorageClass: C_FILE + NumberOfAuxEntries: 1 + - Name: iiiiiiiii + Value: 0x0 + Section: N_UNDEF + Type: 0x0 + StorageClass: C_EXT + NumberOfAuxEntries: 0 + - Name: .text + Value: 0x0 + Section: .text + Type: 0x0 + StorageClass: C_HIDEXT + NumberOfAuxEntries: 0 +... diff --git a/llvm/tools/llvm-objcopy/CMakeLists.txt b/llvm/tools/llvm-objcopy/CMakeLists.txt --- a/llvm/tools/llvm-objcopy/CMakeLists.txt +++ b/llvm/tools/llvm-objcopy/CMakeLists.txt @@ -39,6 +39,9 @@ wasm/Reader.cpp wasm/Writer.cpp wasm/WasmObjcopy.cpp + XCOFF/Reader.cpp + XCOFF/Writer.cpp + XCOFF/XCOFFObjcopy.cpp DEPENDS ObjcopyOptsTableGen InstallNameToolOptsTableGen diff --git a/llvm/tools/llvm-objcopy/ConfigManager.h b/llvm/tools/llvm-objcopy/ConfigManager.h --- a/llvm/tools/llvm-objcopy/ConfigManager.h +++ b/llvm/tools/llvm-objcopy/ConfigManager.h @@ -15,6 +15,7 @@ #include "MachO/MachOConfig.h" #include "MultiFormatConfig.h" #include "wasm/WasmConfig.h" +#include "XCOFF/XCOFFConfig.h" #include "llvm/Support/Allocator.h" #include @@ -31,6 +32,7 @@ Expected getCOFFConfig() const override; Expected getMachOConfig() const override; Expected getWasmConfig() const override; + Expected getXCOFFConfig() const override; // All configs. CommonConfig Common; @@ -38,6 +40,7 @@ COFFConfig COFF; MachOConfig MachO; WasmConfig Wasm; + XCOFFConfig XCOFF; }; // Configuration for the overall invocation of this tool. When invoked as diff --git a/llvm/tools/llvm-objcopy/ConfigManager.cpp b/llvm/tools/llvm-objcopy/ConfigManager.cpp --- a/llvm/tools/llvm-objcopy/ConfigManager.cpp +++ b/llvm/tools/llvm-objcopy/ConfigManager.cpp @@ -620,6 +620,33 @@ return Wasm; } +Expected ConfigManager::getXCOFFConfig() const { + if (!Common.AddGnuDebugLink.empty() || Common.ExtractPartition || + !Common.SplitDWO.empty() || !Common.SymbolsPrefix.empty() || + !Common.AllocSectionsPrefix.empty() || + Common.DiscardMode != DiscardType::None || !Common.AddSection.empty() || + !Common.DumpSection.empty() || !Common.SymbolsToAdd.empty() || + !Common.KeepSection.empty() || !Common.OnlySection.empty() || + !Common.ToRemove.empty() || !Common.SymbolsToGlobalize.empty() || + !Common.SymbolsToKeep.empty() || !Common.SymbolsToLocalize.empty() || + !Common.SymbolsToRemove.empty() || + !Common.UnneededSymbolsToRemove.empty() || + !Common.SymbolsToWeaken.empty() || !Common.SymbolsToKeepGlobal.empty() || + !Common.SectionsToRename.empty() || !Common.SetSectionAlignment.empty() || + !Common.SetSectionFlags.empty() || !Common.SymbolsToRename.empty() || + Common.ExtractDWO || Common.ExtractMainPartition || + Common.OnlyKeepDebug || Common.PreserveDates || Common.StripAllGNU || + Common.StripDWO || Common.StripDebug || Common.StripNonAlloc || + Common.StripSections || Common.Weaken || Common.StripUnneeded || + Common.DecompressDebugSections) { + return createStringError( + llvm::errc::invalid_argument, + "no flags are supported yet, only basic copying is allowed"); + } + + return XCOFF; +} + // ParseObjcopyOptions returns the config and sets the input arguments. If a // help flag is set then ParseObjcopyOptions will print the help messege and // exit. diff --git a/llvm/tools/llvm-objcopy/MultiFormatConfig.h b/llvm/tools/llvm-objcopy/MultiFormatConfig.h --- a/llvm/tools/llvm-objcopy/MultiFormatConfig.h +++ b/llvm/tools/llvm-objcopy/MultiFormatConfig.h @@ -19,6 +19,7 @@ struct COFFConfig; struct MachOConfig; struct WasmConfig; +struct XCOFFConfig; class MultiFormatConfig { public: @@ -29,6 +30,7 @@ virtual Expected getCOFFConfig() const = 0; virtual Expected getMachOConfig() const = 0; virtual Expected getWasmConfig() const = 0; + virtual Expected getXCOFFConfig() const = 0; }; } // namespace objcopy diff --git a/llvm/tools/llvm-objcopy/XCOFF/Object.h b/llvm/tools/llvm-objcopy/XCOFF/Object.h --- a/llvm/tools/llvm-objcopy/XCOFF/Object.h +++ b/llvm/tools/llvm-objcopy/XCOFF/Object.h @@ -0,0 +1,44 @@ +//===- Object.h -------------------------------------------------*- 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 +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_TOOLS_OBJCOPY_XCOFF_OBJECT_H +#define LLVM_TOOLS_OBJCOPY_XCOFF_OBJECT_H + +#include "llvm/ADT/ArrayRef.h" +#include "llvm/ADT/StringRef.h" +#include "llvm/Object/XCOFFObjectFile.h" +#include + +namespace llvm { +namespace objcopy { +namespace xcoff { + +using namespace object; + +struct Section { + XCOFFSectionHeader32 SectionHeader; + ArrayRef Contents; + std::vector Relocations; +}; + +struct Symbol { + XCOFFSymbolEntry32 Sym; + StringRef SymbolName; +}; + +struct Object { + XCOFFFileHeader32 FileHeader; + std::vector
Sections; + std::vector Symbols; +}; + +} // end namespace xcoff +} // end namespace objcopy +} // end namespace llvm + +#endif // LLVM_TOOLS_OBJCOPY_XCOFF_OBJECT_H diff --git a/llvm/tools/llvm-objcopy/XCOFF/Reader.h b/llvm/tools/llvm-objcopy/XCOFF/Reader.h --- a/llvm/tools/llvm-objcopy/XCOFF/Reader.h +++ b/llvm/tools/llvm-objcopy/XCOFF/Reader.h @@ -0,0 +1,35 @@ +//===- Reader.h -------------------------------------------------*- 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 +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_TOOLS_OBJCOPY_XCOFF_READER_H +#define LLVM_TOOLS_OBJCOPY_XCOFF_READER_H + +#include "Object.h" + +namespace llvm { +namespace objcopy { +namespace xcoff { + +using namespace object; + +class XCOFFReader { +public: + explicit XCOFFReader(const XCOFFObjectFile &O) : XCOFFObj(O) {} + Expected> create() const; + +private: + const XCOFFObjectFile &XCOFFObj; + Error readSections(Object &Obj) const; + Error readSymbols(Object &Obj) const; +}; + +} // end namespace xcoff +} // end namespace objcopy +} // end namespace llvm + +#endif // LLVM_TOOLS_OBJCOPY_XCOFF_READER_H diff --git a/llvm/tools/llvm-objcopy/XCOFF/Reader.cpp b/llvm/tools/llvm-objcopy/XCOFF/Reader.cpp --- a/llvm/tools/llvm-objcopy/XCOFF/Reader.cpp +++ b/llvm/tools/llvm-objcopy/XCOFF/Reader.cpp @@ -0,0 +1,87 @@ +//===- Reader.cpp ---------------------------------------------------------===// +// +// 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 "Reader.h" + +namespace llvm { +namespace objcopy { +namespace xcoff { + +using namespace object; + +Error XCOFFReader::readSections(Object &Obj) const { + ArrayRef Sections = XCOFFObj.sections32(); + for (const XCOFFSectionHeader32 &Sec : Sections) { + Section ReadSec; + // Read section header. + ReadSec.SectionHeader = Sec; + + // Read section data. + if (Sec.SectionSize) { + DataRefImpl SectionDRI; + SectionDRI.p = reinterpret_cast(&Sec); + Expected> ContentsRef = + XCOFFObj.getSectionContents(SectionDRI); + if (!ContentsRef) + return ContentsRef.takeError(); + ReadSec.Contents = ContentsRef.get(); + } + + // Read relocations. + if (Sec.NumberOfRelocations) { + auto Relocations = + XCOFFObj.relocations(Sec); + if (!Relocations) + return Relocations.takeError(); + for (const XCOFFRelocation32 &Rel : Relocations.get()) + ReadSec.Relocations.push_back(Rel); + } + Obj.Sections.push_back(ReadSec); + } + return Error::success(); +} + +Error XCOFFReader::readSymbols(Object &Obj) const { + std::vector Symbols; + Symbols.reserve(XCOFFObj.getRawNumberOfSymbolTableEntries32()); + for (const SymbolRef &S : XCOFFObj.symbols()) { + Symbol ReadSym; + DataRefImpl SymbolDRI = S.getRawDataRefImpl(); + XCOFFSymbolRef SymbolEntRef = XCOFFObj.toSymbolRef(SymbolDRI); + ReadSym.Sym = *SymbolEntRef.getSymbol32(); + Expected SymNameOrError = XCOFFObj.getSymbolName(SymbolDRI); + if (!SymNameOrError) + return SymNameOrError.takeError(); + ReadSym.SymbolName = SymNameOrError.get(); + Obj.Symbols.push_back(ReadSym); + } + return Error::success(); +} + +Expected> XCOFFReader::create() const { + auto Obj = std::make_unique(); + // Only 32-bit supported now. + if (XCOFFObj.is64Bit()) + return createStringError(object_error::invalid_file_type, + "64-bit XCOFF is not supported yet"); + // Read the file header. + Obj->FileHeader = *XCOFFObj.fileHeader32(); + // Read each section. + Obj->Sections.reserve(XCOFFObj.getNumberOfSections()); + if (Error E = readSections(*Obj)) + return std::move(E); + // Read each symbol. + Obj->Symbols.reserve(XCOFFObj.getRawNumberOfSymbolTableEntries32()); + if (Error E = readSymbols(*Obj)) + return std::move(E); + return std::move(Obj); +} + +} // end namespace xcoff +} // end namespace objcopy +} // end namespace llvm diff --git a/llvm/tools/llvm-objcopy/XCOFF/Writer.h b/llvm/tools/llvm-objcopy/XCOFF/Writer.h --- a/llvm/tools/llvm-objcopy/XCOFF/Writer.h +++ b/llvm/tools/llvm-objcopy/XCOFF/Writer.h @@ -0,0 +1,51 @@ +//===- Writer.h -------------------------------------------------*- 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 +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_TOOLS_OBJCOPY_XCOFF_WRITER_H +#define LLVM_TOOLS_OBJCOPY_XCOFF_WRITER_H + +#include "Object.h" +#include "llvm/MC/StringTableBuilder.h" +#include "llvm/Support/MemoryBuffer.h" +#include +#include + +namespace llvm { +namespace objcopy { +namespace xcoff { + +class XCOFFWriter { +public: + virtual ~XCOFFWriter() {} + XCOFFWriter(Object &Obj, raw_ostream &Out) + : Obj(Obj), Out(Out), Strings(StringTableBuilder::XCOFF) {} + Error write(); + +private: + Object &Obj; + raw_ostream &Out; + std::unique_ptr Buf; + size_t FileSize; + StringTableBuilder Strings; + + void finalizeHeaders(); + void finalizeSections(); + void finalizeSymbols(); + void finalizeStringTable(); + void finalize(); + + void writeHeaders(); + void writeSections(); + void writeSymbolStringTable(); +}; + +} // end namespace xcoff +} // end namespace objcopy +} // end namespace llvm + +#endif // LLVM_TOOLS_OBJCOPY_XCOFF_WRITER_H diff --git a/llvm/tools/llvm-objcopy/XCOFF/Writer.cpp b/llvm/tools/llvm-objcopy/XCOFF/Writer.cpp --- a/llvm/tools/llvm-objcopy/XCOFF/Writer.cpp +++ b/llvm/tools/llvm-objcopy/XCOFF/Writer.cpp @@ -0,0 +1,132 @@ +//===- Writer.cpp ---------------------------------------------------------===// +// +// 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 "Writer.h" +#include "llvm/Support/Errc.h" + +namespace llvm { +namespace objcopy { +namespace xcoff { + +using namespace object; + +void XCOFFWriter::finalizeHeaders() { + // File header. + FileSize += sizeof(XCOFFFileHeader32); + Obj.FileHeader.NumberOfSections = Obj.Sections.size(); + Obj.FileHeader.NumberOfSymTableEntries = Obj.Symbols.size(); + + // Section headers. + FileSize += sizeof(XCOFFSectionHeader32) * Obj.Sections.size(); +} + +void XCOFFWriter::finalizeSections() { + for (Section &Sec : Obj.Sections) { + // Section data. + if (Sec.Contents.size()) { + Sec.SectionHeader.FileOffsetToRawData = FileSize; + FileSize += Sec.Contents.size(); + } + // Relocations. + Sec.SectionHeader.NumberOfRelocations = Sec.Relocations.size(); + if (Sec.Relocations.size()) + FileSize += Sec.Relocations.size() * sizeof(XCOFFRelocation32); + } +} + +void XCOFFWriter::finalizeSymbols() { + Obj.FileHeader.SymbolTableOffset = FileSize; + uint32_t NumOfSymEnt = 0; + for (Symbol &Sym : Obj.Symbols) + NumOfSymEnt += 1 + Sym.Sym.NumberOfAuxEntries; + Obj.FileHeader.NumberOfSymTableEntries = NumOfSymEnt; + FileSize += NumOfSymEnt * sizeof(XCOFFSymbolEntry32); +} + +void XCOFFWriter::finalizeStringTable() { + for (const Symbol &Sym : Obj.Symbols) + if (Sym.SymbolName.size() > XCOFF::NameSize) + Strings.add(Sym.SymbolName); + + Strings.finalize(); + FileSize += Strings.getSize(); +} + +void XCOFFWriter::finalize() { + FileSize = 0; + Strings.clear(); + finalizeHeaders(); + finalizeSections(); + finalizeSymbols(); + finalizeStringTable(); +} + +void XCOFFWriter::writeHeaders() { + // Write the file header. + uint8_t *Ptr = reinterpret_cast(Buf->getBufferStart()); + memcpy(Ptr, &Obj.FileHeader, sizeof(XCOFFFileHeader32)); + Ptr += sizeof(XCOFFFileHeader32); + + // Write section headers. + for (const Section &Sec : Obj.Sections) { + memcpy(Ptr, &Sec.SectionHeader, sizeof(XCOFFSectionHeader32)); + Ptr += sizeof(XCOFFSectionHeader32); + } +} + +void XCOFFWriter::writeSections() { + // Write section data. + for (const Section &Sec : Obj.Sections) { + uint8_t *Ptr = reinterpret_cast(Buf->getBufferStart()) + + Sec.SectionHeader.FileOffsetToRawData; + Ptr = std::copy(Sec.Contents.begin(), Sec.Contents.end(), Ptr); + } + + // Write relocations for sections. + for (const Section &Sec : Obj.Sections) { + uint8_t *Ptr = reinterpret_cast(Buf->getBufferStart()) + + Sec.SectionHeader.FileOffsetToRelocationInfo; + for (const XCOFFRelocation32 &Rel : Sec.Relocations) { + memcpy(Ptr, &Rel, sizeof(XCOFFRelocation32)); + Ptr += sizeof(XCOFFRelocation32); + } + } +} + +void XCOFFWriter::writeSymbolStringTable() { + // Write symbols. + uint8_t *Ptr = reinterpret_cast(Buf->getBufferStart()) + + Obj.FileHeader.SymbolTableOffset; + for (const Symbol &Sym : Obj.Symbols) { + memcpy(Ptr, &Sym.Sym, sizeof(XCOFFSymbolEntry32)); + Ptr += sizeof(XCOFFSymbolEntry32) * (1 + Sym.Sym.NumberOfAuxEntries); + } + // Write the string table. + Strings.write(Ptr); + Ptr += Strings.getSize(); + Out.write(Buf->getBufferStart(), Buf->getBufferSize()); +} + +Error XCOFFWriter::write() { + finalize(); + Buf = WritableMemoryBuffer::getNewMemBuffer(FileSize); + if (!Buf) + return createStringError(errc::not_enough_memory, + "failed to allocate memory buffer of " + + Twine::utohexstr(FileSize) + " bytes"); + + if (Error E = writeHeaders()) + return E; + writeSections(); + writeSymbolStringTable(); + return Error::success(); +} + +} // end namespace xcoff +} // end namespace objcopy +} // end namespace llvm diff --git a/llvm/tools/llvm-objcopy/XCOFF/XCOFFConfig.h b/llvm/tools/llvm-objcopy/XCOFF/XCOFFConfig.h --- a/llvm/tools/llvm-objcopy/XCOFF/XCOFFConfig.h +++ b/llvm/tools/llvm-objcopy/XCOFF/XCOFFConfig.h @@ -0,0 +1,21 @@ +//===- COFFConfig.h ---------------------------------------------*- 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 +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_TOOLS_LLVM_OBJCOPY_XCOFF_XCOFFCONFIG_H +#define LLVM_TOOLS_LLVM_OBJCOPY_XCOFF_XCOFFCONFIG_H + +namespace llvm { +namespace objcopy { + +// XCOFF specific configuration for copying/stripping a single file. +struct XCOFFConfig {}; + +} // namespace objcopy +} // namespace llvm + +#endif // LLVM_TOOLS_LLVM_OBJCOPY_XCOFF_XCOFFCONFIG_H diff --git a/llvm/tools/llvm-objcopy/XCOFF/XCOFFObjcopy.h b/llvm/tools/llvm-objcopy/XCOFF/XCOFFObjcopy.h --- a/llvm/tools/llvm-objcopy/XCOFF/XCOFFObjcopy.h +++ b/llvm/tools/llvm-objcopy/XCOFF/XCOFFObjcopy.h @@ -0,0 +1,33 @@ +//===- XCOFFObjcopy.h -------------------------------------------*- 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 +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_TOOLS_LLVM_OBJCOPY_XCOFFOBJCOPY_H +#define LLVM_TOOLS_LLVM_OBJCOPY_XCOFFOBJCOPY_H + +namespace llvm { +class Error; +class raw_ostream; + +namespace object { +class XCOFFObjectFile; +} // end namespace object + +namespace objcopy { +struct CommonConfig; +struct XCOFFConfig; + +namespace xcoff { +Error executeObjcopyOnBinary(const CommonConfig &Config, const XCOFFConfig &, + object::XCOFFObjectFile &In, raw_ostream &Out); + +} // end namespace xcoff +} // end namespace objcopy +} // end namespace llvm + +#endif // LLVM_TOOLS_LLVM_OBJCOPY_XCOFFOBJCOPY_H + diff --git a/llvm/tools/llvm-objcopy/XCOFF/XCOFFObjcopy.cpp b/llvm/tools/llvm-objcopy/XCOFF/XCOFFObjcopy.cpp --- a/llvm/tools/llvm-objcopy/XCOFF/XCOFFObjcopy.cpp +++ b/llvm/tools/llvm-objcopy/XCOFF/XCOFFObjcopy.cpp @@ -0,0 +1,45 @@ +//===- XCOFFObjcopy.cpp ---------------------------------------------------===// +// +// 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 "XCOFFObjcopy.h" +#include "CommonConfig.h" +#include "Object.h" +#include "Reader.h" +#include "Writer.h" +#include "XCOFFConfig.h" +#include "llvm/Support/Errc.h" + +namespace llvm { +namespace objcopy { +namespace xcoff { + +using namespace object; + +static Error handleArgs(const CommonConfig &Config, Object &Obj) { + return Error::success(); +} + +Error executeObjcopyOnBinary(const CommonConfig &Config, const XCOFFConfig &, + XCOFFObjectFile &In, raw_ostream &Out) { + XCOFFReader Reader(In); + Expected> ObjOrErr = Reader.create(); + if (!ObjOrErr) + return createFileError(Config.InputFilename, ObjOrErr.takeError()); + Object *Obj = ObjOrErr->get(); + assert(Obj && "Unable to deserialize XCOFF object"); + if (Error E = handleArgs(Config, *Obj)) + return createFileError(Config.InputFilename, std::move(E)); + XCOFFWriter Writer(*Obj, Out); + if (Error E = Writer.write()) + return createFileError(Config.OutputFilename, std::move(E)); + return Error::success(); +} + +} // end namespace xcoff +} // end namespace objcopy +} // end namespace llvm diff --git a/llvm/tools/llvm-objcopy/llvm-objcopy.cpp b/llvm/tools/llvm-objcopy/llvm-objcopy.cpp --- a/llvm/tools/llvm-objcopy/llvm-objcopy.cpp +++ b/llvm/tools/llvm-objcopy/llvm-objcopy.cpp @@ -17,6 +17,8 @@ #include "MachO/MachOObjcopy.h" #include "wasm/WasmConfig.h" #include "wasm/WasmObjcopy.h" +#include "XCOFF/XCOFFConfig.h" +#include "XCOFF/XCOFFObjcopy.h" #include "llvm/ADT/STLExtras.h" #include "llvm/ADT/SmallVector.h" @@ -33,6 +35,7 @@ #include "llvm/Object/MachO.h" #include "llvm/Object/MachOUniversal.h" #include "llvm/Object/Wasm.h" +#include "llvm/Object/XCOFFObjectFile.h" #include "llvm/Option/Arg.h" #include "llvm/Option/ArgList.h" #include "llvm/Option/Option.h" @@ -202,6 +205,13 @@ return objcopy::wasm::executeObjcopyOnBinary(Config.getCommonConfig(), *WasmConfig, *WasmBinary, Out); + } else if (auto *XCOFFBinary = dyn_cast(&In)) { + Expected XCOFFConfig = Config.getXCOFFConfig(); + if (!XCOFFConfig) + return XCOFFConfig.takeError(); + + return xcoff::executeObjcopyOnBinary(Config.getCommonConfig(), *XCOFFConfig, + *XCOFFBinary, Out); } else return createStringError(object_error::invalid_file_type, "unsupported object file format");