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 "native_internal.h"
|
||||||
#include "tty_uart.h"
|
#include "tty_uart.h"
|
||||||
|
|
||||||
|
#define ENABLE_DEBUG (0)
|
||||||
|
#include "debug.h"
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
_STDIOTYPE_STDIO = 0, /**< leave intact */
|
_STDIOTYPE_STDIO = 0, /**< leave intact */
|
||||||
_STDIOTYPE_NULL, /**< redirect to "/dev/null" */
|
_STDIOTYPE_NULL, /**< redirect to "/dev/null" */
|
||||||
@ -250,7 +253,22 @@ void usage_exit(int status)
|
|||||||
real_exit(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();
|
_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_null_out_file = _native_log_output(stdouttype, STDOUT_FILENO);
|
||||||
_native_input(stdintype);
|
_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_cpu_init();
|
||||||
native_interrupt_init();
|
native_interrupt_init();
|
||||||
#ifdef MODULE_NETDEV_TAP
|
#ifdef MODULE_NETDEV_TAP
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user