-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Sun Apr 2 13:13:52 1995 Roland McGrath <roland@churchy.gnu.ai.mit.edu>
* sysdeps/mach/hurd/i386/trampoline.c: Add a link to SS->active_resources, so that _hurdsig_longjmp_from_handler will be called when a longjmp unwinds the signal frame. * sysdeps/mach/hurd/i386/sigreturn.c: Remove the link on the SS->active_resources chain added by _hurd_setup_sighandler. * hurd/sigunwind.c: New file. * hurd/Makefile (sig): Add sigunwind. * Makerules (lib%.so: lib%_pic.a): Remove dir name from $*. * MakeTAGS (tags-sources): Include $(all-dist). [subdir] (all-dist): Define to $(distribute).
- Loading branch information
Roland McGrath
committed
Apr 2, 1995
1 parent
193ce8d
commit e607b49
Showing
7 changed files
with
183 additions
and
5 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,135 @@ | ||
/* longjmp cleanup function for unwinding past signal handlers. | ||
Copyright (C) 1995 Free Software Foundation, Inc. | ||
This file is part of the GNU C Library. | ||
The GNU C Library is free software; you can redistribute it and/or | ||
modify it under the terms of the GNU Library General Public License as | ||
published by the Free Software Foundation; either version 2 of the | ||
License, or (at your option) any later version. | ||
The GNU C Library is distributed in the hope that it will be useful, | ||
but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
Library General Public License for more details. | ||
You should have received a copy of the GNU Library General Public | ||
License along with the GNU C Library; see the file COPYING.LIB. If | ||
not, write to the Free Software Foundation, Inc., 675 Mass Ave, | ||
Cambridge, MA 02139, USA. */ | ||
|
||
#include <hurd.h> | ||
#include "thread_state.h" | ||
#include <setjmp.h> | ||
#include <assert.h> | ||
|
||
extern void _hurd_longjmp_thread_state (struct machine_thread_state *, | ||
jmp_buf env, int value); | ||
|
||
|
||
/* _hurd_setup_sighandler puts a link on the `active resources' chain so that | ||
_longjmp_unwind will call this function with the `struct sigcontext *' | ||
describing the context interrupted by the signal, when `longjmp' is jumping | ||
to an environment that unwinds past the interrupted frame. */ | ||
|
||
void | ||
_hurdsig_longjmp_from_handler (void *data, jmp_buf env, int val) | ||
{ | ||
struct sigcontext *scp = data; | ||
struct hurd_sigstate *ss = _hurd_self_sigstate (); | ||
int onstack; | ||
inline void cleanup (void) | ||
{ | ||
/* Destroy the MiG reply port used by the signal handler, and restore | ||
the reply port in use by the thread when interrupted. */ | ||
mach_port_t *reply_port = | ||
(mach_port_t *) __hurd_threadvar_location (_HURD_THREADVAR_MIG_REPLY); | ||
if (*reply_port) | ||
__mach_port_destroy (__mach_task_self (), *reply_port); | ||
*reply_port = scp->sc_reply_port; | ||
} | ||
|
||
__spin_lock (&ss->lock); | ||
/* We should only ever be called from _longjmp_unwind (in jmp-unwind.c), | ||
which calls us inside a critical section. */ | ||
assert (ss->critical_section); | ||
/* Are we on the alternate signal stack now? */ | ||
onstack = (ss->sigaltstack.ss_flags & SA_ONSTACK); | ||
__spin_unlock (&ss->lock); | ||
|
||
if (onstack && ! scp->sc_onstack) | ||
{ | ||
/* We are unwinding off the signal stack. We must use sigreturn to | ||
do it robustly. Mutate the sigcontext so that when sigreturn | ||
resumes from that context, it will be as if `__longjmp (ENV, VAL)' | ||
were done. */ | ||
|
||
struct hurd_userlink *link; | ||
|
||
/* Continue _longjmp_unwind's job of running the unwind | ||
forms for frames being unwound, since we will not | ||
return to its loop like this one, which called us. */ | ||
for (link = ss->active_resources; | ||
link && _JMPBUF_UNWINDS (env[0].__jmpbuf, link); | ||
link = link->thread.next) | ||
if (_hurd_userlink_unlink (link)) | ||
{ | ||
if (link->cleanup == &_hurdsig_longjmp_from_handler) | ||
{ | ||
/* We are unwinding past another signal handler invocation. | ||
Just finish the cleanup for this (inner) one, and then | ||
swap SCP to restore to the outer context. */ | ||
cleanup (); | ||
scp = link->cleanup_data; | ||
} | ||
else | ||
(*link->cleanup) (link->cleanup_data, env, val); | ||
} | ||
|
||
#define sc_machine_thread_state paste(sc_,machine_thread_state) | ||
#define paste(a,b) paste1(a,b) | ||
#define paste1(a,b) a##b | ||
|
||
/* There are no more unwind forms to be run! | ||
Now we can just have the sigreturn do the longjmp for us. */ | ||
_hurd_longjmp_thread_state | ||
((struct machine_thread_state *) &scp->sc_machine_thread_state, | ||
env, val); | ||
|
||
/* Restore to the same current signal mask. If sigsetjmp saved the | ||
mask, longjmp has already restored it as desired; if not, we | ||
should leave it as it is. */ | ||
scp->sc_mask = ss->blocked; | ||
|
||
/* sigreturn expects the link added by _hurd_setup_sighandler | ||
to still be there, but _longjmp_unwind removed it just before | ||
calling us. Put it back now so sigreturn can find it. */ | ||
link = (void *) &scp[1]; | ||
assert (! link->resource.next && ! link->resource.prevp); | ||
assert (link->thread.next == ss->active_resources); | ||
assert (link->thread.prevp = &ss->active_resources); | ||
if (link->thread.next) | ||
link->thread.next->thread.prevp = &link->thread.next; | ||
ss->active_resources = link; | ||
|
||
/* We must momentarily exit the critical section so that sigreturn | ||
does not get upset with us. But we don't want signal handlers | ||
running right now, because we are presently in the bogus state of | ||
having run all the unwind forms back to ENV's frame, but our SP is | ||
still inside those unwound frames. */ | ||
__spin_lock (&ss->lock); | ||
ss->critical_section = 0; | ||
ss->blocked = ~(sigset_t) 0 & ~_SIG_CANT_MASK; | ||
__spin_unlock (&ss->lock); | ||
|
||
/* Restore to the modified signal context that now | ||
performs `longjmp (ENV, VAL)'. */ | ||
__sigreturn (scp); | ||
assert (! "sigreturn returned!"); | ||
} | ||
|
||
/* We are not unwinding off the alternate signal stack. So nothing | ||
really funny is going on here. We can just clean up this handler | ||
frame and let _longjmp_unwind continue unwinding. */ | ||
cleanup (); | ||
ss->intr_port = scp->sc_intr_port; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters