https://git.reactos.org/?p=reactos.git;a=commitdiff;h=e55123a6a286202dea24269ad35b35ab412d68aa

commit e55123a6a286202dea24269ad35b35ab412d68aa
Author:     Jérôme Gardou <[email protected]>
AuthorDate: Wed Feb 24 11:46:53 2021 +0100
Commit:     Jérôme Gardou <[email protected]>
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)
             {

Reply via email to