• Jinoh Kang's avatar
    ntdll: Fix restoring X16 and X17 in ARM64 syscall dispatcher. · 057467bf
    Jinoh Kang authored
    Today, NtContinue() on ARM64 does not restore X16 and X17 from the
    context.
    
    This is because the values for X16 and X17 are overwritten when the
    current thread returns to the "user mode" (PE side) via
    __wine_syscall_dispatcher, which in turn uses them as scratch registers
    for restoring SP and PC respectively.
    
    We cannot avoid using scratch registers when restoring SP and PC.  This
    is because ARMv8 does not have an unprivileged (EL0) instruction that
    loads SP and PC from memory or non-GPR architectural state.
    
    Fix this by making ARM64 __wine_syscall_dispatcher perform a full
    context restore via raise(SIGUSR2) when NtContinue() is used.
    
    Since raising a signal is quite expensive, it should be done only when
    necessary. To achieve this, split the ARM64 syscall dispatcher's
    returning behaviour into a fast path (that does not involve signals) and
    a slow path (that involves signals):
    
    - If CONTEXT_INTEGER is not set, the dispatcher takes the fast path:
      the X16 and X17 registers are clobbered as usual.
    
    - If X16 == PC and X17 == SP, the dispatcher also takes the fast path:
      it can safely use X16 and X17 without corrupting the register values,
      since those two registers already have the desired values.
    
      This fast path is used in call_user_apc_dispatcher(),
      call_user_exception_dispatcher(), and call_init_thunk().
    
    - Otherwise, the dispatcher takes the slow path: it raises SIGUSR2 and
      does full context restore in the signal handler.
    
    Fixes: 88e33621
    057467bf
Name
Last commit
Last update
..
tests Loading commit data...
unix Loading commit data...
Makefile.in Loading commit data...
actctx.c Loading commit data...
atom.c Loading commit data...
crypt.c Loading commit data...
debugbuffer.c Loading commit data...
env.c Loading commit data...
error.c Loading commit data...
error.h Loading commit data...
exception.c Loading commit data...
handletable.c Loading commit data...
heap.c Loading commit data...
large_int.c Loading commit data...
loader.c Loading commit data...
locale.c Loading commit data...
locale_private.h Loading commit data...
make_errors Loading commit data...
math.c Loading commit data...
misc.c Loading commit data...
ntdll.spec Loading commit data...
ntdll_misc.h Loading commit data...
path.c Loading commit data...
printf.c Loading commit data...
printf.h Loading commit data...
process.c Loading commit data...
reg.c Loading commit data...
relay.c Loading commit data...
resource.c Loading commit data...
rtl.c Loading commit data...
rtlbitmap.c Loading commit data...
rtlstr.c Loading commit data...
sec.c Loading commit data...
signal_arm.c Loading commit data...
signal_arm64.c Loading commit data...
signal_i386.c Loading commit data...
signal_x86_64.c Loading commit data...
string.c Loading commit data...
sync.c Loading commit data...
thread.c Loading commit data...
threadpool.c Loading commit data...
time.c Loading commit data...
unixlib.h Loading commit data...
version.c Loading commit data...
version.rc Loading commit data...
wcstring.c Loading commit data...