[lld] f95ed69 - Implement /driver, /driver:wdm and /driver:uponly
Rui Ueyama via llvm-commits
llvm-commits at lists.llvm.org
Wed Nov 13 20:11:09 PST 2019
Author: Rui Ueyama
Date: 2019-11-14T13:07:56+09:00
New Revision: f95ed69641d5431a3789e7ea5d4f7837eaae18f3
URL: https://github.com/llvm/llvm-project/commit/f95ed69641d5431a3789e7ea5d4f7837eaae18f3
DIFF: https://github.com/llvm/llvm-project/commit/f95ed69641d5431a3789e7ea5d4f7837eaae18f3.diff
LOG: 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
Added:
lld/test/COFF/driver-opt.s
Modified:
lld/COFF/Config.h
lld/COFF/Driver.cpp
lld/COFF/Options.td
lld/COFF/Writer.cpp
Removed:
################################################################################
diff --git a/lld/COFF/Config.h b/lld/COFF/Config.h
index 07fa48b3ebc1..2690ea5c4082 100644
--- a/lld/COFF/Config.h
+++ b/lld/COFF/Config.h
@@ -103,6 +103,9 @@ struct Configuration {
bool debugDwarf = false;
bool debugGHashes = false;
bool debugSymtab = false;
+ bool driver = false;
+ bool driverUponly = false;
+ bool driverWdm = false;
bool showTiming = false;
bool showSummary = false;
unsigned debugTypes = static_cast<unsigned>(DebugType::None);
diff --git a/lld/COFF/Driver.cpp b/lld/COFF/Driver.cpp
index 29c3fe7922fc..05d60428d260 100644
--- a/lld/COFF/Driver.cpp
+++ b/lld/COFF/Driver.cpp
@@ -102,9 +102,16 @@ static std::pair<StringRef, StringRef> getOldNewOptions(opt::InputArgList &args,
return ret;
}
-// Drop directory components and replace extension with ".exe" or ".dll".
+// Drop directory components and replace extension with
+// ".exe", ".dll" or ".sys".
static std::string getOutputPath(StringRef path) {
- return (sys::path::stem(path) + (config->dll ? ".dll" : ".exe")).str();
+ StringRef ext = ".exe";
+ if (config->dll)
+ ext = ".dll";
+ else if (config->driver)
+ ext = ".sys";
+
+ return (sys::path::stem(path) + ext).str();
}
// Returns true if S matches /crtend.?\.o$/.
@@ -1229,6 +1236,16 @@ void LinkerDriver::link(ArrayRef<const char *> argsArr) {
// Handle /debugtype
config->debugTypes = parseDebugTypes(args);
+ // Handle /driver[:uponly|:wdm].
+ config->driverUponly = args.hasArg(OPT_driver_uponly) ||
+ args.hasArg(OPT_driver_uponly_wdm) ||
+ args.hasArg(OPT_driver_wdm_uponly);
+ config->driverWdm = args.hasArg(OPT_driver_wdm) ||
+ args.hasArg(OPT_driver_uponly_wdm) ||
+ args.hasArg(OPT_driver_wdm_uponly);
+ config->driver =
+ config->driverUponly || config->driverWdm || args.hasArg(OPT_driver);
+
// Handle /pdb
bool shouldCreatePDB =
(debug == DebugKind::Full || debug == DebugKind::GHash);
@@ -1703,6 +1720,9 @@ void LinkerDriver::link(ArrayRef<const char *> argsArr) {
StringRef s = (config->machine == I386) ? "__DllMainCRTStartup at 12"
: "_DllMainCRTStartup";
config->entry = addUndefined(s);
+ } else if (config->driverWdm) {
+ // /driver:wdm implies /entry:_NtProcessStartup
+ config->entry = addUndefined(mangle("_NtProcessStartup"));
} else {
// Windows specific -- If entry point name is not given, we need to
// infer that from user-defined entry name.
diff --git a/lld/COFF/Options.td b/lld/COFF/Options.td
index 9e58d92e634f..468e4da7d054 100644
--- a/lld/COFF/Options.td
+++ b/lld/COFF/Options.td
@@ -104,7 +104,13 @@ def debug : F<"debug">, HelpText<"Embed a symbol table in the image">;
def debug_opt : P<"debug", "Embed a symbol table in the image with option">;
def debugtype : P<"debugtype", "Debug Info Options">;
def dll : F<"dll">, HelpText<"Create a DLL">;
-def driver : P<"driver", "Generate a Windows NT Kernel Mode Driver">;
+def driver : F<"driver">, HelpText<"Generate a Windows NT Kernel Mode Driver">;
+def driver_wdm : F<"driver:wdm">,
+ HelpText<"Set IMAGE_FILE_UP_SYSTEM_ONLY bit in PE header">;
+def driver_uponly : F<"driver:uponly">,
+ HelpText<"Set IMAGE_DLL_CHARACTERISTICS_WDM_DRIVER bit in PE header">;
+def driver_wdm_uponly : F<"driver:wdm,uponly">;
+def driver_uponly_wdm : F<"driver:uponly,wdm">;
def nodefaultlib_all : F<"nodefaultlib">,
HelpText<"Remove all default libraries">;
def noentry : F<"noentry">,
diff --git a/lld/COFF/Writer.cpp b/lld/COFF/Writer.cpp
index 9638f4202e06..9d912d339bcc 100644
--- a/lld/COFF/Writer.cpp
+++ b/lld/COFF/Writer.cpp
@@ -1304,6 +1304,8 @@ template <typename PEHeaderTy> void Writer::writeHeader() {
coff->Characteristics |= IMAGE_FILE_32BIT_MACHINE;
if (config->dll)
coff->Characteristics |= IMAGE_FILE_DLL;
+ if (config->driverUponly)
+ coff->Characteristics |= IMAGE_FILE_UP_SYSTEM_ONLY;
if (!config->relocatable)
coff->Characteristics |= IMAGE_FILE_RELOCS_STRIPPED;
if (config->swaprunCD)
@@ -1351,6 +1353,8 @@ template <typename PEHeaderTy> void Writer::writeHeader() {
pe->SizeOfHeapCommit = config->heapCommit;
if (config->appContainer)
pe->DLLCharacteristics |= IMAGE_DLL_CHARACTERISTICS_APPCONTAINER;
+ if (config->driverWdm)
+ pe->DLLCharacteristics |= IMAGE_DLL_CHARACTERISTICS_WDM_DRIVER;
if (config->dynamicBase)
pe->DLLCharacteristics |= IMAGE_DLL_CHARACTERISTICS_DYNAMIC_BASE;
if (config->highEntropyVA)
diff --git a/lld/test/COFF/driver-opt.s b/lld/test/COFF/driver-opt.s
new file mode 100644
index 000000000000..72459d6bb590
--- /dev/null
+++ b/lld/test/COFF/driver-opt.s
@@ -0,0 +1,98 @@
+# RUN: mkdir -p %t.dir
+# RUN: yaml2obj < %s > %t.dir/foo.obj
+
+# RUN: rm -f %t.dir/foo.sys
+# RUN: cd %t.dir; lld-link /driver foo.obj
+# RUN: llvm-readobj --file-headers %t.dir/foo.sys | FileCheck -check-prefix=DRIVER %s
+
+# DRIVER-NOT: IMAGE_FILE_UP_SYSTEM_ONLY
+# DRIVER-NOT: IMAGE_DLL_CHARACTERISTICS_WDM_DRIVER
+# DRIVER: AddressOfEntryPoint: 0x1000
+
+# RUN: rm -f %t.dir/foo.sys
+# RUN: cd %t.dir; lld-link /driver:uponly foo.obj
+# RUN: llvm-readobj --file-headers %t.dir/foo.sys | FileCheck -check-prefix=UPONLY %s
+
+# UPONLY: IMAGE_FILE_UP_SYSTEM_ONLY
+# UPONLY: AddressOfEntryPoint: 0x1000
+
+# RUN: rm -f %t.dir/foo.sys
+# RUN: cd %t.dir; lld-link /driver:wdm foo.obj
+# RUN: llvm-readobj --file-headers %t.dir/foo.sys | FileCheck -check-prefix=WDM %s
+
+# WDM: AddressOfEntryPoint: 0x1004
+# WDM: IMAGE_DLL_CHARACTERISTICS_WDM_DRIVER
+
+# RUN: rm -f %t.dir/foo.sys
+# RUN: cd %t.dir; lld-link /driver:wdm,uponly foo.obj
+# RUN: llvm-readobj --file-headers %t.dir/foo.sys | FileCheck -check-prefix=BOTH %s
+
+# RUN: rm -f %t.dir/foo.sys
+# RUN: cd %t.dir; lld-link /driver:uponly,wdm foo.obj
+# RUN: llvm-readobj --file-headers %t.dir/foo.sys | FileCheck -check-prefix=BOTH %s
+
+# BOTH: IMAGE_FILE_UP_SYSTEM_ONLY
+# BOTH: AddressOfEntryPoint: 0x1004
+# BOTH: IMAGE_DLL_CHARACTERISTICS_WDM_DRIVER
+
+# RUN: rm -f %t.dir/foo.sys
+# RUN: cd %t.dir; lld-link /driver foo.obj
+# RUN: llvm-readobj --file-headers %t.dir/foo.sys | FileCheck -check-prefix=FIXED1 %s
+
+# RUN: rm -f %t.dir/foo.sys
+# RUN: cd %t.dir; lld-link /driver foo.obj /fixed:no
+# RUN: llvm-readobj --file-headers %t.dir/foo.sys | FileCheck -check-prefix=FIXED1 %s
+
+# FIXED1: IMAGE_DLL_CHARACTERISTICS_DYNAMIC_BASE
+
+# RUN: rm -f %t.dir/foo.sys
+# RUN: cd %t.dir; lld-link /driver foo.obj /fixed
+# RUN: llvm-readobj --file-headers %t.dir/foo.sys | FileCheck -check-prefix=FIXED2 %s
+
+# FIXED2-NOT: IMAGE_DLL_CHARACTERISTICS_DYNAMIC_BASE
+
+--- !COFF
+header:
+ Machine: IMAGE_FILE_MACHINE_AMD64
+ Characteristics: []
+sections:
+ - Name: .text
+ Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ]
+ Alignment: 4096
+ SectionData: 0000000000000000
+ Relocations:
+ - VirtualAddress: 0
+ SymbolName: __ImageBase
+ Type: IMAGE_REL_AMD64_ADDR64
+symbols:
+ - Name: .text
+ Value: 0
+ SectionNumber: 1
+ SimpleType: IMAGE_SYM_TYPE_NULL
+ ComplexType: IMAGE_SYM_DTYPE_NULL
+ StorageClass: IMAGE_SYM_CLASS_STATIC
+ SectionDefinition:
+ Length: 8
+ NumberOfRelocations: 1
+ NumberOfLinenumbers: 0
+ CheckSum: 0
+ Number: 0
+ - Name: main
+ Value: 0
+ SectionNumber: 1
+ SimpleType: IMAGE_SYM_TYPE_NULL
+ ComplexType: IMAGE_SYM_DTYPE_NULL
+ StorageClass: IMAGE_SYM_CLASS_EXTERNAL
+ - Name: mainCRTStartup
+ Value: 0
+ SectionNumber: 1
+ SimpleType: IMAGE_SYM_TYPE_NULL
+ ComplexType: IMAGE_SYM_DTYPE_NULL
+ StorageClass: IMAGE_SYM_CLASS_EXTERNAL
+ - Name: _NtProcessStartup
+ Value: 4
+ SectionNumber: 1
+ SimpleType: IMAGE_SYM_TYPE_NULL
+ ComplexType: IMAGE_SYM_DTYPE_NULL
+ StorageClass: IMAGE_SYM_CLASS_EXTERNAL
+...
More information about the llvm-commits
mailing list