mirror of
https://sourceware.org/git/glibc.git
synced 2024-12-22 10:50:07 +00:00
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).
This commit is contained in:
parent
193ce8dcd6
commit
e607b492e5
15
ChangeLog
15
ChangeLog
@ -1,3 +1,18 @@
|
|||||||
|
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).
|
||||||
|
|
||||||
Sat Apr 1 00:08:06 1995 Roland McGrath <roland@churchy.gnu.ai.mit.edu>
|
Sat Apr 1 00:08:06 1995 Roland McGrath <roland@churchy.gnu.ai.mit.edu>
|
||||||
|
|
||||||
* Makerules (lib%.so: lib%_pic.a): Pass -L options for subdir and
|
* Makerules (lib%.so: lib%_pic.a): Pass -L options for subdir and
|
||||||
|
8
MakeTAGS
8
MakeTAGS
@ -1,6 +1,6 @@
|
|||||||
# Make the TAGS files.
|
# Make the TAGS files.
|
||||||
|
|
||||||
# Copyright (C) 1992, 1994 Free Software Foundation, Inc.
|
# Copyright (C) 1992, 1994, 1995 Free Software Foundation, Inc.
|
||||||
# This file is part of the GNU C Library.
|
# This file is part of the GNU C Library.
|
||||||
|
|
||||||
# The GNU C Library is free software; you can redistribute it and/or
|
# The GNU C Library is free software; you can redistribute it and/or
|
||||||
@ -33,9 +33,9 @@ ifeq ($(subdir),ctype)
|
|||||||
# the header files so tags for optimizing #define's in the
|
# the header files so tags for optimizing #define's in the
|
||||||
# headers won't be put in the tags files, but for ctype,
|
# headers won't be put in the tags files, but for ctype,
|
||||||
# the functions are just backup for the #define's in the header.
|
# the functions are just backup for the #define's in the header.
|
||||||
tags_sources = $(all-headers) $(all-sources)
|
tags_sources = $(all-headers) $(all-sources) $(all-dist)
|
||||||
else # Not ctype.
|
else # Not ctype.
|
||||||
tags_sources = $(all-sources) $(all-headers)
|
tags_sources = $(all-sources) $(all-headers) $(all-dist)
|
||||||
endif # ctype
|
endif # ctype
|
||||||
endif # No tags_sources
|
endif # No tags_sources
|
||||||
|
|
||||||
@ -67,6 +67,8 @@ all-dist = $(foreach Dist,$(wildcard $(all-dirs:%=%/Dist)),\
|
|||||||
$(filter %.c %.h %.S %.s,\
|
$(filter %.c %.h %.S %.s,\
|
||||||
$(shell cat $(Dist)))))
|
$(shell cat $(Dist)))))
|
||||||
tags_sources = $(all-sources) $(all-headers) $(all-dist)
|
tags_sources = $(all-sources) $(all-headers) $(all-dist)
|
||||||
|
else
|
||||||
|
all-dist = $(distribute)
|
||||||
endif
|
endif
|
||||||
|
|
||||||
# All different versions of $(sources), preserving the configured sysdep
|
# All different versions of $(sources), preserving the configured sysdep
|
||||||
|
@ -343,7 +343,7 @@ ifeq (yes,$(build-shared))
|
|||||||
lib%.so: lib%_pic.a
|
lib%.so: lib%_pic.a
|
||||||
$(LINK.o) -shared -o $@ -Wl,--whole-archive $< \
|
$(LINK.o) -shared -o $@ -Wl,--whole-archive $< \
|
||||||
-L$(firstword $(objdir) .) -L$(common-objpfx:%/=%) \
|
-L$(firstword $(objdir) .) -L$(common-objpfx:%/=%) \
|
||||||
$(LDLIBS-$*.so)
|
$(LDLIBS-$(notdir $*).so)
|
||||||
endif
|
endif
|
||||||
|
|
||||||
libobjs: $(foreach o,$(object-suffixes),\
|
libobjs: $(foreach o,$(object-suffixes),\
|
||||||
|
@ -51,7 +51,7 @@ routines = hurdinit hurdid hurdlookup hurdpid hurdrlimit hurdprio hurdexec \
|
|||||||
ports-get ports-set hurdports hurdmsg \
|
ports-get ports-set hurdports hurdmsg \
|
||||||
$(sig) $(dtable) hurdinline port-cleanup
|
$(sig) $(dtable) hurdinline port-cleanup
|
||||||
sig = hurdsig hurdfault faultexc siginfo hurd-raise preempt-sig \
|
sig = hurdsig hurdfault faultexc siginfo hurd-raise preempt-sig \
|
||||||
trampoline longjmp-ts catch-exc exc2signal hurdkill
|
trampoline longjmp-ts catch-exc exc2signal hurdkill sigunwind
|
||||||
dtable = dtable port2fd new-fd alloc-fd intern-fd \
|
dtable = dtable port2fd new-fd alloc-fd intern-fd \
|
||||||
getdport openport \
|
getdport openport \
|
||||||
fd-close fd-read fd-write hurdioctl ctty-input ctty-output
|
fd-close fd-read fd-write hurdioctl ctty-input ctty-output
|
||||||
|
135
hurd/sigunwind.c
Normal file
135
hurd/sigunwind.c
Normal file
@ -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;
|
||||||
|
}
|
@ -28,6 +28,7 @@ int
|
|||||||
__sigreturn (struct sigcontext *scp)
|
__sigreturn (struct sigcontext *scp)
|
||||||
{
|
{
|
||||||
struct hurd_sigstate *ss;
|
struct hurd_sigstate *ss;
|
||||||
|
struct hurd_userlink *link = (void *) &scp[1];
|
||||||
mach_port_t *reply_port;
|
mach_port_t *reply_port;
|
||||||
|
|
||||||
if (scp == NULL || (scp->sc_mask & _SIG_CANT_MASK))
|
if (scp == NULL || (scp->sc_mask & _SIG_CANT_MASK))
|
||||||
@ -39,6 +40,11 @@ __sigreturn (struct sigcontext *scp)
|
|||||||
ss = _hurd_self_sigstate ();
|
ss = _hurd_self_sigstate ();
|
||||||
__spin_lock (&ss->lock);
|
__spin_lock (&ss->lock);
|
||||||
|
|
||||||
|
/* Remove the link on the `active resources' chain added by
|
||||||
|
_hurd_setup_sighandler. Its purpose was to make sure
|
||||||
|
that we got called; now we have, it is done. */
|
||||||
|
_hurd_userlink_unlink (link);
|
||||||
|
|
||||||
/* Restore the set of blocked signals, and the intr_port slot. */
|
/* Restore the set of blocked signals, and the intr_port slot. */
|
||||||
ss->blocked = scp->sc_mask;
|
ss->blocked = scp->sc_mask;
|
||||||
ss->intr_port = scp->sc_intr_port;
|
ss->intr_port = scp->sc_intr_port;
|
||||||
|
@ -18,6 +18,7 @@ not, write to the Free Software Foundation, Inc., 675 Mass Ave,
|
|||||||
Cambridge, MA 02139, USA. */
|
Cambridge, MA 02139, USA. */
|
||||||
|
|
||||||
#include <hurd/signal.h>
|
#include <hurd/signal.h>
|
||||||
|
#include <hurd/userlink.h>
|
||||||
#include "thread_state.h"
|
#include "thread_state.h"
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
@ -55,6 +56,7 @@ _hurd_setup_sighandler (struct hurd_sigstate *ss, __sighandler_t handler,
|
|||||||
void *sigreturn_returns_here;
|
void *sigreturn_returns_here;
|
||||||
struct sigcontext *return_scp; /* Same; arg to sigreturn. */
|
struct sigcontext *return_scp; /* Same; arg to sigreturn. */
|
||||||
struct sigcontext ctx;
|
struct sigcontext ctx;
|
||||||
|
struct hurd_userlink link;
|
||||||
} *stackframe;
|
} *stackframe;
|
||||||
|
|
||||||
if (ss->context)
|
if (ss->context)
|
||||||
@ -118,6 +120,24 @@ _hurd_setup_sighandler (struct hurd_sigstate *ss, __sighandler_t handler,
|
|||||||
{
|
{
|
||||||
int ok;
|
int ok;
|
||||||
|
|
||||||
|
extern void _hurdsig_longjmp_from_handler (void *, jmp_buf, int);
|
||||||
|
|
||||||
|
/* Add a link to the thread's active-resources list. We mark this as
|
||||||
|
the only user of the "resource", so the cleanup function will be
|
||||||
|
called by any longjmp which is unwinding past the signal frame.
|
||||||
|
The cleanup function (in sigunwind.c) will make sure that all the
|
||||||
|
appropriate cleanups done by sigreturn are taken care of. */
|
||||||
|
stackframe->link.cleanup = &_hurdsig_longjmp_from_handler;
|
||||||
|
stackframe->link.cleanup_data = &stackframe->ctx;
|
||||||
|
stackframe->link.resource.next = NULL;
|
||||||
|
stackframe->link.resource.prevp = NULL;
|
||||||
|
stackframe->link.thread.next = ss->active_resources;
|
||||||
|
stackframe->link.thread.prevp = &ss->active_resources;
|
||||||
|
if (stackframe->link.thread.next)
|
||||||
|
stackframe->link.thread.next->thread.prevp
|
||||||
|
= &stackframe->link.thread.next;
|
||||||
|
ss->active_resources = &stackframe->link;
|
||||||
|
|
||||||
/* Set up the arguments for the signal handler. */
|
/* Set up the arguments for the signal handler. */
|
||||||
stackframe->signo = signo;
|
stackframe->signo = signo;
|
||||||
stackframe->sigcode = sigcode;
|
stackframe->sigcode = sigcode;
|
||||||
|
Loading…
Reference in New Issue
Block a user