https://bugs.winehq.org/show_bug.cgi?id=47970
Zebediah Figura z.figura12@gmail.com changed:
What |Removed |Added ---------------------------------------------------------------------------- Version|unspecified |4.19
--- Comment #4 from Zebediah Figura z.figura12@gmail.com --- (In reply to David Torok from comment #3)
Regarding #1 - I'm not yet sure about the root cause, but I was receiving an i386 context in 64 bit mode. So the check is in place to allow a full i386 context when handling an x86_64 signal. I may need to track down the root cause, because this may or may not be desirable for wine. I have not checked how windows handles this.
Mmh. That seems odd, and I'm not sure how we're supposed to distinguish the two. Is the game calling NtContinue() from 32-bit code? Or maybe there's a difference in flags? I'd also like to see what the %cs and %rip values of the new context are (e.g. is it trying to ljmp into a 32-bit segment?)
Regarding #2 - I have an alternative version of this patch, which clones the syscall argument's from the parent frame, like wine currently does for 32 bit. That fix originally came from Andrew Wesie - and he mentioned that approach could cause a segmentation fault if the arguments are sufficiently close to the end of the stack memory allocation. So I figured, I might try an approach that does not involve growing the stack further. I guess it is best I explain the intent with the dispatcher version I posted: The initial sub instruction changes the thunk's return address to point into the first return of the thunk, this is crucial, and needed by the software to function. Then the thunk's return and the thunk's caller's return are saved into unused space in the TEB and later restored. That is how this version solves the problem of the syscall arguments having to be a specific distance away on the stack. (aka, only having space for one return address) You may recognize, I also left the original code path, in case the TEB was not available for some reason. I'm not sure if this could happen at all.
Ah, yes, so now that I've been able to give a cursory examination, what you're doing unfortunately won't work. Nt*() calls can be reëntrant on Wine (I know, this isn't correct, but fixing it is a lot harder), so we have to use the stack. Fortunately I think this is a lot easier on x86_64, since it's always caller-cleanup.
I've taken the liberty of trying to implement this part myself:
https://github.com/wine-staging/wine-staging/commit/5fbf201ea8b61b09540905a9...
Can you please give it a try (after applying your patches 0001 and 0003) and see if it still works?
Regarding #3 - 64 bit linux signal contexts do not have DS: https://github.com/torvalds/linux/blob/ 6f0d349d922ba44e4348a17a78ea51b7135965b1/arch/x86/include/uapi/asm/ sigcontext.h#L257 Hence Wine cannot and will not capture DS and therefore DS_sig() does not exist for x86_64. My understanding is that DS and SS should always be the same on Windows, hence the manual set in the context structure.
I did a quick test. On my machine, it is true that the values for the segment selectors differ—e.g. I get nonzero values for %cs and %ss, but zero for the other four. But the values are the same outside of the exception handler and inside of it. Is the program depending on %ds having a nonzero value inside of the exception handler?