native: Finish iterating constructor calls before moving on to native_cpu_init
This commit is contained in:
parent
1162f2beff
commit
ad01950b97
@ -43,6 +43,9 @@
|
||||
#include "native_internal.h"
|
||||
#include "tty_uart.h"
|
||||
|
||||
#define ENABLE_DEBUG (0)
|
||||
#include "debug.h"
|
||||
|
||||
typedef enum {
|
||||
_STDIOTYPE_STDIO = 0, /**< leave intact */
|
||||
_STDIOTYPE_NULL, /**< redirect to "/dev/null" */
|
||||
@ -250,7 +253,22 @@ void usage_exit(int status)
|
||||
real_exit(status);
|
||||
}
|
||||
|
||||
__attribute__((constructor)) static void startup(int argc, char **argv)
|
||||
/** @brief Initialization function pointer type */
|
||||
typedef void (*init_func_t)(int argc, char **argv, char **envp);
|
||||
#ifdef __APPLE__
|
||||
/* Taken from the sources of Apple's dyld launcher
|
||||
* https://github.com/opensource-apple/dyld/blob/3f928f32597888c5eac6003b9199d972d49857b5/src/dyldInitialization.cpp#L85-L104
|
||||
*/
|
||||
/* Find the extents of the __DATA __mod_init_func section */
|
||||
extern init_func_t __init_array_start __asm("section$start$__DATA$__mod_init_func");
|
||||
extern init_func_t __init_array_end __asm("section$end$__DATA$__mod_init_func");
|
||||
#else
|
||||
/* Linker script provides pointers to the beginning and end of the init array */
|
||||
extern init_func_t __init_array_start;
|
||||
extern init_func_t __init_array_end;
|
||||
#endif
|
||||
|
||||
__attribute__((constructor)) static void startup(int argc, char **argv, char **envp)
|
||||
{
|
||||
_native_init_syscalls();
|
||||
|
||||
@ -341,6 +359,39 @@ __attribute__((constructor)) static void startup(int argc, char **argv)
|
||||
_native_null_out_file = _native_log_output(stdouttype, STDOUT_FILENO);
|
||||
_native_input(stdintype);
|
||||
|
||||
/* startup is a constructor which is being called from the init_array during
|
||||
* C runtime initialization, this is normally used for code which must run
|
||||
* before launching main(), such as C++ global object constructors etc.
|
||||
* However, this function (startup) misbehaves a bit when we call
|
||||
* kernel_init below, which does not return until there is an abort or a
|
||||
* power off command.
|
||||
* We need all C++ global constructors and other initializers to run before
|
||||
* we enter the normal application code, which may depend on global objects
|
||||
* having been initalized properly. Therefore, we iterate through the
|
||||
* remainder of the init_array and call any constructors which have been
|
||||
* placed after startup in the initialization order.
|
||||
*/
|
||||
init_func_t *init_array_ptr = &__init_array_start;
|
||||
DEBUG("__init_array_start: %p\n", (void *)init_array_ptr);
|
||||
while (init_array_ptr != &__init_array_end) {
|
||||
/* Skip everything which has already been run */
|
||||
if ((*init_array_ptr) == startup) {
|
||||
/* Found ourselves, move on to calling the rest of the constructors */
|
||||
DEBUG("%18p - myself\n", (void *)init_array_ptr);
|
||||
++init_array_ptr;
|
||||
break;
|
||||
}
|
||||
DEBUG("%18p - skip\n", (void *)init_array_ptr);
|
||||
++init_array_ptr;
|
||||
}
|
||||
while (init_array_ptr != &__init_array_end) {
|
||||
/* call all remaining constructors */
|
||||
DEBUG("%18p - call\n", (void *)init_array_ptr);
|
||||
(*init_array_ptr)(argc, argv, envp);
|
||||
++init_array_ptr;
|
||||
}
|
||||
DEBUG("done, __init_array_end: %p\n", (void *)init_array_ptr);
|
||||
|
||||
native_cpu_init();
|
||||
native_interrupt_init();
|
||||
#ifdef MODULE_NETDEV_TAP
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user