diff --git a/llvm/tools/llvm-objcopy/COFF/COFFConfig.h b/llvm/include/llvm/Object/ObjCopy/COFF/COFFConfig.h rename from llvm/tools/llvm-objcopy/COFF/COFFConfig.h rename to llvm/include/llvm/Object/ObjCopy/COFF/COFFConfig.h --- a/llvm/tools/llvm-objcopy/COFF/COFFConfig.h +++ b/llvm/include/llvm/Object/ObjCopy/COFF/COFFConfig.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_TOOLS_LLVM_OBJCOPY_COFF_COFFCONFIG_H -#define LLVM_TOOLS_LLVM_OBJCOPY_COFF_COFFCONFIG_H +#ifndef LLVM_OBJECT_OBJCOPY_COFF_COFFCONFIG_H +#define LLVM_OBJECT_OBJCOPY_COFF_COFFCONFIG_H namespace llvm { namespace objcopy { @@ -18,4 +18,4 @@ } // namespace objcopy } // namespace llvm -#endif // LLVM_TOOLS_LLVM_OBJCOPY_COFF_COFFCONFIG_H +#endif // LLVM_OBJECT_OBJCOPY_COFF_COFFCONFIG_H diff --git a/llvm/tools/llvm-objcopy/COFF/COFFObjcopy.h b/llvm/include/llvm/Object/ObjCopy/COFF/COFFObjcopy.h rename from llvm/tools/llvm-objcopy/COFF/COFFObjcopy.h rename to llvm/include/llvm/Object/ObjCopy/COFF/COFFObjcopy.h --- a/llvm/tools/llvm-objcopy/COFF/COFFObjcopy.h +++ b/llvm/include/llvm/Object/ObjCopy/COFF/COFFObjcopy.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_TOOLS_OBJCOPY_COFFOBJCOPY_H -#define LLVM_TOOLS_OBJCOPY_COFFOBJCOPY_H +#ifndef LLVM_OBJECT_OBJCOPY_COFF_COFFOBJCOPY_H +#define LLVM_OBJECT_OBJCOPY_COFF_COFFOBJCOPY_H namespace llvm { class Error; @@ -23,6 +23,9 @@ namespace coff { +/// Applies the transformations described by \p Config to +/// \p In(FileFormat::Unspecified) and writes the result into \p Out. +/// \returns any Error encountered whilst performing the operation. Error executeObjcopyOnBinary(const CommonConfig &Config, const COFFConfig &, object::COFFObjectFile &In, raw_ostream &Out); @@ -30,4 +33,4 @@ } // end namespace objcopy } // end namespace llvm -#endif // LLVM_TOOLS_OBJCOPY_COFFOBJCOPY_H +#endif // LLVM_OBJECT_OBJCOPY_COFF_COFFOBJCOPY_H diff --git a/llvm/tools/llvm-objcopy/CommonConfig.h b/llvm/include/llvm/Object/ObjCopy/CommonConfig.h rename from llvm/tools/llvm-objcopy/CommonConfig.h rename to llvm/include/llvm/Object/ObjCopy/CommonConfig.h --- a/llvm/tools/llvm-objcopy/CommonConfig.h +++ b/llvm/include/llvm/Object/ObjCopy/CommonConfig.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_TOOLS_LLVM_OBJCOPY_COMMONCONFIG_H -#define LLVM_TOOLS_LLVM_OBJCOPY_COMMONCONFIG_H +#ifndef LLVM_OBJECT_OBJCOPY_COMMONCONFIG_H +#define LLVM_OBJECT_OBJCOPY_COMMONCONFIG_H #include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/CachedHashString.h" @@ -256,4 +256,4 @@ } // namespace objcopy } // namespace llvm -#endif // LLVM_TOOLS_LLVM_OBJCOPY_COMMONCONFIG_H +#endif // LLVM_OBJECT_OBJCOPY_COMMONCONFIG_H diff --git a/llvm/include/llvm/Object/ObjCopy/ConfigManager.h b/llvm/include/llvm/Object/ObjCopy/ConfigManager.h new file mode 100644 --- /dev/null +++ b/llvm/include/llvm/Object/ObjCopy/ConfigManager.h @@ -0,0 +1,106 @@ +//===- ConfigManager.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_OBJECT_OBJCOPY_CONFIGMANAGER_H +#define LLVM_OBJECT_OBJCOPY_CONFIGMANAGER_H + +#include "llvm/Object/ObjCopy/COFF/COFFConfig.h" +#include "llvm/Object/ObjCopy/CommonConfig.h" +#include "llvm/Object/ObjCopy/ELF/ELFConfig.h" +#include "llvm/Object/ObjCopy/MachO/MachOConfig.h" +#include "llvm/Object/ObjCopy/MultiFormatConfig.h" +#include "llvm/Object/ObjCopy/wasm/WasmConfig.h" +#include "llvm/Support/Errc.h" +#include "llvm/Support/Error.h" + +namespace llvm { +namespace objcopy { + +// ConfigManager keeps all configurations and prepare +// format-specific options. +struct ConfigManager : public MultiFormatConfig { + virtual ~ConfigManager() {} + + const CommonConfig &getCommonConfig() const override { return Common; } + + Expected getELFConfig() const override { return ELF; } + + Expected getCOFFConfig() const override { + if (!Common.SplitDWO.empty() || !Common.SymbolsPrefix.empty() || + !Common.AllocSectionsPrefix.empty() || !Common.DumpSection.empty() || + !Common.KeepSection.empty() || !Common.SymbolsToGlobalize.empty() || + !Common.SymbolsToKeep.empty() || !Common.SymbolsToLocalize.empty() || + !Common.SymbolsToWeaken.empty() || + !Common.SymbolsToKeepGlobal.empty() || + !Common.SectionsToRename.empty() || + !Common.SetSectionAlignment.empty() || Common.ExtractDWO || + Common.PreserveDates || Common.StripDWO || Common.StripNonAlloc || + Common.StripSections || Common.Weaken || + Common.DecompressDebugSections || + Common.DiscardMode == DiscardType::Locals || + !Common.SymbolsToAdd.empty()) + return createStringError(llvm::errc::invalid_argument, + "option is not supported for COFF"); + + return COFF; + } + + Expected getMachOConfig() const override { + if (!Common.SplitDWO.empty() || !Common.SymbolsPrefix.empty() || + !Common.AllocSectionsPrefix.empty() || !Common.KeepSection.empty() || + !Common.SymbolsToGlobalize.empty() || !Common.SymbolsToKeep.empty() || + !Common.SymbolsToLocalize.empty() || !Common.SymbolsToWeaken.empty() || + !Common.SymbolsToKeepGlobal.empty() || + !Common.SectionsToRename.empty() || + !Common.UnneededSymbolsToRemove.empty() || + !Common.SetSectionAlignment.empty() || + !Common.SetSectionFlags.empty() || Common.ExtractDWO || + Common.PreserveDates || Common.StripAllGNU || Common.StripDWO || + Common.StripNonAlloc || Common.StripSections || Common.Weaken || + Common.DecompressDebugSections || Common.StripUnneeded || + Common.DiscardMode == DiscardType::Locals || + !Common.SymbolsToAdd.empty()) + return createStringError(llvm::errc::invalid_argument, + "option is not supported for MachO"); + + return MachO; + } + + Expected getWasmConfig() const override { + if (!Common.AddGnuDebugLink.empty() || Common.ExtractPartition || + !Common.SplitDWO.empty() || !Common.SymbolsPrefix.empty() || + !Common.AllocSectionsPrefix.empty() || + Common.DiscardMode != DiscardType::None || + !Common.SymbolsToAdd.empty() || !Common.SymbolsToGlobalize.empty() || + !Common.SymbolsToLocalize.empty() || !Common.SymbolsToKeep.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()) + return createStringError(llvm::errc::invalid_argument, + "only flags for section dumping, removal, and " + "addition are supported"); + + return Wasm; + } + + // All configs. + CommonConfig Common; + ELFConfig ELF; + COFFConfig COFF; + MachOConfig MachO; + WasmConfig Wasm; +}; + +} // namespace objcopy +} // namespace llvm + +#endif // LLVM_OBJECT_OBJCOPY_CONFIGMANAGER_H diff --git a/llvm/tools/llvm-objcopy/ELF/ELFConfig.h b/llvm/include/llvm/Object/ObjCopy/ELF/ELFConfig.h rename from llvm/tools/llvm-objcopy/ELF/ELFConfig.h rename to llvm/include/llvm/Object/ObjCopy/ELF/ELFConfig.h --- a/llvm/tools/llvm-objcopy/ELF/ELFConfig.h +++ b/llvm/include/llvm/Object/ObjCopy/ELF/ELFConfig.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_TOOLS_LLVM_OBJCOPY_ELF_ELFCONFIG_H -#define LLVM_TOOLS_LLVM_OBJCOPY_ELF_ELFCONFIG_H +#ifndef LLVM_OBJECT_OBJCOPY_ELF_ELFCONFIG_H +#define LLVM_OBJECT_OBJCOPY_ELF_ELFCONFIG_H #include "llvm/ADT/Optional.h" #include "llvm/ADT/StringRef.h" @@ -35,4 +35,4 @@ } // namespace objcopy } // namespace llvm -#endif // LLVM_TOOLS_LLVM_OBJCOPY_ELF_ELFCONFIG_H +#endif // LLVM_OBJECT_OBJCOPY_ELF_ELFCONFIG_H diff --git a/llvm/tools/llvm-objcopy/ELF/ELFObjcopy.h b/llvm/include/llvm/Object/ObjCopy/ELF/ELFObjcopy.h rename from llvm/tools/llvm-objcopy/ELF/ELFObjcopy.h rename to llvm/include/llvm/Object/ObjCopy/ELF/ELFObjcopy.h --- a/llvm/tools/llvm-objcopy/ELF/ELFObjcopy.h +++ b/llvm/include/llvm/Object/ObjCopy/ELF/ELFObjcopy.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_TOOLS_OBJCOPY_ELFOBJCOPY_H -#define LLVM_TOOLS_OBJCOPY_ELFOBJCOPY_H +#ifndef LLVM_OBJECT_OBJCOPY_ELF_ELFOBJCOPY_H +#define LLVM_OBJECT_OBJCOPY_ELF_ELFOBJCOPY_H namespace llvm { class Error; @@ -23,12 +23,24 @@ struct ELFConfig; namespace elf { +/// Applies the transformations described by \p Config and \p ELFConfig to +/// \p In(FileFormat::IHex) and writes the result into \p Out. +/// \returns any Error encountered whilst performing the operation. Error executeObjcopyOnIHex(const CommonConfig &Config, const ELFConfig &ELFConfig, MemoryBuffer &In, raw_ostream &Out); + +/// Applies the transformations described by \p Config and \p ELFConfig to +/// \p In(FileFormat::Binary) and writes the result into \p Out. +/// \returns any Error encountered whilst performing the operation. Error executeObjcopyOnRawBinary(const CommonConfig &Config, const ELFConfig &ELFConfig, MemoryBuffer &In, raw_ostream &Out); + +/// Applies the transformations described by \p Config and \p ELFConfig to +/// \p In(FileFormat::ELF or FileFormat::Unspecified) and writes +/// the result into \p Out. +/// \returns any Error encountered whilst performing the operation. Error executeObjcopyOnBinary(const CommonConfig &Config, const ELFConfig &ELFConfig, object::ELFObjectFileBase &In, raw_ostream &Out); @@ -37,4 +49,4 @@ } // end namespace objcopy } // end namespace llvm -#endif // LLVM_TOOLS_OBJCOPY_ELFOBJCOPY_H +#endif // LLVM_OBJECT_OBJCOPY_ELF_ELFOBJCOPY_H diff --git a/llvm/tools/llvm-objcopy/MachO/MachOConfig.h b/llvm/include/llvm/Object/ObjCopy/MachO/MachOConfig.h rename from llvm/tools/llvm-objcopy/MachO/MachOConfig.h rename to llvm/include/llvm/Object/ObjCopy/MachO/MachOConfig.h --- a/llvm/tools/llvm-objcopy/MachO/MachOConfig.h +++ b/llvm/include/llvm/Object/ObjCopy/MachO/MachOConfig.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_TOOLS_LLVM_OBJCOPY_MACHO_MACHOCONFIG_H -#define LLVM_TOOLS_LLVM_OBJCOPY_MACHO_MACHOCONFIG_H +#ifndef LLVM_OBJECT_OBJCOPY_MACHO_MACHOCONFIG_H +#define LLVM_OBJECT_OBJCOPY_MACHO_MACHOCONFIG_H #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/DenseSet.h" @@ -40,4 +40,4 @@ } // namespace objcopy } // namespace llvm -#endif // LLVM_TOOLS_LLVM_OBJCOPY_MACHO_MACHOCONFIG_H +#endif // LLVM_OBJECT_OBJCOPY_MACHO_MACHOCONFIG_H diff --git a/llvm/tools/llvm-objcopy/MachO/MachOObjcopy.h b/llvm/include/llvm/Object/ObjCopy/MachO/MachOObjcopy.h rename from llvm/tools/llvm-objcopy/MachO/MachOObjcopy.h rename to llvm/include/llvm/Object/ObjCopy/MachO/MachOObjcopy.h --- a/llvm/tools/llvm-objcopy/MachO/MachOObjcopy.h +++ b/llvm/include/llvm/Object/ObjCopy/MachO/MachOObjcopy.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_TOOLS_OBJCOPY_MACHOOBJCOPY_H -#define LLVM_TOOLS_OBJCOPY_MACHOOBJCOPY_H +#ifndef LLVM_OBJECT_OBJCOPY_MACHO_MACHOOBJCOPY_H +#define LLVM_OBJECT_OBJCOPY_MACHO_MACHOOBJCOPY_H namespace llvm { class Error; @@ -24,10 +24,16 @@ class MultiFormatConfig; namespace macho { +/// Applies the transformations described by \p Config and \p MachOConfig to +/// \p In(FileFormat::Unspecified) and writes the result into \p Out. +/// \returns any Error encountered whilst performing the operation. Error executeObjcopyOnBinary(const CommonConfig &Config, const MachOConfig &MachOConfig, object::MachOObjectFile &In, raw_ostream &Out); +/// Applies the transformations described by \p Config and \p MachOConfig to +/// \p In(FileFormat::Unspecified) and writes the result into \p Out. +/// \returns any Error encountered whilst performing the operation. Error executeObjcopyOnMachOUniversalBinary( const MultiFormatConfig &Config, const object::MachOUniversalBinary &In, raw_ostream &Out); @@ -36,4 +42,4 @@ } // end namespace objcopy } // end namespace llvm -#endif // LLVM_TOOLS_OBJCOPY_MACHOOBJCOPY_H +#endif // LLVM_OBJECT_OBJCOPY_MACHO_MACHOOBJCOPY_H diff --git a/llvm/tools/llvm-objcopy/MultiFormatConfig.h b/llvm/include/llvm/Object/ObjCopy/MultiFormatConfig.h rename from llvm/tools/llvm-objcopy/MultiFormatConfig.h rename to llvm/include/llvm/Object/ObjCopy/MultiFormatConfig.h --- a/llvm/tools/llvm-objcopy/MultiFormatConfig.h +++ b/llvm/include/llvm/Object/ObjCopy/MultiFormatConfig.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_TOOLS_LLVM_OBJCOPY_MULTIFORMATCONFIG_H -#define LLVM_TOOLS_LLVM_OBJCOPY_MULTIFORMATCONFIG_H +#ifndef LLVM_OBJECT_OBJCOPY_MULTIFORMATCONFIG_H +#define LLVM_OBJECT_OBJCOPY_MULTIFORMATCONFIG_H #include "llvm/Support/Error.h" @@ -34,4 +34,4 @@ } // namespace objcopy } // namespace llvm -#endif // LLVM_TOOLS_LLVM_OBJCOPY_MULTIFORMATCONFIG_H +#endif // LLVM_OBJECT_OBJCOPY_MULTIFORMATCONFIG_H diff --git a/llvm/include/llvm/Object/ObjCopy/ObjCopy.h b/llvm/include/llvm/Object/ObjCopy/ObjCopy.h new file mode 100644 --- /dev/null +++ b/llvm/include/llvm/Object/ObjCopy/ObjCopy.h @@ -0,0 +1,47 @@ +//===- ObjCopy.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_OBJECT_OBJCOPY_OBJCOPY_H +#define LLVM_OBJECT_OBJCOPY_OBJCOPY_H + +#include "llvm/Object/Archive.h" +#include "llvm/Object/ArchiveWriter.h" +#include "llvm/Object/Binary.h" +#include "llvm/Object/ObjCopy/CommonConfig.h" +#include "llvm/Object/ObjCopy/MultiFormatConfig.h" +#include "llvm/Support/Error.h" +#include "llvm/Support/raw_ostream.h" + +namespace llvm { +namespace objcopy { + +/// Applies the transformations described by \p Config to +/// each member in archive \p Ar. +/// \returns Vector of transformed archive members. +Expected> +createNewArchiveMembers(const MultiFormatConfig &Config, + const object::Archive &Ar); + +/// Applies the transformations described by \p Config to +/// each member in archive \p Ar. +/// Writes a result in a file specified by \p Config.OutputFilename. +/// \returns any Error encountered whilst performing the operation. +Error executeObjcopyOnArchive(const MultiFormatConfig &Config, + const object::Archive &Ar); + +/// Applies the transformations described by \p Config to \p In and writes +/// the result into \p Out. This function does the dispatch based on the +/// format of the input binary (COFF, ELF, MachO or wasm). +/// \returns any Error encountered whilst performing the operation. +Error executeObjcopyOnBinary(const MultiFormatConfig &Config, + object::Binary &In, raw_ostream &Out); + +} // end namespace objcopy +} // end namespace llvm + +#endif // LLVM_OBJECT_OBJCOPY_OBJCOPY_H diff --git a/llvm/tools/llvm-objcopy/wasm/WasmConfig.h b/llvm/include/llvm/Object/ObjCopy/wasm/WasmConfig.h rename from llvm/tools/llvm-objcopy/wasm/WasmConfig.h rename to llvm/include/llvm/Object/ObjCopy/wasm/WasmConfig.h --- a/llvm/tools/llvm-objcopy/wasm/WasmConfig.h +++ b/llvm/include/llvm/Object/ObjCopy/wasm/WasmConfig.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_TOOLS_LLVM_OBJCOPY_WASM_WASMCONFIG_H -#define LLVM_TOOLS_LLVM_OBJCOPY_WASM_WASMCONFIG_H +#ifndef LLVM_OBJECT_OBJCOPY_WASM_WASMCONFIG_H +#define LLVM_OBJECT_OBJCOPY_WASM_WASMCONFIG_H namespace llvm { namespace objcopy { @@ -18,4 +18,4 @@ } // namespace objcopy } // namespace llvm -#endif // LLVM_TOOLS_LLVM_OBJCOPY_WASM_WASMCONFIG_H +#endif // LLVM_OBJECT_OBJCOPY_WASM_WASMCONFIG_H diff --git a/llvm/tools/llvm-objcopy/wasm/WasmObjcopy.h b/llvm/include/llvm/Object/ObjCopy/wasm/WasmObjcopy.h rename from llvm/tools/llvm-objcopy/wasm/WasmObjcopy.h rename to llvm/include/llvm/Object/ObjCopy/wasm/WasmObjcopy.h --- a/llvm/tools/llvm-objcopy/wasm/WasmObjcopy.h +++ b/llvm/include/llvm/Object/ObjCopy/wasm/WasmObjcopy.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_TOOLS_LLVM_OBJCOPY_WASM_WASMOBJCOPY_H -#define LLVM_TOOLS_LLVM_OBJCOPY_WASM_WASMOBJCOPY_H +#ifndef LLVM_OBJECT_OBJCOPY_WASM_WASMOBJCOPY_H +#define LLVM_OBJECT_OBJCOPY_WASM_WASMOBJCOPY_H namespace llvm { class Error; @@ -22,6 +22,9 @@ struct WasmConfig; namespace wasm { +/// Applies the transformations described by \p Config to +/// \p In(FileFormat::Unspecified) and writes the result into \p Out. +/// \returns any Error encountered whilst performing the operation. Error executeObjcopyOnBinary(const CommonConfig &Config, const WasmConfig &, object::WasmObjectFile &In, raw_ostream &Out); @@ -29,4 +32,4 @@ } // end namespace objcopy } // end namespace llvm -#endif // LLVM_TOOLS_LLVM_OBJCOPY_WASM_WASMOBJCOPY_H +#endif // LLVM_OBJECT_OBJCOPY_WASM_WASMOBJCOPY_H diff --git a/llvm/lib/Object/CMakeLists.txt b/llvm/lib/Object/CMakeLists.txt --- a/llvm/lib/Object/CMakeLists.txt +++ b/llvm/lib/Object/CMakeLists.txt @@ -29,6 +29,22 @@ WindowsMachineFlag.cpp WindowsResource.cpp XCOFFObjectFile.cpp + ObjCopy/ObjCopy.cpp + ObjCopy/COFF/COFFObjcopy.cpp + ObjCopy/COFF/Object.cpp + ObjCopy/COFF/Reader.cpp + ObjCopy/COFF/Writer.cpp + ObjCopy/ELF/ELFObjcopy.cpp + ObjCopy/ELF/Object.cpp + ObjCopy/MachO/MachOObjcopy.cpp + ObjCopy/MachO/MachOReader.cpp + ObjCopy/MachO/MachOWriter.cpp + ObjCopy/MachO/MachOLayoutBuilder.cpp + ObjCopy/MachO/Object.cpp + ObjCopy/wasm/Object.cpp + ObjCopy/wasm/Reader.cpp + ObjCopy/wasm/Writer.cpp + ObjCopy/wasm/WasmObjcopy.cpp ADDITIONAL_HEADER_DIRS ${LLVM_MAIN_INCLUDE_DIR}/llvm/Object diff --git a/llvm/tools/llvm-objcopy/COFF/COFFObjcopy.cpp b/llvm/lib/Object/ObjCopy/COFF/COFFObjcopy.cpp rename from llvm/tools/llvm-objcopy/COFF/COFFObjcopy.cpp rename to llvm/lib/Object/ObjCopy/COFF/COFFObjcopy.cpp --- a/llvm/tools/llvm-objcopy/COFF/COFFObjcopy.cpp +++ b/llvm/lib/Object/ObjCopy/COFF/COFFObjcopy.cpp @@ -6,12 +6,12 @@ // //===----------------------------------------------------------------------===// -#include "COFFObjcopy.h" -#include "COFFConfig.h" -#include "CommonConfig.h" +#include "llvm/Object/ObjCopy/COFF/COFFObjcopy.h" #include "Object.h" #include "Reader.h" #include "Writer.h" +#include "llvm/Object/ObjCopy/COFF/COFFConfig.h" +#include "llvm/Object/ObjCopy/CommonConfig.h" #include "llvm/Object/Binary.h" #include "llvm/Object/COFF.h" diff --git a/llvm/tools/llvm-objcopy/COFF/Object.h b/llvm/lib/Object/ObjCopy/COFF/Object.h rename from llvm/tools/llvm-objcopy/COFF/Object.h rename to llvm/lib/Object/ObjCopy/COFF/Object.h --- a/llvm/tools/llvm-objcopy/COFF/Object.h +++ b/llvm/lib/Object/ObjCopy/COFF/Object.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_TOOLS_OBJCOPY_COFF_OBJECT_H -#define LLVM_TOOLS_OBJCOPY_COFF_OBJECT_H +#ifndef LLVM_LIB_OBJECT_OBJCOPY_COFF_OBJECT_H +#define LLVM_LIB_OBJECT_OBJCOPY_COFF_OBJECT_H #include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/DenseMap.h" @@ -208,4 +208,4 @@ } // end namespace objcopy } // end namespace llvm -#endif // LLVM_TOOLS_OBJCOPY_COFF_OBJECT_H +#endif // LLVM_LIB_OBJECT_OBJCOPY_COFF_OBJECT_H diff --git a/llvm/tools/llvm-objcopy/COFF/Object.cpp b/llvm/lib/Object/ObjCopy/COFF/Object.cpp rename from llvm/tools/llvm-objcopy/COFF/Object.cpp rename to llvm/lib/Object/ObjCopy/COFF/Object.cpp diff --git a/llvm/tools/llvm-objcopy/COFF/Reader.h b/llvm/lib/Object/ObjCopy/COFF/Reader.h rename from llvm/tools/llvm-objcopy/COFF/Reader.h rename to llvm/lib/Object/ObjCopy/COFF/Reader.h --- a/llvm/tools/llvm-objcopy/COFF/Reader.h +++ b/llvm/lib/Object/ObjCopy/COFF/Reader.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_TOOLS_OBJCOPY_COFF_READER_H -#define LLVM_TOOLS_OBJCOPY_COFF_READER_H +#ifndef LLVM_LIB_OBJECT_OBJCOPY_COFF_READER_H +#define LLVM_LIB_OBJECT_OBJCOPY_COFF_READER_H #include "llvm/BinaryFormat/COFF.h" #include "llvm/Object/COFF.h" @@ -38,4 +38,4 @@ } // end namespace objcopy } // end namespace llvm -#endif // LLVM_TOOLS_OBJCOPY_COFF_READER_H +#endif // LLVM_LIB_OBJECT_OBJCOPY_COFF_READER_H diff --git a/llvm/tools/llvm-objcopy/COFF/Reader.cpp b/llvm/lib/Object/ObjCopy/COFF/Reader.cpp rename from llvm/tools/llvm-objcopy/COFF/Reader.cpp rename to llvm/lib/Object/ObjCopy/COFF/Reader.cpp diff --git a/llvm/tools/llvm-objcopy/COFF/Writer.h b/llvm/lib/Object/ObjCopy/COFF/Writer.h rename from llvm/tools/llvm-objcopy/COFF/Writer.h rename to llvm/lib/Object/ObjCopy/COFF/Writer.h --- a/llvm/tools/llvm-objcopy/COFF/Writer.h +++ b/llvm/lib/Object/ObjCopy/COFF/Writer.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_TOOLS_OBJCOPY_COFF_WRITER_H -#define LLVM_TOOLS_OBJCOPY_COFF_WRITER_H +#ifndef LLVM_LIB_OBJECT_OBJCOPY_COFF_WRITER_H +#define LLVM_LIB_OBJECT_OBJCOPY_COFF_WRITER_H #include "llvm/MC/StringTableBuilder.h" #include "llvm/Support/Error.h" @@ -60,4 +60,4 @@ } // end namespace objcopy } // end namespace llvm -#endif // LLVM_TOOLS_OBJCOPY_COFF_WRITER_H +#endif // LLVM_LIB_OBJECT_OBJCOPY_COFF_WRITER_H diff --git a/llvm/tools/llvm-objcopy/COFF/Writer.cpp b/llvm/lib/Object/ObjCopy/COFF/Writer.cpp rename from llvm/tools/llvm-objcopy/COFF/Writer.cpp rename to llvm/lib/Object/ObjCopy/COFF/Writer.cpp diff --git a/llvm/tools/llvm-objcopy/ELF/ELFObjcopy.cpp b/llvm/lib/Object/ObjCopy/ELF/ELFObjcopy.cpp rename from llvm/tools/llvm-objcopy/ELF/ELFObjcopy.cpp rename to llvm/lib/Object/ObjCopy/ELF/ELFObjcopy.cpp --- a/llvm/tools/llvm-objcopy/ELF/ELFObjcopy.cpp +++ b/llvm/lib/Object/ObjCopy/ELF/ELFObjcopy.cpp @@ -6,11 +6,8 @@ // //===----------------------------------------------------------------------===// -#include "ELFObjcopy.h" -#include "CommonConfig.h" -#include "ELFConfig.h" +#include "llvm/Object/ObjCopy/ELF/ELFObjcopy.h" #include "Object.h" -#include "llvm-objcopy.h" #include "llvm/ADT/BitmaskEnum.h" #include "llvm/ADT/DenseSet.h" #include "llvm/ADT/Optional.h" @@ -24,6 +21,8 @@ #include "llvm/Object/ELFObjectFile.h" #include "llvm/Object/ELFTypes.h" #include "llvm/Object/Error.h" +#include "llvm/Object/ObjCopy/CommonConfig.h" +#include "llvm/Object/ObjCopy/ELF/ELFConfig.h" #include "llvm/Option/Option.h" #include "llvm/Support/Casting.h" #include "llvm/Support/Compression.h" diff --git a/llvm/tools/llvm-objcopy/ELF/Object.h b/llvm/lib/Object/ObjCopy/ELF/Object.h rename from llvm/tools/llvm-objcopy/ELF/Object.h rename to llvm/lib/Object/ObjCopy/ELF/Object.h --- a/llvm/tools/llvm-objcopy/ELF/Object.h +++ b/llvm/lib/Object/ObjCopy/ELF/Object.h @@ -6,16 +6,16 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_TOOLS_OBJCOPY_OBJECT_H -#define LLVM_TOOLS_OBJCOPY_OBJECT_H +#ifndef LLVM_LIB_OBJECT_OBJCOPY_ELF_OBJECT_H +#define LLVM_LIB_OBJECT_OBJCOPY_ELF_OBJECT_H -#include "CommonConfig.h" #include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/StringRef.h" #include "llvm/ADT/Twine.h" #include "llvm/BinaryFormat/ELF.h" #include "llvm/MC/StringTableBuilder.h" #include "llvm/Object/ELFObjectFile.h" +#include "llvm/Object/ObjCopy/CommonConfig.h" #include "llvm/Support/Errc.h" #include "llvm/Support/FileOutputBuffer.h" #include "llvm/Support/MemoryBuffer.h" @@ -1093,4 +1093,4 @@ } // end namespace objcopy } // end namespace llvm -#endif // LLVM_TOOLS_OBJCOPY_OBJECT_H +#endif // LLVM_LIB_OBJECT_OBJCOPY_ELF_OBJECT_H diff --git a/llvm/tools/llvm-objcopy/ELF/Object.cpp b/llvm/lib/Object/ObjCopy/ELF/Object.cpp rename from llvm/tools/llvm-objcopy/ELF/Object.cpp rename to llvm/lib/Object/ObjCopy/ELF/Object.cpp --- a/llvm/tools/llvm-objcopy/ELF/Object.cpp +++ b/llvm/lib/Object/ObjCopy/ELF/Object.cpp @@ -1792,9 +1792,9 @@ Sec->EntrySize = Shdr.sh_entsize; Sec->Index = Index++; Sec->OriginalIndex = Sec->Index; - Sec->OriginalData = - ArrayRef(ElfFile.base() + Shdr.sh_offset, - (Shdr.sh_type == SHT_NOBITS) ? (size_t)0 : Shdr.sh_size); + Sec->OriginalData = ArrayRef( + ElfFile.base() + Shdr.sh_offset, + (Shdr.sh_type == SHT_NOBITS) ? (size_t)0 : Shdr.sh_size); } return Error::success(); diff --git a/llvm/tools/llvm-objcopy/MachO/MachOLayoutBuilder.h b/llvm/lib/Object/ObjCopy/MachO/MachOLayoutBuilder.h rename from llvm/tools/llvm-objcopy/MachO/MachOLayoutBuilder.h rename to llvm/lib/Object/ObjCopy/MachO/MachOLayoutBuilder.h --- a/llvm/tools/llvm-objcopy/MachO/MachOLayoutBuilder.h +++ b/llvm/lib/Object/ObjCopy/MachO/MachOLayoutBuilder.h @@ -6,11 +6,11 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_OBJCOPY_MACHO_MACHOLAYOUTBUILDER_H -#define LLVM_OBJCOPY_MACHO_MACHOLAYOUTBUILDER_H +#ifndef LLVM_LIB_OBJECT_OBJCOPY_MACHO_MACHOLAYOUTBUILDER_H +#define LLVM_LIB_OBJECT_OBJCOPY_MACHO_MACHOLAYOUTBUILDER_H -#include "MachOObjcopy.h" #include "Object.h" +#include "llvm/Object/ObjCopy/MachO/MachOObjcopy.h" namespace llvm { namespace objcopy { @@ -51,4 +51,4 @@ } // end namespace objcopy } // end namespace llvm -#endif // LLVM_OBJCOPY_MACHO_MACHOLAYOUTBUILDER_H +#endif // LLVM_LIB_OBJECT_OBJCOPY_MACHO_MACHOLAYOUTBUILDER_H diff --git a/llvm/tools/llvm-objcopy/MachO/MachOLayoutBuilder.cpp b/llvm/lib/Object/ObjCopy/MachO/MachOLayoutBuilder.cpp rename from llvm/tools/llvm-objcopy/MachO/MachOLayoutBuilder.cpp rename to llvm/lib/Object/ObjCopy/MachO/MachOLayoutBuilder.cpp diff --git a/llvm/tools/llvm-objcopy/MachO/MachOObjcopy.cpp b/llvm/lib/Object/ObjCopy/MachO/MachOObjcopy.cpp rename from llvm/tools/llvm-objcopy/MachO/MachOObjcopy.cpp rename to llvm/lib/Object/ObjCopy/MachO/MachOObjcopy.cpp --- a/llvm/tools/llvm-objcopy/MachO/MachOObjcopy.cpp +++ b/llvm/lib/Object/ObjCopy/MachO/MachOObjcopy.cpp @@ -6,17 +6,17 @@ // //===----------------------------------------------------------------------===// -#include "MachOObjcopy.h" -#include "../llvm-objcopy.h" -#include "CommonConfig.h" -#include "MachO/MachOConfig.h" +#include "llvm/Object/ObjCopy/MachO/MachOObjcopy.h" #include "MachOReader.h" #include "MachOWriter.h" -#include "MultiFormatConfig.h" #include "llvm/ADT/DenseSet.h" #include "llvm/Object/ArchiveWriter.h" #include "llvm/Object/MachOUniversal.h" #include "llvm/Object/MachOUniversalWriter.h" +#include "llvm/Object/ObjCopy/CommonConfig.h" +#include "llvm/Object/ObjCopy/MachO/MachOConfig.h" +#include "llvm/Object/ObjCopy/MultiFormatConfig.h" +#include "llvm/Object/ObjCopy/ObjCopy.h" #include "llvm/Support/Errc.h" #include "llvm/Support/Error.h" #include "llvm/Support/FileOutputBuffer.h" diff --git a/llvm/tools/llvm-objcopy/MachO/MachOReader.h b/llvm/lib/Object/ObjCopy/MachO/MachOReader.h rename from llvm/tools/llvm-objcopy/MachO/MachOReader.h rename to llvm/lib/Object/ObjCopy/MachO/MachOReader.h --- a/llvm/tools/llvm-objcopy/MachO/MachOReader.h +++ b/llvm/lib/Object/ObjCopy/MachO/MachOReader.h @@ -6,10 +6,13 @@ // //===----------------------------------------------------------------------===// -#include "MachOObjcopy.h" +#ifndef LLVM_LIB_OBJECT_OBJCOPY_MACHO_MACHOREADER_H +#define LLVM_LIB_OBJECT_OBJCOPY_MACHO_MACHOREADER_H + #include "Object.h" #include "llvm/BinaryFormat/MachO.h" #include "llvm/Object/MachO.h" +#include "llvm/Object/ObjCopy/MachO/MachOObjcopy.h" #include namespace llvm { @@ -53,3 +56,5 @@ } // end namespace macho } // end namespace objcopy } // end namespace llvm + +#endif // LLVM_LIB_OBJECT_OBJCOPY_MACHO_MACHOREADER_H diff --git a/llvm/tools/llvm-objcopy/MachO/MachOReader.cpp b/llvm/lib/Object/ObjCopy/MachO/MachOReader.cpp rename from llvm/tools/llvm-objcopy/MachO/MachOReader.cpp rename to llvm/lib/Object/ObjCopy/MachO/MachOReader.cpp diff --git a/llvm/tools/llvm-objcopy/MachO/MachOWriter.h b/llvm/lib/Object/ObjCopy/MachO/MachOWriter.h rename from llvm/tools/llvm-objcopy/MachO/MachOWriter.h rename to llvm/lib/Object/ObjCopy/MachO/MachOWriter.h --- a/llvm/tools/llvm-objcopy/MachO/MachOWriter.h +++ b/llvm/lib/Object/ObjCopy/MachO/MachOWriter.h @@ -6,11 +6,14 @@ // //===----------------------------------------------------------------------===// +#ifndef LLVM_LIB_OBJECT_OBJCOPY_MACHO_MACHOWRITER_H +#define LLVM_LIB_OBJECT_OBJCOPY_MACHO_MACHOWRITER_H + #include "MachOLayoutBuilder.h" -#include "MachOObjcopy.h" #include "Object.h" #include "llvm/BinaryFormat/MachO.h" #include "llvm/Object/MachO.h" +#include "llvm/Object/ObjCopy/MachO/MachOObjcopy.h" namespace llvm { class Error; @@ -66,3 +69,5 @@ } // end namespace macho } // end namespace objcopy } // end namespace llvm + +#endif // LLVM_LIB_OBJECT_OBJCOPY_MACHO_MACHOWRITER_H diff --git a/llvm/tools/llvm-objcopy/MachO/MachOWriter.cpp b/llvm/lib/Object/ObjCopy/MachO/MachOWriter.cpp rename from llvm/tools/llvm-objcopy/MachO/MachOWriter.cpp rename to llvm/lib/Object/ObjCopy/MachO/MachOWriter.cpp diff --git a/llvm/tools/llvm-objcopy/MachO/Object.h b/llvm/lib/Object/ObjCopy/MachO/Object.h rename from llvm/tools/llvm-objcopy/MachO/Object.h rename to llvm/lib/Object/ObjCopy/MachO/Object.h --- a/llvm/tools/llvm-objcopy/MachO/Object.h +++ b/llvm/lib/Object/ObjCopy/MachO/Object.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_OBJCOPY_MACHO_OBJECT_H -#define LLVM_OBJCOPY_MACHO_OBJECT_H +#ifndef LLVM_LIB_OBJECT_OBJCOPY_MACHO_OBJECT_H +#define LLVM_LIB_OBJECT_OBJCOPY_MACHO_OBJECT_H #include "llvm/ADT/Optional.h" #include "llvm/ADT/StringRef.h" @@ -363,4 +363,4 @@ } // end namespace objcopy } // end namespace llvm -#endif // LLVM_OBJCOPY_MACHO_OBJECT_H +#endif // LLVM_LIB_OBJECT_OBJCOPY_MACHO_OBJECT_H diff --git a/llvm/tools/llvm-objcopy/MachO/Object.cpp b/llvm/lib/Object/ObjCopy/MachO/Object.cpp rename from llvm/tools/llvm-objcopy/MachO/Object.cpp rename to llvm/lib/Object/ObjCopy/MachO/Object.cpp diff --git a/llvm/lib/Object/ObjCopy/ObjCopy.cpp b/llvm/lib/Object/ObjCopy/ObjCopy.cpp new file mode 100644 --- /dev/null +++ b/llvm/lib/Object/ObjCopy/ObjCopy.cpp @@ -0,0 +1,157 @@ +//===- Objcopy.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 "llvm/Object/ObjCopy/ObjCopy.h" +#include "llvm/BinaryFormat/ELF.h" +#include "llvm/Object/COFF.h" +#include "llvm/Object/ELFObjectFile.h" +#include "llvm/Object/ELFTypes.h" +#include "llvm/Object/Error.h" +#include "llvm/Object/MachO.h" +#include "llvm/Object/MachOUniversal.h" +#include "llvm/Object/ObjCopy/COFF/COFFConfig.h" +#include "llvm/Object/ObjCopy/COFF/COFFObjcopy.h" +#include "llvm/Object/ObjCopy/ELF/ELFConfig.h" +#include "llvm/Object/ObjCopy/ELF/ELFObjcopy.h" +#include "llvm/Object/ObjCopy/MachO/MachOConfig.h" +#include "llvm/Object/ObjCopy/MachO/MachOObjcopy.h" +#include "llvm/Object/ObjCopy/wasm/WasmConfig.h" +#include "llvm/Object/ObjCopy/wasm/WasmObjcopy.h" +#include "llvm/Object/Wasm.h" +#include "llvm/Support/SmallVectorMemoryBuffer.h" + +namespace llvm { +namespace objcopy { + +using namespace llvm::object; + +Expected> +createNewArchiveMembers(const MultiFormatConfig &Config, const Archive &Ar) { + std::vector NewArchiveMembers; + Error Err = Error::success(); + for (const Archive::Child &Child : Ar.children(Err)) { + Expected ChildNameOrErr = Child.getName(); + if (!ChildNameOrErr) + return createFileError(Ar.getFileName(), ChildNameOrErr.takeError()); + + Expected> ChildOrErr = Child.getAsBinary(); + if (!ChildOrErr) + return createFileError(Ar.getFileName() + "(" + *ChildNameOrErr + ")", + ChildOrErr.takeError()); + + SmallVector Buffer; + raw_svector_ostream MemStream(Buffer); + + if (Error E = executeObjcopyOnBinary(Config, *ChildOrErr->get(), MemStream)) + return std::move(E); + + Expected Member = NewArchiveMember::getOldMember( + Child, Config.getCommonConfig().DeterministicArchives); + if (!Member) + return createFileError(Ar.getFileName(), Member.takeError()); + + Member->Buf = std::make_unique( + std::move(Buffer), ChildNameOrErr.get()); + Member->MemberName = Member->Buf->getBufferIdentifier(); + NewArchiveMembers.push_back(std::move(*Member)); + } + if (Err) + return createFileError(Config.getCommonConfig().InputFilename, + std::move(Err)); + return std::move(NewArchiveMembers); +} + +// For regular archives this function simply calls llvm::writeArchive, +// For thin archives it writes the archive file itself as well as its members. +static Error deepWriteArchive(StringRef ArcName, + ArrayRef NewMembers, + bool WriteSymtab, object::Archive::Kind Kind, + bool Deterministic, bool Thin) { + if (Error E = writeArchive(ArcName, NewMembers, WriteSymtab, Kind, + Deterministic, Thin)) + return createFileError(ArcName, std::move(E)); + + if (!Thin) + return Error::success(); + + for (const NewArchiveMember &Member : NewMembers) { + // For regular files (as is the case for deepWriteArchive), + // FileOutputBuffer::create will return OnDiskBuffer. + // OnDiskBuffer uses a temporary file and then renames it. So in reality + // there is no inefficiency / duplicated in-memory buffers in this case. For + // now in-memory buffers can not be completely avoided since + // NewArchiveMember still requires them even though writeArchive does not + // write them on disk. + Expected> FB = + FileOutputBuffer::create(Member.MemberName, Member.Buf->getBufferSize(), + FileOutputBuffer::F_executable); + if (!FB) + return FB.takeError(); + std::copy(Member.Buf->getBufferStart(), Member.Buf->getBufferEnd(), + (*FB)->getBufferStart()); + if (Error E = (*FB)->commit()) + return E; + } + return Error::success(); +} + +Error executeObjcopyOnArchive(const MultiFormatConfig &Config, + const object::Archive &Ar) { + Expected> NewArchiveMembersOrErr = + createNewArchiveMembers(Config, Ar); + if (!NewArchiveMembersOrErr) + return NewArchiveMembersOrErr.takeError(); + const CommonConfig &CommonConfig = Config.getCommonConfig(); + return deepWriteArchive(CommonConfig.OutputFilename, *NewArchiveMembersOrErr, + Ar.hasSymbolTable(), Ar.kind(), + CommonConfig.DeterministicArchives, Ar.isThin()); +} + +/// The function executeObjcopyOnBinary does the dispatch based on the format +/// of the input binary (ELF, MachO or COFF). +Error executeObjcopyOnBinary(const MultiFormatConfig &Config, + object::Binary &In, raw_ostream &Out) { + if (auto *ELFBinary = dyn_cast(&In)) { + Expected ELFConfig = Config.getELFConfig(); + if (!ELFConfig) + return ELFConfig.takeError(); + + return elf::executeObjcopyOnBinary(Config.getCommonConfig(), *ELFConfig, + *ELFBinary, Out); + } else if (auto *COFFBinary = dyn_cast(&In)) { + Expected COFFConfig = Config.getCOFFConfig(); + if (!COFFConfig) + return COFFConfig.takeError(); + + return coff::executeObjcopyOnBinary(Config.getCommonConfig(), *COFFConfig, + *COFFBinary, Out); + } else if (auto *MachOBinary = dyn_cast(&In)) { + Expected MachOConfig = Config.getMachOConfig(); + if (!MachOConfig) + return MachOConfig.takeError(); + + return macho::executeObjcopyOnBinary(Config.getCommonConfig(), *MachOConfig, + *MachOBinary, Out); + } else if (auto *MachOUniversalBinary = + dyn_cast(&In)) { + return macho::executeObjcopyOnMachOUniversalBinary( + Config, *MachOUniversalBinary, Out); + } else if (auto *WasmBinary = dyn_cast(&In)) { + Expected WasmConfig = Config.getWasmConfig(); + if (!WasmConfig) + return WasmConfig.takeError(); + + return objcopy::wasm::executeObjcopyOnBinary(Config.getCommonConfig(), + *WasmConfig, *WasmBinary, Out); + } else + return createStringError(object_error::invalid_file_type, + "unsupported object file format"); +} + +} // end namespace objcopy +} // end namespace llvm diff --git a/llvm/tools/llvm-objcopy/wasm/Object.h b/llvm/lib/Object/ObjCopy/wasm/Object.h rename from llvm/tools/llvm-objcopy/wasm/Object.h rename to llvm/lib/Object/ObjCopy/wasm/Object.h --- a/llvm/tools/llvm-objcopy/wasm/Object.h +++ b/llvm/lib/Object/ObjCopy/wasm/Object.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_TOOLS_LLVM_OBJCOPY_WASM_OBJECT_H -#define LLVM_TOOLS_LLVM_OBJCOPY_WASM_OBJECT_H +#ifndef LLVM_LIB_OBJECT_OBJCOPY_WASM_OBJECT_H +#define LLVM_LIB_OBJECT_OBJCOPY_WASM_OBJECT_H #include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/StringRef.h" @@ -44,4 +44,4 @@ } // end namespace objcopy } // end namespace llvm -#endif // LLVM_TOOLS_LLVM_OBJCOPY_WASM_OBJECT_H +#endif // LLVM_LIB_OBJECT_OBJCOPY_WASM_OBJECT_H diff --git a/llvm/tools/llvm-objcopy/wasm/Object.cpp b/llvm/lib/Object/ObjCopy/wasm/Object.cpp rename from llvm/tools/llvm-objcopy/wasm/Object.cpp rename to llvm/lib/Object/ObjCopy/wasm/Object.cpp diff --git a/llvm/tools/llvm-objcopy/wasm/Reader.h b/llvm/lib/Object/ObjCopy/wasm/Reader.h rename from llvm/tools/llvm-objcopy/wasm/Reader.h rename to llvm/lib/Object/ObjCopy/wasm/Reader.h --- a/llvm/tools/llvm-objcopy/wasm/Reader.h +++ b/llvm/lib/Object/ObjCopy/wasm/Reader.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_TOOLS_LLVM_OBJCOPY_WASM_READER_H -#define LLVM_TOOLS_LLVM_OBJCOPY_WASM_READER_H +#ifndef LLVM_LIB_OBJECT_OBJCOPY_WASM_READER_H +#define LLVM_LIB_OBJECT_OBJCOPY_WASM_READER_H #include "Object.h" @@ -28,4 +28,4 @@ } // end namespace objcopy } // end namespace llvm -#endif // LLVM_TOOLS_LLVM_OBJCOPY_WASM_READER_H +#endif // LLVM_LIB_OBJECT_OBJCOPY_WASM_READER_H diff --git a/llvm/tools/llvm-objcopy/wasm/Reader.cpp b/llvm/lib/Object/ObjCopy/wasm/Reader.cpp rename from llvm/tools/llvm-objcopy/wasm/Reader.cpp rename to llvm/lib/Object/ObjCopy/wasm/Reader.cpp diff --git a/llvm/tools/llvm-objcopy/wasm/WasmObjcopy.cpp b/llvm/lib/Object/ObjCopy/wasm/WasmObjcopy.cpp rename from llvm/tools/llvm-objcopy/wasm/WasmObjcopy.cpp rename to llvm/lib/Object/ObjCopy/wasm/WasmObjcopy.cpp --- a/llvm/tools/llvm-objcopy/wasm/WasmObjcopy.cpp +++ b/llvm/lib/Object/ObjCopy/wasm/WasmObjcopy.cpp @@ -6,11 +6,11 @@ // //===----------------------------------------------------------------------===// -#include "WasmObjcopy.h" -#include "CommonConfig.h" +#include "llvm/Object/ObjCopy/wasm/WasmObjcopy.h" #include "Object.h" #include "Reader.h" #include "Writer.h" +#include "llvm/Object/ObjCopy/CommonConfig.h" #include "llvm/Support/Errc.h" #include "llvm/Support/FileOutputBuffer.h" diff --git a/llvm/tools/llvm-objcopy/wasm/Writer.h b/llvm/lib/Object/ObjCopy/wasm/Writer.h rename from llvm/tools/llvm-objcopy/wasm/Writer.h rename to llvm/lib/Object/ObjCopy/wasm/Writer.h --- a/llvm/tools/llvm-objcopy/wasm/Writer.h +++ b/llvm/lib/Object/ObjCopy/wasm/Writer.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_TOOLS_LLVM_OBJCOPY_WASM_WRITER_H -#define LLVM_TOOLS_LLVM_OBJCOPY_WASM_WRITER_H +#ifndef LLVM_LIB_OBJECT_OBJCOPY_WASM_WRITER_H +#define LLVM_LIB_OBJECT_OBJCOPY_WASM_WRITER_H #include "Object.h" #include @@ -46,4 +46,4 @@ } // end namespace objcopy } // end namespace llvm -#endif // LLVM_TOOLS_LLVM_OBJCOPY_WASM_WRITER_H +#endif // LLVM_LIB_OBJECT_OBJCOPY_WASM_WRITER_H diff --git a/llvm/tools/llvm-objcopy/wasm/Writer.cpp b/llvm/lib/Object/ObjCopy/wasm/Writer.cpp rename from llvm/tools/llvm-objcopy/wasm/Writer.cpp rename to llvm/lib/Object/ObjCopy/wasm/Writer.cpp 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 @@ -22,23 +22,8 @@ add_public_tablegen_target(StripOptsTableGen) add_llvm_tool(llvm-objcopy - ConfigManager.cpp + ObjcopyOptions.cpp llvm-objcopy.cpp - COFF/COFFObjcopy.cpp - COFF/Object.cpp - COFF/Reader.cpp - COFF/Writer.cpp - ELF/ELFObjcopy.cpp - ELF/Object.cpp - MachO/MachOObjcopy.cpp - MachO/MachOReader.cpp - MachO/MachOWriter.cpp - MachO/MachOLayoutBuilder.cpp - MachO/Object.cpp - wasm/Object.cpp - wasm/Reader.cpp - wasm/Writer.cpp - wasm/WasmObjcopy.cpp DEPENDS ObjcopyOptsTableGen InstallNameToolOptsTableGen diff --git a/llvm/tools/llvm-objcopy/ConfigManager.h b/llvm/tools/llvm-objcopy/ObjcopyOptions.h rename from llvm/tools/llvm-objcopy/ConfigManager.h rename to llvm/tools/llvm-objcopy/ObjcopyOptions.h --- a/llvm/tools/llvm-objcopy/ConfigManager.h +++ b/llvm/tools/llvm-objcopy/ObjcopyOptions.h @@ -1,4 +1,4 @@ -//===- ConfigManager.h ----------------------------------------------------===// +//===- ObjcopyOptions.h ---------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -6,40 +6,16 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_TOOLS_LLVM_OBJCOPY_CONFIGMANAGER_H -#define LLVM_TOOLS_LLVM_OBJCOPY_CONFIGMANAGER_H +#ifndef LLVM_TOOLS_LLVM_OBJCOPY_OBJCOPYOPTIONS_H +#define LLVM_TOOLS_LLVM_OBJCOPY_OBJCOPYOPTIONS_H -#include "COFF/COFFConfig.h" -#include "CommonConfig.h" -#include "ELF/ELFConfig.h" -#include "MachO/MachOConfig.h" -#include "MultiFormatConfig.h" -#include "wasm/WasmConfig.h" +#include "llvm/Object/ObjCopy/ConfigManager.h" #include "llvm/Support/Allocator.h" #include namespace llvm { namespace objcopy { -// ConfigManager keeps all configurations and prepare -// format-specific options. -struct ConfigManager : public MultiFormatConfig { - virtual ~ConfigManager() {} - - const CommonConfig &getCommonConfig() const override { return Common; } - Expected getELFConfig() const override; - Expected getCOFFConfig() const override; - Expected getMachOConfig() const override; - Expected getWasmConfig() const override; - - // All configs. - CommonConfig Common; - ELFConfig ELF; - COFFConfig COFF; - MachOConfig MachO; - WasmConfig Wasm; -}; - // Configuration for the overall invocation of this tool. When invoked as // objcopy, will always contain exactly one CopyConfig. When invoked as strip, // will contain one or more CopyConfigs. @@ -77,4 +53,4 @@ } // namespace objcopy } // namespace llvm -#endif // LLVM_TOOLS_LLVM_OBJCOPY_CONFIGMANAGER_H +#endif // LLVM_TOOLS_LLVM_OBJCOPY_OBJCOPYOPTIONS_H diff --git a/llvm/tools/llvm-objcopy/ConfigManager.cpp b/llvm/tools/llvm-objcopy/ObjcopyOptions.cpp rename from llvm/tools/llvm-objcopy/ConfigManager.cpp rename to llvm/tools/llvm-objcopy/ObjcopyOptions.cpp --- a/llvm/tools/llvm-objcopy/ConfigManager.cpp +++ b/llvm/tools/llvm-objcopy/ObjcopyOptions.cpp @@ -1,4 +1,4 @@ -//===- ConfigManager.cpp --------------------------------------------------===// +//===- ObjcopyOptions.cpp -------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -6,7 +6,7 @@ // //===----------------------------------------------------------------------===// -#include "ConfigManager.h" +#include "ObjcopyOptions.h" #include "llvm/ADT/Optional.h" #include "llvm/ADT/SmallVector.h" #include "llvm/ADT/StringRef.h" @@ -558,68 +558,6 @@ return SI; } -Expected ConfigManager::getELFConfig() const { - return ELF; -} - -Expected ConfigManager::getCOFFConfig() const { - if (!Common.SplitDWO.empty() || !Common.SymbolsPrefix.empty() || - !Common.AllocSectionsPrefix.empty() || !Common.DumpSection.empty() || - !Common.KeepSection.empty() || !Common.SymbolsToGlobalize.empty() || - !Common.SymbolsToKeep.empty() || !Common.SymbolsToLocalize.empty() || - !Common.SymbolsToWeaken.empty() || !Common.SymbolsToKeepGlobal.empty() || - !Common.SectionsToRename.empty() || !Common.SetSectionAlignment.empty() || - Common.ExtractDWO || Common.PreserveDates || Common.StripDWO || - Common.StripNonAlloc || Common.StripSections || Common.Weaken || - Common.DecompressDebugSections || - Common.DiscardMode == DiscardType::Locals || - !Common.SymbolsToAdd.empty()) { - return createStringError(llvm::errc::invalid_argument, - "option not supported by llvm-objcopy for COFF"); - } - - return COFF; -} - -Expected ConfigManager::getMachOConfig() const { - if (!Common.SplitDWO.empty() || !Common.SymbolsPrefix.empty() || - !Common.AllocSectionsPrefix.empty() || !Common.KeepSection.empty() || - !Common.SymbolsToGlobalize.empty() || !Common.SymbolsToKeep.empty() || - !Common.SymbolsToLocalize.empty() || !Common.SymbolsToWeaken.empty() || - !Common.SymbolsToKeepGlobal.empty() || !Common.SectionsToRename.empty() || - !Common.UnneededSymbolsToRemove.empty() || - !Common.SetSectionAlignment.empty() || !Common.SetSectionFlags.empty() || - Common.ExtractDWO || Common.PreserveDates || Common.StripAllGNU || - Common.StripDWO || Common.StripNonAlloc || Common.StripSections || - Common.Weaken || Common.DecompressDebugSections || Common.StripUnneeded || - Common.DiscardMode == DiscardType::Locals || - !Common.SymbolsToAdd.empty()) { - return createStringError(llvm::errc::invalid_argument, - "option not supported by llvm-objcopy for MachO"); - } - - return MachO; -} - -Expected ConfigManager::getWasmConfig() const { - if (!Common.AddGnuDebugLink.empty() || Common.ExtractPartition || - !Common.SplitDWO.empty() || !Common.SymbolsPrefix.empty() || - !Common.AllocSectionsPrefix.empty() || - Common.DiscardMode != DiscardType::None || !Common.SymbolsToAdd.empty() || - !Common.SymbolsToGlobalize.empty() || !Common.SymbolsToLocalize.empty() || - !Common.SymbolsToKeep.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()) { - return createStringError( - llvm::errc::invalid_argument, - "only flags for section dumping, removal, and addition are supported"); - } - - return Wasm; -} - // 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/llvm-objcopy.h b/llvm/tools/llvm-objcopy/llvm-objcopy.h deleted file mode 100644 --- a/llvm/tools/llvm-objcopy/llvm-objcopy.h +++ /dev/null @@ -1,34 +0,0 @@ -//===- llvm-objcopy.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_OBJCOPY_H -#define LLVM_TOOLS_OBJCOPY_OBJCOPY_H - -#include "llvm/Support/Error.h" -#include "llvm/Support/raw_ostream.h" - -namespace llvm { - -struct NewArchiveMember; - -namespace object { - -class Archive; - -} // end namespace object - -namespace objcopy { -class MultiFormatConfig; -Expected> -createNewArchiveMembers(const MultiFormatConfig &Config, - const object::Archive &Ar); - -} // end namespace objcopy -} // end namespace llvm - -#endif // LLVM_TOOLS_OBJCOPY_OBJCOPY_H 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 @@ -6,17 +6,17 @@ // //===----------------------------------------------------------------------===// -#include "llvm-objcopy.h" -#include "COFF/COFFConfig.h" -#include "COFF/COFFObjcopy.h" -#include "CommonConfig.h" -#include "ConfigManager.h" -#include "ELF/ELFConfig.h" -#include "ELF/ELFObjcopy.h" -#include "MachO/MachOConfig.h" -#include "MachO/MachOObjcopy.h" -#include "wasm/WasmConfig.h" -#include "wasm/WasmObjcopy.h" +#include "ObjcopyOptions.h" +#include "llvm/Object/ObjCopy/COFF/COFFConfig.h" +#include "llvm/Object/ObjCopy/COFF/COFFObjcopy.h" +#include "llvm/Object/ObjCopy/CommonConfig.h" +#include "llvm/Object/ObjCopy/ELF/ELFConfig.h" +#include "llvm/Object/ObjCopy/ELF/ELFObjcopy.h" +#include "llvm/Object/ObjCopy/MachO/MachOConfig.h" +#include "llvm/Object/ObjCopy/MachO/MachOObjcopy.h" +#include "llvm/Object/ObjCopy/ObjCopy.h" +#include "llvm/Object/ObjCopy/wasm/WasmConfig.h" +#include "llvm/Object/ObjCopy/wasm/WasmObjcopy.h" #include "llvm/ADT/STLExtras.h" #include "llvm/ADT/SmallVector.h" @@ -96,40 +96,6 @@ return parseObjcopyOptions(Args, reportWarning); } -// For regular archives this function simply calls llvm::writeArchive, -// For thin archives it writes the archive file itself as well as its members. -static Error deepWriteArchive(StringRef ArcName, - ArrayRef NewMembers, - bool WriteSymtab, object::Archive::Kind Kind, - bool Deterministic, bool Thin) { - if (Error E = writeArchive(ArcName, NewMembers, WriteSymtab, Kind, - Deterministic, Thin)) - return createFileError(ArcName, std::move(E)); - - if (!Thin) - return Error::success(); - - for (const NewArchiveMember &Member : NewMembers) { - // For regular files (as is the case for deepWriteArchive), - // FileOutputBuffer::create will return OnDiskBuffer. - // OnDiskBuffer uses a temporary file and then renames it. So in reality - // there is no inefficiency / duplicated in-memory buffers in this case. For - // now in-memory buffers can not be completely avoided since - // NewArchiveMember still requires them even though writeArchive does not - // write them on disk. - Expected> FB = - FileOutputBuffer::create(Member.MemberName, Member.Buf->getBufferSize(), - FileOutputBuffer::F_executable); - if (!FB) - return FB.takeError(); - std::copy(Member.Buf->getBufferStart(), Member.Buf->getBufferEnd(), - (*FB)->getBufferStart()); - if (Error E = (*FB)->commit()) - return E; - } - return Error::success(); -} - /// The function executeObjcopyOnIHex does the dispatch based on the format /// of the output specified by the command line options. static Error executeObjcopyOnIHex(ConfigManager &ConfigMgr, MemoryBuffer &In, @@ -166,101 +132,6 @@ llvm_unreachable("unsupported output format"); } -/// The function executeObjcopyOnBinary does the dispatch based on the format -/// of the input binary (ELF, MachO or COFF). -static Error executeObjcopyOnBinary(const MultiFormatConfig &Config, - object::Binary &In, raw_ostream &Out) { - if (auto *ELFBinary = dyn_cast(&In)) { - Expected ELFConfig = Config.getELFConfig(); - if (!ELFConfig) - return ELFConfig.takeError(); - - return elf::executeObjcopyOnBinary(Config.getCommonConfig(), *ELFConfig, - *ELFBinary, Out); - } else if (auto *COFFBinary = dyn_cast(&In)) { - Expected COFFConfig = Config.getCOFFConfig(); - if (!COFFConfig) - return COFFConfig.takeError(); - - return coff::executeObjcopyOnBinary(Config.getCommonConfig(), *COFFConfig, - *COFFBinary, Out); - } else if (auto *MachOBinary = dyn_cast(&In)) { - Expected MachOConfig = Config.getMachOConfig(); - if (!MachOConfig) - return MachOConfig.takeError(); - - return macho::executeObjcopyOnBinary(Config.getCommonConfig(), *MachOConfig, - *MachOBinary, Out); - } else if (auto *MachOUniversalBinary = - dyn_cast(&In)) { - return macho::executeObjcopyOnMachOUniversalBinary( - Config, *MachOUniversalBinary, Out); - } else if (auto *WasmBinary = dyn_cast(&In)) { - Expected WasmConfig = Config.getWasmConfig(); - if (!WasmConfig) - return WasmConfig.takeError(); - - return objcopy::wasm::executeObjcopyOnBinary(Config.getCommonConfig(), - *WasmConfig, *WasmBinary, Out); - } else - return createStringError(object_error::invalid_file_type, - "unsupported object file format"); -} - -namespace llvm { -namespace objcopy { - -Expected> -createNewArchiveMembers(const MultiFormatConfig &Config, const Archive &Ar) { - std::vector NewArchiveMembers; - Error Err = Error::success(); - for (const Archive::Child &Child : Ar.children(Err)) { - Expected ChildNameOrErr = Child.getName(); - if (!ChildNameOrErr) - return createFileError(Ar.getFileName(), ChildNameOrErr.takeError()); - - Expected> ChildOrErr = Child.getAsBinary(); - if (!ChildOrErr) - return createFileError(Ar.getFileName() + "(" + *ChildNameOrErr + ")", - ChildOrErr.takeError()); - - SmallVector Buffer; - raw_svector_ostream MemStream(Buffer); - - if (Error E = executeObjcopyOnBinary(Config, *ChildOrErr->get(), MemStream)) - return std::move(E); - - Expected Member = NewArchiveMember::getOldMember( - Child, Config.getCommonConfig().DeterministicArchives); - if (!Member) - return createFileError(Ar.getFileName(), Member.takeError()); - - Member->Buf = std::make_unique( - std::move(Buffer), ChildNameOrErr.get()); - Member->MemberName = Member->Buf->getBufferIdentifier(); - NewArchiveMembers.push_back(std::move(*Member)); - } - if (Err) - return createFileError(Config.getCommonConfig().InputFilename, - std::move(Err)); - return std::move(NewArchiveMembers); -} - -} // end namespace objcopy -} // end namespace llvm - -static Error executeObjcopyOnArchive(const ConfigManager &ConfigMgr, - const object::Archive &Ar) { - Expected> NewArchiveMembersOrErr = - createNewArchiveMembers(ConfigMgr, Ar); - if (!NewArchiveMembersOrErr) - return NewArchiveMembersOrErr.takeError(); - const CommonConfig &Config = ConfigMgr.getCommonConfig(); - return deepWriteArchive(Config.OutputFilename, *NewArchiveMembersOrErr, - Ar.hasSymbolTable(), Ar.kind(), - Config.DeterministicArchives, Ar.isThin()); -} - static Error restoreStatOnFile(StringRef Filename, const sys::fs::file_status &Stat, const ConfigManager &ConfigMgr) { diff --git a/llvm/unittests/Object/CMakeLists.txt b/llvm/unittests/Object/CMakeLists.txt --- a/llvm/unittests/Object/CMakeLists.txt +++ b/llvm/unittests/Object/CMakeLists.txt @@ -14,6 +14,7 @@ SymbolSizeTest.cpp SymbolicFileTest.cpp XCOFFObjectFileTest.cpp + ObjCopyTest.cpp ) target_link_libraries(ObjectTests PRIVATE LLVMTestingSupport) diff --git a/llvm/unittests/Object/ObjCopyTest.cpp b/llvm/unittests/Object/ObjCopyTest.cpp new file mode 100644 --- /dev/null +++ b/llvm/unittests/Object/ObjCopyTest.cpp @@ -0,0 +1,125 @@ +//===- ObjCopyTest.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 "llvm/Object/ObjCopy/ObjCopy.h" +#include "llvm/ADT/SmallString.h" +#include "llvm/Object/COFF.h" +#include "llvm/Object/ELFObjectFile.h" +#include "llvm/Object/MachO.h" +#include "llvm/Object/ObjCopy/COFF/COFFObjcopy.h" +#include "llvm/Object/ObjCopy/CommonConfig.h" +#include "llvm/Object/ObjCopy/ConfigManager.h" +#include "llvm/Object/ObjCopy/ELF/ELFConfig.h" +#include "llvm/Object/ObjCopy/ELF/ELFObjcopy.h" +#include "llvm/Object/ObjCopy/MachO/MachOObjcopy.h" +#include "llvm/Object/ObjCopy/wasm/WasmObjcopy.h" +#include "llvm/Object/ObjectFile.h" +#include "llvm/Object/Wasm.h" +#include "llvm/ObjectYAML/yaml2obj.h" +#include "llvm/Support/Error.h" +#include "llvm/Support/FileUtilities.h" +#include "llvm/Support/SmallVectorMemoryBuffer.h" +#include "llvm/Testing/Support/Error.h" +#include "gtest/gtest.h" + +using namespace llvm; +using namespace object; +using namespace objcopy; +using namespace yaml; + +void copySimpleFileImpl(const char *YamlCreationString, + std::function IsValidFormat) { + auto ErrHandler = [&](const Twine &Msg) { FAIL() << "Error: " << Msg; }; + + // Create Object file from yaml description. + SmallString<0> Storage; + std::unique_ptr Obj = + yaml2ObjectFile(Storage, YamlCreationString, ErrHandler); + ASSERT_TRUE(Obj); + ASSERT_TRUE(IsValidFormat(*Obj)); + + // Reserve temporary name for the resulting file. + SmallString<64> Path; + int FD; + ASSERT_FALSE(sys::fs::createTemporaryFile("a", "out", FD, Path)); + FileRemover Cleanup(Path); + + ConfigManager Config; + Config.Common.OutputFilename = Path; + + // Call executeObjcopyOnBinary() + std::error_code EC; + raw_fd_ostream OutStream(Config.Common.OutputFilename, EC); + Error Err = objcopy::executeObjcopyOnBinary(Config, *Obj.get(), OutStream); + OutStream.flush(); + ASSERT_FALSE(std::move(Err)); + + // Load and check copied file. + Expected> Result = + ObjectFile::createObjectFile(Config.Common.OutputFilename); + ASSERT_THAT_EXPECTED(Result, Succeeded()); + ASSERT_TRUE(IsValidFormat(*Result->getBinary())); +} + +TEST(CopySimpleFile, COFF) { + copySimpleFileImpl( + R"( +--- !COFF +header: + Machine: IMAGE_FILE_MACHINE_AMD64 + Characteristics: [ ] +sections: + - Name: .text + Characteristics: [ ] + Alignment: 4 + SectionData: E800000000C3C3C3 +symbols: +... +)", + [](const Binary &File) { return File.isCOFF(); }); +} + +TEST(CopySimpleFile, ELF) { + copySimpleFileImpl( + R"( +--- !ELF +FileHeader: + Class: ELFCLASS64 + Data: ELFDATA2LSB + Type: ET_REL)", + [](const Binary &File) { return File.isELF(); }); +} + +TEST(CopySimpleFile, MachO) { + copySimpleFileImpl( + R"( +--- !mach-o +FileHeader: + magic: 0xFEEDFACF + cputype: 0x01000007 + cpusubtype: 0x80000003 + filetype: 0x00000002 + ncmds: 0 + sizeofcmds: 0 + flags: 0x00218085 + reserved: 0x00000000 +... +)", + [](const Binary &File) { return File.isMachO(); }); +} + +TEST(CopySimpleFile, Wasm) { + copySimpleFileImpl( + R"( +--- !WASM +FileHeader: + Version: 0x00000001 +... +)", + [](const Binary &File) { return File.isWasm(); }); +}