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 { \
+ − 32 char *buf = alloca_array (char, strlen (n) + 2); \
+ − 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 int
442
+ − 66 dll_init (const char *arg)
428
+ − 67 {
+ − 68 return 0;
+ − 69 }
+ − 70
+ − 71 dll_handle
442
+ − 72 dll_open (const char *fname)
428
+ − 73 {
880
+ − 74 return (dll_handle) dlopen (fname, RTLD_NOW);
428
+ − 75 }
+ − 76
+ − 77 int
+ − 78 dll_close (dll_handle h)
+ − 79 {
442
+ − 80 return dlclose ((void *) h);
428
+ − 81 }
+ − 82
+ − 83 dll_func
442
+ − 84 dll_function (dll_handle h, const char *n)
428
+ − 85 {
1383
+ − 86 MAYBE_PREPEND_UNDERSCORE (n);
442
+ − 87 return (dll_func) dlsym ((void *) h, n);
428
+ − 88 }
+ − 89
+ − 90 dll_var
442
+ − 91 dll_variable (dll_handle h, const char *n)
428
+ − 92 {
1383
+ − 93 MAYBE_PREPEND_UNDERSCORE (n);
428
+ − 94 return (dll_var)dlsym ((void *)h, n);
+ − 95 }
+ − 96
442
+ − 97 const char *
428
+ − 98 dll_error (dll_handle h)
+ − 99 {
+ − 100 #if defined(HAVE_DLERROR) || defined(dlerror)
442
+ − 101 return (const char *) dlerror ();
428
+ − 102 #elif defined(HAVE__DLERROR)
442
+ − 103 return (const char *) _dlerror();
428
+ − 104 #else
+ − 105 return "Shared library error";
+ − 106 #endif
+ − 107 }
+ − 108
+ − 109 #elif defined(HAVE_SHL_LOAD)
+ − 110 /* This is the HP/UX version */
+ − 111 #include <dl.h>
+ − 112 int
442
+ − 113 dll_init (const char *arg)
428
+ − 114 {
+ − 115 return 0;
+ − 116 }
+ − 117
+ − 118 dll_handle
442
+ − 119 dll_open (const char *fname)
428
+ − 120 {
442
+ − 121 /* shl_load will hang hard if passed a NULL fname. */
+ − 122 if (fname == NULL) return NULL;
428
+ − 123
1383
+ − 124 return (dll_handle) shl_load (fname, BIND_DEFERRED, 0L);
428
+ − 125 }
+ − 126
+ − 127 int
+ − 128 dll_close (dll_handle h)
+ − 129 {
442
+ − 130 return shl_unload ((shl_t) h);
428
+ − 131 }
+ − 132
+ − 133 dll_func
442
+ − 134 dll_function (dll_handle h, const char *n)
428
+ − 135 {
+ − 136 long handle = 0L;
+ − 137
442
+ − 138 if (shl_findsym ((shl_t *) &h, n, TYPE_PROCEDURE, &handle))
428
+ − 139 return NULL;
+ − 140
442
+ − 141 return (dll_func) handle;
428
+ − 142 }
+ − 143
+ − 144 dll_var
442
+ − 145 dll_variable (dll_handle h, const char *n)
428
+ − 146 {
+ − 147 long handle = 0L;
+ − 148
442
+ − 149 if (shl_findsym ((shl_t *) &h, n, TYPE_DATA, &handle))
428
+ − 150 return NULL;
+ − 151
442
+ − 152 return (dll_var) handle;
428
+ − 153 }
+ − 154
442
+ − 155 const char *
428
+ − 156 dll_error (dll_handle h)
+ − 157 {
+ − 158 /* #### WTF?! Shouldn't this at least attempt to get strerror or
+ − 159 something? --hniksic */
+ − 160 return "Generic shared library error";
+ − 161 }
+ − 162
1596
+ − 163 #elif defined(HAVE_DLD_INIT)
428
+ − 164 #include <dld.h>
+ − 165 int
442
+ − 166 dll_init (const char *arg)
428
+ − 167 {
+ − 168 char *real_exe = dld_find_executable (arg);
+ − 169 int rc;
+ − 170
+ − 171 rc = dld_init (real_exe);
+ − 172 if (rc)
+ − 173 {
+ − 174 dld_perror (exe);
+ − 175 return -1;
+ − 176 }
+ − 177 return 0;
+ − 178 }
+ − 179
+ − 180 dll_handle
442
+ − 181 dll_open (const char *fname)
428
+ − 182 {
+ − 183 rc = dld_link (fname);
+ − 184 if (rc)
+ − 185 return NULL;
+ − 186
442
+ − 187 return (dll_handle) 1;
428
+ − 188 }
+ − 189
+ − 190 int
+ − 191 dll_close (dll_handle h)
+ − 192 {
+ − 193 /* *sigh* DLD is pretty lame and doesn't return a handle that you can use
+ − 194 ** later on to free the file - you have to remember the filename and
+ − 195 ** use that as the unlinker. We should eventually keep a linked list
+ − 196 ** of loaded modules and then use the node pointer as the unique id
+ − 197 ** for the shared library. Wheeee. But not now.
+ − 198 */
+ − 199 return 1;
+ − 200 }
+ − 201
+ − 202 DLL_FUNC
442
+ − 203 dll_function (dll_handle h, const char *n)
428
+ − 204 {
442
+ − 205 return dld_get_func (n);
428
+ − 206 }
+ − 207
+ − 208 DLL_FUNC
442
+ − 209 dll_variable (dll_handle h, const char *n)
428
+ − 210 {
442
+ − 211 return dld_get_symbol (n);
428
+ − 212 }
1632
+ − 213 #elif defined (WIN32_NATIVE) || defined (CYGWIN)
442
+ − 214
1632
+ − 215 #include "syswindows.h"
+ − 216 #include "sysfile.h"
442
+ − 217
428
+ − 218 int
442
+ − 219 dll_init (const char *arg)
428
+ − 220 {
+ − 221 return 0;
+ − 222 }
+ − 223
+ − 224 dll_handle
442
+ − 225 dll_open (const char *fname)
428
+ − 226 {
1632
+ − 227 Ibyte *winfname, *unifname;
+ − 228 LOCAL_TO_WIN32_FILE_FORMAT ((char *) fname, winfname);
+ − 229 C_STRING_TO_TSTR (winfname, unifname);
+ − 230 return (dll_handle) qxeLoadLibrary (unifname);
428
+ − 231 }
+ − 232
+ − 233 int
+ − 234 dll_close (dll_handle h)
+ − 235 {
+ − 236 return FreeLibrary (h);
+ − 237 }
+ − 238
+ − 239 dll_func
442
+ − 240 dll_function (dll_handle h, const char *n)
428
+ − 241 {
442
+ − 242 return (dll_func) GetProcAddress (h, n);
428
+ − 243 }
+ − 244
+ − 245 dll_func
442
+ − 246 dll_variable (dll_handle h, const char *n)
428
+ − 247 {
442
+ − 248 return (dll_func) GetProcAddress (h, n);
428
+ − 249 }
+ − 250
442
+ − 251 const char *
428
+ − 252 dll_error (dll_handle h)
+ − 253 {
1632
+ − 254 /* Since nobody frees the returned string, I have to make this ugly hack. */
+ − 255 static char err[32] = "Windows DLL Error ";
+ − 256 snprintf (&err[18], 14, "%lu", GetLastError ());
+ − 257 return err;
428
+ − 258 }
1383
+ − 259 #elif defined(HAVE_DYLD)
+ − 260 /* This section supports MacOSX dynamic libraries. Dynamically
+ − 261 loadable libraries must be compiled as bundles, not dynamiclibs.
+ − 262 */
+ − 263
+ − 264 #include <mach-o/dyld.h>
+ − 265
+ − 266 int
+ − 267 dll_init (const char *arg)
+ − 268 {
+ − 269 return 0;
+ − 270 }
+ − 271
+ − 272 dll_handle
+ − 273 dll_open (const char *fname)
+ − 274 {
+ − 275 NSObjectFileImage file;
1418
+ − 276 NSModule out;
1383
+ − 277 NSObjectFileImageReturnCode ret =
+ − 278 NSCreateObjectFileImageFromFile(fname, &file);
+ − 279 if (ret != NSObjectFileImageSuccess) {
+ − 280 return NULL;
+ − 281 }
1418
+ − 282 out = NSLinkModule(file, fname,
+ − 283 NSLINKMODULE_OPTION_BINDNOW |
+ − 284 NSLINKMODULE_OPTION_PRIVATE |
+ − 285 NSLINKMODULE_OPTION_RETURN_ON_ERROR);
1383
+ − 286 return (dll_handle)out;
+ − 287 }
+ − 288
+ − 289 int
+ − 290 dll_close (dll_handle h)
+ − 291 {
+ − 292 return NSUnLinkModule((NSModule)h, NSUNLINKMODULE_OPTION_NONE);
+ − 293 }
+ − 294
+ − 295 dll_func
+ − 296 dll_function (dll_handle h, const char *n)
+ − 297 {
+ − 298 NSSymbol sym;
+ − 299 MAYBE_PREPEND_UNDERSCORE (n);
+ − 300 sym = NSLookupSymbolInModule((NSModule)h, n);
+ − 301 if (sym == 0) return 0;
+ − 302 return (dll_func)NSAddressOfSymbol(sym);
+ − 303 }
+ − 304
+ − 305 dll_var
+ − 306 dll_variable (dll_handle h, const char *n)
+ − 307 {
+ − 308 NSSymbol sym;
+ − 309 MAYBE_PREPEND_UNDERSCORE (n);
+ − 310 sym = NSLookupSymbolInModule((NSModule)h, n);
+ − 311 if (sym == 0) return 0;
+ − 312 return (dll_var)NSAddressOfSymbol(sym);
+ − 313 }
+ − 314
+ − 315 const char *
+ − 316 dll_error (dll_handle h)
+ − 317 {
+ − 318 NSLinkEditErrors c;
+ − 319 int errorNumber;
+ − 320 const char *fileNameWithError, *errorString;
+ − 321 NSLinkEditError(&c, &errorNumber, &fileNameWithError, &errorString);
+ − 322 return errorString;
+ − 323 }
428
+ − 324 #else
+ − 325 /* Catchall if we don't know about this systems method of dynamic loading */
+ − 326 int
442
+ − 327 dll_init (const char *arg)
428
+ − 328 {
+ − 329 return -1;
+ − 330 }
+ − 331
+ − 332 dll_handle
442
+ − 333 dll_open (const char *fname)
428
+ − 334 {
+ − 335 return NULL;
+ − 336 }
+ − 337
+ − 338 int
+ − 339 dll_close (dll_handle h)
+ − 340 {
+ − 341 return 0;
+ − 342 }
+ − 343
+ − 344 dll_func
442
+ − 345 dll_function (dll_handle h, const char *n)
428
+ − 346 {
+ − 347 return NULL;
+ − 348 }
+ − 349
+ − 350 dll_func
442
+ − 351 dll_variable (dll_handle h, const char *n)
428
+ − 352 {
+ − 353 return NULL;
+ − 354 }
+ − 355
442
+ − 356 const char *
428
+ − 357 dll_error (dll_handle h)
+ − 358 {
+ − 359 return "Shared libraries not implemented on this system";
+ − 360 }
+ − 361 #endif /* System conditionals */
+ − 362
+ − 363 #endif /* HAVE_SHLIB */