On Feb 20, 2014, at 2:44 PM, Stefan Dösinger wrote:
Am 2014-02-20 17:20, schrieb Ken Thomases:
Besides running under an emulator, it may be possible to wrap every call out to system libraries with code to save and restore the register. Or, if you prefer to think of it this way, the wrapper would be on exit from and entry back into native Windows binary code. This would be somewhat similar to what we do with stack alignment, although we have compiler help for that. Either way, that would probably impose a significant performance penalty.
Sounds much more pleasant than an emulator. But doesn't the problem also affect multitasking context switches?
It's conceivable, but I don't know if it actually happens.
I have some llvm work (__ms_hook_prologue__) on my todo list anyway. Maybe it's an idea to add a compiler feature to take care of this.
This will actually be more complicated than stack alignment (__force_align_arg_pointer__) and the hook prologue. With stack alignment, Windows code is not allergic to 16-byte-aligned stack, it just fails to maintain it. So, it's sufficient for us to force 16-byte alignment when Windows code calls into Wine code. When Wine code calls out to Windows code, there's nothing we need to do. So, putting the attribute in the WINAPI declspec works.
With this register issue, there are two approaches:
1) Wrap all calls out to system libraries. Save the register, restore what the OS X ABI expects/requires, call the system API, restore the original value of the register.
2) Conceptually wrap the Windows code. This has a component similar to stack alignment and the hook prologue, but also has to affect all places that call out to Windows code. Where Windows code calls Wine code, we'd save the Windows value of the register and restore the OS X ABI value. When the Wine code returns, it would restore the Windows value. But also, wherever Wine calls out to Windows code, it will have to save the OS X ABI value, restore the Windows value, do the call-out, then restore the OS X ABI value.
With either approach, the problem is that there's work that needs to happen at call sites, not just entry points to WINAPI functions. I don't know how to identify such call sites. They're ubiquitous but anonymous. Perhaps the CALLBACK declspec would help for approach 2, but I doubt it will be thorough enough.
I suppose the third approach would be to just compile all Wine code such that it does this dance at every call site. Yikes!
-Ken