summaryrefslogtreecommitdiffhomepage
path: root/arch
diff options
context:
space:
mode:
Diffstat (limited to 'arch')
-rw-r--r--arch/nt32/psxglue.h2
-rw-r--r--arch/nt32/src/crt_glue.c30
-rw-r--r--arch/nt64/psxglue.h2
-rw-r--r--arch/nt64/src/crt_glue.c30
4 files changed, 58 insertions, 6 deletions
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);