diff options
author | Bruno Haible <bruno@clisp.org> | 2023-05-15 18:33:47 +0200 |
---|---|---|
committer | Bruno Haible <bruno@clisp.org> | 2023-05-15 18:35:22 +0200 |
commit | f3059fb80504e1f4e1e4c34562508f404ce7b0f7 (patch) | |
tree | 1c29363ec7dc53cc66a7cc0b7a3aed224216a01d /lib | |
parent | 735716931755c74f3788ac83fead717c0bb22dfe (diff) | |
download | gnulib-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.
Diffstat (limited to 'lib')
-rw-r--r-- | lib/sigsegv.c | 58 |
1 files changed, 46 insertions, 12 deletions
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 |