> I think for -fstack-check, in may be desirable to trigger copy-on-write
> on some systems, but for -fstack-clash-protection, that does not seem
> necessary (no proactive triggering of stack overflow traps needed).

Yes, some OSes, like Windows, require stack probing to extend the stack, and 
for example ___chkstk_ms from cygwin.S uses ORL.  When -fstack-check is used 
on Windows, ___chkstk_ms is disabled:

/* Decide whether we must probe the stack before any space allocation
   on this target.  It's essentially TARGET_STACK_PROBE except when
   -fstack-check causes the stack to be already probed differently.  */

bool
ix86_target_stack_probe (void)
{
  /* Do not probe the stack twice if static stack checking is enabled.  */
  if (flag_stack_check == STATIC_BUILTIN_STACK_CHECK)
    return false;

  return TARGET_STACK_PROBE;
}

so -fstack-check needs to implement the system-required stack probing; changes 
in this area therefore need to be tested on Windows too.

Note that the change has introduced a couple Ada regressions on x86-64/Linux:

                === acats tests ===
FAIL:  c52103x
FAIL:  c52104x

because the Ada runtime performs pattern matching on the probes.  I have 
installed the following fix.


        PR target/124336
        * init.c (__gnat_adjust_context_for_raise) [x86/Linux]: Adjust
        pattern matching to new stack probes.

-- 
Eric Botcazou
diff --git a/init.c b/init.c
index 87d6cf242e..edf66182a9 100644
--- a/init.c
+++ b/init.c
@@ -507,17 +507,18 @@ __gnat_adjust_context_for_raise (int signo ATTRIBUTE_UNUSED, void *ucontext)
 
 #if defined (__i386__)
   unsigned long *pc = (unsigned long *)mcontext->gregs[REG_EIP];
-  /* The pattern is "orl $0x0,(%esp)" for a probe in 32-bit mode.  */
-  if (signo == SIGSEGV && pc && *pc == 0x00240c83)
+  /* The pattern is "or{l,b} $0x0,(%esp)" for a probe in 32-bit mode.  */
+  if (signo == SIGSEGV && pc && (*pc == 0x00240c83 || *pc == 0x00240c80))
     mcontext->gregs[REG_ESP] += 4096 + 4 * sizeof (unsigned long);
 #elif defined (__x86_64__)
   unsigned long long *pc = (unsigned long long *)mcontext->gregs[REG_RIP];
   if (signo == SIGSEGV && pc
       /* The pattern is "orq $0x0,(%rsp)" for a probe in 64-bit mode.  */
       && ((*pc & 0xffffffffffLL) == 0x00240c8348LL
-	  /* The pattern may also be "orl $0x0,(%esp)" for a probe in
-	     x32 mode.  */
-	  || (*pc & 0xffffffffLL) == 0x00240c83LL))
+	  /* The pattern is "orl $0x0,(%rsp)" for a probe in x32 mode.  */
+	  || (*pc & 0xffffffffLL) == 0x00240c83LL)
+	  /* The pattern may also be "orb $0x0,(%rsp)" in both modes.  */
+	  || (*pc & 0xffffffffLL) == 0x00240c80LL)
     mcontext->gregs[REG_RSP] += 4096 + 4 * sizeof (unsigned long);
 #elif defined (__ia64__)
   /* ??? The IA-64 unwinder doesn't compensate for signals.  */

Reply via email to