aboutsummaryrefslogtreecommitdiff
path: root/libc/startup
diff options
context:
space:
mode:
Diffstat (limited to 'libc/startup')
-rw-r--r--libc/startup/gpu/amdgpu/start.cpp13
-rw-r--r--libc/startup/gpu/nvptx/start.cpp13
-rw-r--r--libc/startup/linux/CMakeLists.txt1
-rw-r--r--libc/startup/linux/aarch64/tls.cpp2
-rw-r--r--libc/startup/linux/do_start.cpp15
-rw-r--r--libc/startup/linux/riscv/tls.cpp2
-rw-r--r--libc/startup/linux/x86_64/tls.cpp2
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);