diff options
Diffstat (limited to 'arch/x86/kernel/ptrace_64.c')
-rw-r--r-- | arch/x86/kernel/ptrace_64.c | 224 |
1 files changed, 112 insertions, 112 deletions
diff --git a/arch/x86/kernel/ptrace_64.c b/arch/x86/kernel/ptrace_64.c index 56b31cd3b865..2427548f2a01 100644 --- a/arch/x86/kernel/ptrace_64.c +++ b/arch/x86/kernel/ptrace_64.c @@ -2,7 +2,7 @@ /* * Pentium III FXSR, SSE support * Gareth Hughes <gareth@valinux.com>, May 2000 - * + * * x86-64 port 2000-2002 Andi Kleen */ @@ -48,7 +48,7 @@ * Make sure the single step bit is not set. */ void ptrace_disable(struct task_struct *child) -{ +{ user_disable_single_step(child); } @@ -63,69 +63,69 @@ static int putreg(struct task_struct *child, { struct pt_regs *regs = task_pt_regs(child); switch (regno) { - case offsetof(struct user_regs_struct,fs): - if (value && (value & 3) != 3) - return -EIO; - child->thread.fsindex = value & 0xffff; - return 0; - case offsetof(struct user_regs_struct,gs): - if (value && (value & 3) != 3) - return -EIO; - child->thread.gsindex = value & 0xffff; - return 0; - case offsetof(struct user_regs_struct,ds): - if (value && (value & 3) != 3) - return -EIO; - child->thread.ds = value & 0xffff; - return 0; - case offsetof(struct user_regs_struct,es): - if (value && (value & 3) != 3) - return -EIO; - child->thread.es = value & 0xffff; - return 0; - case offsetof(struct user_regs_struct,ss): - if ((value & 3) != 3) - return -EIO; - value &= 0xffff; - return 0; - case offsetof(struct user_regs_struct,fs_base): - if (value >= TASK_SIZE_OF(child)) - return -EIO; - /* - * When changing the segment base, use do_arch_prctl - * to set either thread.fs or thread.fsindex and the - * corresponding GDT slot. - */ - if (child->thread.fs != value) - return do_arch_prctl(child, ARCH_SET_FS, value); - return 0; - case offsetof(struct user_regs_struct,gs_base): - /* - * Exactly the same here as the %fs handling above. - */ - if (value >= TASK_SIZE_OF(child)) - return -EIO; - if (child->thread.gs != value) - return do_arch_prctl(child, ARCH_SET_GS, value); - return 0; - case offsetof(struct user_regs_struct,flags): - value &= FLAG_MASK; - /* - * If the user value contains TF, mark that - * it was not "us" (the debugger) that set it. - * If not, make sure it stays set if we had. - */ - if (value & X86_EFLAGS_TF) - clear_tsk_thread_flag(child, TIF_FORCED_TF); - else if (test_tsk_thread_flag(child, TIF_FORCED_TF)) - value |= X86_EFLAGS_TF; - value |= regs->flags & ~FLAG_MASK; - break; - case offsetof(struct user_regs_struct,cs): - if ((value & 3) != 3) - return -EIO; - value &= 0xffff; - break; + case offsetof(struct user_regs_struct,fs): + if (value && (value & 3) != 3) + return -EIO; + child->thread.fsindex = value & 0xffff; + return 0; + case offsetof(struct user_regs_struct,gs): + if (value && (value & 3) != 3) + return -EIO; + child->thread.gsindex = value & 0xffff; + return 0; + case offsetof(struct user_regs_struct,ds): + if (value && (value & 3) != 3) + return -EIO; + child->thread.ds = value & 0xffff; + return 0; + case offsetof(struct user_regs_struct,es): + if (value && (value & 3) != 3) + return -EIO; + child->thread.es = value & 0xffff; + return 0; + case offsetof(struct user_regs_struct,ss): + if ((value & 3) != 3) + return -EIO; + value &= 0xffff; + return 0; + case offsetof(struct user_regs_struct,fs_base): + if (value >= TASK_SIZE_OF(child)) + return -EIO; + /* + * When changing the segment base, use do_arch_prctl + * to set either thread.fs or thread.fsindex and the + * corresponding GDT slot. + */ + if (child->thread.fs != value) + return do_arch_prctl(child, ARCH_SET_FS, value); + return 0; + case offsetof(struct user_regs_struct,gs_base): + /* + * Exactly the same here as the %fs handling above. + */ + if (value >= TASK_SIZE_OF(child)) + return -EIO; + if (child->thread.gs != value) + return do_arch_prctl(child, ARCH_SET_GS, value); + return 0; + case offsetof(struct user_regs_struct,flags): + value &= FLAG_MASK; + /* + * If the user value contains TF, mark that + * it was not "us" (the debugger) that set it. + * If not, make sure it stays set if we had. + */ + if (value & X86_EFLAGS_TF) + clear_tsk_thread_flag(child, TIF_FORCED_TF); + else if (test_tsk_thread_flag(child, TIF_FORCED_TF)) + value |= X86_EFLAGS_TF; + value |= regs->flags & ~FLAG_MASK; + break; + case offsetof(struct user_regs_struct,cs): + if ((value & 3) != 3) + return -EIO; + value &= 0xffff; + break; } *pt_regs_access(regs, regno) = value; return 0; @@ -136,49 +136,49 @@ static unsigned long getreg(struct task_struct *child, unsigned long regno) struct pt_regs *regs = task_pt_regs(child); unsigned long val; switch (regno) { - case offsetof(struct user_regs_struct, fs): - return child->thread.fsindex; - case offsetof(struct user_regs_struct, gs): - return child->thread.gsindex; - case offsetof(struct user_regs_struct, ds): - return child->thread.ds; - case offsetof(struct user_regs_struct, es): - return child->thread.es; - case offsetof(struct user_regs_struct, fs_base): - /* - * do_arch_prctl may have used a GDT slot instead of - * the MSR. To userland, it appears the same either - * way, except the %fs segment selector might not be 0. - */ - if (child->thread.fs != 0) - return child->thread.fs; - if (child->thread.fsindex != FS_TLS_SEL) - return 0; - return get_desc_base(&child->thread.tls_array[FS_TLS]); - case offsetof(struct user_regs_struct, gs_base): - /* - * Exactly the same here as the %fs handling above. - */ - if (child->thread.gs != 0) - return child->thread.gs; - if (child->thread.gsindex != GS_TLS_SEL) - return 0; - return get_desc_base(&child->thread.tls_array[GS_TLS]); - case offsetof(struct user_regs_struct, flags): - /* - * If the debugger set TF, hide it from the readout. - */ - val = regs->flags; - if (test_tsk_thread_flag(child, TIF_IA32)) - val &= 0xffffffff; - if (test_tsk_thread_flag(child, TIF_FORCED_TF)) - val &= ~X86_EFLAGS_TF; - return val; - default: - val = *pt_regs_access(regs, regno); - if (test_tsk_thread_flag(child, TIF_IA32)) - val &= 0xffffffff; - return val; + case offsetof(struct user_regs_struct, fs): + return child->thread.fsindex; + case offsetof(struct user_regs_struct, gs): + return child->thread.gsindex; + case offsetof(struct user_regs_struct, ds): + return child->thread.ds; + case offsetof(struct user_regs_struct, es): + return child->thread.es; + case offsetof(struct user_regs_struct, fs_base): + /* + * do_arch_prctl may have used a GDT slot instead of + * the MSR. To userland, it appears the same either + * way, except the %fs segment selector might not be 0. + */ + if (child->thread.fs != 0) + return child->thread.fs; + if (child->thread.fsindex != FS_TLS_SEL) + return 0; + return get_desc_base(&child->thread.tls_array[FS_TLS]); + case offsetof(struct user_regs_struct, gs_base): + /* + * Exactly the same here as the %fs handling above. + */ + if (child->thread.gs != 0) + return child->thread.gs; + if (child->thread.gsindex != GS_TLS_SEL) + return 0; + return get_desc_base(&child->thread.tls_array[GS_TLS]); + case offsetof(struct user_regs_struct, flags): + /* + * If the debugger set TF, hide it from the readout. + */ + val = regs->flags; + if (test_tsk_thread_flag(child, TIF_IA32)) + val &= 0xffffffff; + if (test_tsk_thread_flag(child, TIF_FORCED_TF)) + val &= ~X86_EFLAGS_TF; + return val; + default: + val = *pt_regs_access(regs, regno); + if (test_tsk_thread_flag(child, TIF_IA32)) + val &= 0xffffffff; + return val; } } @@ -244,7 +244,7 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data) switch (request) { /* when I and D space are separate, these will need to be fixed. */ - case PTRACE_PEEKTEXT: /* read word at location addr. */ + case PTRACE_PEEKTEXT: /* read word at location addr. */ case PTRACE_PEEKDATA: ret = generic_ptrace_peekdata(child, addr, data); break; @@ -310,10 +310,10 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data) (struct user_desc __user *) data, 0); break; #endif - /* normal 64bit interface to access TLS data. + /* normal 64bit interface to access TLS data. Works just like arch_prctl, except that the arguments are reversed. */ - case PTRACE_ARCH_PRCTL: + case PTRACE_ARCH_PRCTL: ret = do_arch_prctl(child, data, addr); break; @@ -386,7 +386,7 @@ static void syscall_trace(struct pt_regs *regs) printk("trace %s ip %lx sp %lx ax %d origrax %d caller %lx tiflags %x ptrace %x\n", current->comm, regs->ip, regs->sp, regs->ax, regs->orig_ax, __builtin_return_address(0), - current_thread_info()->flags, current->ptrace); + current_thread_info()->flags, current->ptrace); #endif ptrace_notify(SIGTRAP | ((current->ptrace & PT_TRACESYSGOOD) |