Mercurial > pub > dyncall > dyncall
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;