mirror of
git://sourceware.org/git/newlib-cygwin.git
synced 2025-01-19 12:59:21 +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
c9a50a1276
commit
4a6ba932f1
@ -1075,14 +1075,17 @@ mmap64 (void *addr, size_t len, int prot, int flags, int fd, off_t off)
|
|||||||
}
|
}
|
||||||
fsiz -= off;
|
fsiz -= off;
|
||||||
/* We're creating the pages beyond EOF as reserved, anonymous pages.
|
/* We're creating the pages beyond EOF as reserved, anonymous pages.
|
||||||
Note that this isn't done in 64 bit environments since apparently
|
Note that 64 bit environments don't support the AT_ROUND_TO_PAGE
|
||||||
64 bit systems don't support the AT_ROUND_TO_PAGE flag, which is
|
flag, which is required to get this right for the remainder of
|
||||||
required to get this right. Too bad. */
|
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__
|
#ifdef __i386__
|
||||||
if (!wincap.is_wow64 ()
|
else if (!wincap.is_wow64 () && roundup2 (len, wincap.page_size ())
|
||||||
&& (((off_t) len > fsiz && !autogrow (flags))
|
< roundup2 (len, pagesize))
|
||||||
|| roundup2 (len, wincap.page_size ())
|
|
||||||
< roundup2 (len, pagesize)))
|
|
||||||
orig_len = len;
|
orig_len = len;
|
||||||
#endif
|
#endif
|
||||||
if ((off_t) len > fsiz)
|
if ((off_t) len > fsiz)
|
||||||
@ -1185,12 +1188,22 @@ go_ahead:
|
|||||||
raise a SIGBUS when trying to access them. AT_ROUND_TO_PAGE
|
raise a SIGBUS when trying to access them. AT_ROUND_TO_PAGE
|
||||||
and page protection on shared pages is only supported by the
|
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.
|
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. */
|
This results in an allocation gap in the first 64K block the file
|
||||||
len = roundup2 (len, wincap.page_size ());
|
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)
|
if (orig_len - len)
|
||||||
{
|
{
|
||||||
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;
|
size_t sigbus_page_len = orig_len - valid_page_len;
|
||||||
|
|
||||||
caddr_t at_base = base + len;
|
caddr_t at_base = base + len;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user