diff options
Diffstat (limited to 'sys/rt')
-rw-r--r-- | sys/rt/amd64/crt1.s | 21 | ||||
-rw-r--r-- | sys/rt/amd64/crti.s | 17 | ||||
-rw-r--r-- | sys/rt/amd64/crtn.s | 9 | ||||
-rw-r--r-- | sys/rt/amd64/rt1.s | 9 | ||||
-rw-r--r-- | sys/rt/amd64/rti.s | 9 | ||||
-rw-r--r-- | sys/rt/amd64/rtn.s | 7 | ||||
-rw-r--r-- | sys/rt/arm/rt1.s | 11 | ||||
-rw-r--r-- | sys/rt/arm/rti.s | 13 | ||||
-rw-r--r-- | sys/rt/arm/rtn.s | 9 | ||||
-rw-r--r-- | sys/rt/arm64/rt1.s | 10 | ||||
-rw-r--r-- | sys/rt/arm64/rti.s | 13 | ||||
-rw-r--r-- | sys/rt/arm64/rtn.s | 7 | ||||
-rw-r--r-- | sys/rt/boot.c | 57 | ||||
-rw-r--r-- | sys/rt/context.c | 4 | ||||
-rw-r--r-- | sys/rt/dummy.c | 6 | ||||
-rw-r--r-- | sys/rt/env.c | 3 | ||||
-rw-r--r-- | sys/rt/exit.c | 22 | ||||
-rw-r--r-- | sys/rt/i386/rt1.s | 14 | ||||
-rw-r--r-- | sys/rt/i386/rti.s | 9 | ||||
-rw-r--r-- | sys/rt/i386/rtn.s | 7 | ||||
-rw-r--r-- | sys/rt/include/rt.h | 12 | ||||
-rw-r--r-- | sys/rt/riscv64/rt1.s | 0 | ||||
-rw-r--r-- | sys/rt/riscv64/rti.s | 0 | ||||
-rw-r--r-- | sys/rt/riscv64/rtn.s | 0 | ||||
-rw-r--r-- | sys/rt/stack.c | 17 | ||||
-rw-r--r-- | sys/rt/thunk.c | 17 |
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); +} |