Mercurial > hg > xemacs-beta
annotate src/sysdll.c @ 4879:c356806cc933
fix compile errors when --with-msw=no
-------------------- ChangeLog entries follow: --------------------
modules/ChangeLog addition:
2010-01-16 Ben Wing <ben@xemacs.org>
* common/Makefile.common:
* common/Makefile.common (.PHONY):
Use WIN32_ANY not HAVE_MS_WINDOWS so we still link with the
import library even when --with-msw=no.
src/ChangeLog addition:
2010-01-16 Ben Wing <ben@xemacs.org>
* win32.c (mswindows_read_link_1):
Conditionalize COM support on HAVE_MS_WINDOWS because otherwise we
haven't linked with the appropriate libraries.
author | Ben Wing <ben@xemacs.org> |
---|---|
date | Sat, 16 Jan 2010 06:50:01 -0600 |
parents | b3ea9c582280 |
children | 19a72041c5ed |
rev | line source |
---|---|
428 | 1 /* sysdll.c --- system dependent support for dynamic linked libraries |
2 Copyright (C) 1998 Free Software Foundation, Inc. | |
3 Author: William Perry <wmperry@aventail.com> | |
4 | |
5 This file is part of XEmacs. | |
6 | |
7 XEmacs is free software; you can redistribute it and/or modify it | |
8 under the terms of the GNU General Public License as published by the | |
9 Free Software Foundation; either version 2, or (at your option) any | |
10 later version. | |
11 | |
12 XEmacs is distributed in the hope that it will be useful, but WITHOUT | |
13 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
14 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
15 for more details. | |
16 | |
17 You should have received a copy of the GNU General Public License | |
18 along with XEmacs; see the file COPYING. If not, write to the Free | |
19 Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA | |
20 02111-1307, USA. */ | |
21 | |
22 #ifdef HAVE_CONFIG_H | |
23 #include <config.h> | |
24 #endif | |
25 | |
430 | 26 #include <stdlib.h> |
1272 | 27 #include "lisp.h" |
428 | 28 #include "sysdll.h" |
29 | |
1383 | 30 #ifdef DLSYM_NEEDS_UNDERSCORE |
31 #define MAYBE_PREPEND_UNDERSCORE(n) do { \ | |
1706 | 32 CIbyte *buf = alloca_array (CIbyte, strlen (n) + 2); \ |
1383 | 33 *buf = '_'; \ |
34 strcpy (buf + 1, n); \ | |
35 n = buf; \ | |
36 } while (0) | |
37 #else | |
38 #define MAYBE_PREPEND_UNDERSCORE(n) | |
39 #endif | |
40 | |
428 | 41 /* This whole file is conditional upon HAVE_SHLIB */ |
42 #ifdef HAVE_SHLIB | |
43 | |
44 /* Thankfully, most systems follow the ELFish dlopen() method. | |
45 */ | |
452 | 46 #if defined(HAVE_DLOPEN) |
428 | 47 #include <dlfcn.h> |
48 | |
49 #ifndef RTLD_LAZY | |
1383 | 50 # ifdef DL_LAZY |
51 # define RTLD_LAZY DL_LAZY | |
52 # else | |
53 # define RTLD_LAZY 1 | |
54 # endif | |
428 | 55 #endif /* RTLD_LAZY isn't defined under FreeBSD - ick */ |
56 | |
863 | 57 #ifndef RTLD_NOW |
1383 | 58 # ifdef DL_NOW |
59 # define RTLD_NOW DL_NOW | |
60 # else | |
61 # define RTLD_NOW 2 | |
62 # endif | |
863 | 63 #endif |
64 | |
428 | 65 dll_handle |
1706 | 66 dll_open (Lisp_Object fname) |
428 | 67 { |
1706 | 68 Extbyte *soname; |
69 | |
70 if (NILP (fname)) | |
71 { | |
72 soname = NULL; | |
73 } | |
74 else | |
75 { | |
76 LISP_STRING_TO_EXTERNAL (fname, soname, Qdll_filename_encoding); | |
77 } | |
78 return (dll_handle) dlopen (soname, RTLD_NOW); | |
428 | 79 } |
80 | |
81 int | |
82 dll_close (dll_handle h) | |
83 { | |
442 | 84 return dlclose ((void *) h); |
428 | 85 } |
86 | |
87 dll_func | |
1706 | 88 dll_function (dll_handle h, const CIbyte *n) |
428 | 89 { |
1383 | 90 MAYBE_PREPEND_UNDERSCORE (n); |
442 | 91 return (dll_func) dlsym ((void *) h, n); |
428 | 92 } |
93 | |
94 dll_var | |
1706 | 95 dll_variable (dll_handle h, const CIbyte *n) |
428 | 96 { |
1383 | 97 MAYBE_PREPEND_UNDERSCORE (n); |
428 | 98 return (dll_var)dlsym ((void *)h, n); |
99 } | |
100 | |
1706 | 101 Lisp_Object |
1811 | 102 dll_error () |
428 | 103 { |
1706 | 104 const Extbyte *msg; |
428 | 105 #if defined(HAVE_DLERROR) || defined(dlerror) |
1706 | 106 msg = (const Extbyte *) dlerror (); |
428 | 107 #elif defined(HAVE__DLERROR) |
1706 | 108 msg = (const Extbyte *) _dlerror(); |
428 | 109 #else |
1706 | 110 msg = (const Extbyte *) "Shared library error"; |
428 | 111 #endif |
4834
b3ea9c582280
Use new cygwin_conv_path API with Cygwin 1.7 for converting names between Win32 and POSIX, UTF-8-aware, with attendant changes elsewhere
Ben Wing <ben@xemacs.org>
parents:
3841
diff
changeset
|
112 return build_ext_string (msg, Qerror_message_encoding); |
428 | 113 } |
114 | |
115 #elif defined(HAVE_SHL_LOAD) | |
116 /* This is the HP/UX version */ | |
117 #include <dl.h> | |
118 dll_handle | |
1706 | 119 dll_open (Lisp_Object fname) |
428 | 120 { |
1706 | 121 Extbyte *soname; |
428 | 122 |
1706 | 123 if (NILP (fname)) |
124 { | |
125 soname = NULL; | |
126 } | |
127 else | |
128 { | |
129 LISP_STRING_TO_EXTERNAL (fname, soname, Qdll_filename_encoding); | |
130 } | |
131 return (dll_handle) shl_load (soname, BIND_DEFERRED, 0L); | |
428 | 132 } |
133 | |
134 int | |
135 dll_close (dll_handle h) | |
136 { | |
442 | 137 return shl_unload ((shl_t) h); |
428 | 138 } |
139 | |
140 dll_func | |
1706 | 141 dll_function (dll_handle h, const CIbyte *n) |
428 | 142 { |
143 long handle = 0L; | |
144 | |
442 | 145 if (shl_findsym ((shl_t *) &h, n, TYPE_PROCEDURE, &handle)) |
428 | 146 return NULL; |
147 | |
442 | 148 return (dll_func) handle; |
428 | 149 } |
150 | |
151 dll_var | |
1706 | 152 dll_variable (dll_handle h, const CIbyte *n) |
428 | 153 { |
154 long handle = 0L; | |
155 | |
442 | 156 if (shl_findsym ((shl_t *) &h, n, TYPE_DATA, &handle)) |
428 | 157 return NULL; |
158 | |
442 | 159 return (dll_var) handle; |
428 | 160 } |
161 | |
1706 | 162 Lisp_Object |
1811 | 163 dll_error () |
428 | 164 { |
165 /* #### WTF?! Shouldn't this at least attempt to get strerror or | |
166 something? --hniksic */ | |
4834
b3ea9c582280
Use new cygwin_conv_path API with Cygwin 1.7 for converting names between Win32 and POSIX, UTF-8-aware, with attendant changes elsewhere
Ben Wing <ben@xemacs.org>
parents:
3841
diff
changeset
|
167 return build_string ("Generic shared library error", |
b3ea9c582280
Use new cygwin_conv_path API with Cygwin 1.7 for converting names between Win32 and POSIX, UTF-8-aware, with attendant changes elsewhere
Ben Wing <ben@xemacs.org>
parents:
3841
diff
changeset
|
168 Qerror_message_encoding); |
428 | 169 } |
170 | |
1632 | 171 #elif defined (WIN32_NATIVE) || defined (CYGWIN) |
442 | 172 |
1632 | 173 #include "syswindows.h" |
174 #include "sysfile.h" | |
442 | 175 |
428 | 176 dll_handle |
1706 | 177 dll_open (Lisp_Object fname) |
428 | 178 { |
1706 | 179 Extbyte *soname; |
180 | |
181 if (NILP (fname)) | |
182 { | |
183 soname = NULL; | |
184 } | |
185 else | |
186 { | |
4834
b3ea9c582280
Use new cygwin_conv_path API with Cygwin 1.7 for converting names between Win32 and POSIX, UTF-8-aware, with attendant changes elsewhere
Ben Wing <ben@xemacs.org>
parents:
3841
diff
changeset
|
187 LISP_LOCAL_FILE_FORMAT_TO_TSTR (fname, soname); |
1706 | 188 } |
189 return (dll_handle) qxeLoadLibrary (soname); | |
428 | 190 } |
191 | |
192 int | |
193 dll_close (dll_handle h) | |
194 { | |
1706 | 195 return FreeLibrary ((HMODULE) h); |
428 | 196 } |
197 | |
198 dll_func | |
1706 | 199 dll_function (dll_handle h, const CIbyte *n) |
428 | 200 { |
1706 | 201 return (dll_func) GetProcAddress ((HINSTANCE) h, n); |
428 | 202 } |
203 | |
204 dll_func | |
1706 | 205 dll_variable (dll_handle h, const CIbyte *n) |
428 | 206 { |
1706 | 207 return (dll_func) GetProcAddress ((HINSTANCE) h, n); |
428 | 208 } |
209 | |
1706 | 210 Lisp_Object |
1811 | 211 dll_error () |
428 | 212 { |
1706 | 213 CIbyte err[32]; |
214 snprintf (err, 32, "Windows DLL Error %lu", GetLastError ()); | |
215 return build_string (err); | |
428 | 216 } |
1383 | 217 #elif defined(HAVE_DYLD) |
218 /* This section supports MacOSX dynamic libraries. Dynamically | |
219 loadable libraries must be compiled as bundles, not dynamiclibs. | |
220 */ | |
221 | |
222 #include <mach-o/dyld.h> | |
223 | |
224 dll_handle | |
1706 | 225 dll_open (Lisp_Object fname) |
1383 | 226 { |
1706 | 227 Extbyte *soname; |
1383 | 228 NSObjectFileImage file; |
1418 | 229 NSModule out; |
1706 | 230 NSObjectFileImageReturnCode ret; |
231 | |
2855 | 232 /* |
233 * MacOS X dll support is for bundles, not the current executable, so return | |
234 * NULL is this case. However, dll_function() uses a special hack where a | |
235 * NULL handle can be used to find executable symbols. This satisfies the | |
236 * needs of ui-gtk.c but is not a general solution. | |
237 */ | |
1706 | 238 if (NILP (fname)) |
239 { | |
2855 | 240 return NULL; |
1706 | 241 } |
242 else | |
243 { | |
244 LISP_STRING_TO_EXTERNAL (fname, soname, Qdll_filename_encoding); | |
245 } | |
246 ret = NSCreateObjectFileImageFromFile(soname, &file); | |
1383 | 247 if (ret != NSObjectFileImageSuccess) { |
248 return NULL; | |
249 } | |
1706 | 250 out = NSLinkModule(file, soname, |
1418 | 251 NSLINKMODULE_OPTION_BINDNOW | |
252 NSLINKMODULE_OPTION_PRIVATE | | |
253 NSLINKMODULE_OPTION_RETURN_ON_ERROR); | |
1383 | 254 return (dll_handle)out; |
255 } | |
256 | |
257 int | |
258 dll_close (dll_handle h) | |
259 { | |
260 return NSUnLinkModule((NSModule)h, NSUNLINKMODULE_OPTION_NONE); | |
261 } | |
262 | |
1851 | 263 /* Given an address, return the mach_header for the image containing it |
264 * or zero if the given address is not contained in any loaded images. | |
265 * | |
266 * Note: image_for_address(), my_find_image() and search_linked_libs() are | |
267 * based on code from the dlcompat library | |
268 * (http://www.opendarwin.org/projects/dlcompat). | |
269 */ | |
270 | |
3841 | 271 static const struct mach_header* |
1851 | 272 image_for_address(void *address) |
273 { | |
274 unsigned long i; | |
275 unsigned long count = _dyld_image_count(); | |
3841 | 276 const struct mach_header *mh = 0; |
1851 | 277 |
278 for (i = 0; i < count; i++) | |
279 { | |
280 unsigned long addr = (unsigned long)address - | |
281 _dyld_get_image_vmaddr_slide(i); | |
282 mh = _dyld_get_image_header(i); | |
283 | |
284 if (mh) | |
285 { | |
286 struct load_command *lc = | |
287 (struct load_command *)((char *)mh + sizeof(struct mach_header)); | |
288 unsigned long j; | |
289 | |
290 for (j = 0; j < mh->ncmds; | |
291 j++, lc = (struct load_command *)((char *)lc + lc->cmdsize)) | |
292 { | |
293 if (LC_SEGMENT == lc->cmd && | |
294 addr >= ((struct segment_command *)lc)->vmaddr && | |
295 addr < | |
296 ((struct segment_command *)lc)->vmaddr + | |
297 ((struct segment_command *)lc)->vmsize) | |
298 { | |
299 goto image_found; | |
300 } | |
301 } | |
302 } | |
303 | |
304 mh = 0; | |
305 } | |
306 | |
307 image_found: | |
308 return mh; | |
309 } | |
310 | |
311 static const struct mach_header* | |
312 my_find_image(const char *name) | |
313 { | |
314 const struct mach_header *mh = (struct mach_header *) | |
315 NSAddImage(name, NSADDIMAGE_OPTION_RETURN_ONLY_IF_LOADED | | |
316 NSADDIMAGE_OPTION_RETURN_ON_ERROR); | |
317 | |
318 if (!mh) | |
319 { | |
320 int count = _dyld_image_count(); | |
321 int j; | |
322 | |
323 for (j = 0; j < count; j++) | |
324 { | |
325 const char *id = _dyld_get_image_name(j); | |
326 | |
327 if (!strcmp(id, name)) | |
328 { | |
329 mh = _dyld_get_image_header(j); | |
330 break; | |
331 } | |
332 } | |
333 } | |
334 | |
335 return mh; | |
336 } | |
337 | |
338 /* | |
339 * dyld adds libraries by first adding the directly dependant libraries in | |
340 * link order, and then adding the dependencies for those libraries, so we | |
341 * should do the same... but we don't bother adding the extra dependencies, if | |
342 * the symbols are neither in the loaded image nor any of it's direct | |
343 * dependencies, then it probably isn't there. | |
344 */ | |
345 static NSSymbol | |
346 search_linked_libs(const struct mach_header * mh, const char *symbol) | |
347 { | |
2054 | 348 unsigned long n; |
1851 | 349 NSSymbol nssym = 0; |
350 | |
351 struct load_command *lc = | |
352 (struct load_command *)((char *)mh + sizeof(struct mach_header)); | |
353 | |
354 for (n = 0; n < mh->ncmds; | |
355 n++, lc = (struct load_command *)((char *)lc + lc->cmdsize)) | |
356 { | |
357 if ((LC_LOAD_DYLIB == lc->cmd) || (LC_LOAD_WEAK_DYLIB == lc->cmd)) | |
358 { | |
359 struct mach_header *wh; | |
360 | |
361 if ((wh = (struct mach_header *) | |
362 my_find_image((char *)(((struct dylib_command *)lc)->dylib.name.offset + | |
363 (char *)lc)))) | |
364 { | |
365 if (NSIsSymbolNameDefinedInImage(wh, symbol)) | |
366 { | |
367 nssym = | |
368 NSLookupSymbolInImage(wh, | |
369 symbol, | |
370 NSLOOKUPSYMBOLINIMAGE_OPTION_BIND | | |
371 NSLOOKUPSYMBOLINIMAGE_OPTION_RETURN_ON_ERROR); | |
372 break; | |
373 } | |
374 } | |
375 } | |
376 } | |
377 | |
378 return nssym; | |
379 } | |
380 | |
1383 | 381 dll_func |
1706 | 382 dll_function (dll_handle h, const CIbyte *n) |
1383 | 383 { |
1851 | 384 NSSymbol sym = 0; |
1383 | 385 MAYBE_PREPEND_UNDERSCORE (n); |
1851 | 386 |
387 /* NULL means the program image and shared libraries, not bundles. */ | |
388 | |
389 if (h == NULL) | |
390 { | |
391 /* NOTE: This assumes that this function is included in the main program | |
392 and not in a shared library. */ | |
2054 | 393 const struct mach_header* my_mh = image_for_address((void*) &dll_function); |
1851 | 394 |
395 if (NSIsSymbolNameDefinedInImage(my_mh, n)) | |
396 { | |
397 sym = | |
398 NSLookupSymbolInImage(my_mh, | |
399 n, | |
400 NSLOOKUPSYMBOLINIMAGE_OPTION_BIND | | |
401 NSLOOKUPSYMBOLINIMAGE_OPTION_RETURN_ON_ERROR); | |
402 } | |
403 | |
404 if (!sym) | |
405 { | |
406 sym = search_linked_libs(my_mh, n); | |
407 } | |
408 } | |
409 else | |
410 { | |
411 sym = NSLookupSymbolInModule((NSModule)h, n); | |
412 } | |
413 | |
414 if (sym == 0) return 0; | |
415 return (dll_func)NSAddressOfSymbol(sym); | |
416 } | |
1383 | 417 |
418 dll_var | |
1706 | 419 dll_variable (dll_handle h, const CIbyte *n) |
1383 | 420 { |
421 NSSymbol sym; | |
422 MAYBE_PREPEND_UNDERSCORE (n); | |
423 sym = NSLookupSymbolInModule((NSModule)h, n); | |
424 if (sym == 0) return 0; | |
425 return (dll_var)NSAddressOfSymbol(sym); | |
426 } | |
427 | |
1706 | 428 Lisp_Object |
1811 | 429 dll_error () |
1383 | 430 { |
431 NSLinkEditErrors c; | |
432 int errorNumber; | |
1706 | 433 const CIbyte *fileNameWithError, *errorString; |
1383 | 434 NSLinkEditError(&c, &errorNumber, &fileNameWithError, &errorString); |
4834
b3ea9c582280
Use new cygwin_conv_path API with Cygwin 1.7 for converting names between Win32 and POSIX, UTF-8-aware, with attendant changes elsewhere
Ben Wing <ben@xemacs.org>
parents:
3841
diff
changeset
|
435 return build_ext_string (errorString, Qerror_message_encoding); |
1383 | 436 } |
2078 | 437 #elif HAVE_LTDL |
438 /* Libtool's libltdl */ | |
439 #include <ltdl.h> | |
440 | |
441 dll_handle | |
442 dll_open (Lisp_Object fname) | |
443 { | |
444 Extbyte *soname; | |
445 | |
446 if (NILP (fname)) | |
447 { | |
448 soname = NULL; | |
449 } | |
450 else | |
451 { | |
452 LISP_STRING_TO_EXTERNAL (fname, soname, Qdll_filename_encoding); | |
453 } | |
454 return (dll_handle) lt_dlopen (soname); | |
455 } | |
456 | |
457 int | |
458 dll_close (dll_handle h) | |
459 { | |
460 return lt_dlclose ((lt_dlhandle) h); | |
461 } | |
462 | |
463 dll_func | |
464 dll_function (dll_handle h, const CIbyte *n) | |
465 { | |
466 MAYBE_PREPEND_UNDERSCORE (n); | |
467 return (dll_func) lt_dlsym ((lt_dlhandle) h, n); | |
468 } | |
469 | |
470 dll_var | |
471 dll_variable (dll_handle h, const CIbyte *n) | |
472 { | |
473 MAYBE_PREPEND_UNDERSCORE (n); | |
474 return (dll_var) lt_dlsym ((lt_dlhandle) h, n); | |
475 } | |
476 | |
477 Lisp_Object | |
478 dll_error () | |
479 { | |
4834
b3ea9c582280
Use new cygwin_conv_path API with Cygwin 1.7 for converting names between Win32 and POSIX, UTF-8-aware, with attendant changes elsewhere
Ben Wing <ben@xemacs.org>
parents:
3841
diff
changeset
|
480 return build_ext_string (lt_dlerror (), Qerror_message_encoding); |
2078 | 481 } |
428 | 482 #else |
1706 | 483 /* Catchall if we don't know about this system's method of dynamic loading */ |
428 | 484 dll_handle |
1706 | 485 dll_open (Lisp_Object fname) |
428 | 486 { |
487 return NULL; | |
488 } | |
489 | |
490 int | |
491 dll_close (dll_handle h) | |
492 { | |
493 return 0; | |
494 } | |
495 | |
496 dll_func | |
1706 | 497 dll_function (dll_handle h, const CIbyte *n) |
428 | 498 { |
499 return NULL; | |
500 } | |
501 | |
502 dll_func | |
1706 | 503 dll_variable (dll_handle h, const CIbyte *n) |
428 | 504 { |
505 return NULL; | |
506 } | |
507 | |
1706 | 508 Lisp_Object |
1811 | 509 dll_error () |
428 | 510 { |
1706 | 511 return build_string ("Shared libraries not implemented on this system"); |
428 | 512 } |
513 #endif /* System conditionals */ | |
514 | |
515 #endif /* HAVE_SHLIB */ |