Mercurial > pub > dyncall > bindings
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 } |