diff options
| author | Felix Morgner <felix.morgner@ost.ch> | 2025-07-24 12:28:23 +0000 |
|---|---|---|
| committer | Felix Morgner <felix.morgner@ost.ch> | 2025-07-24 12:28:23 +0000 |
| commit | f62b05c93c6c539d899d2656c0638d404a036f1a (patch) | |
| tree | 971236e6732e0341f96f16d3e200270a68f22397 /arch/x86_64/src/boot/initialize_runtime.cpp | |
| parent | 2ebf8d525e6a030efc8ca23bcbdf92c2d0cb8985 (diff) | |
| download | teachos-f62b05c93c6c539d899d2656c0638d404a036f1a.tar.xz teachos-f62b05c93c6c539d899d2656c0638d404a036f1a.zip | |
x86_64: implement robust C++ global initialization
Implement a comprehensive mechanism to ensure correct C++ runtime
initialization before the kernel main function is called. This replaces
the previous, incomplete reliance on an `_init` function.
The new design robustly handles both legacy `.ctors` and modern
`.init_array` initialization schemes used by the GNU toolchain. A single
C++ function, `invoke_global_constructors`, now iterates through both
arrays of function pointers to ensure all types of global initializers
are executed.
Diffstat (limited to 'arch/x86_64/src/boot/initialize_runtime.cpp')
| -rw-r--r-- | arch/x86_64/src/boot/initialize_runtime.cpp | 24 |
1 files changed, 24 insertions, 0 deletions
diff --git a/arch/x86_64/src/boot/initialize_runtime.cpp b/arch/x86_64/src/boot/initialize_runtime.cpp new file mode 100644 index 0000000..9a3df0e --- /dev/null +++ b/arch/x86_64/src/boot/initialize_runtime.cpp @@ -0,0 +1,24 @@ +#include <algorithm> +#include <functional> +#include <span> + +extern "C" +{ + using global_initializer = auto (*)() -> void; + + extern global_initializer __ctors_start; + extern global_initializer __ctors_end; + extern global_initializer __init_array_start; + extern global_initializer __init_array_end; + + auto invoke_global_constructors() -> void + { + auto constructors = std::span{&__ctors_start, &__ctors_end}; + auto initializers = std::span{&__init_array_start, &__init_array_end}; + + auto apply_invoke = [](auto invokable) { return std::invoke(invokable); }; + + std::ranges::for_each(constructors, apply_invoke); + std::ranges::for_each(initializers, apply_invoke); + } +} |
