diff --git a/userspace/libraries/LibC/CMakeLists.txt b/userspace/libraries/LibC/CMakeLists.txt index 27e172f3..2d47825f 100644 --- a/userspace/libraries/LibC/CMakeLists.txt +++ b/userspace/libraries/LibC/CMakeLists.txt @@ -64,10 +64,6 @@ target_compile_definitions(objlibc PRIVATE __arch=${BANAN_ARCH}) target_compile_options(objlibc PRIVATE -O2 -g -Wstack-usage=512 -fno-exceptions -fpic -nolibc) target_compile_options(objlibc PUBLIC -Wall -Wextra -Werror -Wno-error=stack-usage=) -if("${BANAN_ARCH}" STREQUAL "i686") - target_compile_definitions(objlibc PRIVATE __disable_thread_local_storage) -endif() - function(add_crtx crtx) add_custom_target(${crtx} COMMAND ${CMAKE_CXX_COMPILER} -c -o ${CMAKE_INSTALL_LIBDIR}/${crtx}.o ${CMAKE_CURRENT_SOURCE_DIR}/arch/${BANAN_ARCH}/${crtx}.S diff --git a/userspace/libraries/LibC/pthread.cpp b/userspace/libraries/LibC/pthread.cpp index f435b42e..3b32feba 100644 --- a/userspace/libraries/LibC/pthread.cpp +++ b/userspace/libraries/LibC/pthread.cpp @@ -105,7 +105,6 @@ void pthread_cleanup_push(void (*routine)(void*), void* arg) uthread->cleanup_stack = cleanup; } -#if not __disable_thread_local_storage static thread_local struct { void* value; void (*destructor)(void*); @@ -159,7 +158,6 @@ int pthread_setspecific(pthread_key_t key, const void* value) s_pthread_keys[key].value = const_cast(value); return 0; } -#endif int pthread_attr_destroy(pthread_attr_t* attr) { @@ -413,7 +411,6 @@ void pthread_exit(void* value_ptr) while (uthread->cleanup_stack) pthread_cleanup_pop(1); -#if not __disable_thread_local_storage for (size_t iteration = 0; iteration < PTHREAD_DESTRUCTOR_ITERATIONS; iteration++) { bool called = false; @@ -431,7 +428,6 @@ void pthread_exit(void* value_ptr) if (!called) break; } -#endif free_uthread(uthread); syscall(SYS_PTHREAD_EXIT, value_ptr); @@ -1199,7 +1195,6 @@ int pthread_barrier_wait(pthread_barrier_t* barrier) return 0; } -#if not __disable_thread_local_storage struct tls_index { unsigned long int ti_module; @@ -1214,7 +1209,6 @@ extern "C" void* __tls_get_addr(tls_index* ti) #if ARCH(i686) extern "C" void* __attribute__((__regparm__(1))) ___tls_get_addr(tls_index* ti) { - return reinterpret_cast(get_uthread()->dtv[ti->ti_module] + ti->ti_offset); + return reinterpret_cast(_get_uthread()->dtv[ti->ti_module] + ti->ti_offset); } #endif -#endif diff --git a/userspace/programs/DynamicLoader/main.cpp b/userspace/programs/DynamicLoader/main.cpp index af4d0fa5..1e015652 100644 --- a/userspace/programs/DynamicLoader/main.cpp +++ b/userspace/programs/DynamicLoader/main.cpp @@ -338,7 +338,6 @@ static void handle_tls_relocation(const LoadedElf& elf, const RelocT& reloc) if (elf.tls_addr == nullptr) print_error_and_exit("tls relocation without tls", 0); - #if defined(__x86_64__) switch (ELF64_R_TYPE(reloc.r_info)) { @@ -607,7 +606,27 @@ static void relocate_elf(LoadedElf& elf, bool lazy_load) #error "unsupported architecture" #endif - *reinterpret_cast(elf.base + offset) += elf.base; + bool do_relocation = false; + + if (const uint32_t symbol_index = ELF_R_SYM(info)) + { + const auto& symbol = *reinterpret_cast(elf.symtab + symbol_index * elf.syment); + const char* symbol_name = reinterpret_cast(elf.strtab + symbol.st_name); + if (strcmp(symbol_name, "__tls_get_addr") == 0 || strcmp(symbol_name, "___tls_get_addr") == 0) + do_relocation = true; + } + + if (!do_relocation) + *reinterpret_cast(elf.base + offset) += elf.base; + else switch (elf.pltrel) + { + case DT_REL: + handle_relocation(elf, reinterpret_cast(elf.jmprel)[i], true); + break; + case DT_RELA: + handle_relocation(elf, reinterpret_cast(elf.jmprel)[i], true); + break; + } } } } @@ -1063,9 +1082,6 @@ static MasterTLS initialize_master_tls() static void initialize_tls(MasterTLS master_tls) { - if (master_tls.addr == nullptr) - return; - const size_t tls_size = master_tls.size + sizeof(uthread) + (master_tls.module_count + 1) * sizeof(uintptr_t);