Part of this patch was [submitted 3 years ago](https://list.winehq.org/mailman3/hyperkitty/list/wine-devel@winehq.org/threa...) by Keno Fischer, but was not merged.
The separate `.byte` causes `gas` to [emit incorrect DWARF line info](https://sourceware.org/bugzilla/show_bug.cgi?id=28699), which caused a [crash in rr](https://github.com/rr-debugger/rr/issues/3009). Using `%fs`/`%gs` is also clearer.
From: Brendan Shanks bshanks@codeweavers.com
--- include/wine/exception.h | 8 ++++---- include/winnt.h | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-)
diff --git a/include/wine/exception.h b/include/wine/exception.h index e82bf2ea645..8c91e02e17e 100644 --- a/include/wine/exception.h +++ b/include/wine/exception.h @@ -253,9 +253,9 @@ static inline EXCEPTION_REGISTRATION_RECORD *__wine_push_frame( EXCEPTION_REGIST { #if defined(__GNUC__) && defined(__i386__) EXCEPTION_REGISTRATION_RECORD *prev; - __asm__ __volatile__(".byte 0x64\n\tmovl (0),%0" + __asm__ __volatile__("movl %%fs:0,%0" "\n\tmovl %0,(%1)" - "\n\t.byte 0x64\n\tmovl %1,(0)" + "\n\tmovl %1,%%fs:0" : "=&r" (prev) : "r" (frame) : "memory" ); return prev; #else @@ -269,7 +269,7 @@ static inline EXCEPTION_REGISTRATION_RECORD *__wine_push_frame( EXCEPTION_REGIST static inline EXCEPTION_REGISTRATION_RECORD *__wine_pop_frame( EXCEPTION_REGISTRATION_RECORD *frame ) { #if defined(__GNUC__) && defined(__i386__) - __asm__ __volatile__(".byte 0x64\n\tmovl %0,(0)" + __asm__ __volatile__("movl %0,%%fs:0" : : "r" (frame->Prev) : "memory" ); return frame->Prev;
@@ -284,7 +284,7 @@ static inline EXCEPTION_REGISTRATION_RECORD *__wine_get_frame(void) { #if defined(__GNUC__) && defined(__i386__) EXCEPTION_REGISTRATION_RECORD *ret; - __asm__ __volatile__(".byte 0x64\n\tmovl (0),%0" : "=r" (ret) ); + __asm__ __volatile__("movl %%fs:0,%0" : "=r" (ret) ); return ret; #else NT_TIB *teb = (NT_TIB *)NtCurrentTeb(); diff --git a/include/winnt.h b/include/winnt.h index c810830b2b3..0dae6a05b99 100644 --- a/include/winnt.h +++ b/include/winnt.h @@ -2446,7 +2446,7 @@ NTSYSAPI struct _TEB * WINAPI NtCurrentTeb(void); static FORCEINLINE struct _TEB * WINAPI NtCurrentTeb(void) { struct _TEB *teb; - __asm__(".byte 0x64\n\tmovl (0x18),%0" : "=r" (teb)); + __asm__("movl %%fs:0x18,%0" : "=r" (teb)); return teb; } #elif defined(__i386__) && defined(_MSC_VER) @@ -2471,7 +2471,7 @@ static FORCEINLINE struct _TEB * WINAPI NtCurrentTeb(void) static FORCEINLINE struct _TEB * WINAPI NtCurrentTeb(void) { struct _TEB *teb; - __asm__(".byte 0x65\n\tmovq (0x30),%0" : "=r" (teb)); + __asm__("movq %%gs:0x30,%0" : "=r" (teb)); return teb; } #elif defined(__x86_64__) && defined(_MSC_VER)
From: Brendan Shanks bshanks@codeweavers.com
--- dlls/ntdll/signal_i386.c | 14 +++++--------- dlls/ntdll/unix/signal_x86_64.c | 4 ++-- 2 files changed, 7 insertions(+), 11 deletions(-)
diff --git a/dlls/ntdll/signal_i386.c b/dlls/ntdll/signal_i386.c index 8f11d19024b..dd7c33933ba 100644 --- a/dlls/ntdll/signal_i386.c +++ b/dlls/ntdll/signal_i386.c @@ -617,7 +617,7 @@ __ASM_STDCALL_FUNC( DbgUserBreakPoint, 0, "int $3; ret" /********************************************************************** * NtCurrentTeb (NTDLL.@) */ -__ASM_STDCALL_FUNC( NtCurrentTeb, 0, ".byte 0x64\n\tmovl 0x18,%eax\n\tret" ) +__ASM_STDCALL_FUNC( NtCurrentTeb, 0, "movl %fs:0x18,%eax\n\tret" )
/************************************************************************** @@ -683,20 +683,16 @@ __ASM_GLOBAL_FUNC(call_exception_handler, "subl $12,%esp\n\t" "pushl 12(%ebp)\n\t" /* make any exceptions in this... */ "pushl %edx\n\t" /* handler be handled by... */ - ".byte 0x64\n\t" - "pushl (0)\n\t" /* nested_handler (passed in edx). */ - ".byte 0x64\n\t" - "movl %esp,(0)\n\t" /* push the new exception frame onto the exception stack. */ + "pushl %fs:0\n\t" /* nested_handler (passed in edx). */ + "movl %esp,%fs:0\n\t" /* push the new exception frame onto the exception stack. */ "pushl 20(%ebp)\n\t" "pushl 16(%ebp)\n\t" "pushl 12(%ebp)\n\t" "pushl 8(%ebp)\n\t" "movl 24(%ebp), %ecx\n\t" /* (*1) */ "call *%ecx\n\t" /* call handler. (*2) */ - ".byte 0x64\n\t" - "movl (0), %esp\n\t" /* restore previous... (*3) */ - ".byte 0x64\n\t" - "popl (0)\n\t" /* exception frame. */ + "movl %fs:0, %esp\n\t" /* restore previous... (*3) */ + "popl %fs:0\n\t" /* exception frame. */ "movl %ebp, %esp\n\t" /* restore saved stack, in case it was corrupted */ "popl %ebp\n\t" __ASM_CFI(".cfi_def_cfa %esp,4\n\t") diff --git a/dlls/ntdll/unix/signal_x86_64.c b/dlls/ntdll/unix/signal_x86_64.c index 537e4e1f60e..caa85249896 100644 --- a/dlls/ntdll/unix/signal_x86_64.c +++ b/dlls/ntdll/unix/signal_x86_64.c @@ -2597,8 +2597,8 @@ void call_init_thunk( LPTHREAD_START_ROUTINE entry, void *arg, BOOL suspend, TEB #elif defined(__NetBSD__) sysarch( X86_64_SET_GSBASE, &teb ); #elif defined (__APPLE__) - __asm__ volatile (".byte 0x65\n\tmovq %0,%c1" :: "r" (teb->Tib.Self), "n" (FIELD_OFFSET(TEB, Tib.Self))); - __asm__ volatile (".byte 0x65\n\tmovq %0,%c1" :: "r" (teb->ThreadLocalStoragePointer), "n" (FIELD_OFFSET(TEB, ThreadLocalStoragePointer))); + __asm__ volatile ("movq %0,%%gs:%c1" :: "r" (teb->Tib.Self), "n" (FIELD_OFFSET(TEB, Tib.Self))); + __asm__ volatile ("movq %0,%%gs:%c1" :: "r" (teb->ThreadLocalStoragePointer), "n" (FIELD_OFFSET(TEB, ThreadLocalStoragePointer))); thread_data->pthread_teb = mac_thread_gsbase(); /* alloc_tls_slot() needs to poke a value to an address relative to each thread's gsbase. Have each thread record its gsbase pointer into its