diff --git a/arch/aarch64.c b/arch/aarch64.c new file mode 100644 index 0000000..15edf9c --- /dev/null +++ b/arch/aarch64.c @@ -0,0 +1,53 @@ +#if defined(__aarch64__) + +void exit(int8_t status){ + asm ( "mov x0, %0\n" // Move the exit status into register x0 + "mov x8, #93\n" // Syscall number for 'exit' is 93 in AArch64 + "svc #0\n" // Make the syscall + : // No output operands + : "r" ((long)status) // Input operand: status + : "x0", "x8" // Clobbered registers + ); +} + +intptr_t write(int32_t fd, const void* buf, intptr_t size){ + intptr_t n_written = 0; + asm volatile( + "mov x0, %2\n" + "mov x1, %0\n" + "mov x2, %1\n" + "mov x8, #64\n" + "svc #0\n" + : //TODO: n_written + : "r" (buf), "r"(count), "r"(fd) + : "x0", "x8" // Clobbered registers + ); + return n_written; +} + +#define CLONE_CHILD_SETTID 0x1000000 +#define CLONE_CHILD_CLEARTID 0x200000 +uint32_t fork(){ + long int rtn; + long int flags = CLONE_CHILD_CLEARTID | CLONE_CHILD_SETTID; + asm volatile ( + // Assembly Instructions + "mov x8, #220\n" // Syscall number for 'clone' is 220 in AArch64 + "mov x0, %1\n" // clone flags + "mov x1, #0\n" // child stack pointer + "mov x2, #0\n" // parent_tidptr + "mov x3, #0\n" // tls + "mov x4, #0\n" // child_tidptr + "svc #0\n" // Make the syscall + "mov %0, x0\n" // save return value + // Output operands + : "=r" (rtn) + // Input operand + : "r" (flags) + // Clobbered registers + : "x0", "x1", "x2", "x3", "x4", "x8" + ); + return (uint32_t)rtn; +} + +#endif diff --git a/arch/mips.c b/arch/mips.c new file mode 100644 index 0000000..afc3e29 --- /dev/null +++ b/arch/mips.c @@ -0,0 +1,43 @@ +#if defined(__mips__) +#include + +void exit(int8_t status){ + asm ( + "move $a0, %0\n" + "li $v0, 4001\n" + "syscall\n" + : + : "r" (status) + : "a0", "v0" + ); +} + +intptr_t write(int32_t fd, const void* buf, intptr_t size){ + intptr_t n_written = 0; + asm ( + "li $a0, 1\n" + "move $a1, %0\n" + "move $a2, %1\n" + "li $v0, 4004\n" + "syscall\n" + : //TODO: n_written + : "r"(buf), "r"(count) + : "a0", "a1", "a2", "v0" //TODO: temp registers clobbered by syscall should probably also be listed but this fn returns right away so it should be fine? + ); + return n_written; +} +//intptr_t read(int32_t fd, const void* buf, intptr_t size); + +uint32_t fork(){ + int rtn; + asm ( + "li $v0, 4002\n" + "syscall\n" + "move %0, $v0" + :"=r" (rtn) + : + : "a0", "v0" + ); + return (uint32_t)rtn; +} +#endif diff --git a/arch/x86_64.c b/arch/x86_64.c new file mode 100644 index 0000000..ebb7394 --- /dev/null +++ b/arch/x86_64.c @@ -0,0 +1,36 @@ +#include +#if defined(__x86_64__) + +void exit(int8_t status) { + asm volatile( + "syscall" + : + : "a"(60), "D"(status) + : + ); +} + +intptr_t write(int32_t fd, const void* buf, intptr_t size) { + intptr_t n_written = 0; + asm volatile ( + "syscall\n" + "movq %0, %%rax\n" + : "=r"(n_written) + : "a"(1), "D"(fd), "S"(buf), "d"(size) // RDI, RSI, RDX are used in x86-64 for write args + : "rcx", "r11", "memory" + ); + return n_written; +} + +uint32_t fork() { + uint64_t rtn; + asm volatile( + "syscall\n" // syscall + "movq %0, %%rax\n" // save return value + : "=r"(rtn) + : "a"(57) + : + ); + return (uint32_t)rtn; +} +#endif /* ifdef __x86_64__ */ diff --git a/sys.h b/sys.h new file mode 100644 index 0000000..46682ea --- /dev/null +++ b/sys.h @@ -0,0 +1,12 @@ +#ifndef MINIMALSYS_H +#include + +void exit(int8_t status); + +#define STDIO 1 +#define STDERR 2 +intptr_t write(int32_t fd, const void* buf, intptr_t size); +//intptr_t read(int32_t fd, const void* buf, intptr_t size); + +uint32_t fork(); +#endif // !MINIMALSYS_H