Fix init / libc_init ordering

_init might require working pthreads, due to C++ constructors using
mutexes and threads. Since libc does not require _init execution, we
simply reorder them.

This removes support for kernel-mode _init on user programs that run in
kernel mode (mostly old FW 1.5, but should not affect almost any
homebrew out there, since they don't use user-mode main thread).
This commit is contained in:
David Guillen Fandos
2023-06-28 23:11:56 +02:00
parent 710deac140
commit 4b2982cb7d
2 changed files with 8 additions and 12 deletions

View File

@@ -75,6 +75,9 @@ void _main(SceSize args, void *argp)
/* Call libc initialization hook */ /* Call libc initialization hook */
__libcglue_init(argc, argv); __libcglue_init(argc, argv);
/* Init can contain C++ constructors that require working threading */
_init();
/* Make sure _fini() is called when the program ends. */ /* Make sure _fini() is called when the program ends. */
atexit((void *) _fini); atexit((void *) _fini);
@@ -96,21 +99,13 @@ void _main(SceSize args, void *argp)
int _start(SceSize args, void *argp) int _start(SceSize args, void *argp)
{ {
void (*_main_func)(SceSize args, void *argp) = _main; void (*_main_func)(SceSize args, void *argp) = _main;
void (*_init_func)(void) = _init;
if ((&module_info != NULL) && (module_info.modattribute & 0x1000)) { if ((&module_info != NULL) && (module_info.modattribute & PSP_MODULE_KERNEL)) {
/* If we're running in kernel mode, the addresses of our _main() thread /* If we're running in kernel mode, the addresses of our _main() thread
and _init() function must also reside in kernel mode. */ must also reside in kernel mode. */
_main_func = (void *) ((u32) _main_func | 0x80000000); _main_func = (void *) ((u32) _main_func | 0x80000000);
_init_func = (void *) ((u32) _init_func | 0x80000000);
} }
/* Call _init() here, because an app may have code that needs to run in
kernel mode, but want their main() thread to run in user mode. If they
define "constructors" they can do any kernel mode initialization here
before their app is switched. */
_init_func();
if (&sce_newlib_nocreate_thread_in_start != NULL) { if (&sce_newlib_nocreate_thread_in_start != NULL) {
/* The program does not want main() to be run in a seperate thread. */ /* The program does not want main() to be run in a seperate thread. */
_main_func(args, argp); _main_func(args, argp);

View File

@@ -58,8 +58,6 @@ void _main(SceSize args, void *argp)
int loc = 0; int loc = 0;
char *ptr = argp; char *ptr = argp;
_init();
/* Turn our thread arguments into main()'s argc and argv[]. */ /* Turn our thread arguments into main()'s argc and argv[]. */
while(loc < args) while(loc < args)
{ {
@@ -77,6 +75,9 @@ void _main(SceSize args, void *argp)
/* Call libc initialization hook */ /* Call libc initialization hook */
__libcglue_init(argc, argv); __libcglue_init(argc, argv);
/* Init can contain C++ constructors that require working threading */
_init();
/* Make sure _fini() is called when the program ends. */ /* Make sure _fini() is called when the program ends. */
atexit((void *) _fini); atexit((void *) _fini);