b06217d022997c48b9321aaea58deaa6387be429
[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
21 void syscall_handler_tt(int sig, union uml_pt_regs *regs)
22 {
23         void *sc;
24         long result;
25         int index, syscall;
26
27         syscall = UPT_SYSCALL_NR(regs);
28         sc = UPT_SC(regs);
29         SC_START_SYSCALL(sc);
30
31         index = record_syscall_start(syscall);
32         syscall_trace(regs, 0);
33         result = execute_syscall(regs);
34
35         /* regs->sc may have changed while the system call ran (there may
36          * have been an interrupt or segfault), so it needs to be refreshed.
37          */
38         UPT_SC(regs) = sc;
39
40         SC_SET_SYSCALL_RETURN(sc, result);
41
42         syscall_trace(regs, 1);
43         record_syscall_end(index, result);
44 }
45
46 int do_syscall(void *task, int pid, int local_using_sysemu)
47 {
48         unsigned long proc_regs[FRAME_SIZE];
49         union uml_pt_regs *regs;
50         int syscall;
51
52         if(ptrace_getregs(pid, proc_regs) < 0)
53                 tracer_panic("Couldn't read registers");
54         syscall = PT_SYSCALL_NR(proc_regs);
55
56         regs = TASK_REGS(task);
57         UPT_SYSCALL_NR(regs) = syscall;
58
59         if(syscall < 0)
60                 return(0);
61
62         if((syscall != __NR_sigreturn) &&
63            ((unsigned long *) PT_IP(proc_regs) >= &_stext) && 
64            ((unsigned long *) PT_IP(proc_regs) <= &_etext))
65                 tracer_panic("I'm tracing myself and I can't get out");
66
67         if(local_using_sysemu)
68                 return(1);
69
70         if(ptrace(PTRACE_POKEUSER, pid, PT_SYSCALL_NR_OFFSET, 
71                   __NR_getpid) < 0)
72                 tracer_panic("do_syscall : Nullifying syscall failed, "
73                              "errno = %d", errno);
74         return(1);
75 }
76
77 /*
78  * Overrides for Emacs so that we follow Linus's tabbing style.
79  * Emacs will notice this stuff at the end of the file and automatically
80  * adjust the settings for this buffer only.  This must remain at the end
81  * of the file.
82  * ---------------------------------------------------------------------------
83  * Local variables:
84  * c-file-style: "linux"
85  * End:
86  */