X-Git-Url: https://git.openpandora.org/cgi-bin/gitweb.cgi?p=pandora-kernel.git;a=blobdiff_plain;f=arch%2Fi386%2Fkernel%2Fptrace.c;h=4a8f8a2597233d06316afa6463d9e1eabdd9592e;hp=d3db03f4085d75ef607acda75e020cf0c0f10ffe;hb=9cdd79c9b99873d600d397fda012fc3f57cc2776;hpb=b3cf257623fabd8f1ee6700a6d328cc1c5da5a1d diff --git a/arch/i386/kernel/ptrace.c b/arch/i386/kernel/ptrace.c index d3db03f4085d..4a8f8a259723 100644 --- a/arch/i386/kernel/ptrace.c +++ b/arch/i386/kernel/ptrace.c @@ -45,7 +45,7 @@ /* * Offset of eflags on child stack.. */ -#define EFL_OFFSET ((EFL-2)*4-sizeof(struct pt_regs)) +#define EFL_OFFSET offsetof(struct pt_regs, eflags) static inline struct pt_regs *get_child_regs(struct task_struct *task) { @@ -54,24 +54,24 @@ static inline struct pt_regs *get_child_regs(struct task_struct *task) } /* - * 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 + * This routine will get a word off of the processes privileged stack. + * the offset is bytes into the pt_regs structure on the stack. + * This routine assumes that all the privileged stacks are in our * data space. */ static inline int get_stack_long(struct task_struct *task, int offset) { unsigned char *stack; - stack = (unsigned char *)task->thread.esp0; + stack = (unsigned char *)task->thread.esp0 - sizeof(struct pt_regs); stack += offset; return (*((int *)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 + * This routine will put a word on the processes privileged stack. + * the offset is bytes into the pt_regs structure on the stack. + * This routine assumes that all the privileged stacks are in our * data space. */ static inline int put_stack_long(struct task_struct *task, int offset, @@ -79,7 +79,7 @@ static inline int put_stack_long(struct task_struct *task, int offset, { unsigned char * stack; - stack = (unsigned char *) task->thread.esp0; + stack = (unsigned char *)task->thread.esp0 - sizeof(struct pt_regs); stack += offset; *(unsigned long *) stack = data; return 0; @@ -89,11 +89,6 @@ static int putreg(struct task_struct *child, unsigned long regno, unsigned long value) { switch (regno >> 2) { - case FS: - if (value && (value & 3) != 3) - return -EIO; - child->thread.fs = value; - return 0; case GS: if (value && (value & 3) != 3) return -EIO; @@ -101,6 +96,7 @@ static int putreg(struct task_struct *child, return 0; case DS: case ES: + case FS: if (value && (value & 3) != 3) return -EIO; value &= 0xffff; @@ -116,9 +112,9 @@ static int putreg(struct task_struct *child, value |= get_stack_long(child, EFL_OFFSET) & ~FLAG_MASK; break; } - if (regno > GS*4) - regno -= 2*4; - put_stack_long(child, regno - sizeof(struct pt_regs), value); + if (regno > FS*4) + regno -= 1*4; + put_stack_long(child, regno, value); return 0; } @@ -128,22 +124,19 @@ static unsigned long getreg(struct task_struct *child, unsigned long retval = ~0UL; switch (regno >> 2) { - case FS: - retval = child->thread.fs; - break; case GS: retval = child->thread.gs; break; case DS: case ES: + case FS: case SS: case CS: retval = 0xffff; /* fall through */ default: - if (regno > GS*4) - regno -= 2*4; - regno = regno - sizeof(struct pt_regs); + if (regno > FS*4) + regno -= 1*4; retval &= get_stack_long(child, regno); } return retval; @@ -185,17 +178,17 @@ static unsigned long convert_eip_to_linear(struct task_struct *child, struct pt_ return addr; } -static inline int is_at_popf(struct task_struct *child, struct pt_regs *regs) +static inline int is_setting_trap_flag(struct task_struct *child, struct pt_regs *regs) { int i, copied; - unsigned char opcode[16]; + unsigned char opcode[15]; unsigned long addr = convert_eip_to_linear(child, regs); copied = access_process_vm(child, addr, opcode, sizeof(opcode), 0); for (i = 0; i < copied; i++) { switch (opcode[i]) { - /* popf */ - case 0x9d: + /* popf and iret */ + case 0x9d: case 0xcf: return 1; /* opcode and address size prefixes */ case 0x66: case 0x67: @@ -247,7 +240,7 @@ static void set_singlestep(struct task_struct *child) * don't mark it as being "us" that set it, so that we * won't clear it by hand later. */ - if (is_at_popf(child, regs)) + if (is_setting_trap_flag(child, regs)) return; child->ptrace |= PT_DTRACE;