diff options
author | Andreas Färber <afaerber@suse.de> | 2012-04-16 04:31:11 +0000 |
---|---|---|
committer | Andreas Färber <andreas.faerber@web.de> | 2012-05-01 00:17:27 +0200 |
commit | 0adb124659cfadf9f0b5c99874c476116f0cf74f (patch) | |
tree | f4f820e8ddb4b0889138712043261ac4ca390696 /darwin-user/signal.c | |
parent | 148210301e334694badcc8ae72ecb522c6d7bac6 (diff) |
Drop darwin-user
It's been orphaned, not compiling for a long time and despite Apple's
drop of their Rosetta ppc emulation technology with Mac OS X Lion no one
has stepped up to fix it.
Testing necessary changes wrt QOM'ification thus is impossible, so we
might as well remove it completely.
Signed-off-by: Andreas Färber <afaerber@suse.de>
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Diffstat (limited to 'darwin-user/signal.c')
-rw-r--r-- | darwin-user/signal.c | 452 |
1 files changed, 0 insertions, 452 deletions
diff --git a/darwin-user/signal.c b/darwin-user/signal.c deleted file mode 100644 index 489cb64282..0000000000 --- a/darwin-user/signal.c +++ /dev/null @@ -1,452 +0,0 @@ -/* - * Emulation of Linux signals - * - * Copyright (c) 2003 Fabrice Bellard - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, see <http://www.gnu.org/licenses/>. - */ -#include <stdlib.h> -#include <stdio.h> -#include <string.h> -#include <stdarg.h> -#include <unistd.h> -#include <errno.h> -#include <sys/ucontext.h> - -#ifdef __ia64__ -#undef uc_mcontext -#undef uc_sigmask -#undef uc_stack -#undef uc_link -#endif - -#include "qemu.h" -#include "qemu-common.h" - -#define DEBUG_SIGNAL - -#define MAX_SIGQUEUE_SIZE 1024 - -struct sigqueue { - struct sigqueue *next; - target_siginfo_t info; -}; - -struct emulated_sigaction { - struct target_sigaction sa; - int pending; /* true if signal is pending */ - struct sigqueue *first; - struct sigqueue info; /* in order to always have memory for the - first signal, we put it here */ -}; - -static struct sigaltstack target_sigaltstack_used = { - 0, 0, SA_DISABLE -}; - -static struct emulated_sigaction sigact_table[NSIG]; -static struct sigqueue sigqueue_table[MAX_SIGQUEUE_SIZE]; /* siginfo queue */ -static struct sigqueue *first_free; /* first free siginfo queue entry */ -static int signal_pending; /* non zero if a signal may be pending */ - -static void host_signal_handler(int host_signum, siginfo_t *info, - void *puc); - - -static inline int host_to_target_signal(int sig) -{ - return sig; -} - -static inline int target_to_host_signal(int sig) -{ - return sig; -} - -/* siginfo conversion */ - - - -void host_to_target_siginfo(target_siginfo_t *tinfo, const siginfo_t *info) -{ - -} - -void target_to_host_siginfo(siginfo_t *info, const target_siginfo_t *tinfo) -{ - -} - -void signal_init(void) -{ - struct sigaction act; - int i; - - /* set all host signal handlers. ALL signals are blocked during - the handlers to serialize them. */ - sigfillset(&act.sa_mask); - act.sa_flags = SA_SIGINFO; - act.sa_sigaction = host_signal_handler; - for(i = 1; i < NSIG; i++) { - sigaction(i, &act, NULL); - } - - memset(sigact_table, 0, sizeof(sigact_table)); - - first_free = &sigqueue_table[0]; - for(i = 0; i < MAX_SIGQUEUE_SIZE - 1; i++) - sigqueue_table[i].next = &sigqueue_table[i + 1]; - sigqueue_table[MAX_SIGQUEUE_SIZE - 1].next = NULL; -} - -/* signal queue handling */ - -static inline struct sigqueue *alloc_sigqueue(void) -{ - struct sigqueue *q = first_free; - if (!q) - return NULL; - first_free = q->next; - return q; -} - -static inline void free_sigqueue(struct sigqueue *q) -{ - q->next = first_free; - first_free = q; -} - -/* abort execution with signal */ -void QEMU_NORETURN force_sig(int sig) -{ - int host_sig; - host_sig = target_to_host_signal(sig); - fprintf(stderr, "qemu: uncaught target signal %d (%s) - exiting\n", - sig, strsignal(host_sig)); - _exit(-host_sig); -} - -/* queue a signal so that it will be send to the virtual CPU as soon - as possible */ -int queue_signal(int sig, target_siginfo_t *info) -{ - struct emulated_sigaction *k; - struct sigqueue *q, **pq; - target_ulong handler; - -#if defined(DEBUG_SIGNAL) - fprintf(stderr, "queue_signal: sig=%d\n", - sig); -#endif - k = &sigact_table[sig - 1]; - handler = (target_ulong)k->sa.sa_handler; - if (handler == SIG_DFL) { - /* default handler : ignore some signal. The other are fatal */ - if (sig != SIGCHLD && - sig != SIGURG && - sig != SIGWINCH) { - force_sig(sig); - } else { - return 0; /* indicate ignored */ - } - } else if (handler == host_to_target_signal(SIG_IGN)) { - /* ignore signal */ - return 0; - } else if (handler == host_to_target_signal(SIG_ERR)) { - force_sig(sig); - } else { - pq = &k->first; - if (!k->pending) { - /* first signal */ - q = &k->info; - } else { - q = alloc_sigqueue(); - if (!q) - return -EAGAIN; - while (*pq != NULL) - pq = &(*pq)->next; - } - *pq = q; - q->info = *info; - q->next = NULL; - k->pending = 1; - /* signal that a new signal is pending */ - signal_pending = 1; - return 1; /* indicates that the signal was queued */ - } -} - -static void host_signal_handler(int host_signum, siginfo_t *info, - void *puc) -{ - int sig; - target_siginfo_t tinfo; - - /* the CPU emulator uses some host signals to detect exceptions, - we we forward to it some signals */ - if (host_signum == SIGSEGV || host_signum == SIGBUS) { - if (cpu_signal_handler(host_signum, (void*)info, puc)) - return; - } - - /* get target signal number */ - sig = host_to_target_signal(host_signum); - if (sig < 1 || sig > NSIG) - return; - -#if defined(DEBUG_SIGNAL) - fprintf(stderr, "qemu: got signal %d\n", sig); -#endif - if (queue_signal(sig, &tinfo) == 1) { - /* interrupt the virtual CPU as soon as possible */ - cpu_exit(global_env); - } -} - -int do_sigaltstack(const struct sigaltstack *ss, struct sigaltstack *oss) -{ - /* XXX: test errors */ - if(oss) - { - oss->ss_sp = tswap32(target_sigaltstack_used.ss_sp); - oss->ss_size = tswap32(target_sigaltstack_used.ss_size); - oss->ss_flags = tswap32(target_sigaltstack_used.ss_flags); - } - if(ss) - { - target_sigaltstack_used.ss_sp = tswap32(ss->ss_sp); - target_sigaltstack_used.ss_size = tswap32(ss->ss_size); - target_sigaltstack_used.ss_flags = tswap32(ss->ss_flags); - } - return 0; -} - -int do_sigaction(int sig, const struct sigaction *act, - struct sigaction *oact) -{ - struct emulated_sigaction *k; - struct sigaction act1; - int host_sig; - - if (sig < 1 || sig > NSIG) - return -EINVAL; - - k = &sigact_table[sig - 1]; -#if defined(DEBUG_SIGNAL) - fprintf(stderr, "sigaction 1 sig=%d act=0x%08x, oact=0x%08x\n", - sig, (int)act, (int)oact); -#endif - if (oact) { -#if defined(DEBUG_SIGNAL) - fprintf(stderr, "sigaction 1 sig=%d act=0x%08x, oact=0x%08x\n", - sig, (int)act, (int)oact); -#endif - - oact->sa_handler = tswapl(k->sa.sa_handler); - oact->sa_flags = tswapl(k->sa.sa_flags); - oact->sa_mask = tswapl(k->sa.sa_mask); - } - if (act) { -#if defined(DEBUG_SIGNAL) - fprintf(stderr, "sigaction handler 0x%x flag 0x%x mask 0x%x\n", - act->sa_handler, act->sa_flags, act->sa_mask); -#endif - - k->sa.sa_handler = tswapl(act->sa_handler); - k->sa.sa_flags = tswapl(act->sa_flags); - k->sa.sa_mask = tswapl(act->sa_mask); - /* we update the host signal state */ - host_sig = target_to_host_signal(sig); - if (host_sig != SIGSEGV && host_sig != SIGBUS) { -#if defined(DEBUG_SIGNAL) - fprintf(stderr, "sigaction handler going to call sigaction\n"); -#endif - - sigfillset(&act1.sa_mask); - act1.sa_flags = SA_SIGINFO; - if (k->sa.sa_flags & SA_RESTART) - act1.sa_flags |= SA_RESTART; - /* NOTE: it is important to update the host kernel signal - ignore state to avoid getting unexpected interrupted - syscalls */ - if (k->sa.sa_handler == SIG_IGN) { - act1.sa_sigaction = (void *)SIG_IGN; - } else if (k->sa.sa_handler == SIG_DFL) { - act1.sa_sigaction = (void *)SIG_DFL; - } else { - act1.sa_sigaction = host_signal_handler; - } - sigaction(host_sig, &act1, NULL); - } - } - return 0; -} - - -#ifdef TARGET_I386 - -static inline void * -get_sigframe(struct emulated_sigaction *ka, CPUX86State *env, size_t frame_size) -{ - /* XXX Fix that */ - if(target_sigaltstack_used.ss_flags & SA_DISABLE) - { - int esp; - /* Default to using normal stack */ - esp = env->regs[R_ESP]; - - return (void *)((esp - frame_size) & -8ul); - } - else - { - return target_sigaltstack_used.ss_sp; - } -} - -static void setup_frame(int sig, struct emulated_sigaction *ka, - void *set, CPUX86State *env) -{ - void *frame; - - fprintf(stderr, "setup_frame %d\n", sig); - frame = get_sigframe(ka, env, sizeof(*frame)); - - /* Set up registers for signal handler */ - env->regs[R_ESP] = (unsigned long) frame; - env->eip = (unsigned long) ka->sa.sa_handler; - - env->eflags &= ~TF_MASK; - - return; - -give_sigsegv: - if (sig == SIGSEGV) - ka->sa.sa_handler = SIG_DFL; - force_sig(SIGSEGV /* , current */); -} - -long do_sigreturn(CPUX86State *env, int num) -{ - int i = 0; - struct target_sigcontext *scp = get_int_arg(&i, env); - /* XXX Get current signal number */ - /* XXX Adjust accordin to sc_onstack, sc_mask */ - if(tswapl(scp->sc_onstack) & 0x1) - target_sigaltstack_used.ss_flags |= ~SA_DISABLE; - else - target_sigaltstack_used.ss_flags &= SA_DISABLE; - int set = tswapl(scp->sc_eax); - sigprocmask(SIG_SETMASK, &set, NULL); - - fprintf(stderr, "do_sigreturn: partially implemented %x EAX:%x EBX:%x\n", scp->sc_mask, tswapl(scp->sc_eax), tswapl(scp->sc_ebx)); - fprintf(stderr, "ECX:%x EDX:%x EDI:%x\n", scp->sc_ecx, tswapl(scp->sc_edx), tswapl(scp->sc_edi)); - fprintf(stderr, "EIP:%x\n", tswapl(scp->sc_eip)); - - env->regs[R_EAX] = tswapl(scp->sc_eax); - env->regs[R_EBX] = tswapl(scp->sc_ebx); - env->regs[R_ECX] = tswapl(scp->sc_ecx); - env->regs[R_EDX] = tswapl(scp->sc_edx); - env->regs[R_EDI] = tswapl(scp->sc_edi); - env->regs[R_ESI] = tswapl(scp->sc_esi); - env->regs[R_EBP] = tswapl(scp->sc_ebp); - env->regs[R_ESP] = tswapl(scp->sc_esp); - env->segs[R_SS].selector = (void*)tswapl(scp->sc_ss); - env->eflags = tswapl(scp->sc_eflags); - env->eip = tswapl(scp->sc_eip); - env->segs[R_CS].selector = (void*)tswapl(scp->sc_cs); - env->segs[R_DS].selector = (void*)tswapl(scp->sc_ds); - env->segs[R_ES].selector = (void*)tswapl(scp->sc_es); - env->segs[R_FS].selector = (void*)tswapl(scp->sc_fs); - env->segs[R_GS].selector = (void*)tswapl(scp->sc_gs); - - /* Again, because our caller's caller will reset EAX */ - return env->regs[R_EAX]; -} - -#else - -static void setup_frame(int sig, struct emulated_sigaction *ka, - void *set, CPUArchState *env) -{ - fprintf(stderr, "setup_frame: not implemented\n"); -} - -long do_sigreturn(CPUArchState *env, int num) -{ - int i = 0; - struct target_sigcontext *scp = get_int_arg(&i, env); - fprintf(stderr, "do_sigreturn: not implemented\n"); - return -ENOSYS; -} - -#endif - -void process_pending_signals(void *cpu_env) -{ - struct emulated_sigaction *k; - struct sigqueue *q; - target_ulong handler; - int sig; - - if (!signal_pending) - return; - - k = sigact_table; - - for(sig = 1; sig <= NSIG; sig++) { - if (k->pending) - goto handle_signal; - k++; - } - - /* if no signal is pending, just return */ - signal_pending = 0; - return; -handle_signal: - #ifdef DEBUG_SIGNAL - fprintf(stderr, "qemu: process signal %d\n", sig); - #endif - /* dequeue signal */ - q = k->first; - k->first = q->next; - if (!k->first) - k->pending = 0; - - sig = gdb_handlesig (cpu_env, sig); - if (!sig) { - fprintf (stderr, "Lost signal\n"); - abort(); - } - - handler = k->sa.sa_handler; - if (handler == SIG_DFL) { - /* default handler : ignore some signal. The other are fatal */ - if (sig != SIGCHLD && - sig != SIGURG && - sig != SIGWINCH) { - force_sig(sig); - } - } else if (handler == SIG_IGN) { - /* ignore sig */ - } else if (handler == SIG_ERR) { - force_sig(sig); - } else { - - setup_frame(sig, k, 0, cpu_env); - if (k->sa.sa_flags & SA_RESETHAND) - k->sa.sa_handler = SIG_DFL; - } - if (q != &k->info) - free_sigqueue(q); -} |