diff --git a/hal/armv7a/cpu.c b/hal/armv7a/cpu.c index f42852058..a50f93e77 100644 --- a/hal/armv7a/cpu.c +++ b/hal/armv7a/cpu.c @@ -23,13 +23,11 @@ /* Function creates new cpu context on top of given thread kernel stack */ -int hal_cpuCreateContext(cpu_context_t **nctx, void *start, void *kstack, size_t kstacksz, void *ustack, void *arg, hal_tls_t *tls) +int hal_cpuCreateContext(cpu_context_t **nctx, void *start, void *kstack, size_t kstacksz, void *ustack, void *arg) { cpu_context_t *ctx; int i; - (void)tls; - *nctx = 0; if (kstack == NULL) { return -1; @@ -232,13 +230,19 @@ char *hal_cpuFeatures(char *features, unsigned int len) } -void hal_cpuTlsSet(hal_tls_t *tls, cpu_context_t *ctx) +void hal_cpuTlsSet(ptr_t tlsPtr, ptr_t tlsReg) +{ + (void)tlsReg; + + __asm__ volatile("mcr p15, 0, %[value], cr13, cr0, 3;" ::[value] "r"(tlsPtr)); +} + + +void hal_cpuSetCtxTls(cpu_context_t *ctx, ptr_t tlsPtr) { - /* In theory there should be 8-byte thread control block but - * it's stored elsewhere so we need to subtract 8 from the pointer - */ - ptr_t ptr = tls->tls_base - 8; - __asm__ volatile("mcr p15, 0, %[value], cr13, cr0, 3;" ::[value] "r"(ptr)); + /* TLS pointer is not stored in context */ + (void)ctx; + (void)tlsPtr; } diff --git a/hal/armv7m/cpu.c b/hal/armv7m/cpu.c index aa5617d4a..0f0319c8f 100644 --- a/hal/armv7m/cpu.c +++ b/hal/armv7m/cpu.c @@ -81,12 +81,10 @@ void hal_cpuSetDevBusy(int s) } -int hal_cpuCreateContext(cpu_context_t **nctx, void *start, void *kstack, size_t kstacksz, void *ustack, void *arg, hal_tls_t *tls) +int hal_cpuCreateContext(cpu_context_t **nctx, void *start, void *kstack, size_t kstacksz, void *ustack, void *arg) { cpu_context_t *ctx; - (void)tls; - *nctx = 0; if (kstack == NULL) return -1; @@ -336,8 +334,17 @@ void hal_cpuSmpSync(void) } -/* Not safe to call if TLS is not present (tls_base mustn't be NULL) */ -void hal_cpuTlsSet(hal_tls_t *tls, cpu_context_t *ctx) +void hal_cpuTlsSet(ptr_t tlsPtr, ptr_t tlsReg) +{ + if (tlsReg != NULL) { + *(ptr_t *)tlsReg = tlsPtr; + } +} + + +void hal_cpuSetCtxTls(cpu_context_t *ctx, ptr_t tlsPtr) { - *(ptr_t *)tls->arm_m_tls = tls->tls_base - 8; + /* TLS pointer is not stored in context */ + (void)ctx; + (void)tlsPtr; } diff --git a/hal/armv8m/cpu.c b/hal/armv8m/cpu.c index 587a446c5..5c06291a9 100644 --- a/hal/armv8m/cpu.c +++ b/hal/armv8m/cpu.c @@ -68,12 +68,10 @@ void hal_cpuSetDevBusy(int s) hal_spinlockClear(&cpu_common.busySp, &scp); } -int hal_cpuCreateContext(cpu_context_t **nctx, void *start, void *kstack, size_t kstacksz, void *ustack, void *arg, hal_tls_t *tls) +int hal_cpuCreateContext(cpu_context_t **nctx, void *start, void *kstack, size_t kstacksz, void *ustack, void *arg) { cpu_context_t *ctx; - (void)tls; - *nctx = 0; if (kstack == NULL) { return -1; @@ -285,8 +283,17 @@ void hal_cpuSmpSync(void) } -/* Not safe to call if TLS is not present (tls_base mustn't be NULL) */ -void hal_cpuTlsSet(hal_tls_t *tls, cpu_context_t *ctx) +void hal_cpuTlsSet(ptr_t tlsPtr, ptr_t tlsReg) +{ + if (tlsReg != NULL) { + *(ptr_t *)tlsReg = tlsPtr; + } +} + + +void hal_cpuSetCtxTls(cpu_context_t *ctx, ptr_t tlsPtr) { - *(ptr_t *)tls->arm_m_tls = tls->tls_base - 8; + /* TLS pointer is not stored in context */ + (void)ctx; + (void)tlsPtr; } diff --git a/hal/armv8r/cpu.c b/hal/armv8r/cpu.c index 8a9a3c15a..24775f5ec 100644 --- a/hal/armv8r/cpu.c +++ b/hal/armv8r/cpu.c @@ -25,13 +25,11 @@ extern void _hal_platformInit(void); -int hal_cpuCreateContext(cpu_context_t **nctx, void *start, void *kstack, size_t kstacksz, void *ustack, void *arg, hal_tls_t *tls) +int hal_cpuCreateContext(cpu_context_t **nctx, void *start, void *kstack, size_t kstacksz, void *ustack, void *arg) { cpu_context_t *ctx; int i; - (void)tls; - *nctx = 0; if (kstack == NULL) { return -1; @@ -232,13 +230,19 @@ char *hal_cpuFeatures(char *features, unsigned int len) } -void hal_cpuTlsSet(hal_tls_t *tls, cpu_context_t *ctx) +void hal_cpuTlsSet(ptr_t tlsPtr, ptr_t tlsReg) +{ + (void)tlsReg; + + __asm__ volatile("mcr p15, 0, %[value], cr13, cr0, 3;" ::[value] "r"(tlsPtr)); +} + + +void hal_cpuSetCtxTls(cpu_context_t *ctx, ptr_t tlsPtr) { - /* In theory there should be 8-byte thread control block but - * it's stored elsewhere so we need to subtract 8 from the pointer - */ - ptr_t ptr = tls->tls_base - 8; - __asm__ volatile("mcr p15, 0, %[value], cr13, cr0, 3;" ::[value] "r"(ptr)); + /* TLS pointer is not stored in context */ + (void)ctx; + (void)tlsPtr; } diff --git a/hal/cpu.h b/hal/cpu.h index fe29b5386..a06c4d9cf 100644 --- a/hal/cpu.h +++ b/hal/cpu.h @@ -23,9 +23,6 @@ #include "spinlock.h" -struct _hal_tls_t; - - typedef ptr_t arg_t; @@ -79,7 +76,7 @@ extern void hal_cpuSetGot(void *got); extern void *hal_cpuGetGot(void); -extern int hal_cpuCreateContext(cpu_context_t **nctx, void *start, void *kstack, size_t kstacksz, void *ustack, void *arg, struct _hal_tls_t *tls); +extern int hal_cpuCreateContext(cpu_context_t **nctx, void *start, void *kstack, size_t kstacksz, void *ustack, void *arg); extern int hal_cpuReschedule(struct _spinlock_t *spinlock, spinlock_ctx_t *scp); @@ -139,7 +136,10 @@ extern void hal_cpuSmpSync(void); /* thread local storage */ -extern void hal_cpuTlsSet(struct _hal_tls_t *tls, cpu_context_t *ctx); +extern void hal_cpuTlsSet(ptr_t tlsPtr, ptr_t tlsReg); + + +extern void hal_cpuSetCtxTls(cpu_context_t *ctx, ptr_t tlsPtr); /* cache management */ diff --git a/hal/hal.h b/hal/hal.h index 2976d0a5f..e45402e5a 100644 --- a/hal/hal.h +++ b/hal/hal.h @@ -29,15 +29,6 @@ #include "types.h" -typedef struct _hal_tls_t { - ptr_t tls_base; - ptr_t arm_m_tls; - size_t tdata_sz; - size_t tbss_sz; - size_t tls_sz; -} hal_tls_t; - - extern void *hal_syspageRelocate(void *data); diff --git a/hal/ia32/cpu.c b/hal/ia32/cpu.c index adffe7b37..29f5b55a4 100644 --- a/hal/ia32/cpu.c +++ b/hal/ia32/cpu.c @@ -114,12 +114,10 @@ u32 cpu_getEFLAGS(void) } -int hal_cpuCreateContext(cpu_context_t **nctx, void *start, void *kstack, size_t kstacksz, void *ustack, void *arg, hal_tls_t *tls) +int hal_cpuCreateContext(cpu_context_t **nctx, void *start, void *kstack, size_t kstacksz, void *ustack, void *arg) { cpu_context_t *ctx; - (void)tls; - *nctx = NULL; if (kstack == NULL) { return -EINVAL; @@ -600,11 +598,20 @@ void _hal_cpuInit(void) } -void hal_cpuTlsSet(hal_tls_t *tls, cpu_context_t *ctx) +void hal_cpuTlsSet(ptr_t tlsPtr, ptr_t tlsReg) { - (void)ctx; + (void)tlsReg; + hal_tlbFlushLocal(NULL); - _cpu_gdtInsert(hal_cpuGetTlsIndex(), tls->tls_base + tls->tbss_sz + tls->tdata_sz, VADDR_KERNEL - tls->tls_base + tls->tbss_sz + tls->tdata_sz, DESCR_TLS); + _cpu_gdtInsert(hal_cpuGetTlsIndex(), tlsPtr, VADDR_KERNEL, DESCR_TLS); /* Reload the hidden gs register*/ hal_cpuReloadTlsSegment(); } + + +void hal_cpuSetCtxTls(cpu_context_t *ctx, ptr_t tlsPtr) +{ + /* TLS pointer is not stored in context */ + (void)ctx; + (void)tlsPtr; +} diff --git a/hal/riscv64/cpu.c b/hal/riscv64/cpu.c index 59d516ac3..02ae1c0d8 100644 --- a/hal/riscv64/cpu.c +++ b/hal/riscv64/cpu.c @@ -116,7 +116,7 @@ unsigned int hal_cpuGetFirstBit(unsigned long v) /* context management */ -int hal_cpuCreateContext(cpu_context_t **nctx, void *start, void *kstack, size_t kstacksz, void *ustack, void *arg, hal_tls_t *tls) +int hal_cpuCreateContext(cpu_context_t **nctx, void *start, void *kstack, size_t kstacksz, void *ustack, void *arg) { cpu_context_t *ctx; @@ -178,14 +178,14 @@ int hal_cpuCreateContext(cpu_context_t **nctx, void *start, void *kstack, size_t ctx->sepc = (u64)start; ctx->ksp = (u64)ctx; + ctx->tp = 0; + if (ustack != NULL) { ctx->sp = (u64)ustack; ctx->sstatus = (csr_read(sstatus) | SSTATUS_SPIE | SSTATUS_SUM) & ~SSTATUS_SPP; - ctx->tp = tls->tls_base; } else { ctx->sstatus = csr_read(sstatus) | SSTATUS_SPIE | SSTATUS_SPP; - ctx->tp = 0; } *nctx = ctx; @@ -438,9 +438,15 @@ __attribute__((section(".init"))) void _hal_cpuInit(void) } -void hal_cpuTlsSet(hal_tls_t *tls, cpu_context_t *ctx) +void hal_cpuTlsSet(ptr_t tlsPtr, ptr_t tlsReg) { - (void)ctx; + /* TLS pointer is set during user state restoration, as it's part of cpu context. */ + (void)tlsReg; + (void)tlsPtr; +} - __asm__ volatile("mv tp, %0" ::"r"(tls->tls_base)); + +void hal_cpuSetCtxTls(cpu_context_t *ctx, ptr_t tlsPtr) +{ + ctx->tp = tlsPtr; } diff --git a/hal/sparcv8leon3/cpu.c b/hal/sparcv8leon3/cpu.c index ec8608b0c..c4ffc56e9 100644 --- a/hal/sparcv8leon3/cpu.c +++ b/hal/sparcv8leon3/cpu.c @@ -57,7 +57,7 @@ static const char *hal_cpuGetFpuOption(void) } -int hal_cpuCreateContext(cpu_context_t **nctx, void *start, void *kstack, size_t kstacksz, void *ustack, void *arg, hal_tls_t *tls) +int hal_cpuCreateContext(cpu_context_t **nctx, void *start, void *kstack, size_t kstacksz, void *ustack, void *arg) { cpu_context_t *ctx; cpu_winContext_t *wctx; @@ -82,7 +82,6 @@ int hal_cpuCreateContext(cpu_context_t **nctx, void *start, void *kstack, size_t wctx->fp = (ptr_t)ustack; ctx->psr = (PSR_S | PSR_ET) & (~PSR_CWP); - ctx->g7 = tls->tls_base + tls->tbss_sz + tls->tdata_sz; } else { ctx = (cpu_context_t *)((ptr_t)kstack + kstacksz - sizeof(cpu_context_t) - sizeof(cpu_winContext_t)); @@ -93,7 +92,6 @@ int hal_cpuCreateContext(cpu_context_t **nctx, void *start, void *kstack, size_t wctx->fp = (ptr_t)kstack + kstacksz; /* supervisor mode, enable traps, cwp = 0 */ ctx->psr = (PSR_S | PSR_ET | PSR_PS) & (~PSR_CWP); - ctx->g7 = 0x77777777; } ctx->o0 = (u32)arg; @@ -127,6 +125,7 @@ int hal_cpuCreateContext(cpu_context_t **nctx, void *start, void *kstack, size_t ctx->g4 = 0x44444444; ctx->g5 = 0x55555555; ctx->g6 = 0x66666666; + ctx->g7 = 0x77777777; ctx->sp = (u32)wctx; ctx->savesp = (u32)ctx; @@ -298,9 +297,17 @@ unsigned int hal_cpuGetFirstBit(unsigned long v) } -void hal_cpuTlsSet(hal_tls_t *tls, cpu_context_t *ctx) +void hal_cpuTlsSet(ptr_t tlsPtr, ptr_t tlsReg) { - __asm__ volatile("mov %0, %%g7" ::"r"(tls->tls_base + tls->tbss_sz + tls->tdata_sz)); + /* TLS pointer is set during user state restoration, as it's part of cpu context. */ + (void)tlsReg; + (void)tlsPtr; +} + + +void hal_cpuSetCtxTls(cpu_context_t *ctx, ptr_t tlsPtr) +{ + ctx->g7 = tlsPtr; } diff --git a/include/auxv.h b/include/auxv.h new file mode 100644 index 000000000..fc2d20feb --- /dev/null +++ b/include/auxv.h @@ -0,0 +1,38 @@ +/* + * Phoenix-RTOS + * + * Operating system kernel + * + * Auxiliary vector definitions + * + * Copyright 2024 Phoenix Systems + * Author: Hubert Badocha + * + * This file is part of Phoenix-RTOS. + * + * %LICENSE% + */ + +#ifndef _PHOENIX_AUXV_H_ +#define _PHOENIX_AUXV_H_ + + +#include "types.h" + + +struct auxInfo { + __u32 a_type; /* Type of element. */ + __u64 a_v; /* Value of element. */ +}; + + +#define AT_NULL 0 /* End of auxiliary vector. */ +#define AT_PHDR 1 /* Location of program header table. */ +#define AT_PHENT 2 /* Size of one entry in program header table. */ +#define AT_PHNUM 3 /* Number of entries in program header table. */ + + +#define AUXV_TYPE_COUNT 4 /* Number of auxiliary vector element types. */ + + +#endif diff --git a/proc/elf.h b/include/elf.h similarity index 58% rename from proc/elf.h rename to include/elf.h index e0b8bbbe7..87ed07ff0 100644 --- a/proc/elf.h +++ b/include/elf.h @@ -19,45 +19,47 @@ typedef unsigned short Elf32_Half; -typedef unsigned int Elf32_Word; -typedef unsigned int Elf32_Addr; -typedef unsigned int Elf32_Off; -typedef int Elf32_Sword; - - -typedef u16 Elf64_Half; -typedef u32 Elf64_Word; -typedef u64 Elf64_Addr; -typedef u64 Elf64_Off; -typedef s64 Elf64_Sword; -typedef u64 Elf64_Xword; - - -#define EI_NIDENT 16 - -#define SHT_SYMTAB 2 -#define SHT_STRTAB 3 -#define SHT_NOBITS 8 -#define SHT_REL 9 -#define SHT_DYNSYM 11 -#define SHT_LOPROC 0x70000000 -#define SHT_HIPROC 0x7fffffff -#define SHT_LOUSER 0x80000000 -#define SHT_HIUSER 0xffffffff - -#define STT_LOPROC 13 -#define STT_HIPROC 15 - -#define PT_LOAD 1 -#define PT_DYNAMIC 2 -#define PT_INTERP 3 -#define PT_GNU_STACK 0x6474e551 -#define PT_LOPROC 0x70000000 -#define PT_HIPROC 0x7fffffff - -#define PF_X 0x1 -#define PF_W 0x2 -#define PF_R 0x4 +typedef unsigned int Elf32_Word; +typedef unsigned int Elf32_Addr; +typedef unsigned int Elf32_Off; +typedef int Elf32_Sword; + + +typedef __u16 Elf64_Half; +typedef __u32 Elf64_Word; +typedef __u64 Elf64_Addr; +typedef __u64 Elf64_Off; +typedef __s64 Elf64_Sword; +typedef __u64 Elf64_Xword; + + +#define EI_NIDENT 16 + +#define SHT_SYMTAB 2 +#define SHT_STRTAB 3 +#define SHT_NOBITS 8 +#define SHT_REL 9 +#define SHT_DYNSYM 11 +#define SHT_LOPROC 0x70000000 +#define SHT_HIPROC 0x7fffffff +#define SHT_LOUSER 0x80000000 +#define SHT_HIUSER 0xffffffff + +#define STT_LOPROC 13 +#define STT_HIPROC 15 + +#define PT_LOAD 1 +#define PT_DYNAMIC 2 +#define PT_INTERP 3 +#define PT_PHDR 6 +#define PT_TLS 7 +#define PT_GNU_STACK 0x6474e551 +#define PT_LOPROC 0x70000000 +#define PT_HIPROC 0x7fffffff + +#define PF_X 0x1 +#define PF_W 0x2 +#define PF_R 0x4 #pragma pack(push, 1) @@ -67,8 +69,8 @@ typedef struct { Elf32_Half e_machine; Elf32_Word e_version; Elf32_Addr e_entry; - Elf32_Off e_phoff; - Elf32_Off e_shoff; + Elf32_Off e_phoff; + Elf32_Off e_shoff; Elf32_Word e_flags; Elf32_Half e_hsize; Elf32_Half e_phentsize; @@ -84,7 +86,7 @@ typedef struct { Elf32_Word sh_type; Elf32_Word sh_flags; Elf32_Addr sh_addr; - Elf32_Off sh_offset; + Elf32_Off sh_offset; Elf32_Word sh_size; Elf32_Word sh_link; Elf32_Word sh_info; @@ -95,7 +97,7 @@ typedef struct { typedef struct { Elf32_Word p_type; - Elf32_Off p_offset; + Elf32_Off p_offset; Elf32_Addr p_vaddr; Elf32_Addr p_paddr; Elf32_Word p_filesz; @@ -106,36 +108,36 @@ typedef struct { typedef struct { - u32 st_name; - Elf32_Addr st_value; - u32 st_size; + __u32 st_name; + Elf32_Addr st_value; + __u32 st_size; unsigned char st_info; unsigned char st_other; - u16 st_shndx; + __u16 st_shndx; } Elf32_Sym; typedef struct { Elf32_Addr r_offset; - u32 r_info; + __u32 r_info; } Elf32_Rel; typedef struct { Elf32_Addr r_offset; - u32 r_info; + __u32 r_info; Elf32_Sword r_addend; } Elf32_Rela; typedef struct { - unsigned char e_ident [EI_NIDENT]; + unsigned char e_ident[EI_NIDENT]; Elf64_Half e_type; Elf64_Half e_machine; Elf64_Word e_version; Elf64_Addr e_entry; - Elf64_Off e_phoff; - Elf64_Off e_shoff; + Elf64_Off e_phoff; + Elf64_Off e_shoff; Elf64_Word e_flags; Elf64_Half e_ehsize; Elf64_Half e_phentsize; @@ -147,11 +149,11 @@ typedef struct { typedef struct { - Elf64_Word p_type; - Elf64_Word p_flags; - Elf64_Off p_offset; - Elf64_Addr p_vaddr; - Elf64_Addr p_paddr; + Elf64_Word p_type; + Elf64_Word p_flags; + Elf64_Off p_offset; + Elf64_Addr p_vaddr; + Elf64_Addr p_paddr; Elf64_Xword p_filesz; Elf64_Xword p_memsz; Elf64_Xword p_align; @@ -175,9 +177,9 @@ typedef struct { #pragma pack(pop) -#define ELF32_R_SYM(info) ((info)>>8) -#define ELF32_R_TYPE(info) ((unsigned char)(info)) -#define ELF32_R_INFO(sym, type) (((sym)<<8)+(unsigned char)(type)) +#define ELF32_R_SYM(info) ((info) >> 8) +#define ELF32_R_TYPE(info) ((unsigned char)(info)) +#define ELF32_R_INFO(sym, type) (((sym) << 8) + (unsigned char)(type)) #define R_ARM_ABS32 2 diff --git a/include/syscalls.h b/include/syscalls.h index da0103f05..7be238ec8 100644 --- a/include/syscalls.h +++ b/include/syscalls.h @@ -29,8 +29,8 @@ ID(getpid) \ ID(getppid) \ ID(gettid) \ - ID(beginthreadex) \ - ID(endthread) \ + ID(beginthreadexsvc) \ + ID(endthreadsvc) \ ID(nsleep) \ ID(phMutexCreate) \ ID(phMutexLock) \ @@ -121,5 +121,8 @@ ID(sbi_getchar) \ ID(sigreturn) \ \ - ID(mprotect) + ID(mprotect) \ + \ + ID(tlsSetPtr) \ + ID(tlsSetReg) /* clang-format on */ diff --git a/proc/process.c b/proc/process.c index a3df1f946..1dfba745a 100644 --- a/proc/process.c +++ b/proc/process.c @@ -15,14 +15,15 @@ */ #include "hal/hal.h" +#include "include/auxv.h" #include "include/errno.h" #include "include/signal.h" +#include "include/elf.h" #include "vm/vm.h" #include "lib/lib.h" #include "posix/posix.h" #include "process.h" #include "threads.h" -#include "elf.h" #include "resource.h" #include "name.h" #include "msg.h" @@ -201,11 +202,6 @@ int proc_start(void (*initthr)(void *), void *arg, const char *path) process->sigpend = 0; process->sigmask = 0; process->sighandler = NULL; - process->tls.tls_base = NULL; - process->tls.tbss_sz = 0; - process->tls.tdata_sz = 0; - process->tls.tls_sz = 0; - process->tls.arm_m_tls = NULL; #ifndef NOMMU process->lazy = 0; @@ -213,6 +209,8 @@ int proc_start(void (*initthr)(void *), void *arg, const char *path) process->lazy = 1; #endif + process->tlsReg = NULL; + proc_changeMap(process, NULL, NULL, NULL); /* Initialize resources tree for mutex and cond handles */ @@ -220,7 +218,7 @@ int proc_start(void (*initthr)(void *), void *arg, const char *path) process_alloc(process); perf_fork(process); - if (proc_threadCreate(process, initthr, NULL, 4, SIZE_KSTACK, NULL, 0, (void *)arg) < 0) { + if (proc_threadCreate(process, initthr, NULL, 4, SIZE_KSTACK, NULL, 0, (void *)arg, NULL) < 0) { proc_put(process); return -EINVAL; } @@ -300,24 +298,6 @@ static void process_illegal(unsigned int n, exc_context_t *ctx) } -static void process_tlsAssign(hal_tls_t *process_tls, hal_tls_t *tls, ptr_t tbssAddr) -{ - if (tls->tls_base != NULL) { - process_tls->tls_base = tls->tls_base; - } - else if (tbssAddr != NULL) { - process_tls->tls_base = tbssAddr; - } - else { - process_tls->tls_base = NULL; - } - process_tls->tdata_sz = tls->tdata_sz; - process_tls->tbss_sz = tls->tbss_sz; - 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; -} - - static int process_isPtrValid(void *mapStart, size_t mapSize, void *ptrStart, size_t ptrSize) { void *mapEnd = ((char *)mapStart) + mapSize; @@ -481,44 +461,34 @@ static int process_validateElf64(void *iehdr, size_t size) /* TODO - adding error handling and unmapping of already mapped segments */ -int process_load32(vm_map_t *map, vm_object_t *o, off_t base, void *iehdr, size_t size, size_t *ustacksz, hal_tls_t *tls, ptr_t *tbssAddr) +int process_load32(vm_map_t *map, vm_object_t *o, off_t base, void *iehdr, size_t size, size_t *ustacksz, struct auxInfo **auxData) { void *vaddr; size_t memsz, filesz; Elf32_Ehdr *ehdr = iehdr; Elf32_Phdr *phdr; - Elf32_Shdr *shdr, *shstrshdr; + void *phLoadSegmentStart = NULL; + Elf32_Off phStart, phEnd; + Elf32_Addr phaddr = 0; unsigned i, prot, flags, misalign; off_t offs; - char *snameTab; if (process_validateElf32(iehdr, size) < 0) { return -ENOEXEC; } - shdr = (void *)((char *)ehdr + ehdr->e_shoff); - shstrshdr = shdr + ehdr->e_shstrndx; - snameTab = (char *)ehdr + shstrshdr->sh_offset; - /* Find .tdata and .tbss sections */ - for (i = 0; i < ehdr->e_shnum; i++, shdr++) { - if (hal_strcmp(&snameTab[shdr->sh_name], ".tdata") == 0) { - tls->tls_base = (ptr_t)shdr->sh_addr; - tls->tdata_sz += shdr->sh_size; - } - else if (hal_strcmp(&snameTab[shdr->sh_name], ".tbss") == 0) { - *tbssAddr = (ptr_t)shdr->sh_addr; - tls->tbss_sz += shdr->sh_size; - } - else if (hal_strcmp(&snameTab[shdr->sh_name], "armtls") == 0) { - tls->arm_m_tls = (ptr_t)shdr->sh_addr; - } - } + phStart = ehdr->e_phoff; + phEnd = phStart + (ehdr->e_phentsize * ehdr->e_phnum); for (i = 0, phdr = (void *)ehdr + ehdr->e_phoff; i < ehdr->e_phnum; i++, phdr++) { if ((phdr->p_type == PT_GNU_STACK) && (phdr->p_memsz != 0)) { *ustacksz = round_page(phdr->p_memsz); } + if (phdr->p_type == PT_PHDR) { + phaddr = phdr->p_vaddr; + } + if ((phdr->p_type != PT_LOAD) || (phdr->p_vaddr == 0)) { continue; } @@ -559,49 +529,61 @@ int process_load32(vm_map_t *map, vm_object_t *o, off_t base, void *iehdr, size_ hal_memset(vaddr + filesz, 0, round_page((ptr_t)vaddr + memsz) - ((ptr_t)vaddr + filesz)); } + + if ((phdr->p_offset <= phStart) && (phEnd <= (phdr->p_offset + phdr->p_memsz))) { + phLoadSegmentStart = vaddr; + } + } + + /* PT_PHDR is only present in dynamically linked binaries. Try to augment headers position. */ + if ((phaddr == 0) && (phLoadSegmentStart != NULL)) { + phaddr = (Elf32_Addr)(ptr_t)(((char *)phLoadSegmentStart) + ehdr->e_phoff); + } + + if (phaddr != 0) { + (*auxData)->a_type = AT_PHDR; + (*auxData)->a_v = (u64)phaddr; + (*auxData)++; + (*auxData)->a_type = AT_PHNUM; + (*auxData)->a_v = (u64)ehdr->e_phnum; + (*auxData)++; + (*auxData)->a_type = AT_PHENT; + (*auxData)->a_v = (u64)ehdr->e_phentsize; + (*auxData)++; } + return EOK; } -int process_load64(vm_map_t *map, vm_object_t *o, off_t base, void *iehdr, size_t size, size_t *ustacksz, hal_tls_t *tls, ptr_t *tbssAddr) +int process_load64(vm_map_t *map, vm_object_t *o, off_t base, void *iehdr, size_t size, size_t *ustacksz, struct auxInfo **auxData) { void *vaddr; size_t memsz, filesz; Elf64_Ehdr *ehdr = iehdr; Elf64_Phdr *phdr; - Elf64_Shdr *shdr, *shstrshdr; + void *phLoadSegmentStart = NULL; + Elf64_Off phStart, phEnd; + Elf64_Addr phaddr = 0; unsigned i, prot, flags, misalign; off_t offs; - char *snameTab; if (process_validateElf64(iehdr, size) < 0) { return -ENOEXEC; } - shdr = (void *)((char *)ehdr + ehdr->e_shoff); - shstrshdr = shdr + ehdr->e_shstrndx; - snameTab = (char *)ehdr + shstrshdr->sh_offset; - /* Find .tdata and .tbss sections */ - for (i = 0; i < ehdr->e_shnum; i++, shdr++) { - if (hal_strcmp(&snameTab[shdr->sh_name], ".tdata") == 0) { - tls->tls_base = (ptr_t)shdr->sh_addr; - tls->tdata_sz += shdr->sh_size; - } - else if (hal_strcmp(&snameTab[shdr->sh_name], ".tbss") == 0) { - *tbssAddr = (ptr_t)shdr->sh_addr; - tls->tbss_sz += shdr->sh_size; - } - else if (hal_strcmp(&snameTab[shdr->sh_name], "armtls") == 0) { - tls->arm_m_tls = (ptr_t)shdr->sh_addr; - } - } + phStart = ehdr->e_phoff; + phEnd = phStart + (ehdr->e_phentsize * ehdr->e_phnum); for (i = 0, phdr = (void *)ehdr + ehdr->e_phoff; i < ehdr->e_phnum; i++, phdr++) { if ((phdr->p_type == PT_GNU_STACK) && (phdr->p_memsz != 0)) { *ustacksz = round_page(phdr->p_memsz); } + if (phdr->p_type == PT_PHDR) { + phaddr = phdr->p_vaddr; + } + if ((phdr->p_type != PT_LOAD) || (phdr->p_vaddr == 0)) { continue; } @@ -642,26 +624,40 @@ int process_load64(vm_map_t *map, vm_object_t *o, off_t base, void *iehdr, size_ hal_memset(vaddr + filesz, 0, round_page((ptr_t)vaddr + memsz) - ((ptr_t)vaddr + filesz)); } + + if ((phdr->p_offset <= phStart) && (phEnd <= (phdr->p_offset + phdr->p_memsz))) { + phLoadSegmentStart = vaddr; + } + } + + /* PT_PHDR is only present in dynamically linked binaries. Try to augment headers position. */ + if ((phaddr == 0) && (phLoadSegmentStart != NULL)) { + phaddr = (Elf64_Addr)(ptr_t)(((char *)phLoadSegmentStart) + ehdr->e_phoff); } + + if (phaddr != 0) { + (*auxData)->a_type = AT_PHDR; + (*auxData)->a_v = (u64)phaddr; + (*auxData)++; + (*auxData)->a_type = AT_PHNUM; + (*auxData)->a_v = (u64)ehdr->e_phnum; + (*auxData)++; + (*auxData)->a_type = AT_PHENT; + (*auxData)->a_v = (u64)ehdr->e_phentsize; + (*auxData)++; + } + return EOK; } -int process_load(process_t *process, vm_object_t *o, off_t base, size_t size, void **ustack, void **entry) +int process_load(process_t *process, vm_object_t *o, off_t base, size_t size, void **ustack, void **entry, struct auxInfo **auxData) { void *stack; Elf64_Ehdr *ehdr; vm_map_t *map = process->mapp; size_t ustacksz = SIZE_USTACK; int err = EOK; - hal_tls_t tlsNew; - ptr_t tbssAddr = 0; - - tlsNew.tls_base = NULL; - tlsNew.tdata_sz = 0; - tlsNew.tbss_sz = 0; - tlsNew.tls_sz = 0; - tlsNew.arm_m_tls = NULL; size = round_page(size); @@ -674,13 +670,13 @@ int process_load(process_t *process, vm_object_t *o, off_t base, size_t size, vo /* 32-bit binary */ case 1: *entry = (void *)(ptr_t)((Elf32_Ehdr *)ehdr)->e_entry; - err = process_load32(map, o, base, ehdr, size, &ustacksz, &tlsNew, &tbssAddr); + err = process_load32(map, o, base, ehdr, size, &ustacksz, auxData); break; /* 64-bit binary */ case 2: *entry = (void *)(ptr_t)ehdr->e_entry; - err = process_load64(map, o, base, ehdr, size, &ustacksz, &tlsNew, &tbssAddr); + err = process_load64(map, o, base, ehdr, size, &ustacksz, auxData); break; default: @@ -692,8 +688,6 @@ int process_load(process_t *process, vm_object_t *o, off_t base, size_t size, vo return err; } - process_tlsAssign(&process->tls, &tlsNew, tbssAddr); - /* Allocate and map user stack */ stack = vm_mmap(map, map->pmap.end - ustacksz, NULL, ustacksz, PROT_READ | PROT_WRITE | PROT_USER, NULL, -1, MAP_NONE); if (stack == NULL) { @@ -736,7 +730,7 @@ static int process_relocate(struct _reloc *reloc, size_t relocsz, char **addr) } -int process_load(process_t *process, vm_object_t *o, off_t base, size_t size, void **ustack, void **entry) +int process_load(process_t *process, vm_object_t *o, off_t base, size_t size, void **ustack, void **entry, struct auxInfo **auxData) { void *stack, *paddr; Elf32_Ehdr *ehdr; @@ -749,6 +743,9 @@ int process_load(process_t *process, vm_object_t *o, off_t base, size_t size, vo #else Elf32_Rel *rel; #endif + void *phLoadSegmentStart = NULL; + Elf64_Off phStart, phEnd; + Elf64_Addr phaddr = 0; unsigned prot, flags, reloffs; int i, j, relocsz = 0, reltype, badreloc = 0, err; void *relptr; @@ -756,8 +753,6 @@ int process_load(process_t *process, vm_object_t *o, off_t base, size_t size, vo ptr_t *got; struct _reloc reloc[8]; size_t stacksz = SIZE_USTACK; - hal_tls_t tlsNew; - ptr_t tbssAddr = 0; if (o != VM_OBJ_PHYSMEM) { return -ENOEXEC; @@ -770,6 +765,9 @@ int process_load(process_t *process, vm_object_t *o, off_t base, size_t size, vo return err; } + phStart = ehdr->e_phoff; + phEnd = phStart + (ehdr->e_phentsize * ehdr->e_phnum); + hal_memset(reloc, 0, sizeof(reloc)); for (i = 0, j = 0, phdr = (void *)ehdr + ehdr->e_phoff; i < ehdr->e_phnum; i++, phdr++) { @@ -777,6 +775,10 @@ int process_load(process_t *process, vm_object_t *o, off_t base, size_t size, vo stacksz = round_page(phdr->p_memsz); } + if (phdr->p_type == PT_PHDR) { + phaddr = phdr->p_vaddr; + } + if (phdr->p_type != PT_LOAD) { continue; } @@ -834,6 +836,10 @@ int process_load(process_t *process, vm_object_t *o, off_t base, size_t size, vo return -ENOMEM; } + if ((phdr->p_offset <= phStart) && (phEnd <= (phdr->p_offset + phdr->p_memsz))) { + phLoadSegmentStart = paddr; + } + reloc[j].vbase = (void *)phdr->p_vaddr; reloc[j].pbase = (void *)((char *)paddr + reloffs); reloc[j].size = phdr->p_memsz; @@ -965,37 +971,6 @@ int process_load(process_t *process, vm_object_t *o, off_t base, size_t size, vo } #endif - tlsNew.tls_base = NULL; - tlsNew.tdata_sz = 0; - tlsNew.tbss_sz = 0; - tlsNew.tls_sz = 0; - tlsNew.arm_m_tls = NULL; - - /* Perform .tdata, .tbss and .armtls relocations */ - for (i = 0, shdr = (void *)((char *)ehdr + ehdr->e_shoff); i < ehdr->e_shnum; i++, shdr++) { - if (hal_strcmp(&snameTab[shdr->sh_name], ".tdata") == 0) { - tlsNew.tls_base = (ptr_t)shdr->sh_addr; - tlsNew.tdata_sz += shdr->sh_size; - if (process_relocate(reloc, relocsz, (char **)&tlsNew.tls_base) < 0) { - return -ENOEXEC; - } - } - else if (hal_strcmp(&snameTab[shdr->sh_name], ".tbss") == 0) { - tbssAddr = (ptr_t)shdr->sh_addr; - tlsNew.tbss_sz += shdr->sh_size; - if (process_relocate(reloc, relocsz, (char **)&tbssAddr) < 0) { - return -ENOEXEC; - } - } - else if (hal_strcmp(&snameTab[shdr->sh_name], "armtls") == 0) { - tlsNew.arm_m_tls = (ptr_t)shdr->sh_addr; - if (process_relocate(reloc, relocsz, (char **)&tlsNew.arm_m_tls) < 0) { - return -ENOEXEC; - } - } - } - process_tlsAssign(&process->tls, &tlsNew, tbssAddr); - /* Allocate and map user stack */ stack = vm_mmap(process->mapp, NULL, NULL, stacksz, PROT_READ | PROT_WRITE | PROT_USER, NULL, -1, MAP_NONE); if (stack == NULL) { @@ -1018,6 +993,23 @@ int process_load(process_t *process, vm_object_t *o, off_t base, size_t size, vo lib_printf("Found %d badreloc%c\n", badreloc, (badreloc > 1) ? 's' : ' '); } + /* PT_PHDR is only present in dynamically linked binaries. Try to augment headers position. */ + if ((phaddr == 0) && (phLoadSegmentStart != NULL)) { + phaddr = (Elf32_Addr)(ptr_t)(((char *)phLoadSegmentStart) + ehdr->e_phoff); + } + + if (phaddr != 0) { + (*auxData)->a_type = AT_PHDR; + (*auxData)->a_v = (u64)phaddr; + (*auxData)++; + (*auxData)->a_type = AT_PHNUM; + (*auxData)->a_v = (u64)ehdr->e_phnum; + (*auxData)++; + (*auxData)->a_type = AT_PHENT; + (*auxData)->a_v = (u64)ehdr->e_phentsize; + (*auxData)++; + } + return EOK; } @@ -1055,6 +1047,28 @@ void *proc_copyargs(char **args) } +static struct auxInfo *process_finishAuxv(struct auxInfo *auxDataEnd) +{ + auxDataEnd->a_type = AT_NULL; + auxDataEnd->a_v = 0; + auxDataEnd++; + + return auxDataEnd; +} + + +static void *process_putauxv(void *stack, struct auxInfo *auxDataBegin, struct auxInfo *auxDataEnd) +{ + size_t sz; + + sz = ((ptr_t)auxDataEnd - (ptr_t)auxDataBegin); + stack = (char *)stack - SIZE_STACK_ARG(sz); + hal_memcpy(stack, auxDataBegin, sz); + + return stack; +} + + static void *process_putargs(void *stack, char ***argsp, int *count) { int argc; @@ -1095,6 +1109,8 @@ static void process_exec(thread_t *current, process_spawn_t *spawn) { &count, sizeof(count) }, { &cleanupFn, sizeof(cleanupFn) } }; + struct auxInfo auxData[AUXV_TYPE_COUNT]; + struct auxInfo *auxDataEnd = auxData; current->process->argv = spawn->argv; current->process->envp = spawn->envp; @@ -1124,10 +1140,14 @@ static void process_exec(thread_t *current, process_spawn_t *spawn) pmap_switch(current->process->pmapp); if (err == 0) { - err = process_load(current->process, spawn->object, spawn->offset, spawn->size, &stack, &entry); + err = process_load(current->process, spawn->object, spawn->offset, spawn->size, &stack, &entry, &auxDataEnd); } if (err == 0) { + auxDataEnd = process_finishAuxv(auxDataEnd); + + stack = process_putauxv(stack, auxData, auxDataEnd); + stack = process_putargs(stack, &spawn->envp, &count); stack = process_putargs(stack, &spawn->argv, &count); hal_stackPutArgs(&stack, sizeof(args) / sizeof(args[0]), args); @@ -1145,10 +1165,6 @@ 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(¤t->tls, ¤t->process->tls, current->process->mapp); - } - if (err != 0) { current->process->exit = err; proc_threadEnd(); @@ -1158,10 +1174,6 @@ static void process_exec(thread_t *current, process_spawn_t *spawn) _hal_cpuSetKernelStack(current->kstack + current->kstacksz); hal_cpuSetGot(current->process->got); - if (current->tls.tls_base != NULL) { - hal_cpuTlsSet(¤t->tls, current->context); - } - hal_cpuSmpSync(); hal_jmp(entry, current->kstack + current->kstacksz, stack, 0, NULL); } @@ -1391,8 +1403,8 @@ static void process_vforkThread(void *arg) current->execkstack = current->kstack; current->execdata = spawn; - hal_memcpy(¤t->process->tls, &parent->process->tls, sizeof(hal_tls_t)); - hal_memcpy(¤t->tls, &parent->tls, sizeof(hal_tls_t)); + current->tlsPtr = parent->tlsPtr; + current->process->tlsReg = parent->process->tlsReg; ret = proc_resourcesCopy(parent->process); if (ret < 0) { @@ -1410,10 +1422,6 @@ static void process_vforkThread(void *arg) current->kstack = parent->kstack; _hal_cpuSetKernelStack(current->kstack + current->kstacksz); - if (current->tls.tls_base != NULL) { - hal_cpuTlsSet(¤t->tls, current->context); - } - /* Start execution from parent suspend point */ proc_longjmp(parent->context); @@ -1747,33 +1755,3 @@ int _process_init(vm_map_t *kmap, vm_object_t *kernel) hal_exceptionsSetHandler(EXC_UNDEFINED, process_illegal); return EOK; } - - -int process_tlsInit(hal_tls_t *dest, hal_tls_t *source, vm_map_t *map) -{ - int err; - dest->tdata_sz = source->tdata_sz; - dest->tbss_sz = source->tbss_sz; - dest->tls_sz = round_page(source->tls_sz); - 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) { - 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 */ - *(ptr_t *)((dest->tls_base + dest->tdata_sz + dest->tbss_sz + sizeof(ptr_t) - 1) & ~(sizeof(ptr_t) - 1)) = dest->tls_base + dest->tdata_sz + dest->tbss_sz; - err = EOK; - } - else { - err = -ENOMEM; - } - return err; -} - - -int process_tlsDestroy(hal_tls_t *tls, vm_map_t *map) -{ - return vm_munmap(map, (void *)tls->tls_base, tls->tls_sz); -} diff --git a/proc/process.h b/proc/process.h index c0c881ae3..dc7bfe458 100644 --- a/proc/process.h +++ b/proc/process.h @@ -69,7 +69,8 @@ typedef struct _process_t { void *sighandler; void *got; - hal_tls_t tls; + + ptr_t tlsReg; } process_t; @@ -130,10 +131,4 @@ 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_tlsDestroy(hal_tls_t *tls, vm_map_t *map); - - #endif diff --git a/proc/threads.c b/proc/threads.c index 1b9280c9d..bcb442131 100644 --- a/proc/threads.c +++ b/proc/threads.c @@ -635,8 +635,8 @@ int _threads_schedule(unsigned int n, cpu_context_t *context, void *arg) selected->longjmpctx = NULL; } - if (selected->tls.tls_base != NULL) { - hal_cpuTlsSet(&selected->tls, selCtx); + if (selected->process != NULL) { + hal_cpuTlsSet(selected->tlsPtr, selected->process->tlsReg); } _perf_scheduling(selected); @@ -737,11 +737,10 @@ void threads_canaryInit(thread_t *t, void *ustack) } -int proc_threadCreate(process_t *process, void (*start)(void *), int *id, unsigned int priority, size_t kstacksz, void *stack, size_t stacksz, void *arg) +int proc_threadCreate(process_t *process, void (*start)(void *), int *id, unsigned int priority, size_t kstacksz, void *stack, size_t stacksz, void *arg, void *tls) { thread_t *t; spinlock_ctx_t sc; - int err; if (priority >= sizeof(threads_common.ready) / sizeof(thread_t *)) { return -EINVAL; @@ -787,31 +786,19 @@ 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 (err != EOK) { - lib_idtreeRemove(&threads_common.id, &t->idlinkage); - vm_kfree(t->kstack); - vm_kfree(t); - return err; - } - } - else { - t->tls.tls_base = NULL; - t->tls.tdata_sz = 0; - t->tls.tbss_sz = 0; - t->tls.tls_sz = 0; - t->tls.arm_m_tls = NULL; - } - if (id != NULL) { *id = proc_getTid(t); } /* Prepare initial stack */ - hal_cpuCreateContext(&t->context, start, t->kstack, t->kstacksz, (stack == NULL) ? NULL : (unsigned char *)stack + stacksz, arg, &t->tls); + hal_cpuCreateContext(&t->context, start, t->kstack, t->kstacksz, (stack == NULL) ? NULL : (unsigned char *)stack + stacksz, arg); threads_canaryInit(t, stack); + if (tls != NULL) { + t->tlsPtr = (ptr_t)tls; + hal_cpuSetCtxTls(t->context, t->tlsPtr); + } + if (process != NULL) { hal_cpuSetCtxGot(t->context, process->got); hal_spinlockSet(&threads_common.spinlock, &sc); @@ -1000,6 +987,36 @@ void proc_threadsDestroy(thread_t **threads) } +void proc_tlsSetPtr(void *tlsPtr) +{ + thread_t *t; + void *kstackTop; + cpu_context_t *ctx; + + t = proc_current(); + + kstackTop = t->kstack + t->kstacksz; + ctx = kstackTop - sizeof(cpu_context_t); + + t->tlsPtr = (ptr_t)tlsPtr; + + hal_cpuTlsSet(t->tlsPtr, t->process->tlsReg); + hal_cpuSetCtxTls(ctx, t->tlsPtr); +} + + +void proc_tlsSetReg(void *tlsReg) +{ + thread_t *t; + + t = proc_current(); + + t->process->tlsReg = (ptr_t)tlsReg; + + hal_cpuTlsSet(t->tlsPtr, t->process->tlsReg); +} + + void proc_reap(void) { thread_t *ghost; @@ -1325,10 +1342,6 @@ int proc_join(int tid, time_t timeout) } hal_spinlockClear(&threads_common.spinlock, &sc); - if ((ghost != NULL) && (ghost->tls.tls_sz != 0)) { - process_tlsDestroy(&ghost->tls, process->mapp); - } - vm_kfree(ghost); return err < 0 ? err : id; } @@ -2056,7 +2069,7 @@ int _threads_init(vm_map_t *kmap, vm_object_t *kernel) /* Run idle thread on every cpu */ for (i = 0; i < hal_cpuGetCount(); i++) { threads_common.current[i] = NULL; - proc_threadCreate(NULL, threads_idlethr, NULL, sizeof(threads_common.ready) / sizeof(thread_t *) - 1, SIZE_KSTACK, NULL, 0, NULL); + proc_threadCreate(NULL, threads_idlethr, NULL, sizeof(threads_common.ready) / sizeof(thread_t *) - 1, SIZE_KSTACK, NULL, 0, NULL, NULL); } /* Install scheduler on clock interrupt */ diff --git a/proc/threads.h b/proc/threads.h index f98206f7b..4bb8883f2 100644 --- a/proc/threads.h +++ b/proc/threads.h @@ -70,7 +70,7 @@ typedef struct _thread_t { size_t kstacksz; char *ustack; - hal_tls_t tls; + ptr_t tlsPtr; /* for vfork/exec */ void *parentkstack, *execkstack; @@ -118,7 +118,7 @@ extern thread_t *proc_current(void); extern void threads_canaryInit(thread_t *t, void *ustack); -extern int proc_threadCreate(process_t *process, void (*start)(void *), int *id, unsigned int priority, size_t kstacksz, void *stack, size_t stacksz, void *arg); +extern int proc_threadCreate(process_t *process, void (*start)(void *), int *id, unsigned int priority, size_t kstacksz, void *stack, size_t stacksz, void *arg, void *tls); extern int proc_threadPriority(int priority); @@ -178,6 +178,12 @@ extern int proc_threadBroadcast(thread_t **queue); extern void proc_threadBroadcastYield(thread_t **queue); +extern void proc_tlsSetPtr(void *tlsPtr); + + +extern void proc_tlsSetReg(void *tlsReg); + + extern int threads_getCpuTime(thread_t *t); diff --git a/syscalls.c b/syscalls.c index fc991c893..704cdcec3 100644 --- a/syscalls.c +++ b/syscalls.c @@ -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 *); @@ -293,6 +293,7 @@ int syscalls_beginthreadex(void *ustack) void *stack, *arg; int *id; int err; + void *tls; GETFROMSTACK(ustack, void *, start, 0); GETFROMSTACK(ustack, unsigned int, priority, 1); @@ -300,6 +301,7 @@ int syscalls_beginthreadex(void *ustack) GETFROMSTACK(ustack, unsigned int, stacksz, 3); GETFROMSTACK(ustack, void *, arg, 4); GETFROMSTACK(ustack, int *, id, 5); + GETFROMSTACK(ustack, void *, tls, 6); if ((id != NULL) && (vm_mapBelongs(proc, id, sizeof(*id)) < 0)) { return -EFAULT; @@ -307,7 +309,7 @@ int syscalls_beginthreadex(void *ustack) proc_get(proc); - err = proc_threadCreate(proc, start, id, priority, SIZE_KSTACK, stack, stacksz, arg); + err = proc_threadCreate(proc, start, id, priority, SIZE_KSTACK, stack, stacksz, arg, tls); if (err < 0) { proc_put(proc); @@ -317,10 +319,29 @@ int syscalls_beginthreadex(void *ustack) } -int syscalls_endthread(void *ustack) +void syscalls_endthreadsvc(void *ustack) { proc_threadEnd(); - return EOK; +} + + +void syscalls_tlsSetPtr(void *ustack) +{ + void *tlsPtr; + + GETFROMSTACK(ustack, void *, tlsPtr, 0); + + proc_tlsSetPtr(tlsPtr); +} + + +void syscalls_tlsSetReg(void *ustack) +{ + void *tlsReg; + + GETFROMSTACK(ustack, void *, tlsReg, 0); + + proc_tlsSetReg(tlsReg); } diff --git a/test/msg.c b/test/msg.c index 722ed9245..2d96f74a4 100644 --- a/test/msg.c +++ b/test/msg.c @@ -162,6 +162,6 @@ void test_msg(void) hal_cpuHalt(); } - proc_threadCreate(NULL, test_pong, NULL, 4, 1024, NULL, 0, (void *)(long)port); - proc_threadCreate(NULL, test_ping, NULL, 4, 1024, NULL, 0, (void *)(long)port); + proc_threadCreate(NULL, test_pong, NULL, 4, 1024, NULL, 0, (void *)(long)port, NULL); + proc_threadCreate(NULL, test_ping, NULL, 4, 1024, NULL, 0, (void *)(long)port, NULL); } diff --git a/test/proc.c b/test/proc.c index 08734204f..a7b75e3e0 100644 --- a/test/proc.c +++ b/test/proc.c @@ -114,16 +114,16 @@ void test_proc_threads1(void) for (i = 0; i < 8; i++) test_proc_common.rotations[i] = 0; - proc_threadCreate(NULL, test_proc_indthr, NULL, 0, stacksz, NULL, 0, NULL); - proc_threadCreate(NULL, test_proc_rotthr1, NULL, 1, stacksz, NULL, 0, (void *)1); - proc_threadCreate(NULL, test_proc_rotthr1, NULL, 2, stacksz, NULL, 0, (void *)2); - proc_threadCreate(NULL, test_proc_rotthr1, NULL, 3, stacksz, NULL, 0, (void *)3); - proc_threadCreate(NULL, test_proc_rotthr1, NULL, 4, stacksz, NULL, 0, (void *)4); - proc_threadCreate(NULL, test_proc_rotthr1, NULL, 5, stacksz, NULL, 0, (void *)5); - proc_threadCreate(NULL, test_proc_rotthr1, NULL, 6, stacksz, NULL, 0, (void *)6); - proc_threadCreate(NULL, test_proc_rotthr1, NULL, 7, stacksz, NULL, 0, (void *)7); - - proc_threadCreate(NULL, test_proc_busythr, NULL, 4, 1024, NULL, 0, NULL); + proc_threadCreate(NULL, test_proc_indthr, NULL, 0, stacksz, NULL, 0, NULL, NULL); + proc_threadCreate(NULL, test_proc_rotthr1, NULL, 1, stacksz, NULL, 0, (void *)1, NULL); + proc_threadCreate(NULL, test_proc_rotthr1, NULL, 2, stacksz, NULL, 0, (void *)2, NULL); + proc_threadCreate(NULL, test_proc_rotthr1, NULL, 3, stacksz, NULL, 0, (void *)3, NULL); + proc_threadCreate(NULL, test_proc_rotthr1, NULL, 4, stacksz, NULL, 0, (void *)4, NULL); + proc_threadCreate(NULL, test_proc_rotthr1, NULL, 5, stacksz, NULL, 0, (void *)5, NULL); + proc_threadCreate(NULL, test_proc_rotthr1, NULL, 6, stacksz, NULL, 0, (void *)6, NULL); + proc_threadCreate(NULL, test_proc_rotthr1, NULL, 7, stacksz, NULL, 0, (void *)7, NULL); + + proc_threadCreate(NULL, test_proc_busythr, NULL, 4, 1024, NULL, 0, NULL, NULL); } @@ -166,13 +166,13 @@ void test_proc_threads2(void) test_proc_common.queue = NULL; hal_spinlockCreate(&test_proc_common.spinlock, "test_proc_common.spinlock"); - proc_threadCreate(NULL, test_proc_indthr, NULL, 0, 1024, NULL, 0, NULL); - proc_threadCreate(NULL, test_proc_timethr, NULL, 0, 1024, NULL, 0, NULL); + proc_threadCreate(NULL, test_proc_indthr, NULL, 0, 1024, NULL, 0, NULL, NULL); + proc_threadCreate(NULL, test_proc_timethr, NULL, 0, 1024, NULL, 0, NULL, NULL); - proc_threadCreate(NULL, test_proc_rotthr2, NULL, 1, 1024, NULL, 0, (void *)1); - proc_threadCreate(NULL, test_proc_rotthr2, NULL, 2, 1024, NULL, 0, (void *)2); - proc_threadCreate(NULL, test_proc_rotthr2, NULL, 3, 1024, NULL, 0, (void *)3); - proc_threadCreate(NULL, test_proc_rotthr2, NULL, 4, 1024, NULL, 0, (void *)4); + proc_threadCreate(NULL, test_proc_rotthr2, NULL, 1, 1024, NULL, 0, (void *)1, NULL); + proc_threadCreate(NULL, test_proc_rotthr2, NULL, 2, 1024, NULL, 0, (void *)2, NULL); + proc_threadCreate(NULL, test_proc_rotthr2, NULL, 3, 1024, NULL, 0, (void *)3, NULL); + proc_threadCreate(NULL, test_proc_rotthr2, NULL, 4, 1024, NULL, 0, (void *)4, NULL); } diff --git a/test/rb.c b/test/rb.c index 4ef6737a9..2d8bef633 100644 --- a/test/rb.c +++ b/test/rb.c @@ -182,5 +182,5 @@ static void test_rb_autothr(void *arg) void test_rb(void) { - proc_threadCreate(NULL, test_rb_autothr, NULL, 1, 512, NULL, 0, NULL); + proc_threadCreate(NULL, test_rb_autothr, NULL, 1, 512, NULL, 0, NULL, NULL); } diff --git a/test/vm.c b/test/vm.c index 5d9bd6125..bcffb96ad 100644 --- a/test/vm.c +++ b/test/vm.c @@ -232,8 +232,8 @@ void test_vm_kmallocsim(void) unsigned int i; proc_lockInit(&lock, &proc_lockAttrDefault, "kmalloc.sim"); - proc_threadCreate(0, _test_vm_upgrsimthr, NULL, 0, 512, 0, 0, 0); + proc_threadCreate(0, _test_vm_upgrsimthr, NULL, 0, 512, 0, 0, 0, NULL); for (i = 0; i < 16; i++) - proc_threadCreate(0, _test_vm_msgsimthr, NULL, 0, 512, 0, 0, 0); + proc_threadCreate(0, _test_vm_msgsimthr, NULL, 0, 512, 0, 0, 0, NULL); } diff --git a/usrv.c b/usrv.c index 80f86f6ac..dbfb50234 100644 --- a/usrv.c +++ b/usrv.c @@ -66,7 +66,7 @@ void _usrv_start(void) return; } - proc_threadCreate(NULL, usrv_msgthr, NULL, 4, 2048, NULL, 0, NULL); + proc_threadCreate(NULL, usrv_msgthr, NULL, 4, 2048, NULL, 0, NULL, NULL); }