@@ -322,37 +322,52 @@ ___libload_libs_ret:
322322 call _main
323323#endif
324324 . equ __start._main , $ - 3
325+
326+ ;-------------------------------------------------------------------------------
327+ ; call atexit/on_exit and fini functions
328+ ;-------------------------------------------------------------------------------
329+
325330 . global ___exithl
326331 .type ___exithl , @function
327332___exithl:
328- #if HAS_ATEXIT || HAS_FINI_ARRAY || HAS_ABORT
329- push hl
330- push de
333+
334+ #if HAS_ATEXIT || HAS_FINI_ARRAY
335+ push hl ; preserve exit status
331336#endif
337+ #if HAS_EXIT
338+ ; jr .L.exit_function_start
339+ db 0x3E ; ld a, *
332340 . global _exit
333341 .type _exit , @function
334342_exit:
343+ ; exit status is currently at (sp + 3), so we need to fix that
344+ pop bc ; destroy return address
345+ #endif
335346#if HAS_ATEXIT
347+ ; input: (sp + 0) = exit status
336348 jr .L.exit_function_start
337349.L.exit_function_loop:
338350 ld hl , (ix + 1 + 0 * 3 )
339351 ld (__atexit_functions) , hl
340- pop hl
341- ld de , (ix + 1 + 2 * 3 )
342- push hl
343- push de
344- push hl
345- ld hl , (ix + 1 + 1 * 3 )
346- push hl
352+ pop hl ; exit status
353+ push hl ; exit status
354+ ld de , (ix + 1 + 2 * 3 ) ; arg
355+ push de ; arg
356+ push hl ; exit status
357+ ld hl , (ix + 1 + 1 * 3 ) ; func
358+ push hl ; func
347359 pea ix + 1
348360 call _free
349- pop bc
350- pop hl
361+ pop bc ; reset SP
362+ pop hl ; func
363+ ; atexit : void (*func)(void)
364+ ; on_exit : void (*func)(int status, void *arg)
351365 call __indcallhl
352- pop bc
353- pop bc
366+ pop bc ; reset SP
367+ pop bc ; reset SP
354368.L.exit_function_start:
355369 ld ix , (__atexit_functions)
370+ ; NULL indicates no more atexit functions
356371 ld bc , - 1
357372 add ix , bc
358373 jr c , .L.exit_function_loop
@@ -378,10 +393,27 @@ _exit:
378393 . extern __fini_array_start
379394 . extern __fini_array_end
380395#endif
381- #if HAS_ATEXIT || HAS_FINI_ARRAY || HAS_ABORT
382- pop de
383- pop hl
396+
397+ #if HAS_C99__EXIT
398+ ; jr .L.skip.__Exit
399+ db 0x3E ; ld a, *
400+ . global __Exit
401+ .type __Exit , @function
402+ __Exit:
403+ ; exit status is currently at (sp + 3), so we need to fix that
404+ pop bc ; destroy return address
405+ .L.skip.__Exit:
406+ #endif
407+
408+ #if HAS_ATEXIT || HAS_FINI_ARRAY || HAS_EXIT || HAS_C99__EXIT
409+ pop hl ; restore exit status
384410#endif
411+
412+ ;-------------------------------------------------------------------------------
413+ ; We have now called all atexit/on_exit and fini functions
414+ ; HL = exit status
415+ ;-------------------------------------------------------------------------------
416+
385417#if HAS_ABORT
386418 jr .L.skip._abort
387419 . global _abort
0 commit comments