Open squalldc opened 3 years ago
Can you post the source code of your project? Member function pointers have no special relocation treatment.
At the moment, the source isn't ready for release yet (it's quite large and all over the place) unfortunately.
I've uploaded the test source code. Not sure if this results in the exact same issue (seems similar) but I've trimmed out a lot of the code so you can just build it like the other 3ds samples:
https://anonfiles.com/XfE6Xfnbu2/3ds_bug_7z
Basically, main.c just calls this one function now:
void BugTest(bool set) {
CNF_PARAMS current = ConfigureParams;
ConfigureParams.System.bFastForward = (set != 0);
if (ConfigureParams.System.bFastForward) {
ConfigureParams.Screen.nFrameSkips = 5;
} else {
ConfigureParams.Screen.nFrameSkips = 0;
}
Change_CopyChangedParamsToConfiguration(¤t, &ConfigureParams, false);
This will build the elf and 3dsx with no errors. But:
If you comment out the last line, then there's no problem and everything loads and runs fine
// Change_CopyChangedParamsToConfiguration(¤t, &ConfigureParams, false);
This is another strange behaviour. If you keep the call to that function, but delete all code inside that function (ie, if you modify change.c so it looks like this)
void Change_CopyChangedParamsToConfiguration(CNF_PARAMS *current, CNF_PARAMS *changed, bool bForceReset)
{
}
It will load but crash at runtime even though the code does nothing.
Forgot to mention that the CIA seems to work fine with no issues:
We've identified the cause of this issue after some testing. Unfortunately, it involves broken assumptions made by some of the infrastructure that is used to support hax 2.x; specifically the problem arises with certain (legal) code optimizations GCC generates (if you're curious, the problematic code is in IoMem_VoidRead
). The mere presence of this code in the binary is enough to produce an invalid 3DSX executable that fails to load (it doesn't even get to the point where it finishes loading). Fixing this will require us to consider dropping support for hax 2.x as a supported homebrew environment, leaving Luma3DS' Rosalina as the only remaining supported entrypoint. No decision has been taken yet, though.
With that said, we've also spotted some problematic practices in your source code tree. I'm not sure if they apply to your actual project or just the test case you posted, but generally it's not a good idea to replace an existing project's buildsystem with something else, it's best to make the existing buildsystem work directly. It's also not a good idea to drop a random version of a library into a project (especially when it's something complex like SDL). We happen to supply a 3ds-sdl package through devkitPro pacman, although it's SDL 1.x based. Also, I can't exactly tell which version you attempted to get working, supposedly Hatari requires SDL2 now, which is definitely not available for 3DS (at least for now). Either way, we can be reached for further advice and guidance.
Thanks for looking into this.
Yeah the test code was just put together quickly to try to get a smaller reproduction of the crash. The actual project doesn't use the same buildsystem or sdl library in the test case.
Just curious, does the issue arise when function pointers are stored in static arrays and comparing those values to function addresses at runtime?
sdl library in the test case.
Which SDL library are you using then?
Just curious, does the issue arise when function pointers are stored in static arrays and comparing those values to function addresses at runtime?
It has to do with an optimization GCC does when accessing an array with an index that is offsetted by a constant. GCC saves one instruction by adding the offset (which in this case is negative) directly to the pointer that is stored as a spill immediate in the code. This later doesn't play nice with 3DSX's relocation processing, since it ends up highly out of bounds.
Thanks for the explanation, it makes a lot of sense now.
Hatari currently still supports SDL 1.x, but this will be deprecated soon at which time I'll need to switch to SDL 2. I was using Vice3DS's SDL library (although I found their mutex code still has some bugs). I did notice devkitPro has it's own version when I upgraded the toolchain while looking into this crash issue, so I'll be switching over to your version of SDL 1.x.
For what's worth, we rewrote the synchronization primitive code (and fixed a couple of other related bugs). While SDL on 3DS is still not exactly ideal, it should hopefully be a bit more stable now.
Hi,
I get a crash when running the generated 3dsx file on a real 3ds as well as in Citra. I'm not sure if it's something I'm doing or some limitation in the 3dsx format.
It seems to be relocation related as it crashes at runtime when trying to get the address of a c++ member function pointer.
I've uploaded the just the test elf here (let me know if you need the smdh and romfs folder as well): https://anonfiles.com/ycnfj2ndu8/test_7z
Is there anything I can do to help look into this? Thanks,