Cygwin: fix heap allocation on WOW64 and /3GB enabled 32 bit machines

The check for the TEB being allocated beyond the first 2GB area is not
valid anymore.  At least on W10 WOW64, the TEB is allocated in the
lower 2GB even in large-address aware executables.  Use VirtualQuery
instead.  It fails for invalid addresses so that's a simple enough test.

Signed-off-by: Corinna Vinschen <corinna@vinschen.de>
This commit is contained in:
Corinna Vinschen 2018-12-19 21:10:37 +01:00
parent b3692aed5e
commit a091d5da63
1 changed files with 17 additions and 11 deletions

View File

@ -44,22 +44,28 @@ eval_start_address ()
starting at 0x20000000. This should work right from the start in 99% starting at 0x20000000. This should work right from the start in 99%
of the cases. */ of the cases. */
uintptr_t start_address = 0x20000000L; uintptr_t start_address = 0x20000000L;
if ((uintptr_t) NtCurrentTeb () >= 0xbf000000L) MEMORY_BASIC_INFORMATION mbi;
if (VirtualQuery ((void *) 0xbf000000L, &mbi, sizeof mbi))
{ {
/* However, if we're running on a /3GB enabled 32 bit system or on /* However, if we're running on a /3GB enabled 32 bit system or on
a 64 bit system, and the executable is large address aware, then a 64 bit system, and the executable is large address aware, then
we know that we have spare 1 Gig (32 bit) or even 2 Gigs (64 bit) we know that we have spare 1 Gig (32 bit) or even 2 Gigs (64 bit)
virtual address space. This memory region is practically unused virtual address space. This memory region is practically unused
by Windows, only PEB and TEBs are allocated top-down here. We use by Windows, only PEB and TEBs are allocated top-down here.
the current TEB address as very simple test that this is a large
address aware executable. We used to use the current TEB address as very simple test that
The above test for an address beyond 0xbf000000 is supposed to this is a large address aware executable, but that fails on W10
make sure that we really have 3GB on a 32 bit system. Windows WOW64 because the main TEB is apparently commited in the lower
supports smaller large address regions, but then it's not that 2 Gigs these days.
interesting for us to use it for the heap.
If the region is big enough, the heap gets allocated at its The above test for address 0xbf000000 is supposed to make sure
start. What we get are 0.999 or 1.999 Gigs of free contiguous that we really have 3GB on a 32 bit system. Windows supports
memory for heap, thread stacks, and shared memory regions. */ smaller large address regions, but then it's not that interesting
for us to use it for the heap. If the region is big enough, the
heap gets allocated at its start. What we get are 0.999 or 1.999
Gigs of free contiguous memory for heap, thread stacks, and shared
memory regions. */
start_address = 0x80000000L; start_address = 0x80000000L;
} }
#endif #endif