diff options
author | Siva Chandra Reddy <sivachandra@google.com> | 2022-12-14 20:38:45 +0000 |
---|---|---|
committer | Siva Chandra Reddy <sivachandra@google.com> | 2022-12-15 19:54:21 +0000 |
commit | 9a07780687ab5afd9e1bafe8a7c99f512eb98ce8 (patch) | |
tree | ac99350169e5246f5f94ec0acacb6092081db83f /libc/loader | |
parent | c53d84ae5299ce90a12c4f43fdc90074b9bc3219 (diff) | |
download | llvm-9a07780687ab5afd9e1bafe8a7c99f512eb98ce8.zip llvm-9a07780687ab5afd9e1bafe8a7c99f512eb98ce8.tar.gz llvm-9a07780687ab5afd9e1bafe8a7c99f512eb98ce8.tar.bz2 |
[libc][NFC] Rename "loader" to "startup".
Reviewed By: lntue
Differential Revision: https://reviews.llvm.org/D140049
Diffstat (limited to 'libc/loader')
-rw-r--r-- | libc/loader/CMakeLists.txt | 3 | ||||
-rw-r--r-- | libc/loader/linux/CMakeLists.txt | 96 | ||||
-rw-r--r-- | libc/loader/linux/aarch64/CMakeLists.txt | 16 | ||||
-rw-r--r-- | libc/loader/linux/aarch64/start.cpp | 230 | ||||
-rw-r--r-- | libc/loader/linux/crti.cpp | 0 | ||||
-rw-r--r-- | libc/loader/linux/crtn.cpp | 0 | ||||
-rw-r--r-- | libc/loader/linux/x86_64/CMakeLists.txt | 20 | ||||
-rw-r--r-- | libc/loader/linux/x86_64/start.cpp | 234 |
8 files changed, 0 insertions, 599 deletions
diff --git a/libc/loader/CMakeLists.txt b/libc/loader/CMakeLists.txt deleted file mode 100644 index b4bbe81c..0000000 --- a/libc/loader/CMakeLists.txt +++ /dev/null @@ -1,3 +0,0 @@ -if(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/${LIBC_TARGET_OS}) - add_subdirectory(${LIBC_TARGET_OS}) -endif() diff --git a/libc/loader/linux/CMakeLists.txt b/libc/loader/linux/CMakeLists.txt deleted file mode 100644 index 92ff896..0000000 --- a/libc/loader/linux/CMakeLists.txt +++ /dev/null @@ -1,96 +0,0 @@ -function(add_loader_object name) - cmake_parse_arguments( - "ADD_LOADER_OBJECT" - "ALIAS" # Option argument - "SRC" # Single value arguments - "DEPENDS;COMPILE_OPTIONS" # Multi value arguments - ${ARGN} - ) - - get_fq_target_name(${name} fq_target_name) - get_fq_deps_list(fq_deps_list ${ADD_LOADER_OBJECT_DEPENDS}) - if(ADD_LOADER_OBJECT_ALIAS) - list(LENGTH ADD_LOADER_OBJECT_DEPENDS deps_size) - if(NOT (${deps_size} EQUAL "1")) - message(FATAL_ERROR "A loader object alias should have exactly one dependency.") - endif() - list(GET ADD_LOADER_OBJECT_DEPENDS 0 dep) - get_fq_dep_name(fq_dep_name ${dep}) - - add_custom_target(${fq_target_name}) - add_dependencies(${fq_target_name} ${fq_dep_name}) - get_target_property(loader_object ${fq_dep_name} LOADER_OBJECT) - set_target_properties( - ${fq_target_name} - PROPERTIES - "TARGET_TYPE" "${OBJECT_LIBRARY_TARGET_TYPE}" - "LOADER_OBJECT" "${loader_object}" - "OBJECT_FILES" "" - "DEPS" "${fq_dep_name}" - ) - return() - endif() - - add_object_library( - ${name}.__objects__ - SRCS ${ADD_LOADER_OBJECT_SRC} - DEPENDS ${ADD_LOADER_OBJECT_DEPENDS} - COMPILE_OPTIONS ${ADD_LOADER_OBJECT_COMPILE_OPTIONS} - ) - - set(objfile ${LIBC_BUILD_DIR}/lib/${name}.o) - add_custom_command( - OUTPUT ${objfile} - COMMAND cp $<TARGET_OBJECTS:${fq_target_name}.__objects__> ${objfile} - DEPENDS $<TARGET_OBJECTS:${fq_target_name}.__objects__> - ) - add_custom_target( - ${fq_target_name} - DEPENDS ${objfile} - ) - set_target_properties( - ${fq_target_name} - PROPERTIES - "TARGET_TYPE" "${OBJECT_LIBRARY_TARGET_TYPE}" - "LOADER_OBJECT" "${objfile}" - "OBJECT_FILES" "" - "DEPS" "${fq_target_name}.__objects__" - ) -endfunction() - -if(NOT (EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/${LIBC_TARGET_ARCHITECTURE})) - message(STATUS "Skipping loader for target architecture ${LIBC_TARGET_ARCHITECTURE}") - return() -endif() - -add_subdirectory(${LIBC_TARGET_ARCHITECTURE}) - -add_loader_object( - crt1 - ALIAS - DEPENDS - .${LIBC_TARGET_ARCHITECTURE}.crt1 -) - -add_loader_object( - crti - SRC - crti.cpp -) - -add_loader_object( - crtn - SRC - crtn.cpp -) - -add_custom_target(libc-startup) -set(startup_components crt1 crti crtn) -foreach(target IN LISTS startup_components) - set(fq_target_name libc.loader.linux.${target}) - add_dependencies(libc-startup ${fq_target_name}) - get_target_property(loader_object ${fq_target_name} LOADER_OBJECT) - install(FILES ${loader_object} - DESTINATION ${CMAKE_INSTALL_LIBDIR} - COMPONENT ${LIBC_COMPONENT}) -endforeach() diff --git a/libc/loader/linux/aarch64/CMakeLists.txt b/libc/loader/linux/aarch64/CMakeLists.txt deleted file mode 100644 index 054df0b..0000000 --- a/libc/loader/linux/aarch64/CMakeLists.txt +++ /dev/null @@ -1,16 +0,0 @@ -add_loader_object( - crt1 - SRC - start.cpp - DEPENDS - libc.config.linux.app_h - libc.include.sys_mman - libc.include.sys_syscall - libc.src.__support.OSUtil.osutil - libc.src.stdlib.exit - libc.src.stdlib.atexit - libc.src.string.memory_utils.memcpy_implementation - COMPILE_OPTIONS - -fno-omit-frame-pointer - -ffreestanding # To avoid compiler warnings about calling the main function. -) diff --git a/libc/loader/linux/aarch64/start.cpp b/libc/loader/linux/aarch64/start.cpp deleted file mode 100644 index b02ea7d..0000000 --- a/libc/loader/linux/aarch64/start.cpp +++ /dev/null @@ -1,230 +0,0 @@ -//===-- Implementation of crt for aarch64 ---------------------------------===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// - -#include "config/linux/app.h" -#include "src/__support/OSUtil/syscall.h" -#include "src/__support/threads/thread.h" -#include "src/stdlib/atexit.h" -#include "src/stdlib/exit.h" -#include "src/string/memory_utils/memcpy_implementations.h" - -#include <arm_acle.h> - -#include <linux/auxvec.h> -#include <linux/elf.h> -#include <stdint.h> -#include <sys/mman.h> -#include <sys/syscall.h> -#include <unistd.h> - -extern "C" int main(int, char **, char **); - -// Source documentation: -// https://github.com/ARM-software/abi-aa/tree/main/sysvabi64 - -namespace __llvm_libc { - -#ifdef SYS_mmap2 -static constexpr long MMAP_SYSCALL_NUMBER = SYS_mmap2; -#elif SYS_mmap -static constexpr long MMAP_SYSCALL_NUMBER = SYS_mmap; -#else -#error "Target platform does not have SYS_mmap or SYS_mmap2 defined" -#endif - -AppProperties app; - -static ThreadAttributes main_thread_attrib; - -void init_tls(TLSDescriptor &tls_descriptor) { - if (app.tls.size == 0) { - tls_descriptor.size = 0; - tls_descriptor.tp = 0; - return; - } - - // aarch64 follows the variant 1 TLS layout: - // - // 1. First entry is the dynamic thread vector pointer - // 2. Second entry is a 8-byte reserved word. - // 3. Padding for alignment. - // 4. The TLS data from the ELF image. - // - // The thread pointer points to the first entry. - - const uintptr_t size_of_pointers = 2 * sizeof(uintptr_t); - uintptr_t padding = 0; - const uintptr_t ALIGNMENT_MASK = app.tls.align - 1; - uintptr_t diff = size_of_pointers & ALIGNMENT_MASK; - if (diff != 0) - padding += (ALIGNMENT_MASK - diff) + 1; - - uintptr_t alloc_size = size_of_pointers + padding + app.tls.size; - - // We cannot call the mmap function here as the functions set errno on - // failure. Since errno is implemented via a thread local variable, we cannot - // use errno before TLS is setup. - long mmap_ret_val = __llvm_libc::syscall_impl( - MMAP_SYSCALL_NUMBER, nullptr, alloc_size, PROT_READ | PROT_WRITE, - 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.pageSize) - __llvm_libc::syscall_impl(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; - __llvm_libc::inline_memcpy(reinterpret_cast<char *>(tls_addr), - reinterpret_cast<const char *>(app.tls.address), - app.tls.init_size); - tls_descriptor.size = alloc_size; - tls_descriptor.addr = thread_ptr; - tls_descriptor.tp = thread_ptr; -} - -void cleanup_tls(uintptr_t addr, uintptr_t size) { - if (size == 0) - return; - __llvm_libc::syscall_impl(SYS_munmap, addr, size); -} - -static void set_thread_ptr(uintptr_t val) { __arm_wsr64("tpidr_el0", val); } - -using InitCallback = void(int, char **, char **); -using FiniCallback = void(void); - -extern "C" { -// These arrays are present in the .init_array and .fini_array sections. -// The symbols are inserted by linker when it sees references to them. -extern uintptr_t __preinit_array_start[]; -extern uintptr_t __preinit_array_end[]; -extern uintptr_t __init_array_start[]; -extern uintptr_t __init_array_end[]; -extern uintptr_t __fini_array_start[]; -extern uintptr_t __fini_array_end[]; -} - -static void call_init_array_callbacks(int argc, char **argv, char **env) { - size_t preinit_array_size = __preinit_array_end - __preinit_array_start; - for (size_t i = 0; i < preinit_array_size; ++i) - reinterpret_cast<InitCallback *>(__preinit_array_start[i])(argc, argv, env); - size_t init_array_size = __init_array_end - __init_array_start; - for (size_t i = 0; i < init_array_size; ++i) - reinterpret_cast<InitCallback *>(__init_array_start[i])(argc, argv, env); -} - -static void call_fini_array_callbacks() { - size_t fini_array_size = __fini_array_end - __fini_array_start; - for (size_t i = fini_array_size; i > 0; --i) - reinterpret_cast<FiniCallback *>(__fini_array_start[i - 1])(); -} - -} // namespace __llvm_libc - -using __llvm_libc::app; - -// TODO: Would be nice to use the aux entry structure from elf.h when available. -struct AuxEntry { - uint64_t type; - uint64_t value; -}; - -__attribute__((noinline)) static void do_start() { - auto tid = __llvm_libc::syscall_impl(SYS_gettid); - if (tid <= 0) - __llvm_libc::syscall_impl(SYS_exit, 1); - __llvm_libc::main_thread_attrib.tid = tid; - - // After the argv array, is a 8-byte long NULL value before the array of env - // values. The end of the env values is marked by another 8-byte long NULL - // value. We step over it (the "+ 1" below) to get to the env values. - uint64_t *env_ptr = app.args->argv + app.args->argc + 1; - uint64_t *env_end_marker = env_ptr; - app.envPtr = env_ptr; - while (*env_end_marker) - ++env_end_marker; - - // Initialize the POSIX global declared in unistd.h - environ = reinterpret_cast<char **>(env_ptr); - - // After the env array, is the aux-vector. The end of the aux-vector is - // denoted by an AT_NULL entry. - Elf64_Phdr *programHdrTable = nullptr; - uintptr_t programHdrCount; - for (AuxEntry *aux_entry = reinterpret_cast<AuxEntry *>(env_end_marker + 1); - aux_entry->type != AT_NULL; ++aux_entry) { - switch (aux_entry->type) { - case AT_PHDR: - programHdrTable = reinterpret_cast<Elf64_Phdr *>(aux_entry->value); - break; - case AT_PHNUM: - programHdrCount = aux_entry->value; - break; - case AT_PAGESZ: - app.pageSize = aux_entry->value; - break; - default: - break; // TODO: Read other useful entries from the aux vector. - } - } - - app.tls.size = 0; - for (uintptr_t i = 0; i < programHdrCount; ++i) { - Elf64_Phdr *phdr = programHdrTable + i; - if (phdr->p_type != PT_TLS) - continue; - // TODO: p_vaddr value has to be adjusted for static-pie executables. - app.tls.address = phdr->p_vaddr; - app.tls.size = phdr->p_memsz; - app.tls.init_size = phdr->p_filesz; - app.tls.align = phdr->p_align; - } - - __llvm_libc::TLSDescriptor tls; - __llvm_libc::init_tls(tls); - if (tls.size != 0) - __llvm_libc::set_thread_ptr(tls.tp); - - __llvm_libc::self.attrib = &__llvm_libc::main_thread_attrib; - __llvm_libc::main_thread_attrib.atexit_callback_mgr = - __llvm_libc::internal::get_thread_atexit_callback_mgr(); - - // We want the fini array callbacks to be run after other atexit - // callbacks are run. So, we register them before running the init - // array callbacks as they can potentially register their own atexit - // callbacks. - __llvm_libc::atexit(&__llvm_libc::call_fini_array_callbacks); - - __llvm_libc::call_init_array_callbacks( - app.args->argc, reinterpret_cast<char **>(app.args->argv), - reinterpret_cast<char **>(env_ptr)); - - int retval = main(app.args->argc, reinterpret_cast<char **>(app.args->argv), - reinterpret_cast<char **>(env_ptr)); - - // TODO: TLS cleanup should be done after all other atexit callbacks - // are run. So, register a cleanup callback for it with atexit before - // everything else. - __llvm_libc::cleanup_tls(tls.addr, tls.size); - __llvm_libc::exit(retval); -} - -extern "C" void _start() { - // Skip the Frame Pointer and the Link Register - // https://github.com/ARM-software/abi-aa/blob/main/aapcs64/aapcs64.rst - // Section 6.2.3. Note that this only works if the current function - // is not using any callee-saved registers (x19 to x28). If the - // function uses such registers, then their value is pushed on to the - // stack before the frame pointer an link register values. That breaks - // the assumption that stepping over the frame pointer and link register - // will take us to the previous stack pointer. That is the reason why the - // actual business logic of the startup code is pushed into a non-inline - // function do_start so that this function is free of any stack usage. - app.args = reinterpret_cast<__llvm_libc::Args *>( - reinterpret_cast<uintptr_t *>(__builtin_frame_address(0)) + 2); - do_start(); -} diff --git a/libc/loader/linux/crti.cpp b/libc/loader/linux/crti.cpp deleted file mode 100644 index e69de29..0000000 --- a/libc/loader/linux/crti.cpp +++ /dev/null diff --git a/libc/loader/linux/crtn.cpp b/libc/loader/linux/crtn.cpp deleted file mode 100644 index e69de29..0000000 --- a/libc/loader/linux/crtn.cpp +++ /dev/null diff --git a/libc/loader/linux/x86_64/CMakeLists.txt b/libc/loader/linux/x86_64/CMakeLists.txt deleted file mode 100644 index f62ad0a..0000000 --- a/libc/loader/linux/x86_64/CMakeLists.txt +++ /dev/null @@ -1,20 +0,0 @@ -add_loader_object( - crt1 - SRC - start.cpp - DEPENDS - libc.config.linux.app_h - libc.include.sys_mman - libc.include.sys_syscall - libc.include.unistd - libc.src.__support.threads.thread - libc.src.__support.OSUtil.osutil - libc.src.stdlib.exit - libc.src.stdlib.atexit - libc.src.string.memory_utils.memcpy_implementation - libc.src.unistd.environ - COMPILE_OPTIONS - -fno-omit-frame-pointer - -ffreestanding # To avoid compiler warnings about calling the main function. - -fno-builtin -) diff --git a/libc/loader/linux/x86_64/start.cpp b/libc/loader/linux/x86_64/start.cpp deleted file mode 100644 index 6ddb344..0000000 --- a/libc/loader/linux/x86_64/start.cpp +++ /dev/null @@ -1,234 +0,0 @@ -//===-- Implementation of crt for x86_64 ----------------------------------===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// - -#include "config/linux/app.h" -#include "src/__support/OSUtil/syscall.h" -#include "src/__support/threads/thread.h" -#include "src/stdlib/atexit.h" -#include "src/stdlib/exit.h" -#include "src/string/memory_utils/memcpy_implementations.h" - -#include <asm/prctl.h> -#include <linux/auxvec.h> -#include <linux/elf.h> -#include <stdint.h> -#include <sys/mman.h> -#include <sys/syscall.h> -#include <unistd.h> - -extern "C" int main(int, char **, char **); - -namespace __llvm_libc { - -#ifdef SYS_mmap2 -static constexpr long mmapSyscallNumber = SYS_mmap2; -#elif SYS_mmap -static constexpr long mmapSyscallNumber = SYS_mmap; -#else -#error "Target platform does not have SYS_mmap or SYS_mmap2 defined" -#endif - -AppProperties app; - -static ThreadAttributes main_thread_attrib; - -// TODO: The function is x86_64 specific. Move it to config/linux/app.h -// and generalize it. Also, dynamic loading is not handled currently. -void init_tls(TLSDescriptor &tls_descriptor) { - if (app.tls.size == 0) { - tls_descriptor.size = 0; - tls_descriptor.tp = 0; - return; - } - - // We will assume the alignment is always a power of two. - uintptr_t tlsSize = app.tls.size & -app.tls.align; - if (tlsSize != app.tls.size) - tlsSize += app.tls.align; - - // Per the x86_64 TLS ABI, the entry pointed to by the thread pointer is the - // address of the TLS block. So, we add more size to accomodate this address - // entry. - uintptr_t tlsSizeWithAddr = tlsSize + sizeof(uintptr_t); - - // We cannot call the mmap function here as the functions set errno on - // failure. Since errno is implemented via a thread local variable, we cannot - // use errno before TLS is setup. - long mmapRetVal = __llvm_libc::syscall_impl( - mmapSyscallNumber, nullptr, tlsSizeWithAddr, PROT_READ | PROT_WRITE, - 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 (mmapRetVal < 0 && static_cast<uintptr_t>(mmapRetVal) > -app.pageSize) - __llvm_libc::syscall_impl(SYS_exit, 1); - uintptr_t *tlsAddr = reinterpret_cast<uintptr_t *>(mmapRetVal); - - // x86_64 TLS faces down from the thread pointer with the first entry - // pointing to the address of the first real TLS byte. - uintptr_t endPtr = reinterpret_cast<uintptr_t>(tlsAddr) + tlsSize; - *reinterpret_cast<uintptr_t *>(endPtr) = endPtr; - - __llvm_libc::inline_memcpy(reinterpret_cast<char *>(tlsAddr), - reinterpret_cast<const char *>(app.tls.address), - app.tls.init_size); - - tls_descriptor = {tlsSizeWithAddr, uintptr_t(tlsAddr), endPtr}; - return; -} - -void cleanup_tls(uintptr_t addr, uintptr_t size) { - if (size == 0) - return; - __llvm_libc::syscall_impl(SYS_munmap, addr, size); -} - -// Sets the thread pointer to |val|. Returns true on success, false on failure. -static bool set_thread_ptr(uintptr_t val) { - return __llvm_libc::syscall_impl(SYS_arch_prctl, ARCH_SET_FS, val) == -1 - ? false - : true; -} - -using InitCallback = void(int, char **, char **); -using FiniCallback = void(void); - -extern "C" { -// These arrays are present in the .init_array and .fini_array sections. -// The symbols are inserted by linker when it sees references to them. -extern uintptr_t __preinit_array_start[]; -extern uintptr_t __preinit_array_end[]; -extern uintptr_t __init_array_start[]; -extern uintptr_t __init_array_end[]; -extern uintptr_t __fini_array_start[]; -extern uintptr_t __fini_array_end[]; -} - -static void call_init_array_callbacks(int argc, char **argv, char **env) { - size_t preinit_array_size = __preinit_array_end - __preinit_array_start; - for (size_t i = 0; i < preinit_array_size; ++i) - reinterpret_cast<InitCallback *>(__preinit_array_start[i])(argc, argv, env); - size_t init_array_size = __init_array_end - __init_array_start; - for (size_t i = 0; i < init_array_size; ++i) - reinterpret_cast<InitCallback *>(__init_array_start[i])(argc, argv, env); -} - -static void call_fini_array_callbacks() { - size_t fini_array_size = __fini_array_end - __fini_array_start; - for (size_t i = fini_array_size; i > 0; --i) - reinterpret_cast<FiniCallback *>(__fini_array_start[i - 1])(); -} - -} // namespace __llvm_libc - -using __llvm_libc::app; - -// TODO: Would be nice to use the aux entry structure from elf.h when available. -struct AuxEntry { - uint64_t type; - uint64_t value; -}; - -extern "C" void _start() { - // This TU is compiled with -fno-omit-frame-pointer. Hence, the previous value - // of the base pointer is pushed on to the stack. So, we step over it (the - // "+ 1" below) to get to the args. - app.args = reinterpret_cast<__llvm_libc::Args *>( - reinterpret_cast<uintptr_t *>(__builtin_frame_address(0)) + 1); - - // The x86_64 ABI requires that the stack pointer is aligned to a 16-byte - // boundary. We align it here but we cannot use any local variables created - // before the following alignment. Best would be to not create any local - // variables before the alignment. Also, note that we are aligning the stack - // downwards as the x86_64 stack grows downwards. This ensures that we don't - // tread on argc, argv etc. - // NOTE: Compiler attributes for alignment do not help here as the stack - // pointer on entry to this _start function is controlled by the OS. In fact, - // compilers can generate code assuming the alignment as required by the ABI. - // If the stack pointers as setup by the OS are already aligned, then the - // following code is a NOP. - __asm__ __volatile__("andq $0xfffffffffffffff0, %%rsp\n\t" ::: "%rsp"); - __asm__ __volatile__("andq $0xfffffffffffffff0, %%rbp\n\t" ::: "%rbp"); - - auto tid = __llvm_libc::syscall_impl(SYS_gettid); - if (tid <= 0) - __llvm_libc::syscall_impl(SYS_exit, 1); - __llvm_libc::main_thread_attrib.tid = tid; - - // After the argv array, is a 8-byte long NULL value before the array of env - // values. The end of the env values is marked by another 8-byte long NULL - // value. We step over it (the "+ 1" below) to get to the env values. - uint64_t *env_ptr = app.args->argv + app.args->argc + 1; - uint64_t *env_end_marker = env_ptr; - app.envPtr = env_ptr; - while (*env_end_marker) - ++env_end_marker; - - // Initialize the POSIX global declared in unistd.h - environ = reinterpret_cast<char **>(env_ptr); - - // After the env array, is the aux-vector. The end of the aux-vector is - // denoted by an AT_NULL entry. - Elf64_Phdr *programHdrTable = nullptr; - uintptr_t programHdrCount; - for (AuxEntry *aux_entry = reinterpret_cast<AuxEntry *>(env_end_marker + 1); - aux_entry->type != AT_NULL; ++aux_entry) { - switch (aux_entry->type) { - case AT_PHDR: - programHdrTable = reinterpret_cast<Elf64_Phdr *>(aux_entry->value); - break; - case AT_PHNUM: - programHdrCount = aux_entry->value; - break; - case AT_PAGESZ: - app.pageSize = aux_entry->value; - break; - default: - break; // TODO: Read other useful entries from the aux vector. - } - } - - app.tls.size = 0; - for (uintptr_t i = 0; i < programHdrCount; ++i) { - Elf64_Phdr *phdr = programHdrTable + i; - if (phdr->p_type != PT_TLS) - continue; - // TODO: p_vaddr value has to be adjusted for static-pie executables. - app.tls.address = phdr->p_vaddr; - app.tls.size = phdr->p_memsz; - app.tls.init_size = phdr->p_filesz; - app.tls.align = phdr->p_align; - } - - __llvm_libc::TLSDescriptor tls; - __llvm_libc::init_tls(tls); - if (tls.size != 0 && !__llvm_libc::set_thread_ptr(tls.tp)) - __llvm_libc::syscall_impl(SYS_exit, 1); - - __llvm_libc::self.attrib = &__llvm_libc::main_thread_attrib; - __llvm_libc::main_thread_attrib.atexit_callback_mgr = - __llvm_libc::internal::get_thread_atexit_callback_mgr(); - - // We want the fini array callbacks to be run after other atexit - // callbacks are run. So, we register them before running the init - // array callbacks as they can potentially register their own atexit - // callbacks. - __llvm_libc::atexit(&__llvm_libc::call_fini_array_callbacks); - - __llvm_libc::call_init_array_callbacks( - app.args->argc, reinterpret_cast<char **>(app.args->argv), - reinterpret_cast<char **>(env_ptr)); - - int retval = main(app.args->argc, reinterpret_cast<char **>(app.args->argv), - reinterpret_cast<char **>(env_ptr)); - - // TODO: TLS cleanup should be done after all other atexit callbacks - // are run. So, register a cleanup callback for it with atexit before - // everything else. - __llvm_libc::cleanup_tls(tls.addr, tls.size); - __llvm_libc::exit(retval); -} |