ftp://ftp.kernel.org/pub/linux/kernel/v2.6/linux-2.6.6.tar.bz2
[linux-2.6.git] / arch / um / kernel / tt / syscall_user.c
1 /* 
2  * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com)
3  * Licensed under the GPL
4  */
5
6 #include <unistd.h>
7 #include <signal.h>
8 #include <errno.h>
9 #include <sys/ptrace.h>
10 #include <asm/unistd.h>
11 #include "sysdep/ptrace.h"
12 #include "sigcontext.h"
13 #include "ptrace_user.h"
14 #include "task.h"
15 #include "user_util.h"
16 #include "kern_util.h"
17 #include "syscall_user.h"
18 #include "tt.h"
19
20 /* XXX Bogus */
21 #define ERESTARTSYS     512
22 #define ERESTARTNOINTR  513
23 #define ERESTARTNOHAND  514
24
25 void syscall_handler_tt(int sig, union uml_pt_regs *regs)
26 {
27         void *sc;
28         long result;
29         int index, syscall;
30
31         syscall = UPT_SYSCALL_NR(regs);
32         sc = UPT_SC(regs);
33         SC_START_SYSCALL(sc);
34
35         index = record_syscall_start(syscall);
36         syscall_trace();
37         result = execute_syscall(regs);
38
39         /* regs->sc may have changed while the system call ran (there may
40          * have been an interrupt or segfault), so it needs to be refreshed.
41          */
42         UPT_SC(regs) = sc;
43
44         SC_SET_SYSCALL_RETURN(sc, result);
45         if((result == -ERESTARTNOHAND) || (result == -ERESTARTSYS) || 
46            (result == -ERESTARTNOINTR))
47                 do_signal(result);
48
49         syscall_trace();
50         record_syscall_end(index, result);
51 }
52
53 int do_syscall(void *task, int pid)
54 {
55         unsigned long proc_regs[FRAME_SIZE];
56         union uml_pt_regs *regs;
57         int syscall;
58
59         if(ptrace_getregs(pid, proc_regs) < 0)
60                 tracer_panic("Couldn't read registers");
61         syscall = PT_SYSCALL_NR(proc_regs);
62
63         regs = TASK_REGS(task);
64         UPT_SYSCALL_NR(regs) = syscall;
65
66         if(syscall < 1) return(0);
67
68         if((syscall != __NR_sigreturn) &&
69            ((unsigned long *) PT_IP(proc_regs) >= &_stext) && 
70            ((unsigned long *) PT_IP(proc_regs) <= &_etext))
71                 tracer_panic("I'm tracing myself and I can't get out");
72
73         if(ptrace(PTRACE_POKEUSER, pid, PT_SYSCALL_NR_OFFSET, 
74                   __NR_getpid) < 0)
75                 tracer_panic("do_syscall : Nullifying syscall failed, "
76                              "errno = %d", errno);
77         return(1);
78 }
79
80 /*
81  * Overrides for Emacs so that we follow Linus's tabbing style.
82  * Emacs will notice this stuff at the end of the file and automatically
83  * adjust the settings for this buffer only.  This must remain at the end
84  * of the file.
85  * ---------------------------------------------------------------------------
86  * Local variables:
87  * c-file-style: "linux"
88  * End:
89  */