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