From 6e136fe99085d9303e2d6f2882a200792d2e13bc Mon Sep 17 00:00:00 2001 From: Stefan Lankes Date: Tue, 8 Sep 2015 08:39:07 +0200 Subject: [PATCH] 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 --- hermit/arch/x86/kernel/tasks.c | 25 ++++++++++++++----------- hermit/include/hermit/tasks_types.h | 6 ++++-- 2 files changed, 18 insertions(+), 13 deletions(-) diff --git a/hermit/arch/x86/kernel/tasks.c b/hermit/arch/x86/kernel/tasks.c index e51424169..05749fdf6 100644 --- a/hermit/arch/x86/kernel/tasks.c +++ b/hermit/arch/x86/kernel/tasks.c @@ -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 diff --git a/hermit/include/hermit/tasks_types.h b/hermit/include/hermit/tasks_types.h index 8a5be5365..9c39604c3 100644 --- a/hermit/include/hermit/tasks_types.h +++ b/hermit/include/hermit/tasks_types.h @@ -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;