changeset 40:1d50532dce12

- added syscall support to shdc - general cleanup and refactoring
author Tassilo Philipp
date Tue, 14 Apr 2020 17:44:04 +0200
parents b6114d9a9a98
children 3abd4f1ab473
files python/pydc/pydcext.c shell/shdc/examples.txt shell/shdc/shdc.c
diffstat 3 files changed, 40 insertions(+), 44 deletions(-) [+]
line wrap: on
line diff
--- a/python/pydc/pydcext.c	Mon Apr 13 21:58:48 2020 +0200
+++ b/python/pydc/pydcext.c	Tue Apr 14 17:44:04 2020 +0200
@@ -195,7 +195,7 @@
 	dcReset(gpCall);
 	dcMode(gpCall, DC_CALL_C_DEFAULT);
 
-	for (ch = *ptr; ch != '\0' && ch != ')'; ch = *++ptr)
+	for (ch = *ptr; ch != '\0' && ch != DC_SIGCHAR_ENDARG; ch = *++ptr)
 	{
 		PyObject* po;
 
@@ -213,20 +213,9 @@
 				if(*(ptr+1) != '\0')
 				{
 					// @@@ this is easily going out of sync with dyncall, abstract this sigchar->mode lookup somewhere inside dyncall
-					switch(*++ptr) {
-						case DC_SIGCHAR_CC_DEFAULT:          dcMode(gpCall, DC_CALL_C_DEFAULT           ); break;
-						case DC_SIGCHAR_CC_ELLIPSIS:         dcMode(gpCall, DC_CALL_C_ELLIPSIS          ); break;
-						case DC_SIGCHAR_CC_ELLIPSIS_VARARGS: dcMode(gpCall, DC_CALL_C_ELLIPSIS_VARARGS  ); break;
-						case DC_SIGCHAR_CC_CDECL:            dcMode(gpCall, DC_CALL_C_X86_CDECL         ); break;
-						case DC_SIGCHAR_CC_STDCALL:          dcMode(gpCall, DC_CALL_C_X86_WIN32_STD     ); break;
-						case DC_SIGCHAR_CC_FASTCALL_MS:      dcMode(gpCall, DC_CALL_C_X86_WIN32_FAST_MS ); break;
-						case DC_SIGCHAR_CC_FASTCALL_GNU:     dcMode(gpCall, DC_CALL_C_X86_WIN32_FAST_GNU); break;
-						case DC_SIGCHAR_CC_THISCALL_MS:      dcMode(gpCall, DC_CALL_C_X86_WIN32_THIS_MS ); break;
-						case DC_SIGCHAR_CC_THISCALL_GNU:     dcMode(gpCall, DC_CALL_C_X86_WIN32_THIS_GNU); break;
-						case DC_SIGCHAR_CC_ARM_ARM:          dcMode(gpCall, DC_CALL_C_ARM_ARM           ); break;
-						case DC_SIGCHAR_CC_ARM_THUMB:        dcMode(gpCall, DC_CALL_C_ARM_THUMB         ); break;
-						case DC_SIGCHAR_CC_SYSCALL:          dcMode(gpCall, DC_CALL_SYS_DEFAULT         ); break;
-					}
+					DCint mode = dcGetModeFromCCSigChar(*++ptr);
+					if(mode != DC_ERROR_UNSUPPORTED_MODE)
+						dcMode(gpCall, mode);
 				}
 				--pos; // didn't count as arg
 			}
--- a/shell/shdc/examples.txt	Mon Apr 13 21:58:48 2020 +0200
+++ b/shell/shdc/examples.txt	Tue Apr 14 17:44:04 2020 +0200
@@ -1,12 +1,22 @@
 Call:
 -----
-$ ./shdc -c /usr/lib/libm.so sqrt "d)d" 3
+
+$ ./shdc -c /usr/lib/libm.so sqrt 'd)d' 3
 1.73205
-$ ./shdc -c /usr/lib/libm.so powf "ff)f" 3 2.5
+
+$ ./shdc -c /usr/lib/libm.so powf 'ff)f' 3 2.5
 15.5885
-$ ./shdc -c /usr/lib/libc.so printf "_eZZi)v" "Hi! Say hi to %s, l%ier!" "Daniel" 8
+
+$ ./shdc -c /usr/lib/libc.so printf '_eZ_.Zi)v' 'Hi! Say hi to %s, l%ier!' 'Daniel' 8
 Hi! Say hi to Daniel, l8er!
 
+$ # FreeBSD syscall where SYS_write == 4; return value from syscall is 18, with
+$ # write of string results in stdout output of "syscall write test18"
+$ ./shdc -c "" 4 '_$iZi)i' 1 'syscall write test' 18
+syscall write test18
+
+
 List:
 -----
 $ ./shdc -l /usr/lib/libm.so
+
--- a/shell/shdc/shdc.c	Mon Apr 13 21:58:48 2020 +0200
+++ b/shell/shdc/shdc.c	Tue Apr 14 17:44:04 2020 +0200
@@ -24,6 +24,7 @@
 #include "../../dyncall/dynload/dynload.h"
 #include "../../dyncall/dyncall/dyncall_signature.h"
 #include <stdio.h>
+#include <string.h>
 #include <stdlib.h> /* needed on some platforms to make atof work _at_runtime_ */
 
 #define SHDC_VERSION "1.0"
@@ -77,14 +78,14 @@
 		return 1;
 	}
 
-
-	libPath = argv[2];
+	/* if lib path is empty string, use NULL as reference to own process/exe */
+	libPath = argv[2][0] == '\0' ? NULL : argv[2];
 
 	/* List symbols, if 'ls', else it must be 'call', so proceed to call. */
 	if(l == 0) {
 		dlSyms = dlSymsInit(libPath);
 		if(!dlSyms) {
-			printf("Can't load \"%s\".\n", libPath);
+			printf("Can't load \"%s\".\n", libPath?libPath:"<NULL>");
 			usage(argv[0]);
 			return 1;
 		}
@@ -102,7 +103,7 @@
 		/* Load library and get a pointer to the symbol to call. */
 		dlLib = dlLoadLibrary(libPath);
 		if(!dlLib) {
-			printf("Can't load \"%s\".\n", libPath);
+			printf("Can't load \"%s\".\n", libPath?libPath:"<NULL>");
 			usage(argv[0]);
 			return 1;
 		}
@@ -112,10 +113,15 @@
     
 		sym = dlFindSymbol(dlLib, symName);
 		if(!sym) {
-			printf("Can't find symbol \"%s\".\n", symName);
-			dlFreeLibrary(dlLib);
-			usage(argv[0]);
-			return 1;
+			/* this might be a syscall attempt, check if "symbol" is numeric */
+			int n;
+			if(sscanf(symName, "%d", &n) == 0) {
+				printf("Can't find symbol \"%s\".\n", symName);
+				dlFreeLibrary(dlLib);
+				usage(argv[0]);
+				return 1;
+			}
+			sym = (void*)(size_t)n;
 		}
     
     
@@ -125,20 +131,11 @@
 		while(*i != '\0' && *i != DC_SIGCHAR_ENDARG) {
 			switch(*i) {
 				case DC_SIGCHAR_CC_PREFIX:
-					switch(*++i) {
-						case DC_SIGCHAR_CC_DEFAULT:          dcMode(vm, DC_CALL_C_DEFAULT           ); break;
-						case DC_SIGCHAR_CC_ELLIPSIS:         dcMode(vm, DC_CALL_C_ELLIPSIS          ); break;
-						case DC_SIGCHAR_CC_ELLIPSIS_VARARGS: dcMode(vm, DC_CALL_C_ELLIPSIS_VARARGS  ); break;
-						case DC_SIGCHAR_CC_CDECL:            dcMode(vm, DC_CALL_C_X86_CDECL         ); break;
-						case DC_SIGCHAR_CC_STDCALL:          dcMode(vm, DC_CALL_C_X86_WIN32_STD     ); break;
-						case DC_SIGCHAR_CC_FASTCALL_MS:      dcMode(vm, DC_CALL_C_X86_WIN32_FAST_MS ); break;
-						case DC_SIGCHAR_CC_FASTCALL_GNU:     dcMode(vm, DC_CALL_C_X86_WIN32_FAST_GNU); break;
-						case DC_SIGCHAR_CC_THISCALL_MS:      dcMode(vm, DC_CALL_C_X86_WIN32_THIS_MS ); break;
-						case DC_SIGCHAR_CC_THISCALL_GNU:     dcMode(vm, DC_CALL_C_X86_WIN32_THIS_GNU); break;
-						case DC_SIGCHAR_CC_ARM_ARM:          dcMode(vm, DC_CALL_C_ARM_ARM           ); break;
-						case DC_SIGCHAR_CC_ARM_THUMB:        dcMode(vm, DC_CALL_C_ARM_THUMB         ); break;
-						case DC_SIGCHAR_CC_SYSCALL:          dcMode(vm, DC_CALL_SYS_DEFAULT         ); break;
-						/* @@@ extend with other modes when they become available */
+					if(*(i+1) != '\0')
+					{
+						DCint mode = dcGetModeFromCCSigChar(*++i);
+						if(mode != DC_ERROR_UNSUPPORTED_MODE)
+							dcMode(vm, mode);
 					}
 					sig += 2;
 					break;
@@ -175,14 +172,14 @@
 			case DC_SIGCHAR_USHORT:    printf("%d\n",   dcCallShort   (vm,sym)); break;
 			case DC_SIGCHAR_INT:       printf("%d\n",   dcCallInt     (vm,sym)); break;
 			case DC_SIGCHAR_UINT:      printf("%d\n",   dcCallInt     (vm,sym)); break;
-			case DC_SIGCHAR_LONG:      printf("%d\n",   dcCallLong    (vm,sym)); break;
-			case DC_SIGCHAR_ULONG:     printf("%d\n",   dcCallLong    (vm,sym)); break;
+			case DC_SIGCHAR_LONG:      printf("%ld\n",  dcCallLong    (vm,sym)); break;
+			case DC_SIGCHAR_ULONG:     printf("%ld\n",  dcCallLong    (vm,sym)); break;
 			case DC_SIGCHAR_LONGLONG:  printf("%lld\n", dcCallLongLong(vm,sym)); break;
 			case DC_SIGCHAR_ULONGLONG: printf("%lld\n", dcCallLongLong(vm,sym)); break;
 			case DC_SIGCHAR_FLOAT:     printf("%g\n",   dcCallFloat   (vm,sym)); break;
 			case DC_SIGCHAR_DOUBLE:    printf("%g\n",   dcCallDouble  (vm,sym)); break;
-			case DC_SIGCHAR_POINTER:   printf("%x\n",   dcCallPointer (vm,sym)); break;
-			case DC_SIGCHAR_STRING:    printf(          dcCallPointer (vm,sym)); break;
+			case DC_SIGCHAR_POINTER:   printf("%p\n",   dcCallPointer (vm,sym)); break;
+			case DC_SIGCHAR_STRING:    printf("%s",     dcCallPointer (vm,sym)); break;
 		}
     
 		dlFreeLibrary(dlLib);