Welcome to mirror list, hosted at ThFree Co, Russian Federation.

cygwin.com/git/newlib-cygwin.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCorinna Vinschen <corinna@vinschen.de>2006-07-13 12:33:34 +0400
committerCorinna Vinschen <corinna@vinschen.de>2006-07-13 12:33:34 +0400
commitf6105f89d5a809cb2fbcac318da9fa8981576a51 (patch)
tree0758a73e314ae10f937f6e6ca9bd983fa7f28242 /winsup/cygwin/mmap.cc
parentd44b979536f0e922713ab132a871c062f61ea376 (diff)
* exceptions.cc (_cygtls::handle_exceptions): Call new
mmap_is_attached_or_noreserve_page function in case of access violation and allow application to retry access on noreserve pages. * mmap.cc (mmap_is_attached_or_noreserve_page): Changed from mmap_is_attached_page. Handle also noreserve pages now. Change comment accordingly. * winsup.h (mmap_is_attached_or_noreserve_page): Declare instead of mmap_is_attached_page.
Diffstat (limited to 'winsup/cygwin/mmap.cc')
-rw-r--r--winsup/cygwin/mmap.cc39
1 files changed, 27 insertions, 12 deletions
diff --git a/winsup/cygwin/mmap.cc b/winsup/cygwin/mmap.cc
index 7ca176c88..193ed7c0f 100644
--- a/winsup/cygwin/mmap.cc
+++ b/winsup/cygwin/mmap.cc
@@ -900,13 +900,25 @@ map::del_list (unsigned i)
}
/* This function is called from exception_handler when a segmentation
- violation has happened. The function should return true, if the
- faulting address (the parameter) is within attached pages. In this
- case the exception_handler raises SIGBUS, as demanded by the memory
- protection extension described in SUSv3 (see the mmap man page).
- If false is returned, a normal SIGSEGV is raised. */
-bool
-mmap_is_attached_page (ULONG_PTR addr)
+ violation has happened. We have two cases to check here.
+
+ First, is it an address within "attached" mmap pages (indicated by
+ the __PROT_ATTACH protection, see there)? In this case the function
+ returns 1 and the exception_handler raises SIGBUS, as demanded by the
+ memory protection extension described in SUSv3 (see the mmap man
+ page).
+
+ Second, check if the address is within "noreserve" mmap pages
+ (indicated by MAP_NORESERVE flag). If so, the function calls
+ VirtualAlloc to commit the page and returns 2. The exception handler
+ then just returns with 0 and the affected application retries the
+ failing memory access. If VirtualAlloc fails, the function returns
+ 1, so that the exception handler raises a SIGBUS, as described in the
+ MAP_NORESERVE man pages for Linux and Solaris.
+
+ In any other case 0 is returned and a normal SIGSEGV is raised. */
+int
+mmap_is_attached_or_noreserve_page (ULONG_PTR addr)
{
list *map_list;
long record_idx;
@@ -916,13 +928,16 @@ mmap_is_attached_page (ULONG_PTR addr)
addr = rounddown (addr, pagesize);
if (!(map_list = mmapped_areas.get_list_by_fd (-1)))
- return false;
+ return 0;
if ((record_idx = map_list->search_record ((caddr_t)addr, pagesize,
u_addr, u_len, -1)) < 0)
- return false;
- if (!map_list->get_record (record_idx)->attached ())
- return false;
- return true;
+ return 0;
+ if (map_list->get_record (record_idx)->attached ())
+ return 1;
+ if (!map_list->get_record (record_idx)->noreserve ())
+ return 0;
+ DWORD new_prot = map_list->get_record (record_idx)->gen_protect ();
+ return VirtualAlloc ((void *)addr, pagesize, MEM_COMMIT, new_prot) ? 2 : 1;
}
static caddr_t