mirror of
https://github.com/torvalds/linux.git
synced 2024-11-11 22:51:42 +00:00
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>
This commit is contained in:
parent
62a97d447b
commit
e4aed6cc45
@ -42,44 +42,6 @@
|
|||||||
*/
|
*/
|
||||||
#define FLAG_MASK 0x54dd5UL
|
#define FLAG_MASK 0x54dd5UL
|
||||||
|
|
||||||
/*
|
|
||||||
* eflags and offset of eflags on child stack..
|
|
||||||
*/
|
|
||||||
#define EFLAGS offsetof(struct pt_regs, eflags)
|
|
||||||
#define EFL_OFFSET ((int)(EFLAGS-sizeof(struct pt_regs)))
|
|
||||||
|
|
||||||
/*
|
|
||||||
* this routine will get a word off of the processes privileged stack.
|
|
||||||
* the offset is how far from the base addr as stored in the TSS.
|
|
||||||
* this routine assumes that all the privileged stacks are in our
|
|
||||||
* data space.
|
|
||||||
*/
|
|
||||||
static inline unsigned long get_stack_long(struct task_struct *task, int offset)
|
|
||||||
{
|
|
||||||
unsigned char *stack;
|
|
||||||
|
|
||||||
stack = (unsigned char *)task->thread.rsp0;
|
|
||||||
stack += offset;
|
|
||||||
return (*((unsigned long *)stack));
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* this routine will put a word on the processes privileged stack.
|
|
||||||
* the offset is how far from the base addr as stored in the TSS.
|
|
||||||
* this routine assumes that all the privileged stacks are in our
|
|
||||||
* data space.
|
|
||||||
*/
|
|
||||||
static inline long put_stack_long(struct task_struct *task, int offset,
|
|
||||||
unsigned long data)
|
|
||||||
{
|
|
||||||
unsigned char * stack;
|
|
||||||
|
|
||||||
stack = (unsigned char *) task->thread.rsp0;
|
|
||||||
stack += offset;
|
|
||||||
*(unsigned long *) stack = data;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Called by kernel/ptrace.c when detaching..
|
* Called by kernel/ptrace.c when detaching..
|
||||||
*
|
*
|
||||||
@ -90,11 +52,16 @@ void ptrace_disable(struct task_struct *child)
|
|||||||
user_disable_single_step(child);
|
user_disable_single_step(child);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static unsigned long *pt_regs_access(struct pt_regs *regs, unsigned long offset)
|
||||||
|
{
|
||||||
|
BUILD_BUG_ON(offsetof(struct pt_regs, r15) != 0);
|
||||||
|
return ®s->r15 + (offset / sizeof(regs->r15));
|
||||||
|
}
|
||||||
|
|
||||||
static int putreg(struct task_struct *child,
|
static int putreg(struct task_struct *child,
|
||||||
unsigned long regno, unsigned long value)
|
unsigned long regno, unsigned long value)
|
||||||
{
|
{
|
||||||
unsigned long tmp;
|
struct pt_regs *regs = task_pt_regs(child);
|
||||||
|
|
||||||
switch (regno) {
|
switch (regno) {
|
||||||
case offsetof(struct user_regs_struct,fs):
|
case offsetof(struct user_regs_struct,fs):
|
||||||
if (value && (value & 3) != 3)
|
if (value && (value & 3) != 3)
|
||||||
@ -152,9 +119,7 @@ static int putreg(struct task_struct *child,
|
|||||||
clear_tsk_thread_flag(child, TIF_FORCED_TF);
|
clear_tsk_thread_flag(child, TIF_FORCED_TF);
|
||||||
else if (test_tsk_thread_flag(child, TIF_FORCED_TF))
|
else if (test_tsk_thread_flag(child, TIF_FORCED_TF))
|
||||||
value |= X86_EFLAGS_TF;
|
value |= X86_EFLAGS_TF;
|
||||||
tmp = get_stack_long(child, EFL_OFFSET);
|
value |= regs->eflags & ~FLAG_MASK;
|
||||||
tmp &= ~FLAG_MASK;
|
|
||||||
value |= tmp;
|
|
||||||
break;
|
break;
|
||||||
case offsetof(struct user_regs_struct,cs):
|
case offsetof(struct user_regs_struct,cs):
|
||||||
if ((value & 3) != 3)
|
if ((value & 3) != 3)
|
||||||
@ -162,12 +127,13 @@ static int putreg(struct task_struct *child,
|
|||||||
value &= 0xffff;
|
value &= 0xffff;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
put_stack_long(child, regno - sizeof(struct pt_regs), value);
|
*pt_regs_access(regs, regno) = value;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static unsigned long getreg(struct task_struct *child, unsigned long regno)
|
static unsigned long getreg(struct task_struct *child, unsigned long regno)
|
||||||
{
|
{
|
||||||
|
struct pt_regs *regs = task_pt_regs(child);
|
||||||
unsigned long val;
|
unsigned long val;
|
||||||
switch (regno) {
|
switch (regno) {
|
||||||
case offsetof(struct user_regs_struct, fs):
|
case offsetof(struct user_regs_struct, fs):
|
||||||
@ -202,16 +168,14 @@ static unsigned long getreg(struct task_struct *child, unsigned long regno)
|
|||||||
/*
|
/*
|
||||||
* If the debugger set TF, hide it from the readout.
|
* If the debugger set TF, hide it from the readout.
|
||||||
*/
|
*/
|
||||||
regno = regno - sizeof(struct pt_regs);
|
val = regs->eflags;
|
||||||
val = get_stack_long(child, regno);
|
|
||||||
if (test_tsk_thread_flag(child, TIF_IA32))
|
if (test_tsk_thread_flag(child, TIF_IA32))
|
||||||
val &= 0xffffffff;
|
val &= 0xffffffff;
|
||||||
if (test_tsk_thread_flag(child, TIF_FORCED_TF))
|
if (test_tsk_thread_flag(child, TIF_FORCED_TF))
|
||||||
val &= ~X86_EFLAGS_TF;
|
val &= ~X86_EFLAGS_TF;
|
||||||
return val;
|
return val;
|
||||||
default:
|
default:
|
||||||
regno = regno - sizeof(struct pt_regs);
|
val = *pt_regs_access(regs, regno);
|
||||||
val = get_stack_long(child, regno);
|
|
||||||
if (test_tsk_thread_flag(child, TIF_IA32))
|
if (test_tsk_thread_flag(child, TIF_IA32))
|
||||||
val &= 0xffffffff;
|
val &= 0xffffffff;
|
||||||
return val;
|
return val;
|
||||||
|
Loading…
Reference in New Issue
Block a user