aboutsummaryrefslogtreecommitdiff
path: root/sysdeps
diff options
context:
space:
mode:
authorSamuel Thibault <samuel.thibault@ens-lyon.org>2024-12-26 23:11:28 +0100
committerSamuel Thibault <samuel.thibault@ens-lyon.org>2024-12-27 01:10:58 +0100
commit7fa9e786b6e8f78675ecc30d7eaa200e1ee259b9 (patch)
tree084b2c594e73a8ce5e413de177cc5285462a9345 /sysdeps
parent757ac24f8f2344e5f8afd2465c808d0f6adcc948 (diff)
downloadglibc-7fa9e786b6e8f78675ecc30d7eaa200e1ee259b9.zip
glibc-7fa9e786b6e8f78675ecc30d7eaa200e1ee259b9.tar.gz
glibc-7fa9e786b6e8f78675ecc30d7eaa200e1ee259b9.tar.bz2
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
Diffstat (limited to 'sysdeps')
-rw-r--r--sysdeps/mach/hurd/dl-sysdep.c2
-rw-r--r--sysdeps/mach/hurd/i386/sigreturn.c72
-rw-r--r--sysdeps/mach/hurd/init-first.c2
-rw-r--r--sysdeps/mach/hurd/x86_64/sigreturn.c63
-rw-r--r--sysdeps/mach/x86/sysdep.h24
5 files changed, 96 insertions, 67 deletions
diff --git a/sysdeps/mach/hurd/dl-sysdep.c b/sysdeps/mach/hurd/dl-sysdep.c
index 6ba00e4..6506994 100644
--- a/sysdeps/mach/hurd/dl-sysdep.c
+++ b/sysdeps/mach/hurd/dl-sysdep.c
@@ -231,6 +231,8 @@ _dl_sysdep_start (void **start_argptr,
abort ();
}
+RETURN_TO_TRAMPOLINE();
+
void
_dl_sysdep_start_cleanup (void)
{
diff --git a/sysdeps/mach/hurd/i386/sigreturn.c b/sysdeps/mach/hurd/i386/sigreturn.c
index 1333ca5..2efabac 100644
--- a/sysdeps/mach/hurd/i386/sigreturn.c
+++ b/sysdeps/mach/hurd/i386/sigreturn.c
@@ -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)
diff --git a/sysdeps/mach/hurd/init-first.c b/sysdeps/mach/hurd/init-first.c
index 5777c44..445f679 100644
--- a/sysdeps/mach/hurd/init-first.c
+++ b/sysdeps/mach/hurd/init-first.c
@@ -249,6 +249,8 @@ _hurd_stack_setup (void **argptr)
_hurd_startup (argptr, &doinit);
__builtin_unreachable ();
}
+
+RETURN_TO_TRAMPOLINE();
#endif
diff --git a/sysdeps/mach/hurd/x86_64/sigreturn.c b/sysdeps/mach/hurd/x86_64/sigreturn.c
index 7a01934..5206cac 100644
--- a/sysdeps/mach/hurd/x86_64/sigreturn.c
+++ b/sysdeps/mach/hurd/x86_64/sigreturn.c
@@ -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)
diff --git a/sysdeps/mach/x86/sysdep.h b/sysdeps/mach/x86/sysdep.h
index 63be563..27d5dd6 100644
--- a/sysdeps/mach/x86/sysdep.h
+++ b/sysdeps/mach/x86/sysdep.h
@@ -33,17 +33,29 @@
#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