summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBruno Haible <bruno@clisp.org>2023-05-15 18:33:47 +0200
committerBruno Haible <bruno@clisp.org>2023-05-15 18:35:22 +0200
commitf3059fb80504e1f4e1e4c34562508f404ce7b0f7 (patch)
tree1c29363ec7dc53cc66a7cc0b7a3aed224216a01d
parent735716931755c74f3788ac83fead717c0bb22dfe (diff)
downloadgnulib-f3059fb80504e1f4e1e4c34562508f404ce7b0f7.tar.gz
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.
-rw-r--r--ChangeLog6
-rw-r--r--lib/sigsegv.c58
2 files changed, 52 insertions, 12 deletions
diff --git a/ChangeLog b/ChangeLog
index ade908c972..b894505c2b 100644
--- 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
diff --git a/lib/sigsegv.c b/lib/sigsegv.c
index aadba4e060..8263d9b7bd 100644
--- a/lib/sigsegv.c
+++ b/lib/sigsegv.c
@@ -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