[PATCH] ntdll: Always restore TEB to x18 on aarch 64 on return from calls to builtins

Martin Storsjo martin at martin.st
Fri Oct 13 02:52:40 CDT 2017


This requires always enabling relaying of calls though.

This isn't enough for cases where builtin functions call back into
the user code though.

Signed-off-by: Martin Storsjo <martin at martin.st>
---
I'm pretty sure this approach has been suggested and dismissed before,
so I'm not sincerely trying to get this patch merged; I'm using it
locally and posting it for reference, if someone else is interested
in locally patching their builds.

The previous attempts of disabling use of x18 within the wine codebase
worked fine for some of the test binaries from the windows 10 SDK,
however as pointed out by Alexandre before, this is futile as long as
the rest of the host environment can clobber x18 in any call to system
functions.

This fixes running binaries built by Visual C++ for ARM64 (which finally
is out publicly now) on a normal debian aarch64 userland. Visual C++ uses
the TEB while clang for windows/arm64 hasn't (so far).
---
 dlls/ntdll/loader.c | 8 +++++++-
 dlls/ntdll/relay.c  | 4 ++++
 2 files changed, 11 insertions(+), 1 deletion(-)

diff --git a/dlls/ntdll/loader.c b/dlls/ntdll/loader.c
index 9c89d57..ad15a15 100644
--- a/dlls/ntdll/loader.c
+++ b/dlls/ntdll/loader.c
@@ -1687,7 +1687,13 @@ static void load_builtin_callback( void *module, const char *filename )
     SERVER_END_REQ;
 
     /* setup relay debugging entry points */
-    if (TRACE_ON(relay)) RELAY_SetupDLL( module );
+#ifdef __aarch64__
+    /* Always enable relay entry points on aarch64, to allow restoring
+     * the TEB to x18. */
+#else
+    if (TRACE_ON(relay))
+#endif
+        RELAY_SetupDLL( module );
 }
 
 
diff --git a/dlls/ntdll/relay.c b/dlls/ntdll/relay.c
index f16b4fc..9156c08 100644
--- a/dlls/ntdll/relay.c
+++ b/dlls/ntdll/relay.c
@@ -577,8 +577,12 @@ static LONGLONG WINAPI relay_call( struct relay_descr *descr, unsigned int idx,
     BYTE nb_args = LOBYTE(HIWORD(idx));
     BYTE flags   = HIBYTE(HIWORD(idx));
     void *func = relay_trace_entry( descr, idx, stack + 3 );
+    void *teb;
     LONGLONG ret = call_entry_point( func, nb_args, stack + 4, flags );
     relay_trace_exit( descr, idx, stack + 3, ret );
+    teb = NtCurrentTeb();
+    /* Restore the TEB pointer, in case the builtin call clobbered it. */
+    __asm__ __volatile__( "mov x18, %0" : : "r" (teb) );
     return ret;
 }
 
-- 
2.7.4




More information about the wine-patches mailing list