mirror of
git://sourceware.org/git/newlib-cygwin.git
synced 2025-01-19 04:49:25 +08:00
Cygwin: map beyond EOF on 64 bit and WOW64 as well
32 bit Cygwin performs a POSIX-compatible mapping after EOF which is not supported in this form on Windows. The 64 bit Windows kernel never supported the AT_ROUND_TO_PAGE mapping flag, so we couldn't page-aligned map the space right after the file's EOF. So mapping beyond EOF was disabled in 64 bit Windows and WOW64. However, if mmap works, a matching munmap should work as well, *and* it should not accidentally unmap unrelated memory. Therefore we enable mapping beyond EOF on 64 bit as well. Since that mapping is always 64K aligned, the are between the last file page and the next 64K allocation boundary will be unallocated. There's no way around that. Signed-off-by: Corinna Vinschen <corinna@vinschen.de>
This commit is contained in:
parent
b0c033bf3f
commit
605bdcd410
@ -834,7 +834,7 @@ public:
|
||||
{
|
||||
/* If it points to a free area, big enough to fulfill the request,
|
||||
return the address. */
|
||||
if (VirtualQuery (in_addr, &mbi, sizeof mbi)
|
||||
if (VirtualQuery (in_addr, &mbi, sizeof mbi)
|
||||
&& mbi.State == MEM_FREE
|
||||
&& mbi.RegionSize >= size)
|
||||
return in_addr;
|
||||
@ -1075,14 +1075,17 @@ mmap64 (void *addr, size_t len, int prot, int flags, int fd, off_t off)
|
||||
}
|
||||
fsiz -= off;
|
||||
/* We're creating the pages beyond EOF as reserved, anonymous pages.
|
||||
Note that this isn't done in 64 bit environments since apparently
|
||||
64 bit systems don't support the AT_ROUND_TO_PAGE flag, which is
|
||||
required to get this right. Too bad. */
|
||||
Note that 64 bit environments don't support the AT_ROUND_TO_PAGE
|
||||
flag, which is required to get this right for the remainder of
|
||||
the first 64K block the file ends in. We perform the workaround
|
||||
nevertheless to support expectations that the range mapped beyond
|
||||
EOF can be safely munmap'ed instead of being taken by another,
|
||||
totally unrelated mapping. */
|
||||
if ((off_t) len > fsiz && !autogrow (flags))
|
||||
orig_len = len;
|
||||
#ifdef __i386__
|
||||
if (!wincap.is_wow64 ()
|
||||
&& (((off_t) len > fsiz && !autogrow (flags))
|
||||
|| roundup2 (len, wincap.page_size ())
|
||||
< roundup2 (len, pagesize)))
|
||||
else if (!wincap.is_wow64 () && roundup2 (len, wincap.page_size ())
|
||||
< roundup2 (len, pagesize))
|
||||
orig_len = len;
|
||||
#endif
|
||||
if ((off_t) len > fsiz)
|
||||
@ -1185,12 +1188,22 @@ go_ahead:
|
||||
raise a SIGBUS when trying to access them. AT_ROUND_TO_PAGE
|
||||
and page protection on shared pages is only supported by the
|
||||
32 bit environment, so don't even try on 64 bit or even WOW64.
|
||||
This is accomplished by not setting orig_len on 64 bit above. */
|
||||
len = roundup2 (len, wincap.page_size ());
|
||||
This results in an allocation gap in the first 64K block the file
|
||||
ends in, but there's nothing at all we can do about that. */
|
||||
#ifdef __x86_64__
|
||||
len = roundup2 (len, wincap.allocation_granularity ());
|
||||
#else
|
||||
len = roundup2 (len, wincap.is_wow64 () ? wincap.allocation_granularity ()
|
||||
: wincap.page_size ());
|
||||
#endif
|
||||
if (orig_len - len)
|
||||
{
|
||||
orig_len -= len;
|
||||
size_t valid_page_len = orig_len % pagesize;
|
||||
size_t valid_page_len = 0;
|
||||
#ifndef __x86_64__
|
||||
if (!wincap.is_wow64 ())
|
||||
valid_page_len = orig_len % pagesize;
|
||||
#endif
|
||||
size_t sigbus_page_len = orig_len - valid_page_len;
|
||||
|
||||
caddr_t at_base = base + len;
|
||||
|
Loading…
x
Reference in New Issue
Block a user