public inbox for libc-alpha@sourceware.org
 help / color / mirror / Atom feed
From: Sergey Bugaev <bugaevc@gmail.com>
To: bug-hurd@gnu.org, libc-alpha@sourceware.org
Cc: Samuel Thibault <samuel.thibault@gnu.org>,
	Sergey Bugaev <bugaevc@gmail.com>
Subject: [PATCH v2 18.2/34] hurd: Port trampoline.c to x86_64
Date: Mon,  3 Apr 2023 14:56:21 +0300	[thread overview]
Message-ID: <20230403115621.258636-3-bugaevc@gmail.com> (raw)
In-Reply-To: <20230403115621.258636-1-bugaevc@gmail.com>

Signed-off-by: Sergey Bugaev <bugaevc@gmail.com>
---
 sysdeps/mach/hurd/{i386 => x86}/trampoline.c | 158 ++++++++++++++++++-
 1 file changed, 151 insertions(+), 7 deletions(-)
 rename sysdeps/mach/hurd/{i386 => x86}/trampoline.c (68%)

diff --git a/sysdeps/mach/hurd/i386/trampoline.c b/sysdeps/mach/hurd/x86/trampoline.c
similarity index 68%
rename from sysdeps/mach/hurd/i386/trampoline.c
rename to sysdeps/mach/hurd/x86/trampoline.c
index 9cd60b9c..e13c5d85 100644
--- a/sysdeps/mach/hurd/i386/trampoline.c
+++ b/sysdeps/mach/hurd/x86/trampoline.c
@@ -1,4 +1,4 @@
-/* Set thread_state for sighandler, and sigcontext to recover.  i386 version.
+/* Set thread_state for sighandler, and sigcontext to recover.  x86 version.
    Copyright (C) 1994-2023 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
 
@@ -46,7 +46,13 @@ static void fill_siginfo (siginfo_t *si, int signo,
   if (detail->exc == EXC_BAD_ACCESS)
     si->si_addr = (void *) detail->exc_subcode;
   else
-    si->si_addr = (void *) state->basic.eip;
+    {
+#ifdef __x86_64__
+      si->si_addr = (void *) state->basic.rip;
+#else
+      si->si_addr = (void *) state->basic.eip;
+#endif
+    }
 
   /* XXX On SIGCHLD, this should be the exit status of the child
    * process.  We would need a protocol change for the proc server
@@ -63,17 +69,26 @@ static void fill_ucontext (ucontext_t *uc, const struct sigcontext *sc)
   uc->uc_flags = 0;
   uc->uc_link = NULL;
   uc->uc_sigmask = sc->sc_mask;
+#ifdef __x86_64__
+  uc->uc_stack.ss_sp = (__ptr_t) sc->sc_ursp;
+#else
   uc->uc_stack.ss_sp = (__ptr_t) sc->sc_uesp;
+#endif
   uc->uc_stack.ss_size = 0;
   uc->uc_stack.ss_flags = 0;
 
   /* Registers.  */
+#ifdef __x86_64__
+  memcpy (&uc->uc_mcontext.gregs[REG_GSFS], &sc->sc_gs,
+          (REG_ERR - REG_GSFS) * sizeof (long));
+#else
   memcpy (&uc->uc_mcontext.gregs[REG_GS], &sc->sc_gs,
-	  (REG_TRAPNO - REG_GS) * sizeof (int));
-  uc->uc_mcontext.gregs[REG_TRAPNO] = 0;
-  uc->uc_mcontext.gregs[REG_ERR] = 0;
+          (REG_TRAPNO - REG_GS) * sizeof (int));
   memcpy (&uc->uc_mcontext.gregs[REG_EIP], &sc->sc_eip,
 	  (NGREG - REG_EIP) * sizeof (int));
+#endif
+  uc->uc_mcontext.gregs[REG_TRAPNO] = 0;
+  uc->uc_mcontext.gregs[REG_ERR] = 0;
 
   /* XXX FPU state.  */
   memset (&uc->uc_mcontext.fpregs, 0, sizeof (fpregset_t));
@@ -93,7 +108,14 @@ _hurd_setup_sighandler (struct hurd_sigstate *ss, const struct sigaction *action
   struct sigcontext *scp;
   struct
     {
-      int signo;
+      union
+        {
+          int signo;
+          /* Make sure signo takes up a pointer-sized slot on the stack.
+             (This should already be the case considering the siginfop
+             pointer below, but better be explicit.)  */
+          void *_pointer_sized;
+        };
       union
 	{
 	  /* Extra arguments for traditional signal handlers */
@@ -110,6 +132,10 @@ _hurd_setup_sighandler (struct hurd_sigstate *ss, const struct sigaction *action
 	      ucontext_t *uctxp;            /* Points to uctx, below.  */
 	    } posix;
 	};
+
+#ifdef __x86_64__
+      void *_pad;
+#endif
       void *sigreturn_addr;
       void *sigreturn_returns_here;
       struct sigcontext *return_scp; /* Same; arg to sigreturn.  */
@@ -121,6 +147,11 @@ _hurd_setup_sighandler (struct hurd_sigstate *ss, const struct sigaction *action
       siginfo_t siginfo;
     } *stackframe;
 
+#ifdef __x86_64__
+  _Static_assert (offsetof (typeof (*stackframe), sigreturn_addr) % 16 == 0,
+                  "sigreturn_addr must be 16-byte aligned");
+#endif
+
   if (ss->context)
     {
       /* We have a previous sigcontext that sigreturn was about
@@ -142,7 +173,11 @@ _hurd_setup_sighandler (struct hurd_sigstate *ss, const struct sigaction *action
   /* Save the original SP in the gratuitous `esp' slot.
      We may need to reset the SP (the `uesp' slot) to avoid clobbering an
      interrupted RPC frame.  */
+#ifdef __x86_64__
+  state->basic.rsp = state->basic.ursp;
+#else
   state->basic.esp = state->basic.uesp;
+#endif
 
   if ((action->sa_flags & SA_ONSTACK)
       && !(ss->sigaltstack.ss_flags & (SS_DISABLE|SS_ONSTACK)))
@@ -151,7 +186,22 @@ _hurd_setup_sighandler (struct hurd_sigstate *ss, const struct sigaction *action
       ss->sigaltstack.ss_flags |= SS_ONSTACK;
     }
   else
-    sigsp = (char *) state->basic.uesp;
+    {
+#ifdef __x86_64__
+      /* Per the ABI, we're not supposed to clobber 128 bytes below
+         SP -- the red zone.  */
+      sigsp = (char *) state->basic.ursp - 128;
+#else
+      sigsp = (char *) state->basic.uesp;
+#endif
+    }
+
+#ifdef __x86_64__
+  /* Align SP at 16 bytes.  Coupled with the fact that sigreturn_addr is
+     16-byte aligned within the stackframe struct, this ensures that it ends
+     up on a 16-byte aligned address, as required by the ABI.  */
+  sigsp = (void *) ((uintptr_t) sigsp & 16UL);
+#endif
 
   /* Push the arguments to call `trampoline' on the stack.  */
   sigsp -= sizeof (*stackframe);
@@ -238,6 +288,52 @@ _hurd_setup_sighandler (struct hurd_sigstate *ss, const struct sigaction *action
     }
 
   /* Modify the thread state to call the trampoline code on the new stack.  */
+#ifdef __x86_64__
+  if (rpc_wait)
+    {
+      /* The signalee thread was blocked in a mach_msg_trap system call,
+         still waiting for a reply.  We will have it run the special
+         trampoline code which retries the message receive before running
+         the signal handler.
+
+         To do this we change the OPTION argument (in rsi) to enable only
+         message reception, since the request message has already been
+         sent.  */
+
+      assert (state->basic.rsi & MACH_RCV_MSG);
+      /* Disable the message-send, since it has already completed.  The
+         calls we retry need only wait to receive the reply message.  */
+      state->basic.rsi &= ~MACH_SEND_MSG;
+
+      /* Limit the time to receive the reply message, in case the server
+         claimed that `interrupt_operation' succeeded but in fact the RPC
+         is hung.  */
+      state->basic.rsi |= MACH_RCV_TIMEOUT;
+      state->basic.r9 = _hurd_interrupted_rpc_timeout;
+
+      state->basic.rip = (uintptr_t) rpc_wait_trampoline;
+      /* The reply-receiving trampoline code runs initially on the original
+         user stack.  We pass it the signal stack pointer in %rbx.  */
+      state->basic.rbx = (uintptr_t) sigsp;
+      /* After doing the message receive, the trampoline code will need to
+         update the %rax value to be restored by sigreturn.  To simplify
+         the assembly code, we pass the address of its slot in SCP to the
+         trampoline code in %r12.  */
+      state->basic.r12 = (uintptr_t) &scp->sc_rax;
+    }
+  else
+    {
+      state->basic.rip = (uintptr_t) trampoline;
+      state->basic.ursp = (uintptr_t) sigsp;
+    }
+  /* We pass the handler function to the trampoline code in %r13.  */
+  state->basic.r13 = (uintptr_t) handler;
+
+  /* The x86 ABI says the DF bit is clear on entry to any function.  */
+  state->basic.rfl &= ~EFL_DF;
+
+#else
+
   if (rpc_wait)
     {
       /* The signalee thread was blocked in a mach_msg_trap system call,
@@ -290,6 +386,7 @@ _hurd_setup_sighandler (struct hurd_sigstate *ss, const struct sigaction *action
 
   /* The x86 ABI says the DF bit is clear on entry to any function.  */
   state->basic.efl &= ~EFL_DF;
+#endif
 
   return scp;
 }
@@ -301,6 +398,52 @@ _hurd_setup_sighandler (struct hurd_sigstate *ss, const struct sigaction *action
    - in gcc: libgcc/config/i386/gnu-unwind.h x86_gnu_fallback_frame_state,
    - in gdb: gdb/i386-gnu-tdep.c gnu_sigtramp_code.  */
 
+#ifdef __x86_64__
+asm ("rpc_wait_trampoline:\n"
+  /* This is the entry point when we have an RPC reply message to receive
+     before running the handler.  The MACH_MSG_SEND bit has already been
+     cleared in the OPTION argument in our %rsi.  The interrupted user
+     stack pointer has not been changed, so the system call can find its
+     arguments; the signal stack pointer is in %rbx.  For our convenience,
+     %r12 points to the sc_rax member of the sigcontext.  */
+     "movq $-25, %rax\n"	/* mach_msg_trap */
+     "syscall\n"
+     /* When the sigcontext was saved, %rax was MACH_RCV_INTERRUPTED.  But
+        now the message receive has completed and the original caller of
+        the RPC (i.e. the code running when the signal arrived) needs to
+        see the final return value of the message receive in %rax.  So
+        store the new %rax value into the sc_rax member of the sigcontext
+        (whose address is in %r12 to make this code simpler).  */
+     "movq %rax, (%r12)\n"
+     /* Switch to the signal stack.  */
+     "movq %rbx, %rsp\n"
+
+     "trampoline:\n"
+     /* Entry point for running the handler normally.  The arguments to the
+        handler function are on the top of the stack, same as in the i386
+        version:
+
+        0(%rsp)  SIGNO
+        8(%rsp)  SIGCODE
+        16(%rsp) SCP
+
+        Pop them off to the registers, to pass as arguments to the handler.
+     */
+     "popq %rdi\n"
+     "popq %rsi\n"
+     "popq %rdx\n"
+     /* Pop the _pad member to make the stack 16-byte aligned, as per the
+        ABI.  */
+     "addq $8, %rsp\n"
+     "call *%r13\n"		/* Call the handler function.  */
+     /* The word at the top of stack is &__sigreturn; following are a dummy
+        word to fill the slot for the address for __sigreturn to return to,
+        and a copy of SCP for __sigreturn's argument.  Load the SCP as for a
+        call, and "return" to calling __sigreturn (SCP); this call never
+        returns.  */
+     "movq 16(%rsp), %rdi\n"
+     "ret");
+#else
 asm ("rpc_wait_trampoline:\n");
   /* This is the entry point when we have an RPC reply message to receive
      before running the handler.  The MACH_MSG_SEND bit has already been
@@ -336,6 +479,7 @@ asm ("call *%edx\n"		/* Call the handler function.  */
 	and a copy of SCP for __sigreturn's argument.  "Return" to calling
 	__sigreturn (SCP); this call never returns.  */
      "ret");
+#endif
 
 asm ("firewall:\n"
      "hlt");
-- 
2.39.2


  parent reply	other threads:[~2023-04-03 11:56 UTC|newest]

Thread overview: 140+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-03-19 15:09 [RFC PATCH 00/34] The rest of the x86_64-gnu port Sergey Bugaev
2023-03-19 15:09 ` [RFC PATCH gnumach 01/34] Add i386_fsgs_base_state Sergey Bugaev
2023-04-02 22:43   ` Samuel Thibault
2023-03-19 15:09 ` [RFC PATCH gnumach 02/34] Remove bootstrap.defs Sergey Bugaev
2023-04-02 22:43   ` Samuel Thibault
2023-04-03  9:39     ` Sergey Bugaev
2023-03-19 15:09 ` [RFC PATCH gnumach 03/34] Make exception subcode a long Sergey Bugaev
2023-04-02 22:45   ` Samuel Thibault
2023-04-03  9:32     ` Sergey Bugaev
2023-04-06  2:11       ` Flávio Cruz
2023-04-10 23:52         ` Samuel Thibault
2023-03-19 15:09 ` [RFC PATCH glibc 04/34] hurd: " Sergey Bugaev
2023-04-02 22:52   ` Samuel Thibault
2023-03-19 15:09 ` [RFC PATCH glibc 05/34] hurd: Remove __hurd_threadvar_stack_{offset,mask} Sergey Bugaev
2023-04-02 22:53   ` Samuel Thibault
2023-03-19 15:09 ` [RFC PATCH glibc 06/34] hurd: Swap around two function calls Sergey Bugaev
2023-04-02 22:54   ` Samuel Thibault
2023-03-19 15:09 ` [RFC PATCH glibc 07/34] hurd: Fix file name in #error Sergey Bugaev
2023-04-02 22:55   ` Samuel Thibault
2023-03-19 15:09 ` [RFC PATCH glibc 08/34] hurd: Disable O_TRUNC and FS_RETRY_MAGICAL in rtld Sergey Bugaev
2023-04-02 22:57   ` Samuel Thibault
2023-03-19 15:09 ` [RFC PATCH glibc 09/34] hurd: Fix _hurd_setup_sighandler () signature Sergey Bugaev
2023-04-02 22:58   ` Samuel Thibault
2023-03-19 15:09 ` [RFC PATCH glibc 10/34] stdio-common: Fix building when !IS_IN (libc) Sergey Bugaev
2023-04-02 23:01   ` Samuel Thibault
2023-03-19 15:09 ` [RFC PATCH glibc 11/34] mach, hurd: Drop __libc_lock_self0 Sergey Bugaev
2023-04-02 23:02   ` Samuel Thibault
2023-03-19 15:09 ` [RFC PATCH glibc 12/34] hurd: More 64-bit integer casting fixes Sergey Bugaev
2023-04-02 23:03   ` Samuel Thibault
2023-03-19 15:09 ` [RFC PATCH glibc 13/34] x86-64: Disable prefer_map_32bit_exec tunable on non-Linux Sergey Bugaev
2023-04-02 23:09   ` Samuel Thibault
2023-04-03 10:10     ` Sergey Bugaev
2023-04-03 19:02       ` H.J. Lu
2023-04-03 20:11         ` Sergey Bugaev
2023-03-19 15:09 ` [RFC PATCH glibc 14/34] hurd: Move rtld-strncpy-c.c out of mach/hurd/ Sergey Bugaev
2023-04-02 23:10   ` Samuel Thibault
2023-03-19 15:09 ` [RFC PATCH glibc 15/34] hurd: Use uintptr_t for register values in trampoline.c Sergey Bugaev
2023-04-02 23:13   ` Samuel Thibault
2023-03-19 15:09 ` [RFC PATCH glibc 16/34] hurd: Add sys/ucontext.h and sigcontext.h for x86_64 Sergey Bugaev
2023-04-10 18:39   ` Samuel Thibault
2023-04-10 19:07     ` Sergey Bugaev
2023-04-10 19:21       ` Samuel Thibault
2023-04-10 18:58   ` Samuel Thibault
2023-04-10 19:13     ` Sergey Bugaev
2023-04-10 19:21       ` Samuel Thibault
2023-04-10 21:50         ` Sergey Bugaev
2023-04-10 22:23           ` Samuel Thibault
2023-03-19 15:10 ` [RFC PATCH glibc 17/34] hurd: Implement x86_64/intr-msg.h Sergey Bugaev
2023-04-10 18:41   ` Samuel Thibault
2023-03-19 15:10 ` [RFC PATCH glibc 18/34] hurd: Port trampoline.c to x86_64 Sergey Bugaev
2023-04-03 11:56   ` [PATCH v2 18.0/34] Alignment-respecting x86_64 trampoline.c Sergey Bugaev
2023-04-03 11:56     ` [PATCH v2 18.1/34] hurd: Do not declare local variables volatile Sergey Bugaev
2023-04-10 18:42       ` Samuel Thibault
2023-04-03 11:56     ` Sergey Bugaev [this message]
2023-04-10 19:04       ` [PATCH v2 18.2/34] hurd: Port trampoline.c to x86_64 Samuel Thibault
2023-04-10 21:33         ` Sergey Bugaev
2023-03-19 15:10 ` [RFC PATCH glibc 19/34] hurd: Move a couple of singal-related files to x86 Sergey Bugaev
2023-04-02 23:15   ` Samuel Thibault
2023-03-19 15:10 ` [RFC PATCH glibc 20/34] htl: Add tcb-offsets.sym for x86_64 Sergey Bugaev
2023-04-02 23:16   ` Samuel Thibault
2023-03-19 15:10 ` [RFC PATCH glibc 21/34] x86_64: Add rtld-stpncpy & rtld-strncpy Sergey Bugaev
2023-04-02 23:18   ` Samuel Thibault
2023-03-19 15:10 ` [RFC PATCH glibc 22/34] htl: Implement thread_set_pcsptp for x86_64 Sergey Bugaev
2023-04-02 23:19   ` Samuel Thibault
2023-03-19 15:10 ` [RFC PATCH glibc 23/34] elf: Stop including tls.h in ldsodefs.h Sergey Bugaev
2023-04-02 23:20   ` Samuel Thibault
2023-04-03  9:26     ` Sergey Bugaev
2023-04-10 21:26   ` Samuel Thibault
2023-03-19 15:10 ` [RFC PATCH glibc 24/34] hurd: Only check for TLS initialization inside rtld or in static builds Sergey Bugaev
2023-04-10 21:33   ` Samuel Thibault
2023-04-11 18:57   ` Samuel Thibault
2023-04-11 19:18     ` Samuel Thibault
2023-04-11 20:03     ` Samuel Thibault
2023-04-11 20:27     ` Sergey Bugaev
2023-04-11 21:23       ` Samuel Thibault
2023-04-12  8:36         ` Sergey Bugaev
2023-04-12  9:00           ` Samuel Thibault
2023-04-12 10:42             ` Sergey Bugaev
2023-04-12 10:45               ` Samuel Thibault
2023-04-12 17:18                 ` Sergey Bugaev
2023-04-12 23:46               ` Samuel Thibault
2023-04-13 10:02                 ` Sergey Bugaev
2023-04-13 10:10                   ` Samuel Thibault
2023-04-13 12:17                     ` Sergey Bugaev
2023-04-13 21:47                       ` Samuel Thibault
2023-04-13 22:21                         ` Samuel Thibault
2023-04-14  8:29                         ` Sergey Bugaev
2023-04-14  8:36                           ` Samuel Thibault
2023-04-14  8:53                             ` Sergey Bugaev
2023-04-14  9:09                               ` Samuel Thibault
2023-04-14  9:23                                 ` Sergey Bugaev
2023-04-14  9:31                                   ` Samuel Thibault
2023-04-17  7:16                               ` Samuel Thibault
2023-04-14 17:34   ` Samuel Thibault
2023-04-14 19:52     ` Sergey Bugaev
2023-03-19 15:10 ` [RFC PATCH glibc 25/34] hurd: Improve reply port handling when exiting signal handlers Sergey Bugaev
2023-04-10 22:03   ` Samuel Thibault
2023-04-11  7:44     ` Sergey Bugaev
2023-04-11 20:15       ` Samuel Thibault
2023-04-11 20:35         ` Sergey Bugaev
2023-04-12 22:54   ` Samuel Thibault
2023-03-19 15:10 ` [RFC PATCH glibc 26/34] hurd: Remove __hurd_local_reply_port Sergey Bugaev
2023-04-10 22:07   ` Samuel Thibault
2023-04-10 22:35     ` Samuel Thibault
2023-04-11  8:00     ` Sergey Bugaev
2023-04-11 20:18       ` Samuel Thibault
2023-04-13 11:58         ` [RFC PATCH glibc v2 " Sergey Bugaev
2023-04-13 13:12           ` Samuel Thibault
2023-04-13 13:20             ` Sergey Bugaev
2023-04-13 21:28               ` Samuel Thibault
2023-04-14 17:33           ` Samuel Thibault
2023-04-14 20:29             ` Sergey Bugaev
2023-04-15  6:45               ` Samuel Thibault
2023-04-15  7:34                 ` Sergey Bugaev
2023-04-15  7:42                   ` Samuel Thibault
2023-03-19 15:10 ` [RFC PATCH glibc 27/34] hurd: Don't leak __hurd_reply_port0 Sergey Bugaev
2023-04-10 22:25   ` Samuel Thibault
2023-03-19 15:10 ` [RFC PATCH glibc 28/34] hurd: Implement _hurd_longjmp_thread_state for x86_64 Sergey Bugaev
2023-04-02 23:23   ` Samuel Thibault
2023-03-19 15:10 ` [RFC PATCH glibc 29/34] hurd: Add vm_param.h " Sergey Bugaev
2023-04-02 23:24   ` Samuel Thibault
2023-03-19 15:10 ` [RFC PATCH glibc 30/34] hurd: Implement longjmp " Sergey Bugaev
2023-03-19 15:10 ` [RFC PATCH glibc 31/34] hurd: Microoptimize _hurd_self_sigstate () Sergey Bugaev
2023-04-02 23:26   ` Samuel Thibault
2023-03-19 15:10 ` [RFC PATCH glibc 32/34] hurd: Implement sigreturn for x86_64 Sergey Bugaev
2023-04-03 11:47   ` [PATCH v2] " Sergey Bugaev
2023-03-19 15:10 ` [RFC PATCH glibc 33/34] hurd: Create abilist files for lib{mach,hurd}user Sergey Bugaev
2023-03-19 15:19   ` Samuel Thibault
2023-03-19 15:39     ` Sergey Bugaev
2023-03-19 15:43       ` Samuel Thibault
2023-03-19 15:10 ` [RFC PATCH glibc 34/34] hurd: Add expected abilist files for x86_64 Sergey Bugaev
2023-03-19 18:04   ` Florian Weimer
2023-03-19 20:14     ` [PATCH v2] " Sergey Bugaev
2023-03-20  6:30       ` Florian Weimer
2023-03-19 16:44 ` [RFC PATCH 00/34] The rest of the x86_64-gnu port Luca
2023-03-20  5:03   ` Flávio Cruz
2023-04-02 23:30 ` Samuel Thibault
2023-04-10 19:20 ` Samuel Thibault
2023-04-10 21:24   ` Sergey Bugaev
2023-04-10 21:27     ` Samuel Thibault

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20230403115621.258636-3-bugaevc@gmail.com \
    --to=bugaevc@gmail.com \
    --cc=bug-hurd@gnu.org \
    --cc=libc-alpha@sourceware.org \
    --cc=samuel.thibault@gnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).