Commit 7ec30fa
Changed files (3)
platform
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