diff options
Diffstat (limited to 'sys')
33 files changed, 771 insertions, 93 deletions
@@ -289,6 +289,44 @@ def fmtsyscallold(writer, musl): print(f"# {word[0][1:]:<8}{name[0]:<10} {name[1]}", file=writer) # ------------------------------------------------------------------------ +# atomic + +def snaketolower(name): + return "".join(w for w in name.split("_")) + +def modifytype(line): + return line.replace("uint64_t", "uint64").replace("uint32_t", "uint32").replace("uintptr_t","uintptr") + +def fmtatomic(writer, reader): + def fmt(name): + prefix = "" + index = name.find("a_") + if index > 0: + prefix = name[:index] + + name = name[index:] + name = name.replace("a_", "") + return prefix + "atomic·" + snaketolower(name) + + for line in reader: + word = [modifytype(w) for w in line.split(" ")] + if len(word) == 3: + if word[0].strip() == "#define" and word[1].strip() == word[2].strip(): + continue + if len(word) == 2: + if word[0].strip() == "#define" and "libc.h" in word[1]: + continue + + ours = [ fmt(w) if "a_" in w else w for w in word ] + line = " ".join(ours) + line = line.replace("static inline void ", "static inline void\n")\ + .replace("static inline int ", "static inline int\n")\ + .replace("if (", "if(").replace("for (", "for(").replace("while (", "while(")\ + .replace("do {", "do{").replace("} while", "}while").replace(") {", "){") + + print(line, file=writer, end="") + +# ------------------------------------------------------------------------ # types stdintdefs=[ @@ -384,6 +422,10 @@ if __name__ == "__main__": with open(f"{libnarch}/bits.h", "w") as io: fmtbits(io, musl, source) + print("--> emitting atomics", file=stderr) + with open(f"{musl}/atomic_arch.h") as reader, open(f"{libnarch}/atomic.h", "w") as writer: + fmtatomic(writer,reader) + print("--> emitting syscalls", file=stderr) with open(f"{libn}/syscall.h", "w") as io: fmtsyscall(io,musl) @@ -394,17 +436,17 @@ if __name__ == "__main__": source, target = "generic", "port" musl = f"{muslroot}/arch/{source}" - libn = f"linux/{target}/arch" + libn = f"linux/{target}/os" mkpath(libnarch, exist_ok=True) with open(f"{libn}/errno.h","w") as io: fmterrno(io, musl) musl = f"{muslroot}/src/errno" - libn = "src/errno.inc.h" + libn = "linux/src/errno.inc.h" with open(libn,"w") as io: fmtstrerror(io, musl) - libn = "src/internal.h" + libn = "linux/src/internal.h" musl = f"{muslroot}/src/internal/syscall.h" needfix = False diff --git a/sys/linux/amd64/arch/atomic.h b/sys/linux/amd64/arch/atomic.h new file mode 100644 index 0000000..b3aeed1 --- /dev/null +++ b/sys/linux/amd64/arch/atomic.h @@ -0,0 +1,123 @@ +static inline int +atomic·cas(volatile int *p, int t, int s) +{ + __asm__ __volatile__ ( + "lock ; cmpxchg %3, %1" + : "=a"(t), "=m"(*p) : "a"(t), "r"(s) : "memory" ); + return t; +} + +static inline void +*atomic·casp(volatile void *p, void *t, void *s) +{ + __asm__( "lock ; cmpxchg %3, %1" + : "=a"(t), "=m"(*(void *volatile *)p) + : "a"(t), "r"(s) : "memory" ); + return t; +} + +static inline int +atomic·swap(volatile int *p, int v) +{ + __asm__ __volatile__( + "xchg %0, %1" + : "=r"(v), "=m"(*p) : "0"(v) : "memory" ); + return v; +} + +static inline int +atomic·fetchadd(volatile int *p, int v) +{ + __asm__ __volatile__( + "lock ; xadd %0, %1" + : "=r"(v), "=m"(*p) : "0"(v) : "memory" ); + return v; +} + +static inline void +atomic·and(volatile int *p, int v) +{ + __asm__ __volatile__( + "lock ; and %1, %0" + : "=m"(*p) : "r"(v) : "memory" ); +} + +static inline void +atomic·or(volatile int *p, int v) +{ + __asm__ __volatile__( + "lock ; or %1, %0" + : "=m"(*p) : "r"(v) : "memory" ); +} + +static inline void +atomic·and64(volatile uint64 *p, uint64 v) +{ + __asm__ __volatile( + "lock ; and %1, %0" + : "=m"(*p) : "r"(v) : "memory" ); +} + +static inline void +atomic·or64(volatile uint64 *p, uint64 v) +{ + __asm__ __volatile__( + "lock ; or %1, %0" + : "=m"(*p) : "r"(v) : "memory" ); +} + +static inline void +atomic·inc(volatile int *p) +{ + __asm__ __volatile__( + "lock ; incl %0" + : "=m"(*p) : "m"(*p) : "memory" ); +} + +static inline void +atomic·dec(volatile int *p) +{ + __asm__ __volatile__( + "lock ; decl %0" + : "=m"(*p) : "m"(*p) : "memory" ); +} + +static inline void +atomic·store(volatile int *p, int x) +{ + __asm__ __volatile__( + "mov %1, %0 ; lock ; orl $0,(%%rsp)" + : "=m"(*p) : "r"(x) : "memory" ); +} + +static inline void +atomic·barrier() +{ + __asm__ __volatile__( "" : : : "memory" ); +} + +static inline void +atomic·spin() +{ + __asm__ __volatile__( "pause" : : : "memory" ); +} + +static inline void +atomic·crash() +{ + __asm__ __volatile__( "hlt" : : : "memory" ); +} + +static inline int +atomic·ctz64(uint64 x) +{ + __asm__( "bsf %1,%0" : "=r"(x) : "r"(x) ); + return x; +} + +static inline int +atomic·clz64(uint64 x) +{ + __asm__( "bsr %1,%0 ; xor $63,%0" : "=r"(x) : "r"(x) ); + return x; +} diff --git a/sys/linux/arm/arch/atomic.h b/sys/linux/arm/arch/atomic.h new file mode 100644 index 0000000..abb8a7b --- /dev/null +++ b/sys/linux/arm/arch/atomic.h @@ -0,0 +1,107 @@ +#include "libc.h" + +#if __ARM_ARCH_4__ || __ARM_ARCH_4T__ || __ARM_ARCH == 4 +#define BLX "mov lr,pc\n\tbx" +#else +#define BLX "blx" +#endif + +extern hidden uintptr __atomic·casptr, __atomic·barrierptr; + +#if((__ARM_ARCH_6__ || __ARM_ARCH_6K__ || __ARM_ARCH_6KZ__ || __ARM_ARCH_6ZK__) && !__thumb__) \ + || __ARM_ARCH_6T2__ || __ARM_ARCH_7A__ || __ARM_ARCH_7R__ || __ARM_ARCH >= 7 + +static inline int +atomic·ll(volatile int *p) +{ + int v; + __asm__ __volatile__ ("ldrex %0, %1" : "=r"(v) : "Q"(*p)); + return v; +} + +static inline int +atomic·sc(volatile int *p, int v) +{ + int r; + __asm__ __volatile__ ("strex %0,%2,%1" : "=&r"(r), "=Q"(*p) : "r"(v) : "memory"); + return !r; +} + +#if __ARM_ARCH_7A__ || __ARM_ARCH_7R__ || __ARM_ARCH >= 7 + +static inline void +atomic·barrier() +{ + __asm__ __volatile__ ("dmb ish" : : : "memory"); +} + +#endif + +#define atomic·prellsc atomic·barrier +#define atomic·postllsc atomic·barrier + +#else + +static inline int +atomic·cas(volatile int *p, int t, int s) +{ + for(;;){ + register int r0 __asm__("r0") = t; + register int r1 __asm__("r1") = s; + register volatile int *r2 __asm__("r2") = p; + register uintptr r3 __asm__("r3") = __atomic·casptr; + int old; + __asm__ __volatile__ ( + BLX " r3" + : "+r"(r0), "+r"(r3) : "r"(r1), "r"(r2) + : "memory", "lr", "ip", "cc" ); + if(!r0) return t; + if((old=*p)!=t) return old; + } +} + +#endif + +#ifndef atomic·barrier +static inline void +atomic·barrier() +{ + register uintptr ip __asm__("ip") = __atomic·barrierptr; + __asm__ __volatile__( BLX " ip" : "+r"(ip) : : "memory", "cc", "lr" ); +} +#endif + +static inline void +atomic·crash() +{ + __asm__ __volatile__( +#ifndef __thumb__ + ".word 0xe7f000f0" +#else + ".short 0xdeff" +#endif + : : : "memory"); +} + +#if __ARM_ARCH >= 5 && (!__thumb__ || __thumb2__) + +static inline int +atomic·clz32(uint32 x) +{ + __asm__ ("clz %0, %1" : "=r"(x) : "r"(x)); + return x; +} + +#if __ARM_ARCH_6T2__ || __ARM_ARCH_7A__ || __ARM_ARCH_7R__ || __ARM_ARCH >= 7 + +static inline int +atomic·ctz32(uint32 x) +{ + uint32 xr; + __asm__ ("rbit %0, %1" : "=r"(xr) : "r"(x)); + return atomic·clz32(xr); +} + +#endif + +#endif diff --git a/sys/linux/arm64/arch/atomic.h b/sys/linux/arm64/arch/atomic.h new file mode 100644 index 0000000..2fa4b04 --- /dev/null +++ b/sys/linux/arm64/arch/atomic.h @@ -0,0 +1,82 @@ +static inline int +atomic·ll(volatile int *p) +{ + int v; + __asm__ __volatile__ ("ldaxr %w0,%1" : "=r"(v) : "Q"(*p)); + return v; +} + +static inline int +atomic·sc(volatile int *p, int v) +{ + int r; + __asm__ __volatile__ ("stlxr %w0,%w2,%1" : "=&r"(r), "=Q"(*p) : "r"(v) : "memory"); + return !r; +} + +static inline void +atomic·barrier() +{ + __asm__ __volatile__ ("dmb ish" : : : "memory"); +} + +static inline int +atomic·cas(volatile int *p, int t, int s) +{ + int old; + do{ + old = atomic·ll(p); + if(old != t){ + atomic·barrier(); + break; + } + }while(!atomic·sc(p, s)); + return old; +} + +static inline void +*atomic·llp(volatile void *p) +{ + void *v; + __asm__ __volatile__ ("ldaxr %0, %1" : "=r"(v) : "Q"(*(void *volatile *)p)); + return v; +} + +static inline int +atomic·scp(volatile int *p, void *v) +{ + int r; + __asm__ __volatile__ ("stlxr %w0,%2,%1" : "=&r"(r), "=Q"(*(void *volatile *)p) : "r"(v) : "memory"); + return !r; +} + +static inline void +*atomic·casp(volatile void *p, void *t, void *s) +{ + void *old; + do{ + old = atomic·llp(p); + if(old != t){ + atomic·barrier(); + break; + } + }while(!atomic·scp(p, s)); + return old; +} + +static inline int +atomic·ctz64(uint64 x) +{ + __asm__( + " rbit %0, %1\n" + " clz %0, %0\n" + : "=r"(x) : "r"(x)); + return x; +} + +static inline int +atomic·clz64(uint64 x) +{ + __asm__("clz %0, %1" : "=r"(x) : "r"(x)); + return x; +} diff --git a/sys/linux/i386/arch/atomic.h b/sys/linux/i386/arch/atomic.h new file mode 100644 index 0000000..eab161d --- /dev/null +++ b/sys/linux/i386/arch/atomic.h @@ -0,0 +1,108 @@ +static inline int +atomic·cas(volatile int *p, int t, int s) +{ + __asm__ __volatile__ ( + "lock ; cmpxchg %3, %1" + : "=a"(t), "=m"(*p) : "a"(t), "r"(s) : "memory" ); + return t; +} + +static inline int +atomic·swap(volatile int *p, int v) +{ + __asm__ __volatile__( + "xchg %0, %1" + : "=r"(v), "=m"(*p) : "0"(v) : "memory" ); + return v; +} + +static inline int +atomic·fetchadd(volatile int *p, int v) +{ + __asm__ __volatile__( + "lock ; xadd %0, %1" + : "=r"(v), "=m"(*p) : "0"(v) : "memory" ); + return v; +} + +static inline void +atomic·and(volatile int *p, int v) +{ + __asm__ __volatile__( + "lock ; and %1, %0" + : "=m"(*p) : "r"(v) : "memory" ); +} + +static inline void +atomic·or(volatile int *p, int v) +{ + __asm__ __volatile__( + "lock ; or %1, %0" + : "=m"(*p) : "r"(v) : "memory" ); +} + +static inline void +atomic·inc(volatile int *p) +{ + __asm__ __volatile__( + "lock ; incl %0" + : "=m"(*p) : "m"(*p) : "memory" ); +} + +static inline void +atomic·dec(volatile int *p) +{ + __asm__ __volatile__( + "lock ; decl %0" + : "=m"(*p) : "m"(*p) : "memory" ); +} + +static inline void +atomic·store(volatile int *p, int x) +{ + __asm__ __volatile__( + "mov %1, %0 ; lock ; orl $0,(%%esp)" + : "=m"(*p) : "r"(x) : "memory" ); +} + +static inline void +atomic·barrier() +{ + __asm__ __volatile__( "" : : : "memory" ); +} + +static inline void +atomic·spin() +{ + __asm__ __volatile__( "pause" : : : "memory" ); +} + +static inline void +atomic·crash() +{ + __asm__ __volatile__( "hlt" : : : "memory" ); +} + +static inline int +atomic·ctz64(uint64 x) +{ + int r; + __asm__( "bsf %1,%0 ; jnz 1f ; bsf %2,%0 ; add $32,%0\n1:" + : "=&r"(r) : "r"((unsigned)x), "r"((unsigned)(x>>32)) ); + return r; +} + +static inline int +atomic·ctz32(uint32 x) +{ + int r; + __asm__( "bsf %1,%0" : "=r"(r) : "r"(x) ); + return r; +} + +static inline int +atomic·clz32(uint32 x) +{ + __asm__( "bsr %1,%0 ; xor $31,%0" : "=r"(x) : "r"(x) ); + return x; +} diff --git a/sys/linux/riscv64/arch/atomic.h b/sys/linux/riscv64/arch/atomic.h new file mode 100644 index 0000000..95db16d --- /dev/null +++ b/sys/linux/riscv64/arch/atomic.h @@ -0,0 +1,38 @@ +static inline void +atomic·barrier() +{ + __asm__ __volatile__ ("fence rw,rw" : : : "memory"); +} + +static inline int +atomic·cas(volatile int *p, int t, int s) +{ + int old, tmp; + __asm__ __volatile__ ( + "\n1: lr.w.aqrl %0, (%2)\n" + " bne %0, %3, 1f\n" + " sc.w.aqrl %1, %4, (%2)\n" + " bnez %1, 1b\n" + "1:" + : "=&r"(old), "=&r"(tmp) + : "r"(p), "r"((long)t), "r"((long)s) + : "memory"); + return old; +} + +static inline void +*atomic·casp(volatile void *p, void *t, void *s) +{ + void *old; + int tmp; + __asm__ __volatile__ ( + "\n1: lr.d.aqrl %0, (%2)\n" + " bne %0, %3, 1f\n" + " sc.d.aqrl %1, %4, (%2)\n" + " bnez %1, 1b\n" + "1:" + : "=&r"(old), "=&r"(tmp) + : "r"(p), "r"(t), "r"(s) + : "memory"); + return old; +} 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); +} diff --git a/sys/rules.mk b/sys/rules.mk new file mode 100644 index 0000000..3113915 --- /dev/null +++ b/sys/rules.mk @@ -0,0 +1,55 @@ +# rules for rt +RT1 := $(OBJ_DIR)/rt/rt1.a +RTI := $(OBJ_DIR)/rt/rti.o +# rt2 = user program +RTN := $(OBJ_DIR)/rt/rtn.o +RT3 := $(OBJ_DIR)/rt/rt3.a +RUNTIME := $(RT1) $(RTI) $(RTN) $(RT3) + +RT1_SRC := \ + $(SYS_DIR)/rt/env.c\ + $(SYS_DIR)/rt/context.c\ + $(SYS_DIR)/rt/boot.c\ + $(SYS_DIR)/rt/thunk.c + +RT3_SRC := \ + $(SYS_DIR)/rt/dummy.c\ + $(SYS_DIR)/rt/exit.c\ + +RT1_OBJ := $(filter %.o, $(RT1_SRC:.c=.o)) +RT1_OBJ := $(patsubst $(SYS_DIR)/rt/%, $(OBJ_DIR)/rt/%, $(RT1_OBJ)) +RT3_OBJ := $(filter %.o, $(RT3_SRC:.c=.o)) +RT3_OBJ := $(patsubst $(SYS_DIR)/rt/%, $(OBJ_DIR)/rt/%, $(RT3_OBJ)) + +$(RT1_OBJ): TCFLAGS=-fno-builtin -fno-stack-protector +$(RT1): $(SYS_DIR)/rt/$(ARCH)/rt1.s $(RT1_OBJ) + @echo "AS rt1.a" + @$(AS) $(AFLAGS) -o $(OBJ_DIR)/rt/rt1.o -c $< + @$(AR) crs $@ $(OBJ_DIR)/rt/rt1.o $(RT1_OBJ) + +$(RTI): $(SYS_DIR)/rt/$(ARCH)/rti.s + $(ASSEMBLE) + +$(RTN): $(SYS_DIR)/rt/$(ARCH)/rtn.s + $(ASSEMBLE) + +$(OBJ_DIR)/rt/%.o: $(SYS_DIR)/rt/%.c + $(COMPILE) + +$(RT3): $(RT3_OBJ) + $(ARCHIVE) + +# rules for system layer +SYS := $(OBJ_DIR)/sys/sys.a + +SYS_SRCS := $(sort $(wildcard $(SYS_DIR)/$(OS)/src/*.c)) +SYS_OBJS := $(filter %.o, $(SYS_SRCS:.c=.o)) +SYS_OBJS := $(patsubst $(SYS_DIR)/$(OS)/src/%, $(OBJ_DIR)/$(SYS_DIR)/%, $(SYS_OBJS)) + +# rules for kernel interface +$(OBJ_DIR)/sys/%.o: TINCS = -I $(SYS_DIR)/$(OS)/$(ARCH) +$(OBJ_DIR)/sys/%.o: $(SYS_DIR)/$(OS)/src/%.c + $(COMPILE) + +$(SYS): $(SYS_OBJS) + $(ARCHIVE) |