OSDN Git Service

* exceptions.cc (sigreturn): Don't clobber ebp in recursive signal calls.
authorcgf <cgf>
Fri, 22 Aug 2003 19:25:56 +0000 (19:25 +0000)
committercgf <cgf>
Fri, 22 Aug 2003 19:25:56 +0000 (19:25 +0000)
winsup/cygwin/ChangeLog
winsup/cygwin/cygheap.h
winsup/cygwin/exceptions.cc
winsup/cygwin/heap.cc

index 3fed94d..4dfa46d 100644 (file)
@@ -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
index f765541..c03d600 100644 (file)
@@ -234,6 +234,7 @@ struct user_heap_info
   void *base;
   void *ptr;
   void *top;
+  void *max;
   unsigned chunk;
 };
 
index e997517..1732165 100644 (file)
@@ -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)
 );
 }
 }
index 8e0a04e..95fdd12 100644 (file)
@@ -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);