Windows has a 2G/2G split by default, but some addresses are fixed in the win32 API, so we have to ensure that those addresses are still available in the virtual memory space and not taken by Linux.
Kudos to stefand for taking the time to explain on IRC.
-- v5: ntdll: Explaining why 3G/1G split is needed on 32bit
From: Steve Schnepp steve.schnepp@pwkf.org
Windows has a 2G/2G split by default, but some addresses are fixed in the win32 ABI, so we have to ensure that those addresses are still available in the virtual memory space and not taken by Linux.
Kudos to stefand for taking the time to explain on IRC. --- dlls/ntdll/unix/loader.c | 17 +++++++++++++++++ 1 file changed, 17 insertions(+)
diff --git a/dlls/ntdll/unix/loader.c b/dlls/ntdll/unix/loader.c index 65934acfc36..09171e18d88 100644 --- a/dlls/ntdll/unix/loader.c +++ b/dlls/ntdll/unix/loader.c @@ -2309,6 +2309,23 @@ static int pre_exec(void)
#elif defined(__linux__) && (defined(__i386__) || defined(__arm__))
+/* In the Win32 ABI, KUSER_SHARED_DATA is at a fixed address (0x7ffe0000), so + * it needs to be mapped precisely there in every virtual process space by the + * wine process loader. + * + * It is used to map kernel address space pages to user space, so that it is + * user-space readable without any syscall overhead. It is very comparable + * to Linux's vDSO. + * + * For that, we need to ensure that Linux doesn't map anything internal in that + * area, which it does if configured with a 2G/2G split. Unfortunately, Linux + * does initially map the stack there, along with its own vDSO. + * + * More information: + * + * https://learn.microsoft.com/en-us/windows-hardware/drivers/ddi/ntddk/ns-ntdd... + * https://en.wikipedia.org/wiki/VDSO + */ static void check_vmsplit( void *stack ) { if (stack < (void *)0x80000000)
On Mon Feb 6 21:50:45 2023 +0000, Steve Schnepp wrote:
Oh, but it looked actually very similar to how `gettimeofday()` is implemented in Linux.
The KUSER_SHARED_DATA structure is a single page (4096 bytes) in
memory that is mapped at a fixed, hardcoded address in both kernel and user side of VAS. KUSER_SHARED_DATA is mapped into every process and provides a quick mechanism to obtain frequently needed global data (interrupt time, version, debugger state, processor extensions, etc.) from the kernel without involving user-kernel mode switching using system calls or interrupts from https://msrc-blog.microsoft.com/2022/04/05/randomizing-the-kuser_shared_data... On that page, there's even some discussion at _what_ will break and how to move it out. TLDR: you cannot :disappointed:
Actually, you are right and I'm wrong.
vDSO is randomized, vsyscall is the static version.
Also, in Linux a full function is provided, whereas in win32 only the values are provided, relying on header macros to fetch the correct values.
Amending also.