diff --git a/llvm/tools/llvm-objcopy/COFF/COFFConfig.h b/llvm/include/llvm/ObjCopy/COFF/COFFConfig.h rename from llvm/tools/llvm-objcopy/COFF/COFFConfig.h rename to llvm/include/llvm/ObjCopy/COFF/COFFConfig.h --- a/llvm/tools/llvm-objcopy/COFF/COFFConfig.h +++ b/llvm/include/llvm/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_OBJCOPY_COFF_COFFCONFIG_H +#define LLVM_OBJCOPY_COFF_COFFCONFIG_H #include "llvm/ADT/Optional.h" @@ -24,4 +24,4 @@ } // namespace objcopy } // namespace llvm -#endif // LLVM_TOOLS_LLVM_OBJCOPY_COFF_COFFCONFIG_H +#endif // LLVM_OBJCOPY_COFF_COFFCONFIG_H diff --git a/llvm/tools/llvm-objcopy/COFF/COFFObjcopy.h b/llvm/include/llvm/ObjCopy/COFF/COFFObjcopy.h rename from llvm/tools/llvm-objcopy/COFF/COFFObjcopy.h rename to llvm/include/llvm/ObjCopy/COFF/COFFObjcopy.h --- a/llvm/tools/llvm-objcopy/COFF/COFFObjcopy.h +++ b/llvm/include/llvm/ObjCopy/COFF/COFFObjcopy.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_TOOLS_OBJCOPY_COFFOBJCOPY_H -#define LLVM_TOOLS_OBJCOPY_COFFOBJCOPY_H +#ifndef LLVM_OBJCOPY_COFF_COFFOBJCOPY_H +#define LLVM_OBJCOPY_COFF_COFFOBJCOPY_H namespace llvm { class Error; @@ -30,4 +30,4 @@ } // end namespace objcopy } // end namespace llvm -#endif // LLVM_TOOLS_OBJCOPY_COFFOBJCOPY_H +#endif // LLVM_OBJCOPY_COFF_COFFOBJCOPY_H diff --git a/llvm/tools/llvm-objcopy/CommonConfig.h b/llvm/include/llvm/ObjCopy/CommonConfig.h rename from llvm/tools/llvm-objcopy/CommonConfig.h rename to llvm/include/llvm/ObjCopy/CommonConfig.h --- a/llvm/tools/llvm-objcopy/CommonConfig.h +++ b/llvm/include/llvm/ObjCopy/CommonConfig.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_TOOLS_LLVM_OBJCOPY_COMMONCONFIG_H -#define LLVM_TOOLS_LLVM_OBJCOPY_COMMONCONFIG_H +#ifndef LLVM_OBJCOPY_COMMONCONFIG_H +#define LLVM_OBJCOPY_COMMONCONFIG_H #include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/CachedHashString.h" @@ -257,4 +257,4 @@ } // namespace objcopy } // namespace llvm -#endif // LLVM_TOOLS_LLVM_OBJCOPY_COMMONCONFIG_H +#endif // LLVM_OBJCOPY_COMMONCONFIG_H diff --git a/llvm/include/llvm/ObjCopy/ConfigManager.h b/llvm/include/llvm/ObjCopy/ConfigManager.h new file mode 100644 --- /dev/null +++ b/llvm/include/llvm/ObjCopy/ConfigManager.h @@ -0,0 +1,46 @@ +//===- 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_OBJCOPY_CONFIGMANAGER_H +#define LLVM_OBJCOPY_CONFIGMANAGER_H + +#include "llvm/ObjCopy/COFF/COFFConfig.h" +#include "llvm/ObjCopy/CommonConfig.h" +#include "llvm/ObjCopy/ELF/ELFConfig.h" +#include "llvm/ObjCopy/MachO/MachOConfig.h" +#include "llvm/ObjCopy/MultiFormatConfig.h" +#include "llvm/ObjCopy/wasm/WasmConfig.h" + +namespace llvm { +namespace objcopy { + +struct ConfigManager : public MultiFormatConfig { + virtual ~ConfigManager() {} + + const CommonConfig &getCommonConfig() const override { return Common; } + + Expected getELFConfig() const override { return ELF; } + + Expected getCOFFConfig() const override; + + Expected getMachOConfig() const override; + + Expected getWasmConfig() const override; + + // All configs. + CommonConfig Common; + ELFConfig ELF; + COFFConfig COFF; + MachOConfig MachO; + WasmConfig Wasm; +}; + +} // namespace objcopy +} // namespace llvm + +#endif // LLVM_OBJCOPY_CONFIGMANAGER_H diff --git a/llvm/tools/llvm-objcopy/ELF/ELFConfig.h b/llvm/include/llvm/ObjCopy/ELF/ELFConfig.h rename from llvm/tools/llvm-objcopy/ELF/ELFConfig.h rename to llvm/include/llvm/ObjCopy/ELF/ELFConfig.h --- a/llvm/tools/llvm-objcopy/ELF/ELFConfig.h +++ b/llvm/include/llvm/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_OBJCOPY_ELF_ELFCONFIG_H +#define LLVM_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_OBJCOPY_ELF_ELFCONFIG_H diff --git a/llvm/tools/llvm-objcopy/ELF/ELFObjcopy.h b/llvm/include/llvm/ObjCopy/ELF/ELFObjcopy.h rename from llvm/tools/llvm-objcopy/ELF/ELFObjcopy.h rename to llvm/include/llvm/ObjCopy/ELF/ELFObjcopy.h --- a/llvm/tools/llvm-objcopy/ELF/ELFObjcopy.h +++ b/llvm/include/llvm/ObjCopy/ELF/ELFObjcopy.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_TOOLS_OBJCOPY_ELFOBJCOPY_H -#define LLVM_TOOLS_OBJCOPY_ELFOBJCOPY_H +#ifndef LLVM_OBJCOPY_ELF_ELFOBJCOPY_H +#define LLVM_OBJCOPY_ELF_ELFOBJCOPY_H namespace llvm { class Error; @@ -37,4 +37,4 @@ } // end namespace objcopy } // end namespace llvm -#endif // LLVM_TOOLS_OBJCOPY_ELFOBJCOPY_H +#endif // LLVM_OBJCOPY_ELF_ELFOBJCOPY_H diff --git a/llvm/tools/llvm-objcopy/MachO/MachOConfig.h b/llvm/include/llvm/ObjCopy/MachO/MachOConfig.h rename from llvm/tools/llvm-objcopy/MachO/MachOConfig.h rename to llvm/include/llvm/ObjCopy/MachO/MachOConfig.h --- a/llvm/tools/llvm-objcopy/MachO/MachOConfig.h +++ b/llvm/include/llvm/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_OBJCOPY_MACHO_MACHOCONFIG_H +#define LLVM_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_OBJCOPY_MACHO_MACHOCONFIG_H diff --git a/llvm/tools/llvm-objcopy/MachO/MachOObjcopy.h b/llvm/include/llvm/ObjCopy/MachO/MachOObjcopy.h rename from llvm/tools/llvm-objcopy/MachO/MachOObjcopy.h rename to llvm/include/llvm/ObjCopy/MachO/MachOObjcopy.h --- a/llvm/tools/llvm-objcopy/MachO/MachOObjcopy.h +++ b/llvm/include/llvm/ObjCopy/MachO/MachOObjcopy.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_TOOLS_OBJCOPY_MACHOOBJCOPY_H -#define LLVM_TOOLS_OBJCOPY_MACHOOBJCOPY_H +#ifndef LLVM_OBJCOPY_MACHO_MACHOOBJCOPY_H +#define LLVM_OBJCOPY_MACHO_MACHOOBJCOPY_H namespace llvm { class Error; @@ -36,4 +36,4 @@ } // end namespace objcopy } // end namespace llvm -#endif // LLVM_TOOLS_OBJCOPY_MACHOOBJCOPY_H +#endif // LLVM_OBJCOPY_MACHO_MACHOOBJCOPY_H diff --git a/llvm/tools/llvm-objcopy/MultiFormatConfig.h b/llvm/include/llvm/ObjCopy/MultiFormatConfig.h rename from llvm/tools/llvm-objcopy/MultiFormatConfig.h rename to llvm/include/llvm/ObjCopy/MultiFormatConfig.h --- a/llvm/tools/llvm-objcopy/MultiFormatConfig.h +++ b/llvm/include/llvm/ObjCopy/MultiFormatConfig.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_TOOLS_LLVM_OBJCOPY_MULTIFORMATCONFIG_H -#define LLVM_TOOLS_LLVM_OBJCOPY_MULTIFORMATCONFIG_H +#ifndef LLVM_OBJCOPY_MULTIFORMATCONFIG_H +#define LLVM_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_OBJCOPY_MULTIFORMATCONFIG_H diff --git a/llvm/include/llvm/ObjCopy/ObjCopy.h b/llvm/include/llvm/ObjCopy/ObjCopy.h new file mode 100644 --- /dev/null +++ b/llvm/include/llvm/ObjCopy/ObjCopy.h @@ -0,0 +1,42 @@ +//===- 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_OBJCOPY_OBJCOPY_H +#define LLVM_OBJCOPY_OBJCOPY_H + +#include "llvm/Support/Error.h" + +namespace llvm { +class raw_ostream; + +namespace object { +class Archive; +class Binary; +} // end namespace object + +namespace objcopy { +class MultiFormatConfig; + +/// 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_OBJCOPY_OBJCOPY_H diff --git a/llvm/tools/llvm-objcopy/wasm/WasmConfig.h b/llvm/include/llvm/ObjCopy/wasm/WasmConfig.h rename from llvm/tools/llvm-objcopy/wasm/WasmConfig.h rename to llvm/include/llvm/ObjCopy/wasm/WasmConfig.h --- a/llvm/tools/llvm-objcopy/wasm/WasmConfig.h +++ b/llvm/include/llvm/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_OBJCOPY_WASM_WASMCONFIG_H +#define LLVM_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_OBJCOPY_WASM_WASMCONFIG_H diff --git a/llvm/tools/llvm-objcopy/wasm/WasmObjcopy.h b/llvm/include/llvm/ObjCopy/wasm/WasmObjcopy.h rename from llvm/tools/llvm-objcopy/wasm/WasmObjcopy.h rename to llvm/include/llvm/ObjCopy/wasm/WasmObjcopy.h --- a/llvm/tools/llvm-objcopy/wasm/WasmObjcopy.h +++ b/llvm/include/llvm/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_OBJCOPY_WASM_WASMOBJCOPY_H +#define LLVM_OBJCOPY_WASM_WASMOBJCOPY_H namespace llvm { class Error; @@ -29,4 +29,4 @@ } // end namespace objcopy } // end namespace llvm -#endif // LLVM_TOOLS_LLVM_OBJCOPY_WASM_WASMOBJCOPY_H +#endif // LLVM_OBJCOPY_WASM_WASMOBJCOPY_H diff --git a/llvm/lib/CMakeLists.txt b/llvm/lib/CMakeLists.txt --- a/llvm/lib/CMakeLists.txt +++ b/llvm/lib/CMakeLists.txt @@ -21,6 +21,7 @@ add_subdirectory(LTO) add_subdirectory(MC) add_subdirectory(MCA) +add_subdirectory(ObjCopy) add_subdirectory(Object) add_subdirectory(ObjectYAML) add_subdirectory(Option) diff --git a/llvm/tools/llvm-objcopy/llvm-objcopy.h b/llvm/lib/ObjCopy/Archive.h rename from llvm/tools/llvm-objcopy/llvm-objcopy.h rename to llvm/lib/ObjCopy/Archive.h --- a/llvm/tools/llvm-objcopy/llvm-objcopy.h +++ b/llvm/lib/ObjCopy/Archive.h @@ -1,4 +1,4 @@ -//===- llvm-objcopy.h -------------------------------------------*- C++ -*-===// +//===- Archive.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. @@ -6,24 +6,21 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_TOOLS_OBJCOPY_OBJCOPY_H -#define LLVM_TOOLS_OBJCOPY_OBJCOPY_H +#ifndef LLVM_LIB_OBJCOPY_ARCHIVE_H +#define LLVM_LIB_OBJCOPY_ARCHIVE_H +#include "llvm/Object/ArchiveWriter.h" #include "llvm/Support/Error.h" -#include "llvm/Support/raw_ostream.h" +#include namespace llvm { - -struct NewArchiveMember; - -namespace object { - -class Archive; - -} // end namespace object - namespace objcopy { + class MultiFormatConfig; + +/// 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); @@ -31,4 +28,4 @@ } // end namespace objcopy } // end namespace llvm -#endif // LLVM_TOOLS_OBJCOPY_OBJCOPY_H +#endif // LLVM_LIB_OBJCOPY_ARCHIVE_H diff --git a/llvm/lib/ObjCopy/Archive.cpp b/llvm/lib/ObjCopy/Archive.cpp new file mode 100644 --- /dev/null +++ b/llvm/lib/ObjCopy/Archive.cpp @@ -0,0 +1,105 @@ +//===- Archive.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 "Archive.h" +#include "llvm/ObjCopy/CommonConfig.h" +#include "llvm/ObjCopy/MultiFormatConfig.h" +#include "llvm/ObjCopy/ObjCopy.h" +#include "llvm/Object/Error.h" +#include "llvm/Support/FileOutputBuffer.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()); +} + +} // end namespace objcopy +} // end namespace llvm diff --git a/llvm/lib/ObjCopy/CMakeLists.txt b/llvm/lib/ObjCopy/CMakeLists.txt new file mode 100644 --- /dev/null +++ b/llvm/lib/ObjCopy/CMakeLists.txt @@ -0,0 +1,31 @@ +add_llvm_component_library(LLVMObjCopy + Archive.cpp + ObjCopy.cpp + ConfigManager.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 + + ADDITIONAL_HEADER_DIRS + ${LLVM_MAIN_INCLUDE_DIR}/llvm/Object + + DEPENDS + intrinsics_gen + + LINK_COMPONENTS + Object + Support + MC + ) diff --git a/llvm/tools/llvm-objcopy/COFF/COFFObjcopy.cpp b/llvm/lib/ObjCopy/COFF/COFFObjcopy.cpp rename from llvm/tools/llvm-objcopy/COFF/COFFObjcopy.cpp rename to llvm/lib/ObjCopy/COFF/COFFObjcopy.cpp --- a/llvm/tools/llvm-objcopy/COFF/COFFObjcopy.cpp +++ b/llvm/lib/ObjCopy/COFF/COFFObjcopy.cpp @@ -6,12 +6,12 @@ // //===----------------------------------------------------------------------===// -#include "COFFObjcopy.h" -#include "COFFConfig.h" -#include "CommonConfig.h" +#include "llvm/ObjCopy/COFF/COFFObjcopy.h" #include "Object.h" #include "Reader.h" #include "Writer.h" +#include "llvm/ObjCopy/COFF/COFFConfig.h" +#include "llvm/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/ObjCopy/COFF/Object.h rename from llvm/tools/llvm-objcopy/COFF/Object.h rename to llvm/lib/ObjCopy/COFF/Object.h --- a/llvm/tools/llvm-objcopy/COFF/Object.h +++ b/llvm/lib/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_OBJCOPY_COFF_OBJECT_H +#define LLVM_LIB_OBJCOPY_COFF_OBJECT_H #include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/DenseMap.h" @@ -209,4 +209,4 @@ } // end namespace objcopy } // end namespace llvm -#endif // LLVM_TOOLS_OBJCOPY_COFF_OBJECT_H +#endif // LLVM_LIB_OBJCOPY_COFF_OBJECT_H diff --git a/llvm/tools/llvm-objcopy/COFF/Object.cpp b/llvm/lib/ObjCopy/COFF/Object.cpp rename from llvm/tools/llvm-objcopy/COFF/Object.cpp rename to llvm/lib/ObjCopy/COFF/Object.cpp diff --git a/llvm/tools/llvm-objcopy/COFF/Reader.h b/llvm/lib/ObjCopy/COFF/Reader.h rename from llvm/tools/llvm-objcopy/COFF/Reader.h rename to llvm/lib/ObjCopy/COFF/Reader.h --- a/llvm/tools/llvm-objcopy/COFF/Reader.h +++ b/llvm/lib/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_OBJCOPY_COFF_READER_H +#define LLVM_LIB_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_OBJCOPY_COFF_READER_H diff --git a/llvm/tools/llvm-objcopy/COFF/Reader.cpp b/llvm/lib/ObjCopy/COFF/Reader.cpp rename from llvm/tools/llvm-objcopy/COFF/Reader.cpp rename to llvm/lib/ObjCopy/COFF/Reader.cpp diff --git a/llvm/tools/llvm-objcopy/COFF/Writer.h b/llvm/lib/ObjCopy/COFF/Writer.h rename from llvm/tools/llvm-objcopy/COFF/Writer.h rename to llvm/lib/ObjCopy/COFF/Writer.h --- a/llvm/tools/llvm-objcopy/COFF/Writer.h +++ b/llvm/lib/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_OBJCOPY_COFF_WRITER_H +#define LLVM_LIB_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_OBJCOPY_COFF_WRITER_H diff --git a/llvm/tools/llvm-objcopy/COFF/Writer.cpp b/llvm/lib/ObjCopy/COFF/Writer.cpp rename from llvm/tools/llvm-objcopy/COFF/Writer.cpp rename to llvm/lib/ObjCopy/COFF/Writer.cpp diff --git a/llvm/lib/ObjCopy/ConfigManager.cpp b/llvm/lib/ObjCopy/ConfigManager.cpp new file mode 100644 --- /dev/null +++ b/llvm/lib/ObjCopy/ConfigManager.cpp @@ -0,0 +1,70 @@ +//===- ConfigManager.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/ObjCopy/ConfigManager.h" +#include "llvm/Support/Errc.h" +#include "llvm/Support/Error.h" + +namespace llvm { +namespace objcopy { + +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 is not supported 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 is not supported 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; +} + +} // end namespace objcopy +} // end namespace llvm diff --git a/llvm/tools/llvm-objcopy/ELF/ELFObjcopy.cpp b/llvm/lib/ObjCopy/ELF/ELFObjcopy.cpp rename from llvm/tools/llvm-objcopy/ELF/ELFObjcopy.cpp rename to llvm/lib/ObjCopy/ELF/ELFObjcopy.cpp --- a/llvm/tools/llvm-objcopy/ELF/ELFObjcopy.cpp +++ b/llvm/lib/ObjCopy/ELF/ELFObjcopy.cpp @@ -6,11 +6,8 @@ // //===----------------------------------------------------------------------===// -#include "ELFObjcopy.h" -#include "CommonConfig.h" -#include "ELFConfig.h" +#include "llvm/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" @@ -20,6 +17,8 @@ #include "llvm/ADT/Twine.h" #include "llvm/BinaryFormat/ELF.h" #include "llvm/MC/MCTargetOptions.h" +#include "llvm/ObjCopy/CommonConfig.h" +#include "llvm/ObjCopy/ELF/ELFConfig.h" #include "llvm/Object/Binary.h" #include "llvm/Object/ELFObjectFile.h" #include "llvm/Object/ELFTypes.h" @@ -169,7 +168,7 @@ template static Error makeStringError(std::error_code EC, const Twine &Msg, - Ts &&... Args) { + Ts &&...Args) { std::string FullMsg = (EC.message() + ": " + Msg).str(); return createStringError(EC, FullMsg.c_str(), std::forward(Args)...); } diff --git a/llvm/tools/llvm-objcopy/ELF/Object.h b/llvm/lib/ObjCopy/ELF/Object.h rename from llvm/tools/llvm-objcopy/ELF/Object.h rename to llvm/lib/ObjCopy/ELF/Object.h --- a/llvm/tools/llvm-objcopy/ELF/Object.h +++ b/llvm/lib/ObjCopy/ELF/Object.h @@ -6,15 +6,15 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_TOOLS_OBJCOPY_OBJECT_H -#define LLVM_TOOLS_OBJCOPY_OBJECT_H +#ifndef LLVM_LIB_OBJCOPY_ELF_OBJECT_H +#define LLVM_LIB_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/ObjCopy/CommonConfig.h" #include "llvm/Object/ELFObjectFile.h" #include "llvm/Support/Errc.h" #include "llvm/Support/FileOutputBuffer.h" @@ -998,7 +998,7 @@ std::move(E)); } template - Error parseError(size_t LineNo, char const *Fmt, const Ts &... Vals) const { + Error parseError(size_t LineNo, char const *Fmt, const Ts &...Vals) const { Error E = createStringError(errc::invalid_argument, Fmt, Vals...); return parseError(LineNo, std::move(E)); } @@ -1088,7 +1088,7 @@ std::function ToRemove); Error replaceSections(const DenseMap &FromTo); Error removeSymbols(function_ref ToRemove); - template T &addSection(Ts &&... Args) { + template T &addSection(Ts &&...Args) { auto Sec = std::make_unique(std::forward(Args)...); auto Ptr = Sec.get(); MustBeRelocatable |= isa(*Ptr); @@ -1110,4 +1110,4 @@ } // end namespace objcopy } // end namespace llvm -#endif // LLVM_TOOLS_OBJCOPY_OBJECT_H +#endif // LLVM_LIB_OBJCOPY_ELF_OBJECT_H diff --git a/llvm/tools/llvm-objcopy/ELF/Object.cpp b/llvm/lib/ObjCopy/ELF/Object.cpp rename from llvm/tools/llvm-objcopy/ELF/Object.cpp rename to llvm/lib/ObjCopy/ELF/Object.cpp --- a/llvm/tools/llvm-objcopy/ELF/Object.cpp +++ b/llvm/lib/ObjCopy/ELF/Object.cpp @@ -1813,9 +1813,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/ObjCopy/MachO/MachOLayoutBuilder.h rename from llvm/tools/llvm-objcopy/MachO/MachOLayoutBuilder.h rename to llvm/lib/ObjCopy/MachO/MachOLayoutBuilder.h --- a/llvm/tools/llvm-objcopy/MachO/MachOLayoutBuilder.h +++ b/llvm/lib/ObjCopy/MachO/MachOLayoutBuilder.h @@ -6,11 +6,11 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_OBJCOPY_MACHO_MACHOLAYOUTBUILDER_H -#define LLVM_OBJCOPY_MACHO_MACHOLAYOUTBUILDER_H +#ifndef LLVM_LIB_OBJCOPY_MACHO_MACHOLAYOUTBUILDER_H +#define LLVM_LIB_OBJCOPY_MACHO_MACHOLAYOUTBUILDER_H -#include "MachOObjcopy.h" #include "Object.h" +#include "llvm/ObjCopy/MachO/MachOObjcopy.h" namespace llvm { namespace objcopy { @@ -94,4 +94,4 @@ } // end namespace objcopy } // end namespace llvm -#endif // LLVM_OBJCOPY_MACHO_MACHOLAYOUTBUILDER_H +#endif // LLVM_LIB_OBJCOPY_MACHO_MACHOLAYOUTBUILDER_H diff --git a/llvm/tools/llvm-objcopy/MachO/MachOLayoutBuilder.cpp b/llvm/lib/ObjCopy/MachO/MachOLayoutBuilder.cpp rename from llvm/tools/llvm-objcopy/MachO/MachOLayoutBuilder.cpp rename to llvm/lib/ObjCopy/MachO/MachOLayoutBuilder.cpp diff --git a/llvm/tools/llvm-objcopy/MachO/MachOObjcopy.cpp b/llvm/lib/ObjCopy/MachO/MachOObjcopy.cpp rename from llvm/tools/llvm-objcopy/MachO/MachOObjcopy.cpp rename to llvm/lib/ObjCopy/MachO/MachOObjcopy.cpp --- a/llvm/tools/llvm-objcopy/MachO/MachOObjcopy.cpp +++ b/llvm/lib/ObjCopy/MachO/MachOObjcopy.cpp @@ -6,14 +6,15 @@ // //===----------------------------------------------------------------------===// -#include "MachOObjcopy.h" -#include "../llvm-objcopy.h" -#include "CommonConfig.h" -#include "MachO/MachOConfig.h" +#include "llvm/ObjCopy/MachO/MachOObjcopy.h" +#include "Archive.h" #include "MachOReader.h" #include "MachOWriter.h" -#include "MultiFormatConfig.h" #include "llvm/ADT/DenseSet.h" +#include "llvm/ObjCopy/CommonConfig.h" +#include "llvm/ObjCopy/MachO/MachOConfig.h" +#include "llvm/ObjCopy/MultiFormatConfig.h" +#include "llvm/ObjCopy/ObjCopy.h" #include "llvm/Object/ArchiveWriter.h" #include "llvm/Object/MachOUniversal.h" #include "llvm/Object/MachOUniversalWriter.h" diff --git a/llvm/tools/llvm-objcopy/MachO/MachOReader.h b/llvm/lib/ObjCopy/MachO/MachOReader.h rename from llvm/tools/llvm-objcopy/MachO/MachOReader.h rename to llvm/lib/ObjCopy/MachO/MachOReader.h --- a/llvm/tools/llvm-objcopy/MachO/MachOReader.h +++ b/llvm/lib/ObjCopy/MachO/MachOReader.h @@ -6,9 +6,12 @@ // //===----------------------------------------------------------------------===// -#include "MachOObjcopy.h" +#ifndef LLVM_LIB_OBJCOPY_MACHO_MACHOREADER_H +#define LLVM_LIB_OBJCOPY_MACHO_MACHOREADER_H + #include "Object.h" #include "llvm/BinaryFormat/MachO.h" +#include "llvm/ObjCopy/MachO/MachOObjcopy.h" #include "llvm/Object/MachO.h" #include @@ -55,3 +58,5 @@ } // end namespace macho } // end namespace objcopy } // end namespace llvm + +#endif // LLVM_LIB_OBJCOPY_MACHO_MACHOREADER_H diff --git a/llvm/tools/llvm-objcopy/MachO/MachOReader.cpp b/llvm/lib/ObjCopy/MachO/MachOReader.cpp rename from llvm/tools/llvm-objcopy/MachO/MachOReader.cpp rename to llvm/lib/ObjCopy/MachO/MachOReader.cpp diff --git a/llvm/tools/llvm-objcopy/MachO/MachOWriter.h b/llvm/lib/ObjCopy/MachO/MachOWriter.h rename from llvm/tools/llvm-objcopy/MachO/MachOWriter.h rename to llvm/lib/ObjCopy/MachO/MachOWriter.h --- a/llvm/tools/llvm-objcopy/MachO/MachOWriter.h +++ b/llvm/lib/ObjCopy/MachO/MachOWriter.h @@ -6,10 +6,13 @@ // //===----------------------------------------------------------------------===// +#ifndef LLVM_LIB_OBJCOPY_MACHO_MACHOWRITER_H +#define LLVM_LIB_OBJCOPY_MACHO_MACHOWRITER_H + #include "MachOLayoutBuilder.h" -#include "MachOObjcopy.h" #include "Object.h" #include "llvm/BinaryFormat/MachO.h" +#include "llvm/ObjCopy/MachO/MachOObjcopy.h" #include "llvm/Object/MachO.h" namespace llvm { @@ -69,3 +72,5 @@ } // end namespace macho } // end namespace objcopy } // end namespace llvm + +#endif // LLVM_LIB_OBJCOPY_MACHO_MACHOWRITER_H diff --git a/llvm/tools/llvm-objcopy/MachO/MachOWriter.cpp b/llvm/lib/ObjCopy/MachO/MachOWriter.cpp rename from llvm/tools/llvm-objcopy/MachO/MachOWriter.cpp rename to llvm/lib/ObjCopy/MachO/MachOWriter.cpp diff --git a/llvm/tools/llvm-objcopy/MachO/Object.h b/llvm/lib/ObjCopy/MachO/Object.h rename from llvm/tools/llvm-objcopy/MachO/Object.h rename to llvm/lib/ObjCopy/MachO/Object.h --- a/llvm/tools/llvm-objcopy/MachO/Object.h +++ b/llvm/lib/ObjCopy/MachO/Object.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_OBJCOPY_MACHO_OBJECT_H -#define LLVM_OBJCOPY_MACHO_OBJECT_H +#ifndef LLVM_LIB_OBJCOPY_MACHO_OBJECT_H +#define LLVM_LIB_OBJCOPY_MACHO_OBJECT_H #include "llvm/ADT/Optional.h" #include "llvm/ADT/StringRef.h" @@ -371,4 +371,4 @@ } // end namespace objcopy } // end namespace llvm -#endif // LLVM_OBJCOPY_MACHO_OBJECT_H +#endif // LLVM_LIB_OBJCOPY_MACHO_OBJECT_H diff --git a/llvm/tools/llvm-objcopy/MachO/Object.cpp b/llvm/lib/ObjCopy/MachO/Object.cpp rename from llvm/tools/llvm-objcopy/MachO/Object.cpp rename to llvm/lib/ObjCopy/MachO/Object.cpp diff --git a/llvm/lib/ObjCopy/ObjCopy.cpp b/llvm/lib/ObjCopy/ObjCopy.cpp new file mode 100644 --- /dev/null +++ b/llvm/lib/ObjCopy/ObjCopy.cpp @@ -0,0 +1,79 @@ +//===- 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/ObjCopy/ObjCopy.h" +#include "llvm/ObjCopy/COFF/COFFConfig.h" +#include "llvm/ObjCopy/COFF/COFFObjcopy.h" +#include "llvm/ObjCopy/CommonConfig.h" +#include "llvm/ObjCopy/ELF/ELFConfig.h" +#include "llvm/ObjCopy/ELF/ELFObjcopy.h" +#include "llvm/ObjCopy/MachO/MachOConfig.h" +#include "llvm/ObjCopy/MachO/MachOObjcopy.h" +#include "llvm/ObjCopy/MultiFormatConfig.h" +#include "llvm/ObjCopy/wasm/WasmConfig.h" +#include "llvm/ObjCopy/wasm/WasmObjcopy.h" +#include "llvm/Object/COFF.h" +#include "llvm/Object/ELFObjectFile.h" +#include "llvm/Object/Error.h" +#include "llvm/Object/MachO.h" +#include "llvm/Object/MachOUniversal.h" +#include "llvm/Object/Wasm.h" +#include "llvm/Support/SmallVectorMemoryBuffer.h" + +namespace llvm { +namespace objcopy { + +using namespace llvm::object; + +/// 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); + } + if (auto *COFFBinary = dyn_cast(&In)) { + Expected COFFConfig = Config.getCOFFConfig(); + if (!COFFConfig) + return COFFConfig.takeError(); + + return coff::executeObjcopyOnBinary(Config.getCommonConfig(), *COFFConfig, + *COFFBinary, Out); + } + if (auto *MachOBinary = dyn_cast(&In)) { + Expected MachOConfig = Config.getMachOConfig(); + if (!MachOConfig) + return MachOConfig.takeError(); + + return macho::executeObjcopyOnBinary(Config.getCommonConfig(), *MachOConfig, + *MachOBinary, Out); + } + if (auto *MachOUniversalBinary = + dyn_cast(&In)) { + return macho::executeObjcopyOnMachOUniversalBinary( + Config, *MachOUniversalBinary, Out); + } + if (auto *WasmBinary = dyn_cast(&In)) { + Expected WasmConfig = Config.getWasmConfig(); + if (!WasmConfig) + return WasmConfig.takeError(); + + return objcopy::wasm::executeObjcopyOnBinary(Config.getCommonConfig(), + *WasmConfig, *WasmBinary, Out); + } + 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/ObjCopy/wasm/Object.h rename from llvm/tools/llvm-objcopy/wasm/Object.h rename to llvm/lib/ObjCopy/wasm/Object.h --- a/llvm/tools/llvm-objcopy/wasm/Object.h +++ b/llvm/lib/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_OBJCOPY_WASM_OBJECT_H +#define LLVM_LIB_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_OBJCOPY_WASM_OBJECT_H diff --git a/llvm/tools/llvm-objcopy/wasm/Object.cpp b/llvm/lib/ObjCopy/wasm/Object.cpp rename from llvm/tools/llvm-objcopy/wasm/Object.cpp rename to llvm/lib/ObjCopy/wasm/Object.cpp diff --git a/llvm/tools/llvm-objcopy/wasm/Reader.h b/llvm/lib/ObjCopy/wasm/Reader.h rename from llvm/tools/llvm-objcopy/wasm/Reader.h rename to llvm/lib/ObjCopy/wasm/Reader.h --- a/llvm/tools/llvm-objcopy/wasm/Reader.h +++ b/llvm/lib/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_OBJCOPY_WASM_READER_H +#define LLVM_LIB_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_OBJCOPY_WASM_READER_H diff --git a/llvm/tools/llvm-objcopy/wasm/Reader.cpp b/llvm/lib/ObjCopy/wasm/Reader.cpp rename from llvm/tools/llvm-objcopy/wasm/Reader.cpp rename to llvm/lib/ObjCopy/wasm/Reader.cpp diff --git a/llvm/tools/llvm-objcopy/wasm/WasmObjcopy.cpp b/llvm/lib/ObjCopy/wasm/WasmObjcopy.cpp rename from llvm/tools/llvm-objcopy/wasm/WasmObjcopy.cpp rename to llvm/lib/ObjCopy/wasm/WasmObjcopy.cpp --- a/llvm/tools/llvm-objcopy/wasm/WasmObjcopy.cpp +++ b/llvm/lib/ObjCopy/wasm/WasmObjcopy.cpp @@ -6,11 +6,11 @@ // //===----------------------------------------------------------------------===// -#include "WasmObjcopy.h" -#include "CommonConfig.h" +#include "llvm/ObjCopy/wasm/WasmObjcopy.h" #include "Object.h" #include "Reader.h" #include "Writer.h" +#include "llvm/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/ObjCopy/wasm/Writer.h rename from llvm/tools/llvm-objcopy/wasm/Writer.h rename to llvm/lib/ObjCopy/wasm/Writer.h --- a/llvm/tools/llvm-objcopy/wasm/Writer.h +++ b/llvm/lib/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_OBJCOPY_WASM_WRITER_H +#define LLVM_LIB_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_OBJCOPY_WASM_WRITER_H diff --git a/llvm/tools/llvm-objcopy/wasm/Writer.cpp b/llvm/lib/ObjCopy/wasm/Writer.cpp rename from llvm/tools/llvm-objcopy/wasm/Writer.cpp rename to llvm/lib/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 @@ -1,5 +1,6 @@ set(LLVM_LINK_COMPONENTS Object + ObjCopy Option Support MC @@ -22,23 +23,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/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,12 +6,13 @@ // //===----------------------------------------------------------------------===// -#include "ConfigManager.h" +#include "ObjcopyOptions.h" #include "llvm/ADT/Optional.h" #include "llvm/ADT/SmallVector.h" #include "llvm/ADT/StringRef.h" #include "llvm/ADT/StringSet.h" #include "llvm/BinaryFormat/COFF.h" +#include "llvm/ObjCopy/ConfigManager.h" #include "llvm/Option/Arg.h" #include "llvm/Option/ArgList.h" #include "llvm/Support/CRC.h" @@ -20,8 +21,6 @@ #include "llvm/Support/Errc.h" #include "llvm/Support/Error.h" #include "llvm/Support/MemoryBuffer.h" -#include "llvm/Support/StringSaver.h" -#include using namespace llvm; using namespace llvm::objcopy; @@ -559,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. @@ -695,11 +632,10 @@ MatchStyle SectionMatchStyle = InputArgs.hasArg(OBJCOPY_regex) ? MatchStyle::Regex : MatchStyle::Wildcard; - MatchStyle SymbolMatchStyle = InputArgs.hasArg(OBJCOPY_regex) - ? MatchStyle::Regex - : InputArgs.hasArg(OBJCOPY_wildcard) - ? MatchStyle::Wildcard - : MatchStyle::Literal; + MatchStyle SymbolMatchStyle + = InputArgs.hasArg(OBJCOPY_regex) ? MatchStyle::Regex + : InputArgs.hasArg(OBJCOPY_wildcard) ? MatchStyle::Wildcard + : MatchStyle::Literal; StringRef InputFormat, OutputFormat; if (InputArgs.hasArg(OBJCOPY_target)) { InputFormat = InputArgs.getLastArgValue(OBJCOPY_target); @@ -1337,11 +1273,10 @@ "--regex and --wildcard are incompatible"); MatchStyle SectionMatchStyle = InputArgs.hasArg(STRIP_regex) ? MatchStyle::Regex : MatchStyle::Wildcard; - MatchStyle SymbolMatchStyle = InputArgs.hasArg(STRIP_regex) - ? MatchStyle::Regex - : InputArgs.hasArg(STRIP_wildcard) - ? MatchStyle::Wildcard - : MatchStyle::Literal; + MatchStyle SymbolMatchStyle + = InputArgs.hasArg(STRIP_regex) ? MatchStyle::Regex + : InputArgs.hasArg(STRIP_wildcard) ? MatchStyle::Wildcard + : MatchStyle::Literal; ELFConfig.AllowBrokenLinks = InputArgs.hasArg(STRIP_allow_broken_links); Config.StripDebug = InputArgs.hasArg(STRIP_strip_debug); 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,23 +6,22 @@ // //===----------------------------------------------------------------------===// -#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/ADT/STLExtras.h" #include "llvm/ADT/SmallVector.h" #include "llvm/ADT/StringRef.h" #include "llvm/ADT/Twine.h" #include "llvm/BinaryFormat/ELF.h" +#include "llvm/ObjCopy/COFF/COFFConfig.h" +#include "llvm/ObjCopy/COFF/COFFObjcopy.h" +#include "llvm/ObjCopy/CommonConfig.h" +#include "llvm/ObjCopy/ELF/ELFConfig.h" +#include "llvm/ObjCopy/ELF/ELFObjcopy.h" +#include "llvm/ObjCopy/MachO/MachOConfig.h" +#include "llvm/ObjCopy/MachO/MachOObjcopy.h" +#include "llvm/ObjCopy/ObjCopy.h" +#include "llvm/ObjCopy/wasm/WasmConfig.h" +#include "llvm/ObjCopy/wasm/WasmObjcopy.h" #include "llvm/Object/Archive.h" #include "llvm/Object/ArchiveWriter.h" #include "llvm/Object/Binary.h" @@ -96,40 +95,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,102 +131,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(), - /*RequiresNullTerminator=*/false); - 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/ObjCopy/CMakeLists.txt b/llvm/unittests/ObjCopy/CMakeLists.txt new file mode 100644 --- /dev/null +++ b/llvm/unittests/ObjCopy/CMakeLists.txt @@ -0,0 +1,11 @@ +set(LLVM_LINK_COMPONENTS + Object + ObjCopy + ObjectYAML + ) + +add_llvm_unittest(ObjCopyTests + ObjCopyTest.cpp + ) + +target_link_libraries(ObjCopyTests PRIVATE LLVMTestingSupport) diff --git a/llvm/unittests/ObjCopy/ObjCopyTest.cpp b/llvm/unittests/ObjCopy/ObjCopyTest.cpp new file mode 100644 --- /dev/null +++ b/llvm/unittests/ObjCopy/ObjCopyTest.cpp @@ -0,0 +1,118 @@ +//===- 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/ObjCopy/ObjCopy.h" +#include "llvm/ADT/SmallString.h" +#include "llvm/ObjCopy/ConfigManager.h" +#include "llvm/Object/ObjectFile.h" +#include "llvm/ObjectYAML/yaml2obj.h" +#include "llvm/Support/Error.h" +#include "llvm/Support/FileUtilities.h" +#include "llvm/Testing/Support/Error.h" +#include "gtest/gtest.h" + +using namespace llvm; +using namespace object; +using namespace objcopy; +using namespace yaml; + +void copySimpleInMemoryFileImpl( + const char *YamlCreationString, + std::function IsValidFormat) { + auto ErrHandler = [&](const Twine &Msg) { FAIL() << "Error: " << Msg; }; + + // Create Object file from YAML description. + SmallVector Storage; + std::unique_ptr Obj = + yaml2ObjectFile(Storage, YamlCreationString, ErrHandler); + ASSERT_TRUE(Obj); + ASSERT_TRUE(IsValidFormat(*Obj)); + + ConfigManager Config; + Config.Common.OutputFilename = "a.out"; + + // Call executeObjcopyOnBinary() + SmallVector DataVector; + raw_svector_ostream OutStream(DataVector); + Error Err = objcopy::executeObjcopyOnBinary(Config, *Obj.get(), OutStream); + ASSERT_FALSE(std::move(Err)); + + MemoryBufferRef Buffer(StringRef(DataVector.data(), DataVector.size()), + Config.Common.OutputFilename); + + // Check copied file. + Expected> Result = createBinary(Buffer); + ASSERT_THAT_EXPECTED(Result, Succeeded()); + ASSERT_TRUE(IsValidFormat(**Result)); +} + +TEST(CopySimpleInMemoryFile, COFF) { + SCOPED_TRACE("CopySimpleInMemoryFileCOFF"); + + copySimpleInMemoryFileImpl( + 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(CopySimpleInMemoryFile, ELF) { + SCOPED_TRACE("CopySimpleInMemoryFileELF"); + + copySimpleInMemoryFileImpl( + R"( +--- !ELF +FileHeader: + Class: ELFCLASS64 + Data: ELFDATA2LSB + Type: ET_REL)", + [](const Binary &File) { return File.isELF(); }); +} + +TEST(CopySimpleInMemoryFile, MachO) { + SCOPED_TRACE("CopySimpleInMemoryFileMachO"); + + copySimpleInMemoryFileImpl( + 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(CopySimpleInMemoryFile, Wasm) { + SCOPED_TRACE("CopySimpleInMemoryFileWasm"); + + copySimpleInMemoryFileImpl( + R"( +--- !WASM +FileHeader: + Version: 0x00000001 +... +)", + [](const Binary &File) { return File.isWasm(); }); +}