mirror of
https://https.git.savannah.gnu.org/git/gnulib.git
synced 2026-05-13 07:03:33 +00:00
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.
This commit is contained in:
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user