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 Dec 5, 2024
1 parent 83d8c4c commit baa5a58
Show file tree
Hide file tree
Showing 5 changed files with 37 additions and 21 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
43 changes: 29 additions & 14 deletions proc/process.c
Original file line number Diff line number Diff line change
Expand Up @@ -215,6 +215,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 @@ -315,6 +317,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 @@ -564,9 +567,6 @@ int process_load32(vm_map_t *map, vm_object_t *o, off_t base, void *iehdr, size_
}
loadOff = ((Elf32_Addr)(*baseAddr) - loadLow);
*entry = (char *)(*entry) + loadOff;
char dupa[32];
lib_sprintf(dupa, "ENTRY %p %x\n", *entry, loadOff);
hal_consolePrint(ATTR_BOLD, dupa);
}

if (auxData != NULL) {
Expand Down Expand Up @@ -676,7 +676,7 @@ const char *process_getInterpreterPath32(const Elf32_Ehdr *ehdr)


/* *interpreterEntry is changed only if interpreter is found and loaded properly. */
int process_loadInterpreter32(vm_map_t *map, const void *iehdr, void **interpreterEntry, struct auxInfo **auxData)
int process_loadInterpreter32(vm_map_t *map, const void *iehdr, void **interpreterEntry, struct auxInfo **auxData, int *hasInterp)
{
const Elf32_Ehdr *ehdr = iehdr;
int err;
Expand Down Expand Up @@ -725,6 +725,8 @@ int process_loadInterpreter32(vm_map_t *map, const void *iehdr, void **interpret
return err;
}

*hasInterp = 1;

(*auxData)->a_type = AT_BASE;
(*auxData)->a_v = (u64)(ptr_t)baseAddr;
(*auxData)++;
Expand Down Expand Up @@ -781,9 +783,6 @@ int process_load64(vm_map_t *map, vm_object_t *o, off_t base, void *iehdr, size_
}
loadOff = ((Elf64_Addr)(ptr_t)(*baseAddr) - loadLow);
*entry = (char *)(*entry) + loadOff;
char dupa[32];
lib_sprintf(dupa, "ENTRY %p %x\n", *entry, loadOff);
hal_consolePrint(ATTR_BOLD, dupa);
}

if (auxData != NULL) {
Expand Down Expand Up @@ -894,7 +893,7 @@ const char *process_getInterpreterPath64(const Elf64_Ehdr *ehdr)


/* *interpreterEntry is changed only if interpreter is found and loaded properly. */
int process_loadInterpreter64(vm_map_t *map, const void *iehdr, void **interpreterEntry, struct auxInfo **auxData)
int process_loadInterpreter64(vm_map_t *map, const void *iehdr, void **interpreterEntry, struct auxInfo **auxData, int *hasInterp)
{
const Elf64_Ehdr *ehdr = iehdr;
int err;
Expand Down Expand Up @@ -943,6 +942,8 @@ int process_loadInterpreter64(vm_map_t *map, const void *iehdr, void **interpret
return err;
}

*hasInterp = 1;

(*auxData)->a_type = AT_BASE;
(*auxData)->a_v = (u64)(ptr_t)baseAddr;
(*auxData)++;
Expand Down Expand Up @@ -978,14 +979,14 @@ int process_load(process_t *process, vm_object_t *o, off_t base, size_t size, vo
case ELFCLASS32:
err = process_load32(map, o, base, ehdr, size, &ustacksz, &tlsNew, &tbssAddr, entry, NULL, auxData);
if (err == 0) {
err = process_loadInterpreter32(map, ehdr, entry, auxData);
err = process_loadInterpreter32(map, ehdr, entry, auxData, &process->hasInterpreter);
}
break;

case ELFCLASS64:
err = process_load64(map, o, base, ehdr, size, &ustacksz, &tlsNew, &tbssAddr, entry, NULL, auxData);
if (err == 0) {
err = process_loadInterpreter64(map, ehdr, entry, auxData);
err = process_loadInterpreter64(map, ehdr, entry, auxData, &process->hasInterpreter);
}
break;
default:
Expand Down Expand Up @@ -1402,8 +1403,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 @@ -2006,17 +2007,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 @@ -286,7 +286,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 @@ -318,7 +318,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 baa5a58

Please sign in to comment.