-
Notifications
You must be signed in to change notification settings - Fork 14.8k
[DirectX] Add boilerplate integration of objcopy
for DXContainerObjectFile
#153079
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
@llvm/pr-subscribers-llvm-binary-utilities @llvm/pr-subscribers-backend-directx Author: Finn Plummer (inbelic) ChangesThis pr implements the boiler plate required to use It defines a minimal structure This is the first step to implement #150275 and #150277 as compiler actions that invoke Patch is 37.46 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/153079.diff 16 Files Affected:
diff --git a/llvm/include/llvm/ObjCopy/ConfigManager.h b/llvm/include/llvm/ObjCopy/ConfigManager.h
index e7b3775f0e9f1..4b596c604ea3a 100644
--- a/llvm/include/llvm/ObjCopy/ConfigManager.h
+++ b/llvm/include/llvm/ObjCopy/ConfigManager.h
@@ -11,6 +11,7 @@
#include "llvm/ObjCopy/COFF/COFFConfig.h"
#include "llvm/ObjCopy/CommonConfig.h"
+#include "llvm/ObjCopy/DXContainer/DXContainerConfig.h"
#include "llvm/ObjCopy/ELF/ELFConfig.h"
#include "llvm/ObjCopy/MachO/MachOConfig.h"
#include "llvm/ObjCopy/MultiFormatConfig.h"
@@ -36,6 +37,8 @@ struct LLVM_ABI ConfigManager : public MultiFormatConfig {
Expected<const XCOFFConfig &> getXCOFFConfig() const override;
+ Expected<const DXContainerConfig &> getDXContainerConfig() const override;
+
// All configs.
CommonConfig Common;
ELFConfig ELF;
@@ -43,6 +46,7 @@ struct LLVM_ABI ConfigManager : public MultiFormatConfig {
MachOConfig MachO;
WasmConfig Wasm;
XCOFFConfig XCOFF;
+ DXContainerConfig DXContainer;
};
} // namespace objcopy
diff --git a/llvm/include/llvm/ObjCopy/DXContainer/DXContainerConfig.h b/llvm/include/llvm/ObjCopy/DXContainer/DXContainerConfig.h
new file mode 100644
index 0000000000000..1ce4f2bb370eb
--- /dev/null
+++ b/llvm/include/llvm/ObjCopy/DXContainer/DXContainerConfig.h
@@ -0,0 +1,21 @@
+//===- DXContainerConfig.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_DXCONTAINER_DXCONTAINERCONFIG_H
+#define LLVM_OBJCOPY_DXCONTAINER_DXCONTAINERCONFIG_H
+
+namespace llvm {
+namespace objcopy {
+
+// DXContainer specific configuration for copying/stripping a single file.
+struct DXContainerConfig {};
+
+} // namespace objcopy
+} // namespace llvm
+
+#endif // LLVM_OBJCOPY_DXCONTAINER_DXCONTAINERCONFIG_H
diff --git a/llvm/include/llvm/ObjCopy/DXContainer/DXContainerObjcopy.h b/llvm/include/llvm/ObjCopy/DXContainer/DXContainerObjcopy.h
new file mode 100644
index 0000000000000..d27a955b9afab
--- /dev/null
+++ b/llvm/include/llvm/ObjCopy/DXContainer/DXContainerObjcopy.h
@@ -0,0 +1,36 @@
+//===- DXContainerObjcopy.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_DXCONTAINER_DXCONTAINEROBJCOPY_H
+#define LLVM_OBJCOPY_DXCONTAINER_DXCONTAINEROBJCOPY_H
+
+namespace llvm {
+class Error;
+class raw_ostream;
+
+namespace object {
+class DXContainerObjectFile;
+} // end namespace object
+
+namespace objcopy {
+struct CommonConfig;
+struct DXContainerConfig;
+
+namespace dxc {
+/// Apply the transformations described by \p Config and \p DXContainerConfig
+/// to \p In and writes the result into \p Out.
+/// \returns any Error encountered whilst performing the operation.
+Error executeObjcopyOnBinary(const CommonConfig &Config,
+ const DXContainerConfig &,
+ object::DXContainerObjectFile &In,
+ raw_ostream &Out);
+} // end namespace dxc
+} // end namespace objcopy
+} // end namespace llvm
+
+#endif // LLVM_OBJCOPY_DXCONTAINER_DXCONTAINEROBJCOPY_H
diff --git a/llvm/include/llvm/ObjCopy/MultiFormatConfig.h b/llvm/include/llvm/ObjCopy/MultiFormatConfig.h
index 180f2f82a908b..bb93f64aa2788 100644
--- a/llvm/include/llvm/ObjCopy/MultiFormatConfig.h
+++ b/llvm/include/llvm/ObjCopy/MultiFormatConfig.h
@@ -20,6 +20,7 @@ struct COFFConfig;
struct MachOConfig;
struct WasmConfig;
struct XCOFFConfig;
+struct DXContainerConfig;
class MultiFormatConfig {
public:
@@ -31,6 +32,7 @@ class MultiFormatConfig {
virtual Expected<const MachOConfig &> getMachOConfig() const = 0;
virtual Expected<const WasmConfig &> getWasmConfig() const = 0;
virtual Expected<const XCOFFConfig &> getXCOFFConfig() const = 0;
+ virtual Expected<const DXContainerConfig &> getDXContainerConfig() const = 0;
};
} // namespace objcopy
diff --git a/llvm/include/llvm/Object/DXContainer.h b/llvm/include/llvm/Object/DXContainer.h
index 3c8cd174afede..54cfd35b35fe8 100644
--- a/llvm/include/llvm/Object/DXContainer.h
+++ b/llvm/include/llvm/Object/DXContainer.h
@@ -605,6 +605,8 @@ class DXContainerObjectFile : public ObjectFile {
public:
static bool classof(const Binary *v) { return v->isDXContainer(); }
+ const dxbc::Header &getHeader() const { return Container.getHeader(); }
+
Expected<StringRef> getSymbolName(DataRefImpl) const override;
Expected<uint64_t> getSymbolAddress(DataRefImpl Symb) const override;
uint64_t getSymbolValueImpl(DataRefImpl Symb) const override;
diff --git a/llvm/lib/ObjCopy/CMakeLists.txt b/llvm/lib/ObjCopy/CMakeLists.txt
index 2d6bee94875f0..54d0ea99fbc28 100644
--- a/llvm/lib/ObjCopy/CMakeLists.txt
+++ b/llvm/lib/ObjCopy/CMakeLists.txt
@@ -16,6 +16,9 @@ source_group("Header Files\\wasm" REGULAR_EXPRESSION
source_group("Header Files\\XCOFF" REGULAR_EXPRESSION
XCOFF/.*[.]h
)
+source_group("Header Files\\DXContainer" REGULAR_EXPRESSION
+ DXContainer/.*[.]h
+)
source_group("Source Files" REGULAR_EXPRESSION
.*[.]cpp
)
@@ -34,9 +37,15 @@ source_group("Source Files\\wasm" REGULAR_EXPRESSION
source_group("Source Files\\XCOFF" REGULAR_EXPRESSION
XCOFF/.*[.]cpp
)
+source_group("Source Files\\DXContainer" REGULAR_EXPRESSION
+ DXContainer/.*[.]cpp
+)
add_llvm_component_library(LLVMObjCopy
Archive.cpp
+ DXContainer/DXContainerObjcopy.cpp
+ DXContainer/DXContainerReader.cpp
+ DXContainer/DXContainerWriter.cpp
CommonConfig.cpp
ObjCopy.cpp
ConfigManager.cpp
@@ -62,11 +71,13 @@ add_llvm_component_library(LLVMObjCopy
ADDITIONAL_HEADER_DIRS
${LLVM_MAIN_INCLUDE_DIR}/llvm/ObjCopy
${LLVM_MAIN_INCLUDE_DIR}/llvm/ObjCopy/COFF
+ ${LLVM_MAIN_INCLUDE_DIR}/llvm/ObjCopy/DXContainer
${LLVM_MAIN_INCLUDE_DIR}/llvm/ObjCopy/ELF
${LLVM_MAIN_INCLUDE_DIR}/llvm/ObjCopy/MachO
${LLVM_MAIN_INCLUDE_DIR}/llvm/ObjCopy/wasm
${LLVM_MAIN_INCLUDE_DIR}/llvm/ObjCopy/XCOFF
COFF
+ DXContainer
ELF
MachO
wasm
diff --git a/llvm/lib/ObjCopy/ConfigManager.cpp b/llvm/lib/ObjCopy/ConfigManager.cpp
index 9a81b51c4d277..fd82a7f60477f 100644
--- a/llvm/lib/ObjCopy/ConfigManager.cpp
+++ b/llvm/lib/ObjCopy/ConfigManager.cpp
@@ -107,3 +107,35 @@ Expected<const XCOFFConfig &> ConfigManager::getXCOFFConfig() const {
return XCOFF;
}
+
+Expected<const DXContainerConfig &>
+ConfigManager::getDXContainerConfig() const {
+ if (!Common.AddGnuDebugLink.empty() || Common.ExtractPartition ||
+ !Common.SplitDWO.empty() || !Common.SymbolsPrefix.empty() ||
+ !Common.SymbolsPrefixRemove.empty() || !Common.SymbolsToSkip.empty() ||
+ !Common.AllocSectionsPrefix.empty() ||
+ Common.DiscardMode != DiscardType::None || !Common.AddSection.empty() ||
+ !Common.DumpSection.empty() || !Common.SymbolsToAdd.empty() ||
+ !Common.KeepSection.empty() || !Common.OnlySection.empty() ||
+ !Common.ToRemove.empty() || !Common.SymbolsToGlobalize.empty() ||
+ !Common.SymbolsToKeep.empty() || !Common.SymbolsToLocalize.empty() ||
+ !Common.SymbolsToRemove.empty() ||
+ !Common.UnneededSymbolsToRemove.empty() ||
+ !Common.SymbolsToWeaken.empty() || !Common.SymbolsToKeepGlobal.empty() ||
+ !Common.SectionsToRename.empty() || !Common.SetSectionAlignment.empty() ||
+ !Common.SetSectionFlags.empty() || !Common.SetSectionType.empty() ||
+ !Common.SymbolsToRename.empty() || Common.ExtractDWO ||
+ Common.ExtractMainPartition || Common.OnlyKeepDebug ||
+ Common.PreserveDates || Common.StripAllGNU || Common.StripDWO ||
+ Common.StripDebug || Common.StripNonAlloc || Common.StripSections ||
+ Common.Weaken || Common.StripUnneeded || Common.DecompressDebugSections ||
+ Common.GapFill != 0 || Common.PadTo != 0 ||
+ Common.ChangeSectionLMAValAll != 0 ||
+ !Common.ChangeSectionAddress.empty()) {
+ return createStringError(
+ llvm::errc::invalid_argument,
+ "no flags are supported yet, only basic copying is allowed");
+ }
+
+ return DXContainer;
+}
diff --git a/llvm/lib/ObjCopy/DXContainer/DXContainerObjcopy.cpp b/llvm/lib/ObjCopy/DXContainer/DXContainerObjcopy.cpp
new file mode 100644
index 0000000000000..9629555b38a1b
--- /dev/null
+++ b/llvm/lib/ObjCopy/DXContainer/DXContainerObjcopy.cpp
@@ -0,0 +1,47 @@
+//===- DXContainerObjcopy.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/DXContainer/DXContainerObjcopy.h"
+#include "llvm/ObjCopy/CommonConfig.h"
+#include "llvm/ObjCopy/DXContainer/DXContainerConfig.h"
+
+#include "DXContainerReader.h"
+#include "DXContainerWriter.h"
+
+namespace llvm {
+namespace objcopy {
+namespace dxc {
+
+using namespace object;
+
+static Error handleArgs(const CommonConfig &Config, Object &Obj) {
+ return Error::success();
+}
+
+Error executeObjcopyOnBinary(const CommonConfig &Config,
+ const DXContainerConfig &,
+ DXContainerObjectFile &In, raw_ostream &Out) {
+ DXContainerReader Reader(In);
+ Expected<std::unique_ptr<Object>> ObjOrErr = Reader.create();
+ if (!ObjOrErr)
+ return createFileError(Config.InputFilename, ObjOrErr.takeError());
+ Object *Obj = ObjOrErr->get();
+ assert(Obj && "Unable to deserialize DXContainer object");
+
+ if (Error E = handleArgs(Config, *Obj))
+ return E;
+
+ DXContainerWriter Writer(*Obj, Out);
+ if (Error E = Writer.write())
+ return createFileError(Config.OutputFilename, std::move(E));
+ return Error::success();
+}
+
+} // end namespace dxc
+} // end namespace objcopy
+} // end namespace llvm
diff --git a/llvm/lib/ObjCopy/DXContainer/DXContainerObject.h b/llvm/lib/ObjCopy/DXContainer/DXContainerObject.h
new file mode 100644
index 0000000000000..14f948df0ad9a
--- /dev/null
+++ b/llvm/lib/ObjCopy/DXContainer/DXContainerObject.h
@@ -0,0 +1,38 @@
+//===- DXContainerObject.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_LIB_OBJCOPY_DXContainer_DXContainerOBJECT_H
+#define LLVM_LIB_OBJCOPY_DXContainer_DXContainerOBJECT_H
+
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/Object/DXContainer.h"
+#include <vector>
+
+namespace llvm {
+namespace objcopy {
+namespace dxc {
+
+using namespace object;
+
+struct Part {
+ StringRef Name;
+ uint32_t Offset;
+ ArrayRef<uint8_t> Data;
+};
+
+struct Object {
+ dxbc::Header Header;
+ SmallVector<Part> Parts;
+};
+
+} // end namespace dxc
+} // end namespace objcopy
+} // end namespace llvm
+
+#endif // LLVM_LIB_OBJCOPY_DXContainer_DXContainerOBJECT_H
diff --git a/llvm/lib/ObjCopy/DXContainer/DXContainerReader.cpp b/llvm/lib/ObjCopy/DXContainer/DXContainerReader.cpp
new file mode 100644
index 0000000000000..d6e7a2a6a200c
--- /dev/null
+++ b/llvm/lib/ObjCopy/DXContainer/DXContainerReader.cpp
@@ -0,0 +1,38 @@
+//===- DXContainerReader.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 "DXContainerReader.h"
+
+namespace llvm {
+namespace objcopy {
+namespace dxc {
+
+using namespace object;
+
+Expected<std::unique_ptr<Object>> DXContainerReader::create() const {
+ auto Obj = std::make_unique<Object>();
+ Obj->Header = DXContainerObj.getHeader();
+ for (const SectionRef &Part : DXContainerObj.sections()) {
+ DataRefImpl PartDRI = Part.getRawDataRefImpl();
+ Expected<StringRef> Name = DXContainerObj.getSectionName(PartDRI);
+ if (auto E = Name.takeError())
+ return createStringError(inconvertibleErrorCode(), "Missing Part Name");
+ uint32_t Offset = DXContainerObj.getSectionAddress(PartDRI);
+ Expected<ArrayRef<uint8_t>> Data =
+ DXContainerObj.getSectionContents(PartDRI);
+ if (auto E = Data.takeError())
+ return createStringError(inconvertibleErrorCode(),
+ "Missing Part Contents");
+ Obj->Parts.push_back({*Name, Offset, *Data});
+ }
+ return std::move(Obj);
+}
+
+} // end namespace dxc
+} // end namespace objcopy
+} // end namespace llvm
diff --git a/llvm/lib/ObjCopy/DXContainer/DXContainerReader.h b/llvm/lib/ObjCopy/DXContainer/DXContainerReader.h
new file mode 100644
index 0000000000000..32128d0b6df0c
--- /dev/null
+++ b/llvm/lib/ObjCopy/DXContainer/DXContainerReader.h
@@ -0,0 +1,34 @@
+//===- DXContainerReader.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_LIB_OBJCOPY_DXCONTAINER_DXCONTAINERREADER_H
+#define LLVM_LIB_OBJCOPY_DXCONTAINER_DXCONTAINERREADER_H
+
+#include "DXContainerObject.h"
+
+namespace llvm {
+namespace objcopy {
+namespace dxc {
+
+using namespace object;
+
+class DXContainerReader {
+public:
+ explicit DXContainerReader(const DXContainerObjectFile &Obj)
+ : DXContainerObj(Obj) {}
+ Expected<std::unique_ptr<Object>> create() const;
+
+private:
+ const DXContainerObjectFile &DXContainerObj;
+};
+
+} // end namespace dxc
+} // end namespace objcopy
+} // end namespace llvm
+
+#endif // LLVM_LIB_OBJCOPY_DXCONTAINER_DXCONTAINERREADER_H
diff --git a/llvm/lib/ObjCopy/DXContainer/DXContainerWriter.cpp b/llvm/lib/ObjCopy/DXContainer/DXContainerWriter.cpp
new file mode 100644
index 0000000000000..8c7759c9ebe13
--- /dev/null
+++ b/llvm/lib/ObjCopy/DXContainer/DXContainerWriter.cpp
@@ -0,0 +1,50 @@
+//===- DXContainerWriter.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 "DXContainerWriter.h"
+
+namespace llvm {
+namespace objcopy {
+namespace dxc {
+
+using namespace object;
+
+size_t DXContainerWriter::finalize() {
+ size_t ObjectSize = sizeof(dxbc::Header);
+ ObjectSize += Obj.Parts.size() * sizeof(uint32_t);
+ Offsets.reserve(Obj.Parts.size());
+ for (const Part &P : Obj.Parts) {
+ Offsets.push_back(ObjectSize);
+ assert(P.Name.size() == 4 &&
+ "Valid DXIL Part name consists of 4 characters");
+ ObjectSize += 4 + sizeof(uint32_t) + P.Data.size();
+ }
+ return ObjectSize;
+}
+
+Error DXContainerWriter::write() {
+ size_t TotalSize = finalize();
+ Out.reserveExtraSpace(TotalSize);
+
+ Out.write(reinterpret_cast<const char *>(&Obj.Header), sizeof(dxbc::Header));
+ Out.write(reinterpret_cast<const char *>(Offsets.data()),
+ Offsets.size() * sizeof(uint32_t));
+
+ for (const Part &P : Obj.Parts) {
+ Out.write(reinterpret_cast<const char *>(P.Name.data()), P.Name.size());
+ uint32_t Size = P.Data.size();
+ Out.write(reinterpret_cast<const char *>(&Size), sizeof(uint32_t));
+ Out.write(reinterpret_cast<const char *>(P.Data.data()), P.Data.size());
+ }
+
+ return Error::success();
+}
+
+} // end namespace dxc
+} // end namespace objcopy
+} // end namespace llvm
diff --git a/llvm/lib/ObjCopy/DXContainer/DXContainerWriter.h b/llvm/lib/ObjCopy/DXContainer/DXContainerWriter.h
new file mode 100644
index 0000000000000..f330edd75b421
--- /dev/null
+++ b/llvm/lib/ObjCopy/DXContainer/DXContainerWriter.h
@@ -0,0 +1,39 @@
+//===- DXContainerWriter.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_LIB_OBJCOPY_DXCONTAINER_DXCONTAINERWRITER_H
+#define LLVM_LIB_OBJCOPY_DXCONTAINER_DXCONTAINERWRITER_H
+
+#include "DXContainerObject.h"
+
+namespace llvm {
+namespace objcopy {
+namespace dxc {
+
+using namespace object;
+
+class DXContainerWriter {
+public:
+ explicit DXContainerWriter(const Object &Obj, raw_ostream &Out)
+ : Obj(Obj), Out(Out) {}
+ Error write();
+
+private:
+ const Object &Obj;
+ raw_ostream &Out;
+
+ SmallVector<uint32_t> Offsets;
+
+ size_t finalize();
+};
+
+} // end namespace dxc
+} // end namespace objcopy
+} // end namespace llvm
+
+#endif // LLVM_LIB_OBJCOPY_DXCONTAINER_DXCONTAINERWRITER_H
diff --git a/llvm/lib/ObjCopy/ObjCopy.cpp b/llvm/lib/ObjCopy/ObjCopy.cpp
index d9a190d1a2ad1..e8e8067c9518d 100644
--- a/llvm/lib/ObjCopy/ObjCopy.cpp
+++ b/llvm/lib/ObjCopy/ObjCopy.cpp
@@ -9,6 +9,8 @@
#include "llvm/ObjCopy/ObjCopy.h"
#include "llvm/ObjCopy/COFF/COFFConfig.h"
#include "llvm/ObjCopy/COFF/COFFObjcopy.h"
+#include "llvm/ObjCopy/DXContainer/DXContainerConfig.h"
+#include "llvm/ObjCopy/DXContainer/DXContainerObjcopy.h"
#include "llvm/ObjCopy/ELF/ELFConfig.h"
#include "llvm/ObjCopy/ELF/ELFObjcopy.h"
#include "llvm/ObjCopy/MachO/MachOConfig.h"
@@ -19,6 +21,7 @@
#include "llvm/ObjCopy/wasm/WasmConfig.h"
#include "llvm/ObjCopy/wasm/WasmObjcopy.h"
#include "llvm/Object/COFF.h"
+#include "llvm/Object/DXContainer.h"
#include "llvm/Object/ELFObjectFile.h"
#include "llvm/Object/Error.h"
#include "llvm/Object/MachO.h"
@@ -78,6 +81,15 @@ Error objcopy::executeObjcopyOnBinary(const MultiFormatConfig &Config,
return xcoff::executeObjcopyOnBinary(Config.getCommonConfig(), *XCOFFConfig,
*XCOFFBinary, Out);
}
+ if (auto *DXContainerBinary = dyn_cast<object::DXContainerObjectFile>(&In)) {
+ Expected<const DXContainerConfig &> DXContainerConfig =
+ Config.getDXContainerConfig();
+ if (!DXContainerConfig)
+ return DXContainerConfig.takeError();
+
+ return dxc::executeObjcopyOnBinary(
+ Config.getCommonConfig(), *DXContainerConfig, *DXContainerBinary, Out);
+ }
return createStringError(object_error::invalid_file_type,
"unsupported object file format");
}
diff --git a/llvm/test/tools/llvm-objcopy/DXContainer/basic-copy.test b/llvm/test/tools/llvm-objcopy/DXContainer/basic-copy.test
new file mode 100644
index 0000000000000..1958b0ff18ac3
--- /dev/null
+++ b/llvm/test/tools/llvm-objcopy/DXContainer/basic-copy.test
@@ -0,0 +1,292 @@
+# RUN: yaml2obj %s -o %t
+# RUN: llvm-objcopy %t %t.out
+# RUN: cmp %t %t.out
+
+# The following DXContainer to copied was generated with:
+
+# `clang-dxc -T cs_6_7 test.hlsl /Fo temp.dxo`
+# `obj2yaml temp.dxo`
+
+# ``` test.hlsl
+# [RootSignature("")]
+# [numthreads(1,1,1)]
+# void main() {}
+# ```
+
+--- !dxcontainer
+Header:
+ Hash: [ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 ]
+ Version:
+ Major: 1
+ Minor: 0
+ FileSize: 1984
+ PartCount: 7
+ PartOffsets: [ 60, 1792, 1808, 1836, 1852, 1868, 1900 ]
+Parts:
+ - Name: DXIL
+ Size: 1724
+ Program:
+ MajorVersion: 6
+ MinorVersion: 7
+ ShaderKind: 5
+ Size: 431
+ DXILMajorVersion: 1
+ DXILMinorVersion: 7
+ ...
[truncated]
|
Out.reserveExtraSpace(TotalSize); | ||
|
||
Out.write(reinterpret_cast<const char *>(&Obj.Header), sizeof(dxbc::Header)); | ||
Out.write(reinterpret_cast<const char *>(Offsets.data()), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The dxcontainer file is little-endian, any writes that you're doing where you are not explicitly copying data from an existing file buffer you need to properly encode otherwise the big-endian LLVM bots will explode running your tests.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
https://imgflip.com/i/a2ti25 - what could have been
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No major issues from my point of view. I've focused my comments on LLVM style and generally integrating with the rest of llvm-objcopy, since I don't know the DXContainer format.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've not attempted to fully review the testing, but one glaring omission is any form of testing of your error handling when the input is somehow invalid. You should have a test for each of the different error paths you handle in this PR, to show that they are properly handled.
We do have DXContainerTest.cpp, where we test reading invalid structs. I am not sure how much benefit we get from reproducing those here. I have added two tests to sanity check they surface as expected. |
I'm not asking for testing of the underlying parsing code (since it should be tested elsewhere). I'm asking for tests that show that when that code is called and fed an invalid object, the resultant error is handled properly in your new code. This would help identify problems like the one I referred to in the second part of this comment. There are numerous examples of this for the other formats supported by llvm-objcopy, often requiring yaml2obj features for generating invalid object files. It may be necessary to extend yaml2obj to provide ways for creating invalid objects. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the updates. I've skimmed them briefly, but am going to need to give this another go over next week before I'm happy.
Okay, sounds good. |
This pr implements the boiler plate required to use
llvm-objcopy
forDXContainer
object files.It defines a minimal structure
object
to represent theDXContainer
header and the following parts.This structure is a simple representation of the object data to allow for simple modifications at the granularity of each part. It follows similarily to how the respective
object
s are defined forELF
,wasm
,XCOFF
, etc.This is the first step to implement #150275 and #150277 as compiler actions that invoke
llvm-objcopy
for functionality.