Skip to content

Commit 9ac44c1

Browse files
authored
Merge pull request #6785 from Arthapz/support-wdk-clang
feat(wdk rules) support clang and llvm for wdk rules
2 parents e47954a + 2f16b3d commit 9ac44c1

File tree

11 files changed

+101
-118
lines changed

11 files changed

+101
-118
lines changed

tests/projects/windows/driver/kmdf/ioctl/exe/testapp.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -213,7 +213,7 @@ GetCoinstallerVersion(
213213

214214
VOID __cdecl
215215
main(
216-
_In_ ULONG argc,
216+
_In_ INT argc,
217217
_In_reads_(argc) PCHAR argv[]
218218
)
219219
{

tests/projects/windows/driver/umdf/skeleton/xmake.lua

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,12 @@ target("UMDFSkeleton")
88
add_files("*.cpp", {rules = "wdk.tracewpp"})
99
add_files("*.rc", "*.inx")
1010
set_values("wdk.umdf.sdkver", "1.9")
11-
add_shflags("/DEF:exports.def", {force = true})
12-
add_shflags("/ENTRY:_DllMainCRTStartup" .. (is_arch("x86") and "@12" or ""), {force = true})
11+
add_files("exports.def")
12+
on_config(function(target)
13+
if target:has_tool("sh", "clang", "clangxx") then
14+
target:add("shflags", "-Wl,/ENTRY:_DllMainCRTStartup" .. (is_arch("x86") and "@12" or ""), {force = true})
15+
else
16+
target:add("shflags", "/ENTRY:_DllMainCRTStartup" .. (is_arch("x86") and "@12" or ""), {force = true})
17+
end
18+
end)
1319

tests/projects/windows/driver/wdm/msdsm/intrface.c

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ Module Name:
3232

3333
#pragma warning (disable:4305)
3434

35+
DSM_INIT_DATA gDsmInitData;
3536

3637
//
3738
// Flag to indicate whether to NT_ASSERT or ignore a particular condition.
@@ -3430,7 +3431,7 @@ Return Value:
34303431

34313432
NTSTATUS
34323433
DsmRemovePath(
3433-
_In_ IN PDSM_CONTEXT DsmContext,
3434+
_In_ IN PVOID _DsmContext,
34343435
_In_ IN PVOID PathId
34353436
)
34363437
/*++
@@ -3456,6 +3457,8 @@ Return Value:
34563457
PDSM_FAILOVER_GROUP failGroup;
34573458
KIRQL irql;
34583459

3460+
PDSM_CONTEXT DsmContext = (PDSM_CONTEXT)_DsmContext;
3461+
34593462
TracePrint((TRACE_LEVEL_VERBOSE,
34603463
TRACE_FLAG_PNP,
34613464
"DsmRemovePath (PathId %p): Entering function.\n",

tests/projects/windows/driver/wdm/msdsm/msdsm.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -115,7 +115,7 @@ Module Name:
115115
//
116116
// Initialization data structure that needs to be filled in for MPIO
117117
//
118-
DSM_INIT_DATA gDsmInitData;
118+
extern DSM_INIT_DATA gDsmInitData;
119119

120120
//
121121
// Macro used to round of a number to the nearest 8 byte aligned one.

tests/projects/windows/driver/wdm/msdsm/prototypes.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -206,7 +206,7 @@ DsmRemoveDevice(
206206

207207
NTSTATUS
208208
DsmRemovePath(
209-
_In_ IN PDSM_CONTEXT DsmContext,
209+
_In_ IN PVOID DsmContext,
210210
_In_ IN PVOID PathId
211211
);
212212

tests/projects/windows/driver/wdm/perfcounters/kcs.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,9 @@ Module Name:
2727
#include "kcs.h"
2828
#include "kcsCounters.h"
2929

30+
#include <stdlib.h>
31+
#include <math.h>
32+
3033
#pragma code_seg("PAGE")
3134

3235
DRIVER_INITIALIZE DriverEntry;

xmake/rules/platform/windows/subsystem/xmake.lua

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ rule("platform.windows.subsystem")
3939
assert(valid, "Invalid subsystem " .. subsystem)
4040

4141
if target:has_tool("ld", "clang", "clangxx", "clang_cl") then
42-
target:add("ldflags", "-Wl,-subsystem:" .. subsystem, { force = true })
42+
target:add("ldflags", "-Xlinker", "-subsystem:" .. subsystem, { force = true })
4343
elseif target:has_tool("ld", "link", "lld-link") then
4444
target:add("ldflags", "/SUBSYSTEM:" .. subsystem:upper(), { force = true })
4545
elseif target:has_tool("ld", "gcc", "gxx") then

xmake/rules/wdk/env/load.lua

Lines changed: 23 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -38,8 +38,7 @@ function _winver_libdir(winver)
3838
return vervals[winver]
3939
end
4040

41-
-- load for umdf environment
42-
function umdf(target)
41+
function _base(target, mode)
4342

4443
-- get wdk
4544
local wdk = target:data("wdk")
@@ -48,7 +47,8 @@ function umdf(target)
4847
local arch = config.arch()
4948

5049
-- add definitions
51-
local umdfver = wdk.umdfver:split('%.')
50+
local ver = mode == "um" and wdk.umdfver or wdk.kmdfver
51+
local ver_split = ver:split('%.')
5252
if arch == "x64" then
5353
target:add("defines", "_WIN64", "_AMD64_", "AMD64")
5454
else
@@ -57,16 +57,27 @@ function umdf(target)
5757
target:add("defines", "STD_CALL")
5858
target:add("cxflags", "-Gz", {force = true})
5959
end
60-
target:add("defines", "UMDF_VERSION_MAJOR=" .. umdfver[1], "UMDF_VERSION_MINOR=" .. umdfver[2], "UMDF_USING_NTSTATUS")
60+
61+
local prefix = mode == "um" and "UM" or "KM"
62+
target:add("defines", prefix .. "DF_VERSION_MAJOR=" .. ver_split[1], prefix .. "DF_VERSION_MINOR=" .. ver_split[2], prefix .. "DF_USING_NTSTATUS")
6163
target:add("defines", "WIN32_LEAN_AND_MEAN=1", "WINNT=1", "_WINDLL")
6264

6365
-- add include directories
64-
target:add("includedirs", path.join(wdk.includedir, wdk.sdkver, "um"))
65-
target:add("includedirs", path.join(wdk.includedir, "wdf", "umdf", wdk.umdfver))
66+
target:add("sysincludedirs", path.join(wdk.includedir, wdk.sdkver, mode))
67+
target:add("sysincludedirs", path.join(wdk.includedir, "wdf", mode .. "df", ver))
6668

6769
-- add link directories
68-
target:add("linkdirs", path.join(wdk.libdir, wdk.sdkver, "um", arch))
69-
target:add("linkdirs", path.join(wdk.libdir, "wdf", "umdf", arch, wdk.umdfver))
70+
target:add("linkdirs", path.join(wdk.libdir, wdk.sdkver, mode, arch))
71+
local p = path.join(wdk.libdir, "wdf", mode .. "df", arch, ver)
72+
if os.isdir(p) then
73+
target:add("linkdirs", p)
74+
end
75+
end
76+
77+
-- load for umdf environment
78+
function umdf(target)
79+
80+
_base(target, "um")
7081
end
7182

7283
-- load for kmdf environment
@@ -80,69 +91,23 @@ function kmdf(target)
8091

8192
-- add definitions
8293
local winver = target:values("wdk.env.winver") or config.get("wdk_winver")
83-
local kmdfver = wdk.kmdfver:split('%.')
84-
if arch == "x64" then
85-
target:add("defines", "_WIN64", "_AMD64_", "AMD64")
86-
else
87-
target:add("defines", "_X86_=1", "i386=1")
88-
target:add("defines", "DEPRECATE_DDK_FUNCTIONS=1", "MSC_NOOPT", "_ATL_NO_WIN_SUPPORT")
89-
target:add("defines", "STD_CALL")
90-
target:add("cxflags", "-Gz", {force = true})
91-
end
92-
target:add("defines", "KMDF_VERSION_MAJOR=" .. kmdfver[1], "KMDF_VERSION_MINOR=" .. kmdfver[2], "KMDF_USING_NTSTATUS")
93-
target:add("defines", "WIN32_LEAN_AND_MEAN=1", "WINNT=1", "_WINDLL")
94+
95+
_base(target, "km")
9496

9597
-- add include directories
96-
target:add("includedirs", path.join(wdk.includedir, wdk.sdkver, "km"))
9798
if target:rule("wdk.driver") then
98-
target:add("includedirs", path.join(wdk.includedir, wdk.sdkver, "km", "crt"))
99+
target:add("sysincludedirs", path.join(wdk.includedir, wdk.sdkver, "km", "crt"))
99100
end
100-
target:add("includedirs", path.join(wdk.includedir, "wdf", "kmdf", wdk.kmdfver))
101101

102102
-- add link directories
103103
local libdirver = _winver_libdir(winver)
104104
if libdirver then
105105
target:add("linkdirs", path.join(wdk.libdir, libdirver, "km", arch))
106106
end
107-
target:add("linkdirs", path.join(wdk.libdir, wdk.sdkver, "km", arch))
108-
target:add("linkdirs", path.join(wdk.libdir, "wdf", "kmdf", arch, wdk.kmdfver))
109107
end
110108

111109
-- load for wdm environment
112110
function wdm(target)
113111

114-
-- get wdk
115-
local wdk = target:data("wdk")
116-
117-
-- get arch
118-
local arch = config.arch()
119-
120-
-- add definitions
121-
local winver = target:values("wdk.env.winver") or config.get("wdk_winver")
122-
local kmdfver = wdk.kmdfver:split('%.')
123-
if arch == "x64" then
124-
target:add("defines", "_WIN64", "_AMD64_", "AMD64")
125-
else
126-
target:add("defines", "_X86_=1", "i386=1")
127-
target:add("defines", "DEPRECATE_DDK_FUNCTIONS=1", "MSC_NOOPT", "_ATL_NO_WIN_SUPPORT")
128-
target:add("defines", "STD_CALL")
129-
target:add("cxflags", "-Gz", {force = true})
130-
end
131-
target:add("defines", "KMDF_VERSION_MAJOR=" .. kmdfver[1], "KMDF_VERSION_MINOR=" .. kmdfver[2], "KMDF_USING_NTSTATUS")
132-
target:add("defines", "WIN32_LEAN_AND_MEAN=1", "WINNT=1", "_WINDLL")
133-
134-
-- add include directories
135-
target:add("includedirs", path.join(wdk.includedir, wdk.sdkver, "km"))
136-
if target:rule("wdk.driver") then
137-
target:add("includedirs", path.join(wdk.includedir, wdk.sdkver, "km", "crt"))
138-
end
139-
target:add("includedirs", path.join(wdk.includedir, "wdf", "kmdf", wdk.kmdfver))
140-
141-
-- add link directories
142-
local libdirver = _winver_libdir(winver)
143-
if libdirver then
144-
target:add("linkdirs", path.join(wdk.libdir, libdirver, "km", arch))
145-
end
146-
target:add("linkdirs", path.join(wdk.libdir, wdk.sdkver, "km", arch))
147-
target:add("linkdirs", path.join(wdk.libdir, "wdf", "kmdf", arch, wdk.kmdfver))
112+
kmdf(target)
148113
end

xmake/rules/wdk/load.lua

Lines changed: 50 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,29 @@
2020

2121
-- imports
2222
import("core.project.config")
23+
import("core.base.semver")
2324
import("os.winver", {alias = "os_winver"})
2425

26+
function _add_linkflags(target, t, ...)
27+
local args = table.pack(...)
28+
if target:has_tool("ld", "clang", "clangxx") then
29+
for i, flag in ipairs(args) do
30+
if type(flag) == "string" then
31+
args[i] = "-Wl," .. flag
32+
end
33+
end
34+
end
35+
target:add(t, table.unpack(args))
36+
end
37+
38+
function _add_ldflags(target, ...)
39+
_add_linkflags(target, "ldflags", ...)
40+
end
41+
42+
function _add_shflags(target, ...)
43+
_add_linkflags(target, "shflags", ...)
44+
end
45+
2546
-- load for umdf driver
2647
function driver_umdf(target)
2748

@@ -30,10 +51,10 @@ function driver_umdf(target)
3051

3152
-- add links
3253
target:add("links", "ntdll", "OneCoreUAP", "mincore", "ucrt")
33-
target:add("shflags", "-NODEFAULTLIB:kernel32.lib", "-NODEFAULTLIB:user32.lib", "-NODEFAULTLIB:libucrt.lib", {force = true})
54+
55+
_add_shflags(target, "-NODEFAULTLIB:kernel32.lib", "-NODEFAULTLIB:user32.lib", "-NODEFAULTLIB:libucrt.lib", {force = true})
3456

3557
-- add subsystem
36-
local winver = target:values("wdk.env.winver") or config.get("wdk_winver")
3758
if not target:values("windows.subsystem") then
3859
target:values_set("windows.subsystem", "windows," .. os_winver.subsystem(winver))
3960
end
@@ -47,13 +68,15 @@ function driver_umdf(target)
4768
break
4869
end
4970
end
50-
if not entry then
71+
72+
-- get wdk
73+
local wdk = target:data("wdk")
74+
if not entry and semver.compare(wdk.umdfver, "2.0") >= 0 then
5175
target:add("links", "WdfDriverStubUm")
5276
end
5377
end
5478

55-
-- load for kmdf driver
56-
function driver_kmdf(target)
79+
function _kernel_driver_base(target, default_entrypoint)
5780

5881
-- set kind
5982
target:set("kind", "binary")
@@ -68,76 +91,52 @@ function driver_kmdf(target)
6891
else
6992
target:add("links", "BufferOverflowK")
7093
end
71-
target:add("links", "ntoskrnl", "hal", "wmilib", "WdfLdr", "ntstrsafe", "wdmsec")
7294

7395
-- compile as kernel driver
74-
target:add("cxflags", "-kernel", {force = true})
75-
target:add("ldflags", "-kernel", "-driver", {force = true})
76-
target:add("ldflags", "-nodefaultlib", {force = true})
96+
if not target:has_tool("cc", "clang", "clangxx") then
97+
target:add("cxflags", "-kernel", {force = true})
98+
else
99+
-- emulate kernel mode https://learn.microsoft.com/en-us/cpp/build/reference/kernel-create-kernel-mode-binary?view=msvc-170
100+
target:add("cxxflags", "-fno-exceptions", "-fno-rtti")
101+
target:add("defines", "_KERNEL_MODE=1")
102+
end
103+
104+
_add_ldflags(target, "-kernel", "-driver", "-nodefaultlib", {force = true})
77105

78106
-- add subsystem
79107
if not target:values("windows.subsystem") then
80108
target:values_set("windows.subsystem", "native," .. os_winver.subsystem(winver))
81109
end
82110

83111
-- set default driver entry if does not exist
84-
local entry = false
112+
local has_entry = false
85113
for _, ldflag in ipairs(target:get("ldflags")) do
86114
if type(ldflag) == "string" then
87115
ldflag = ldflag:lower()
88116
if ldflag:find("[/%-]entry:") then
89-
entry = true
117+
has_entry = true
90118
break
91119
end
92120
end
93121
end
94-
if not entry then
95-
target:add("links", "WdfDriverEntry")
96-
target:add("ldflags", "-entry:FxDriverEntry" .. (is_arch("x86") and "@8" or ""), {force = true})
122+
if not has_entry then
123+
local arch = (target:is_arch("x86") and "@8" or "") target:add("links", "WdfDriverEntry")
124+
_add_ldflags(target, "-entry:" .. default_entrypoint .. arch, {force = true})
97125
end
98126
end
99127

100-
-- load for wdm driver
101-
function driver_wdm(target)
128+
-- load for kmdf driver
129+
function driver_kmdf(target)
102130

103-
-- set kind
104-
target:set("kind", "binary")
131+
target:add("links", "ntoskrnl", "hal", "wmilib", "WdfLdr", "ntstrsafe", "wdmsec")
105132

106-
-- set filename: xxx.sys
107-
target:set("filename", target:basename() .. ".sys")
133+
_kernel_driver_base(target, "FxDriverEntry")
134+
end
108135

109-
-- add links
110-
local winver = target:values("wdk.env.winver") or config.get("wdk_winver")
111-
if winver and os_winver.version(winver) >= os_winver.version("win8") then
112-
target:add("links", "BufferOverflowFastFailK")
113-
else
114-
target:add("links", "BufferOverflowK")
115-
end
136+
-- load for wdm driver
137+
function driver_wdm(target)
116138
target:add("links", "ntoskrnl", "hal", "wmilib", "ntstrsafe")
117139

118-
-- compile as kernel driver
119-
target:add("cxflags", "-kernel", {force = true})
120-
target:add("ldflags", "-kernel", "-driver", {force = true})
121-
target:add("ldflags", "-nodefaultlib", {force = true})
122-
123-
-- add subsystem
124-
if not target:values("windows.subsystem") then
125-
target:values_set("windows.subsystem", "native," .. os_winver.subsystem(winver))
126-
end
127-
128-
-- set default driver entry if does not exist
129-
local entry = false
130-
for _, ldflag in ipairs(target:get("ldflags")) do
131-
if type(ldflag) == "string" then
132-
ldflag = ldflag:lower()
133-
if ldflag:find("[/%-]entry:") then
134-
entry = true
135-
break
136-
end
137-
end
138-
end
139-
if not entry then
140-
target:add("ldflags", "-entry:GsDriverEntry" .. (is_arch("x86") and "@8" or ""), {force = true})
141-
end
140+
_kernel_driver_base(target, "GsDriverEntry")
142141
end
143142

xmake/rules/wdk/man/xmake.lua

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,13 @@ rule("wdk.man")
124124
end
125125
os.vrunv(ctrpp, args)
126126

127+
if target:has_tool("cxx", "clang", "clangxx") then
128+
if resourcefile and os.isfile(resourcefile) then
129+
local content = io.readfile(resourcefile)
130+
io.writefile(resourcefile, content, {encoding = "utf8"})
131+
end
132+
end
133+
127134
-- update files and values to the dependent file
128135
dependinfo.files = {sourcefile}
129136
dependinfo.values = args

0 commit comments

Comments
 (0)