diff options
author | Ian Moffett <ian@osmora.org> | 2024-03-07 17:28:00 -0500 |
---|---|---|
committer | Ian Moffett <ian@osmora.org> | 2024-03-07 17:28:32 -0500 |
commit | bd5969fc876a10b18613302db7087ef3c40f18e1 (patch) | |
tree | 7c2b8619afe902abf99570df2873fbdf40a4d1a1 /lib/mlibc/options/elf/generic/startup.cpp | |
parent | a95b38b1b92b172e6cc4e8e56a88a30cc65907b0 (diff) |
lib: Add mlibc
Signed-off-by: Ian Moffett <ian@osmora.org>
Diffstat (limited to 'lib/mlibc/options/elf/generic/startup.cpp')
-rw-r--r-- | lib/mlibc/options/elf/generic/startup.cpp | 73 |
1 files changed, 73 insertions, 0 deletions
diff --git a/lib/mlibc/options/elf/generic/startup.cpp b/lib/mlibc/options/elf/generic/startup.cpp new file mode 100644 index 0000000..d53881b --- /dev/null +++ b/lib/mlibc/options/elf/generic/startup.cpp @@ -0,0 +1,73 @@ + +#include <errno.h> +#include <string.h> +#include <stdint.h> +#include <stdlib.h> +#include <bits/ensure.h> +#include <mlibc/elf/startup.h> +#include <mlibc/environment.hpp> + +extern "C" size_t __init_array_start[]; +extern "C" size_t __init_array_end[]; +extern "C" size_t __preinit_array_start[]; +extern "C" size_t __preinit_array_end[]; + +static int constructors_ran_already = 0; + +struct global_constructor_guard { + global_constructor_guard() { + constructors_ran_already = 1; + } +}; + +static global_constructor_guard g; + +void __mlibc_run_constructors() { +/* + if (!constructors_ran_already) { + size_t constructor_count = (size_t)__init_array_end - (size_t)__init_array_start; + constructor_count /= sizeof(void*); + for (size_t i = 0; i < constructor_count; i++) { + void (*ptr)(void) = (void(*)(void))(__init_array_start[i]); + ptr(); + } + } +*/ +} + +namespace mlibc { + +void parse_exec_stack(void *opaque_sp, exec_stack_data *data) { + auto sp = reinterpret_cast<uintptr_t *>(opaque_sp); + data->argc = *sp++; + data->argv = reinterpret_cast<char **>(sp); + sp += data->argc; // Skip all arguments. + __ensure(!*sp); // Skip the terminating null element. + sp++; + data->envp = reinterpret_cast<char **>(sp); +} + +// TODO: This does not have to be here; we could also move it to options/internal. +void set_startup_data(int argc, char **argv, char **envp) { + if(argc) { + program_invocation_name = argv[0]; + + if(auto slash = strrchr(argv[0], '/'); slash) { + program_invocation_short_name = slash + 1; + }else{ + program_invocation_short_name = argv[0]; + } + } + + // Initialize environ. + // TODO: Copy the arguments instead of pointing to them? + auto ev = envp; + while(*ev) { + auto fail = mlibc::putenv(*ev); + __ensure(!fail); + ev++; + } +} + +} // namespace mlibc + |