Commit 7ec30fa

kravantokh <kravantokh@noreply.codeberg.org>
2026-07-04 17:05:27
Add linux syscall wrappers.
1 parent a932036
platform/linux/syscall_wrappers_gcclike.h
@@ -0,0 +1,111 @@
+#ifndef HEADER_PLATFORM_LINUX_SYSCALL_WRAPPERS_GCCLIKE_INCLUDED
+#define HEADER_PLATFORM_LINUX_SYSCALL_WRAPPERS_GCCLIKE_INCLUDED
+
+#include "./coretypes.h"
+
+X86_64(
+
+	/* All this mess, just so *maybe* the compiler can optimize register usage when inlining. Check the generic wrappers for a more typical way of going about this. This here is unusual, from what I have seen. */
+	static inline syscall_uint linux_syscall1(syscall_uint num, syscall_uint arg1) {
+			register syscall_uint ret __asm__("rax") = num;
+
+			register syscall_uint a1 __asm__("rdi") = arg1;
+
+			__asm__ volatile(
+				"syscall\n"
+				: "+r"(ret)
+				: "r"(a1)
+				: "rcx", "r11", "memory"
+			);
+		return ret;
+	}
+	static inline syscall_uint linux_syscall2(syscall_uint num, syscall_uint arg1, syscall_uint arg2) {
+			register syscall_uint ret __asm__("rax") = num;
+
+			register syscall_uint a1 __asm__("rdi") = arg1;
+			register syscall_uint a2 __asm__("rsi") = arg2;
+
+			__asm__ volatile(
+				"syscall\n"
+				: "+r"(ret)
+				: "r"(a1), "r"(a2)
+				: "rcx", "r11", "memory"
+			);
+		return ret;
+	}
+	static inline syscall_uint linux_syscall3(syscall_uint num, syscall_uint arg1, syscall_uint arg2, syscall_uint arg3) {
+			register syscall_uint ret __asm__("rax") = num;
+
+			register syscall_uint a1 __asm__("rdi") = arg1;
+			register syscall_uint a2 __asm__("rsi") = arg2;
+			register syscall_uint a3 __asm__("rdx") = arg3;
+
+			__asm__ volatile(
+				"syscall\n"
+				: "+r"(ret)
+				: "r"(a1), "r"(a2), "r"(a3)
+				: "rcx", "r11", "memory"
+			);
+		return ret;
+	}
+	static inline syscall_uint linux_syscall4(syscall_uint num, syscall_uint arg1, syscall_uint arg2, syscall_uint arg3, syscall_uint arg4) {
+			register syscall_uint ret __asm__("rax") = num;
+
+			register syscall_uint a1 __asm__("rdi") = arg1;
+			register syscall_uint a2 __asm__("rsi") = arg2;
+			register syscall_uint a3 __asm__("rdx") = arg3;
+			register syscall_uint a4 __asm__("r10") = arg4;
+
+			__asm__ volatile(
+				"syscall\n"
+				: "+r"(ret)
+				: "r"(a1), "r"(a2), "r"(a3), "r"(a4)
+				: "rcx", "r11", "memory"
+			);
+		return ret;
+	}
+
+	static inline syscall_uint linux_syscall5(syscall_uint num, syscall_uint arg1, syscall_uint arg2, syscall_uint arg3, syscall_uint arg4, syscall_uint arg5) {
+			register syscall_uint ret __asm__("rax") = num;
+
+			register syscall_uint a1 __asm__("rdi") = arg1;
+			register syscall_uint a2 __asm__("rsi") = arg2;
+			register syscall_uint a3 __asm__("rdx") = arg3;
+			register syscall_uint a4 __asm__("r10") = arg4;
+			register syscall_uint a5 __asm__("r8") = arg5;
+
+			__asm__ volatile(
+				"syscall\n"
+				: "+r"(ret)
+				: "r"(a1), "r"(a2), "r"(a3), "r"(a4), "r"(a5)
+				: "rcx", "r11", "memory"
+			);
+		return ret;
+	}
+
+	static inline syscall_uint linux_syscall6(syscall_uint num, syscall_uint arg1, syscall_uint arg2, syscall_uint arg3, syscall_uint arg4, syscall_uint arg5, syscall_uint arg6) {
+			register syscall_uint ret __asm__("rax") = num;
+
+			register syscall_uint a1 __asm__("rdi") = arg1;
+			register syscall_uint a2 __asm__("rsi") = arg2;
+			register syscall_uint a3 __asm__("rdx") = arg3;
+			register syscall_uint a4 __asm__("r10") = arg4;
+			register syscall_uint a5 __asm__("r8") = arg5;
+			register syscall_uint a6 __asm__("r9") = arg6;
+
+			__asm__ volatile(
+				"syscall\n"
+				: "+r"(ret)
+				: "r"(a1), "r"(a2), "r"(a3), "r"(a4), "r"(a5), "r"(a6)
+				: "rcx", "r11", "memory"
+			);
+		return ret;
+	}
+)
+
+
+I386(
+	ERROR("Linux syscalls not implemented for I386.");
+)
+
+#endif
platform/linux/syscall_wrappers_generic.h
@@ -0,0 +1,92 @@
+#ifndef HEADER_PLATFORM_LINUX_SYSCALL_WRAPPERS_GCCLIKE_INCLUDED
+#define HEADER_PLATFORM_LINUX_SYSCALL_WRAPPERS_GCCLIKE_INCLUDED
+
+#include "./coretypes.h"
+
+
+X86_64(
+
+	static inline syscall_uint linux_syscall1(syscall_uint num, syscall_uint arg1) {
+		__asm__ volatile (
+			"mov %[a1], %%rdi\n"
+			"syscall\n"
+			: [num]"+a"(num)
+			: [a1]"r"(arg1)
+			: "rcx", "r11", "memory"
+		);
+		return num;
+	}
+
+	static inline syscall_uint linux_syscall2(syscall_uint num, syscall_uint arg1, syscall_uint arg2) {
+		__asm__ volatile (
+			"mov %[a1], %%rdi\n"
+			"mov %[a2], %%rsi\n"
+			"syscall\n"
+			: [num]"+a"(num)
+			: [a1]"r"(arg1), [a2]"r"(arg2)
+			: "rcx", "r11", "memory"
+		);
+		return num;
+	}
+	static inline syscall_uint linux_syscall3(syscall_uint num, syscall_uint arg1, syscall_uint arg2, syscall_uint arg3) {
+		__asm__ volatile (
+			"mov %[a1], %%rdi\n"
+			"mov %[a2], %%rsi\n"
+			"mov %[a3], %%rdx\n"
+			"syscall\n"
+			: [num]"+a"(num)
+			: [a1]"r"(arg1), [a2]"r"(arg2), [a3]"r"(arg3)
+			: "rcx", "r11", "memory"
+		);
+		return num;
+	}
+	static inline syscall_uint linux_syscall4(syscall_uint num, syscall_uint arg1, syscall_uint arg2, syscall_uint arg3, syscall_uint arg4) {
+		__asm__ volatile (
+			"mov %[a1], %%rdi\n"
+			"mov %[a2], %%rsi\n"
+			"mov %[a3], %%rdx\n"
+			"mov %[a4], %%r10\n"
+			"syscall\n"
+			: [num]"+a"(num)
+			: [a1]"r"(arg1), [a2]"r"(arg2), [a3]"r"(arg3), [a4]"r"(arg4)
+			: "rcx", "r11", "memory"
+		);
+		return num;
+	}
+	static inline syscall_uint linux_syscall5(syscall_uint num, syscall_uint arg1, syscall_uint arg2, syscall_uint arg3, syscall_uint arg4, syscall_uint arg5) {
+		__asm__ volatile (
+			"mov %[a1], %%rdi\n"
+			"mov %[a2], %%rsi\n"
+			"mov %[a3], %%rdx\n"
+			"mov %[a4], %%r10\n"
+			"mov %[a5], %%r8\n"
+			: [num]"+a"(num)
+			: [a1]"r"(arg1), [a2]"r"(arg2), [a3]"r"(arg3), [a4]"r"(arg4), [a5]"r"(arg5)
+			: "rcx", "r11", "memory"
+		);
+		return num;
+	}
+
+	static inline syscall_uint linux_syscall6(syscall_uint num, syscall_uint arg1, syscall_uint arg2, syscall_uint arg3, syscall_uint arg4, syscall_uint arg5, syscall_uint arg6) {
+		__asm__ volatile (
+			"mov %[a1], %%rdi\n"
+			"mov %[a2], %%rsi\n"
+			"mov %[a3], %%rdx\n"
+			"mov %[a4], %%r10\n"
+			"mov %[a5], %%r8\n"
+			"mov %[a6], %%r9\n"
+			"syscall\n"
+			: [num]"+a"(num)
+			: [a1]"r"(arg1), [a2]"r"(arg2), [a3]"r"(arg3), [a4]"r"(arg4), [a5]"r"(arg5), [a6]"r"(arg6)
+			: "rcx", "r11", "memory"
+		);
+		return num;
+	}
+
+)
+
+I386(
+	ERROR("Linux syscalls not implemented for I386.");
+)
+
+#endif
platform/linux/syscalls.h
@@ -0,0 +1,21 @@
+#ifndef HEADER_PLATFORM_LINUX_SYSCALLS_INCLUDED
+#define HEADER_PLATFORM_LINUX_SYSCALLS_INCLUDED
+
+#include "../common/arch.h"
+#include "../common/compiler.h"
+#include "./coretypes.h"
+
+static inline syscall_uint linux_syscall1(syscall_uint num, syscall_uint arg1);
+static inline syscall_uint linux_syscall2(syscall_uint num, syscall_uint arg1, syscall_uint arg2);
+static inline syscall_uint linux_syscall3(syscall_uint num, syscall_uint arg1, syscall_uint arg2, syscall_uint arg3);
+static inline syscall_uint linux_syscall4(syscall_uint num, syscall_uint arg1, syscall_uint arg2, syscall_uint arg3, syscall_uint arg4);
+static inline syscall_uint linux_syscall5(syscall_uint num, syscall_uint arg1, syscall_uint arg2, syscall_uint arg3, syscall_uint arg4, syscall_uint arg5);
+static inline syscall_uint linux_syscall6(syscall_uint num, syscall_uint arg1, syscall_uint arg2, syscall_uint arg3, syscall_uint arg4, syscall_uint arg5, syscall_uint arg6);
+
+#if COMPILER == COMPILER_GCC || COMPILER == COMPILER_CLANG
+	#include "./syscall_wrappers_gcclike.h"
+#else
+	#include "./syscall_wrappers_generic.h"
+#endif
+
+#endif