forked from Bananymous/banan-os
				
			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 | ||||||
| 
 | 
 | ||||||
| 				*reinterpret_cast<uintptr_t*>(elf.base + offset) += elf.base; | 				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; | ||||||
|  | 				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