diff options
Diffstat (limited to 'arch/um/sys-x86_64/ptrace.c')
-rw-r--r-- | arch/um/sys-x86_64/ptrace.c | 53 |
1 files changed, 49 insertions, 4 deletions
diff --git a/arch/um/sys-x86_64/ptrace.c b/arch/um/sys-x86_64/ptrace.c index 8c146b2a1e00..74eee5c7c6dd 100644 --- a/arch/um/sys-x86_64/ptrace.c +++ b/arch/um/sys-x86_64/ptrace.c | |||
@@ -5,10 +5,11 @@ | |||
5 | */ | 5 | */ |
6 | 6 | ||
7 | #define __FRAME_OFFSETS | 7 | #define __FRAME_OFFSETS |
8 | #include "asm/ptrace.h" | 8 | #include <asm/ptrace.h> |
9 | #include "linux/sched.h" | 9 | #include <linux/sched.h> |
10 | #include "linux/errno.h" | 10 | #include <linux/errno.h> |
11 | #include "asm/elf.h" | 11 | #include <asm/uaccess.h> |
12 | #include <asm/elf.h> | ||
12 | 13 | ||
13 | /* XXX x86_64 */ | 14 | /* XXX x86_64 */ |
14 | unsigned long not_ss; | 15 | unsigned long not_ss; |
@@ -62,6 +63,27 @@ int putreg(struct task_struct *child, int regno, unsigned long value) | |||
62 | return 0; | 63 | return 0; |
63 | } | 64 | } |
64 | 65 | ||
66 | int poke_user(struct task_struct *child, long addr, long data) | ||
67 | { | ||
68 | if ((addr & 3) || addr < 0) | ||
69 | return -EIO; | ||
70 | |||
71 | if (addr < MAX_REG_OFFSET) | ||
72 | return putreg(child, addr, data); | ||
73 | |||
74 | #if 0 /* Need x86_64 debugregs handling */ | ||
75 | else if((addr >= offsetof(struct user, u_debugreg[0])) && | ||
76 | (addr <= offsetof(struct user, u_debugreg[7]))){ | ||
77 | addr -= offsetof(struct user, u_debugreg[0]); | ||
78 | addr = addr >> 2; | ||
79 | if((addr == 4) || (addr == 5)) return -EIO; | ||
80 | child->thread.arch.debugregs[addr] = data; | ||
81 | return 0; | ||
82 | } | ||
83 | #endif | ||
84 | return -EIO; | ||
85 | } | ||
86 | |||
65 | unsigned long getreg(struct task_struct *child, int regno) | 87 | unsigned long getreg(struct task_struct *child, int regno) |
66 | { | 88 | { |
67 | unsigned long retval = ~0UL; | 89 | unsigned long retval = ~0UL; |
@@ -84,6 +106,29 @@ unsigned long getreg(struct task_struct *child, int regno) | |||
84 | return retval; | 106 | return retval; |
85 | } | 107 | } |
86 | 108 | ||
109 | int peek_user(struct task_struct *child, long addr, long data) | ||
110 | { | ||
111 | /* read the word at location addr in the USER area. */ | ||
112 | unsigned long tmp; | ||
113 | |||
114 | if ((addr & 3) || addr < 0) | ||
115 | return -EIO; | ||
116 | |||
117 | tmp = 0; /* Default return condition */ | ||
118 | if(addr < MAX_REG_OFFSET){ | ||
119 | tmp = getreg(child, addr); | ||
120 | } | ||
121 | #if 0 /* Need x86_64 debugregs handling */ | ||
122 | else if((addr >= offsetof(struct user, u_debugreg[0])) && | ||
123 | (addr <= offsetof(struct user, u_debugreg[7]))){ | ||
124 | addr -= offsetof(struct user, u_debugreg[0]); | ||
125 | addr = addr >> 2; | ||
126 | tmp = child->thread.arch.debugregs[addr]; | ||
127 | } | ||
128 | #endif | ||
129 | return put_user(tmp, (unsigned long *) data); | ||
130 | } | ||
131 | |||
87 | void arch_switch(void) | 132 | void arch_switch(void) |
88 | { | 133 | { |
89 | /* XXX | 134 | /* XXX |