aboutsummaryrefslogtreecommitdiff
path: root/sys/rt
diff options
context:
space:
mode:
Diffstat (limited to 'sys/rt')
-rw-r--r--sys/rt/amd64/crt1.s21
-rw-r--r--sys/rt/amd64/crti.s17
-rw-r--r--sys/rt/amd64/crtn.s9
-rw-r--r--sys/rt/amd64/rt1.s9
-rw-r--r--sys/rt/amd64/rti.s9
-rw-r--r--sys/rt/amd64/rtn.s7
-rw-r--r--sys/rt/arm/rt1.s11
-rw-r--r--sys/rt/arm/rti.s13
-rw-r--r--sys/rt/arm/rtn.s9
-rw-r--r--sys/rt/arm64/rt1.s10
-rw-r--r--sys/rt/arm64/rti.s13
-rw-r--r--sys/rt/arm64/rtn.s7
-rw-r--r--sys/rt/boot.c57
-rw-r--r--sys/rt/context.c4
-rw-r--r--sys/rt/dummy.c6
-rw-r--r--sys/rt/env.c3
-rw-r--r--sys/rt/exit.c22
-rw-r--r--sys/rt/i386/rt1.s14
-rw-r--r--sys/rt/i386/rti.s9
-rw-r--r--sys/rt/i386/rtn.s7
-rw-r--r--sys/rt/include/rt.h12
-rw-r--r--sys/rt/riscv64/rt1.s0
-rw-r--r--sys/rt/riscv64/rti.s0
-rw-r--r--sys/rt/riscv64/rtn.s0
-rw-r--r--sys/rt/stack.c17
-rw-r--r--sys/rt/thunk.c17
26 files changed, 213 insertions, 90 deletions
diff --git a/sys/rt/amd64/crt1.s b/sys/rt/amd64/crt1.s
deleted file mode 100644
index aaad0ba..0000000
--- a/sys/rt/amd64/crt1.s
+++ /dev/null
@@ -1,21 +0,0 @@
-global _start
-
-; NOTE: assumes program loader has put argc, argv, envc, envp on stack
-section .text
-_start:
- xor rbp,rbp ; base pointer undefined: set to 0
- mov r9,rdx ; 6th arg: function to register with atexit()
- pop rsi ; 2nd arg: argc
- mov rdx,rsp ; 3rd arg: argv
- and rsp,$-16 ; align stack pointer to 16 bytes
- mov $_fini,r8 ; 5th arg: fini
- mov $_init,rcx ; 4th arg: init
- mov $main,rdi ; 1st arg: main
-
- call rt·boot ; int boot(
- ; int(*main)(int,char*[],char*[]),
- ; int argc,
- ; char *argv[],
- ; init, fini, atexit);
-
-.loop: jmp .loop ; should never reach...
diff --git a/sys/rt/amd64/crti.s b/sys/rt/amd64/crti.s
deleted file mode 100644
index eeba8b1..0000000
--- a/sys/rt/amd64/crti.s
+++ /dev/null
@@ -1,17 +0,0 @@
-global _init
-global _fini
-
-section .init
-_init:
- ; call pushes an 8 byte return address on the stack
- ; 64 bit ABI requires stack to be aligned to 16 bytes
- ; we realign with another 8 byte address
- push rbp
- mov rbp, rsp
- ;; compiler inserts the rest here
-
-section .fini
-_fini:
- push rbp ; see above
- mov rbp, rsp
- ;; compiler inserts the rest here
diff --git a/sys/rt/amd64/crtn.s b/sys/rt/amd64/crtn.s
deleted file mode 100644
index 45d1a29..0000000
--- a/sys/rt/amd64/crtn.s
+++ /dev/null
@@ -1,9 +0,0 @@
-section .init
- ;; compiler inserts here
- pop rbp ;; undo our push
- ret
-
-section .fini
- ;; compiler inserts here
- pop rbp ;; undo our push
- ret
diff --git a/sys/rt/amd64/rt1.s b/sys/rt/amd64/rt1.s
new file mode 100644
index 0000000..afb5c32
--- /dev/null
+++ b/sys/rt/amd64/rt1.s
@@ -0,0 +1,9 @@
+.extern rt·thunk
+
+.text
+.global _start
+_start:
+ xor %rbp,%rbp
+ mov %rsp,%rdi
+ andq $-16,%rsp
+ call rt·thunk
diff --git a/sys/rt/amd64/rti.s b/sys/rt/amd64/rti.s
new file mode 100644
index 0000000..4788968
--- /dev/null
+++ b/sys/rt/amd64/rti.s
@@ -0,0 +1,9 @@
+.section .init
+.global _init
+_init:
+ push %rax
+
+.section .fini
+.global _fini
+_fini:
+ push %rax
diff --git a/sys/rt/amd64/rtn.s b/sys/rt/amd64/rtn.s
new file mode 100644
index 0000000..29198b7
--- /dev/null
+++ b/sys/rt/amd64/rtn.s
@@ -0,0 +1,7 @@
+.section .init
+ pop %rax
+ ret
+
+.section .fini
+ pop %rax
+ ret
diff --git a/sys/rt/arm/rt1.s b/sys/rt/arm/rt1.s
new file mode 100644
index 0000000..2adfee8
--- /dev/null
+++ b/sys/rt/arm/rt1.s
@@ -0,0 +1,11 @@
+.extern rt·thunk
+
+.text
+.global _start
+.type _start, %function
+_start:
+ mov fp, #0
+ mov lr, #0
+ mov a1, sp
+ and sp, sp, #-16
+ bl rt·thunk
diff --git a/sys/rt/arm/rti.s b/sys/rt/arm/rti.s
new file mode 100644
index 0000000..18dc1e4
--- /dev/null
+++ b/sys/rt/arm/rti.s
@@ -0,0 +1,13 @@
+.syntax unified
+
+.section .init
+.global _init
+.type _init,%function
+_init:
+ push {r0,lr}
+
+.section .fini
+.global _fini
+.type _fini,%function
+_fini:
+ push {r0,lr}
diff --git a/sys/rt/arm/rtn.s b/sys/rt/arm/rtn.s
new file mode 100644
index 0000000..dc020f9
--- /dev/null
+++ b/sys/rt/arm/rtn.s
@@ -0,0 +1,9 @@
+.syntax unified
+
+.section .init
+ pop {r0,lr}
+ bx lr
+
+.section .fini
+ pop {r0,lr}
+ bx lr
diff --git a/sys/rt/arm64/rt1.s b/sys/rt/arm64/rt1.s
new file mode 100644
index 0000000..d0f76da
--- /dev/null
+++ b/sys/rt/arm64/rt1.s
@@ -0,0 +1,10 @@
+ .extern rt·thunk
+
+.global _start
+.type _start, %function
+_start:
+ mov x29, #0
+ mov x30, #0
+ mov x0, sp
+ and sp, x0, #-16
+ b rt·thunk
diff --git a/sys/rt/arm64/rti.s b/sys/rt/arm64/rti.s
new file mode 100644
index 0000000..775df0a
--- /dev/null
+++ b/sys/rt/arm64/rti.s
@@ -0,0 +1,13 @@
+.section .init
+.global _init
+.type _init,%function
+_init:
+ stp x29,x30,[sp,-16]!
+ mov x29,sp
+
+.section .fini
+.global _fini
+.type _fini,%function
+_fini:
+ stp x29,x30,[sp,-16]!
+ mov x29,sp
diff --git a/sys/rt/arm64/rtn.s b/sys/rt/arm64/rtn.s
new file mode 100644
index 0000000..73cab69
--- /dev/null
+++ b/sys/rt/arm64/rtn.s
@@ -0,0 +1,7 @@
+.section .init
+ ldp x29,x30,[sp],#16
+ ret
+
+.section .fini
+ ldp x29,x30,[sp],#16
+ ret
diff --git a/sys/rt/boot.c b/sys/rt/boot.c
index 197e861..76f5599 100644
--- a/sys/rt/boot.c
+++ b/sys/rt/boot.c
@@ -1,34 +1,41 @@
+#include <u.h>
#include <rt.h>
+#include <elf.h>
-int
-rt·boot(
- int (*main)(int,char **,char **), int argc, char **argv,
- int (*init)(int, char **, char **), void (*fini)(void),
- void (*exit)(void)
-)
+/* tell linker to go find */
+int __libc_start_main(int (*main)(int,char **,char **), int argc, char **argv);
+
+#define NAUX 38
+static void
+rt·init(char **env, char *program)
{
- char **envp = argv+argc+1;
- rt·environ = envp;
+ uintptr i, *auxv, aux[NAUX];
+ for(i=0; env[i]; i++)
+ ;
+ rt·context.auxv = auxv = (void *)(env+i+1);
+ for(i=0; auxv[i]; i+=2)
+ if(auxv[i]<NAUX)
+ aux[auxv[i]] = auxv[i+1];
- if(exit)
- rt·context.exit = exit;
+ rt·context.sysinfo = aux[AT_SYSINFO];
+ rt·context.pagesize = aux[AT_PAGESZ];
+}
- if(fini)
- rt·context.fini = fini;
+int
+rt·boot(int (*main)(), int argc, char **argv, void (*init)(), void (*fini)(), void (*exit)())
+{
+ char **env = argv+argc+1;
+ rt·init(env, argv[0]);
- if(init){
- rt·context.init = init;
- init(argc, argv, envp);
- }
+ /* ring libc, anyone home? */
+ __libc_start_main(main, argc, argv);
- /* XXX:
- * we could call __libc_start_main of musl here:
- * this would give us the normal C runtime along with ours
- * which would allow seamless linking to other libraries
- * or we can implement a compatibility layer
- */
- rt·exit(main(argc, argv, envp));
+ /* no? ok we continue on if there is no libc linked */
+ init();
+ if(fini)
+ rt·context.fini = fini;
+ if(exit)
+ rt·context.exit = exit;
- /* should never get here */
- return 0;
+ rt·exit(main(argc, argv, env));
}
diff --git a/sys/rt/context.c b/sys/rt/context.c
new file mode 100644
index 0000000..fb383e3
--- /dev/null
+++ b/sys/rt/context.c
@@ -0,0 +1,4 @@
+#include <u.h>
+#include <rt.h>
+
+struct rt·Context rt·context;
diff --git a/sys/rt/dummy.c b/sys/rt/dummy.c
new file mode 100644
index 0000000..f123d16
--- /dev/null
+++ b/sys/rt/dummy.c
@@ -0,0 +1,6 @@
+#include <u.h>
+#include <rt.h>
+
+/* provide a dummy implementation if libc is not linked */
+static int noop(int (*main)(), int argc, char **argv) { return 0; }
+weakalias(noop, __libc_start_main);
diff --git a/sys/rt/env.c b/sys/rt/env.c
index ddd559d..be710ae 100644
--- a/sys/rt/env.c
+++ b/sys/rt/env.c
@@ -1,3 +1,4 @@
+#include <u.h>
#include <rt.h>
-char *rt·environ = 0;
+char **rt·environ = 0;
diff --git a/sys/rt/exit.c b/sys/rt/exit.c
index 55a684a..e6027b7 100644
--- a/sys/rt/exit.c
+++ b/sys/rt/exit.c
@@ -1,15 +1,27 @@
+#include <u.h>
#include <rt.h>
-#include <sys.h>
+#include <syscall.h>
-void
-rt·exit(int code)
+/* XXX:
+ * if we are here, we are in charge, call exit syscalls
+ * think of better way to encapsulate these syscalls?
+ */
+static noreturn void
+rt·shutdown(int code)
{
if(rt·context.fini)
rt·context.fini();
if(rt·context.exit)
rt·context.exit();
- /* call exit syscalls here */
+ _syscall1(·ExitGroup, code);
+ for(;;)
+ _syscall1(·Exit, code);
+}
+weakalias(rt·shutdown, exit);
- for(;;);
+noreturn void
+rt·exit(int code)
+{
+ rt·shutdown(code);
}
diff --git a/sys/rt/i386/rt1.s b/sys/rt/i386/rt1.s
new file mode 100644
index 0000000..aef4f05
--- /dev/null
+++ b/sys/rt/i386/rt1.s
@@ -0,0 +1,14 @@
+.extern rt·thunk
+
+.text
+.global _start
+_start:
+ xor %ebp,%ebp
+ mov %esp,%eax
+ and $-16,%esp
+ push %eax
+ push %eax
+ push %eax
+ push %eax
+ call rt·thunk
+");
diff --git a/sys/rt/i386/rti.s b/sys/rt/i386/rti.s
new file mode 100644
index 0000000..d2682a2
--- /dev/null
+++ b/sys/rt/i386/rti.s
@@ -0,0 +1,9 @@
+.section .init
+.global _init
+_init:
+ sub $12,%esp
+
+.section .fini
+.global _fini
+_fini:
+ sub $12,%esp
diff --git a/sys/rt/i386/rtn.s b/sys/rt/i386/rtn.s
new file mode 100644
index 0000000..f3b61e0
--- /dev/null
+++ b/sys/rt/i386/rtn.s
@@ -0,0 +1,7 @@
+.section .init
+ add $12,%esp
+ ret
+
+.section .fini
+ add $12,%esp
+ ret
diff --git a/sys/rt/include/rt.h b/sys/rt/include/rt.h
deleted file mode 100644
index dd1598b..0000000
--- a/sys/rt/include/rt.h
+++ /dev/null
@@ -1,12 +0,0 @@
-#pragma once
-
-extern struct rt·context
-{
- void (*init)(void);
- void (*fini)(void);
- void (*exit)(void);
-} rt·context;
-
-extern char **rt·environ;
-
-void rt·exit(int code);
diff --git a/sys/rt/riscv64/rt1.s b/sys/rt/riscv64/rt1.s
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/sys/rt/riscv64/rt1.s
diff --git a/sys/rt/riscv64/rti.s b/sys/rt/riscv64/rti.s
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/sys/rt/riscv64/rti.s
diff --git a/sys/rt/riscv64/rtn.s b/sys/rt/riscv64/rtn.s
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/sys/rt/riscv64/rtn.s
diff --git a/sys/rt/stack.c b/sys/rt/stack.c
new file mode 100644
index 0000000..5ab7a8a
--- /dev/null
+++ b/sys/rt/stack.c
@@ -0,0 +1,17 @@
+#include <u.h>
+#include <arch/atomic.h>
+
+/* unprefixed names determined by gcc */
+uintptr __stack_chk_guard;
+
+void
+rt·guardstack(void)
+{
+ __stack_chk_guard = (uintptr)&__stack_chk_guard*1103515245;
+}
+
+void
+__stack_chk_fail(void)
+{
+ atomic·crash();
+}
diff --git a/sys/rt/thunk.c b/sys/rt/thunk.c
new file mode 100644
index 0000000..3e9fa35
--- /dev/null
+++ b/sys/rt/thunk.c
@@ -0,0 +1,17 @@
+#include <u.h>
+#include <rt.h>
+
+int main();
+void _init() __attribute__((weak));
+void _fini() __attribute__((weak));
+
+void rt·boot(int (*)(), int , char **, void (*)(), void (*)(), void (*)());
+
+void
+rt·thunk(intptr *stack)
+{
+ int argc = stack[0];
+ char **argv = (void *)(stack+1);
+
+ rt·boot(main, argc, argv, _init, _fini, 0);
+}