From 5085e91a323072e923f46bad4199e6abd9d12ae7 Mon Sep 17 00:00:00 2001 From: midipix Date: Sat, 25 Apr 2015 10:14:19 -0400 Subject: complete/fix support of ctors/dtors and tls. + do not build libc.so with -DSHARED for the midipix targets. + provide surrogate init/fini arrays that allow invocation of the ctors/dtors iteration routines. + provide a builtin tls for the first thread. + update __copy_tls to match the layout of the simplified struct __tls. signed-off by Z. Gilboa; see copying.midipix (9cd0746c) for additional information. --- arch/nt32/psxglue.h | 2 ++ arch/nt32/src/crt_glue.c | 30 +++++++++++++++++++++++++++--- arch/nt64/psxglue.h | 2 ++ arch/nt64/src/crt_glue.c | 30 +++++++++++++++++++++++++++--- crt/nt32/crti.s | 8 ++++---- crt/nt64/crti.s | 8 ++++---- musl.lzy | 3 ++- src/env/nt32/__init_tls.s | 0 src/env/nt32/__reset_tls.s | 0 src/env/nt64/__init_tls.s | 0 src/env/nt64/__reset_tls.s | 0 src/ldso/nt32/dynlink.c | 12 +++++++----- src/ldso/nt32/start.s | 19 +++++++++++++++++++ src/ldso/nt64/dynlink.c | 12 +++++++----- src/ldso/nt64/start.s | 19 +++++++++++++++++++ 15 files changed, 120 insertions(+), 25 deletions(-) create mode 100644 src/env/nt32/__init_tls.s create mode 100644 src/env/nt32/__reset_tls.s create mode 100644 src/env/nt64/__init_tls.s create mode 100644 src/env/nt64/__reset_tls.s diff --git a/arch/nt32/psxglue.h b/arch/nt32/psxglue.h index 73ad2b0..4910be4 100644 --- a/arch/nt32/psxglue.h +++ b/arch/nt32/psxglue.h @@ -44,6 +44,8 @@ struct __psx_context { unsigned int teb_libc_idx; void * pthread_surrogate_fn; void * pthread_create_fn; + void * do_global_ctors_fn; + void * do_global_dtors_fn; }; struct __tlca { diff --git a/arch/nt32/src/crt_glue.c b/arch/nt32/src/crt_glue.c index abfd1fe..2559348 100644 --- a/arch/nt32/src/crt_glue.c +++ b/arch/nt32/src/crt_glue.c @@ -8,6 +8,9 @@ extern struct __ldso_vtbl * __ldso_vtbl; extern struct __psx_vtbl * __psx_vtbl; +extern void * __init_array_start; +extern void * __fini_array_start; + typedef int __app_main(); typedef int __pthread_surrogate_routine(struct pthread *); @@ -19,6 +22,26 @@ extern int __libc_start_main( int argc, char ** argv); +static struct __tls { + void * pad[16/sizeof(void *)]; + struct pthread pt; +} __builtin_tls = {{0}}; + +void __init_tls (size_t * auxv) +{ + #define T __builtin_tls + + __set_thread_area(&T.pt); + + T.pt.self = &T.pt; + T.pt.locale = &libc.global_locale; + T.pt.tid = __syscall(SYS_set_tid_address, &T.pt.tid); + + libc.can_do_threads = 1; + libc.has_thread_pointer = 1; + libc.tls_size = sizeof(struct __tls); +}; + void __libc_entry_routine( __app_main * __main, __psx_init_routine * __psx_init, @@ -43,9 +66,6 @@ void __libc_entry_routine( else if (envp != argv + (argc + 1)) a_crash(); - /* dso init routines */ - _init(); - /* write once */ __syscall_vtbl = (unsigned long **)ctx.sys_vtbl; __ldso_vtbl = ctx.ldso_vtbl; @@ -53,6 +73,10 @@ void __libc_entry_routine( __teb_sys_idx = ctx.teb_sys_idx; __teb_libc_idx = ctx.teb_libc_idx; + /* surrogate init/fini arrays */ + __init_array_start = ctx.do_global_ctors_fn; + __fini_array_start = ctx.do_global_dtors_fn; + /* enter libc */ __libc_start_main(__main,argc,argv); diff --git a/arch/nt64/psxglue.h b/arch/nt64/psxglue.h index 73ad2b0..4910be4 100644 --- a/arch/nt64/psxglue.h +++ b/arch/nt64/psxglue.h @@ -44,6 +44,8 @@ struct __psx_context { unsigned int teb_libc_idx; void * pthread_surrogate_fn; void * pthread_create_fn; + void * do_global_ctors_fn; + void * do_global_dtors_fn; }; struct __tlca { diff --git a/arch/nt64/src/crt_glue.c b/arch/nt64/src/crt_glue.c index abfd1fe..e621fdc 100644 --- a/arch/nt64/src/crt_glue.c +++ b/arch/nt64/src/crt_glue.c @@ -8,6 +8,9 @@ extern struct __ldso_vtbl * __ldso_vtbl; extern struct __psx_vtbl * __psx_vtbl; +extern void * __init_array_start; +extern void * __fini_array_start; + typedef int __app_main(); typedef int __pthread_surrogate_routine(struct pthread *); @@ -19,6 +22,26 @@ extern int __libc_start_main( int argc, char ** argv); +struct __tls { + void * pad[16/sizeof(void *)]; + struct pthread pt; +} __builtin_tls = {{0}}; + +void __init_tls (size_t * auxv) +{ + #define T __builtin_tls + + __set_thread_area(&T.pt); + + T.pt.self = &T.pt; + T.pt.locale = &libc.global_locale; + T.pt.tid = __syscall(SYS_set_tid_address, &T.pt.tid); + + libc.can_do_threads = 1; + libc.has_thread_pointer = 1; + libc.tls_size = sizeof(struct __tls); +}; + void __libc_entry_routine( __app_main * __main, __psx_init_routine * __psx_init, @@ -43,9 +66,6 @@ void __libc_entry_routine( else if (envp != argv + (argc + 1)) a_crash(); - /* dso init routines */ - _init(); - /* write once */ __syscall_vtbl = (unsigned long **)ctx.sys_vtbl; __ldso_vtbl = ctx.ldso_vtbl; @@ -53,6 +73,10 @@ void __libc_entry_routine( __teb_sys_idx = ctx.teb_sys_idx; __teb_libc_idx = ctx.teb_libc_idx; + /* surrogate init/fini arrays */ + __init_array_start = ctx.do_global_ctors_fn; + __fini_array_start = ctx.do_global_dtors_fn; + /* enter libc */ __libc_start_main(__main,argc,argv); diff --git a/crt/nt32/crti.s b/crt/nt32/crti.s index 7b1a642..1b484b0 100644 --- a/crt/nt32/crti.s +++ b/crt/nt32/crti.s @@ -5,13 +5,11 @@ __pei386_runtime_relocator: .globl __init __init: - call .init - ret + jmp .init .globl __fini __fini: - call .fini - ret + jmp .fini .section .init xor %eax,%eax @@ -39,3 +37,5 @@ __fini: .long 1 .long 0 .long 0 + .long __CTOR_LIST__ + .long __DTOR_LIST__ diff --git a/crt/nt64/crti.s b/crt/nt64/crti.s index 14fdd90..44ecc61 100644 --- a/crt/nt64/crti.s +++ b/crt/nt64/crti.s @@ -5,13 +5,11 @@ _pei386_runtime_relocator: .globl _init _init: - call .init - ret + jmp .init .globl _fini _fini: - call .fini - ret + jmp .fini .section .init xor %rax,%rax @@ -39,3 +37,5 @@ _fini: .long 1 .long 0 .long 0 + .quad __CTOR_LIST__ + .quad __DTOR_LIST__ diff --git a/musl.lzy b/musl.lzy index 9152d04..1261c5f 100644 --- a/musl.lzy +++ b/musl.lzy @@ -19,7 +19,7 @@ lz_project_definitions() musl_empty_lib_names="m rt pthread crypt util xnet resolv dl" musl_cflags_crt="-fPIC" - musl_cflags_shared="-fPIC -DSHARED" + musl_cflags_shared="-fPIC" if [ "$lz_pecoff_winnt"x = yesx ]; then pe_excluded_symbols="__libc_entry_point" @@ -39,6 +39,7 @@ lz_project_definitions() --exclude-symbols=$pe_excluded_symbols" else musl_libc_so_ldflags="-shared -e _start -Bsymbolic-functions" + musl_cflags_shared="$musl_cflags_shared -DSHARED" fi musl_libc_src_dirs="src arch/$lz_arch/src arch/$lz_arch/weak" diff --git a/src/env/nt32/__init_tls.s b/src/env/nt32/__init_tls.s new file mode 100644 index 0000000..e69de29 diff --git a/src/env/nt32/__reset_tls.s b/src/env/nt32/__reset_tls.s new file mode 100644 index 0000000..e69de29 diff --git a/src/env/nt64/__init_tls.s b/src/env/nt64/__init_tls.s new file mode 100644 index 0000000..e69de29 diff --git a/src/env/nt64/__reset_tls.s b/src/env/nt64/__reset_tls.s new file mode 100644 index 0000000..e69de29 diff --git a/src/ldso/nt32/dynlink.c b/src/ldso/nt32/dynlink.c index c3cb23e..edfa4a8 100644 --- a/src/ldso/nt32/dynlink.c +++ b/src/ldso/nt32/dynlink.c @@ -50,13 +50,15 @@ void *__copy_tls(unsigned char * mem) **/ pthread_t td; - void ** dtv; + uintptr_t addr; - dtv = (void **)mem; - dtv[0] = 0; + addr = (uintptr_t)mem; + addr >>= 4; + addr <<= 4; + addr += 16; - td = (void *)(dtv + 1); - td->dtv = dtv; + td = (struct __pthread *)addr; + td->dtv = 0; return td; } diff --git a/src/ldso/nt32/start.s b/src/ldso/nt32/start.s index 32dc52f..d4815dd 100644 --- a/src/ldso/nt32/start.s +++ b/src/ldso/nt32/start.s @@ -1,2 +1,21 @@ # standard dynamic loader is not required # optional dynamic loader [to be] provided by libldso/libpsxscl + +.section .data + +.globl ___init_array_start +.globl ___init_array_end +.globl ___fini_array_start +.globl ___fini_array_end + +___init_array_start: + .long 0 + +___init_array_end: + .long 0 + +___fini_array_start: + .long 0 + +___fini_array_end: + .long 0 diff --git a/src/ldso/nt64/dynlink.c b/src/ldso/nt64/dynlink.c index c3cb23e..edfa4a8 100644 --- a/src/ldso/nt64/dynlink.c +++ b/src/ldso/nt64/dynlink.c @@ -50,13 +50,15 @@ void *__copy_tls(unsigned char * mem) **/ pthread_t td; - void ** dtv; + uintptr_t addr; - dtv = (void **)mem; - dtv[0] = 0; + addr = (uintptr_t)mem; + addr >>= 4; + addr <<= 4; + addr += 16; - td = (void *)(dtv + 1); - td->dtv = dtv; + td = (struct __pthread *)addr; + td->dtv = 0; return td; } diff --git a/src/ldso/nt64/start.s b/src/ldso/nt64/start.s index 32dc52f..e710319 100644 --- a/src/ldso/nt64/start.s +++ b/src/ldso/nt64/start.s @@ -1,2 +1,21 @@ # standard dynamic loader is not required # optional dynamic loader [to be] provided by libldso/libpsxscl + +.section .data + +.globl __init_array_start +.globl __init_array_end +.globl __fini_array_start +.globl __fini_array_end + +__init_array_start: + .quad 0 + +__init_array_end: + .quad 0 + +__fini_array_start: + .quad 0 + +__fini_array_end: + .quad 0 -- cgit v1.2.3