comparison shell/shdc/shdc.c @ 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 6387d39ecce2
comparison
equal deleted inserted replaced
39:b6114d9a9a98 40:1d50532dce12
22 22
23 #include "../../dyncall/dyncall/dyncall.h" 23 #include "../../dyncall/dyncall/dyncall.h"
24 #include "../../dyncall/dynload/dynload.h" 24 #include "../../dyncall/dynload/dynload.h"
25 #include "../../dyncall/dyncall/dyncall_signature.h" 25 #include "../../dyncall/dyncall/dyncall_signature.h"
26 #include <stdio.h> 26 #include <stdio.h>
27 #include <string.h>
27 #include <stdlib.h> /* needed on some platforms to make atof work _at_runtime_ */ 28 #include <stdlib.h> /* needed on some platforms to make atof work _at_runtime_ */
28 29
29 #define SHDC_VERSION "1.0" 30 #define SHDC_VERSION "1.0"
30 31
31 32
75 if((c != 0 && l != 0) || (c == 0 && argc < 4)) { 76 if((c != 0 && l != 0) || (c == 0 && argc < 4)) {
76 usage(argv[0]); 77 usage(argv[0]);
77 return 1; 78 return 1;
78 } 79 }
79 80
80 81 /* if lib path is empty string, use NULL as reference to own process/exe */
81 libPath = argv[2]; 82 libPath = argv[2][0] == '\0' ? NULL : argv[2];
82 83
83 /* List symbols, if 'ls', else it must be 'call', so proceed to call. */ 84 /* List symbols, if 'ls', else it must be 'call', so proceed to call. */
84 if(l == 0) { 85 if(l == 0) {
85 dlSyms = dlSymsInit(libPath); 86 dlSyms = dlSymsInit(libPath);
86 if(!dlSyms) { 87 if(!dlSyms) {
87 printf("Can't load \"%s\".\n", libPath); 88 printf("Can't load \"%s\".\n", libPath?libPath:"<NULL>");
88 usage(argv[0]); 89 usage(argv[0]);
89 return 1; 90 return 1;
90 } 91 }
91 92
92 /* hacky: reuse c and l */ 93 /* hacky: reuse c and l */
100 /*if(n != argc-4)@@@*/ /* 0 is prog, 1 is flag, 2 is lib, 3 is symbol name, 4 is sig */ 101 /*if(n != argc-4)@@@*/ /* 0 is prog, 1 is flag, 2 is lib, 3 is symbol name, 4 is sig */
101 102
102 /* Load library and get a pointer to the symbol to call. */ 103 /* Load library and get a pointer to the symbol to call. */
103 dlLib = dlLoadLibrary(libPath); 104 dlLib = dlLoadLibrary(libPath);
104 if(!dlLib) { 105 if(!dlLib) {
105 printf("Can't load \"%s\".\n", libPath); 106 printf("Can't load \"%s\".\n", libPath?libPath:"<NULL>");
106 usage(argv[0]); 107 usage(argv[0]);
107 return 1; 108 return 1;
108 } 109 }
109 110
110 symName = argv[3]; 111 symName = argv[3];
111 sig = i = argv[4]; 112 sig = i = argv[4];
112 113
113 sym = dlFindSymbol(dlLib, symName); 114 sym = dlFindSymbol(dlLib, symName);
114 if(!sym) { 115 if(!sym) {
115 printf("Can't find symbol \"%s\".\n", symName); 116 /* this might be a syscall attempt, check if "symbol" is numeric */
116 dlFreeLibrary(dlLib); 117 int n;
117 usage(argv[0]); 118 if(sscanf(symName, "%d", &n) == 0) {
118 return 1; 119 printf("Can't find symbol \"%s\".\n", symName);
120 dlFreeLibrary(dlLib);
121 usage(argv[0]);
122 return 1;
123 }
124 sym = (void*)(size_t)n;
119 } 125 }
120 126
121 127
122 vm = dcNewCallVM(4096/*@@@*/);/*@@@ error checking */ 128 vm = dcNewCallVM(4096/*@@@*/);/*@@@ error checking */
123 dcReset(vm); 129 dcReset(vm);
124 130
125 while(*i != '\0' && *i != DC_SIGCHAR_ENDARG) { 131 while(*i != '\0' && *i != DC_SIGCHAR_ENDARG) {
126 switch(*i) { 132 switch(*i) {
127 case DC_SIGCHAR_CC_PREFIX: 133 case DC_SIGCHAR_CC_PREFIX:
128 switch(*++i) { 134 if(*(i+1) != '\0')
129 case DC_SIGCHAR_CC_DEFAULT: dcMode(vm, DC_CALL_C_DEFAULT ); break; 135 {
130 case DC_SIGCHAR_CC_ELLIPSIS: dcMode(vm, DC_CALL_C_ELLIPSIS ); break; 136 DCint mode = dcGetModeFromCCSigChar(*++i);
131 case DC_SIGCHAR_CC_ELLIPSIS_VARARGS: dcMode(vm, DC_CALL_C_ELLIPSIS_VARARGS ); break; 137 if(mode != DC_ERROR_UNSUPPORTED_MODE)
132 case DC_SIGCHAR_CC_CDECL: dcMode(vm, DC_CALL_C_X86_CDECL ); break; 138 dcMode(vm, mode);
133 case DC_SIGCHAR_CC_STDCALL: dcMode(vm, DC_CALL_C_X86_WIN32_STD ); break;
134 case DC_SIGCHAR_CC_FASTCALL_MS: dcMode(vm, DC_CALL_C_X86_WIN32_FAST_MS ); break;
135 case DC_SIGCHAR_CC_FASTCALL_GNU: dcMode(vm, DC_CALL_C_X86_WIN32_FAST_GNU); break;
136 case DC_SIGCHAR_CC_THISCALL_MS: dcMode(vm, DC_CALL_C_X86_WIN32_THIS_MS ); break;
137 case DC_SIGCHAR_CC_THISCALL_GNU: dcMode(vm, DC_CALL_C_X86_WIN32_THIS_GNU); break;
138 case DC_SIGCHAR_CC_ARM_ARM: dcMode(vm, DC_CALL_C_ARM_ARM ); break;
139 case DC_SIGCHAR_CC_ARM_THUMB: dcMode(vm, DC_CALL_C_ARM_THUMB ); break;
140 case DC_SIGCHAR_CC_SYSCALL: dcMode(vm, DC_CALL_SYS_DEFAULT ); break;
141 /* @@@ extend with other modes when they become available */
142 } 139 }
143 sig += 2; 140 sig += 2;
144 break; 141 break;
145 142
146 case DC_SIGCHAR_BOOL: dcArgBool (vm, (DCbool) atoi (argv[5+i-sig] )); break; 143 case DC_SIGCHAR_BOOL: dcArgBool (vm, (DCbool) atoi (argv[5+i-sig] )); break;
173 case DC_SIGCHAR_UCHAR: printf("%d\n", dcCallChar (vm,sym)); break; 170 case DC_SIGCHAR_UCHAR: printf("%d\n", dcCallChar (vm,sym)); break;
174 case DC_SIGCHAR_SHORT: printf("%d\n", dcCallShort (vm,sym)); break; 171 case DC_SIGCHAR_SHORT: printf("%d\n", dcCallShort (vm,sym)); break;
175 case DC_SIGCHAR_USHORT: printf("%d\n", dcCallShort (vm,sym)); break; 172 case DC_SIGCHAR_USHORT: printf("%d\n", dcCallShort (vm,sym)); break;
176 case DC_SIGCHAR_INT: printf("%d\n", dcCallInt (vm,sym)); break; 173 case DC_SIGCHAR_INT: printf("%d\n", dcCallInt (vm,sym)); break;
177 case DC_SIGCHAR_UINT: printf("%d\n", dcCallInt (vm,sym)); break; 174 case DC_SIGCHAR_UINT: printf("%d\n", dcCallInt (vm,sym)); break;
178 case DC_SIGCHAR_LONG: printf("%d\n", dcCallLong (vm,sym)); break; 175 case DC_SIGCHAR_LONG: printf("%ld\n", dcCallLong (vm,sym)); break;
179 case DC_SIGCHAR_ULONG: printf("%d\n", dcCallLong (vm,sym)); break; 176 case DC_SIGCHAR_ULONG: printf("%ld\n", dcCallLong (vm,sym)); break;
180 case DC_SIGCHAR_LONGLONG: printf("%lld\n", dcCallLongLong(vm,sym)); break; 177 case DC_SIGCHAR_LONGLONG: printf("%lld\n", dcCallLongLong(vm,sym)); break;
181 case DC_SIGCHAR_ULONGLONG: printf("%lld\n", dcCallLongLong(vm,sym)); break; 178 case DC_SIGCHAR_ULONGLONG: printf("%lld\n", dcCallLongLong(vm,sym)); break;
182 case DC_SIGCHAR_FLOAT: printf("%g\n", dcCallFloat (vm,sym)); break; 179 case DC_SIGCHAR_FLOAT: printf("%g\n", dcCallFloat (vm,sym)); break;
183 case DC_SIGCHAR_DOUBLE: printf("%g\n", dcCallDouble (vm,sym)); break; 180 case DC_SIGCHAR_DOUBLE: printf("%g\n", dcCallDouble (vm,sym)); break;
184 case DC_SIGCHAR_POINTER: printf("%x\n", dcCallPointer (vm,sym)); break; 181 case DC_SIGCHAR_POINTER: printf("%p\n", dcCallPointer (vm,sym)); break;
185 case DC_SIGCHAR_STRING: printf( dcCallPointer (vm,sym)); break; 182 case DC_SIGCHAR_STRING: printf("%s", dcCallPointer (vm,sym)); break;
186 } 183 }
187 184
188 dlFreeLibrary(dlLib); 185 dlFreeLibrary(dlLib);
189 dcFree(vm); 186 dcFree(vm);
190 } 187 }