Skip to content
Snippets Groups Projects
Commit ad01950b authored by Joakim Nohlgård's avatar Joakim Nohlgård
Browse files

native: Finish iterating constructor calls before moving on to native_cpu_init

parent 1162f2be
No related branches found
No related tags found
No related merge requests found
...@@ -43,6 +43,9 @@ ...@@ -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) ...@@ -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) ...@@ -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
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment