- start of external Imager API access:
[imager.git] / dynaload.c
1 #include "imager.h"
2 #include "dynaload.h"
3 /* #include "XSUB.h"  so we can compile on threaded perls */
4 #include "imageri.h"
5
6 static 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,
9                              i_box,i_line,i_arc,i_copyto,i_copyto_trans,i_rubthru};
10
11
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
20 void
21 DSO_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
29 void*
30 DSO_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;
50   (*plugin_utiltab)=&i_UTIL_table;
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") );
56   f(&symbol_table,&i_UTIL_table);
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; 
60   if ( (dso_handle=(DSO_handle*)malloc(sizeof(DSO_handle))) == NULL) /* checked 17jul05 tonyc */
61     return NULL;
62
63   dso_handle->handle=tt_handle; /* needed to close again */
64   dso_handle->function_list=function_list;
65   if ( (dso_handle->filename=(char*)malloc(strlen(file)+1)) == NULL) { /* checked 17jul05 tonyc */
66     free(dso_handle); return NULL;
67   }
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
74 undef_int
75 DSO_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
83 void *
84 DSO_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"));
109   f(&symbol_table, &i_UTIL_table);
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   }
117   if ( (dso_handle = (DSO_handle*)malloc(sizeof(DSO_handle))) == NULL) { /* checked 17jul05 tonyc */
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;
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   }
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
136 undef_int
137 DSO_close(void *ptr) {
138   DSO_handle *handle = (DSO_handle *)ptr;
139   BOOL result = FreeLibrary(handle->handle);
140   free(handle->filename);
141   free(handle);
142
143   return result;
144 }
145
146 #else
147
148 /* OS/2 has no dlclose; Perl doesn't provide one. */
149 #ifdef __EMX__ /* OS/2 */
150 int
151 dlclose(minthandle_t h) {
152   return DosFreeModule(h) ? -1 : 0;
153 }
154 #endif /* __EMX__ */
155
156 #ifdef OS_darwin
157
158 #import <mach-o/dyld.h>
159
160 static char *dl_error = "unknown";
161
162 static 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
204 static void *
205 dlsym(void *handle, char *symbol)
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
222 static int dlclose(void *handle) /* stub only */
223 {
224   return 0;
225 }
226
227 static char *dlerror(void) /* stub only */
228 {
229   printf("Error occurred\n");
230   return dl_error; 
231 }
232
233 #define RTLD_LAZY 0
234
235 #endif 
236
237 void*
238 DSO_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") );
285   f(&symbol_table,&i_UTIL_table);
286   mm_log( (1,"Call ok.\n") );
287
288   /* (*plugin_symtab)=&symbol_table;
289      (*plugin_utiltab)=&i_UTIL_table; */
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   
297   if ( (dso_handle=(DSO_handle*)malloc(sizeof(DSO_handle))) == NULL) /* checked 17jul05 tonyc */
298     return NULL;
299   
300   dso_handle->handle=d_handle; /* needed to close again */
301   dso_handle->function_list=function_list;
302   if ( (dso_handle->filename=(char*)malloc(strlen(file)+1)) == NULL) { /* checked 17jul05 tonyc */
303     free(dso_handle); 
304     return NULL;
305   }
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
312 undef_int
313 DSO_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