summaryrefslogtreecommitdiffhomepage
path: root/src/arch
diff options
context:
space:
mode:
Diffstat (limited to 'src/arch')
-rw-r--r--src/arch/nt32/_dlstart.c10
-rw-r--r--src/arch/nt32/chelper.c0
-rw-r--r--src/arch/nt32/crt_glue.c124
-rw-r--r--src/arch/nt32/crt_pe.c7
-rw-r--r--src/arch/nt32/crt_tls.c24
-rw-r--r--src/arch/nt32/nt32/chelper.S20
-rw-r--r--src/arch/nt32/syscall_disp.c23
-rw-r--r--src/arch/nt32/vtbl.c25
-rw-r--r--src/arch/nt64/_dlstart.c10
-rw-r--r--src/arch/nt64/crt_glue.c124
-rw-r--r--src/arch/nt64/crt_pe.c7
-rw-r--r--src/arch/nt64/crt_tls.c24
-rw-r--r--src/arch/nt64/syscall_disp.c23
-rw-r--r--src/arch/nt64/vtbl.c25
14 files changed, 446 insertions, 0 deletions
diff --git a/src/arch/nt32/_dlstart.c b/src/arch/nt32/_dlstart.c
new file mode 100644
index 0000000..2cfbcbf
--- /dev/null
+++ b/src/arch/nt32/_dlstart.c
@@ -0,0 +1,10 @@
+typedef unsigned int uint32_t;
+
+int dlstart(
+ void * hinstance,
+ uint32_t reason,
+ void * reserved)
+{
+ return 1;
+}
+
diff --git a/src/arch/nt32/chelper.c b/src/arch/nt32/chelper.c
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/src/arch/nt32/chelper.c
diff --git a/src/arch/nt32/crt_glue.c b/src/arch/nt32/crt_glue.c
new file mode 100644
index 0000000..c5af4b0
--- /dev/null
+++ b/src/arch/nt32/crt_glue.c
@@ -0,0 +1,124 @@
+#include <unistd.h>
+#include <stdint.h>
+#include <pthread.h>
+#include "atomic.h"
+#include "syscall.h"
+#include "psxglue.h"
+#include "pthread_impl.h"
+
+extern const struct __ldso_vtbl * __ldso_vtbl;
+extern const struct __psx_vtbl * __psx_vtbl;
+
+typedef int __app_main();
+typedef int __pthread_surrogate_routine(struct pthread *);
+
+static int __pthread_surrogate_init(struct pthread * self);
+
+extern int __libc_start_main(
+ void * main,
+ int argc,
+ char ** argv);
+
+static void (*__global_ctors_fn)();
+static void (*__global_dtors_fn)();
+
+void _init()
+{
+ __global_ctors_fn();
+}
+
+void _fini()
+{
+ __global_dtors_fn();
+}
+
+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.tls_size = sizeof(struct __tls);
+};
+
+void __libc_entry_routine(
+ __app_main * __main,
+ __psx_init_routine * __psx_init,
+ const unsigned short * __ctty,
+ int options)
+{
+ int argc;
+ char ** argv;
+ char ** envp;
+ struct __psx_context ctx;
+
+ /* ctx init */
+ ctx.size = sizeof(ctx);
+ ctx.options = options;
+ ctx.refaddr = __main;
+ ctx.libcaddr = _init;
+ ctx.ctty = __ctty;
+ ctx.pthread_create_fn = pthread_create;
+ ctx.pthread_surrogate_fn= __pthread_surrogate_init;
+
+ /* __psx_init must succeed... */
+ if (__psx_init(&argc,&argv,&envp,&ctx))
+ a_crash();
+
+ /* ...and conform */
+ else if (envp != argv + (argc + 1))
+ a_crash();
+
+ /* write once */
+ __syscall_vtbl = (unsigned long **)ctx.sys_vtbl;
+ __ldso_vtbl = ctx.ldso_vtbl;
+ __psx_vtbl = ctx.psx_vtbl;
+ __teb_sys_idx = ctx.teb_sys_idx;
+ __teb_libc_idx = ctx.teb_libc_idx;
+
+ /* surrogate init/fini arrays */
+ __global_ctors_fn = __psx_vtbl->do_global_ctors_fn;
+ __global_dtors_fn = __psx_vtbl->do_global_dtors_fn;
+
+ /* enter libc */
+ __psx_vtbl->start_main(__main,argc,argv,__libc_start_main);
+
+ /* guard */
+ a_crash();
+}
+
+static int __pthread_surrogate_init(struct pthread * self)
+{
+ /**
+ * invoked by psxscl upon creation of a surrogate libc
+ * thread, which in turn may only call pthread_create();
+ *
+ * the purpose of this mecahnism is to support a scenario
+ * where a third-party library creates a non-posix thread
+ * which then calls, be it directly or via a callback
+ * function, a libc api that depends on a valid
+ * pthread_self.
+ *
+ * self: a pointer to an already zero'ed memory page
+ *
+ * struct pthread relevant members:
+ * --------------------------------
+ * cancel (already zero)
+ * canary (already zero)
+ *
+ * pthread_create() reference:
+ * 1a47ed15eebf96d0c8d5de4aea54108bc8cc3f53
+ **/
+
+ return 0;
+}
diff --git a/src/arch/nt32/crt_pe.c b/src/arch/nt32/crt_pe.c
new file mode 100644
index 0000000..0dc75a4
--- /dev/null
+++ b/src/arch/nt32/crt_pe.c
@@ -0,0 +1,7 @@
+#include "pthread_impl.h"
+#include <threads.h>
+
+void * __pthread_getspecific_impl(pthread_key_t k)
+{
+ return (__pthread_self())->tsd[k];
+}
diff --git a/src/arch/nt32/crt_tls.c b/src/arch/nt32/crt_tls.c
new file mode 100644
index 0000000..20080c6
--- /dev/null
+++ b/src/arch/nt32/crt_tls.c
@@ -0,0 +1,24 @@
+#include <unistd.h>
+#include <stdint.h>
+#include <stddef.h>
+#include "psxglue.h"
+#include "pthread_arch.h"
+
+typedef unsigned int __tls_word __attribute__((mode(word)));
+typedef unsigned int __tls_ptr __attribute__((mode(pointer)));
+
+struct __emutls_object
+{
+ __tls_word size;
+ __tls_word align;
+ ptrdiff_t offset;
+ void * defval;
+};
+
+void * __emutls_get_address (struct __emutls_object * obj)
+{
+ int dsoidx = obj->align & 0xFFFF0000;
+ struct __tlca_abi * tlca = (struct __tlca_abi *)__psx_tlca();
+ return tlca->pthread_dtls[dsoidx >> 16] + obj->offset;
+}
+
diff --git a/src/arch/nt32/nt32/chelper.S b/src/arch/nt32/nt32/chelper.S
new file mode 100644
index 0000000..6d6a52b
--- /dev/null
+++ b/src/arch/nt32/nt32/chelper.S
@@ -0,0 +1,20 @@
+#ifdef LIBC_NO_COMPLEX
+
+.globl ___udivdi3
+.globl ___umoddi3
+.globl ___divdi3
+.globl ___moddi3
+
+___udivdi3:
+ ret
+
+___umoddi3:
+ ret
+
+___divdi3:
+ ret
+
+___moddi3:
+ ret
+
+#endif
diff --git a/src/arch/nt32/syscall_disp.c b/src/arch/nt32/syscall_disp.c
new file mode 100644
index 0000000..9ea5966
--- /dev/null
+++ b/src/arch/nt32/syscall_disp.c
@@ -0,0 +1,23 @@
+#include <unistd.h>
+#include <stdint.h>
+#include <stddef.h>
+#include "syscall.h"
+#include "psxglue.h"
+
+extern struct __psx_vtbl * __psx_vtbl;
+
+void __unmapself(void * base, size_t size)
+{
+ __psx_vtbl->unmapself(base,(void *)size);
+}
+
+uintptr_t __syscall_disp(long n,
+ uintptr_t a1,
+ uintptr_t a2,
+ uintptr_t a3,
+ uintptr_t a4,
+ uintptr_t a5,
+ uintptr_t a6)
+{
+ return __syscall(n,a1,a2,a3,a4,a5,a6);
+}
diff --git a/src/arch/nt32/vtbl.c b/src/arch/nt32/vtbl.c
new file mode 100644
index 0000000..f21ce17
--- /dev/null
+++ b/src/arch/nt32/vtbl.c
@@ -0,0 +1,25 @@
+#include <unistd.h>
+#include <stdint.h>
+#include "psxglue.h"
+#include "errno.h"
+
+const struct __ldso_vtbl * __ldso_vtbl = 0;
+const struct __psx_vtbl * __psx_vtbl = 0;
+unsigned long ** __syscall_vtbl = 0;
+unsigned long __teb_sys_idx = 0;
+unsigned long __teb_libc_idx = 0;
+
+long __syscall_alert(long n)
+{
+ char __lmsg[] = "DING ALARM! UNIMPLEMENTED SYSCALL 000\n";
+
+ __lmsg[36] = '0' + n % 10; n /= 10;
+ __lmsg[35] = '0' + n % 10; n /= 10;
+ __lmsg[34] = '0' + n % 10;
+
+ __psx_vtbl->log_output(
+ __lmsg,
+ sizeof(__lmsg));
+
+ return -ENOSYS;
+}
diff --git a/src/arch/nt64/_dlstart.c b/src/arch/nt64/_dlstart.c
new file mode 100644
index 0000000..40498da
--- /dev/null
+++ b/src/arch/nt64/_dlstart.c
@@ -0,0 +1,10 @@
+typedef unsigned int uint32_t;
+
+int _dlstart(
+ void * hinstance,
+ uint32_t reason,
+ void * reserved)
+{
+ return 1;
+}
+
diff --git a/src/arch/nt64/crt_glue.c b/src/arch/nt64/crt_glue.c
new file mode 100644
index 0000000..c5af4b0
--- /dev/null
+++ b/src/arch/nt64/crt_glue.c
@@ -0,0 +1,124 @@
+#include <unistd.h>
+#include <stdint.h>
+#include <pthread.h>
+#include "atomic.h"
+#include "syscall.h"
+#include "psxglue.h"
+#include "pthread_impl.h"
+
+extern const struct __ldso_vtbl * __ldso_vtbl;
+extern const struct __psx_vtbl * __psx_vtbl;
+
+typedef int __app_main();
+typedef int __pthread_surrogate_routine(struct pthread *);
+
+static int __pthread_surrogate_init(struct pthread * self);
+
+extern int __libc_start_main(
+ void * main,
+ int argc,
+ char ** argv);
+
+static void (*__global_ctors_fn)();
+static void (*__global_dtors_fn)();
+
+void _init()
+{
+ __global_ctors_fn();
+}
+
+void _fini()
+{
+ __global_dtors_fn();
+}
+
+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.tls_size = sizeof(struct __tls);
+};
+
+void __libc_entry_routine(
+ __app_main * __main,
+ __psx_init_routine * __psx_init,
+ const unsigned short * __ctty,
+ int options)
+{
+ int argc;
+ char ** argv;
+ char ** envp;
+ struct __psx_context ctx;
+
+ /* ctx init */
+ ctx.size = sizeof(ctx);
+ ctx.options = options;
+ ctx.refaddr = __main;
+ ctx.libcaddr = _init;
+ ctx.ctty = __ctty;
+ ctx.pthread_create_fn = pthread_create;
+ ctx.pthread_surrogate_fn= __pthread_surrogate_init;
+
+ /* __psx_init must succeed... */
+ if (__psx_init(&argc,&argv,&envp,&ctx))
+ a_crash();
+
+ /* ...and conform */
+ else if (envp != argv + (argc + 1))
+ a_crash();
+
+ /* write once */
+ __syscall_vtbl = (unsigned long **)ctx.sys_vtbl;
+ __ldso_vtbl = ctx.ldso_vtbl;
+ __psx_vtbl = ctx.psx_vtbl;
+ __teb_sys_idx = ctx.teb_sys_idx;
+ __teb_libc_idx = ctx.teb_libc_idx;
+
+ /* surrogate init/fini arrays */
+ __global_ctors_fn = __psx_vtbl->do_global_ctors_fn;
+ __global_dtors_fn = __psx_vtbl->do_global_dtors_fn;
+
+ /* enter libc */
+ __psx_vtbl->start_main(__main,argc,argv,__libc_start_main);
+
+ /* guard */
+ a_crash();
+}
+
+static int __pthread_surrogate_init(struct pthread * self)
+{
+ /**
+ * invoked by psxscl upon creation of a surrogate libc
+ * thread, which in turn may only call pthread_create();
+ *
+ * the purpose of this mecahnism is to support a scenario
+ * where a third-party library creates a non-posix thread
+ * which then calls, be it directly or via a callback
+ * function, a libc api that depends on a valid
+ * pthread_self.
+ *
+ * self: a pointer to an already zero'ed memory page
+ *
+ * struct pthread relevant members:
+ * --------------------------------
+ * cancel (already zero)
+ * canary (already zero)
+ *
+ * pthread_create() reference:
+ * 1a47ed15eebf96d0c8d5de4aea54108bc8cc3f53
+ **/
+
+ return 0;
+}
diff --git a/src/arch/nt64/crt_pe.c b/src/arch/nt64/crt_pe.c
new file mode 100644
index 0000000..0dc75a4
--- /dev/null
+++ b/src/arch/nt64/crt_pe.c
@@ -0,0 +1,7 @@
+#include "pthread_impl.h"
+#include <threads.h>
+
+void * __pthread_getspecific_impl(pthread_key_t k)
+{
+ return (__pthread_self())->tsd[k];
+}
diff --git a/src/arch/nt64/crt_tls.c b/src/arch/nt64/crt_tls.c
new file mode 100644
index 0000000..20080c6
--- /dev/null
+++ b/src/arch/nt64/crt_tls.c
@@ -0,0 +1,24 @@
+#include <unistd.h>
+#include <stdint.h>
+#include <stddef.h>
+#include "psxglue.h"
+#include "pthread_arch.h"
+
+typedef unsigned int __tls_word __attribute__((mode(word)));
+typedef unsigned int __tls_ptr __attribute__((mode(pointer)));
+
+struct __emutls_object
+{
+ __tls_word size;
+ __tls_word align;
+ ptrdiff_t offset;
+ void * defval;
+};
+
+void * __emutls_get_address (struct __emutls_object * obj)
+{
+ int dsoidx = obj->align & 0xFFFF0000;
+ struct __tlca_abi * tlca = (struct __tlca_abi *)__psx_tlca();
+ return tlca->pthread_dtls[dsoidx >> 16] + obj->offset;
+}
+
diff --git a/src/arch/nt64/syscall_disp.c b/src/arch/nt64/syscall_disp.c
new file mode 100644
index 0000000..9ea5966
--- /dev/null
+++ b/src/arch/nt64/syscall_disp.c
@@ -0,0 +1,23 @@
+#include <unistd.h>
+#include <stdint.h>
+#include <stddef.h>
+#include "syscall.h"
+#include "psxglue.h"
+
+extern struct __psx_vtbl * __psx_vtbl;
+
+void __unmapself(void * base, size_t size)
+{
+ __psx_vtbl->unmapself(base,(void *)size);
+}
+
+uintptr_t __syscall_disp(long n,
+ uintptr_t a1,
+ uintptr_t a2,
+ uintptr_t a3,
+ uintptr_t a4,
+ uintptr_t a5,
+ uintptr_t a6)
+{
+ return __syscall(n,a1,a2,a3,a4,a5,a6);
+}
diff --git a/src/arch/nt64/vtbl.c b/src/arch/nt64/vtbl.c
new file mode 100644
index 0000000..f21ce17
--- /dev/null
+++ b/src/arch/nt64/vtbl.c
@@ -0,0 +1,25 @@
+#include <unistd.h>
+#include <stdint.h>
+#include "psxglue.h"
+#include "errno.h"
+
+const struct __ldso_vtbl * __ldso_vtbl = 0;
+const struct __psx_vtbl * __psx_vtbl = 0;
+unsigned long ** __syscall_vtbl = 0;
+unsigned long __teb_sys_idx = 0;
+unsigned long __teb_libc_idx = 0;
+
+long __syscall_alert(long n)
+{
+ char __lmsg[] = "DING ALARM! UNIMPLEMENTED SYSCALL 000\n";
+
+ __lmsg[36] = '0' + n % 10; n /= 10;
+ __lmsg[35] = '0' + n % 10; n /= 10;
+ __lmsg[34] = '0' + n % 10;
+
+ __psx_vtbl->log_output(
+ __lmsg,
+ sizeof(__lmsg));
+
+ return -ENOSYS;
+}