-
Notifications
You must be signed in to change notification settings - Fork 15.4k
[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
Changes from 2 commits
44f66db
648d0fc
c4b1096
a3229ee
7ca8df7
56cbd57
c78cc58
152c383
99e3b41
dc8e3c2
364681a
4fa61af
9a60220
79c043e
40d4594
c0aec7a
b4c17fb
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -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 | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -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 |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -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" | ||
jh7370 marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
|
|
||
| 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 | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -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 | ||
jh7370 marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
|
|
||
| #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 | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -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"); | ||
jh7370 marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| uint32_t Offset = DXContainerObj.getSectionAddress(PartDRI); | ||
| Expected<ArrayRef<uint8_t>> Data = | ||
| DXContainerObj.getSectionContents(PartDRI); | ||
| if (auto E = Data.takeError()) | ||
| return createStringError(inconvertibleErrorCode(), | ||
jh7370 marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| "Missing Part Contents"); | ||
| Obj->Parts.push_back({*Name, Offset, *Data}); | ||
| } | ||
| return std::move(Obj); | ||
| } | ||
|
|
||
| } // end namespace dxc | ||
| } // end namespace objcopy | ||
| } // end namespace llvm | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -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 { | ||
inbelic marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
|
|
||
| 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 | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -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()); | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Should this either call |
||
| 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()), | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. https://imgflip.com/i/a2ti25 - what could have been |
||
| 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 | ||
Uh oh!
There was an error while loading. Please reload this page.