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
This commit is contained in:
parent
70ee430c6e
commit
f95ed69641
|
|
@ -103,6 +103,9 @@ struct Configuration {
|
||||||
bool debugDwarf = false;
|
bool debugDwarf = false;
|
||||||
bool debugGHashes = false;
|
bool debugGHashes = false;
|
||||||
bool debugSymtab = false;
|
bool debugSymtab = false;
|
||||||
|
bool driver = false;
|
||||||
|
bool driverUponly = false;
|
||||||
|
bool driverWdm = false;
|
||||||
bool showTiming = false;
|
bool showTiming = false;
|
||||||
bool showSummary = false;
|
bool showSummary = false;
|
||||||
unsigned debugTypes = static_cast<unsigned>(DebugType::None);
|
unsigned debugTypes = static_cast<unsigned>(DebugType::None);
|
||||||
|
|
|
||||||
|
|
@ -102,9 +102,16 @@ static std::pair<StringRef, StringRef> getOldNewOptions(opt::InputArgList &args,
|
||||||
return ret;
|
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) {
|
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$/.
|
// Returns true if S matches /crtend.?\.o$/.
|
||||||
|
|
@ -1229,6 +1236,16 @@ void LinkerDriver::link(ArrayRef<const char *> argsArr) {
|
||||||
// Handle /debugtype
|
// Handle /debugtype
|
||||||
config->debugTypes = parseDebugTypes(args);
|
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
|
// Handle /pdb
|
||||||
bool shouldCreatePDB =
|
bool shouldCreatePDB =
|
||||||
(debug == DebugKind::Full || debug == DebugKind::GHash);
|
(debug == DebugKind::Full || debug == DebugKind::GHash);
|
||||||
|
|
@ -1703,6 +1720,9 @@ void LinkerDriver::link(ArrayRef<const char *> argsArr) {
|
||||||
StringRef s = (config->machine == I386) ? "__DllMainCRTStartup@12"
|
StringRef s = (config->machine == I386) ? "__DllMainCRTStartup@12"
|
||||||
: "_DllMainCRTStartup";
|
: "_DllMainCRTStartup";
|
||||||
config->entry = addUndefined(s);
|
config->entry = addUndefined(s);
|
||||||
|
} else if (config->driverWdm) {
|
||||||
|
// /driver:wdm implies /entry:_NtProcessStartup
|
||||||
|
config->entry = addUndefined(mangle("_NtProcessStartup"));
|
||||||
} else {
|
} else {
|
||||||
// Windows specific -- If entry point name is not given, we need to
|
// Windows specific -- If entry point name is not given, we need to
|
||||||
// infer that from user-defined entry name.
|
// infer that from user-defined entry name.
|
||||||
|
|
|
||||||
|
|
@ -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 debug_opt : P<"debug", "Embed a symbol table in the image with option">;
|
||||||
def debugtype : P<"debugtype", "Debug Info Options">;
|
def debugtype : P<"debugtype", "Debug Info Options">;
|
||||||
def dll : F<"dll">, HelpText<"Create a DLL">;
|
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">,
|
def nodefaultlib_all : F<"nodefaultlib">,
|
||||||
HelpText<"Remove all default libraries">;
|
HelpText<"Remove all default libraries">;
|
||||||
def noentry : F<"noentry">,
|
def noentry : F<"noentry">,
|
||||||
|
|
|
||||||
|
|
@ -1304,6 +1304,8 @@ template <typename PEHeaderTy> void Writer::writeHeader() {
|
||||||
coff->Characteristics |= IMAGE_FILE_32BIT_MACHINE;
|
coff->Characteristics |= IMAGE_FILE_32BIT_MACHINE;
|
||||||
if (config->dll)
|
if (config->dll)
|
||||||
coff->Characteristics |= IMAGE_FILE_DLL;
|
coff->Characteristics |= IMAGE_FILE_DLL;
|
||||||
|
if (config->driverUponly)
|
||||||
|
coff->Characteristics |= IMAGE_FILE_UP_SYSTEM_ONLY;
|
||||||
if (!config->relocatable)
|
if (!config->relocatable)
|
||||||
coff->Characteristics |= IMAGE_FILE_RELOCS_STRIPPED;
|
coff->Characteristics |= IMAGE_FILE_RELOCS_STRIPPED;
|
||||||
if (config->swaprunCD)
|
if (config->swaprunCD)
|
||||||
|
|
@ -1351,6 +1353,8 @@ template <typename PEHeaderTy> void Writer::writeHeader() {
|
||||||
pe->SizeOfHeapCommit = config->heapCommit;
|
pe->SizeOfHeapCommit = config->heapCommit;
|
||||||
if (config->appContainer)
|
if (config->appContainer)
|
||||||
pe->DLLCharacteristics |= IMAGE_DLL_CHARACTERISTICS_APPCONTAINER;
|
pe->DLLCharacteristics |= IMAGE_DLL_CHARACTERISTICS_APPCONTAINER;
|
||||||
|
if (config->driverWdm)
|
||||||
|
pe->DLLCharacteristics |= IMAGE_DLL_CHARACTERISTICS_WDM_DRIVER;
|
||||||
if (config->dynamicBase)
|
if (config->dynamicBase)
|
||||||
pe->DLLCharacteristics |= IMAGE_DLL_CHARACTERISTICS_DYNAMIC_BASE;
|
pe->DLLCharacteristics |= IMAGE_DLL_CHARACTERISTICS_DYNAMIC_BASE;
|
||||||
if (config->highEntropyVA)
|
if (config->highEntropyVA)
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
...
|
||||||
Loading…
Reference in New Issue