]> Savannah Git Hosting - gnulib.git/commitdiff
sigsegv: Add tentative support for Hurd/x86_64.
authorBruno Haible <bruno@clisp.org>
Mon, 15 May 2023 16:33:47 +0000 (18:33 +0200)
committerBruno Haible <bruno@clisp.org>
Mon, 15 May 2023 16:35:22 +0000 (18:35 +0200)
Based on explanations by Sergey Bugaev <bugaevc@gmail.com>.

* lib/sigsegv.c: Update from libsigsegv/src/fault-hurd-i386-old.h.

ChangeLog
lib/sigsegv.c

index ade908c9720f490cbf1b4fac1bf25108a4a4af48..b894505c2beaebcfc5c88aafe16551d7d179c063 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,9 @@
+2023-05-15  Bruno Haible  <bruno@clisp.org>
+
+       sigsegv: Add tentative support for Hurd/x86_64.
+       Based on explanations by Sergey Bugaev <bugaevc@gmail.com>.
+       * lib/sigsegv.c: Update from libsigsegv/src/fault-hurd-i386-old.h.
+
 2023-05-15  Paul Eggert  <eggert@cs.ucla.edu>
 
        file-has-acl: improve port to Fedora 39
index aadba4e060889bd76c0e3e6e08697088fca581f4..8263d9b7bdfe4c1e3655b4f2e1ad96dc7c0eeabb 100644 (file)
@@ -361,7 +361,7 @@ int libsigsegv_version = LIBSIGSEGV_VERSION;
 
 #if defined __GNU__ /* Hurd */
 
-# define SIGSEGV_FAULT_HANDLER_ARGLIST  int sig, int code, struct sigcontext *scp
+# define SIGSEGV_FAULT_HANDLER_ARGLIST  int sig, long code, struct sigcontext *scp
 # define SIGSEGV_FAULT_ADDRESS  (unsigned long) code
 # define SIGSEGV_FAULT_CONTEXT  scp
 
@@ -370,11 +370,29 @@ int libsigsegv_version = LIBSIGSEGV_VERSION;
 
 /* scp points to a 'struct sigcontext' (defined in
    glibc/sysdeps/mach/hurd/x86_64/bits/sigcontext.h).
-   The registers, at the moment the signal occurred, get pushed on the stack
-   through gnumach/x86_64/locore.S:alltraps and then copied into the struct
-   through glibc/sysdeps/mach/hurd/x86/trampoline.c.  */
-/* sc_rsp is unused (not set by gnumach/x86_64/locore.S:alltraps).  We need
-   to use sc_ursp.  */
+   The registers, at the moment the signal occurred, get pushed on the kernel
+   stack through gnumach/x86_64/locore.S:alltraps. They are denoted by a
+   'struct i386_saved_state' (defined in gnumach/i386/i386/thread.h).
+   Upon invocation of the Mach interface function thread_get_state
+   <https://www.gnu.org/software/hurd/gnumach-doc/Thread-Execution.html>
+   (= __thread_get_state in glibc), defined in gnumach/kern/thread.c,
+   the function thread_getstatus, defined in gnumach/i386/i386/pcb.c, copies the
+   register values in a different arrangement into a 'struct i386_thread_state',
+   defined in gnumach/i386/include/mach/i386/thread_status.h. (Different
+   arrangement: trapno, err get dropped; different order of r8...r15; also rsp
+   gets set to 0.)
+   This 'struct i386_thread_state' is actually the 'basic' part of a
+   'struct machine_thread_all_state', defined in
+   glibc/sysdeps/mach/x86/thread_state.h.
+   From there, the function _hurd_setup_sighandler, defined in
+   glibc/sysdeps/mach/hurd/x86/trampoline.c,
+   1. sets rsp to the same value as ursp,
+   2. copies the 'struct i386_thread_state' into the appropriate part of a
+      'struct sigcontext', defined in
+      glibc/sysdeps/mach/hurd/x86_64/bits/sigcontext.h.  */
+/* Both sc_rsp and sc_ursp have the same value.
+   It appears more reliable to use sc_ursp because sc_rsp is marked as
+   "not used".  */
 #  define SIGSEGV_FAULT_STACKPOINTER  scp->sc_ursp
 
 # elif defined __i386__
@@ -382,12 +400,28 @@ int libsigsegv_version = LIBSIGSEGV_VERSION;
 
 /* scp points to a 'struct sigcontext' (defined in
    glibc/sysdeps/mach/hurd/i386/bits/sigcontext.h).
-   The registers, at the moment the signal occurred, get pushed on the stack
-   through gnumach/i386/i386/locore.S:alltraps and then copied into the struct
-   through glibc/sysdeps/mach/hurd/x86/trampoline.c.  */
-/* Both sc_esp and sc_uesp appear to have the same value.
-   It appears more reliable to use sc_uesp because it is labelled as
-   "old esp, if trapped from user".  */
+   The registers, at the moment the signal occurred, get pushed on the kernel
+   stack through gnumach/i386/i386/locore.S:alltraps. They are denoted by a
+   'struct i386_saved_state' (defined in gnumach/i386/i386/thread.h).
+   Upon invocation of the Mach interface function thread_get_state
+   <https://www.gnu.org/software/hurd/gnumach-doc/Thread-Execution.html>
+   (= __thread_get_state in glibc), defined in gnumach/kern/thread.c,
+   the function thread_getstatus, defined in gnumach/i386/i386/pcb.c, copies the
+   register values in a different arrangement into a 'struct i386_thread_state',
+   defined in gnumach/i386/include/mach/i386/thread_status.h. (Different
+   arrangement: trapno, err get dropped; also esp gets set to 0.)
+   This 'struct i386_thread_state' is actually the 'basic' part of a
+   'struct machine_thread_all_state', defined in
+   glibc/sysdeps/mach/x86/thread_state.h.
+   From there, the function _hurd_setup_sighandler, defined in
+   glibc/sysdeps/mach/hurd/x86/trampoline.c,
+   1. sets esp to the same value as uesp,
+   2. copies the 'struct i386_thread_state' into the appropriate part of a
+      'struct sigcontext', defined in
+      glibc/sysdeps/mach/hurd/i386/bits/sigcontext.h.  */
+/* Both sc_esp and sc_uesp have the same value.
+   It appears more reliable to use sc_uesp because sc_esp is marked as
+   "not used".  */
 #  define SIGSEGV_FAULT_STACKPOINTER  scp->sc_uesp
 
 # endif