mirror of
https://github.com/reactos/reactos.git
synced 2024-12-28 18:15:11 +00:00
[CMAKE] Add the kernel module type
Take this as an occasion to use target_link_options more
This commit is contained in:
parent
812c9e5a11
commit
e55123a6a2
5 changed files with 125 additions and 71 deletions
|
@ -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()
|
||||
|
||||
# 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)
|
||||
elseif(${TYPE} STREQUAL win32cui)
|
||||
set(__subsystem 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)))
|
||||
# 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})
|
||||
|
||||
if(DEFINED __subsystem)
|
||||
set_subsystem(${MODULE} ${__subsystem})
|
||||
# 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.
|
||||
if(TYPE IN_LIST NATIVE_MODULE_TYPES)
|
||||
set_subsystem(${MODULE} native)
|
||||
elseif(${TYPE} STREQUAL win32cui)
|
||||
set_subsystem(${MODULE} console)
|
||||
elseif(${TYPE} STREQUAL win32gui)
|
||||
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()
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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_DRIVER;
|
||||
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_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)
|
||||
{
|
||||
|
|
Loading…
Reference in a new issue