https://git.reactos.org/?p=reactos.git;a=commitdiff;h=e55123a6a286202dea242…
commit e55123a6a286202dea24269ad35b35ab412d68aa
Author: Jérôme Gardou <jerome.gardou(a)reactos.org>
AuthorDate: Wed Feb 24 11:46:53 2021 +0100
Commit: Jérôme Gardou <zefklop(a)users.noreply.github.com>
CommitDate: Tue Mar 23 11:18:43 2021 +0100
[CMAKE] Add the kernel module type
Take this as an occasion to use target_link_options more
---
sdk/cmake/CMakeMacros.cmake | 99 +++++++++++++++++++++------------------------
sdk/cmake/gcc.cmake | 10 +++--
sdk/cmake/msvc.cmake | 21 ++++++----
sdk/include/host/pecoff.h | 16 ++++++++
sdk/tools/pefixup.c | 48 ++++++++++++++++++----
5 files changed, 124 insertions(+), 70 deletions(-)
diff --git a/sdk/cmake/CMakeMacros.cmake b/sdk/cmake/CMakeMacros.cmake
index 2d5628f02a2..9df6eb608e2 100644
--- a/sdk/cmake/CMakeMacros.cmake
+++ b/sdk/cmake/CMakeMacros.cmake
@@ -541,7 +541,10 @@ function(add_importlibs _module)
endfunction()
# Some helper lists
-list(APPEND KERNEL_MODULE_TYPES kerneldll kernelmodedriver wdmdriver)
+list(APPEND VALID_MODULE_TYPES kernel kerneldll kernelmodedriver wdmdriver nativecui
nativedll win32cui win32gui win32dll win32ocx cpl module)
+list(APPEND KERNEL_MODULE_TYPES kernel kerneldll kernelmodedriver wdmdriver)
+list(APPEND NATIVE_MODULE_TYPES kernel kerneldll kernelmodedriver wdmdriver nativecui
nativedll)
+
function(set_module_type MODULE TYPE)
cmake_parse_arguments(__module "UNICODE" "IMAGEBASE"
"ENTRYPOINT" ${ARGN})
@@ -549,38 +552,34 @@ function(set_module_type MODULE TYPE)
message(STATUS "set_module_type : unparsed arguments
${__module_UNPARSED_ARGUMENTS}, module : ${MODULE}")
endif()
+ # Check this is a type that we know
+ if (NOT TYPE IN_LIST VALID_MODULE_TYPES)
+ message(FATAL_ERROR "Unknown type ${TYPE} for module ${MODULE}")
+ endif()
+
+ # Set our target property
+ set_target_properties(${MODULE} PROPERTIES REACTOS_MODULE_TYPE ${TYPE})
+
# Add the module to the module group list, if it is defined
if(DEFINED CURRENT_MODULE_GROUP)
set_property(GLOBAL APPEND PROPERTY ${CURRENT_MODULE_GROUP}_MODULE_LIST
"${MODULE}")
endif()
- # Set subsystem. Also take this as an occasion
- # to error out if someone gave a non existing type
- if((${TYPE} STREQUAL nativecui) OR (${TYPE} STREQUAL nativedll)
- OR (${TYPE} STREQUAL kernelmodedriver) OR (${TYPE} STREQUAL wdmdriver) OR
(${TYPE} STREQUAL kerneldll))
- set(__subsystem native)
+ # Set subsystem.
+ if(TYPE IN_LIST NATIVE_MODULE_TYPES)
+ set_subsystem(${MODULE} native)
elseif(${TYPE} STREQUAL win32cui)
- set(__subsystem console)
+ set_subsystem(${MODULE} console)
elseif(${TYPE} STREQUAL win32gui)
- set(__subsystem windows)
- elseif(NOT ((${TYPE} STREQUAL win32dll) OR (${TYPE} STREQUAL win32ocx)
- OR (${TYPE} STREQUAL cpl) OR (${TYPE} STREQUAL module)))
- message(FATAL_ERROR "Unknown type ${TYPE} for module ${MODULE}")
- endif()
-
- # Set our target property
- set_target_properties(${MODULE} PROPERTIES REACTOS_MODULE_TYPE ${TYPE})
-
- if(DEFINED __subsystem)
- set_subsystem(${MODULE} ${__subsystem})
+ set_subsystem(${MODULE} windows)
endif()
# Set the PE image version numbers from the NT OS version ReactOS is based on
if(MSVC)
- add_target_link_flags(${MODULE} "/VERSION:5.01")
+ target_link_options(${MODULE} PRIVATE "/VERSION:5.01")
else()
- add_target_link_flags(${MODULE} "-Wl,--major-image-version,5
-Wl,--minor-image-version,01")
- add_target_link_flags(${MODULE} "-Wl,--major-os-version,5
-Wl,--minor-os-version,01")
+ target_link_options(${MODULE} PRIVATE
+ -Wl,--major-image-version,5 -Wl,--minor-image-version,01
-Wl,--major-os-version,5 -Wl,--minor-os-version,01)
endif()
# Set unicode definitions
@@ -590,49 +589,32 @@ function(set_module_type MODULE TYPE)
# Set entry point
if(__module_ENTRYPOINT OR (__module_ENTRYPOINT STREQUAL "0"))
- list(GET __module_ENTRYPOINT 0 __entrypoint)
- list(LENGTH __module_ENTRYPOINT __length)
- if(${__length} EQUAL 2)
- list(GET __module_ENTRYPOINT 1 __entrystack)
- elseif(NOT ${__length} EQUAL 1)
- message(FATAL_ERROR "Wrong arguments for ENTRYPOINT parameter of
set_module_type : ${__module_ENTRYPOINT}")
- endif()
- unset(__length)
+ set_entrypoint(${MODULE} ${__module_ENTRYPOINT})
elseif(${TYPE} STREQUAL nativecui)
- set(__entrypoint NtProcessStartup)
- set(__entrystack 4)
+ set_entrypoint(${MODULE} NtProcessStartup 4)
elseif(${TYPE} STREQUAL win32cui)
if(__module_UNICODE)
- set(__entrypoint wmainCRTStartup)
+ set_entrypoint(${MODULE} wmainCRTStartup)
else()
- set(__entrypoint mainCRTStartup)
+ set_entrypoint(${MODULE} mainCRTStartup)
endif()
elseif(${TYPE} STREQUAL win32gui)
if(__module_UNICODE)
- set(__entrypoint wWinMainCRTStartup)
+ set_entrypoint(${MODULE} wWinMainCRTStartup)
else()
- set(__entrypoint WinMainCRTStartup)
+ set_entrypoint(${MODULE} WinMainCRTStartup)
endif()
elseif((${TYPE} STREQUAL win32dll) OR (${TYPE} STREQUAL win32ocx)
OR (${TYPE} STREQUAL cpl))
- set(__entrypoint DllMainCRTStartup)
- set(__entrystack 12)
+ set_entrypoint(${MODULE} DllMainCRTStartup 12)
elseif((${TYPE} STREQUAL kernelmodedriver) OR (${TYPE} STREQUAL wdmdriver))
- set(__entrypoint DriverEntry)
- set(__entrystack 8)
+ set_entrypoint(${MODULE} DriverEntry 8)
elseif(${TYPE} STREQUAL nativedll)
- set(__entrypoint DllMain)
- set(__entrystack 12)
+ set_entrypoint(${MODULE} DllMain 12)
+ elseif(TYPE STREQUAL kernel)
+ set_entrypoint(${MODULE} KiSystemStartup 4)
elseif(${TYPE} STREQUAL module)
- set(__entrypoint 0)
- endif()
-
- if(DEFINED __entrypoint)
- if(DEFINED __entrystack)
- set_entrypoint(${MODULE} ${__entrypoint} ${__entrystack})
- else()
- set_entrypoint(${MODULE} ${__entrypoint})
- endif()
+ set_entrypoint(${MODULE} 0)
endif()
# Set base address
@@ -644,18 +626,29 @@ function(set_module_type MODULE TYPE)
else()
message(STATUS "${MODULE} has no base address")
endif()
- elseif((${TYPE} STREQUAL kernelmodedriver) OR (${TYPE} STREQUAL wdmdriver) OR
(${TYPE} STREQUAL kerneldll))
- set_image_base(${MODULE} 0x00010000)
+ elseif(TYPE IN_LIST KERNEL_MODULE_TYPES)
+ # special case for kernel
+ if (TYPE STREQUAL kernel)
+ set_image_base(${MODULE} 0x00400000)
+ else()
+ set_image_base(${MODULE} 0x00010000)
+ endif()
endif()
# Now do some stuff which is specific to each type
- if((${TYPE} STREQUAL kernelmodedriver) OR (${TYPE} STREQUAL wdmdriver) OR (${TYPE}
STREQUAL kerneldll))
+ if(TYPE IN_LIST KERNEL_MODULE_TYPES)
add_dependencies(${MODULE} bugcodes xdk)
if((${TYPE} STREQUAL kernelmodedriver) OR (${TYPE} STREQUAL wdmdriver))
set_target_properties(${MODULE} PROPERTIES SUFFIX ".sys")
endif()
endif()
+ if (TYPE STREQUAL kernel)
+ # Kernels are executables with exports
+ set_property(TARGET ${MODULE} PROPERTY ENABLE_EXPORTS TRUE)
+ set_target_properties(${MODULE} PROPERTIES DEFINE_SYMBOL "")
+ endif()
+
if(${TYPE} STREQUAL win32ocx)
set_target_properties(${MODULE} PROPERTIES SUFFIX ".ocx")
endif()
diff --git a/sdk/cmake/gcc.cmake b/sdk/cmake/gcc.cmake
index 442422a74dc..cd9585dc6cf 100644
--- a/sdk/cmake/gcc.cmake
+++ b/sdk/cmake/gcc.cmake
@@ -285,11 +285,15 @@ function(set_module_type_toolchain MODULE TYPE)
if(${TYPE} STREQUAL "wdmdriver")
target_link_options(${MODULE} PRIVATE "-Wl,--wdmdriver")
endif()
- # Place INIT section at the tail of the module
+ # Place INIT &.rsrc section at the tail of the module, before .reloc
add_linker_script(${MODULE} ${REACTOS_SOURCE_DIR}/sdk/cmake/init-section.lds)
- # Fixup section characteristiscs
+ # Fixup section characteristics
+ # - Remove flags that LD overzealously puts (alignment flag, Initialized flags
for code sections)
+ # - INIT section is made discardable
+ # - .rsrc is made read-only
+ # - PAGE & .edata sections are made pageable.
add_custom_command(TARGET ${MODULE} POST_BUILD
- COMMAND native-pefixup --driver $<TARGET_FILE:${MODULE}>)
+ COMMAND native-pefixup --${TYPE} $<TARGET_FILE:${MODULE}>)
# Believe it or not, cmake doesn't do that
set_property(TARGET ${MODULE} APPEND PROPERTY LINK_DEPENDS
$<TARGET_PROPERTY:native-pefixup,IMPORTED_LOCATION>)
endif()
diff --git a/sdk/cmake/msvc.cmake b/sdk/cmake/msvc.cmake
index 33fdbea00f0..fd716b96266 100644
--- a/sdk/cmake/msvc.cmake
+++ b/sdk/cmake/msvc.cmake
@@ -249,13 +249,20 @@ function(set_image_base MODULE IMAGE_BASE)
endfunction()
function(set_module_type_toolchain MODULE TYPE)
- if((${TYPE} STREQUAL "win32dll") OR (${TYPE} STREQUAL "win32ocx")
OR (${TYPE} STREQUAL "cpl"))
- add_target_link_flags(${MODULE} "/DLL")
- elseif(${TYPE} STREQUAL "kernelmodedriver")
- # Disable linker warning 4078 (multiple sections found with different attributes)
for INIT section use
- add_target_link_flags(${MODULE} "/DRIVER /SECTION:INIT,ERWD")
- elseif(${TYPE} STREQUAL "wdmdriver")
- add_target_link_flags(${MODULE} "/DRIVER:WDM /SECTION:INIT,ERWD")
+ if((TYPE STREQUAL win32dll) OR (TYPE STREQUAL win32ocx) OR (TYPE STREQUAL cpl))
+ target_link_options(${MODULE} PRIVATE /DLL)
+ elseif(TYPE IN_LIST KERNEL_MODULE_TYPES)
+ # Mark INIT section as Executable Read Write Discardable
+ target_link_options(${MODULE} PRIVATE /SECTION:INIT,ERWD)
+
+ if(TYPE STREQUAL kernelmodedriver)
+ target_link_options(${MODULE} PRIVATE /DRIVER)
+ elseif(TYPE STREQUAL wdmdriver)
+ target_link_options(${MODULE} PRIVATE /DRIVER:WDM)
+ elseif (TYPE STREQUAL kernel)
+ # Mark .rsrc section as non-disposable non-pageable, as bugcheck code needs
to access it
+ target_link_options(${MODULE} PRIVATE /SECTION:.rsrc,!DP )
+ endif()
endif()
if(RUNTIME_CHECKS)
diff --git a/sdk/include/host/pecoff.h b/sdk/include/host/pecoff.h
index 28daca13da4..74104075fb6 100644
--- a/sdk/include/host/pecoff.h
+++ b/sdk/include/host/pecoff.h
@@ -39,6 +39,22 @@
#define IMAGE_SCN_MEM_READ 0x40000000
#define IMAGE_SCN_MEM_WRITE 0x80000000
+#define IMAGE_SCN_ALIGN_1BYTES 0x00100000
+#define IMAGE_SCN_ALIGN_2BYTES 0x00200000
+#define IMAGE_SCN_ALIGN_4BYTES 0x00300000
+#define IMAGE_SCN_ALIGN_8BYTES 0x00400000
+#define IMAGE_SCN_ALIGN_16BYTES 0x00500000
+#define IMAGE_SCN_ALIGN_32BYTES 0x00600000
+#define IMAGE_SCN_ALIGN_64BYTES 0x00700000
+#define IMAGE_SCN_ALIGN_128BYTES 0x00800000
+#define IMAGE_SCN_ALIGN_256BYTES 0x00900000
+#define IMAGE_SCN_ALIGN_512BYTES 0x00A00000
+#define IMAGE_SCN_ALIGN_1024BYTES 0x00B00000
+#define IMAGE_SCN_ALIGN_2048BYTES 0x00C00000
+#define IMAGE_SCN_ALIGN_4096BYTES 0x00D00000
+#define IMAGE_SCN_ALIGN_8192BYTES 0x00E00000
+#define IMAGE_SCN_ALIGN_MASK 0x00F00000
+
#define IMAGE_NUMBEROF_DIRECTORY_ENTRIES 16
#define IMAGE_REL_I386_ABSOLUTE 0x0001
diff --git a/sdk/tools/pefixup.c b/sdk/tools/pefixup.c
index 81dfcc96c5a..3ea638653a0 100644
--- a/sdk/tools/pefixup.c
+++ b/sdk/tools/pefixup.c
@@ -27,7 +27,10 @@ static const char* g_Target;
enum fixup_mode
{
MODE_LOADCONFIG,
- MODE_DRIVER
+ MODE_KERNELDRIVER,
+ MODE_WDMDRIVER,
+ MODE_KERNELDLL,
+ MODE_KERNEL
};
void *rva_to_ptr(unsigned char *buffer, PIMAGE_NT_HEADERS nt_header, DWORD rva)
@@ -127,13 +130,27 @@ static int add_loadconfig(unsigned char *buffer, PIMAGE_NT_HEADERS
nt_header)
return 1;
}
-static int driver_fixup(unsigned char *buffer, PIMAGE_NT_HEADERS nt_header)
+static int driver_fixup(int mode, unsigned char *buffer, PIMAGE_NT_HEADERS nt_header)
{
/* GNU LD just doesn't know what a driver is, and has notably no idea of paged vs
non-paged sections */
for (unsigned i = 0; i < nt_header->FileHeader.NumberOfSections; i++)
{
PIMAGE_SECTION_HEADER Section = IMAGE_FIRST_SECTION(nt_header) + i;
+ /* LD puts alignment crap that nobody asked for */
+ Section->Characteristics &= ~IMAGE_SCN_ALIGN_MASK;
+
+ /* LD overdoes it and puts the initialized flag everywhere */
+ if (Section->Characteristics & IMAGE_SCN_CNT_CODE)
+ Section->Characteristics &= ~IMAGE_SCN_CNT_INITIALIZED_DATA;
+
+ /* For some reason, .rsrc is made writable by windres */
+ if (strncasecmp((char*)Section->Name, ".rsrc", 5) == 0)
+ {
+ Section->Characteristics &= ~IMAGE_SCN_MEM_WRITE;
+ continue;
+ }
+
/* Known sections which can be discarded */
if (strncasecmp((char*)Section->Name, "INIT", 4) == 0)
{
@@ -143,6 +160,8 @@ static int driver_fixup(unsigned char *buffer, PIMAGE_NT_HEADERS
nt_header)
/* Known sections which can be paged */
if ((strncasecmp((char*)Section->Name, "PAGE", 4) == 0)
+ || (strncasecmp((char*)Section->Name, ".rsrc", 5) == 0)
+ || (strncasecmp((char*)Section->Name, ".edata", 6) == 0)
|| (strncasecmp((char*)Section->Name, ".reloc", 6) == 0))
{
continue;
@@ -164,8 +183,11 @@ print_usage(void)
{
printf("Usage: %s <mode> <filename>\n", g_ApplicationName);
printf("Where <mode> is on of the following:\n");
- printf(" --loadconfig Fix the LOAD_CONFIG directory entry\n");
- printf(" --driver Fix code and data sections for driver images\n");
+ printf(" --loadconfig Fix the LOAD_CONFIG directory entry\n");
+ printf(" --kernelmodedriver Fix code and data sections for driver
images\n");
+ printf(" --wdmdriver Fix code and data sections for WDM
drivers\n");
+ printf(" --kerneldll Fix code and data sections for Kernel-Mode
DLLs\n");
+ printf(" --kernel Fix code and data sections for
kernels\n");
}
int main(int argc, char **argv)
@@ -189,9 +211,21 @@ int main(int argc, char **argv)
{
mode = MODE_LOADCONFIG;
}
- else if (strcmp(argv[1], "--driver") == 0)
+ else if (strcmp(argv[1], "--kernelmodedriver") == 0)
+ {
+ mode = MODE_KERNELDRIVER;
+ }
+ else if (strcmp(argv[1], "--wdmdriver") == 0)
+ {
+ mode = MODE_WDMDRIVER;
+ }
+ else if (strcmp(argv[1], "--kerneldll") == 0)
+ {
+ mode = MODE_KERNELDLL;
+ }
+ else if (strcmp(argv[1], "--kernel") == 0)
{
- mode = MODE_DRIVER;
+ mode = MODE_KERNEL;
}
else
{
@@ -245,7 +279,7 @@ int main(int argc, char **argv)
if (mode == MODE_LOADCONFIG)
result = add_loadconfig(buffer, nt_header);
else
- result = driver_fixup(buffer, nt_header);
+ result = driver_fixup(mode, buffer, nt_header);
if (!result)
{