https://bugs.winehq.org/show_bug.cgi?id=49436
--- Comment #12 from Paul Gofman pgofman@codeweavers.com --- (In reply to Maciej Stanczew from comment #10)
What I found from the logs is that there are repeated (recursive?) calls to KiUserExceptionDispatcher just before the stack overflow exception. New exceptions are generated on dereferencing of 'rec' and/or 'context' variables. But I don't really understand how this hotpatching works, so I don't know if those logs make any sense at all.
Thank you very much for your analysis, I was about to skip the core problem here. The fact is, the exception after (unsuccessful) ntdll.dll loading from disk happens regardless of -launch parameter (sooner or later), but the application handler is willing to catch the exception and continue regardless.
The problem is that KiUserExceptionDispatcher has a different ABI (call parameters) on x64 from how it is currently implemented in Wine. So if the exception is properly processed the game launches, with or without -launch option (provided the regression from 537bb7a8aee278d285cb77669fd9258dfaa3222f is bypassed).
The ABI difference comes into play only when KiUserExceptionDispatcher is found and hotpatched by the program, that's why the hack which renames the implementation helps. The context and exception record are just copied to the stack, the function seem to have no explicit pointers to those. Also there is no return address on the stack (the latter requires special care to make sure stack unwinding from the called handlers still works, the game depends on that).
I've got a very draft implementation for x64 KiUserExceptionDispatcher which allows the game to work without the hacks. I will send it after bringing it to some sensible form.