FS#27560 - [wine] Wine needs -mstackrealign to prevent random ABI crashes

Attached to Project: Community Packages
Opened by John Schoenick (Nephyrin) - Tuesday, 13 December 2011, 22:00 GMT
Last edited by Sven-Hendrik Haase (Svenstaro) - Wednesday, 14 December 2011, 17:22 GMT
Task Type Bug Report
Category Packages: Multilib
Status Closed
Assigned To Florian Pritz (bluewind)
Sven-Hendrik Haase (Svenstaro)
Architecture All
Severity Medium
Priority Normal
Reported Version
Due in Version Undecided
Due Date Undecided
Percent Complete 100%
Votes 1
Private No

Details

The Short Version:
Most windows apps on x86 are compiled for 4byte stack alignment. Code generated by new versions of GCC assumes incoming stack is 16byte aligned. This can cause crashes in unrelated libraries when a wine app calls into a function that uses SSE instructions with an unaligned stack. The library assumes stack is aligned, executes a requires-alignment SSE function, boom.

The Long Version:
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=40838
http://bugs.winehq.org/show_bug.cgi?id=22316

Basically, GCC basically unilaterally decided the linux ABI was 16byte assumed alignment. The wine people assert that this is incorrect, and that linux is traditionally only 4-byte aligned. Ergo its up to the distro to resolve the problem.

New compiles coming out of arch's modern GCC are now assuming 16byte alignment. Because windows/wine apps will only enforce four byte alignment, random crashes will occur.
This was exacerbated by the recent change to gcc-multilib to use fpmath=sse, which is causing more packages to have SSE instructions that require the stack be aligned. For instance, StarCraft II will cease to run in wine on arch when the wine package is next compiled, due to stack alignment issues!

GCC's position:
The linux ABI should be 16byte, apps like wine that run 4byte aligned code should use -mstackrealign

Wine's position:
The linux ABI is 'de facto' 4byte, if some distros use GCC's default of 16byte (like Arch), its up to them to fix what breaks.

There are multiple ways to fix this:

A) Add -mpreferred-stack-boundary=2 to global CFLAGS, recompile all of arch. This will cause all arch libraries to only assume 4-byte stack alignment, so wine apps can't crash them, and make 4-byte alignment the standard ABI of arch. Yeah...

B) Add -mincoming-stack-boundary=2 to global CFLAGS, recompile all of arch. This would make all arch packages continue to use 16byte alignment, but only assuming incoming calls are 4byte aligned, thus re-aligning when a SSE or other aligned call is required. This makes all arch libraries 'compatible' with 4byte compiled code, while still using 16byte alignment as preferred. Also yuck.

C) Add -mstackrealign to the CFLAGS for just wine's 32bit compile. This will cause wine to realign all calls coming out of windows apps, so the calls are 16byte aligned when they hit any arch binaries. This fixes wine, and keeps arch as a de-facto 16byte aligned distro.

I vote for C.

To reproduce a problem right now:
Recompile wine with the newest gcc-multilib, try to run a directsound game (StarCraft II). This is a stack alignment crash.
Note that reverting the fpmath=sse from gcc-multilib fixes this, but that's only a workaround. There are certainly other more obscure crash bugs.

If you need more clarification ping me on freenode:nephyrin
This task depends upon

Closed by  Sven-Hendrik Haase (Svenstaro)
Wednesday, 14 December 2011, 17:22 GMT
Reason for closing:  Fixed
Additional comments about closing:  Fixed in svn.
Comment by Jason William Walton (jasonww) - Wednesday, 14 December 2011, 14:01 GMT
Wine should work around this in their build configuration without packagers having to deal with it. Comments on bugzilla are pretty clear to me.
Comment by Sverd Johnsen (sjohnsen) - Wednesday, 14 December 2011, 15:19 GMT
There always has been MMX/SSE/SSE2 code in wine since multilib toolchain defaults to -march=x86_64 even with -m32, which is a good thing.

I suppose --with-fpmath=sse just makes GCC use SSE more often (on 32bit) now , exposing the issue at last.

1) Use -march=i686 -mfpmath=387 for wine32. (This should work, maybe -mfpmath is redundant?)
2) Use -mstackrealign without changing anything and hope it doesn't kill performance/works correctly.
3) Use -mfpmath=387 and pray it continues to work.
4) Tell wine people to stop being ignorant and let them detect proper flags. They should know best.

I dont use multilib so I dont really care, just my two cents.
Comment by Sven-Hendrik Haase (Svenstaro) - Wednesday, 14 December 2011, 16:04 GMT
Can't reproduce with gcc-multilib 4.6.2-3 by recompiling wine 1.3.34. SC2 works wonderfully and I get sound.

EDIT: Sorry scratch that, I mixed up my build box host names. I can reproduce. Great bug report, by the way. :)
Comment by Jason William Walton (jasonww) - Wednesday, 14 December 2011, 17:14 GMT
Try -mstackrealign for wine on 32bit and be done with it.

I don't think the result is going to be too bad, but we'll see.
Comment by Sven-Hendrik Haase (Svenstaro) - Wednesday, 14 December 2011, 17:22 GMT
Fixed in svn.

Loading...