From 1d2a6f21294f8390b683e4e097cb49210ed832d1 Mon Sep 17 00:00:00 2001
From: johannst <johannes.stoelp@gmail.com>
Date: Fri, 26 Mar 2021 23:17:46 +0100
Subject: Added dyn allocator + syscall wrappers + minor fixes.

---
 lib/include/alloc.h    |  6 ++++++
 lib/include/auxv.h     |  2 +-
 lib/include/common.h   | 18 ++++++++----------
 lib/include/syscall.h  | 33 ++++++++++++++++++++++++---------
 lib/include/syscalls.h | 23 +++++++++++++++++++++++
 5 files changed, 62 insertions(+), 20 deletions(-)
 create mode 100644 lib/include/alloc.h
 create mode 100644 lib/include/syscalls.h

(limited to 'lib/include')

diff --git a/lib/include/alloc.h b/lib/include/alloc.h
new file mode 100644
index 0000000..baf8d3d
--- /dev/null
+++ b/lib/include/alloc.h
@@ -0,0 +1,6 @@
+// Copyright (c) 2021 Johannes Stoelp
+
+#pragma once
+
+void* alloc(unsigned size);
+void dealloc(void* ptr);
diff --git a/lib/include/auxv.h b/lib/include/auxv.h
index 42dac38..1ac953e 100644
--- a/lib/include/auxv.h
+++ b/lib/include/auxv.h
@@ -15,7 +15,7 @@
 #define AT_EXECFD  2  /* [val] File descriptor of user program (in case Linux Kernel didn't mapped) */
 #define AT_PHDR    3  /* [ptr] Address of Phdr of use program (in case Kernel mapped user program) */
 #define AT_PHENT   4  /* [val] Size in bytes of one Phdr entry */
-#define AT_PHNUM   5  /* [val] Number of Phread entries */
+#define AT_PHNUM   5  /* [val] Number of Phdr entries */
 #define AT_PAGESZ  6  /* [val] System page size */
 #define AT_BASE    7  /* [ptr] `base address` interpreter was loaded to */
 #define AT_FLAGS   8  /* [val] */
diff --git a/lib/include/common.h b/lib/include/common.h
index 5ea6050..631c25f 100644
--- a/lib/include/common.h
+++ b/lib/include/common.h
@@ -3,14 +3,12 @@
 #pragma once
 
 #include "io.h"
-#include "syscall.h"
-
-#include <asm/unistd.h>
-
-#define ERROR_ON(cond, ...)         \
-    do {                            \
-        if ((cond)) {               \
-            efmt(__VA_ARGS__);      \
-            syscall1(__NR_exit, 1); \
-        }                           \
+#include "syscalls.h"
+
+#define ERROR_ON(cond, fmt, ...)                                               \
+    do {                                                                       \
+        if ((cond)) {                                                          \
+            efmt("%s:%d " fmt, __FILE__, __LINE__ __VA_OPT__(, ) __VA_ARGS__); \
+            _exit(1);                                                          \
+        }                                                                      \
     } while (0)
diff --git a/lib/include/syscall.h b/lib/include/syscall.h
index 4947155..c9314d2 100644
--- a/lib/include/syscall.h
+++ b/lib/include/syscall.h
@@ -35,29 +35,44 @@
 //   https://gcc.gnu.org/onlinedocs/gcc/Extended-Asm.html
 //   https://gcc.gnu.org/onlinedocs/gcc/Machine-Constraints.html#Machine-Constraints
 //   https://gcc.gnu.org/onlinedocs/gcc/Local-Register-Variables.html
-
-// Linux syscall ABI
-//  x86-64
-//    #syscall: rax
-//    ret     : rax
-//    instr   : syscall
-//    args    : rdi   rsi   rdx   r10   r8    r9
+//
+//
+// Linux syscall ABI - x86-64
+//   #syscall: rax
+//   ret     : rax
+//   instr   : syscall
+//   args    : rdi   rsi   rdx   r10   r8    r9
 //
 // Reference:
 //   syscall(2)
+//
+//
+// X86_64 `syscall` instruction additionally clobbers following registers:
+//   rcx   Store return address.
+//   r11   Store RFLAGS.
+//
+// Reference:
+//   https://www.felixcloutier.com/x86/syscall
 
 #define argcast(A)              ((long)(A))
 #define syscall1(n, a1)         _syscall1(n, argcast(a1))
+#define syscall2(n, a1, a2)     _syscall2(n, argcast(a1), argcast(a2))
 #define syscall3(n, a1, a2, a3) _syscall3(n, argcast(a1), argcast(a2), argcast(a3))
 
 static inline long _syscall1(long n, long a1) {
     long ret;
-    asm volatile("syscall" : "=a"(ret) : "a"(n), "D"(a1) : "memory");
+    asm volatile("syscall" : "=a"(ret) : "a"(n), "D"(a1) : "rcx", "r11", "memory");
+    return ret;
+}
+
+static inline long _syscall2(long n, long a1, long a2) {
+    long ret;
+    asm volatile("syscall" : "=a"(ret) : "a"(n), "D"(a1), "S"(a2) : "rcx", "r11", "memory");
     return ret;
 }
 
 static inline long _syscall3(long n, long a1, long a2, long a3) {
     long ret;
-    asm volatile("syscall" : "=a"(ret) : "a"(n), "D"(a1), "S"(a2), "d"(a3) : "memory");
+    asm volatile("syscall" : "=a"(ret) : "a"(n), "D"(a1), "S"(a2), "d"(a3) : "rcx", "r11", "memory");
     return ret;
 }
diff --git a/lib/include/syscalls.h b/lib/include/syscalls.h
new file mode 100644
index 0000000..34b6b37
--- /dev/null
+++ b/lib/include/syscalls.h
@@ -0,0 +1,23 @@
+// Copyright (c) 2021 Johannes Stoelp
+
+#pragma once
+
+#include <stddef.h>     // size_t
+#include <sys/types.h>  // ssize_t, off_t, ...
+
+// Syscall definitions taken from corresponding man pages, eg
+//   open(2)
+//   read(2)
+//   ...
+
+#define O_RDONLY 00
+int open(const char* path, int flags);
+
+ssize_t read(int fd, void* buf, size_t count);
+
+#define SEEK_SET 0
+#define SEEK_CUR 1
+#define SEEK_END 2
+off_t lseek(int fd, off_t offset, int whence);
+
+void _exit(int status);
-- 
cgit v1.2.3