]> git.imager.perl.org - imager.git/blob - dynaload.c
fbc55c71e891dd85bd40fff3b5b6df14ada96457
[imager.git] / dynaload.c
1 #include "image.h"
2 #include "dynaload.h"
3 /* #include "XSUB.h"  so we can compile on threaded perls */
4 #include "imagei.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) return NULL;
61
62   dso_handle->handle=tt_handle; /* needed to close again */
63   dso_handle->function_list=function_list;
64   if ( (dso_handle->filename=(char*)malloc(strlen(file))) == NULL) { free(dso_handle); return NULL; }
65   strcpy(dso_handle->filename,file);
66
67   mm_log((1,"DSO_open <- (0x%X)\n",dso_handle));
68   return (void*)dso_handle;
69 }
70
71 undef_int
72 DSO_close(void *ptr) {
73   DSO_handle *handle=(DSO_handle*) ptr;
74   mm_log((1,"DSO_close(ptr 0x%X)\n",ptr));
75   return !shl_unload((handle->handle));
76 }
77
78 #elif defined(WIN32)
79
80 void *
81 DSO_open(char *file, char **evalstring) {
82   HMODULE d_handle;
83   func_ptr *function_list;
84   DSO_handle *dso_handle;
85   
86   void (*f)(void *s,void *u); /* these will just have to be void for now */
87
88   mm_log( (1,"DSO_open(file '%s' (0x%08X), evalstring 0x%08X)\n",file,file,evalstring) );
89
90   *evalstring = NULL;
91   if ((d_handle = LoadLibrary(file)) == NULL) {
92     mm_log((1, "DSO_open: LoadLibrary(%s) failed: %lu\n", file, GetLastError()));
93     return NULL;
94   }
95   if ( (*evalstring = (char *)GetProcAddress(d_handle, I_EVALSTR)) == NULL) {
96     mm_log((1,"DSO_open: GetProcAddress didn't fine '%s': %lu\n", I_EVALSTR, GetLastError()));
97     FreeLibrary(d_handle);
98     return NULL;
99   }
100   if ((f = (void (*)(void *, void*))GetProcAddress(d_handle, I_INSTALL_TABLES)) == NULL) {
101     mm_log((1, "DSO_open: GetProcAddress didn't find '%s': %lu\n", I_INSTALL_TABLES, GetLastError()));
102     FreeLibrary(d_handle);
103     return NULL;
104   }
105   mm_log((1, "Calling install tables\n"));
106   f(&symbol_table, &i_UTIL_table);
107   mm_log((1, "Call ok\n"));
108   
109   if ( (function_list = (func_ptr *)GetProcAddress(d_handle, I_FUNCTION_LIST)) == NULL) {
110     mm_log((1, "DSO_open: GetProcAddress didn't find '%s': %lu\n", I_FUNCTION_LIST, GetLastError()));
111     FreeLibrary(d_handle);
112     return NULL;
113   }
114   if ( (dso_handle = (DSO_handle*)malloc(sizeof(DSO_handle))) == NULL) {
115     mm_log( (1, "DSO_Open: out of memory\n") );
116     FreeLibrary(d_handle);
117     return NULL;
118   }
119   dso_handle->handle=d_handle; /* needed to close again */
120   dso_handle->function_list=function_list;
121   if ( (dso_handle->filename=(char*)malloc(strlen(file))) == NULL) { free(dso_handle); FreeLibrary(d_handle); return NULL; }
122   strcpy(dso_handle->filename,file);
123
124   mm_log( (1,"DSO_open <- 0x%X\n",dso_handle) );
125   return (void*)dso_handle;
126
127 }
128
129 undef_int
130 DSO_close(void *ptr) {
131   DSO_handle *handle = (DSO_handle *)ptr;
132   BOOL result = FreeLibrary(handle->handle);
133   free(handle->filename);
134   free(handle);
135
136   return result;
137 }
138
139 #else
140
141 /* OS/2 has no dlclose; Perl doesn't provide one. */
142 #ifdef __EMX__ /* OS/2 */
143 int
144 dlclose(minthandle_t h) {
145   return DosFreeModule(h) ? -1 : 0;
146 }
147 #endif /* __EMX__ */
148
149 #ifdef OS_darwin
150
151 #import <mach-o/dyld.h>
152
153 static char *dl_error = "unknown";
154
155 static char *dlopen(char *path, int mode /* mode is ignored */)
156 {
157   int dyld_result;
158   NSObjectFileImage ofile;
159   NSModule handle = NULL;
160
161
162
163   dyld_result = NSCreateObjectFileImageFromFile(path, &ofile);
164   if (dyld_result != NSObjectFileImageSuccess)
165     {
166      switch (dyld_result) {
167        case NSObjectFileImageFailure:
168            dl_error = "object file setup failure";
169            break;
170        case NSObjectFileImageInappropriateFile:
171            dl_error = "not a Mach-O MH_BUNDLE file type";
172            break;
173        case NSObjectFileImageArch:
174            dl_error = "no object for this architecture";
175            break;
176        case NSObjectFileImageFormat:
177            dl_error = "bad object file format";
178            break;
179        case NSObjectFileImageAccess:
180            dl_error = "can't read object file";
181            break;
182        default:
183            dl_error = "unknown error from NSCreateObjectFileImageFromFile()";
184            break;
185      }
186     }
187     else
188       {
189         // NSLinkModule will cause the run to abort on any link error's
190         // not very friendly but the error recovery functionality is limited.
191         handle = NSLinkModule(ofile, path, TRUE);
192       }
193
194   return handle;
195 }
196
197 static void *
198 dlsym(void *handle, char *symbol)
199 {
200   void *addr;
201
202   if (NSIsSymbolNameDefined(symbol))
203   {
204     addr = NSAddressOfSymbol(NSLookupAndBindSymbol(symbol));
205   }
206   else
207   {
208     dl_error = "cannot find symbol";
209     addr = NULL;
210   }
211
212   return addr;
213 }
214
215 static int dlclose(void *handle) /* stub only */
216 {
217   return 0;
218 }
219
220 static char *dlerror(void) /* stub only */
221 {
222   printf("Error occurred\n");
223   return dl_error; 
224 }
225
226 #define RTLD_LAZY 0
227
228 #endif 
229
230 void*
231 DSO_open(char* file,char** evalstring) {
232   void *d_handle;
233   func_ptr *function_list;
234   DSO_handle *dso_handle;
235
236   void (*f)(void *s,void *u); /* these will just have to be void for now */
237   
238   *evalstring=NULL;
239
240   mm_log( (1,"DSO_open(file '%s' (0x%08X), evalstring 0x%08X)\n",file,file,evalstring) );
241
242   if ( (d_handle = dlopen(file, RTLD_LAZY)) == NULL) {
243     mm_log( (1,"DSO_open: dlopen failed: %s.\n",dlerror()) );
244     return NULL;
245   }
246
247   if ( (*evalstring = (char *)dlsym(d_handle, I_EVALSTR)) == NULL) {
248     mm_log( (1,"DSO_open: dlsym didn't find '%s': %s.\n",I_EVALSTR,dlerror()) );
249     return NULL;
250   }
251
252   /*
253
254     I'll just leave this thing in here for now if I need it real soon
255
256    mm_log( (1,"DSO_open: going to dlsym '%s'\n", I_SYMBOL_TABLE ));
257    if ( (plugin_symtab = dlsym(d_handle, I_SYMBOL_TABLE)) == NULL) {
258      mm_log( (1,"DSO_open: dlsym didn't find '%s': %s.\n",I_SYMBOL_TABLE,dlerror()) );
259      return NULL;
260    }
261   
262    mm_log( (1,"DSO_open: going to dlsym '%s'\n", I_UTIL_TABLE ));
263     if ( (plugin_utiltab = dlsym(d_handle, I_UTIL_TABLE)) == NULL) {
264      mm_log( (1,"DSO_open: dlsym didn't find '%s': %s.\n",I_UTIL_TABLE,dlerror()) );
265      return NULL;
266    }
267
268   */
269
270   f = (void(*)(void *s,void *u))dlsym(d_handle, I_INSTALL_TABLES);
271   mm_log( (1,"DSO_open: going to dlsym '%s'\n", I_INSTALL_TABLES ));
272   if ( (f = (void(*)(void *s,void *u))dlsym(d_handle, I_INSTALL_TABLES)) == NULL) {
273     mm_log( (1,"DSO_open: dlsym didn't find '%s': %s.\n",I_INSTALL_TABLES,dlerror()) );
274     return NULL;
275   }
276
277   mm_log( (1,"Calling install_tables\n") );
278   f(&symbol_table,&i_UTIL_table);
279   mm_log( (1,"Call ok.\n") );
280
281   /* (*plugin_symtab)=&symbol_table;
282      (*plugin_utiltab)=&i_UTIL_table; */
283   
284   mm_log( (1,"DSO_open: going to dlsym '%s'\n", I_FUNCTION_LIST ));
285   if ( (function_list=(func_ptr *)dlsym(d_handle, I_FUNCTION_LIST)) == NULL) {
286     mm_log( (1,"DSO_open: dlsym didn't find '%s': %s.\n",I_FUNCTION_LIST,dlerror()) );
287     return NULL;
288   }
289   
290   if ( (dso_handle=(DSO_handle*)malloc(sizeof(DSO_handle))) == NULL) return NULL;
291   
292   dso_handle->handle=d_handle; /* needed to close again */
293   dso_handle->function_list=function_list;
294   if ( (dso_handle->filename=(char*)malloc(strlen(file))) == NULL) { free(dso_handle); return NULL; }
295   strcpy(dso_handle->filename,file);
296
297   mm_log( (1,"DSO_open <- 0x%X\n",dso_handle) );
298   return (void*)dso_handle;
299 }
300
301 undef_int
302 DSO_close(void *ptr) {
303   DSO_handle *handle;
304   mm_log((1,"DSO_close(ptr 0x%X)\n",ptr));
305   handle=(DSO_handle*) ptr;
306   return !dlclose(handle->handle);
307 }
308
309 #endif
310