changeset 339:4f9f49fb82ce

- x64 SysV syscall support
author Tassilo Philipp
date Sat, 04 Jan 2020 01:07:49 +0100
parents ee2b6e54b074
children 6e33db95e724
files ChangeLog ToDo dyncall/dyncall.h dyncall/dyncall_call_x64.S dyncall/dyncall_call_x64.h dyncall/dyncall_callvm_x64.c dyncall/dyncall_callvm_x86.c
diffstat 7 files changed, 89 insertions(+), 12 deletions(-) [+]
line wrap: on
line diff
--- a/ChangeLog	Fri Jan 03 22:48:20 2020 +0100
+++ b/ChangeLog	Sat Jan 04 01:07:49 2020 +0100
@@ -3,6 +3,7 @@
 Version 1.1 (upcoming)
 dyncall:
   o support for soft-float MIPS o32 & n64 (big- and little-endian, each)
+  o x64 System V syscall support
 dyncallback:
   o support for soft-float MIPS o32 & n64 (big- and little-endian, each)
 dynload:
--- a/ToDo	Fri Jan 03 22:48:20 2020 +0100
+++ b/ToDo	Sat Jan 04 01:07:49 2020 +0100
@@ -64,9 +64,6 @@
 - consider automatic type-promotion for arguments passed through DC_CALL_C_ELLIPSIS_VARARGS;
   this would make it easier to just pass arguments instead of having to know about the C
   type promotions (this is partly done, see todo-item above under 1.1)
-- syscalls for x64
-  * bsd
-  * linux
 - other syscalls
 - test MIPS32 eabi big endian (current port works on psp, which is little endian)
 - implement MIPS64 N32 (gcc -mabi=n32); both, little and big-endian (looks like NetNBSD on and
--- a/dyncall/dyncall.h	Fri Jan 03 22:48:20 2020 +0100
+++ b/dyncall/dyncall.h	Sat Jan 04 01:07:49 2020 +0100
@@ -6,7 +6,7 @@
  Description: public header for library dyncall
  License:
 
-   Copyright (c) 2007-2018 Daniel Adler <dadler@uni-goettingen.de>, 
+   Copyright (c) 2007-2020 Daniel Adler <dadler@uni-goettingen.de>, 
                            Tassilo Philipp <tphilipp@potion-studios.com>
 
    Permission to use, copy, modify, and distribute this software for any
@@ -83,6 +83,7 @@
 #define DC_CALL_SYS_DEFAULT           200
 #define DC_CALL_SYS_X86_INT80H_LINUX  201
 #define DC_CALL_SYS_X86_INT80H_BSD    202
+#define DC_CALL_SYS_X64_SYSCALL_SYSV  204
 #define DC_CALL_SYS_PPC32             210
 #define DC_CALL_SYS_PPC64             211
 
--- a/dyncall/dyncall_call_x64.S	Fri Jan 03 22:48:20 2020 +0100
+++ b/dyncall/dyncall_call_x64.S	Sat Jan 04 01:07:49 2020 +0100
@@ -6,7 +6,7 @@
  Description: All x64 abi call kernel implementation
  License:
 
-   Copyright (c) 2007-2018 Daniel Adler <dadler@uni-goettingen.de>,
+   Copyright (c) 2007-2020 Daniel Adler <dadler@uni-goettingen.de>,
                            Tassilo Philipp <tphilipp@potion-studios.com>
 
    Permission to use, copy, modify, and distribute this software for any
@@ -60,7 +60,7 @@
 
 	ADD(LIT(31),RDI)		/* Align stack to 32-byte. */
 	AND(LIT(-32),RDI)
-	ADD(LIT(8),RDI)		/* Adjust by 8-byte for the return-address. */
+	ADD(LIT(8),RDI)			/* Adjust by 8-byte for the return-address. */
 	SUB(RDI,RSP)			/* Setup stack frame by subtracting the size of arguments. */
 
 	MOV(RDI,RCX)			/* Store number of bytes to copy to stack in RCX (for rep movsb). */
@@ -143,5 +143,30 @@
 
 END_PROC(dcCall_x64_win64)
 
+/*---------------------------------------------------------------------------
+
+  Call Kernel for x64 System V syscalls
+
+  Input:
+    RDI : pointer to arguments
+    RSI : syscall id
+
+*/
+	
+GLOBAL(dcCall_x64_sys_syscall_sysv)
+BEGIN_PROC(dcCall_x64_sys_syscall_sysv)
+
+	MOV(RSI,RAX)			/* load system call id. */
+	MOV(QWORD(RDI,40),R9)		/* copy first six int/pointer arguments to RDI, RSI, RDX, R10, R8, R9. */
+	MOV(QWORD(RDI,32),R8)
+	MOV(QWORD(RDI,24),R10)
+	MOV(QWORD(RDI,16),RDX)
+	MOV(QWORD(RDI,8),RSI)
+	MOV(QWORD(RDI,0),RDI)		/* Set RDI last to not overwrite it to soon. */
+	SYSCALL
+	RET()
+
+END_PROC(dcCall_x64_sys_syscall_sysv)
+
 END_ASM
 
--- a/dyncall/dyncall_call_x64.h	Fri Jan 03 22:48:20 2020 +0100
+++ b/dyncall/dyncall_call_x64.h	Sat Jan 04 01:07:49 2020 +0100
@@ -6,7 +6,7 @@
  Description: 
  License:
 
-   Copyright (c) 2007-2018 Daniel Adler <dadler@uni-goettingen.de>, 
+   Copyright (c) 2007-2020 Daniel Adler <dadler@uni-goettingen.de>, 
                            Tassilo Philipp <tphilipp@potion-studios.com>
 
    Permission to use, copy, modify, and distribute this software for any
@@ -54,6 +54,7 @@
 
 void dcCall_x64_sysv(DCsize stacksize, DCpointer stackdata, DCpointer regdata_i, DCpointer regdata_f, DCpointer target);
 void dcCall_x64_win64(DCsize stacksize, DCpointer stackdata, DCpointer regdata, DCpointer target);
+void dcCall_x64_sys_syscall_sysv(DCpointer argdata, DCpointer target);
 
 #ifdef __cplusplus
 }
--- a/dyncall/dyncall_callvm_x64.c	Fri Jan 03 22:48:20 2020 +0100
+++ b/dyncall/dyncall_callvm_x64.c	Sat Jan 04 01:07:49 2020 +0100
@@ -6,7 +6,7 @@
  Description: 
  License:
 
-   Copyright (c) 2007-2018 Daniel Adler <dadler@uni-goettingen.de>, 
+   Copyright (c) 2007-2020 Daniel Adler <dadler@uni-goettingen.de>, 
                            Tassilo Philipp <tphilipp@potion-studios.com>
 
    Permission to use, copy, modify, and distribute this software for any
@@ -167,7 +167,7 @@
 , &dc_callvm_mode_x64
 , &dc_callvm_argBool_x64
 , &dc_callvm_argChar_x64
-, &dc_callvm_argShort_x64 
+, &dc_callvm_argShort_x64
 , &dc_callvm_argInt_x64
 , &dc_callvm_argLong_x64
 , &dc_callvm_argLongLong_x64
@@ -188,7 +188,52 @@
 , NULL /* callStruct */
 };
 
-/* mode: only a single mode available currently. */
+
+/* --- syscall ------------------------------------------------------------- */
+
+#include <assert.h>
+void dc_callvm_call_x64_sys_syscall_sysv(DCCallVM* in_self, DCpointer target)
+{
+  /* syscalls can have up to 6 args, required to be "Only values of class INTEGER or class MEMORY" (from */
+  /* SysV manual), so we can use self->mRegData.i directly; verify this holds at least 6 values, though. */
+  assert(numIntRegs >= 6);
+
+  DCCallVM_x64* self = (DCCallVM_x64*)in_self;
+  dcCall_x64_sys_syscall_sysv(self->mRegData.i, target);
+}
+
+DCCallVM_vt gVT_x64_sys_syscall_sysv =
+{
+  &dc_callvm_free_x64
+, &dc_callvm_reset_x64
+, &dc_callvm_mode_x64
+, &dc_callvm_argBool_x64
+, &dc_callvm_argChar_x64
+, &dc_callvm_argShort_x64
+, &dc_callvm_argInt_x64
+, &dc_callvm_argLong_x64
+, &dc_callvm_argLongLong_x64
+, &dc_callvm_argFloat_x64
+, &dc_callvm_argDouble_x64
+, &dc_callvm_argPointer_x64
+, NULL /* argStruct */
+, (DCvoidvmfunc*)       &dc_callvm_call_x64_sys_syscall_sysv
+, (DCboolvmfunc*)       &dc_callvm_call_x64_sys_syscall_sysv
+, (DCcharvmfunc*)       &dc_callvm_call_x64_sys_syscall_sysv
+, (DCshortvmfunc*)      &dc_callvm_call_x64_sys_syscall_sysv
+, (DCintvmfunc*)        &dc_callvm_call_x64_sys_syscall_sysv
+, (DClongvmfunc*)       &dc_callvm_call_x64_sys_syscall_sysv
+, (DClonglongvmfunc*)   &dc_callvm_call_x64_sys_syscall_sysv
+, (DCfloatvmfunc*)      &dc_callvm_call_x64_sys_syscall_sysv
+, (DCdoublevmfunc*)     &dc_callvm_call_x64_sys_syscall_sysv
+, (DCpointervmfunc*)    &dc_callvm_call_x64_sys_syscall_sysv
+, NULL /* callStruct */
+};
+
+
+
+/* mode */
+
 static void dc_callvm_mode_x64(DCCallVM* in_self, DCint mode)
 {
   DCCallVM_x64* self = (DCCallVM_x64*)in_self;
@@ -205,6 +250,13 @@
     case DC_CALL_C_ELLIPSIS_VARARGS:
       vt = &gVT_x64;
       break;
+    case DC_CALL_SYS_DEFAULT:
+# if defined DC_UNIX
+    case DC_CALL_SYS_X64_SYSCALL_SYSV:
+      vt = &gVT_x64_sys_syscall_sysv; break;
+# else
+      self->mInterface.mError = DC_ERROR_UNSUPPORTED_MODE; return;
+# endif
     default:
       self->mInterface.mError = DC_ERROR_UNSUPPORTED_MODE; 
       return;
--- a/dyncall/dyncall_callvm_x86.c	Fri Jan 03 22:48:20 2020 +0100
+++ b/dyncall/dyncall_callvm_x86.c	Sat Jan 04 01:07:49 2020 +0100
@@ -6,7 +6,7 @@
  Description: Call VM for x86 architecture implementation
  License:
 
-   Copyright (c) 2007-2018 Daniel Adler <dadler@uni-goettingen.de>, 
+   Copyright (c) 2007-2020 Daniel Adler <dadler@uni-goettingen.de>, 
                            Tassilo Philipp <tphilipp@potion-studios.com>
 
    Permission to use, copy, modify, and distribute this software for any
@@ -592,7 +592,7 @@
     case DC_CALL_C_X86_WIN32_THIS_MS:  vt = &gVT_x86_win32_this_ms;  break;
     case DC_CALL_C_X86_WIN32_FAST_GNU: vt = &gVT_x86_win32_fast_gnu; break;
     case DC_CALL_C_X86_WIN32_THIS_GNU: vt = &gVT_x86_cdecl;          break;
-    case DC_CALL_SYS_DEFAULT:         
+    case DC_CALL_SYS_DEFAULT:
 # if defined DC_UNIX
 #   if defined DC__OS_Linux
       vt = &gVT_x86_sys_int80h_linux; break;