]>
Commit | Line | Data |
---|---|---|
02d1d628 AMH |
1 | #include "dynaload.h" |
2 | #include "XSUB.h" /* so we can compile on threaded perls */ | |
3 | ||
b6cfd214 TC |
4 | static symbol_table_t symbol_table={i_has_format,ICL_set_internal,ICL_info, |
5 | i_img_new,i_img_empty,i_img_empty_ch,i_img_exorcise, | |
6 | i_img_info,i_img_setmask,i_img_getmask, | |
7 | i_box,i_draw,i_arc,i_copyto,i_copyto_trans,i_rubthru}; | |
8 | ||
9 | ||
02d1d628 AMH |
10 | /* These functions are all shared - then comes platform dependant code */ |
11 | ||
12 | ||
13 | int getstr(void *hv_t,char *key,char **store) { | |
14 | SV** svpp; | |
15 | HV* hv=(HV*)hv_t; | |
16 | ||
17 | mm_log((1,"getstr(hv_t 0x%X, key %s, store 0x%X)\n",hv_t,key,store)); | |
18 | ||
19 | if ( !hv_exists(hv,key,strlen(key)) ) return 0; | |
20 | ||
21 | svpp=hv_fetch(hv, key, strlen(key), 0); | |
22 | *store=SvPV(*svpp, PL_na ); | |
23 | ||
24 | return 1; | |
25 | } | |
26 | ||
27 | int getint(void *hv_t,char *key,int *store) { | |
28 | SV** svpp; | |
29 | HV* hv=(HV*)hv_t; | |
30 | ||
31 | mm_log((1,"getint(hv_t 0x%X, key %s, store 0x%X)\n",hv_t,key,store)); | |
32 | ||
33 | if ( !hv_exists(hv,key,strlen(key)) ) return 0; | |
34 | ||
35 | svpp=hv_fetch(hv, key, strlen(key), 0); | |
36 | *store=(int)SvIV(*svpp); | |
37 | return 1; | |
38 | } | |
39 | ||
40 | int getdouble(void *hv_t,char* key,double *store) { | |
41 | SV** svpp; | |
42 | HV* hv=(HV*)hv_t; | |
43 | ||
44 | mm_log((1,"getdouble(hv_t 0x%X, key %s, store 0x%X)\n",hv_t,key,store)); | |
45 | ||
46 | if ( !hv_exists(hv,key,strlen(key)) ) return 0; | |
47 | svpp=hv_fetch(hv, key, strlen(key), 0); | |
48 | *store=(float)SvNV(*svpp); | |
49 | return 1; | |
50 | } | |
51 | ||
52 | int getvoid(void *hv_t,char* key,void **store) { | |
53 | SV** svpp; | |
54 | HV* hv=(HV*)hv_t; | |
55 | ||
56 | mm_log((1,"getvoid(hv_t 0x%X, key %s, store 0x%X)\n",hv_t,key,store)); | |
57 | ||
58 | if ( !hv_exists(hv,key,strlen(key)) ) return 0; | |
59 | ||
60 | svpp=hv_fetch(hv, key, strlen(key), 0); | |
61 | *store=(void*)SvIV(*svpp); | |
62 | ||
63 | return 1; | |
64 | } | |
65 | ||
66 | int getobj(void *hv_t,char *key,char *type,void **store) { | |
67 | SV** svpp; | |
68 | HV* hv=(HV*)hv_t; | |
69 | ||
70 | mm_log((1,"getobj(hv_t 0x%X, key %s,type %s, store 0x%X)\n",hv_t,key,type,store)); | |
71 | ||
72 | if ( !hv_exists(hv,key,strlen(key)) ) return 0; | |
73 | ||
74 | svpp=hv_fetch(hv, key, strlen(key), 0); | |
75 | ||
76 | if (sv_derived_from(*svpp,type)) { | |
77 | IV tmp = SvIV((SV*)SvRV(*svpp)); | |
78 | *store = (void*) tmp; | |
79 | } else { | |
80 | mm_log((1,"getobj: key exists in hash but is not of correct type")); | |
81 | return 0; | |
82 | } | |
83 | ||
84 | return 1; | |
85 | } | |
86 | ||
87 | ||
88 | UTIL_table_t UTIL_table={getstr,getint,getdouble,getvoid,getobj}; | |
02d1d628 AMH |
89 | |
90 | /* | |
91 | Dynamic loading works like this: | |
92 | dynaload opens the shared object and | |
93 | loads all the functions into an array of functions | |
94 | it returns a string from the dynamic function that | |
95 | can be supplied to the parser for evaling. | |
96 | */ | |
97 | ||
98 | void | |
99 | DSO_call(DSO_handle *handle,int func_index,HV* hv) { | |
100 | mm_log((1,"DSO_call(handle 0x%X, func_index %d, hv 0x%X)\n",handle,func_index,hv)); | |
101 | (handle->function_list[func_index].iptr)((void*)hv); | |
102 | } | |
103 | ||
104 | ||
105 | #if defined( OS_hpux ) | |
106 | ||
107 | void* | |
108 | DSO_open(char* file,char** evalstring) { | |
109 | shl_t tt_handle; | |
110 | void *d_handle,**plugin_symtab,**plugin_utiltab; | |
111 | int rc,*iptr, (*fptr)(int); | |
112 | func_ptr *function_list; | |
113 | DSO_handle *dso_handle; | |
114 | void (*f)(void *s,void *u); /* these will just have to be void for now */ | |
115 | int i; | |
116 | ||
117 | *evalstring=NULL; | |
118 | ||
119 | mm_log( (1,"DSO_open(file '%s' (0x%08X), evalstring 0x%08X)\n",file,file,evalstring) ); | |
120 | ||
121 | if ( (tt_handle = shl_load(file, BIND_DEFERRED,0L)) == NULL) return NULL; | |
122 | if ( (shl_findsym(&tt_handle, I_EVALSTR,TYPE_UNDEFINED,(void*)evalstring))) return NULL; | |
123 | ||
124 | /* | |
125 | if ( (shl_findsym(&tt_handle, "symbol_table",TYPE_UNDEFINED,(void*)&plugin_symtab))) return NULL; | |
126 | if ( (shl_findsym(&tt_handle, "util_table",TYPE_UNDEFINED,&plugin_utiltab))) return NULL; | |
127 | (*plugin_symtab)=&symbol_table; | |
128 | (*plugin_utiltab)=&UTIL_table; | |
129 | */ | |
130 | ||
131 | if ( (shl_findsym(&tt_handle, I_INSTALL_TABLES ,TYPE_UNDEFINED, &f ))) return NULL; | |
132 | ||
133 | mm_log( (1,"Calling install_tables\n") ); | |
134 | f(&symbol_table,&UTIL_table); | |
135 | mm_log( (1,"Call ok.\n") ); | |
136 | ||
137 | if ( (shl_findsym(&tt_handle, I_FUNCTION_LIST ,TYPE_UNDEFINED,(func_ptr*)&function_list))) return NULL; | |
138 | if ( (dso_handle=(DSO_handle*)malloc(sizeof(DSO_handle))) == NULL) return NULL; | |
139 | ||
140 | dso_handle->handle=tt_handle; /* needed to close again */ | |
141 | dso_handle->function_list=function_list; | |
142 | if ( (dso_handle->filename=(char*)malloc(strlen(file))) == NULL) { free(dso_handle); return NULL; } | |
143 | strcpy(dso_handle->filename,file); | |
144 | ||
145 | mm_log((1,"DSO_open <- (0x%X)\n",dso_handle)); | |
146 | return (void*)dso_handle; | |
147 | } | |
148 | ||
149 | undef_int | |
150 | DSO_close(void *ptr) { | |
151 | DSO_handle *handle=(DSO_handle*) ptr; | |
152 | mm_log((1,"DSO_close(ptr 0x%X)\n",ptr)); | |
153 | return !shl_unload((handle->handle)); | |
154 | } | |
155 | ||
156 | #elif defined(WIN32) | |
157 | ||
158 | void * | |
159 | DSO_open(char *file, char **evalstring) { | |
160 | HMODULE d_handle; | |
161 | func_ptr *function_list; | |
162 | DSO_handle *dso_handle; | |
163 | ||
164 | void (*f)(void *s,void *u); /* these will just have to be void for now */ | |
165 | ||
166 | mm_log( (1,"DSO_open(file '%s' (0x%08X), evalstring 0x%08X)\n",file,file,evalstring) ); | |
167 | ||
168 | *evalstring = NULL; | |
169 | if ((d_handle = LoadLibrary(file)) == NULL) { | |
170 | mm_log((1, "DSO_open: LoadLibrary(%s) failed: %lu\n", file, GetLastError())); | |
171 | return NULL; | |
172 | } | |
173 | if ( (*evalstring = (char *)GetProcAddress(d_handle, I_EVALSTR)) == NULL) { | |
174 | mm_log((1,"DSO_open: GetProcAddress didn't fine '%s': %lu\n", I_EVALSTR, GetLastError())); | |
175 | FreeLibrary(d_handle); | |
176 | return NULL; | |
177 | } | |
178 | if ((f = (void (*)(void *, void*))GetProcAddress(d_handle, I_INSTALL_TABLES)) == NULL) { | |
179 | mm_log((1, "DSO_open: GetProcAddress didn't find '%s': %lu\n", I_INSTALL_TABLES, GetLastError())); | |
180 | FreeLibrary(d_handle); | |
181 | return NULL; | |
182 | } | |
183 | mm_log((1, "Calling install tables\n")); | |
184 | f(&symbol_table, &UTIL_table); | |
185 | mm_log((1, "Call ok\n")); | |
186 | ||
187 | if ( (function_list = (func_ptr *)GetProcAddress(d_handle, I_FUNCTION_LIST)) == NULL) { | |
188 | mm_log((1, "DSO_open: GetProcAddress didn't find '%s': %lu\n", I_FUNCTION_LIST, GetLastError())); | |
189 | FreeLibrary(d_handle); | |
190 | return NULL; | |
191 | } | |
192 | if ( (dso_handle = (DSO_handle*)malloc(sizeof(DSO_handle))) == NULL) { | |
193 | mm_log( (1, "DSO_Open: out of memory\n") ); | |
194 | FreeLibrary(d_handle); | |
195 | return NULL; | |
196 | } | |
197 | dso_handle->handle=d_handle; /* needed to close again */ | |
198 | dso_handle->function_list=function_list; | |
199 | if ( (dso_handle->filename=(char*)malloc(strlen(file))) == NULL) { free(dso_handle); FreeLibrary(d_handle); return NULL; } | |
200 | strcpy(dso_handle->filename,file); | |
201 | ||
202 | mm_log( (1,"DSO_open <- 0x%X\n",dso_handle) ); | |
203 | return (void*)dso_handle; | |
204 | ||
205 | } | |
206 | ||
207 | undef_int | |
208 | DSO_close(void *ptr) { | |
209 | DSO_handle *handle = (DSO_handle *)ptr; | |
210 | FreeLibrary(handle->handle); | |
211 | free(handle->filename); | |
212 | free(handle); | |
213 | } | |
214 | ||
215 | #else | |
216 | ||
217 | /* OS/2 has no dlclose; Perl doesn't provide one. */ | |
218 | #ifdef __EMX__ /* OS/2 */ | |
219 | int | |
220 | dlclose(minthandle_t h) { | |
221 | return DosFreeModule(h) ? -1 : 0; | |
222 | } | |
223 | #endif /* __EMX__ */ | |
224 | ||
b6cfd214 TC |
225 | #ifdef OS_darwin |
226 | ||
227 | #import <mach-o/dyld.h> | |
228 | ||
229 | static char *dl_error = "unknown"; | |
230 | ||
231 | static char *dlopen(char *path, int mode /* mode is ignored */) | |
232 | { | |
233 | int dyld_result; | |
234 | NSObjectFileImage ofile; | |
235 | NSModule handle = NULL; | |
236 | ||
237 | ||
238 | ||
239 | dyld_result = NSCreateObjectFileImageFromFile(path, &ofile); | |
240 | if (dyld_result != NSObjectFileImageSuccess) | |
241 | { | |
242 | switch (dyld_result) { | |
243 | case NSObjectFileImageFailure: | |
244 | dl_error = "object file setup failure"; | |
245 | break; | |
246 | case NSObjectFileImageInappropriateFile: | |
247 | dl_error = "not a Mach-O MH_BUNDLE file type"; | |
248 | break; | |
249 | case NSObjectFileImageArch: | |
250 | dl_error = "no object for this architecture"; | |
251 | break; | |
252 | case NSObjectFileImageFormat: | |
253 | dl_error = "bad object file format"; | |
254 | break; | |
255 | case NSObjectFileImageAccess: | |
256 | dl_error = "can't read object file"; | |
257 | break; | |
258 | default: | |
259 | dl_error = "unknown error from NSCreateObjectFileImageFromFile()"; | |
260 | break; | |
261 | } | |
262 | } | |
263 | else | |
264 | { | |
265 | // NSLinkModule will cause the run to abort on any link error's | |
266 | // not very friendly but the error recovery functionality is limited. | |
267 | handle = NSLinkModule(ofile, path, TRUE); | |
268 | } | |
269 | ||
270 | return handle; | |
271 | } | |
272 | ||
560a3a0a TC |
273 | static void * |
274 | dlsym(void *handle, char *symbol) | |
b6cfd214 TC |
275 | { |
276 | void *addr; | |
277 | ||
278 | if (NSIsSymbolNameDefined(symbol)) | |
279 | { | |
280 | addr = NSAddressOfSymbol(NSLookupAndBindSymbol(symbol)); | |
281 | } | |
282 | else | |
283 | { | |
284 | dl_error = "cannot find symbol"; | |
285 | addr = NULL; | |
286 | } | |
287 | ||
288 | return addr; | |
289 | } | |
290 | ||
560a3a0a | 291 | static int dlclose(void *handle) /* stub only */ |
b6cfd214 TC |
292 | { |
293 | return 0; | |
294 | } | |
295 | ||
4ede8fe2 | 296 | static char *dlerror(void) /* stub only */ |
b6cfd214 | 297 | { |
560a3a0a | 298 | printf("Error occurred\n"); |
b6cfd214 TC |
299 | return dl_error; |
300 | } | |
301 | ||
302 | #define RTLD_LAZY 0 | |
303 | ||
304 | #endif | |
02d1d628 AMH |
305 | |
306 | void* | |
307 | DSO_open(char* file,char** evalstring) { | |
308 | void *d_handle; | |
309 | func_ptr *function_list; | |
310 | DSO_handle *dso_handle; | |
311 | ||
312 | void (*f)(void *s,void *u); /* these will just have to be void for now */ | |
313 | ||
314 | *evalstring=NULL; | |
315 | ||
316 | mm_log( (1,"DSO_open(file '%s' (0x%08X), evalstring 0x%08X)\n",file,file,evalstring) ); | |
317 | ||
318 | if ( (d_handle = dlopen(file, RTLD_LAZY)) == NULL) { | |
319 | mm_log( (1,"DSO_open: dlopen failed: %s.\n",dlerror()) ); | |
320 | return NULL; | |
321 | } | |
322 | ||
323 | if ( (*evalstring = (char *)dlsym(d_handle, I_EVALSTR)) == NULL) { | |
324 | mm_log( (1,"DSO_open: dlsym didn't find '%s': %s.\n",I_EVALSTR,dlerror()) ); | |
325 | return NULL; | |
326 | } | |
327 | ||
328 | /* | |
329 | ||
330 | I'll just leave this thing in here for now if I need it real soon | |
331 | ||
332 | mm_log( (1,"DSO_open: going to dlsym '%s'\n", I_SYMBOL_TABLE )); | |
333 | if ( (plugin_symtab = dlsym(d_handle, I_SYMBOL_TABLE)) == NULL) { | |
334 | mm_log( (1,"DSO_open: dlsym didn't find '%s': %s.\n",I_SYMBOL_TABLE,dlerror()) ); | |
335 | return NULL; | |
336 | } | |
337 | ||
338 | mm_log( (1,"DSO_open: going to dlsym '%s'\n", I_UTIL_TABLE )); | |
339 | if ( (plugin_utiltab = dlsym(d_handle, I_UTIL_TABLE)) == NULL) { | |
340 | mm_log( (1,"DSO_open: dlsym didn't find '%s': %s.\n",I_UTIL_TABLE,dlerror()) ); | |
341 | return NULL; | |
342 | } | |
343 | ||
344 | */ | |
345 | ||
346 | f = (void(*)(void *s,void *u))dlsym(d_handle, I_INSTALL_TABLES); | |
347 | mm_log( (1,"DSO_open: going to dlsym '%s'\n", I_INSTALL_TABLES )); | |
348 | if ( (f = (void(*)(void *s,void *u))dlsym(d_handle, I_INSTALL_TABLES)) == NULL) { | |
349 | mm_log( (1,"DSO_open: dlsym didn't find '%s': %s.\n",I_INSTALL_TABLES,dlerror()) ); | |
350 | return NULL; | |
351 | } | |
352 | ||
353 | mm_log( (1,"Calling install_tables\n") ); | |
354 | f(&symbol_table,&UTIL_table); | |
355 | mm_log( (1,"Call ok.\n") ); | |
356 | ||
357 | /* (*plugin_symtab)=&symbol_table; | |
358 | (*plugin_utiltab)=&UTIL_table; */ | |
359 | ||
360 | mm_log( (1,"DSO_open: going to dlsym '%s'\n", I_FUNCTION_LIST )); | |
361 | if ( (function_list=(func_ptr *)dlsym(d_handle, I_FUNCTION_LIST)) == NULL) { | |
362 | mm_log( (1,"DSO_open: dlsym didn't find '%s': %s.\n",I_FUNCTION_LIST,dlerror()) ); | |
363 | return NULL; | |
364 | } | |
365 | ||
366 | if ( (dso_handle=(DSO_handle*)malloc(sizeof(DSO_handle))) == NULL) return NULL; | |
367 | ||
368 | dso_handle->handle=d_handle; /* needed to close again */ | |
369 | dso_handle->function_list=function_list; | |
370 | if ( (dso_handle->filename=(char*)malloc(strlen(file))) == NULL) { free(dso_handle); return NULL; } | |
371 | strcpy(dso_handle->filename,file); | |
372 | ||
373 | mm_log( (1,"DSO_open <- 0x%X\n",dso_handle) ); | |
374 | return (void*)dso_handle; | |
375 | } | |
376 | ||
377 | undef_int | |
378 | DSO_close(void *ptr) { | |
379 | DSO_handle *handle; | |
380 | mm_log((1,"DSO_close(ptr 0x%X)\n",ptr)); | |
381 | handle=(DSO_handle*) ptr; | |
382 | return !dlclose(handle->handle); | |
383 | } | |
384 | ||
385 | #endif | |
386 |