[llvm-dev] Automatically backing up and restoring x18 around function calls on AArch64?
Martin Storsjö via llvm-dev
llvm-dev at lists.llvm.org
Fri Apr 26 05:30:26 PDT 2019
Hi,
When using Wine to run Windows ARM64 executables on Linux, there's one
major ABI incompatibility between the two; Windows treats the x18
register as the reserved platform register, while it is free to be
clobbered anywhere in code on Linux.
The Wine code sets up this register before passing control over to the
Windows executable code, but whenever the Windows code calls a function
implemented in Wine, this register ends up clobbered.
The initial solution is to compile Wine itself with the -ffixed-x18 flag,
to treat the x18 register as reserved within Wine, so that no compiler
generated code touches it. This works fine as long as Wine makes no calls
to other libraries from the outside Linux distribution - but e.g. as soon
as any glibc function is called, it can end up clobbered again.
The full, proper solution would of course to be rebuilding one's Linux
distribution from scratch with -ffixed-x18 on every single library. But
this is of course pretty much impractical.
My current makeshift workaround for the matter is to reroute calls from
native Windows code to Wine functions via a relay wrapper, which backs up
and restores the register. This works in practice, but hasn't been
accepted upstream, as it is not deemed a correct/complete solution. Also,
if the emulated Windows API functions do callbacks, the register would
need to be restored before the callbacks call windows code.
Another idea which was raised in
https://bugs.winehq.org/show_bug.cgi?id=38780#c13, which disucsses this
matter, was if it would be possible to make Clang/LLVM always back up and
restore x18 on any call to any other function, to make sure that the
register maintains the right value as long as running in Wine code. (One
concern is that this could end up rather expensive though.)
I didn't really find any straighforward way of starting to implement this
however. Does anyone here happen to have ideas about how one could either
implement this, or solve it in another way?
// Martin
More information about the llvm-dev
mailing list