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:
authorChristopher Faylor <me@cgf.cx>2003-08-22 23:25:56 +0400
committerChristopher Faylor <me@cgf.cx>2003-08-22 23:25:56 +0400
commit897c6b5231b76e475959a3e0c5559df5d46fb87c (patch)
tree09fb4f23d4f036f9b144c4fa744c229fd175ecba
parent9fc9e1c916af8d91539ace77cb123b4fa99e0d37 (diff)
* exceptions.cc (sigreturn): Don't clobber ebp in recursive signal calls.
-rw-r--r--winsup/cygwin/ChangeLog5
-rw-r--r--winsup/cygwin/cygheap.h1
-rw-r--r--winsup/cygwin/exceptions.cc6
-rw-r--r--winsup/cygwin/heap.cc33
4 files changed, 31 insertions, 14 deletions
diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog
index 3fed94d14..4dfa46d42 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 f765541c4..c03d60077 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 e99751714..173216525 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 8e0a04e23..95fdd12eb 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);