Skip to content

[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

Merged
merged 17 commits into from
Aug 20, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions llvm/include/llvm/ObjCopy/ConfigManager.h
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand All @@ -36,13 +37,16 @@ struct LLVM_ABI ConfigManager : public MultiFormatConfig {

Expected<const XCOFFConfig &> getXCOFFConfig() const override;

Expected<const DXContainerConfig &> getDXContainerConfig() const override;

// All configs.
CommonConfig Common;
ELFConfig ELF;
COFFConfig COFF;
MachOConfig MachO;
WasmConfig Wasm;
XCOFFConfig XCOFF;
DXContainerConfig DXContainer;
};

} // namespace objcopy
Expand Down
23 changes: 23 additions & 0 deletions llvm/include/llvm/ObjCopy/DXContainer/DXContainerConfig.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
//===- 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. This
// is defined, following convention elsewhere, as the return type of
// `getDXContainerConfig`, which reports an error for an unsupported option.
struct DXContainerConfig {};

} // namespace objcopy
} // namespace llvm

#endif // LLVM_OBJCOPY_DXCONTAINER_DXCONTAINERCONFIG_H
36 changes: 36 additions & 0 deletions llvm/include/llvm/ObjCopy/DXContainer/DXContainerObjcopy.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 dxbc {
/// 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 dxbc
} // end namespace objcopy
} // end namespace llvm

#endif // LLVM_OBJCOPY_DXCONTAINER_DXCONTAINEROBJCOPY_H
2 changes: 2 additions & 0 deletions llvm/include/llvm/ObjCopy/MultiFormatConfig.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ struct COFFConfig;
struct MachOConfig;
struct WasmConfig;
struct XCOFFConfig;
struct DXContainerConfig;

class MultiFormatConfig {
public:
Expand All @@ -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
Expand Down
2 changes: 2 additions & 0 deletions llvm/include/llvm/Object/DXContainer.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
11 changes: 11 additions & 0 deletions llvm/lib/ObjCopy/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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
)
Expand All @@ -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
Expand All @@ -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
Expand Down
24 changes: 24 additions & 0 deletions llvm/lib/ObjCopy/ConfigManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -107,3 +107,27 @@ Expected<const XCOFFConfig &> ConfigManager::getXCOFFConfig() const {

return XCOFF;
}

Expected<const DXContainerConfig &>
ConfigManager::getDXContainerConfig() const {
// All other flags are either supported or not applicable for DXContainer
// object files and will be silently ignored.
if (!Common.AddGnuDebugLink.empty() || !Common.SplitDWO.empty() ||
!Common.AllocSectionsPrefix.empty() ||
Common.DiscardMode != DiscardType::None || !Common.AddSection.empty() ||
!Common.DumpSection.empty() || !Common.KeepSection.empty() ||
!Common.OnlySection.empty() || !Common.ToRemove.empty() ||
!Common.SectionsToRename.empty() || !Common.SetSectionAlignment.empty() ||
!Common.SetSectionFlags.empty() || !Common.SetSectionType.empty() ||
Common.ExtractDWO || Common.OnlyKeepDebug || Common.StripAllGNU ||
Common.StripDWO || Common.StripDebug || Common.StripNonAlloc ||
Common.StripSections || 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;
}
46 changes: 46 additions & 0 deletions llvm/lib/ObjCopy/DXContainer/DXContainerObjcopy.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
//===- 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 "DXContainerReader.h"
#include "DXContainerWriter.h"
#include "llvm/ObjCopy/CommonConfig.h"
#include "llvm/ObjCopy/DXContainer/DXContainerConfig.h"

namespace llvm {
namespace objcopy {
namespace dxbc {

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 dxbc
} // end namespace objcopy
} // end namespace llvm
47 changes: 47 additions & 0 deletions llvm/lib/ObjCopy/DXContainer/DXContainerObject.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
//===- 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 dxbc {

using namespace object;

struct Part {
StringRef Name;
ArrayRef<uint8_t> Data;

size_t size() const {
return sizeof(::llvm::dxbc::PartHeader) // base header
+ Data.size(); // contents size
}
};

struct Object {
::llvm::dxbc::Header Header;
SmallVector<Part> Parts;

size_t headerSize() const {
return sizeof(::llvm::dxbc::Header) // base header
+ sizeof(uint32_t) * Parts.size(); // part offset values
}
};

} // end namespace dxbc
} // end namespace objcopy
} // end namespace llvm

#endif // LLVM_LIB_OBJCOPY_DXCONTAINER_DXCONTAINEROBJECT_H
38 changes: 38 additions & 0 deletions llvm/lib/ObjCopy/DXContainer/DXContainerReader.cpp
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 dxbc {

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 E;
assert(Name->size() == 4 &&
"Valid DXIL Part name consists of 4 characters");
Expected<ArrayRef<uint8_t>> Data =
DXContainerObj.getSectionContents(PartDRI);
if (auto E = Data.takeError())
return E;
Obj->Parts.push_back({*Name, *Data});
}
return std::move(Obj);
}

} // end namespace dxbc
} // end namespace objcopy
} // end namespace llvm
34 changes: 34 additions & 0 deletions llvm/lib/ObjCopy/DXContainer/DXContainerReader.h
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 dxbc {

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 dxbc
} // end namespace objcopy
} // end namespace llvm

#endif // LLVM_LIB_OBJCOPY_DXCONTAINER_DXCONTAINERREADER_H
Loading