-
Notifications
You must be signed in to change notification settings - Fork 289
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
BUG: Libco defect in many libretro-cores causes crashes in Windows x64 #1643
Comments
well damn, thanks for the excellent bug report! |
Couple of things I neglected to mention are as follows:
|
Does this only affect windows and not linux? |
Linux uses the System V ABI which doesn't require callee-saving the XMM6-XMM15 registers so it shouldn't be affected by this issue specifically. I reviewed the libco call-site code for both Windows 64-bit and System V 64-bit and didn't see any issues outside of this particular XMM issue. All other callee-save registers appear to be properly saved and restored in both the inline assembly and inline machine code for both ABIs. For reference to the calling conventions, see Table 4 here. |
Many of the libretro cores contain a defect in
libco
that causes floating point register corruption under x86_64 Windows due to incorrect handwritten 'machine code' found here for example.Specifically, the issue is that the restore code uses the wrong opcode for MOVAPS when attempting to restore callee-saved registers. The bug appears to originate in the earliest incarnations of libco. It seems to have been fixed some years ago in some of the libretro repositories when an update was pulled from the mainline libco repository (e.g. here). Many of the repositories hold a broken copy though, and it does result in real-world crashes and/or broken behavior.
More specifically, lines 62 through 71 use opcode 0x29 instead of 0x28. Semantically, the difference is as follows:
The former is for storing a memory value into a register, and the latter is for storing register contents into a memory location.
The earliest incarnations of the code were uncommented and written in an era when 64-bit processors were rare, so it isn't surprising it wasn't fixed in mainline for almost a decade. Interestingly, eventually the incorrect code was commented with the actual assembly it represents and even it shows the operations are incorrect (in the libretro copies). The original author of those comments probably didn't realize the implications at the time.
This issue was found while investigating a crash bug in scummvm.
I've determined that the following scummvm games are affected by this issue and either crash or have severe display issues as result of the fault:
The following scummvm games are most likely affected by this issue but I am unable to confirm:
Here is a list of related open issue reports that have a high probability of having been caused by this bug:
The following is a list of ALL cores that currently contain the faulty code in the main branch. I am unable to determine if this causes fault behavior (in practice) on any of the cores outside of scummvm:
- 3dengine- boom3- bsnes2014- bsnes-cplusplus98- bsnes-mercury- desmume- desmume2015- dosbox- fbalpha- flycast- mame2000- mame2016- beetle-bsnes- melonds- parallel-n64- reminiscence- scummvmThe following is a list of additional subrepositories within the libretro organization that currently contain the faulty code in the main branch:
- opentyrian test
- sdl-tetris test
The following is a list of 3rd party libretro repos that currently contain the faulty code in the main branch:
The text was updated successfully, but these errors were encountered: