diff options
author | Roland McGrath <roland@redhat.com> | 2008-01-30 07:30:52 -0500 |
---|---|---|
committer | Ingo Molnar <mingo@elte.hu> | 2008-01-30 07:30:52 -0500 |
commit | e4aed6cc45f06acd35e3dfbbaf632c5d5aa897c0 (patch) | |
tree | e39ce619e9035e283fc858d6ea7fa235f74f7992 /arch | |
parent | 62a97d447b511bf4f0f0aa8cdccfb9ed1c934c8b (diff) |
x86-64 ptrace: use task_pt_regs
This cleans up the 64-bit ptrace code to use task_pt_regs instead of its
own redundant code that does the same thing a different way.
Signed-off-by: Roland McGrath <roland@redhat.com>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Diffstat (limited to 'arch')
-rw-r--r-- | arch/x86/kernel/ptrace_64.c | 60 |
1 files changed, 12 insertions, 48 deletions
diff --git a/arch/x86/kernel/ptrace_64.c b/arch/x86/kernel/ptrace_64.c index b129b1fbb5d9..d0a0aeaaa0c2 100644 --- a/arch/x86/kernel/ptrace_64.c +++ b/arch/x86/kernel/ptrace_64.c | |||
@@ -43,44 +43,6 @@ | |||
43 | #define FLAG_MASK 0x54dd5UL | 43 | #define FLAG_MASK 0x54dd5UL |
44 | 44 | ||
45 | /* | 45 | /* |
46 | * eflags and offset of eflags on child stack.. | ||
47 | */ | ||
48 | #define EFLAGS offsetof(struct pt_regs, eflags) | ||
49 | #define EFL_OFFSET ((int)(EFLAGS-sizeof(struct pt_regs))) | ||
50 | |||
51 | /* | ||
52 | * this routine will get a word off of the processes privileged stack. | ||
53 | * the offset is how far from the base addr as stored in the TSS. | ||
54 | * this routine assumes that all the privileged stacks are in our | ||
55 | * data space. | ||
56 | */ | ||
57 | static inline unsigned long get_stack_long(struct task_struct *task, int offset) | ||
58 | { | ||
59 | unsigned char *stack; | ||
60 | |||
61 | stack = (unsigned char *)task->thread.rsp0; | ||
62 | stack += offset; | ||
63 | return (*((unsigned long *)stack)); | ||
64 | } | ||
65 | |||
66 | /* | ||
67 | * this routine will put a word on the processes privileged stack. | ||
68 | * the offset is how far from the base addr as stored in the TSS. | ||
69 | * this routine assumes that all the privileged stacks are in our | ||
70 | * data space. | ||
71 | */ | ||
72 | static inline long put_stack_long(struct task_struct *task, int offset, | ||
73 | unsigned long data) | ||
74 | { | ||
75 | unsigned char * stack; | ||
76 | |||
77 | stack = (unsigned char *) task->thread.rsp0; | ||
78 | stack += offset; | ||
79 | *(unsigned long *) stack = data; | ||
80 | return 0; | ||
81 | } | ||
82 | |||
83 | /* | ||
84 | * Called by kernel/ptrace.c when detaching.. | 46 | * Called by kernel/ptrace.c when detaching.. |
85 | * | 47 | * |
86 | * Make sure the single step bit is not set. | 48 | * Make sure the single step bit is not set. |
@@ -90,11 +52,16 @@ void ptrace_disable(struct task_struct *child) | |||
90 | user_disable_single_step(child); | 52 | user_disable_single_step(child); |
91 | } | 53 | } |
92 | 54 | ||
55 | static unsigned long *pt_regs_access(struct pt_regs *regs, unsigned long offset) | ||
56 | { | ||
57 | BUILD_BUG_ON(offsetof(struct pt_regs, r15) != 0); | ||
58 | return ®s->r15 + (offset / sizeof(regs->r15)); | ||
59 | } | ||
60 | |||
93 | static int putreg(struct task_struct *child, | 61 | static int putreg(struct task_struct *child, |
94 | unsigned long regno, unsigned long value) | 62 | unsigned long regno, unsigned long value) |
95 | { | 63 | { |
96 | unsigned long tmp; | 64 | struct pt_regs *regs = task_pt_regs(child); |
97 | |||
98 | switch (regno) { | 65 | switch (regno) { |
99 | case offsetof(struct user_regs_struct,fs): | 66 | case offsetof(struct user_regs_struct,fs): |
100 | if (value && (value & 3) != 3) | 67 | if (value && (value & 3) != 3) |
@@ -152,9 +119,7 @@ static int putreg(struct task_struct *child, | |||
152 | clear_tsk_thread_flag(child, TIF_FORCED_TF); | 119 | clear_tsk_thread_flag(child, TIF_FORCED_TF); |
153 | else if (test_tsk_thread_flag(child, TIF_FORCED_TF)) | 120 | else if (test_tsk_thread_flag(child, TIF_FORCED_TF)) |
154 | value |= X86_EFLAGS_TF; | 121 | value |= X86_EFLAGS_TF; |
155 | tmp = get_stack_long(child, EFL_OFFSET); | 122 | value |= regs->eflags & ~FLAG_MASK; |
156 | tmp &= ~FLAG_MASK; | ||
157 | value |= tmp; | ||
158 | break; | 123 | break; |
159 | case offsetof(struct user_regs_struct,cs): | 124 | case offsetof(struct user_regs_struct,cs): |
160 | if ((value & 3) != 3) | 125 | if ((value & 3) != 3) |
@@ -162,12 +127,13 @@ static int putreg(struct task_struct *child, | |||
162 | value &= 0xffff; | 127 | value &= 0xffff; |
163 | break; | 128 | break; |
164 | } | 129 | } |
165 | put_stack_long(child, regno - sizeof(struct pt_regs), value); | 130 | *pt_regs_access(regs, regno) = value; |
166 | return 0; | 131 | return 0; |
167 | } | 132 | } |
168 | 133 | ||
169 | static unsigned long getreg(struct task_struct *child, unsigned long regno) | 134 | static unsigned long getreg(struct task_struct *child, unsigned long regno) |
170 | { | 135 | { |
136 | struct pt_regs *regs = task_pt_regs(child); | ||
171 | unsigned long val; | 137 | unsigned long val; |
172 | switch (regno) { | 138 | switch (regno) { |
173 | case offsetof(struct user_regs_struct, fs): | 139 | case offsetof(struct user_regs_struct, fs): |
@@ -202,16 +168,14 @@ static unsigned long getreg(struct task_struct *child, unsigned long regno) | |||
202 | /* | 168 | /* |
203 | * If the debugger set TF, hide it from the readout. | 169 | * If the debugger set TF, hide it from the readout. |
204 | */ | 170 | */ |
205 | regno = regno - sizeof(struct pt_regs); | 171 | val = regs->eflags; |
206 | val = get_stack_long(child, regno); | ||
207 | if (test_tsk_thread_flag(child, TIF_IA32)) | 172 | if (test_tsk_thread_flag(child, TIF_IA32)) |
208 | val &= 0xffffffff; | 173 | val &= 0xffffffff; |
209 | if (test_tsk_thread_flag(child, TIF_FORCED_TF)) | 174 | if (test_tsk_thread_flag(child, TIF_FORCED_TF)) |
210 | val &= ~X86_EFLAGS_TF; | 175 | val &= ~X86_EFLAGS_TF; |
211 | return val; | 176 | return val; |
212 | default: | 177 | default: |
213 | regno = regno - sizeof(struct pt_regs); | 178 | val = *pt_regs_access(regs, regno); |
214 | val = get_stack_long(child, regno); | ||
215 | if (test_tsk_thread_flag(child, TIF_IA32)) | 179 | if (test_tsk_thread_flag(child, TIF_IA32)) |
216 | val &= 0xffffffff; | 180 | val &= 0xffffffff; |
217 | return val; | 181 | return val; |