Skip to content

Commit f95ed69

Browse files
committed
Implement /driver, /driver:wdm and /driver:uponly
This patch implements /driver, /driver:wdm and /driver:uponly as described in https://docs.microsoft.com/en-us/cpp/build/reference/driver-windows-nt-kernel-mode-driver?view=vs-2019. Differential Revision: https://reviews.llvm.org/D70162
1 parent 70ee430 commit f95ed69

File tree

5 files changed

+134
-3
lines changed

5 files changed

+134
-3
lines changed

lld/COFF/Config.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,9 @@ struct Configuration {
103103
bool debugDwarf = false;
104104
bool debugGHashes = false;
105105
bool debugSymtab = false;
106+
bool driver = false;
107+
bool driverUponly = false;
108+
bool driverWdm = false;
106109
bool showTiming = false;
107110
bool showSummary = false;
108111
unsigned debugTypes = static_cast<unsigned>(DebugType::None);

lld/COFF/Driver.cpp

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -102,9 +102,16 @@ static std::pair<StringRef, StringRef> getOldNewOptions(opt::InputArgList &args,
102102
return ret;
103103
}
104104

105-
// Drop directory components and replace extension with ".exe" or ".dll".
105+
// Drop directory components and replace extension with
106+
// ".exe", ".dll" or ".sys".
106107
static std::string getOutputPath(StringRef path) {
107-
return (sys::path::stem(path) + (config->dll ? ".dll" : ".exe")).str();
108+
StringRef ext = ".exe";
109+
if (config->dll)
110+
ext = ".dll";
111+
else if (config->driver)
112+
ext = ".sys";
113+
114+
return (sys::path::stem(path) + ext).str();
108115
}
109116

110117
// Returns true if S matches /crtend.?\.o$/.
@@ -1229,6 +1236,16 @@ void LinkerDriver::link(ArrayRef<const char *> argsArr) {
12291236
// Handle /debugtype
12301237
config->debugTypes = parseDebugTypes(args);
12311238

1239+
// Handle /driver[:uponly|:wdm].
1240+
config->driverUponly = args.hasArg(OPT_driver_uponly) ||
1241+
args.hasArg(OPT_driver_uponly_wdm) ||
1242+
args.hasArg(OPT_driver_wdm_uponly);
1243+
config->driverWdm = args.hasArg(OPT_driver_wdm) ||
1244+
args.hasArg(OPT_driver_uponly_wdm) ||
1245+
args.hasArg(OPT_driver_wdm_uponly);
1246+
config->driver =
1247+
config->driverUponly || config->driverWdm || args.hasArg(OPT_driver);
1248+
12321249
// Handle /pdb
12331250
bool shouldCreatePDB =
12341251
(debug == DebugKind::Full || debug == DebugKind::GHash);
@@ -1703,6 +1720,9 @@ void LinkerDriver::link(ArrayRef<const char *> argsArr) {
17031720
StringRef s = (config->machine == I386) ? "__DllMainCRTStartup@12"
17041721
: "_DllMainCRTStartup";
17051722
config->entry = addUndefined(s);
1723+
} else if (config->driverWdm) {
1724+
// /driver:wdm implies /entry:_NtProcessStartup
1725+
config->entry = addUndefined(mangle("_NtProcessStartup"));
17061726
} else {
17071727
// Windows specific -- If entry point name is not given, we need to
17081728
// infer that from user-defined entry name.

lld/COFF/Options.td

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,13 @@ def debug : F<"debug">, HelpText<"Embed a symbol table in the image">;
104104
def debug_opt : P<"debug", "Embed a symbol table in the image with option">;
105105
def debugtype : P<"debugtype", "Debug Info Options">;
106106
def dll : F<"dll">, HelpText<"Create a DLL">;
107-
def driver : P<"driver", "Generate a Windows NT Kernel Mode Driver">;
107+
def driver : F<"driver">, HelpText<"Generate a Windows NT Kernel Mode Driver">;
108+
def driver_wdm : F<"driver:wdm">,
109+
HelpText<"Set IMAGE_FILE_UP_SYSTEM_ONLY bit in PE header">;
110+
def driver_uponly : F<"driver:uponly">,
111+
HelpText<"Set IMAGE_DLL_CHARACTERISTICS_WDM_DRIVER bit in PE header">;
112+
def driver_wdm_uponly : F<"driver:wdm,uponly">;
113+
def driver_uponly_wdm : F<"driver:uponly,wdm">;
108114
def nodefaultlib_all : F<"nodefaultlib">,
109115
HelpText<"Remove all default libraries">;
110116
def noentry : F<"noentry">,

lld/COFF/Writer.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1304,6 +1304,8 @@ template <typename PEHeaderTy> void Writer::writeHeader() {
13041304
coff->Characteristics |= IMAGE_FILE_32BIT_MACHINE;
13051305
if (config->dll)
13061306
coff->Characteristics |= IMAGE_FILE_DLL;
1307+
if (config->driverUponly)
1308+
coff->Characteristics |= IMAGE_FILE_UP_SYSTEM_ONLY;
13071309
if (!config->relocatable)
13081310
coff->Characteristics |= IMAGE_FILE_RELOCS_STRIPPED;
13091311
if (config->swaprunCD)
@@ -1351,6 +1353,8 @@ template <typename PEHeaderTy> void Writer::writeHeader() {
13511353
pe->SizeOfHeapCommit = config->heapCommit;
13521354
if (config->appContainer)
13531355
pe->DLLCharacteristics |= IMAGE_DLL_CHARACTERISTICS_APPCONTAINER;
1356+
if (config->driverWdm)
1357+
pe->DLLCharacteristics |= IMAGE_DLL_CHARACTERISTICS_WDM_DRIVER;
13541358
if (config->dynamicBase)
13551359
pe->DLLCharacteristics |= IMAGE_DLL_CHARACTERISTICS_DYNAMIC_BASE;
13561360
if (config->highEntropyVA)

lld/test/COFF/driver-opt.s

Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
# RUN: mkdir -p %t.dir
2+
# RUN: yaml2obj < %s > %t.dir/foo.obj
3+
4+
# RUN: rm -f %t.dir/foo.sys
5+
# RUN: cd %t.dir; lld-link /driver foo.obj
6+
# RUN: llvm-readobj --file-headers %t.dir/foo.sys | FileCheck -check-prefix=DRIVER %s
7+
8+
# DRIVER-NOT: IMAGE_FILE_UP_SYSTEM_ONLY
9+
# DRIVER-NOT: IMAGE_DLL_CHARACTERISTICS_WDM_DRIVER
10+
# DRIVER: AddressOfEntryPoint: 0x1000
11+
12+
# RUN: rm -f %t.dir/foo.sys
13+
# RUN: cd %t.dir; lld-link /driver:uponly foo.obj
14+
# RUN: llvm-readobj --file-headers %t.dir/foo.sys | FileCheck -check-prefix=UPONLY %s
15+
16+
# UPONLY: IMAGE_FILE_UP_SYSTEM_ONLY
17+
# UPONLY: AddressOfEntryPoint: 0x1000
18+
19+
# RUN: rm -f %t.dir/foo.sys
20+
# RUN: cd %t.dir; lld-link /driver:wdm foo.obj
21+
# RUN: llvm-readobj --file-headers %t.dir/foo.sys | FileCheck -check-prefix=WDM %s
22+
23+
# WDM: AddressOfEntryPoint: 0x1004
24+
# WDM: IMAGE_DLL_CHARACTERISTICS_WDM_DRIVER
25+
26+
# RUN: rm -f %t.dir/foo.sys
27+
# RUN: cd %t.dir; lld-link /driver:wdm,uponly foo.obj
28+
# RUN: llvm-readobj --file-headers %t.dir/foo.sys | FileCheck -check-prefix=BOTH %s
29+
30+
# RUN: rm -f %t.dir/foo.sys
31+
# RUN: cd %t.dir; lld-link /driver:uponly,wdm foo.obj
32+
# RUN: llvm-readobj --file-headers %t.dir/foo.sys | FileCheck -check-prefix=BOTH %s
33+
34+
# BOTH: IMAGE_FILE_UP_SYSTEM_ONLY
35+
# BOTH: AddressOfEntryPoint: 0x1004
36+
# BOTH: IMAGE_DLL_CHARACTERISTICS_WDM_DRIVER
37+
38+
# RUN: rm -f %t.dir/foo.sys
39+
# RUN: cd %t.dir; lld-link /driver foo.obj
40+
# RUN: llvm-readobj --file-headers %t.dir/foo.sys | FileCheck -check-prefix=FIXED1 %s
41+
42+
# RUN: rm -f %t.dir/foo.sys
43+
# RUN: cd %t.dir; lld-link /driver foo.obj /fixed:no
44+
# RUN: llvm-readobj --file-headers %t.dir/foo.sys | FileCheck -check-prefix=FIXED1 %s
45+
46+
# FIXED1: IMAGE_DLL_CHARACTERISTICS_DYNAMIC_BASE
47+
48+
# RUN: rm -f %t.dir/foo.sys
49+
# RUN: cd %t.dir; lld-link /driver foo.obj /fixed
50+
# RUN: llvm-readobj --file-headers %t.dir/foo.sys | FileCheck -check-prefix=FIXED2 %s
51+
52+
# FIXED2-NOT: IMAGE_DLL_CHARACTERISTICS_DYNAMIC_BASE
53+
54+
--- !COFF
55+
header:
56+
Machine: IMAGE_FILE_MACHINE_AMD64
57+
Characteristics: []
58+
sections:
59+
- Name: .text
60+
Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ]
61+
Alignment: 4096
62+
SectionData: 0000000000000000
63+
Relocations:
64+
- VirtualAddress: 0
65+
SymbolName: __ImageBase
66+
Type: IMAGE_REL_AMD64_ADDR64
67+
symbols:
68+
- Name: .text
69+
Value: 0
70+
SectionNumber: 1
71+
SimpleType: IMAGE_SYM_TYPE_NULL
72+
ComplexType: IMAGE_SYM_DTYPE_NULL
73+
StorageClass: IMAGE_SYM_CLASS_STATIC
74+
SectionDefinition:
75+
Length: 8
76+
NumberOfRelocations: 1
77+
NumberOfLinenumbers: 0
78+
CheckSum: 0
79+
Number: 0
80+
- Name: main
81+
Value: 0
82+
SectionNumber: 1
83+
SimpleType: IMAGE_SYM_TYPE_NULL
84+
ComplexType: IMAGE_SYM_DTYPE_NULL
85+
StorageClass: IMAGE_SYM_CLASS_EXTERNAL
86+
- Name: mainCRTStartup
87+
Value: 0
88+
SectionNumber: 1
89+
SimpleType: IMAGE_SYM_TYPE_NULL
90+
ComplexType: IMAGE_SYM_DTYPE_NULL
91+
StorageClass: IMAGE_SYM_CLASS_EXTERNAL
92+
- Name: _NtProcessStartup
93+
Value: 4
94+
SectionNumber: 1
95+
SimpleType: IMAGE_SYM_TYPE_NULL
96+
ComplexType: IMAGE_SYM_DTYPE_NULL
97+
StorageClass: IMAGE_SYM_CLASS_EXTERNAL
98+
...

0 commit comments

Comments
 (0)