Compare commits
6 Commits
7c8c2e2dc2
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
| 73ad441585 | |||
| ea0ec6a818 | |||
| ed7a811736 | |||
| f7109b8743 | |||
| cc557ed1b9 | |||
| 02f308ffbd |
11
.gitignore
vendored
11
.gitignore
vendored
@@ -1,10 +1,3 @@
|
||||
print
|
||||
print_aarch64
|
||||
print_mips32
|
||||
print_x64
|
||||
bldtst
|
||||
bldtst_aarch64
|
||||
bldtst_mips32
|
||||
bldtst_x64
|
||||
bldtst_llvm
|
||||
a.out
|
||||
bin
|
||||
tmp
|
||||
|
||||
97
Makefile
97
Makefile
@@ -1,32 +1,85 @@
|
||||
all: buildtest
|
||||
bindir ?= ./bin
|
||||
|
||||
CFLAGS := -nostdlib -static -fuse-ld=lld -fno-stack-protector
|
||||
|
||||
CLANG_WNO := -Wno-incompatible-library-redeclaration
|
||||
GCC_WNO := -Wno-builtin-declaration-mismatch
|
||||
|
||||
MIPS_CFLAGS := --target=mips-linux-gnu -fno-pic
|
||||
MIPSEL_CFLAGS := --target=mipsel-linux-gnu -fno-pic
|
||||
X86_64_CFLAGS := --target=x86_64-linux-gnu
|
||||
|
||||
AARCH64_CFLAGS := --target=aarch64-linux-gnu
|
||||
|
||||
all: buildtest socktest stackdump
|
||||
|
||||
clean:
|
||||
if test -f print; then rm print; fi
|
||||
if test -f print_x64; then rm print_x64; fi
|
||||
if test -f print_aarch64; then rm print_aarch64; fi
|
||||
if test -f print_mips32; then rm print_mips32; fi
|
||||
if test -f bldtst; then rm bldtst; fi
|
||||
if test -f bldtst_llvm; then rm bldtst_llvm; fi
|
||||
if test -f bldtst_x64; then rm bldtst_x64; fi
|
||||
if test -f bldtst_aarch64; then rm bldtst_aarch64; fi
|
||||
if test -f bldtst_mips32; then rm bldtst_mips32; fi
|
||||
rm $(bindir)/*
|
||||
|
||||
buildtest: bldtst bldtst_llvm bldtst_x64 bldtst_aarch64 bldtst_mips32
|
||||
$(bindir)/:
|
||||
mkdir -p ${bindir}
|
||||
|
||||
.PHONY: all buildtest clean
|
||||
headers := sys.h int.h
|
||||
buildtest: $(bindir)/bldtst $(bindir)/bldtst_llvm $(bindir)/bldtst_x64 $(bindir)/bldtst_aarch64 $(bindir)/bldtst_mips $(bindir)/bldtst_mipsel
|
||||
socktest: $(bindir)/socktest $(bindir)/socktest_llvm $(bindir)/socktest_x64 $(bindir)/socktest_aarch64 $(bindir)/socktest_mips $(bindir)/socktest_mipsel
|
||||
stackdump: $(bindir)/stackdump $(bindir)/stackdump_llvm $(bindir)/stackdump_x64 $(bindir)/stackdump_aarch64 $(bindir)/stackdump_mips $(bindir)/stackdump_mipsel
|
||||
|
||||
|
||||
bldtst: buildtest.c arch/*.c
|
||||
gcc -static -nostdlib -Wno-builtin-declaration-mismatch -fno-stack-protector -o bldtst buildtest.c arch/*.c
|
||||
.PHONY: all clean buildtest socktest stackdump
|
||||
|
||||
bldtst_llvm: buildtest.c arch/*.c
|
||||
clang -nostdlib -Wno-incompatible-library-redeclaration -static -fuse-ld=lld -fno-stack-protector -o bldtst_llvm buildtest.c arch/*.c
|
||||
|
||||
bldtst_x64: buildtest.c arch/x86_64.c
|
||||
clang --target=x86_64-linux-gnu -nostdlib -Wno-incompatible-library-redeclaration -static -fuse-ld=lld -fno-stack-protector -o bldtst_x64 buildtest.c arch/x86_64.c
|
||||
${bindir}/bldtst: buildtest.c $(headers) arch/* | $(bindir)/
|
||||
gcc $(CFLAGS) $(GCC_WNO) -o $@ buildtest.c arch/*.c
|
||||
|
||||
bldtst_aarch64: buildtest.c arch/aarch64.c
|
||||
clang --target=aarch64-linux-gnu -nostdlib -Wno-incompatible-library-redeclaration -static -fuse-ld=lld -fno-stack-protector -o bldtst_aarch64 buildtest.c arch/aarch64.c
|
||||
${bindir}/bldtst_llvm: $(headers) buildtest.c arch/* | $(bindir)/
|
||||
clang $(CFLAGS) $(CLANG_WNO) -o $@ buildtest.c arch/*.c
|
||||
|
||||
bldtst_mips32: buildtest.c arch/mips.c
|
||||
clang --target=mips-linux-gnu -nostdlib -Wno-incompatible-library-redeclaration -static -fuse-ld=lld -fno-stack-protector -fno-pic -o bldtst_mips32 buildtest.c arch/mips.c
|
||||
${bindir}/bldtst_x64: $(headers) buildtest.c arch/x86_64.c arch/generic.h | $(bindir)/
|
||||
clang $(X86_64_CFLAGS) $(CFLAGS) $(CLANG_WNO) -o $@ buildtest.c arch/x86_64.c
|
||||
|
||||
${bindir}/bldtst_aarch64: $(headers) buildtest.c arch/aarch64.c arch/generic.h | $(bindir)/
|
||||
clang $(AARCH64_CFLAGS) $(CFLAGS) $(CLANG_WNO) -o $@ buildtest.c arch/aarch64.c
|
||||
|
||||
${bindir}/bldtst_mips: $(headers) buildtest.c arch/mips.c arch/generic.h | $(bindir)/
|
||||
clang $(MIPS_CFLAGS) $(CFLAGS) $(CLANG_WNO) -o $@ buildtest.c arch/mips.c
|
||||
|
||||
${bindir}/bldtst_mipsel: $(headers) buildtest.c arch/mips.c arch/generic.h | $(bindir)/
|
||||
clang $(MIPSEL_CFLAGS) $(CFLAGS) $(CLANG_WNO) -o $@ buildtest.c arch/mips.c
|
||||
|
||||
|
||||
${bindir}/socktest: socktest.c $(headers) arch/* | $(bindir)/
|
||||
gcc $(CFLAGS) $(GCC_WNO) -o $@ socktest.c arch/*.c
|
||||
|
||||
${bindir}/socktest_llvm: $(headers) socktest.c arch/* | $(bindir)/
|
||||
clang $(CFLAGS) $(CLANG_WNO) -o $@ socktest.c arch/*.c
|
||||
|
||||
${bindir}/socktest_x64: $(headers) socktest.c arch/x86_64.c arch/generic.h | $(bindir)/
|
||||
clang $(X86_64_CFLAGS) $(CFLAGS) $(CLANG_WNO) -o $@ socktest.c arch/x86_64.c
|
||||
|
||||
${bindir}/socktest_aarch64: $(headers) socktest.c arch/aarch64.c arch/generic.h | $(bindir)/
|
||||
clang $(AARCH64_CFLAGS) $(CFLAGS) $(CLANG_WNO) -o $@ socktest.c arch/aarch64.c
|
||||
|
||||
${bindir}/socktest_mips: $(headers) socktest.c arch/mips.c arch/generic.h | $(bindir)/
|
||||
clang $(MIPS_CFLAGS) $(CFLAGS) $(CLANG_WNO) -o $@ socktest.c arch/mips.c
|
||||
|
||||
${bindir}/socktest_mipsel: $(headers) socktest.c arch/mips.c arch/generic.h | $(bindir)/
|
||||
clang $(MIPSEL_CFLAGS) $(CFLAGS) $(CLANG_WNO) -o $@ socktest.c arch/mips.c
|
||||
|
||||
|
||||
${bindir}/stackdump: stackdump.c $(headers) arch/* | $(bindir)/
|
||||
gcc -D _START_DEFINED $(CFLAGS) $(GCC_WNO) -o $@ stackdump.c arch/*.c
|
||||
|
||||
${bindir}/stackdump_llvm: $(headers) stackdump.c arch/* | $(bindir)/
|
||||
clang -D _START_DEFINED $(CFLAGS) $(CLANG_WNO) -o $@ stackdump.c arch/*.c
|
||||
|
||||
${bindir}/stackdump_x64: $(headers) stackdump.c arch/x86_64.c arch/generic.h | $(bindir)/
|
||||
clang -D _START_DEFINED $(X86_64_CFLAGS) $(CFLAGS) $(CLANG_WNO) -o $@ stackdump.c arch/x86_64.c
|
||||
|
||||
${bindir}/stackdump_aarch64: $(headers) stackdump.c arch/aarch64.c arch/generic.h | $(bindir)/
|
||||
clang -D _START_DEFINED $(AARCH64_CFLAGS) $(CFLAGS) $(CLANG_WNO) -o $@ stackdump.c arch/aarch64.c
|
||||
|
||||
${bindir}/stackdump_mips: $(headers) stackdump.c arch/mips.c arch/generic.h | $(bindir)/
|
||||
clang -D _START_DEFINED $(MIPS_CFLAGS) $(CFLAGS) $(CLANG_WNO) -o $@ stackdump.c arch/mips.c
|
||||
|
||||
${bindir}/stackdump_mipsel: $(headers) stackdump.c arch/mips.c arch/generic.h | $(bindir)/
|
||||
clang -D _START_DEFINED $(MIPSEL_CFLAGS) $(CFLAGS) $(CLANG_WNO) -o $@ stackdump.c arch/mips.c
|
||||
|
||||
@@ -57,9 +57,10 @@ intptr_t read(int32_t fd, const void* buf, intptr_t size){
|
||||
|
||||
#define CLONE_CHILD_SETTID 0x1000000
|
||||
#define CLONE_CHILD_CLEARTID 0x200000
|
||||
#define SIGCHLD 0x11
|
||||
uint32_t fork(){
|
||||
long int rtn;
|
||||
long int flags = CLONE_CHILD_CLEARTID | CLONE_CHILD_SETTID;
|
||||
long int flags = CLONE_CHILD_CLEARTID | CLONE_CHILD_SETTID | SIGCHLD;
|
||||
asm volatile (
|
||||
// Assembly Instructions
|
||||
"mov x8, #220\n" // Syscall number for 'clone' is 220 in AArch64
|
||||
@@ -80,6 +81,50 @@ uint32_t fork(){
|
||||
return (uint32_t)rtn;
|
||||
}
|
||||
|
||||
// SYS_EXECVE 221
|
||||
int32_t execve(const char* filename, const char* argv[], const char* envp[]){
|
||||
long int rtn;
|
||||
asm volatile(
|
||||
// Assembly Instructions
|
||||
"mov x0, %0\n" // Set x0 to value of filename
|
||||
"mov x1, %1\n" // Set x1 to value of argv
|
||||
"mov x2, %2\n" // Set x2 to value of envp
|
||||
"mov x8, #221\n" // Syscall number
|
||||
"svc #0\n" // Make syscall
|
||||
// Output operands
|
||||
: "=r"(rtn)
|
||||
// Input operands
|
||||
: "r"(filename), "r" (argv), "r"(envp)
|
||||
// Clobbered registers
|
||||
: "x0", "x1", "x2", "x8", "memory"
|
||||
);
|
||||
return (int32_t)rtn;
|
||||
}
|
||||
|
||||
uint32_t wait4(uint32_t pid, int* wstatus, int options, void* rusage) {
|
||||
uint64_t rtn;
|
||||
asm volatile (
|
||||
// Assembly Instructions
|
||||
"mov x8, #260\n" // Syscall number for 'listen' is 201 in AArch64
|
||||
"mov x0, %1\n" // pid
|
||||
"mov x1, %2\n" // wstatus
|
||||
"mov x2, %3\n" // options
|
||||
"mov x3, %4\n" // rusage
|
||||
"svc #0\n" // Make the syscall
|
||||
"mov %0, x0\n" // save return value
|
||||
// Output operands
|
||||
: "=r" (rtn)
|
||||
// Input operand
|
||||
: "r" ((uint64_t)pid), "r"(wstatus), "r"((int64_t)options), "r"(rusage)
|
||||
// Clobbered registers
|
||||
: "x0", "x1", "x8", "memory"
|
||||
);
|
||||
return (uint32_t)rtn;
|
||||
}
|
||||
uint32_t waitpid(uint32_t pid, int* wstatus, int options) {
|
||||
return wait4(pid, wstatus, options, 0);
|
||||
}
|
||||
|
||||
int32_t openat(int32_t fd, const char* filename, uint32_t flags, uint32_t mode) {
|
||||
long int rtn;
|
||||
asm volatile (
|
||||
|
||||
45
arch/mips.c
45
arch/mips.c
@@ -1,5 +1,19 @@
|
||||
#if defined(__mips__)
|
||||
#include "../int.h"
|
||||
#include "../sys.h"
|
||||
|
||||
/*
|
||||
#ifndef _START_DEFINED
|
||||
#define _START_DEFINED
|
||||
extern int main(int c, char** v);
|
||||
void __start() {
|
||||
void* fp = __builtin_frame_address(0);
|
||||
register int argc asm("a0") = *(uintptr_t*)(fp+32);
|
||||
register char** argv asm("a1") = fp+36;
|
||||
exit(main(argc, argv));
|
||||
}
|
||||
|
||||
#endif */ /* ifndef _START_DEFINED */
|
||||
|
||||
#include "generic.h"
|
||||
|
||||
@@ -59,6 +73,37 @@ uint32_t fork(){
|
||||
return (uint32_t)rtn;
|
||||
}
|
||||
|
||||
uint32_t waitpid(uint32_t pid, int* wstatus, int options) {
|
||||
int child_pid = 0;
|
||||
asm volatile (
|
||||
"move $a0, %1\n"
|
||||
"move $a1, %2\n"
|
||||
"move $a2, %3\n"
|
||||
"li $v0, 4007\n"
|
||||
"syscall\n"
|
||||
"move %0, $v0\n"
|
||||
: "=r"(child_pid)
|
||||
: "r"(pid), "r"(wstatus), "r"(options)
|
||||
: "a0", "a1", "a2", "v0", "memory"
|
||||
);
|
||||
return child_pid;
|
||||
}
|
||||
|
||||
int32_t execve(const char* filename, const char* argv[], const char* envp[]){
|
||||
int rtn;
|
||||
asm volatile (
|
||||
"move $a0, %0\n"
|
||||
"move $a1, %1\n"
|
||||
"move $a2, %2\n"
|
||||
"li $v0, 4011\n"
|
||||
"syscall\n"
|
||||
: "=r"(rtn)
|
||||
: "r"(filename), "r"(argv), "r"(envp)
|
||||
: "a0", "a1", "a2", "a3", "v0"
|
||||
);
|
||||
return (int32_t)rtn;
|
||||
}
|
||||
|
||||
int32_t openat(int32_t fd, const char* filename, uint32_t flags, uint32_t mode) {
|
||||
int32_t file = 0;
|
||||
asm volatile (
|
||||
|
||||
187
arch/x86_64.c
187
arch/x86_64.c
@@ -22,254 +22,245 @@ void _start() {
|
||||
|
||||
#define SYS_EXIT 60
|
||||
void exit(int8_t status) {
|
||||
asm volatile(
|
||||
"syscall"
|
||||
:
|
||||
: "a"(SYS_EXIT), "D"(status)
|
||||
:
|
||||
);
|
||||
for(;;);
|
||||
asm volatile("syscall" : : "a"(SYS_EXIT), "D"(status) :);
|
||||
for (;;)
|
||||
;
|
||||
}
|
||||
|
||||
#define SYS_WRITE 1
|
||||
intptr_t write(int32_t fd, const void *buf, intptr_t size) {
|
||||
intptr_t n_written = 0;
|
||||
asm volatile (
|
||||
"syscall\n"
|
||||
asm volatile("syscall\n"
|
||||
"movq %0, %%rax\n"
|
||||
: "=r"(n_written)
|
||||
: "a"(SYS_WRITE), "D"(fd), "S"(buf), "d"(size) // RDI, RSI, RDX are used in x86-64 for write args
|
||||
: "rcx", "r11"
|
||||
);
|
||||
: "a"(SYS_WRITE), "D"(fd), "S"(buf),
|
||||
"d"(size) // RDI, RSI, RDX are used in x86-64 for write args
|
||||
: "rcx", "r11");
|
||||
return n_written;
|
||||
}
|
||||
|
||||
#define SYS_READ 0
|
||||
intptr_t read(int32_t fd, const void *buf, intptr_t size) {
|
||||
intptr_t n_read = 0;
|
||||
asm volatile (
|
||||
"syscall\n"
|
||||
asm volatile("syscall\n"
|
||||
"movq %0, %%rax\n"
|
||||
: "=r"(n_read)
|
||||
: "a"(SYS_READ), "D"(fd), "S"(buf), "d"(size) // RDI, RSI, RDX are used in x86-64 for write args
|
||||
: "rcx", "r11", "memory"
|
||||
);
|
||||
: "a"(SYS_READ), "D"(fd), "S"(buf),
|
||||
"d"(size) // RDI, RSI, RDX are used in x86-64 for write args
|
||||
: "rcx", "r11", "memory");
|
||||
return n_read;
|
||||
}
|
||||
|
||||
#define SYS_FORK 57
|
||||
uint32_t fork() {
|
||||
uint64_t rtn;
|
||||
asm volatile(
|
||||
"syscall\n" // syscall
|
||||
asm volatile("syscall\n" // syscall
|
||||
"movq %0, %%rax\n" // save return value
|
||||
: "=r"(rtn)
|
||||
: "a"(SYS_FORK)
|
||||
:
|
||||
);
|
||||
:);
|
||||
return (uint32_t)rtn;
|
||||
}
|
||||
|
||||
#define SYS_EXECVE 59
|
||||
int32_t execve(const char *filename, const char *argv[], const char *envp[]) {
|
||||
int64_t rtn;
|
||||
asm volatile("syscall\n"
|
||||
: "=r"(rtn)
|
||||
: "a"(SYS_EXECVE), "D"(filename), "S"(argv), "d"(envp)
|
||||
: "rcx", "r11");
|
||||
return (int32_t)rtn;
|
||||
}
|
||||
|
||||
#define SYS_WAIT4 61
|
||||
uint32_t wait4(uint32_t pid, int *wstatus, int options, void *rusage) {
|
||||
uint32_t child_pid;
|
||||
asm volatile("mov %5, %%r10\n"
|
||||
"syscall\n"
|
||||
: "=a"(child_pid)
|
||||
: "a"(SYS_WAIT4), "D"(pid), "S"(wstatus), "d"(options),
|
||||
"r"(rusage)
|
||||
: "rcx", "r10", "r11", "memory");
|
||||
return child_pid;
|
||||
}
|
||||
uint32_t waitpid(uint32_t pid, int *wstatus, int options) {
|
||||
return wait4(pid, wstatus, options, 0);
|
||||
}
|
||||
|
||||
#define SYS_OPENAT 257
|
||||
int32_t openat(int32_t fd, const char* filename, uint32_t flags, uint32_t mode) {
|
||||
int32_t openat(int32_t fd, const char *filename, uint32_t flags,
|
||||
uint32_t mode) {
|
||||
int32_t file;
|
||||
asm volatile(
|
||||
"mov %5, %%r10\n"
|
||||
"syscall\n"
|
||||
: "=a"(file)
|
||||
: "a"(SYS_OPENAT), "D"(fd), "S"(filename), "d"(flags), "r"((uint64_t)mode) // RDI, RSI, RDX are used in x86-64 for write args
|
||||
: "rcx", "r10", "r11"
|
||||
);
|
||||
: "a"(SYS_OPENAT), "D"(fd), "S"(filename), "d"(flags),
|
||||
"r"((uint64_t)mode) // RDI, RSI, RDX are used in x86-64 for write args
|
||||
: "rcx", "r10", "r11");
|
||||
return file;
|
||||
}
|
||||
|
||||
#define SYS_CLOSE 3
|
||||
int close(unsigned int fd) {
|
||||
int rtn;
|
||||
asm volatile(
|
||||
"syscall"
|
||||
: "=a"(rtn)
|
||||
: "a"(SYS_CLOSE), "D"(fd)
|
||||
: "rcx", "r11"
|
||||
);
|
||||
asm volatile("syscall" : "=a"(rtn) : "a"(SYS_CLOSE), "D"(fd) : "rcx", "r11");
|
||||
return rtn;
|
||||
}
|
||||
|
||||
#define SYS_FSYNC 74
|
||||
int fsync(unsigned int fd) {
|
||||
int rtn;
|
||||
asm volatile(
|
||||
"syscall"
|
||||
: "=a"(rtn)
|
||||
: "a"(SYS_FSYNC), "D"(fd)
|
||||
: "rcx", "r11"
|
||||
);
|
||||
asm volatile("syscall" : "=a"(rtn) : "a"(SYS_FSYNC), "D"(fd) : "rcx", "r11");
|
||||
return rtn;
|
||||
}
|
||||
|
||||
#define SYS_SOCKET 41
|
||||
int socket(int domain, int type, int protocol) {
|
||||
int32_t fd;
|
||||
asm volatile (
|
||||
"syscall\n"
|
||||
asm volatile("syscall\n"
|
||||
: "=a"(fd)
|
||||
: "a"(SYS_SOCKET), "D"(domain), "S"(type), "d"(protocol)
|
||||
: "rcx", "r11"
|
||||
);
|
||||
: "rcx", "r11");
|
||||
return fd;
|
||||
}
|
||||
|
||||
#define SYS_SETSOCKOPT 54
|
||||
int setsockopt(int fd, int level, int optname, const void* optval, socklen_t optlen) {
|
||||
int setsockopt(int fd, int level, int optname, const void *optval,
|
||||
socklen_t optlen) {
|
||||
int rtn;
|
||||
asm volatile(
|
||||
"mov %5, %%r10\n"
|
||||
asm volatile("mov %5, %%r10\n"
|
||||
"mov %6, %%r8\n"
|
||||
"syscall\n"
|
||||
: "=a"(rtn)
|
||||
: "a"(SYS_SETSOCKOPT), "D"(fd), "S"(level), "d"(optname), "r"(optval), "r"((uint64_t)optlen)
|
||||
: "rcx", "r11"
|
||||
);
|
||||
: "a"(SYS_SETSOCKOPT), "D"(fd), "S"(level), "d"(optname),
|
||||
"r"(optval), "r"((uint64_t)optlen)
|
||||
: "rcx", "r11");
|
||||
return rtn;
|
||||
}
|
||||
|
||||
#define SYS_BIND 49
|
||||
int bind(int fd, const void *sockaddr, socklen_t addrlen) {
|
||||
int rtn;
|
||||
asm volatile(
|
||||
"syscall\n"
|
||||
asm volatile("syscall\n"
|
||||
: "=a"(rtn)
|
||||
: "a"(SYS_BIND), "D"(fd), "S"(sockaddr), "d"(addrlen)
|
||||
: "rcx", "r11"
|
||||
);
|
||||
: "rcx", "r11");
|
||||
return rtn;
|
||||
}
|
||||
|
||||
#define SYS_LISTEN 50
|
||||
int listen(int fd, int backlog) {
|
||||
int rtn;
|
||||
asm volatile(
|
||||
"syscall\n"
|
||||
asm volatile("syscall\n"
|
||||
: "=a"(rtn)
|
||||
: "a"(SYS_LISTEN), "D"(fd), "S"(backlog)
|
||||
: "rcx", "r11"
|
||||
);
|
||||
: "rcx", "r11");
|
||||
return rtn;
|
||||
}
|
||||
|
||||
#define SYS_ACCEPT 43
|
||||
int accept(int fd, void *addr, socklen_t *addrlen) {
|
||||
int rtn;
|
||||
asm volatile(
|
||||
"syscall\n"
|
||||
asm volatile("syscall\n"
|
||||
: "=a"(rtn)
|
||||
: "a"(SYS_ACCEPT), "D"(fd), "S"(addr), "d"(addrlen)
|
||||
: "rcx", "r11", "memory"
|
||||
);
|
||||
: "rcx", "r11", "memory");
|
||||
return rtn;
|
||||
}
|
||||
|
||||
#define SYS_CONNECT 42
|
||||
int connect(int fd, void *addr, socklen_t addrlen) {
|
||||
int rtn;
|
||||
asm volatile(
|
||||
"syscall\n"
|
||||
asm volatile("syscall\n"
|
||||
: "=a"(rtn)
|
||||
: "a"(SYS_CONNECT), "D"(fd), "S"(addr), "d"(addrlen)
|
||||
: "rcx", "r11"
|
||||
);
|
||||
: "rcx", "r11");
|
||||
return rtn;
|
||||
}
|
||||
|
||||
#define SYS_SENDTO 44
|
||||
ssize_t sendto(int fd, const void* buf, size_t size, int flags, const void* sockaddr, socklen_t addrlen) {
|
||||
ssize_t sendto(int fd, const void *buf, size_t size, int flags,
|
||||
const void *sockaddr, socklen_t addrlen) {
|
||||
ssize_t nsent;
|
||||
asm volatile(
|
||||
"mov %5, %%r10\n"
|
||||
asm volatile("mov %5, %%r10\n"
|
||||
"mov %6, %%r8\n"
|
||||
"mov %7, %%r9\n"
|
||||
"syscall\n"
|
||||
: "=a"(nsent)
|
||||
: "a"(SYS_SENDTO), "D"(fd), "S"(buf), "d"(size), "r"((int64_t)flags), "r"(sockaddr), "r"((uint64_t)addrlen)
|
||||
: "rcx", "r11"
|
||||
);
|
||||
: "a"(SYS_SENDTO), "D"(fd), "S"(buf), "d"(size),
|
||||
"r"((int64_t)flags), "r"(sockaddr), "r"((uint64_t)addrlen)
|
||||
: "rcx", "r11");
|
||||
return nsent;
|
||||
}
|
||||
|
||||
#define SYS_RECVFROM 45
|
||||
ssize_t recvfrom(int fd, const void* buf, size_t size, int flags, const void* sockaddr, socklen_t addrlen) {
|
||||
ssize_t recvfrom(int fd, const void *buf, size_t size, int flags,
|
||||
const void *sockaddr, socklen_t addrlen) {
|
||||
ssize_t nrecv;
|
||||
asm volatile(
|
||||
"mov %5, %%r10\n"
|
||||
asm volatile("mov %5, %%r10\n"
|
||||
"mov %6, %%r8\n"
|
||||
"mov %7, %%r9\n"
|
||||
"syscall\n"
|
||||
: "=a"(nrecv)
|
||||
: "a"(SYS_RECVFROM), "D"(fd), "S"(buf), "d"(size), "r"((int64_t)flags), "r"(sockaddr), "r"((int64_t)addrlen)
|
||||
: "rcx", "r11", "memory"
|
||||
);
|
||||
: "a"(SYS_RECVFROM), "D"(fd), "S"(buf), "d"(size),
|
||||
"r"((int64_t)flags), "r"(sockaddr), "r"((int64_t)addrlen)
|
||||
: "rcx", "r11", "memory");
|
||||
return nrecv;
|
||||
}
|
||||
|
||||
#define SYS_CLOCK_SETTIME 227
|
||||
int clock_settime(clockid_t clockid, const struct timespec *tp) {
|
||||
int rtn;
|
||||
asm volatile(
|
||||
"syscall\n"
|
||||
asm volatile("syscall\n"
|
||||
: "=a"(rtn)
|
||||
: "a"(SYS_CLOCK_SETTIME), "D"(clockid), "S"(tp)
|
||||
: "rcx", "r11"
|
||||
);
|
||||
: "rcx", "r11");
|
||||
return rtn;
|
||||
}
|
||||
|
||||
#define SYS_CLOCK_GETTIME 228
|
||||
int clock_gettime(clockid_t clockid, struct timespec *tp) {
|
||||
int rtn;
|
||||
asm volatile(
|
||||
"syscall\n"
|
||||
asm volatile("syscall\n"
|
||||
: "=a"(rtn)
|
||||
: "a"(SYS_CLOCK_GETTIME), "D"(clockid), "S"(tp)
|
||||
: "rcx", "r11", "memory"
|
||||
);
|
||||
: "rcx", "r11", "memory");
|
||||
return rtn;
|
||||
}
|
||||
|
||||
#define SYS_CLOCK_GETRES 229
|
||||
int clock_getres(clockid_t clockid, struct timespec *res) {
|
||||
int rtn;
|
||||
asm volatile(
|
||||
"syscall\n"
|
||||
asm volatile("syscall\n"
|
||||
: "=a"(rtn)
|
||||
: "a"(SYS_CLOCK_GETRES), "D"(clockid), "S"(res)
|
||||
: "rcx", "r11", "memory"
|
||||
);
|
||||
: "rcx", "r11", "memory");
|
||||
return rtn;
|
||||
}
|
||||
|
||||
#define SYS_CLOCK_NANOSLEEP 230
|
||||
int clock_nanosleep(clockid_t clockid, int flags, const struct timespec *t, struct timespec* remain){
|
||||
int clock_nanosleep(clockid_t clockid, int flags, const struct timespec *t,
|
||||
struct timespec *remain) {
|
||||
int rtn;
|
||||
asm volatile(
|
||||
"mov %5, %%r10\n"
|
||||
asm volatile("mov %5, %%r10\n"
|
||||
"syscall\n"
|
||||
: "=a"(rtn)
|
||||
: "a"(SYS_CLOCK_NANOSLEEP), "D"(clockid), "S"(flags), "d"(t), "r"(remain)
|
||||
: "rcx", "r11", "memory"
|
||||
);
|
||||
: "a"(SYS_CLOCK_NANOSLEEP), "D"(clockid), "S"(flags), "d"(t),
|
||||
"r"(remain)
|
||||
: "rcx", "r11", "memory");
|
||||
return rtn;
|
||||
}
|
||||
|
||||
#define SYS_RT_SIGACTION 13
|
||||
int rt_sigaction(int signum, const void *act, void *oldact, size_t sigset_len) {
|
||||
int rtn;
|
||||
asm volatile(
|
||||
"mov %5, %%r10\n"
|
||||
asm volatile("mov %5, %%r10\n"
|
||||
"syscall\n"
|
||||
: "=a"(rtn)
|
||||
: "a"(SYS_RT_SIGACTION), "D"(signum), "S"(act), "d"(oldact), "r"(sigset_len)
|
||||
: "rcx", "r11", "memory"
|
||||
);
|
||||
: "a"(SYS_RT_SIGACTION), "D"(signum), "S"(act), "d"(oldact),
|
||||
"r"(sigset_len)
|
||||
: "rcx", "r11", "memory");
|
||||
return rtn;
|
||||
}
|
||||
|
||||
|
||||
55
buildtest.c
55
buildtest.c
@@ -1,6 +1,22 @@
|
||||
#include "int.h"
|
||||
#include "sys.h"
|
||||
|
||||
#define print(str) write(STDOUT, str, (sizeof str) - 1)
|
||||
void printhex(uint64_t num) {
|
||||
char msg[17] = {' '};
|
||||
msg[16] = '\n';
|
||||
for (int i = 0; i < 16; ++i) {
|
||||
char nibble = (num >> ((15 - i) * 4)) & 0xf;
|
||||
char c;
|
||||
if (nibble > 9) {
|
||||
c = nibble + '7';
|
||||
} else {
|
||||
c = nibble + '0';
|
||||
}
|
||||
msg[i] = c;
|
||||
}
|
||||
write(STDOUT, msg, 17);
|
||||
}
|
||||
|
||||
int main(int argc, char* argv[]) {
|
||||
// Test the write syscall
|
||||
@@ -17,27 +33,32 @@ int main(int argc, char* argv[]) {
|
||||
// Test the fork syscall
|
||||
uint64_t pid = fork();
|
||||
// Print the pid in hex
|
||||
char msg[17] = {' '};
|
||||
msg[16] = '\n';
|
||||
for(int i = 0; i < 16; ++i) {
|
||||
char nibble = (pid >> ((15 - i) * 4)) & 0xf;
|
||||
char c;
|
||||
if (nibble > 9) {c = nibble + '7';}
|
||||
else {c = nibble + '0';}
|
||||
msg[i] = c;
|
||||
printhex(pid);
|
||||
// Child process
|
||||
if (pid == 0) {
|
||||
const char *progname = "/bin/sh";
|
||||
const char *argv[4] = {
|
||||
progname,
|
||||
"-c",
|
||||
"echo hi from sh",
|
||||
0,
|
||||
};
|
||||
const char **envp = {0};
|
||||
int32_t err = execve(progname, argv, envp);
|
||||
// return with error code if execve fails
|
||||
return err;
|
||||
}
|
||||
write(STDOUT, msg, 17);
|
||||
|
||||
// Child process exits
|
||||
if(pid == 0) return 0;
|
||||
//TODO: wait on child to remove zombie process
|
||||
int status; // Note: this is not JUST the exit code of the child
|
||||
waitpid(pid, &status, 0);
|
||||
print("Child wstatus: ");
|
||||
printhex((uint64_t)status);
|
||||
|
||||
// Test the read syscall
|
||||
#define INPUT_BUFFER_LEN 4096
|
||||
char input_buffer[INPUT_BUFFER_LEN] = {0};
|
||||
int32_t fout = openc("outfile", O_RDWR | O_CREAT | O_TRUNC, 0664);
|
||||
|
||||
write(STDOUT, "Enter some text:", 16);
|
||||
print("Enter some text:");
|
||||
intptr_t n_read = read(STDIN, input_buffer, INPUT_BUFFER_LEN);
|
||||
write(STDOUT, input_buffer, n_read);
|
||||
if(fout > 0) {
|
||||
@@ -55,15 +76,15 @@ int main(int argc, char* argv[]) {
|
||||
i = read(file, input_buffer, INPUT_BUFFER_LEN);
|
||||
}
|
||||
} else {
|
||||
write(STDOUT, "Could not open /proc/version\n", 29);
|
||||
print("Could not open /proc/version\n");
|
||||
}
|
||||
|
||||
// Test sleep
|
||||
write(STDOUT, "Sleeping for 5 secs\n", 20);
|
||||
print("Sleeping for 5 secs\n");
|
||||
struct timespec sleeptime;
|
||||
sleeptime.tv_sec = 5;
|
||||
while (nanosleep(&sleeptime, &sleeptime) != 0) {}
|
||||
write(STDOUT, "DONE\n", 5);
|
||||
print("DONE\n");
|
||||
|
||||
return 69;
|
||||
}
|
||||
|
||||
@@ -9,7 +9,7 @@ int main() {
|
||||
server.sin_family = AF_INET;
|
||||
server.sin_addr.s_addr = INADDR_ANY;
|
||||
|
||||
#if defined(__mips__)
|
||||
#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
|
||||
server.sin_port = 6969;
|
||||
#else
|
||||
server.sin_port = 0x391b;
|
||||
|
||||
133
stackdump.c
Normal file
133
stackdump.c
Normal file
@@ -0,0 +1,133 @@
|
||||
#include "sys.h"
|
||||
#include "int.h"
|
||||
|
||||
/*
|
||||
Line format: "AAAAAAAAAAAAAAAA BBBB BBBB BBBB BBBB CCCCCCCC\n"
|
||||
16: hex ptr
|
||||
2: space
|
||||
4: 2 hex bytes data
|
||||
1: space
|
||||
4: 2 hex bytes data
|
||||
1: space
|
||||
4: 2 hex bytes data
|
||||
1: space
|
||||
4: 2 hex bytes data
|
||||
2: space
|
||||
8: 8 char bytes data
|
||||
1: new line
|
||||
---
|
||||
48: total bytes
|
||||
|
||||
# s0: original sp
|
||||
# s1: buffer start pointer
|
||||
# s2: line counter
|
||||
# s3: current data being printed (both addr and *addr)
|
||||
# s4: nibble/byte offset
|
||||
# s5: current nibble (both binary and ascii hex)
|
||||
# s6: current buffer position pointer
|
||||
*/
|
||||
#if defined(__x86_64__) || defined(__aarch64__)
|
||||
#define WRD_LEN 64
|
||||
typedef uint64_t word_t;
|
||||
#define SIZEOF_WORD_T 8
|
||||
#define LEN 48
|
||||
#elif defined(__mips__)
|
||||
#define WRD_LEN 32
|
||||
typedef uint32_t word_t;
|
||||
#define SIZEOF_WORD_T 4
|
||||
#define LEN 26
|
||||
#endif
|
||||
|
||||
#define NIBBLE_LEN 4
|
||||
#define CHAR_LEN 8
|
||||
//uint64_t* sp; // Original sp
|
||||
char* sp; // Original sp
|
||||
char* fp; // frame pointer
|
||||
char buff[LEN]; // buffer pointer
|
||||
int line; // line counter
|
||||
word_t data; // Current data
|
||||
int offset; // nibble/char offset
|
||||
int nibble; // current nibble/char
|
||||
char* pos; // buffer position
|
||||
|
||||
// Compile with -D _START_DEFINED
|
||||
#if defined(__mips__)
|
||||
void __start() {
|
||||
#else
|
||||
void _start() {
|
||||
#endif /* ifndef defined(__mips__) */
|
||||
// Save stack pointer
|
||||
#if defined(__x86_64__)
|
||||
asm volatile("mov %%rsp, %0\n" : "=r"(sp));
|
||||
#elif defined(__mips__)
|
||||
asm volatile("move %0, $sp\n" : "=r"(sp));
|
||||
#elif defined(__aarch64__)
|
||||
asm volatile("mov %0, sp\n" : "=r"(sp));
|
||||
#else
|
||||
#error arch not supported
|
||||
#endif
|
||||
fp = __builtin_frame_address(0);
|
||||
//fp = __builtin_return_address(0);
|
||||
|
||||
//if(fp != sp) exit(sp - fp);
|
||||
// Clear buffer with spaces and newline
|
||||
for(pos=buff; pos < buff+LEN-1; ++pos) *pos = ' ';
|
||||
buff[LEN-1] = '\n';
|
||||
|
||||
// Add some vars to see how ith changes the stack
|
||||
// volatile word_t padd = 0x11;
|
||||
// volatile word_t padd2 = 0x12;
|
||||
|
||||
// Loop until segfault
|
||||
for(line = 0;;line += 1) {
|
||||
// Load address of next word into data
|
||||
data = (word_t)((line*SIZEOF_WORD_T) + sp);
|
||||
if(fp == (char*)data) write(STDOUT, "FP\n", 3);
|
||||
// reset buffer position
|
||||
pos = buff;
|
||||
|
||||
// print addr in hex //
|
||||
for(offset=WRD_LEN-NIBBLE_LEN; offset >= 0; offset -= NIBBLE_LEN) {
|
||||
nibble = (data >> offset) & 0x0f; // store current nibble in nibble
|
||||
// convert nibble to hex
|
||||
nibble = nibble + '0';
|
||||
if(nibble > '9') nibble = nibble + 7;
|
||||
// write hex char to buffer
|
||||
*pos = nibble;
|
||||
pos += 1;
|
||||
}
|
||||
|
||||
// Print data as hex //
|
||||
pos += 2; // Add 2 padded spaces
|
||||
data = *(word_t*)data; // Load data into data
|
||||
for(offset=WRD_LEN-NIBBLE_LEN; offset>=0; offset -= NIBBLE_LEN) {
|
||||
nibble = (data >> offset) & 0x0f; // Store current nibble in nibble
|
||||
// Convert nibble to hex char
|
||||
nibble = nibble + '0';
|
||||
if(nibble > '9') nibble = nibble + 7;
|
||||
// Write hex char to buffer
|
||||
*pos = nibble;
|
||||
pos += 1;
|
||||
// Add space every 2 bytes (4 nibbles)
|
||||
if((offset % 16) == 0) pos += 1;
|
||||
}
|
||||
|
||||
pos += 1;
|
||||
|
||||
// Print data as char //
|
||||
#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
|
||||
for(offset = WRD_LEN - CHAR_LEN; offset >= 0; offset -= CHAR_LEN) {
|
||||
#else
|
||||
for(offset = 0; offset < WRD_LEN; offset += CHAR_LEN) {
|
||||
#endif /* ifndef defined(__mips__) */
|
||||
nibble = (data >> offset) & 0xff; // Store current char in nibble
|
||||
if((nibble < ' ') || (nibble > '~')) *pos = '~'; // Use placeholder for non printable chars
|
||||
else *pos = nibble; // Write printable char
|
||||
pos += 1;
|
||||
}
|
||||
|
||||
// Write to STDOUT //
|
||||
write(STDOUT, buff, LEN);
|
||||
fsync(STDOUT);
|
||||
}
|
||||
}
|
||||
2
sys.h
2
sys.h
@@ -141,6 +141,8 @@ int clock_nanosleep(clockid_t clockid, int flags, const struct timespec *t, stru
|
||||
#define nanosleep(t, remain) clock_nanosleep(CLOCK_MONOTONIC, 0, t, remain)
|
||||
|
||||
uint32_t fork();
|
||||
int32_t execve(const char* filename, const char* argv[], const char* envp[]);
|
||||
uint32_t waitpid(uint32_t pid, int* wstatus, int options);
|
||||
|
||||
void *memset(void* s, int c, unsigned long n);
|
||||
int strlen(char* s);
|
||||
|
||||
Reference in New Issue
Block a user