DynamicLoader: Fix TLS on 32 bit platform
There were two problems with my previous implementation - TLS was not allocated if nothing used it. There is a fallback initialization in _init_libc, but this was not enough if one of the init functions tried to access errno. - __tls_get_addr was not resolved. If __tls_get_addr was called through a plt entry, everything would just break :(
This commit is contained in:
parent
00c6820825
commit
5ad7d7edb1
|
@ -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 PRIVATE -O2 -g -Wstack-usage=512 -fno-exceptions -fpic -nolibc)
|
||||||
target_compile_options(objlibc PUBLIC -Wall -Wextra -Werror -Wno-error=stack-usage=)
|
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)
|
function(add_crtx crtx)
|
||||||
add_custom_target(${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
|
COMMAND ${CMAKE_CXX_COMPILER} -c -o ${CMAKE_INSTALL_LIBDIR}/${crtx}.o ${CMAKE_CURRENT_SOURCE_DIR}/arch/${BANAN_ARCH}/${crtx}.S
|
||||||
|
|
|
@ -105,7 +105,6 @@ void pthread_cleanup_push(void (*routine)(void*), void* arg)
|
||||||
uthread->cleanup_stack = cleanup;
|
uthread->cleanup_stack = cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if not __disable_thread_local_storage
|
|
||||||
static thread_local struct {
|
static thread_local struct {
|
||||||
void* value;
|
void* value;
|
||||||
void (*destructor)(void*);
|
void (*destructor)(void*);
|
||||||
|
@ -159,7 +158,6 @@ int pthread_setspecific(pthread_key_t key, const void* value)
|
||||||
s_pthread_keys[key].value = const_cast<void*>(value);
|
s_pthread_keys[key].value = const_cast<void*>(value);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
int pthread_attr_destroy(pthread_attr_t* attr)
|
int pthread_attr_destroy(pthread_attr_t* attr)
|
||||||
{
|
{
|
||||||
|
@ -413,7 +411,6 @@ void pthread_exit(void* value_ptr)
|
||||||
while (uthread->cleanup_stack)
|
while (uthread->cleanup_stack)
|
||||||
pthread_cleanup_pop(1);
|
pthread_cleanup_pop(1);
|
||||||
|
|
||||||
#if not __disable_thread_local_storage
|
|
||||||
for (size_t iteration = 0; iteration < PTHREAD_DESTRUCTOR_ITERATIONS; iteration++)
|
for (size_t iteration = 0; iteration < PTHREAD_DESTRUCTOR_ITERATIONS; iteration++)
|
||||||
{
|
{
|
||||||
bool called = false;
|
bool called = false;
|
||||||
|
@ -431,7 +428,6 @@ void pthread_exit(void* value_ptr)
|
||||||
if (!called)
|
if (!called)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
free_uthread(uthread);
|
free_uthread(uthread);
|
||||||
syscall(SYS_PTHREAD_EXIT, value_ptr);
|
syscall(SYS_PTHREAD_EXIT, value_ptr);
|
||||||
|
@ -1199,7 +1195,6 @@ int pthread_barrier_wait(pthread_barrier_t* barrier)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if not __disable_thread_local_storage
|
|
||||||
struct tls_index
|
struct tls_index
|
||||||
{
|
{
|
||||||
unsigned long int ti_module;
|
unsigned long int ti_module;
|
||||||
|
@ -1214,7 +1209,6 @@ extern "C" void* __tls_get_addr(tls_index* ti)
|
||||||
#if ARCH(i686)
|
#if ARCH(i686)
|
||||||
extern "C" void* __attribute__((__regparm__(1))) ___tls_get_addr(tls_index* ti)
|
extern "C" void* __attribute__((__regparm__(1))) ___tls_get_addr(tls_index* ti)
|
||||||
{
|
{
|
||||||
return reinterpret_cast<void*>(get_uthread()->dtv[ti->ti_module] + ti->ti_offset);
|
return reinterpret_cast<void*>(_get_uthread()->dtv[ti->ti_module] + ti->ti_offset);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
#endif
|
|
||||||
|
|
|
@ -338,7 +338,6 @@ static void handle_tls_relocation(const LoadedElf& elf, const RelocT& reloc)
|
||||||
if (elf.tls_addr == nullptr)
|
if (elf.tls_addr == nullptr)
|
||||||
print_error_and_exit("tls relocation without tls", 0);
|
print_error_and_exit("tls relocation without tls", 0);
|
||||||
|
|
||||||
|
|
||||||
#if defined(__x86_64__)
|
#if defined(__x86_64__)
|
||||||
switch (ELF64_R_TYPE(reloc.r_info))
|
switch (ELF64_R_TYPE(reloc.r_info))
|
||||||
{
|
{
|
||||||
|
@ -607,7 +606,27 @@ static void relocate_elf(LoadedElf& elf, bool lazy_load)
|
||||||
#error "unsupported architecture"
|
#error "unsupported architecture"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
bool do_relocation = false;
|
||||||
|
|
||||||
|
if (const uint32_t symbol_index = ELF_R_SYM(info))
|
||||||
|
{
|
||||||
|
const auto& symbol = *reinterpret_cast<ElfNativeSymbol*>(elf.symtab + symbol_index * elf.syment);
|
||||||
|
const char* symbol_name = reinterpret_cast<const char*>(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<uintptr_t*>(elf.base + offset) += elf.base;
|
*reinterpret_cast<uintptr_t*>(elf.base + offset) += elf.base;
|
||||||
|
else switch (elf.pltrel)
|
||||||
|
{
|
||||||
|
case DT_REL:
|
||||||
|
handle_relocation(elf, reinterpret_cast<ElfNativeRelocation*>(elf.jmprel)[i], true);
|
||||||
|
break;
|
||||||
|
case DT_RELA:
|
||||||
|
handle_relocation(elf, reinterpret_cast<ElfNativeRelocationA*>(elf.jmprel)[i], true);
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1063,9 +1082,6 @@ static MasterTLS initialize_master_tls()
|
||||||
|
|
||||||
static void initialize_tls(MasterTLS master_tls)
|
static void initialize_tls(MasterTLS master_tls)
|
||||||
{
|
{
|
||||||
if (master_tls.addr == nullptr)
|
|
||||||
return;
|
|
||||||
|
|
||||||
const size_t tls_size = master_tls.size
|
const size_t tls_size = master_tls.size
|
||||||
+ sizeof(uthread)
|
+ sizeof(uthread)
|
||||||
+ (master_tls.module_count + 1) * sizeof(uintptr_t);
|
+ (master_tls.module_count + 1) * sizeof(uintptr_t);
|
||||||
|
|
Loading…
Reference in New Issue