mirror of
https://github.com/hermitcore/libhermit.git
synced 2025-03-09 00:00:03 +01:00
consider the elf header to initialize the TLS
- file_size describes the amount of data in the elf file to initialize TLS => read file_size instead of mem_size from the elf file
This commit is contained in:
parent
42dc81ee3f
commit
6e136fe990
2 changed files with 18 additions and 13 deletions
|
@ -91,14 +91,15 @@ static int thread_entry(void* arg, size_t ep)
|
|||
//vma_dump();
|
||||
|
||||
// do we have to create a TLS segement?
|
||||
if (curr_task->tls_addr && curr_task->tls_size) {
|
||||
if (curr_task->tls_addr && curr_task->tls_mem_size) {
|
||||
// set fs register to the TLS segment
|
||||
writefs(stack+offset);
|
||||
kprintf("Task %d set fs to 0x%llx\n", curr_task->id, stack+offset);
|
||||
|
||||
// copy default TLS segment to stack
|
||||
offset -= curr_task->tls_size;
|
||||
memcpy((void*) (stack+offset), (void*) curr_task->tls_addr, curr_task->tls_size);
|
||||
offset -= curr_task->tls_mem_size;
|
||||
if (curr_task->tls_file_size)
|
||||
memcpy((void*) (stack+offset), (void*) curr_task->tls_addr, curr_task->tls_file_size);
|
||||
} else writefs(0); // no TLS => clear fs register
|
||||
|
||||
// set first argument
|
||||
|
@ -352,9 +353,10 @@ static int load_task(load_args_t* largs)
|
|||
vma_add(stack, stack+npages*PAGE_SIZE-1, flags);
|
||||
break;
|
||||
case ELF_PT_TLS:
|
||||
kprintf("Found TLS segment. addr 0x%llx, size 0x%llx\n", prog_header.virt_addr, prog_header.mem_size);
|
||||
kprintf("Found TLS segment. addr 0x%llx, mem size 0x%llx, file size 0x%llx\n", prog_header.virt_addr, prog_header.mem_size, prog_header.file_size);
|
||||
curr_task->tls_addr = prog_header.virt_addr;
|
||||
curr_task->tls_size = prog_header.mem_size;
|
||||
curr_task->tls_mem_size = prog_header.mem_size;
|
||||
curr_task->tls_file_size = prog_header.file_size;
|
||||
break;
|
||||
default:
|
||||
kprintf("Unknown type 0x%lx in program header\n", prog_header.type);
|
||||
|
@ -384,20 +386,21 @@ static int load_task(load_args_t* largs)
|
|||
offset = DEFAULT_STACK_SIZE-16;
|
||||
|
||||
// do we have to create a TLS segement?
|
||||
if (curr_task->tls_addr && curr_task->tls_size) {
|
||||
if (curr_task->tls_size >= DEFAULT_STACK_SIZE-128) {
|
||||
kprintf("TLS is too large: 0x%zx\n", curr_task->tls_size);
|
||||
if (curr_task->tls_addr && curr_task->tls_mem_size) {
|
||||
if (curr_task->tls_mem_size >= DEFAULT_STACK_SIZE-128) {
|
||||
kprintf("TLS is too large: 0x%zx\n", curr_task->tls_mem_size);
|
||||
ret = -ENOMEM;
|
||||
goto Lerr;
|
||||
}
|
||||
|
||||
// set fs register to the TLS segment
|
||||
writefs(stack+offset);
|
||||
kprintf("Task %d set fs to 0x%zx\n", curr_task->id, readfs());
|
||||
kprintf("Task %d set fs to 0x%zx\n", curr_task->id, stack+offset);
|
||||
|
||||
// copy default TLS segment to stack
|
||||
offset -= curr_task->tls_size;
|
||||
memcpy((void*) (stack+offset), (void*) curr_task->tls_addr, curr_task->tls_size);
|
||||
offset -= curr_task->tls_mem_size;
|
||||
if (curr_task->tls_file_size)
|
||||
memcpy((void*) (stack+offset), (void*) curr_task->tls_addr, curr_task->tls_file_size);
|
||||
}
|
||||
|
||||
// push strings on the stack
|
||||
|
|
|
@ -108,8 +108,10 @@ typedef struct task {
|
|||
struct task* prev;
|
||||
/// TLS address
|
||||
size_t tls_addr;
|
||||
/// TLS size
|
||||
size_t tls_size;
|
||||
/// TLS mem size
|
||||
size_t tls_mem_size;
|
||||
/// TLS file size
|
||||
size_t tls_file_size;
|
||||
/// FPU state
|
||||
union fpu_state fpu;
|
||||
} task_t;
|
||||
|
|
Loading…
Add table
Reference in a new issue