summaryrefslogtreecommitdiff
path: root/arch/x86/um/os-Linux/registers.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2011-11-02 09:45:39 -0700
committerLinus Torvalds <torvalds@linux-foundation.org>2011-11-02 09:45:39 -0700
commitde0a5345a55b8dd5a4695181275df0e691176830 (patch)
tree17530e824f7f46ce0b1757657179fb5957a6add5 /arch/x86/um/os-Linux/registers.c
parent994c0e992522c123298b4a91b72f5e67ba2d1123 (diff)
parent8535639810e578960233ad39def3ac2157b0c3ec (diff)
downloadlinux-rt-de0a5345a55b8dd5a4695181275df0e691176830.tar.gz
Merge branch 'for-linus' of git://github.com/richardweinberger/linux
* 'for-linus' of git://github.com/richardweinberger/linux: (90 commits) um: fix ubd cow size um: Fix kmalloc argument order in um/vdso/vma.c um: switch to use of drivers/Kconfig UserModeLinux-HOWTO.txt: fix a typo UserModeLinux-HOWTO.txt: remove ^H characters um: we need sys/user.h only on i386 um: merge delay_{32,64}.c um: distribute exports to where exported stuff is defined um: kill system-um.h um: generic ftrace.h will do... um: segment.h is x86-only and needed only there um: asm/pda.h is not needed anymore um: hw_irq.h can go generic as well um: switch to generic-y um: clean Kconfig up a bit um: a couple of missing dependencies... um: kill useless argument of free_chan() and free_one_chan() um: unify ptrace_user.h um: unify KSTK_... um: fix gcov build breakage ...
Diffstat (limited to 'arch/x86/um/os-Linux/registers.c')
-rw-r--r--arch/x86/um/os-Linux/registers.c113
1 files changed, 113 insertions, 0 deletions
diff --git a/arch/x86/um/os-Linux/registers.c b/arch/x86/um/os-Linux/registers.c
new file mode 100644
index 000000000000..0cdbb86b012b
--- /dev/null
+++ b/arch/x86/um/os-Linux/registers.c
@@ -0,0 +1,113 @@
+/*
+ * Copyright (C) 2004 PathScale, Inc
+ * Copyright (C) 2004 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
+ * Licensed under the GPL
+ */
+
+#include <errno.h>
+#include <sys/ptrace.h>
+#ifdef __i386__
+#include <sys/user.h>
+#endif
+#include "longjmp.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)
+ return -errno;
+ return 0;
+}
+
+int restore_fp_registers(int pid, unsigned long *fp_regs)
+{
+ if (ptrace(PTRACE_SETFPREGS, pid, 0, fp_regs) < 0)
+ return -errno;
+ return 0;
+}
+
+#ifdef __i386__
+int have_fpx_regs = 1;
+int save_fpx_registers(int pid, unsigned long *fp_regs)
+{
+ 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)
+ return -errno;
+ return 0;
+}
+
+int get_fp_registers(int pid, unsigned long *regs)
+{
+ if (have_fpx_regs)
+ return save_fpx_registers(pid, regs);
+ else
+ return save_fp_registers(pid, regs);
+}
+
+int put_fp_registers(int pid, unsigned long *regs)
+{
+ if (have_fpx_regs)
+ return restore_fpx_registers(pid, regs);
+ else
+ return restore_fp_registers(pid, regs);
+}
+
+void arch_init_registers(int pid)
+{
+ struct user_fpxregs_struct fpx_regs;
+ int err;
+
+ err = ptrace(PTRACE_GETFPXREGS, pid, 0, &fpx_regs);
+ if (!err)
+ return;
+
+ if (errno != EIO)
+ panic("check_ptrace : PTRACE_GETFPXREGS failed, errno = %d",
+ errno);
+
+ have_fpx_regs = 0;
+}
+#else
+
+int get_fp_registers(int pid, unsigned long *regs)
+{
+ return save_fp_registers(pid, regs);
+}
+
+int put_fp_registers(int pid, unsigned long *regs)
+{
+ return restore_fp_registers(pid, regs);
+}
+
+#endif
+
+unsigned long get_thread_reg(int reg, jmp_buf *buf)
+{
+ switch (reg) {
+#ifdef __i386__
+ case HOST_IP:
+ return buf[0]->__eip;
+ case HOST_SP:
+ return buf[0]->__esp;
+ case HOST_BP:
+ return buf[0]->__ebp;
+#else
+ case HOST_IP:
+ return buf[0]->__rip;
+ case HOST_SP:
+ return buf[0]->__rsp;
+ case HOST_BP:
+ return buf[0]->__rbp;
+#endif
+ default:
+ printk(UM_KERN_ERR "get_thread_regs - unknown register %d\n",
+ reg);
+ return 0;
+ }
+}