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