diff options
author | Christopher Faylor <me@cgf.cx> | 2003-08-22 19:25:56 +0000 |
---|---|---|
committer | Christopher Faylor <me@cgf.cx> | 2003-08-22 19:25:56 +0000 |
commit | 897c6b5231b76e475959a3e0c5559df5d46fb87c (patch) | |
tree | 09fb4f23d4f036f9b144c4fa744c229fd175ecba /winsup/cygwin | |
parent | 9fc9e1c916af8d91539ace77cb123b4fa99e0d37 (diff) | |
download | newlib-897c6b5231b76e475959a3e0c5559df5d46fb87c.zip newlib-897c6b5231b76e475959a3e0c5559df5d46fb87c.tar.gz newlib-897c6b5231b76e475959a3e0c5559df5d46fb87c.tar.bz2 |
* exceptions.cc (sigreturn): Don't clobber ebp in recursive signal calls.
Diffstat (limited to 'winsup/cygwin')
-rw-r--r-- | winsup/cygwin/ChangeLog | 5 | ||||
-rw-r--r-- | winsup/cygwin/cygheap.h | 1 | ||||
-rw-r--r-- | winsup/cygwin/exceptions.cc | 6 | ||||
-rw-r--r-- | winsup/cygwin/heap.cc | 33 |
4 files changed, 31 insertions, 14 deletions
diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog index 3fed94d..4dfa46d 100644 --- a/winsup/cygwin/ChangeLog +++ b/winsup/cygwin/ChangeLog @@ -1,3 +1,8 @@ +2003-08-20 Pierre Humblet <pierre.humblet@ieee.org> + + * exceptions.cc (sigreturn): Don't clobber ebp in recursive signal + calls. + 2003-08-22 Christopher Faylor <cgf@redhat.com> * exceptions.cc (sig_handle): Change so that default signals indicate diff --git a/winsup/cygwin/cygheap.h b/winsup/cygwin/cygheap.h index f765541..c03d600 100644 --- a/winsup/cygwin/cygheap.h +++ b/winsup/cygwin/cygheap.h @@ -234,6 +234,7 @@ struct user_heap_info void *base; void *ptr; void *top; + void *max; unsigned chunk; }; diff --git a/winsup/cygwin/exceptions.cc b/winsup/cygwin/exceptions.cc index e997517..1732165 100644 --- a/winsup/cygwin/exceptions.cc +++ b/winsup/cygwin/exceptions.cc @@ -1225,8 +1225,7 @@ _sigreturn: \n\ cmpl $0,%4 # Did a signal come in? \n\ jz 1f # No, if zero \n\ movl %2,%%eax \n\ - movl %%esp,%%ebp \n\ - movl %%eax,36(%%ebp) # Restore return address \n\ + movl %%eax,36(%%esp) # Restore return address \n\ jmp 3f \n\ \n\ 1: popl %%eax # saved errno \n\ @@ -1275,7 +1274,8 @@ _sigdelayed0: \n\ __no_sig_end: \n\ " : "=m" (sigsave.sig): "X" ((char *) &_impure_ptr->_errno), "g" (sigsave.retaddr), "g" (sigsave.oldmask), "g" (sigsave.sig), - "g" (sigsave.func), "g" (sigsave.saved_errno), "g" (sigsave.newmask) + "g" (sigsave.func), "g" (sigsave.saved_errno), "g" (sigsave.newmask), + "g" (sigsave.retaddr_on_stack) ); } } diff --git a/winsup/cygwin/heap.cc b/winsup/cygwin/heap.cc index 8e0a04e..95fdd12 100644 --- a/winsup/cygwin/heap.cc +++ b/winsup/cygwin/heap.cc @@ -56,6 +56,7 @@ heap_init () if (cygheap->user_heap.base == NULL) api_fatal ("unable to allocate heap, heap_chunk_size %d, %E", cygheap->user_heap.chunk); + cygheap->user_heap.max = (char *) cygheap->user_heap.base + cygheap->user_heap.chunk; } else { @@ -101,7 +102,7 @@ sbrk (int n) unsigned commitbytes, newbrksize; if (n == 0) - return cygheap->user_heap.ptr; /* Just wanted to find current cygheap->user_heap.ptr address */ + return cygheap->user_heap.ptr; /* Just wanted to find current cygheap->user_heap.ptr address */ newbrk = (char *) cygheap->user_heap.ptr + n; /* Where new cygheap->user_heap.ptr will be */ newtop = (char *) pround (newbrk); /* Actual top of allocated memory - @@ -122,23 +123,33 @@ sbrk (int n) assert (newtop > cygheap->user_heap.top); - /* Need to grab more pages from the OS. If this fails it may be because - * we have used up previously reserved memory. Or, we're just plumb out - * of memory. */ + /* Find the number of bytes to commit, rounded up to the nearest page. */ commitbytes = pround (newtop - (char *) cygheap->user_heap.top); - if (VirtualAlloc (cygheap->user_heap.top, commitbytes, MEM_COMMIT, PAGE_READWRITE) != NULL) - goto good; + + /* Need to grab more pages from the OS. If this fails it may be because + we have used up previously reserved memory. Or, we're just plumb out + of memory. Only attempt to commit memory that we know we've previously + reserved. */ + if (newtop <= cygheap->user_heap.max) + { + if (VirtualAlloc (cygheap->user_heap.top, commitbytes, MEM_COMMIT, PAGE_READWRITE) != NULL) + goto good; + } /* Couldn't allocate memory. Maybe we can reserve some more. - Reserve either the maximum of the standard cygwin_shared->heap_chunk_size () or the requested - amount. Then attempt to actually allocate it. */ + Reserve either the maximum of the standard cygwin_shared->heap_chunk_size () + or the requested amount. Then attempt to actually allocate it. */ if ((newbrksize = cygheap->user_heap.chunk) < commitbytes) newbrksize = commitbytes; - if ((VirtualAlloc (cygheap->user_heap.top, newbrksize, MEM_RESERVE, PAGE_NOACCESS) != NULL) && - (VirtualAlloc (cygheap->user_heap.top, commitbytes, MEM_COMMIT, PAGE_READWRITE) != NULL)) - goto good; + if ((VirtualAlloc (cygheap->user_heap.top, newbrksize, MEM_RESERVE, PAGE_NOACCESS) + || VirtualAlloc (cygheap->user_heap.top, newbrksize = commitbytes, MEM_RESERVE, PAGE_NOACCESS)) + && VirtualAlloc (cygheap->user_heap.top, commitbytes, MEM_COMMIT, PAGE_READWRITE) != NULL) + { + (char *) cygheap->user_heap.max += newbrksize; + goto good; + } err: set_errno (ENOMEM); |