Skip to content

Commit

Permalink
i#1901: switch to r10 instead of rcx for the first syscall param
Browse files Browse the repository at this point in the history
Switches to using r10 which is where the first syscall param is for
OP_syscall.  This allows tools to clobber rcx at the syscall.  This fixes
some weird behavior with tools on Windows 10.

Fixes #1901

Review-URL: https://codereview.appspot.com/310720043
  • Loading branch information
derekbruening committed Aug 29, 2016
1 parent 639b429 commit 542d0ae
Show file tree
Hide file tree
Showing 2 changed files with 14 additions and 5 deletions.
6 changes: 5 additions & 1 deletion core/win32/os_private.h
Original file line number Diff line number Diff line change
Expand Up @@ -259,7 +259,11 @@ sys_param_addr(dcontext_t *dcontext, reg_t *param_base, int num)
/* we force-inline get_mcontext() and so don't take it as a param */
priv_mcontext_t *mc = get_mcontext(dcontext);
switch (num) {
case 0: return &mc->xcx;
/* The first arg was in rcx, but that's clobbered by OP_sysycall, so the wrapper
* copies it to r10. We need to use r10 as our own instru sometimes takes
* advantage of the dead rcx and clobbers it inside the wrapper (i#1901).
*/
case 0: return &mc->r10;
case 1: return &mc->xdx;
case 2: return &mc->r8;
case 3: return &mc->r9;
Expand Down
13 changes: 9 additions & 4 deletions core/win32/syscall.c
Original file line number Diff line number Diff line change
Expand Up @@ -1750,7 +1750,10 @@ presys_TerminateProcess(dcontext_t *dcontext, reg_t *param_base)
/* FIXME: what if syscall returns w/ STATUS_PROCESS_IS_TERMINATING? */
os_terminate_wow64_write_args(true/*process*/, process_handle, exit_status);
cleanup_and_terminate(dcontext, syscalls[SYS_TerminateProcess],
IF_X64_ELSE(mc->xcx, mc->xdx),
/* r10, which will go to rcx in cleanup_and_terminate
* and back to r10 in global_do_syscall_syscall (i#1901).
*/
IF_X64_ELSE(mc->r10, mc->xdx),
mc->xdx, true /* entire process */, 0, 0);
}
return true;
Expand Down Expand Up @@ -1829,7 +1832,10 @@ presys_TerminateThread(dcontext_t *dcontext, reg_t *param_base)
KSTOP(num_exits_dir_syscall);
os_terminate_wow64_write_args(false/*thread*/, thread_handle, exit_status);
cleanup_and_terminate(dcontext, syscalls[SYS_TerminateThread],
IF_X64_ELSE(mc->xcx, mc->xdx),
/* r10, which will go to rcx in cleanup_and_terminate
* and back to r10 in global_do_syscall_syscall (i#1901).
*/
IF_X64_ELSE(mc->r10, mc->xdx),
mc->xdx, exitproc, 0, 0);
}
}
Expand Down Expand Up @@ -4474,8 +4480,7 @@ dr_syscall_invoke_another(void *drcontext)
}
# ifdef X64
else if (get_syscall_method() == SYSCALL_METHOD_SYSCALL) {
/* we could instead have sys_param_addr() use r10, like we do on linux */
mc->r10 = mc->xcx;
/* sys_param_addr() is already using r10 */
}
# endif
}
Expand Down

0 comments on commit 542d0ae

Please sign in to comment.