diff options
Diffstat (limited to 'libc/startup')
-rw-r--r-- | libc/startup/gpu/amdgpu/start.cpp | 13 | ||||
-rw-r--r-- | libc/startup/gpu/nvptx/start.cpp | 13 | ||||
-rw-r--r-- | libc/startup/linux/CMakeLists.txt | 1 | ||||
-rw-r--r-- | libc/startup/linux/aarch64/tls.cpp | 2 | ||||
-rw-r--r-- | libc/startup/linux/do_start.cpp | 15 | ||||
-rw-r--r-- | libc/startup/linux/riscv/tls.cpp | 2 | ||||
-rw-r--r-- | libc/startup/linux/x86_64/tls.cpp | 2 |
7 files changed, 29 insertions, 19 deletions
diff --git a/libc/startup/gpu/amdgpu/start.cpp b/libc/startup/gpu/amdgpu/start.cpp index 8bd0c3a..48f095d 100644 --- a/libc/startup/gpu/amdgpu/start.cpp +++ b/libc/startup/gpu/amdgpu/start.cpp @@ -14,12 +14,16 @@ #include "src/stdlib/exit.h" extern "C" int main(int argc, char **argv, char **envp); +extern "C" void __cxa_finalize(void *dso); namespace LIBC_NAMESPACE_DECL { // FIXME: Factor this out into common logic so we don't need to stub it here. void teardown_main_tls() {} +// FIXME: Touch this symbol to force this to be linked in statically. +volatile void *dummy = &LIBC_NAMESPACE::rpc::client; + DataEnvironment app; extern "C" uintptr_t __init_array_start[]; @@ -68,9 +72,8 @@ _start(int argc, char **argv, char **envp, int *ret) { extern "C" [[gnu::visibility("protected"), clang::amdgpu_kernel, clang::amdgpu_flat_work_group_size(1, 1), clang::amdgpu_max_num_work_groups(1)]] void -_end(int retval) { - // Only a single thread should call `exit` here, the rest should gracefully - // return from the kernel. This is so only one thread calls the destructors - // registred with 'atexit' above. - LIBC_NAMESPACE::exit(retval); +_end() { + // Only a single thread should call the destructors registred with 'atexit'. + // The loader utility will handle the actual exit and return code cleanly. + __cxa_finalize(nullptr); } diff --git a/libc/startup/gpu/nvptx/start.cpp b/libc/startup/gpu/nvptx/start.cpp index bc529b3..ce8f5bbb 100644 --- a/libc/startup/gpu/nvptx/start.cpp +++ b/libc/startup/gpu/nvptx/start.cpp @@ -14,6 +14,7 @@ #include "src/stdlib/exit.h" extern "C" int main(int argc, char **argv, char **envp); +extern "C" void __cxa_finalize(void *dso); namespace LIBC_NAMESPACE_DECL { @@ -22,6 +23,9 @@ DataEnvironment app; // FIXME: Factor this out into common logic so we don't need to stub it here. void teardown_main_tls() {} +// FIXME: Touch this symbol to force this to be linked in statically. +volatile void *dummy = &LIBC_NAMESPACE::rpc::client; + extern "C" { // Nvidia's 'nvlink' linker does not provide these symbols. We instead need // to manually create them and update the globals in the loader implememtation. @@ -70,9 +74,8 @@ _start(int argc, char **argv, char **envp, int *ret) { __atomic_fetch_or(ret, main(argc, argv, envp), __ATOMIC_RELAXED); } -extern "C" [[gnu::visibility("protected"), clang::nvptx_kernel]] void -_end(int retval) { - // To finis the execution we invoke all the callbacks registered via 'atexit' - // and then exit with the appropriate return value. - LIBC_NAMESPACE::exit(retval); +extern "C" [[gnu::visibility("protected"), clang::nvptx_kernel]] void _end() { + // Only a single thread should call the destructors registred with 'atexit'. + // The loader utility will handle the actual exit and return code cleanly. + __cxa_finalize(nullptr); } diff --git a/libc/startup/linux/CMakeLists.txt b/libc/startup/linux/CMakeLists.txt index 7af1819..df2c4b9 100644 --- a/libc/startup/linux/CMakeLists.txt +++ b/libc/startup/linux/CMakeLists.txt @@ -105,6 +105,7 @@ add_object_library( libc.src.stdlib.exit libc.src.stdlib.atexit libc.src.unistd.environ + libc.src.__support.OSUtil.linux.auxv COMPILE_OPTIONS -ffreestanding # To avoid compiler warnings about calling the main function. -fno-builtin # avoid emit unexpected calls diff --git a/libc/startup/linux/aarch64/tls.cpp b/libc/startup/linux/aarch64/tls.cpp index ea1b50c..7847797 100644 --- a/libc/startup/linux/aarch64/tls.cpp +++ b/libc/startup/linux/aarch64/tls.cpp @@ -62,7 +62,7 @@ void init_tls(TLSDescriptor &tls_descriptor) { MAP_ANONYMOUS | MAP_PRIVATE, -1, 0); // We cannot check the return value with MAP_FAILED as that is the return // of the mmap function and not the mmap syscall. - if (mmap_ret_val < 0 && static_cast<uintptr_t>(mmap_ret_val) > -app.page_size) + if (!linux_utils::is_valid_mmap(mmap_ret_val)) syscall_impl<long>(SYS_exit, 1); uintptr_t thread_ptr = uintptr_t(reinterpret_cast<uintptr_t *>(mmap_ret_val)); uintptr_t tls_addr = thread_ptr + size_of_pointers + padding; diff --git a/libc/startup/linux/do_start.cpp b/libc/startup/linux/do_start.cpp index 94c4ec7..a67bf18 100644 --- a/libc/startup/linux/do_start.cpp +++ b/libc/startup/linux/do_start.cpp @@ -9,6 +9,7 @@ #include "config/linux/app.h" #include "hdr/stdint_proxy.h" #include "include/llvm-libc-macros/link-macros.h" +#include "src/__support/OSUtil/linux/auxv.h" #include "src/__support/OSUtil/syscall.h" #include "src/__support/macros/config.h" #include "src/__support/threads/thread.h" @@ -88,17 +89,19 @@ void teardown_main_tls() { cleanup_tls(tls.addr, tls.size); } // denoted by an AT_NULL entry. ElfW(Phdr) *program_hdr_table = nullptr; uintptr_t program_hdr_count = 0; - app.auxv_ptr = reinterpret_cast<AuxEntry *>(env_end_marker + 1); - for (auto *aux_entry = app.auxv_ptr; aux_entry->id != AT_NULL; ++aux_entry) { - switch (aux_entry->id) { + auxv::Vector::initialize_unsafe( + reinterpret_cast<const auxv::Entry *>(env_end_marker + 1)); + auxv::Vector auxvec; + for (const auto &aux_entry : auxvec) { + switch (aux_entry.type) { case AT_PHDR: - program_hdr_table = reinterpret_cast<ElfW(Phdr) *>(aux_entry->value); + program_hdr_table = reinterpret_cast<ElfW(Phdr) *>(aux_entry.val); break; case AT_PHNUM: - program_hdr_count = aux_entry->value; + program_hdr_count = aux_entry.val; break; case AT_PAGESZ: - app.page_size = aux_entry->value; + app.page_size = aux_entry.val; break; default: break; // TODO: Read other useful entries from the aux vector. diff --git a/libc/startup/linux/riscv/tls.cpp b/libc/startup/linux/riscv/tls.cpp index 04d44e6..e9d23c5 100644 --- a/libc/startup/linux/riscv/tls.cpp +++ b/libc/startup/linux/riscv/tls.cpp @@ -50,7 +50,7 @@ void init_tls(TLSDescriptor &tls_descriptor) { MAP_ANONYMOUS | MAP_PRIVATE, -1, 0); // We cannot check the return value with MAP_FAILED as that is the return // of the mmap function and not the mmap syscall. - if (mmap_ret_val < 0 && static_cast<uintptr_t>(mmap_ret_val) > -app.page_size) + if (!linux_utils::is_valid_mmap(mmap_ret_val)) syscall_impl<long>(SYS_exit, 1); uintptr_t thread_ptr = uintptr_t(reinterpret_cast<uintptr_t *>(mmap_ret_val)); uintptr_t tls_addr = thread_ptr + size_of_pointers + padding; diff --git a/libc/startup/linux/x86_64/tls.cpp b/libc/startup/linux/x86_64/tls.cpp index d6b549a..497f744 100644 --- a/libc/startup/linux/x86_64/tls.cpp +++ b/libc/startup/linux/x86_64/tls.cpp @@ -53,7 +53,7 @@ void init_tls(TLSDescriptor &tls_descriptor) { MAP_ANONYMOUS | MAP_PRIVATE, -1, 0); // We cannot check the return value with MAP_FAILED as that is the return // of the mmap function and not the mmap syscall. - if (mmap_retval < 0 && static_cast<uintptr_t>(mmap_retval) > -app.page_size) + if (!linux_utils::is_valid_mmap(mmap_retval)) syscall_impl<long>(SYS_exit, 1); uintptr_t *tls_addr = reinterpret_cast<uintptr_t *>(mmap_retval); |