aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
authorRoland McGrath <roland@redhat.com>2008-01-30 07:30:52 -0500
committerIngo Molnar <mingo@elte.hu>2008-01-30 07:30:52 -0500
commite4aed6cc45f06acd35e3dfbbaf632c5d5aa897c0 (patch)
treee39ce619e9035e283fc858d6ea7fa235f74f7992 /arch
parent62a97d447b511bf4f0f0aa8cdccfb9ed1c934c8b (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.c60
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 */
57static 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 */
72static 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
55static 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 &regs->r15 + (offset / sizeof(regs->r15));
59}
60
93static int putreg(struct task_struct *child, 61static 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
169static unsigned long getreg(struct task_struct *child, unsigned long regno) 134static 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;