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 | 62a97d447b511bf4f0f0aa8cdccfb9ed1c934c8b (patch) | |
tree | 4a1d7e285b3013ff34189bff17269f0ce11f05b0 /arch/x86/kernel/ptrace_32.c | |
parent | d6f4fb7558ee8138fe86e2778bc16e3794d0baa2 (diff) |
x86-32 ptrace: use task_pt_regs
This cleans up the 32-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/x86/kernel/ptrace_32.c')
-rw-r--r-- | arch/x86/kernel/ptrace_32.c | 68 |
1 files changed, 16 insertions, 52 deletions
diff --git a/arch/x86/kernel/ptrace_32.c b/arch/x86/kernel/ptrace_32.c index bd3668c2421a..a1425e9ad028 100644 --- a/arch/x86/kernel/ptrace_32.c +++ b/arch/x86/kernel/ptrace_32.c | |||
@@ -37,53 +37,20 @@ | |||
37 | */ | 37 | */ |
38 | #define FLAG_MASK 0x00050dd5 | 38 | #define FLAG_MASK 0x00050dd5 |
39 | 39 | ||
40 | /* | 40 | static long *pt_regs_access(struct pt_regs *regs, unsigned long regno) |
41 | * Offset of eflags on child stack.. | ||
42 | */ | ||
43 | #define EFL_OFFSET offsetof(struct pt_regs, eflags) | ||
44 | |||
45 | static inline struct pt_regs *get_child_regs(struct task_struct *task) | ||
46 | { | ||
47 | void *stack_top = (void *)task->thread.esp0; | ||
48 | return stack_top - sizeof(struct pt_regs); | ||
49 | } | ||
50 | |||
51 | /* | ||
52 | * This routine will get a word off of the processes privileged stack. | ||
53 | * the offset is bytes into the pt_regs structure on the stack. | ||
54 | * This routine assumes that all the privileged stacks are in our | ||
55 | * data space. | ||
56 | */ | ||
57 | static inline int get_stack_long(struct task_struct *task, int offset) | ||
58 | { | 41 | { |
59 | unsigned char *stack; | 42 | BUILD_BUG_ON(offsetof(struct pt_regs, ebx) != 0); |
60 | 43 | if (regno > FS) | |
61 | stack = (unsigned char *)task->thread.esp0 - sizeof(struct pt_regs); | 44 | --regno; |
62 | stack += offset; | 45 | return ®s->ebx + regno; |
63 | return (*((int *)stack)); | ||
64 | } | ||
65 | |||
66 | /* | ||
67 | * This routine will put a word on the processes privileged stack. | ||
68 | * the offset is bytes into the pt_regs structure on the stack. | ||
69 | * This routine assumes that all the privileged stacks are in our | ||
70 | * data space. | ||
71 | */ | ||
72 | static inline int 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.esp0 - sizeof(struct pt_regs); | ||
78 | stack += offset; | ||
79 | *(unsigned long *) stack = data; | ||
80 | return 0; | ||
81 | } | 46 | } |
82 | 47 | ||
83 | static int putreg(struct task_struct *child, | 48 | static int putreg(struct task_struct *child, |
84 | unsigned long regno, unsigned long value) | 49 | unsigned long regno, unsigned long value) |
85 | { | 50 | { |
86 | switch (regno >> 2) { | 51 | struct pt_regs *regs = task_pt_regs(child); |
52 | regno >>= 2; | ||
53 | switch (regno) { | ||
87 | case GS: | 54 | case GS: |
88 | if (value && (value & 3) != 3) | 55 | if (value && (value & 3) != 3) |
89 | return -EIO; | 56 | return -EIO; |
@@ -113,26 +80,25 @@ static int putreg(struct task_struct *child, | |||
113 | clear_tsk_thread_flag(child, TIF_FORCED_TF); | 80 | clear_tsk_thread_flag(child, TIF_FORCED_TF); |
114 | else if (test_tsk_thread_flag(child, TIF_FORCED_TF)) | 81 | else if (test_tsk_thread_flag(child, TIF_FORCED_TF)) |
115 | value |= X86_EFLAGS_TF; | 82 | value |= X86_EFLAGS_TF; |
116 | value |= get_stack_long(child, EFL_OFFSET) & ~FLAG_MASK; | 83 | value |= regs->eflags & ~FLAG_MASK; |
117 | break; | 84 | break; |
118 | } | 85 | } |
119 | if (regno > FS*4) | 86 | *pt_regs_access(regs, regno) = value; |
120 | regno -= 1*4; | ||
121 | put_stack_long(child, regno, value); | ||
122 | return 0; | 87 | return 0; |
123 | } | 88 | } |
124 | 89 | ||
125 | static unsigned long getreg(struct task_struct *child, | 90 | static unsigned long getreg(struct task_struct *child, unsigned long regno) |
126 | unsigned long regno) | ||
127 | { | 91 | { |
92 | struct pt_regs *regs = task_pt_regs(child); | ||
128 | unsigned long retval = ~0UL; | 93 | unsigned long retval = ~0UL; |
129 | 94 | ||
130 | switch (regno >> 2) { | 95 | regno >>= 2; |
96 | switch (regno) { | ||
131 | case EFL: | 97 | case EFL: |
132 | /* | 98 | /* |
133 | * If the debugger set TF, hide it from the readout. | 99 | * If the debugger set TF, hide it from the readout. |
134 | */ | 100 | */ |
135 | retval = get_stack_long(child, EFL_OFFSET); | 101 | retval = regs->eflags; |
136 | if (test_tsk_thread_flag(child, TIF_FORCED_TF)) | 102 | if (test_tsk_thread_flag(child, TIF_FORCED_TF)) |
137 | retval &= ~X86_EFLAGS_TF; | 103 | retval &= ~X86_EFLAGS_TF; |
138 | break; | 104 | break; |
@@ -147,9 +113,7 @@ static unsigned long getreg(struct task_struct *child, | |||
147 | retval = 0xffff; | 113 | retval = 0xffff; |
148 | /* fall through */ | 114 | /* fall through */ |
149 | default: | 115 | default: |
150 | if (regno > FS*4) | 116 | retval &= *pt_regs_access(regs, regno); |
151 | regno -= 1*4; | ||
152 | retval &= get_stack_long(child, regno); | ||
153 | } | 117 | } |
154 | return retval; | 118 | return retval; |
155 | } | 119 | } |