The way the init code in start_serial uses the EFP_PROG_EXIT vector to handle program exit is flawed in two ways:
The original handler is stored in a program variable
The code relies on kmain returning to restore the original handler
This is generally "fine" but breaks when user code does "weird things" like chaining to another user program (as is the case with sdfat_menu). In this case, the program variable is likely to be overwritten, and the original handler is likely to never be restored, leaving it as a dangling pointer to code that no longer exists when chained code (or anything run following warm boot) calls it.
Briefly:
The way the init code in
start_serial
uses theEFP_PROG_EXIT
vector to handle program exit is flawed in two ways:kmain
returning to restore the original handlerThis is generally "fine" but breaks when user code does "weird things" like chaining to another user program (as is the case with
sdfat_menu
). In this case, the program variable is likely to be overwritten, and the original handler is likely to never be restored, leaving it as a dangling pointer to code that no longer exists when chained code (or anything run following warm boot) calls it.Since user programs (like
sdfat_menu
) should be able to do this, this should be fixed in the libs. The obvious (and perhaps wrong) way to do this would be to makeexit
,atexit
handlers and the init code itself work like it does in the new(lib) startup code: https://github.com/rosco-m68k/newlib-4.4.0.20231231/blob/062620702eccd78b1f19ea7f6d4a05bdbbfb0f14/libgloss/rosco/crt0.asm#L69For full context, see this thread: https://discord.com/channels/698525682199822367/711035186170822727/1226460649673064449