diff options
author | Linus Torvalds <torvalds@ppc970.osdl.org> | 2005-04-16 15:20:36 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@ppc970.osdl.org> | 2005-04-16 15:20:36 -0700 |
commit | 1da177e4c3f41524e886b7f1b8a0c1fc7321cac2 (patch) | |
tree | 0bba044c4ce775e45a88a51686b5d9f90697ea9d /arch/um/kernel/tt/syscall_user.c |
Linux-2.6.12-rc2v2.6.12-rc2
Initial git repository build. I'm not bothering with the full history,
even though we have it. We can create a separate "historical" git
archive of that later if we want to, and in the meantime it's about
3.2GB when imported into git - space that would just make the early
git days unnecessarily complicated, when we don't have a lot of good
infrastructure for it.
Let it rip!
Diffstat (limited to 'arch/um/kernel/tt/syscall_user.c')
-rw-r--r-- | arch/um/kernel/tt/syscall_user.c | 90 |
1 files changed, 90 insertions, 0 deletions
diff --git a/arch/um/kernel/tt/syscall_user.c b/arch/um/kernel/tt/syscall_user.c new file mode 100644 index 00000000000..e4e7e9c2224 --- /dev/null +++ b/arch/um/kernel/tt/syscall_user.c @@ -0,0 +1,90 @@ +/* + * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com) + * Licensed under the GPL + */ + +#include <unistd.h> +#include <signal.h> +#include <errno.h> +#include <asm/unistd.h> +#include "sysdep/ptrace.h" +#include "sigcontext.h" +#include "ptrace_user.h" +#include "task.h" +#include "user_util.h" +#include "kern_util.h" +#include "syscall_user.h" +#include "tt.h" + + +void syscall_handler_tt(int sig, union uml_pt_regs *regs) +{ + void *sc; + long result; + int syscall; +#ifdef UML_CONFIG_DEBUG_SYSCALL + int index; +#endif + + syscall = UPT_SYSCALL_NR(regs); + sc = UPT_SC(regs); + SC_START_SYSCALL(sc); + +#ifdef UML_CONFIG_DEBUG_SYSCALL + index = record_syscall_start(syscall); +#endif + syscall_trace(regs, 0); + result = execute_syscall_tt(regs); + + /* regs->sc may have changed while the system call ran (there may + * have been an interrupt or segfault), so it needs to be refreshed. + */ + UPT_SC(regs) = sc; + + SC_SET_SYSCALL_RETURN(sc, result); + + syscall_trace(regs, 1); +#ifdef UML_CONFIG_DEBUG_SYSCALL + record_syscall_end(index, result); +#endif +} + +void do_sigtrap(void *task) +{ + UPT_SYSCALL_NR(TASK_REGS(task)) = -1; +} + +void do_syscall(void *task, int pid, int local_using_sysemu) +{ + unsigned long proc_regs[FRAME_SIZE]; + + if(ptrace_getregs(pid, proc_regs) < 0) + tracer_panic("Couldn't read registers"); + + UPT_SYSCALL_NR(TASK_REGS(task)) = PT_SYSCALL_NR(proc_regs); + + if(((unsigned long *) PT_IP(proc_regs) >= &_stext) && + ((unsigned long *) PT_IP(proc_regs) <= &_etext)) + tracer_panic("I'm tracing myself and I can't get out"); + + /* advanced sysemu mode set syscall number to -1 automatically */ + if (local_using_sysemu==2) + return; + + /* syscall number -1 in sysemu skips syscall restarting in host */ + if(ptrace(PTRACE_POKEUSR, pid, PT_SYSCALL_NR_OFFSET, + local_using_sysemu ? -1 : __NR_getpid) < 0) + tracer_panic("do_syscall : Nullifying syscall failed, " + "errno = %d", errno); +} + +/* + * Overrides for Emacs so that we follow Linus's tabbing style. + * Emacs will notice this stuff at the end of the file and automatically + * adjust the settings for this buffer only. This must remain at the end + * of the file. + * --------------------------------------------------------------------------- + * Local variables: + * c-file-style: "linux" + * End: + */ |