vserver 1.9.5.x5
[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 void do_sigtrap(void *task)
47 {
48         UPT_SYSCALL_NR(TASK_REGS(task)) = -1;
49 }
50
51 void do_syscall(void *task, int pid, int local_using_sysemu)
52 {
53         unsigned long proc_regs[FRAME_SIZE];
54
55         if(ptrace_getregs(pid, proc_regs) < 0)
56                 tracer_panic("Couldn't read registers");
57
58         UPT_SYSCALL_NR(TASK_REGS(task)) = PT_SYSCALL_NR(proc_regs);
59
60         if(((unsigned long *) PT_IP(proc_regs) >= &_stext) &&
61            ((unsigned long *) PT_IP(proc_regs) <= &_etext))
62                 tracer_panic("I'm tracing myself and I can't get out");
63
64         /* advanced sysemu mode set syscall number to -1 automatically */
65         if (local_using_sysemu==2)
66                 return;
67
68         /* syscall number -1 in sysemu skips syscall restarting in host */
69         if(ptrace(PTRACE_POKEUSER, pid, PT_SYSCALL_NR_OFFSET, 
70                   local_using_sysemu ? -1 : __NR_getpid) < 0)
71                 tracer_panic("do_syscall : Nullifying syscall failed, "
72                              "errno = %d", errno);
73 }
74
75 /*
76  * Overrides for Emacs so that we follow Linus's tabbing style.
77  * Emacs will notice this stuff at the end of the file and automatically
78  * adjust the settings for this buffer only.  This must remain at the end
79  * of the file.
80  * ---------------------------------------------------------------------------
81  * Local variables:
82  * c-file-style: "linux"
83  * End:
84  */