ld.so: Possibly incorrect dynamic TLS implementation

This commit is contained in:
K. Lange 2022-05-26 08:58:49 +09:00
parent 5b57bba995
commit 9e44d08ed7
2 changed files with 22 additions and 0 deletions

View File

@ -10,6 +10,7 @@
#include <pthread.h>
#include <errno.h>
#include <string.h>
#include <stdio.h>
#include <sys/wait.h>
#include <sys/sysfunc.h>
@ -37,7 +38,19 @@ struct pthread {
};
void * __tls_get_addr(void* input) {
#ifdef __x86_64__
struct tls_index {
uintptr_t module;
uintptr_t offset;
};
struct tls_index * index = input;
/* We only support initial-exec stuff, so this must be %fs:offset */
uintptr_t threadbase;
asm ("mov %%fs:0, %0" :"=r"(threadbase));
return (void*)(threadbase + index->offset);
#else
return NULL;
#endif
}
void __make_tls(void) {

View File

@ -402,6 +402,8 @@ static int need_symbol_for_type(unsigned int type) {
case R_X86_64_JUMP_SLOT:
case R_X86_64_8:
case R_X86_64_TPOFF64:
case R_X86_64_DTPMOD64:
case R_X86_64_DTPOFF64:
return 1;
default:
return 0;
@ -523,8 +525,15 @@ static int object_relocate(elf_t * object) {
memcpy((void *)(table->r_offset + object->base), &x, sizeof(uintptr_t));
break;
case R_X86_64_DTPMOD64:
if (!hashmap_has(tls_map, symname)) { fprintf(stderr, "tls entry is unallocated?\n"); break; }
x = 0;
memcpy((void *)(table->r_offset + object->base), &x, sizeof(uintptr_t));
break;
case R_X86_64_DTPOFF64:
if (!hashmap_has(tls_map, symname)) { fprintf(stderr, "tls entry is unallocated?\n"); break; }
x = table->r_addend;
x += (size_t)hashmap_get(tls_map, symname);
memcpy((void *)(table->r_offset + object->base), &x, sizeof(uintptr_t));
break;
#elif defined(__aarch64__)
case 1024: /* COPY */