diff options
Diffstat (limited to 'arch/um')
-rw-r--r-- | arch/um/include/sysdep-i386/sigcontext.h | 13 | ||||
-rw-r--r-- | arch/um/include/sysdep-x86_64/sigcontext.h | 28 | ||||
-rw-r--r-- | arch/um/kernel/ptrace.c | 2 | ||||
-rw-r--r-- | arch/um/os-Linux/sys-i386/registers.c | 26 | ||||
-rw-r--r-- | arch/um/sys-i386/Makefile | 6 | ||||
-rw-r--r-- | arch/um/sys-i386/sigcontext.c | 71 | ||||
-rw-r--r-- | arch/um/sys-x86_64/Makefile | 6 | ||||
-rw-r--r-- | arch/um/sys-x86_64/ptrace.c | 101 | ||||
-rw-r--r-- | arch/um/sys-x86_64/sigcontext.c | 39 | ||||
-rw-r--r-- | arch/um/sys-x86_64/signal.c | 23 |
10 files changed, 77 insertions, 238 deletions
diff --git a/arch/um/include/sysdep-i386/sigcontext.h b/arch/um/include/sysdep-i386/sigcontext.h index 3050a6a..67e7712 100644 --- a/arch/um/include/sysdep-i386/sigcontext.h +++ b/arch/um/include/sysdep-i386/sigcontext.h @@ -6,15 +6,10 @@ #ifndef __SYS_SIGCONTEXT_I386_H #define __SYS_SIGCONTEXT_I386_H -#include "uml-config.h" -#include "skas.h" #include "sysdep/sc.h" #define IP_RESTART_SYSCALL(ip) ((ip) -= 2) -#define SC_RESTART_SYSCALL(sc) IP_RESTART_SYSCALL(SC_IP(sc)) -#define SC_SET_SYSCALL_RETURN(sc, result) SC_EAX(sc) = (result) - #define GET_FAULTINFO_FROM_SC(fi,sc) \ { \ (fi).cr2 = SC_CR2(sc); \ @@ -22,18 +17,10 @@ (fi).trap_no = SC_TRAPNO(sc); \ } -/* ptrace expects that, at the start of a system call, %eax contains - * -ENOSYS, so this makes it so. - */ -#define SC_START_SYSCALL(sc) do SC_EAX(sc) = -ENOSYS; while(0) - /* This is Page Fault */ #define SEGV_IS_FIXABLE(fi) ((fi)->trap_no == 14) /* SKAS3 has no trap_no on i386, but get_skas_faultinfo() sets it to 0. */ #define SEGV_MAYBE_FIXABLE(fi) ((fi)->trap_no == 0 && ptrace_faultinfo) -extern unsigned long *sc_sigmask(void *sc_ptr); -extern int sc_get_fpregs(unsigned long buf, void *sc_ptr); - #endif diff --git a/arch/um/include/sysdep-x86_64/sigcontext.h b/arch/um/include/sysdep-x86_64/sigcontext.h index 4107323..0155133 100644 --- a/arch/um/include/sysdep-x86_64/sigcontext.h +++ b/arch/um/include/sysdep-x86_64/sigcontext.h @@ -11,43 +11,17 @@ #define IP_RESTART_SYSCALL(ip) ((ip) -= 2) -#define SC_RESTART_SYSCALL(sc) IP_RESTART_SYSCALL(SC_IP(sc)) -#define SC_SET_SYSCALL_RETURN(sc, result) SC_RAX(sc) = (result) - -#define SC_FAULT_ADDR(sc) SC_CR2(sc) -#define SC_FAULT_TYPE(sc) SC_ERR(sc) - -#define GET_FAULTINFO_FROM_SC(fi,sc) \ +#define GET_FAULTINFO_FROM_SC(fi, sc) \ { \ (fi).cr2 = SC_CR2(sc); \ (fi).error_code = SC_ERR(sc); \ (fi).trap_no = SC_TRAPNO(sc); \ } -/* ptrace expects that, at the start of a system call, %eax contains - * -ENOSYS, so this makes it so. - */ - -#define SC_START_SYSCALL(sc) do SC_RAX(sc) = -ENOSYS; while(0) - /* This is Page Fault */ #define SEGV_IS_FIXABLE(fi) ((fi)->trap_no == 14) /* No broken SKAS API, which doesn't pass trap_no, here. */ #define SEGV_MAYBE_FIXABLE(fi) 0 -extern unsigned long *sc_sigmask(void *sc_ptr); - #endif - -/* - * 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: - */ - diff --git a/arch/um/kernel/ptrace.c b/arch/um/kernel/ptrace.c index 2511f91..a0eba08 100644 --- a/arch/um/kernel/ptrace.c +++ b/arch/um/kernel/ptrace.c @@ -171,8 +171,6 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data) */ ret = copy_to_user(p, &child->thread.arch.faultinfo, sizeof(struct ptrace_faultinfo)); - if (ret) - break; break; } diff --git a/arch/um/os-Linux/sys-i386/registers.c b/arch/um/os-Linux/sys-i386/registers.c index 8f1f0ab..d1997ca 100644 --- a/arch/um/os-Linux/sys-i386/registers.c +++ b/arch/um/os-Linux/sys-i386/registers.c @@ -1,49 +1,55 @@ /* * Copyright (C) 2004 PathScale, Inc + * Copyright (C) 2004 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com) * Licensed under the GPL */ #include <errno.h> -#include <sysdep/ptrace_user.h> +#include "kern_constants.h" #include "longjmp.h" #include "user.h" +#include "sysdep/ptrace_user.h" int save_fp_registers(int pid, unsigned long *fp_regs) { - if(ptrace(PTRACE_GETFPREGS, pid, 0, fp_regs) < 0) + if (ptrace(PTRACE_GETFPREGS, pid, 0, fp_regs) < 0) return -errno; return 0; } int restore_fp_registers(int pid, unsigned long *fp_regs) { - if(ptrace(PTRACE_SETFPREGS, pid, 0, fp_regs) < 0) + if (ptrace(PTRACE_SETFPREGS, pid, 0, fp_regs) < 0) return -errno; return 0; } int save_fpx_registers(int pid, unsigned long *fp_regs) { - if(ptrace(PTRACE_GETFPXREGS, pid, 0, fp_regs) < 0) + if (ptrace(PTRACE_GETFPXREGS, pid, 0, fp_regs) < 0) return -errno; return 0; } int restore_fpx_registers(int pid, unsigned long *fp_regs) { - if(ptrace(PTRACE_SETFPXREGS, pid, 0, fp_regs) < 0) + if (ptrace(PTRACE_SETFPXREGS, pid, 0, fp_regs) < 0) return -errno; return 0; } unsigned long get_thread_reg(int reg, jmp_buf *buf) { - switch(reg){ - case EIP: return buf[0]->__eip; - case UESP: return buf[0]->__esp; - case EBP: return buf[0]->__ebp; + switch (reg) { + case EIP: + return buf[0]->__eip; + case UESP: + return buf[0]->__esp; + case EBP: + return buf[0]->__ebp; default: - printk("get_thread_regs - unknown register %d\n", reg); + printk(UM_KERN_ERR "get_thread_regs - unknown register %d\n", + reg); return 0; } } diff --git a/arch/um/sys-i386/Makefile b/arch/um/sys-i386/Makefile index 9468cf3..964dc1a0 100644 --- a/arch/um/sys-i386/Makefile +++ b/arch/um/sys-i386/Makefile @@ -3,14 +3,14 @@ # obj-y = bug.o bugs.o checksum.o delay.o fault.o ksyms.o ldt.o ptrace.o \ - ptrace_user.o setjmp.o signal.o sigcontext.o stub.o stub_segv.o \ - syscalls.o sysrq.o sys_call_table.o tls.o + ptrace_user.o setjmp.o signal.o stub.o stub_segv.o syscalls.o sysrq.o \ + sys_call_table.o tls.o subarch-obj-y = lib/bitops_32.o lib/semaphore_32.o lib/string_32.o subarch-obj-$(CONFIG_HIGHMEM) += mm/highmem_32.o subarch-obj-$(CONFIG_MODULES) += kernel/module_32.o -USER_OBJS := bugs.o ptrace_user.o sigcontext.o fault.o +USER_OBJS := bugs.o ptrace_user.o fault.o USER_OBJS += user-offsets.s extra-y += user-offsets.s diff --git a/arch/um/sys-i386/sigcontext.c b/arch/um/sys-i386/sigcontext.c deleted file mode 100644 index 467d489..0000000 --- a/arch/um/sys-i386/sigcontext.c +++ /dev/null @@ -1,71 +0,0 @@ -/* - * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com) - * Licensed under the GPL - */ - -#include <stddef.h> -#include <string.h> -#include <asm/ptrace.h> -#include <asm/sigcontext.h> -#include "sysdep/ptrace.h" -#include "kern_util.h" - -void sc_to_sc(void *to_ptr, void *from_ptr) -{ - struct sigcontext *to = to_ptr, *from = from_ptr; - - memcpy(to, from, sizeof(*to) + sizeof(struct _fpstate)); - if(from->fpstate != NULL) - to->fpstate = (struct _fpstate *) (to + 1); -} - -unsigned long *sc_sigmask(void *sc_ptr) -{ - struct sigcontext *sc = sc_ptr; - return &sc->oldmask; -} - -int sc_get_fpregs(unsigned long buf, void *sc_ptr) -{ - struct sigcontext *sc = sc_ptr; - struct _fpstate *from = sc->fpstate, *to = (struct _fpstate *) buf; - int err = 0; - - if(from == NULL){ - err |= clear_user_proc(&to->cw, sizeof(to->cw)); - err |= clear_user_proc(&to->sw, sizeof(to->sw)); - err |= clear_user_proc(&to->tag, sizeof(to->tag)); - err |= clear_user_proc(&to->ipoff, sizeof(to->ipoff)); - err |= clear_user_proc(&to->cssel, sizeof(to->cssel)); - err |= clear_user_proc(&to->dataoff, sizeof(to->dataoff)); - err |= clear_user_proc(&to->datasel, sizeof(to->datasel)); - err |= clear_user_proc(&to->_st, sizeof(to->_st)); - } - else { - err |= copy_to_user_proc(&to->cw, &from->cw, sizeof(to->cw)); - err |= copy_to_user_proc(&to->sw, &from->sw, sizeof(to->sw)); - err |= copy_to_user_proc(&to->tag, &from->tag, - sizeof(to->tag)); - err |= copy_to_user_proc(&to->ipoff, &from->ipoff, - sizeof(to->ipoff)); - err |= copy_to_user_proc(&to->cssel,& from->cssel, - sizeof(to->cssel)); - err |= copy_to_user_proc(&to->dataoff, &from->dataoff, - sizeof(to->dataoff)); - err |= copy_to_user_proc(&to->datasel, &from->datasel, - sizeof(to->datasel)); - err |= copy_to_user_proc(to->_st, from->_st, sizeof(to->_st)); - } - return(err); -} - -/* - * 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: - */ diff --git a/arch/um/sys-x86_64/Makefile b/arch/um/sys-x86_64/Makefile index 002bb02..3c22de5 100644 --- a/arch/um/sys-x86_64/Makefile +++ b/arch/um/sys-x86_64/Makefile @@ -5,8 +5,8 @@ # obj-y = bug.o bugs.o delay.o fault.o ldt.o mem.o ptrace.o ptrace_user.o \ - setjmp.o sigcontext.o signal.o stub.o stub_segv.o syscalls.o \ - syscall_table.o sysrq.o ksyms.o tls.o + setjmp.o signal.o stub.o stub_segv.o syscalls.o syscall_table.o \ + sysrq.o ksyms.o tls.o obj-$(CONFIG_MODULES) += um_module.o @@ -15,7 +15,7 @@ subarch-obj-$(CONFIG_MODULES) += kernel/module_64.o ldt-y = ../sys-i386/ldt.o -USER_OBJS := ptrace_user.o sigcontext.o +USER_OBJS := ptrace_user.o USER_OBJS += user-offsets.s extra-y += user-offsets.s diff --git a/arch/um/sys-x86_64/ptrace.c b/arch/um/sys-x86_64/ptrace.c index b903299..a3cfeed 100644 --- a/arch/um/sys-x86_64/ptrace.c +++ b/arch/um/sys-x86_64/ptrace.c @@ -1,5 +1,6 @@ /* * Copyright 2003 PathScale, Inc. + * Copyright (C) 2003 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com) * * Licensed under the GPL */ @@ -12,17 +13,10 @@ #include <asm/uaccess.h> #include <asm/elf.h> -/* XXX x86_64 */ -unsigned long not_ss; -unsigned long not_ds; -unsigned long not_es; - -#define SC_SS(r) (not_ss) -#define SC_DS(r) (not_ds) -#define SC_ES(r) (not_es) - -/* determines which flags the user has access to. */ -/* 1 = access 0 = no access */ +/* + * determines which flags the user has access to. + * 1 = access 0 = no access + */ #define FLAG_MASK 0x44dd5UL int putreg(struct task_struct *child, int regno, unsigned long value) @@ -66,20 +60,21 @@ int putreg(struct task_struct *child, int regno, unsigned long value) int poke_user(struct task_struct *child, long addr, long data) { - if ((addr & 3) || addr < 0) - return -EIO; - - if (addr < MAX_REG_OFFSET) - return putreg(child, addr, data); - else if((addr >= offsetof(struct user, u_debugreg[0])) && - (addr <= offsetof(struct user, u_debugreg[7]))){ - addr -= offsetof(struct user, u_debugreg[0]); - addr = addr >> 2; - if((addr == 4) || (addr == 5)) return -EIO; - child->thread.arch.debugregs[addr] = data; - return 0; - } - return -EIO; + if ((addr & 3) || addr < 0) + return -EIO; + + if (addr < MAX_REG_OFFSET) + return putreg(child, addr, data); + else if ((addr >= offsetof(struct user, u_debugreg[0])) && + (addr <= offsetof(struct user, u_debugreg[7]))){ + addr -= offsetof(struct user, u_debugreg[0]); + addr = addr >> 2; + if ((addr == 4) || (addr == 5)) + return -EIO; + child->thread.arch.debugregs[addr] = data; + return 0; + } + return -EIO; } unsigned long getreg(struct task_struct *child, int regno) @@ -107,29 +102,22 @@ unsigned long getreg(struct task_struct *child, int regno) int peek_user(struct task_struct *child, long addr, long data) { /* read the word at location addr in the USER area. */ - unsigned long tmp; - - if ((addr & 3) || addr < 0) - return -EIO; - - tmp = 0; /* Default return condition */ - if(addr < MAX_REG_OFFSET){ - tmp = getreg(child, addr); - } - else if((addr >= offsetof(struct user, u_debugreg[0])) && - (addr <= offsetof(struct user, u_debugreg[7]))){ - addr -= offsetof(struct user, u_debugreg[0]); - addr = addr >> 2; - tmp = child->thread.arch.debugregs[addr]; - } - return put_user(tmp, (unsigned long *) data); -} + unsigned long tmp; -void arch_switch(void) -{ -/* XXX - printk("arch_switch\n"); -*/ + if ((addr & 3) || addr < 0) + return -EIO; + + tmp = 0; /* Default return condition */ + if (addr < MAX_REG_OFFSET){ + tmp = getreg(child, addr); + } + else if ((addr >= offsetof(struct user, u_debugreg[0])) && + (addr <= offsetof(struct user, u_debugreg[7]))){ + addr -= offsetof(struct user, u_debugreg[0]); + addr = addr >> 2; + tmp = child->thread.arch.debugregs[addr]; + } + return put_user(tmp, (unsigned long *) data); } /* XXX Mostly copied from sys-i386 */ @@ -139,21 +127,21 @@ int is_syscall(unsigned long addr) int n; n = copy_from_user(&instr, (void __user *) addr, sizeof(instr)); - if(n){ + if (n){ /* access_process_vm() grants access to vsyscall and stub, * while copy_from_user doesn't. Maybe access_process_vm is * slow, but that doesn't matter, since it will be called only * in case of singlestepping, if copy_from_user failed. */ n = access_process_vm(current, addr, &instr, sizeof(instr), 0); - if(n != sizeof(instr)) { + if (n != sizeof(instr)) { printk("is_syscall : failed to read instruction from " "0x%lx\n", addr); - return(1); + return 1; } } /* sysenter */ - return(instr == 0x050f); + return instr == 0x050f; } int get_fpregs(struct user_i387_struct __user *buf, struct task_struct *child) @@ -204,14 +192,3 @@ long subarch_ptrace(struct task_struct *child, long request, long addr, return ret; } - -/* - * 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: - */ diff --git a/arch/um/sys-x86_64/sigcontext.c b/arch/um/sys-x86_64/sigcontext.c deleted file mode 100644 index c88e64d..0000000 --- a/arch/um/sys-x86_64/sigcontext.c +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Copyright 2003 PathScale, Inc. - * - * Licensed under the GPL - */ - -#include <stdio.h> -#include <string.h> -#include <signal.h> -#include "user.h" - -void sc_to_sc(void *to_ptr, void *from_ptr) -{ - struct sigcontext *to = to_ptr, *from = from_ptr; - int size = sizeof(*to); /* + sizeof(struct _fpstate); */ - - memcpy(to, from, size); - if(from->fpstate != NULL) - to->fpstate = (struct _fpstate *) (to + 1); - - to->fpstate = NULL; -} - -unsigned long *sc_sigmask(void *sc_ptr) -{ - struct sigcontext *sc = sc_ptr; - - return(&sc->oldmask); -} - -/* 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: - */ diff --git a/arch/um/sys-x86_64/signal.c b/arch/um/sys-x86_64/signal.c index a8e5fd7..1778d33 100644 --- a/arch/um/sys-x86_64/signal.c +++ b/arch/um/sys-x86_64/signal.c @@ -1,5 +1,6 @@ /* * Copyright (C) 2003 PathScale, Inc. + * Copyright (C) 2003 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com) * Licensed under the GPL */ @@ -110,7 +111,8 @@ static int copy_sc_to_user(struct sigcontext __user *to, err |= PUTREG(regs, RDI, to, rdi); err |= PUTREG(regs, RSI, to, rsi); err |= PUTREG(regs, RBP, to, rbp); - /* Must use orignal RSP, which is passed in, rather than what's in + /* + * Must use orignal RSP, which is passed in, rather than what's in * the pt_regs, because that's already been updated to point at the * signal frame. */ @@ -152,7 +154,7 @@ static int copy_sc_to_user(struct sigcontext __user *to, if (copy_to_user(to_fp, &fp, sizeof(struct user_i387_struct))) return 1; - return(err); + return err; } struct rt_sigframe @@ -188,7 +190,8 @@ int setup_signal_stack_si(unsigned long stack_top, int sig, goto out; } - /* Update SP now because the page fault handler refuses to extend + /* + * Update SP now because the page fault handler refuses to extend * the stack if the faulting address is too far below the current * SP, which frame now certainly is. If there's an error, the original * value is restored on the way out. @@ -216,8 +219,10 @@ int setup_signal_stack_si(unsigned long stack_top, int sig, err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set)); - /* Set up to return from userspace. If provided, use a stub - already in userspace. */ + /* + * Set up to return from userspace. If provided, use a stub + * already in userspace. + */ /* x86-64 should always use SA_RESTORER. */ if (ka->sa.sa_flags & SA_RESTORER) err |= __put_user(ka->sa.sa_restorer, &frame->pretcode); @@ -239,8 +244,10 @@ int setup_signal_stack_si(unsigned long stack_top, int sig, /* In case the signal handler was declared without prototypes */ PT_REGS_RAX(regs) = 0; - /* This also works for non SA_SIGINFO handlers because they expect the - next argument after the signal number on the stack. */ + /* + * This also works for non SA_SIGINFO handlers because they expect the + * next argument after the signal number on the stack. + */ PT_REGS_RSI(regs) = (unsigned long) &frame->info; PT_REGS_RDX(regs) = (unsigned long) &frame->uc; PT_REGS_RIP(regs) = (unsigned long) ka->sa.sa_handler; @@ -276,7 +283,7 @@ long sys_rt_sigreturn(struct pt_regs *regs) /* Avoid ERESTART handling */ PT_REGS_SYSCALL_NR(¤t->thread.regs) = -1; - return(PT_REGS_SYSCALL_RET(¤t->thread.regs)); + return PT_REGS_SYSCALL_RET(¤t->thread.regs); segfault: force_sig(SIGSEGV, current); |