blob: b5d9d64d91e403b82b8d7a6fe525091122b6d9a7 [file] [log] [blame]
Gennady Sharapovea2ba7d2006-01-08 01:01:31 -08001/*
Linus Torvalds1da177e2005-04-16 15:20:36 -07002 * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
3 * Licensed under the GPL
4 */
5
6#include <stdlib.h>
7#include <errno.h>
8#include <signal.h>
9#include "sysdep/ptrace.h"
Bodo Stroesserc5784552005-05-05 16:15:31 -070010#include "sysdep/sigcontext.h"
Linus Torvalds1da177e2005-04-16 15:20:36 -070011#include "user_util.h"
12#include "kern_util.h"
13#include "task.h"
14#include "tt.h"
Gennady Sharapov0805d892006-01-08 01:01:29 -080015#include "os.h"
Linus Torvalds1da177e2005-04-16 15:20:36 -070016
17void sig_handler_common_tt(int sig, void *sc_ptr)
18{
19 struct sigcontext *sc = sc_ptr;
20 struct tt_regs save_regs, *r;
Bodo Stroesser097fdf02006-01-18 17:42:51 -080021 int save_errno = errno, is_user = 0;
Gennady Sharapovea2ba7d2006-01-08 01:01:31 -080022 void (*handler)(int, union uml_pt_regs *);
Linus Torvalds1da177e2005-04-16 15:20:36 -070023
24 /* This is done because to allow SIGSEGV to be delivered inside a SEGV
25 * handler. This can happen in copy_user, and if SEGV is disabled,
26 * the process will die.
27 */
28 if(sig == SIGSEGV)
29 change_sig(SIGSEGV, 1);
30
31 r = &TASK_REGS(get_current())->tt;
Bodo Stroesserc5784552005-05-05 16:15:31 -070032 if ( sig == SIGFPE || sig == SIGSEGV ||
33 sig == SIGBUS || sig == SIGILL ||
34 sig == SIGTRAP ) {
35 GET_FAULTINFO_FROM_SC(r->faultinfo, sc);
36 }
Linus Torvalds1da177e2005-04-16 15:20:36 -070037 save_regs = *r;
Bodo Stroesser097fdf02006-01-18 17:42:51 -080038 if (sc)
39 is_user = user_context(SC_SP(sc));
Linus Torvalds1da177e2005-04-16 15:20:36 -070040 r->sc = sc;
41 if(sig != SIGUSR2)
42 r->syscall = -1;
43
Gennady Sharapovea2ba7d2006-01-08 01:01:31 -080044 handler = sig_info[sig];
Linus Torvalds1da177e2005-04-16 15:20:36 -070045
Gennady Sharapovea2ba7d2006-01-08 01:01:31 -080046 /* unblock SIGALRM, SIGVTALRM, SIGIO if sig isn't IRQ signal */
47 if (sig != SIGIO && sig != SIGWINCH &&
48 sig != SIGVTALRM && sig != SIGALRM)
49 unblock_signals();
50
51 handler(sig, (union uml_pt_regs *) r);
Linus Torvalds1da177e2005-04-16 15:20:36 -070052
53 if(is_user){
54 interrupt_end();
55 block_signals();
56 set_user_mode(NULL);
57 }
58 *r = save_regs;
59 errno = save_errno;
60}
61
62/*
63 * Overrides for Emacs so that we follow Linus's tabbing style.
64 * Emacs will notice this stuff at the end of the file and automatically
65 * adjust the settings for this buffer only. This must remain at the end
66 * of the file.
67 * ---------------------------------------------------------------------------
68 * Local variables:
69 * c-file-style: "linux"
70 * End:
71 */