https://bugs.winehq.org/show_bug.cgi?id=47633
--- Comment #4 from Paul Gofman gofmanp@gmail.com --- Looks like a compiler problem. Below is the code of SetThreadStackGuarantee() function. It gets stack pointer misplaced upon return from its main execution path (see code snippet below). I've got the same problem with the other application, application crashes after the call to SetThreadStackGuarantee() stub (from native .Net). I get it with i686-w64-mingw32-gcc 8.3.0.
The problem is not there if DECLSPEC_HOTPATCH is removed. In this case stack frame is not generated.
-------------------------- 71279480 _SetThreadStackGuarantee@4: 71279480: 8b ff mov %edi,%edi
71279482: 55 push %ebp 71279483: 8b ec mov %esp,%ebp
71279485: a1 88 72 29 71 mov 0x71297288,%eax 7127948a: 8d 50 01 lea 0x1(%eax),%edx 7127948d: 89 15 88 72 29 71 mov %edx,0x71297288 71279493: 85 c0 test %eax,%eax 71279495: 75 09 jne 712794a0 <_SetThreadStackGuarantee@4+0x20> 71279497: f6 05 34 f1 27 71 01 testb $0x1,0x7127f134 7127949e: 75 10 jne 712794b0 <_SetThreadStackGuarantee@4+0x30> 712794a0: b8 01 00 00 00 mov $0x1,%eax
; 'leave' or similar is missing here, stack pointer is 4 bytes misplaced upon return. 712794a5: c2 04 00 ret $0x4
712794a8: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi 712794af: 90 nop 712794b0: 83 ec 28 sub $0x28,%esp 712794b3: 8b 45 08 mov 0x8(%ebp),%eax 712794b6: c7 44 24 0c 02 72 28 movl $0x71287202,0xc(%esp) 712794bd: 71 712794be: 89 44 24 10 mov %eax,0x10(%esp) 712794c2: c7 44 24 08 3c 72 28 movl $0x7128723c,0x8(%esp) 712794c9: 71 712794ca: c7 44 24 04 34 f1 27 movl $0x7127f134,0x4(%esp) 712794d1: 71 712794d2: c7 04 24 00 00 00 00 movl $0x0,(%esp) 712794d9: e8 62 f1 ff ff call 71278640 <_wine_dbg_log.constprop.0> 712794de: b8 01 00 00 00 mov $0x1,%eax
; stack pointer is correct on this path 712794e3: c9 leave 712794e4: c2 04 00 ret $0x4 --------------------
I also tested and could reproduce the compilation problem with the following small test program with gcc 9.1.1 (compile with 'gcc -m32 -O2 -g') and i686-w64-mingw32-gcc 8.3.0 (compile with '-O2 -g').
------------------ #include <stdio.h>
unsigned int __attribute__ ((noinline)) __attribute__((__stdcall__)) __attribute__((__ms_hook_prologue__)) test_func( unsigned long *size ) { static int once;
if (once++ == 0) printf("(%p): stub\n", size); return 1; }
int main(int argc, char **argv) { printf("%#x.\n", test_func(NULL)); printf("%#x.\n", test_func(NULL)); } -------------------- ------------------