Skip to content

Commit

Permalink
process/load: Create TLS on interpreted programs
Browse files Browse the repository at this point in the history
JIRA: RTOS-664
  • Loading branch information
badochov committed Oct 6, 2024
1 parent 361a096 commit 8c92309
Show file tree
Hide file tree
Showing 5 changed files with 52 additions and 32 deletions.
4 changes: 2 additions & 2 deletions include/syscalls.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,8 @@
ID(getpid) \
ID(getppid) \
ID(gettid) \
ID(beginthreadex) \
ID(endthread) \
ID(beginthreadexsvc) \
ID(endthreadsvc) \
ID(nsleep) \
ID(phMutexCreate) \
ID(phMutexLock) \
Expand Down
69 changes: 44 additions & 25 deletions proc/process.c
Original file line number Diff line number Diff line change
Expand Up @@ -214,6 +214,8 @@ int proc_start(void (*initthr)(void *), void *arg, const char *path)
process->lazy = 1;
#endif

process->hasInterpreter = 0;

proc_changeMap(process, NULL, NULL, NULL);

/* Initialize resources tree for mutex and cond handles */
Expand Down Expand Up @@ -314,6 +316,7 @@ static void process_tlsAssign(hal_tls_t *process_tls, hal_tls_t *tls, ptr_t tbss
}
process_tls->tdata_sz = tls->tdata_sz;
process_tls->tbss_sz = tls->tbss_sz;
// TODO: Add missing space for linkers additional data.
process_tls->tls_sz = (tls->tbss_sz + tls->tdata_sz + sizeof(void *) + sizeof(void *) - 1) & ~(sizeof(void *) - 1);
process_tls->arm_m_tls = tls->arm_m_tls;
}
Expand Down Expand Up @@ -406,6 +409,25 @@ static int process_validateElf32(void *iehdr, size_t size)
}


static void *process_putauxv(void *stack, struct auxInfo *auxDataBegin, struct auxInfo *auxDataEnd)
{
size_t sz;

auxDataEnd->a_type = AT_PAGESZ;
auxDataEnd->a_v = SIZE_PAGE;
auxDataEnd++;
auxDataEnd->a_type = AT_NULL;
auxDataEnd->a_v = 0;
auxDataEnd++;

sz = ((ptr_t)auxDataEnd - (ptr_t)auxDataBegin);
stack = (char *)stack - SIZE_STACK_ARG(sz);
hal_memcpy(stack, auxDataBegin, sz);

return stack;
}


#ifndef NOMMU


Expand Down Expand Up @@ -790,7 +812,7 @@ int process_doLoadInterpreter32(vm_map_t *map, vm_object_t *o, off_t base, void


/* *interpreterEntry is changed only if interpreter is found and loaded properly. */
int process_loadInterpreter32(vm_map_t *map, vm_object_t *o, off_t base, const void *iehdr, size_t size, void **interpreterEntry, struct auxInfo **auxData)
int process_loadInterpreter32(vm_map_t *map, vm_object_t *o, off_t base, const void *iehdr, size_t size, void **interpreterEntry, struct auxInfo **auxData, int *hasInterpreter)
{
const Elf32_Ehdr *ehdr = iehdr;
int err;
Expand Down Expand Up @@ -835,6 +857,8 @@ int process_loadInterpreter32(vm_map_t *map, vm_object_t *o, off_t base, const v
return err;
}

*hasInterpreter = 1;

(*auxData)->a_type = AT_BASE;
(*auxData)->a_v = (u64)(ptr_t)baseAddr;
(*auxData)++;
Expand Down Expand Up @@ -871,7 +895,7 @@ int process_load(process_t *process, vm_object_t *o, off_t base, size_t size, vo
*entry = (void *)(ptr_t)((Elf32_Ehdr *)ehdr)->e_entry;
err = process_load32(map, o, base, ehdr, size, &ustacksz, &tlsNew, &tbssAddr, auxData);
if (err == 0) {
err = process_loadInterpreter32(map, o, base, ehdr, size, entry, auxData);
err = process_loadInterpreter32(map, o, base, ehdr, size, entry, auxData, &process->hasInterpreter);
}
break;

Expand Down Expand Up @@ -904,25 +928,6 @@ int process_load(process_t *process, vm_object_t *o, off_t base, size_t size, vo
return EOK;
}


static void *process_putauxv(void *stack, struct auxInfo *auxDataBegin, struct auxInfo *auxDataEnd)
{
size_t sz;

auxDataEnd->a_type = AT_PAGESZ;
auxDataEnd->a_v = SIZE_PAGE;
auxDataEnd++;
auxDataEnd->a_type = AT_NULL;
auxDataEnd->a_v = 0;
auxDataEnd++;

sz = ((ptr_t)auxDataEnd - (ptr_t)auxDataBegin);
stack = (char *)stack - SIZE_STACK_ARG(sz);
hal_memcpy(stack, auxDataBegin, sz);

return stack;
}

#else

struct _reloc {
Expand Down Expand Up @@ -1367,8 +1372,8 @@ static void process_exec(thread_t *current, process_spawn_t *spawn)
hal_spinlockClear(&spawn->sl, &sc);
}

if ((err == EOK) && (current->process->tls.tls_base != NULL)) {
err = process_tlsInit(&current->tls, &current->process->tls, current->process->mapp);
if ((err == EOK) && ((current->process->tls.tls_base != NULL) || (current->process->hasInterpreter != 0))) {
err = process_tlsInit(&current->tls, &current->process->tls, current->process->mapp, current->process->hasInterpreter);
}

if (err != 0) {
Expand Down Expand Up @@ -1971,17 +1976,31 @@ int _process_init(vm_map_t *kmap, vm_object_t *kernel)
}


int process_tlsInit(hal_tls_t *dest, hal_tls_t *source, vm_map_t *map)
int process_tlsInit(hal_tls_t *dest, hal_tls_t *source, vm_map_t *map, int hasInterpreter)
{
int err;
/* FIXME: Hack to add support for dynamic binaries. */
/* Binary may not have any TLS section albeit loaded libraries may use it. */
/* RTLD relies on having enough space for static TLS sections of shared libraries. */
/* Thus free space for it is added. */
size_t freeSpaceBefore, freeSpaceAfter;
if (hasInterpreter == 0) {
freeSpaceAfter = 0;
freeSpaceBefore = 0;
}
else {
freeSpaceAfter = 64;
freeSpaceBefore = SIZE_PAGE / 2;
}
dest->tdata_sz = source->tdata_sz;
dest->tbss_sz = source->tbss_sz;
dest->tls_sz = round_page(source->tls_sz);
dest->tls_sz = round_page(source->tls_sz + freeSpaceBefore + freeSpaceAfter);
dest->arm_m_tls = source->arm_m_tls;

dest->tls_base = (ptr_t)vm_mmap(map, NULL, NULL, dest->tls_sz, PROT_READ | PROT_WRITE | PROT_USER, NULL, 0, MAP_NONE);

if (dest->tls_base != NULL) {
dest->tls_base += freeSpaceBefore;
hal_memcpy((void *)dest->tls_base, (void *)source->tls_base, dest->tdata_sz);
hal_memset((char *)dest->tls_base + dest->tdata_sz, 0, dest->tbss_sz);
/* At the end of TLS there must be a pointer to itself */
Expand Down
3 changes: 2 additions & 1 deletion proc/process.h
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ typedef struct _process_t {

void *got;
hal_tls_t tls;
int hasInterpreter;
} process_t;


Expand Down Expand Up @@ -130,7 +131,7 @@ extern int _process_init(vm_map_t *kmap, vm_object_t *kernel);
extern void process_dumpException(unsigned int n, exc_context_t *exc);


extern int process_tlsInit(hal_tls_t *dest, hal_tls_t *source, vm_map_t *map);
extern int process_tlsInit(hal_tls_t *dest, hal_tls_t *source, vm_map_t *map, int hasInterpreter);


extern int process_tlsDestroy(hal_tls_t *tls, vm_map_t *map);
Expand Down
4 changes: 2 additions & 2 deletions proc/threads.c
Original file line number Diff line number Diff line change
Expand Up @@ -787,8 +787,8 @@ int proc_threadCreate(process_t *process, void (*start)(void *), int *id, unsign
return -ENOMEM;
}

if (process != NULL && (process->tls.tdata_sz != 0 || process->tls.tbss_sz != 0)) {
err = process_tlsInit(&t->tls, &process->tls, process->mapp);
if ((process != NULL) && ((process->tls.tls_base != NULL) || (process->hasInterpreter != 0))) {
err = process_tlsInit(&t->tls, &process->tls, process->mapp, process->hasInterpreter);
if (err != EOK) {
lib_idtreeRemove(&threads_common.id, &t->idlinkage);
vm_kfree(t->kstack);
Expand Down
4 changes: 2 additions & 2 deletions syscalls.c
Original file line number Diff line number Diff line change
Expand Up @@ -285,7 +285,7 @@ int syscalls_gettid(void *ustack)
}


int syscalls_beginthreadex(void *ustack)
int syscalls_beginthreadexsvc(void *ustack)
{
process_t *proc = proc_current()->process;
void (*start)(void *);
Expand Down Expand Up @@ -317,7 +317,7 @@ int syscalls_beginthreadex(void *ustack)
}


int syscalls_endthread(void *ustack)
int syscalls_endthreadsvc(void *ustack)
{
proc_threadEnd();
return EOK;
Expand Down

0 comments on commit 8c92309

Please sign in to comment.