Skip to content

Commit 0c9e75e

Browse files
Create new class to handle external validation, and rename existing dll loading class. (#7514)
This PR creates a class that is responsible for loading and unloading dxil.dll, allowing for external validation. Tests are added to test this class's functionality. Additionally, an interface is defined that joins the existing singular dll loading helper class, and the new class that tracks two dlls. The classes were renamed to be more abstract, as well as all existing uses of the original singular dll loader class. Fixes #7422 --------- Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
1 parent 7a8c90c commit 0c9e75e

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

47 files changed

+487
-249
lines changed

include/dxc/Support/HLSLOptions.h

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ class raw_ostream;
3636
} // namespace llvm
3737

3838
namespace dxc {
39-
class DxcDllSupport;
39+
class SpecificDllLoader;
4040
}
4141

4242
namespace hlsl {
@@ -304,9 +304,10 @@ int ReadDxcOpts(const llvm::opt::OptTable *optionTable, unsigned flagsToInclude,
304304
const MainArgs &argStrings, DxcOpts &opts,
305305
llvm::raw_ostream &errors);
306306

307-
/// Sets up the specified DxcDllSupport instance as per the given options.
308-
int SetupDxcDllSupport(const DxcOpts &opts, dxc::DxcDllSupport &dxcSupport,
309-
llvm::raw_ostream &errors);
307+
/// Sets up a SpecificDllLoader instance as per the given options.
308+
int SetupSpecificDllLoader(const DxcOpts &opts,
309+
dxc::SpecificDllLoader &dxcSupport,
310+
llvm::raw_ostream &errors);
310311

311312
void CopyArgsToWStrings(const llvm::opt::InputArgList &inArgs,
312313
unsigned flagsToInclude,

include/dxc/Support/dxcapi.extval.h

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
#include "dxc/Support/dxcapi.use.h"
2+
#include <cassert>
3+
#include <string>
4+
5+
namespace dxc {
6+
class DxcDllExtValidationLoader : public DllLoader {
7+
// DxCompilerSupport manages the
8+
// lifetime of dxcompiler.dll, while DxilExtValSupport
9+
// manages the lifetime of dxil.dll
10+
dxc::SpecificDllLoader DxCompilerSupport;
11+
dxc::SpecificDllLoader DxilExtValSupport;
12+
std::string DxilDllPath;
13+
14+
public:
15+
std::string GetDxilDllPath() { return DxilDllPath; }
16+
bool DxilDllFailedToLoad() {
17+
return !DxilDllPath.empty() && !DxilExtValSupport.IsEnabled();
18+
}
19+
20+
HRESULT CreateInstanceImpl(REFCLSID clsid, REFIID riid,
21+
IUnknown **pResult) override;
22+
HRESULT CreateInstance2Impl(IMalloc *pMalloc, REFCLSID clsid, REFIID riid,
23+
IUnknown **pResult) override;
24+
25+
HRESULT Initialize();
26+
27+
bool IsEnabled() const override { return DxCompilerSupport.IsEnabled(); }
28+
};
29+
} // namespace dxc

include/dxc/Support/dxcapi.use.h

Lines changed: 83 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -19,9 +19,47 @@ namespace dxc {
1919
extern const char *kDxCompilerLib;
2020
extern const char *kDxilLib;
2121

22-
// Helper class to dynamically load the dxcompiler or a compatible libraries.
23-
class DxcDllSupport {
22+
// Interface for common dll operations
23+
class DllLoader {
24+
2425
protected:
26+
virtual HRESULT CreateInstanceImpl(REFCLSID clsid, REFIID riid,
27+
IUnknown **pResult) = 0;
28+
virtual HRESULT CreateInstance2Impl(IMalloc *pMalloc, REFCLSID clsid,
29+
REFIID riid, IUnknown **pResult) = 0;
30+
virtual ~DllLoader() {}
31+
32+
public:
33+
DllLoader() = default;
34+
DllLoader(const DllLoader &) = delete;
35+
DllLoader(DllLoader &&) = delete;
36+
37+
template <typename TInterface>
38+
HRESULT CreateInstance(REFCLSID clsid, TInterface **pResult) {
39+
return CreateInstanceImpl(clsid, __uuidof(TInterface),
40+
(IUnknown **)pResult);
41+
}
42+
HRESULT CreateInstance(REFCLSID clsid, REFIID riid, IUnknown **pResult) {
43+
return CreateInstanceImpl(clsid, riid, (IUnknown **)pResult);
44+
}
45+
46+
template <typename TInterface>
47+
HRESULT CreateInstance2(IMalloc *pMalloc, REFCLSID clsid,
48+
TInterface **pResult) {
49+
return CreateInstance2Impl(pMalloc, clsid, __uuidof(TInterface),
50+
(IUnknown **)pResult);
51+
}
52+
HRESULT CreateInstance2(IMalloc *pMalloc, REFCLSID clsid, REFIID riid,
53+
IUnknown **pResult) {
54+
return CreateInstance2Impl(pMalloc, clsid, riid, (IUnknown **)pResult);
55+
}
56+
57+
virtual bool IsEnabled() const = 0;
58+
};
59+
60+
// Helper class to dynamically load the dxcompiler or a compatible libraries.
61+
class SpecificDllLoader : public DllLoader {
62+
2563
HMODULE m_dll;
2664
DxcCreateInstanceProc m_createFn;
2765
DxcCreateInstance2Proc m_createFn2;
@@ -74,33 +112,19 @@ class DxcDllSupport {
74112
}
75113

76114
public:
77-
DxcDllSupport() : m_dll(nullptr), m_createFn(nullptr), m_createFn2(nullptr) {}
78-
79-
DxcDllSupport(DxcDllSupport &&other) {
80-
m_dll = other.m_dll;
81-
other.m_dll = nullptr;
82-
m_createFn = other.m_createFn;
83-
other.m_createFn = nullptr;
84-
m_createFn2 = other.m_createFn2;
85-
other.m_createFn2 = nullptr;
86-
}
115+
SpecificDllLoader()
116+
: m_dll(nullptr), m_createFn(nullptr), m_createFn2(nullptr) {}
87117

88-
~DxcDllSupport() { Cleanup(); }
89-
90-
HRESULT Initialize() {
91-
return InitializeInternal(kDxCompilerLib, "DxcCreateInstance");
92-
}
118+
~SpecificDllLoader() override { Cleanup(); }
93119

94120
HRESULT InitializeForDll(LPCSTR dll, LPCSTR entryPoint) {
95121
return InitializeInternal(dll, entryPoint);
96122
}
97123

98-
template <typename TInterface>
99-
HRESULT CreateInstance(REFCLSID clsid, TInterface **pResult) {
100-
return CreateInstance(clsid, __uuidof(TInterface), (IUnknown **)pResult);
101-
}
102-
103-
HRESULT CreateInstance(REFCLSID clsid, REFIID riid, IUnknown **pResult) {
124+
// Also bring visibility into the interface definition of this function
125+
// which takes 2 args
126+
HRESULT CreateInstanceImpl(REFCLSID clsid, REFIID riid,
127+
IUnknown **pResult) override {
104128
if (pResult == nullptr)
105129
return E_POINTER;
106130
if (m_dll == nullptr)
@@ -109,15 +133,10 @@ class DxcDllSupport {
109133
return hr;
110134
}
111135

112-
template <typename TInterface>
113-
HRESULT CreateInstance2(IMalloc *pMalloc, REFCLSID clsid,
114-
TInterface **pResult) {
115-
return CreateInstance2(pMalloc, clsid, __uuidof(TInterface),
116-
(IUnknown **)pResult);
117-
}
118-
119-
HRESULT CreateInstance2(IMalloc *pMalloc, REFCLSID clsid, REFIID riid,
120-
IUnknown **pResult) {
136+
// Also bring visibility into the interface definition of this function
137+
// which takes 3 args
138+
HRESULT CreateInstance2Impl(IMalloc *pMalloc, REFCLSID clsid, REFIID riid,
139+
IUnknown **pResult) override {
121140
if (pResult == nullptr)
122141
return E_POINTER;
123142
if (m_dll == nullptr)
@@ -130,7 +149,16 @@ class DxcDllSupport {
130149

131150
bool HasCreateWithMalloc() const { return m_createFn2 != nullptr; }
132151

133-
bool IsEnabled() const { return m_dll != nullptr; }
152+
bool IsEnabled() const override { return m_dll != nullptr; }
153+
154+
bool GetCreateInstanceProcs(DxcCreateInstanceProc *pCreateFn,
155+
DxcCreateInstance2Proc *pCreateFn2) const {
156+
if (pCreateFn == nullptr || pCreateFn2 == nullptr || m_createFn == nullptr)
157+
return false;
158+
*pCreateFn = m_createFn;
159+
*pCreateFn2 = m_createFn2;
160+
return true;
161+
}
134162

135163
void Cleanup() {
136164
if (m_dll != nullptr) {
@@ -152,6 +180,26 @@ class DxcDllSupport {
152180
}
153181
};
154182

183+
// This class is for instances where we *only* expect
184+
// to load dxcompiler.dll, and nothing else
185+
class DxCompilerDllLoader : public SpecificDllLoader {
186+
public:
187+
HRESULT Initialize() {
188+
return InitializeForDll(kDxCompilerLib, "DxcCreateInstance");
189+
}
190+
};
191+
192+
// This class is for instances where we want to load a
193+
// subset of any dlls that would give DxcLibrary functionality.
194+
// e.g, load a IDxcLibrary object.
195+
// Includes but isn't limited to dxcompiler.dll and dxil.dll
196+
class DXCLibraryDllLoader : public SpecificDllLoader {
197+
public:
198+
HRESULT Initialize() {
199+
return InitializeForDll(kDxCompilerLib, "DxcCreateInstance");
200+
}
201+
};
202+
155203
inline DxcDefine GetDefine(LPCWSTR name, LPCWSTR value) {
156204
DxcDefine result;
157205
result.Name = name;
@@ -162,8 +210,8 @@ inline DxcDefine GetDefine(LPCWSTR name, LPCWSTR value) {
162210
// Checks an HRESULT and formats an error message with the appended data.
163211
void IFT_Data(HRESULT hr, LPCWSTR data);
164212

165-
void EnsureEnabled(DxcDllSupport &dxcSupport);
166-
void ReadFileIntoBlob(DxcDllSupport &dxcSupport, LPCWSTR pFileName,
213+
void EnsureEnabled(DXCLibraryDllLoader &dxcSupport);
214+
void ReadFileIntoBlob(DllLoader &dxcSupport, LPCWSTR pFileName,
167215
IDxcBlobEncoding **ppBlobEncoding);
168216
void WriteBlobToConsole(IDxcBlob *pBlob, DWORD streamType = STD_OUTPUT_HANDLE);
169217
void WriteBlobToFile(IDxcBlob *pBlob, LPCWSTR pFileName, UINT32 textCodePage);

include/dxc/Test/CompilationResult.h

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -101,11 +101,9 @@ class TrivialDxcUnsavedFile : public IDxcUnsavedFile {
101101
}
102102
};
103103

104-
class HlslIntellisenseSupport : public dxc::DxcDllSupport {
104+
class HlslIntellisenseSupport : public dxc::DxCompilerDllLoader {
105105
public:
106106
HlslIntellisenseSupport() {}
107-
HlslIntellisenseSupport(HlslIntellisenseSupport &&other)
108-
: dxc::DxcDllSupport(std::move(other)) {}
109107

110108
HRESULT CreateIntellisense(IDxcIntelliSense **pResult) {
111109
return CreateInstance(CLSID_DxcIntelliSense, pResult);

include/dxc/Test/DxcTestUtils.h

Lines changed: 30 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -109,11 +109,11 @@ class FileRunCommandPart {
109109
FileRunCommandPart(const FileRunCommandPart &) = default;
110110
FileRunCommandPart(FileRunCommandPart &&) = default;
111111

112-
FileRunCommandResult Run(dxc::DxcDllSupport &DllSupport,
112+
FileRunCommandResult Run(dxc::DllLoader &DllSupport,
113113
const FileRunCommandResult *Prior,
114114
PluginToolsPaths *pPluginToolsPaths = nullptr,
115115
LPCWSTR dumpName = nullptr);
116-
FileRunCommandResult RunHashTests(dxc::DxcDllSupport &DllSupport);
116+
FileRunCommandResult RunHashTests(dxc::DllLoader &DllSupport);
117117

118118
FileRunCommandResult ReadOptsForDxc(hlsl::options::MainArgs &argStrings,
119119
hlsl::options::DxcOpts &Opts,
@@ -127,30 +127,30 @@ class FileRunCommandPart {
127127
private:
128128
FileRunCommandResult RunFileChecker(const FileRunCommandResult *Prior,
129129
LPCWSTR dumpName = nullptr);
130-
FileRunCommandResult RunDxc(dxc::DxcDllSupport &DllSupport,
130+
FileRunCommandResult RunDxc(dxc::DllLoader &DllSupport,
131131
const FileRunCommandResult *Prior);
132-
FileRunCommandResult RunDxv(dxc::DxcDllSupport &DllSupport,
132+
FileRunCommandResult RunDxv(dxc::DllLoader &DllSupport,
133133
const FileRunCommandResult *Prior);
134-
FileRunCommandResult RunOpt(dxc::DxcDllSupport &DllSupport,
134+
FileRunCommandResult RunOpt(dxc::DllLoader &DllSupport,
135135
const FileRunCommandResult *Prior);
136-
FileRunCommandResult RunListParts(dxc::DxcDllSupport &DllSupport,
136+
FileRunCommandResult RunListParts(dxc::DllLoader &DllSupport,
137137
const FileRunCommandResult *Prior);
138-
FileRunCommandResult RunD3DReflect(dxc::DxcDllSupport &DllSupport,
138+
FileRunCommandResult RunD3DReflect(dxc::DllLoader &DllSupport,
139139
const FileRunCommandResult *Prior);
140-
FileRunCommandResult RunDxr(dxc::DxcDllSupport &DllSupport,
140+
FileRunCommandResult RunDxr(dxc::DllLoader &DllSupport,
141141
const FileRunCommandResult *Prior);
142-
FileRunCommandResult RunLink(dxc::DxcDllSupport &DllSupport,
142+
FileRunCommandResult RunLink(dxc::DllLoader &DllSupport,
143143
const FileRunCommandResult *Prior);
144144
FileRunCommandResult RunTee(const FileRunCommandResult *Prior);
145145
FileRunCommandResult RunXFail(const FileRunCommandResult *Prior);
146-
FileRunCommandResult RunDxilVer(dxc::DxcDllSupport &DllSupport,
146+
FileRunCommandResult RunDxilVer(dxc::DllLoader &DllSupport,
147147
const FileRunCommandResult *Prior);
148-
FileRunCommandResult RunDxcHashTest(dxc::DxcDllSupport &DllSupport);
148+
FileRunCommandResult RunDxcHashTest(dxc::DllLoader &DllSupport);
149149
FileRunCommandResult RunFromPath(const std::string &path,
150150
const FileRunCommandResult *Prior);
151151
FileRunCommandResult RunFileCompareText(const FileRunCommandResult *Prior);
152152
#ifdef _WIN32
153-
FileRunCommandResult RunFxc(dxc::DxcDllSupport &DllSupport,
153+
FileRunCommandResult RunFxc(dxc::DllLoader &DllSupport,
154154
const FileRunCommandResult *Prior);
155155
#endif
156156

@@ -175,12 +175,12 @@ class FileRunTestResult {
175175
PluginToolsPaths *pPluginToolsPaths = nullptr,
176176
LPCWSTR dumpName = nullptr);
177177
static FileRunTestResult
178-
RunFromFileCommands(LPCWSTR fileName, dxc::DxcDllSupport &dllSupport,
178+
RunFromFileCommands(LPCWSTR fileName, dxc::DxCompilerDllLoader &dllSupport,
179179
PluginToolsPaths *pPluginToolsPaths = nullptr,
180180
LPCWSTR dumpName = nullptr);
181181
};
182182

183-
void AssembleToContainer(dxc::DxcDllSupport &dllSupport, IDxcBlob *pModule,
183+
void AssembleToContainer(dxc::DllLoader &dllSupport, IDxcBlob *pModule,
184184
IDxcBlob **pContainer);
185185
std::string BlobToUtf8(IDxcBlob *pBlob);
186186
std::wstring BlobToWide(IDxcBlob *pBlob);
@@ -195,36 +195,34 @@ bool CheckMsgs(const LPCSTR pText, size_t TextCount, const LPCSTR *pErrorMsgs,
195195
size_t errorMsgCount, bool bRegex);
196196
bool CheckNotMsgs(const LPCSTR pText, size_t TextCount,
197197
const LPCSTR *pErrorMsgs, size_t errorMsgCount, bool bRegex);
198-
void GetDxilPart(dxc::DxcDllSupport &dllSupport, IDxcBlob *pProgram,
198+
void GetDxilPart(dxc::DllLoader &dllSupport, IDxcBlob *pProgram,
199199
IDxcBlob **pDxilPart);
200-
std::string DisassembleProgram(dxc::DxcDllSupport &dllSupport,
200+
std::string DisassembleProgram(dxc::DxCompilerDllLoader &dllSupport,
201201
IDxcBlob *pProgram);
202202
void SplitPassList(LPWSTR pPassesBuffer, std::vector<LPCWSTR> &passes);
203-
void MultiByteStringToBlob(dxc::DxcDllSupport &dllSupport,
204-
const std::string &val, UINT32 codePoint,
205-
IDxcBlob **ppBlob);
206-
void MultiByteStringToBlob(dxc::DxcDllSupport &dllSupport,
207-
const std::string &val, UINT32 codePoint,
208-
IDxcBlobEncoding **ppBlob);
209-
void Utf8ToBlob(dxc::DxcDllSupport &dllSupport, const std::string &val,
203+
void MultiByteStringToBlob(dxc::DllLoader &dllSupport, const std::string &val,
204+
UINT32 codePoint, IDxcBlob **ppBlob);
205+
void MultiByteStringToBlob(dxc::DllLoader &dllSupport, const std::string &val,
206+
UINT32 codePoint, IDxcBlobEncoding **ppBlob);
207+
void Utf8ToBlob(dxc::DllLoader &dllSupport, const std::string &val,
210208
IDxcBlob **ppBlob);
211-
void Utf8ToBlob(dxc::DxcDllSupport &dllSupport, const std::string &val,
209+
void Utf8ToBlob(dxc::DllLoader &dllSupport, const std::string &val,
212210
IDxcBlobEncoding **ppBlob);
213-
void Utf8ToBlob(dxc::DxcDllSupport &dllSupport, const char *pVal,
211+
void Utf8ToBlob(dxc::DllLoader &dllSupport, const char *pVal,
214212
IDxcBlobEncoding **ppBlob);
215-
void WideToBlob(dxc::DxcDllSupport &dllSupport, const std::wstring &val,
213+
void WideToBlob(dxc::DllLoader &dllSupport, const std::wstring &val,
216214
IDxcBlob **ppBlob);
217-
void WideToBlob(dxc::DxcDllSupport &dllSupport, const std::wstring &val,
215+
void WideToBlob(dxc::DllLoader &dllSupport, const std::wstring &val,
218216
IDxcBlobEncoding **ppBlob);
219-
void VerifyCompileOK(dxc::DxcDllSupport &dllSupport, LPCSTR pText,
217+
void VerifyCompileOK(dxc::DllLoader &dllSupport, LPCSTR pText,
220218
LPCWSTR pTargetProfile, LPCWSTR pArgs,
221219
IDxcBlob **ppResult);
222-
void VerifyCompileOK(dxc::DxcDllSupport &dllSupport, LPCSTR pText,
220+
void VerifyCompileOK(dxc::DllLoader &dllSupport, LPCSTR pText,
223221
LPCWSTR pTargetProfile, std::vector<LPCWSTR> &args,
224222
IDxcBlob **ppResult);
225223

226-
HRESULT GetVersion(dxc::DxcDllSupport &DllSupport, REFCLSID clsid,
227-
unsigned &Major, unsigned &Minor);
224+
HRESULT GetVersion(dxc::DllLoader &DllSupport, REFCLSID clsid, unsigned &Major,
225+
unsigned &Minor);
228226
bool ParseTargetProfile(llvm::StringRef targetProfile,
229227
llvm::StringRef &outStage, unsigned &outMajor,
230228
unsigned &outMinor);
@@ -240,7 +238,7 @@ class VersionSupportInfo {
240238

241239
VersionSupportInfo();
242240
// Initialize version info structure. TODO: add device shader model support
243-
void Initialize(dxc::DxcDllSupport &dllSupport);
241+
void Initialize(dxc::DllLoader &dllSupport);
244242
// Return true if IR sensitive test should be skipped, and log comment
245243
bool SkipIRSensitiveTest();
246244
// Return true if test requiring DXIL of given version should be skipped, and

lib/DxcSupport/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ add_llvm_library(LLVMDxcSupport
1010
WinAdapter.cpp
1111
WinIncludes.cpp
1212
WinFunctions.cpp
13+
dxcapi.extval.cpp
1314
)
1415

1516
#generate header with platform-specific library name

lib/DxcSupport/HLSLOptions.cpp

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1383,9 +1383,10 @@ int ReadDxcOpts(const OptTable *optionTable, unsigned flagsToInclude,
13831383
return 0;
13841384
}
13851385

1386-
/// Sets up the specified DxcDllSupport instance as per the given options.
1387-
int SetupDxcDllSupport(const DxcOpts &opts, dxc::DxcDllSupport &dxcSupport,
1388-
llvm::raw_ostream &errors) {
1386+
/// Sets up a SpecificDllLoader instance as per the given options.
1387+
int SetupSpecificDllLoader(const DxcOpts &opts,
1388+
dxc::SpecificDllLoader &dxcSupport,
1389+
llvm::raw_ostream &errors) {
13891390
if (!opts.ExternalLib.empty()) {
13901391
DXASSERT(!opts.ExternalFn.empty(), "else ReadDxcOpts should have failed");
13911392
HRESULT hrLoad = dxcSupport.InitializeForDll(opts.ExternalLib.data(),

0 commit comments

Comments
 (0)