git-signal-reply-port
authorGNU Libc Maintainers <debian-glibc@lists.debian.org>
Fri, 3 Jan 2025 10:56:38 +0000 (11:56 +0100)
committerAurelien Jarno <aurel32@debian.org>
Fri, 3 Jan 2025 10:56:38 +0000 (11:56 +0100)
commit 7fa9e786b6e8f78675ecc30d7eaa200e1ee259b9
Author: Samuel Thibault <samuel.thibault@ens-lyon.org>
Date:   Thu Dec 26 23:11:28 2024 +0100

    hurd: Avoid asm statements which return

    They are not supposed to change flow control.

    This fixes miscompilation with gcc 14.2.0 which then drops code, see
    https://lists.gnu.org/archive/html/bug-hurd/2024-11/msg00145.html

Gbp-Pq: Topic hurd-i386
Gbp-Pq: Name git-signal-reply-port.diff

sysdeps/mach/hurd/dl-sysdep.c
sysdeps/mach/hurd/i386/sigreturn.c
sysdeps/mach/hurd/init-first.c
sysdeps/mach/hurd/x86_64/sigreturn.c
sysdeps/mach/x86/sysdep.h

index 6ba00e413da1de6a0e6f3d32e05fa42966eaa126..6506994d02e9395c0e033217c923eed4029072c4 100644 (file)
@@ -231,6 +231,8 @@ _dl_sysdep_start (void **start_argptr,
   abort ();
 }
 
+RETURN_TO_TRAMPOLINE();
+
 void
 _dl_sysdep_start_cleanup (void)
 {
index 1333ca5b54b365627007c1cd6d33551e3749fe46..2efabac703ee0f0cfa9e2f2cfb48584e804f3592 100644 (file)
@@ -15,8 +15,6 @@
    License along with the GNU C Library; if not, see
    <https://www.gnu.org/licenses/>.  */
 
-register int *sp asm ("%esp");
-
 #include <hurd.h>
 #include <hurd/signal.h>
 #include <hurd/msg.h>
@@ -54,29 +52,36 @@ __sigreturn2 (int *usp, struct sigcontext *scp)
                                  MACH_PORT_RIGHT_RECEIVE, -1);
   THREAD_SETMEM (THREAD_SELF, reply_port, scp->sc_reply_port);
 
-  sp = usp;
-#define A(line) asm volatile (#line)
-  /* The members in the sigcontext are arranged in this order
-     so we can pop them easily.  */
-
-  /* Pop the segment registers (except %cs and %ss, done last).  */
-  A (popl %gs);
-  A (popl %fs);
-  A (popl %es);
-  A (popl %ds);
-  /* Pop the general registers.  */
-  A (popa);
-  /* Pop the processor flags.  */
-  A (popf);
-  /* Return to the saved PC.  */
-  A (ret);
-
-  /* Firewall.  */
-  A (hlt);
-#undef A
-  __builtin_unreachable ();
+  void sigreturn2_trampoline (int *usp) __attribute__ ((__noreturn__));
+  sigreturn2_trampoline (usp);
 }
 
+asm("sigreturn2_trampoline:\n"
+
+    /* Restore thread stack */
+    "movl 4(%esp),%esp\n"
+
+    /* The members in the sigcontext are arranged in this order
+       so we can pop them easily.  */
+
+    /* Pop the segment registers (except %cs and %ss, done last).  */
+    "popl %gs\n"
+    "popl %fs\n"
+    "popl %es\n"
+    "popl %ds\n"
+
+    /* Pop the general registers.  */
+    "popa\n"
+
+    /* Pop the processor flags.  */
+    "popf\n"
+
+    /* Return to the saved PC.  */
+    "ret\n"
+
+    /* Firewall.  */
+    "hlt\n");
+
 int
 __sigreturn (struct sigcontext *scp)
 {
@@ -142,16 +147,21 @@ __sigreturn (struct sigcontext *scp)
     *--usp = 0;
     *--usp = (int) __sigreturn2;
 
+
+    void sigreturn_trampoline (int *usp) __attribute__ ((__noreturn__));
+    sigreturn_trampoline (usp);
+  }
+}
+
+asm("sigreturn_trampoline:\n"
+
     /* Restore thread stack */
-    sp = usp;
+    "movl 4(%esp),%esp\n"
+
     /* Return into __sigreturn2.  */
-    asm volatile ("ret");
-    /* Firewall.  */
-    asm volatile ("hlt");
-  }
+    "ret\n"
 
-  /* NOTREACHED */
-  return -1;
-}
+    /* Firewall.  */
+    "hlt\n");
 
 weak_alias (__sigreturn, sigreturn)
index 5777c44c37758c15fea29047a237cd7f185733bb..445f67957563c47acc2b2fd69f6427e2725242ea 100644 (file)
@@ -249,6 +249,8 @@ _hurd_stack_setup (void **argptr)
   _hurd_startup (argptr, &doinit);
   __builtin_unreachable ();
 }
+
+RETURN_TO_TRAMPOLINE();
 #endif
 
 
index 7a0193497dfec71633c45066f2be3fb8863320e8..5206cac44cce68a21187b2e1bc7bcccacf46f508 100644 (file)
@@ -46,31 +46,32 @@ __sigreturn2 (struct hurd_sigstate *ss, uintptr_t *usp,
                                  MACH_PORT_RIGHT_RECEIVE, -1);
   THREAD_SETMEM (THREAD_SELF, reply_port, sc_reply_port);
 
-  asm volatile (
+  void sigreturn2_trampoline (uintptr_t *usp) __attribute__ ((__noreturn__));
+  sigreturn2_trampoline (usp);
+}
+
+asm("sigreturn2_trampoline:\n"
                 /* Point the stack to the register dump.  */
-                "movq %0, %%rsp\n"
+                "movq %rdi, %rsp\n"
                 /* Pop off the registers.  */
-                "popq %%r8\n"
-                "popq %%r9\n"
-                "popq %%r10\n"
-                "popq %%r11\n"
-                "popq %%r12\n"
-                "popq %%r13\n"
-                "popq %%r14\n"
-                "popq %%r15\n"
-                "popq %%rdi\n"
-                "popq %%rsi\n"
-                "popq %%rbp\n"
-                "popq %%rbx\n"
-                "popq %%rdx\n"
-                "popq %%rcx\n"
-                "popq %%rax\n"
+                "popq %r8\n"
+                "popq %r9\n"
+                "popq %r10\n"
+                "popq %r11\n"
+                "popq %r12\n"
+                "popq %r13\n"
+                "popq %r14\n"
+                "popq %r15\n"
+                "popq %rdi\n"
+                "popq %rsi\n"
+                "popq %rbp\n"
+                "popq %rbx\n"
+                "popq %rdx\n"
+                "popq %rcx\n"
+                "popq %rax\n"
                 "popfq\n"
                 /* Restore %rip and %rsp with a single instruction.  */
-                "retq $128" :
-                : "rm" (usp));
-  __builtin_unreachable ();
-}
+                "retq $128" );
 
 int
 __sigreturn (struct sigcontext *scp)
@@ -152,16 +153,18 @@ __sigreturn (struct sigcontext *scp)
   *--usp = scp->sc_r9;
   *--usp = scp->sc_r8;
 
+  void sigreturn_trampoline (struct hurd_sigstate *ss, uintptr_t *usp,
+                             mach_port_t sc_reply_port)
+                             __attribute__ ((__noreturn__));
+  sigreturn_trampoline (ss, usp, sc_reply_port);
+}
+
+asm("sigreturn_trampoline:\n"
   /* Switch to the user's stack that we have just prepared, and call
-     __sigreturn2.  Clobber "memory" to make sure GCC flushes the stack
-     setup to actual memory.  We align the stack as per the ABI, but pass
+     __sigreturn2.  We align the stack as per the ABI, but pass
      the original usp to __sigreturn2 as an argument.  */
-  asm volatile ("movq %1, %%rsp\n"
-                "andq $-16, %%rsp\n"
-                "call __sigreturn2" :
-                : "D" (ss), "S" (usp), "d" (sc_reply_port)
-                : "memory");
-  __builtin_unreachable ();
-}
+                "movq %rsi, %rsp\n"
+                "andq $-16, %rsp\n"
+                "call __sigreturn2");
 
 weak_alias (__sigreturn, sigreturn)
index 63be5638e8fcb17f3f3dc17a0d3f035d59fc752b..27d5dd60af70bffb8a1c979cce943e42c8ed766f 100644 (file)
 #undef ENTRY
 #undef ALIGN
 
+#ifndef __ASSEMBLER__
+void return_to_trampoline(intptr_t *sp, void *pc, intptr_t retval)
+    __attribute__((__noreturn__));
+#endif
+
+#define RETURN_TO return_to_trampoline
+
 #ifdef __x86_64__
-#define RETURN_TO(sp, pc, retval) \
-  asm volatile ("movq %0, %%rsp; jmp %*%1 # %2" \
-               : : "g" (sp), "r" (pc), "a" (retval))
+#define RETURN_TO_TRAMPOLINE() \
+  asm ("return_to_trampoline:\n" \
+       "movq %rdx, %rax\n" \
+       "movq %rdi, %rsp\n" \
+       "jmp *%rsi\n");
 /* This should be rearranged, but at the moment this file provides
    the most useful definitions for assembler syntax details.  */
 #include <sysdeps/unix/x86_64/sysdep.h>
 #else
-#define RETURN_TO(sp, pc, retval) \
-  asm volatile ("movl %0, %%esp; jmp %*%1 # %2" \
-               : : "g" (sp), "r" (pc), "a" (retval))
+#define RETURN_TO_TRAMPOLINE() \
+  asm ("return_to_trampoline:\n" \
+       "movl 12(%esp), %eax\n" \
+       "movl 8(%esp), %edx\n" \
+       "movl 4(%esp), %esp\n" \
+       "jmp *%edx\n");
 #include <sysdeps/unix/i386/sysdep.h>
 #endif