OSDN Git Service

libgcc/:
authorian <ian@138bc75d-0d04-0410-961f-82ee72b054a4>
Fri, 25 May 2012 20:48:19 +0000 (20:48 +0000)
committerian <ian@138bc75d-0d04-0410-961f-82ee72b054a4>
Fri, 25 May 2012 20:48:19 +0000 (20:48 +0000)
* config/i386/morestack.S (__morestack_non_split): Check whether
caller is varargs and needs %bp to hold the stack frame on return.
gcc/testsuite/:
* gcc.dg/split-6.c: New test.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@187894 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/split-6.c [new file with mode: 0644]
libgcc/ChangeLog
libgcc/config/i386/morestack.S

index 22a29b8..285ae9c 100644 (file)
@@ -1,3 +1,7 @@
+2012-05-25  Ian Lance Taylor  <iant@google.com>
+
+       * gcc.dg/split-6.c: New test.
+
 2012-05-25  Eric Botcazou  <ebotcazou@adacore.com>
 
        * gnat.dg/lto14.adb: New test.
diff --git a/gcc/testsuite/gcc.dg/split-6.c b/gcc/testsuite/gcc.dg/split-6.c
new file mode 100644 (file)
index 0000000..b32cf8d
--- /dev/null
@@ -0,0 +1,53 @@
+/* { dg-do run } */
+/* { dg-require-effective-target split_stack } */
+/* { dg-options "-fsplit-stack" } */
+
+/* This test is like split-3.c, but tests with a smaller stack frame,
+   since that uses a different prologue.  */
+
+#include <stdarg.h>
+#include <stdlib.h>
+
+/* Use a noinline function to ensure that the buffer is not removed
+   from the stack.  */
+static void use_buffer (char *buf) __attribute__ ((noinline));
+static void
+use_buffer (char *buf)
+{
+  buf[0] = '\0';
+}
+
+/* When using gold, the call to abort will force a stack split.  */
+
+static void
+down (int i, ...)
+{
+  char buf[1];
+  va_list ap;
+
+  va_start (ap, i);
+  if (va_arg (ap, int) != 1
+      || va_arg (ap, int) != 2
+      || va_arg (ap, int) != 3
+      || va_arg (ap, int) != 4
+      || va_arg (ap, int) != 5
+      || va_arg (ap, int) != 6
+      || va_arg (ap, int) != 7
+      || va_arg (ap, int) != 8
+      || va_arg (ap, int) != 9
+      || va_arg (ap, int) != 10)
+    abort ();
+
+  if (i > 0)
+    {
+      use_buffer (buf);
+      down (i - 1, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
+    }
+}
+
+int
+main (void)
+{
+  down (1000, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
+  return 0;
+}
index db4c801..5c048f5 100644 (file)
@@ -1,3 +1,8 @@
+2012-05-25  Ian Lance Taylor  <iant@google.com>
+
+       * config/i386/morestack.S (__morestack_non_split): Check whether
+       caller is varargs and needs %bp to hold the stack frame on return.
+
 2012-05-25  Olivier Hainque  <hainque@adacore.com>
 
        * config/rs6000/vxworks/tramp.S (trampoline_setup): Use a longcall
@@ -80,9 +85,9 @@
 
 2012-04-28  Aurelien Jarno  <aurelien@aurel32.net>
 
-       * config.host (mips64*-*-linux*, mipsisa64*-*-linux*): Remove. 
-       (mips*-*-linux*): Include mips/t-tpbit when long double is 
-       16 bytes long. 
+       * config.host (mips64*-*-linux*, mipsisa64*-*-linux*): Remove.
+       (mips*-*-linux*): Include mips/t-tpbit when long double is
+       16 bytes long.
 
 2012-04-25  Sriraman Tallam  <tmsriram@google.com>
 
index 62f7ce1..228d690 100644 (file)
@@ -1,5 +1,5 @@
 # x86/x86_64 support for -fsplit-stack.
-# Copyright (C) 2009, 2010, 2011 Free Software Foundation, Inc.
+# Copyright (C) 2009, 2010, 2011, 2012 Free Software Foundation, Inc.
 # Contributed by Ian Lance Taylor <iant@google.com>.
 
 # This file is part of GCC.
@@ -138,6 +138,24 @@ __morestack_non_split:
        je      1f                      # see above.
        addl    $2,%eax
 1:     inc     %eax
+
+       # If the instruction that we return to is
+       #   leal  20(%ebp),{%eax,%ecx,%edx}
+       # then we have been called by a varargs function that expects
+       # %ebp to hold a real value.  That can only work if we do the
+       # full stack split routine.  FIXME: This is fragile.
+       cmpb    $0x8d,(%eax)
+       jne     3f
+       cmpb    $0x14,2(%eax)
+       jne     3f
+       cmpb    $0x45,1(%eax)
+       je      2f
+       cmpb    $0x4d,1(%eax)
+       je      2f
+       cmpb    $0x55,1(%eax)
+       je      2f
+
+3:     
        movl    %eax,4(%esp)            # Update return address.
 
        popl    %eax                    # Restore %eax and stack.
@@ -175,18 +193,32 @@ __morestack_non_split:
 #else
        cmpl    %fs:0x40,%eax
 #endif
-       popq    %rax                    # Restore register.
-
-       .cfi_adjust_cfa_offset -8       # Adjust for popped register.
 
        jb      2f                      # Get more space if we need it.
 
        # This breaks call/return prediction, as described above.
-       incq    (%rsp)                  # Increment the return address.
+       incq    8(%rsp)                 # Increment the return address.
+
+       # If the instruction that we return to is
+       #   leaq  24(%rbp), %r11n
+       # then we have been called by a varargs function that expects
+       # %ebp to hold a real value.  That can only work if we do the
+       # full stack split routine.  FIXME: This is fragile.
+       movq    8(%rsp),%rax
+       cmpl    $0x185d8d4c,(%rax)
+       je      2f
+
+       popq    %rax                    # Restore register.
+
+       .cfi_adjust_cfa_offset -8       # Adjust for popped register.
 
        ret                             # Return to caller.
 
 2:
+       popq    %rax                    # Restore register.
+
+       .cfi_adjust_cfa_offset -8       # Adjust for popped register.
+
        addq    $0x5000+BACKOFF,%r10    # Increment space we request.
 
        # Fall through into morestack.