[lkml]   [2008]   [Mar]   [7]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
Messages in this thread
    Patch in this message
    Subject[PATCH] x86_64 ptrace orig_ax on ia32 task

    This makes 64-bit ptrace calls setting the 64-bit orig_ax field
    for a 32-bit task sign-extend the low 32 bits up to 64. This
    matches what a 64-bit debugger expects when tracing a 32-bit task.

    This follows on my "x86_64 ia32 syscall restart fix".
    This didn't matter until that was fixed.

    The debugger ignores or zeros the high half of every register slot it
    sets (including the orig_rax pseudo-register) uniformly. It expects
    that the setting of the low 32 bits always has the same meaning as a
    32-bit debugger setting those same 32 bits with native 32-bit

    This never arose before because the syscall restart check never
    matched any -ERESTART* values due to lack of sign extension. Before
    that fix, even 32-bit ptrace setting orig_eax to -1 failed to trigger
    the restart check anyway. So this was never noticed as a regression
    of 64-bit debuggers vs 32-bit debuggers on the same 64-bit kernel.

    Signed-off-by: Roland McGrath <>
    arch/x86/kernel/ptrace.c | 14 ++++++++++++++
    1 files changed, 14 insertions(+), 0 deletions(-)

    diff --git a/arch/x86/kernel/ptrace.c b/arch/x86/kernel/ptrace.c
    index f8eed1b..92b44e1 100644
    --- a/arch/x86/kernel/ptrace.c
    +++ b/arch/x86/kernel/ptrace.c
    @@ -322,6 +322,20 @@ static int putreg(struct task_struct *child,
    case offsetof(struct user_regs_struct, flags):
    return set_flags(child, value);

    + case offsetof(struct user_regs_struct, orig_ax):
    + /*
    + * For a 32-bit task, setting only the low 32 bits and
    + * leaving the high bits untouched (all 0) has the same
    + * effect as setting those bits via 32-bit ptrace would.
    + * This means sign-extending an orig_eax of -1, which
    + * here is an orig_rax of (u32)-1.
    + */
    + if (test_tsk_thread_flag(child, TIF_IA32))
    + value = (long) (s32) value;
    + break;
    #ifdef CONFIG_X86_64
    case offsetof(struct user_regs_struct,fs_base):
    if (value >= TASK_SIZE_OF(child))

     \ /
      Last update: 2008-03-07 23:59    [W:0.039 / U:9.600 seconds]
    ©2003-2016 Jasper Spaans. hosted at Digital OceanAdvertise on this site