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.
-- v4: ntdll: Explaining with wine requires a 3G/1G split 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 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. --- dlls/ntdll/unix/loader.c | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+)
diff --git a/dlls/ntdll/unix/loader.c b/dlls/ntdll/unix/loader.c index 65934acfc36..6e5194e40bb 100644 --- a/dlls/ntdll/unix/loader.c +++ b/dlls/ntdll/unix/loader.c @@ -2309,6 +2309,33 @@ static int pre_exec(void)
#elif defined(__linux__) && (defined(__i386__) || defined(__arm__))
+/* In Win32, KUSER_SHARED_DATA is at a fixed address (0x7ffe0000), so it needs + * to be mapped there in every virtual process space by wine. + * + * 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. + * + * A potentially nice thing to have is to move KUSER_SHARED_DATA if the + * hardcoded address does not work. + * + * Yet there is no official way to communicate the address from ntdll to + * kernel32, as is should be at a fixed address in the first place. The only + * alternative might be wine-specific private calls from kernel32 to ntdll, + * which is bad. + * + * Moreover, while it would probably make 99% of applications out there happy, + * this would still break the ABI, which is also bad. + * + * 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)
Alexandre Julliard (@julliard) commented about dlls/ntdll/unix/loader.c:
#elif defined(__linux__) && (defined(__i386__) || defined(__arm__))
+/* In Win32, KUSER_SHARED_DATA is at a fixed address (0x7ffe0000), so it needs
- to be mapped there in every virtual process space by wine.
- 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.
Actually it's very different from vDSO.
Alexandre Julliard (@julliard) commented about dlls/ntdll/unix/loader.c:
- 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.
- A potentially nice thing to have is to move KUSER_SHARED_DATA if the
- hardcoded address does not work.
- Yet there is no official way to communicate the address from ntdll to
- kernel32, as is should be at a fixed address in the first place. The only
- alternative might be wine-specific private calls from kernel32 to ntdll,
- which is bad.
- Moreover, while it would probably make 99% of applications out there happy,
- this would still break the ABI, which is also bad.
That doesn't make any sense. Breaking the ABI is not an option at all.
In general, that sort of info should go to the developers' guide, not in the code.
On Mon Feb 6 19:31:12 2023 +0000, Alexandre Julliard wrote:
That doesn't make any sense. Breaking the ABI is not an option at all.
Let me rephrase it, indeed.
On Mon Feb 6 19:31:10 2023 +0000, Alexandre Julliard wrote:
Actually it's very different from vDSO.
Oh, 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:
On Mon Feb 6 20:09:52 2023 +0000, Alexandre Julliard wrote:
In general, that sort of info should go to the developers' guide, not in the code.
I would object to that by saying that the doc _explaining_ some code should be the closest possible to the explained code, so that an uninitiated user such as me finds it easily.
Yet, I'm not aware of the traditions in wine, so I'll follow whatever I'm told :wink:
To be fair, I was very nicely impressed by the code readability, so I won't complain.