2003-09-16 22:26:57 -04:00
|
|
|
/* loadlib.c
|
2003-09-07 05:55:56 -04:00
|
|
|
*
|
|
|
|
* $Id$
|
|
|
|
*
|
|
|
|
* Copyright 1990, 1991, 1992, 1993, 1994, 1995, Oliver Laumann, Berlin
|
|
|
|
* Copyright 2002, 2003 Sam Hocevar <sam@zoy.org>, Paris
|
|
|
|
*
|
|
|
|
* This software was derived from Elk 1.2, which was Copyright 1987, 1988,
|
|
|
|
* 1989, Nixdorf Computer AG and TELES GmbH, Berlin (Elk 1.2 has been written
|
|
|
|
* by Oliver Laumann for TELES Telematic Services, Berlin, in a joint project
|
|
|
|
* between TELES and Nixdorf Microprocessor Engineering, Berlin).
|
|
|
|
*
|
|
|
|
* Oliver Laumann, TELES GmbH, Nixdorf Computer AG and Sam Hocevar, as co-
|
|
|
|
* owners or individual owners of copyright in this software, grant to any
|
|
|
|
* person or company a worldwide, royalty free, license to
|
|
|
|
*
|
|
|
|
* i) copy this software,
|
|
|
|
* ii) prepare derivative works based on this software,
|
|
|
|
* iii) distribute copies of this software or derivative works,
|
|
|
|
* iv) perform this software, or
|
|
|
|
* v) display this software,
|
|
|
|
*
|
|
|
|
* provided that this notice is not removed and that neither Oliver Laumann
|
|
|
|
* nor Teles nor Nixdorf are deemed to have made any representations as to
|
|
|
|
* the suitability of this software for any purpose nor are held responsible
|
|
|
|
* for any defects of this software.
|
|
|
|
*
|
|
|
|
* THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include "config.h"
|
|
|
|
|
2003-09-07 05:56:55 -04:00
|
|
|
#ifdef CAN_LOAD_LIB
|
|
|
|
|
2003-09-09 09:30:23 -04:00
|
|
|
#include <errno.h>
|
2003-09-07 05:55:56 -04:00
|
|
|
#include <stdlib.h>
|
|
|
|
#include <string.h>
|
|
|
|
#include <unistd.h>
|
|
|
|
|
2003-09-09 09:30:23 -04:00
|
|
|
#if defined(HAVE_MACH_O_DYLD_H)
|
2003-09-07 18:07:33 -04:00
|
|
|
# include <mach-o/dyld.h>
|
|
|
|
#elif defined(HAVE_DL_DLOPEN)
|
2003-09-09 09:30:23 -04:00
|
|
|
# if defined(HAVE_DLFCN_H)
|
|
|
|
# include <dlfcn.h>
|
|
|
|
# endif
|
|
|
|
# if defined(HAVE_SYS_DL_H)
|
|
|
|
# include <sys/dl.h>
|
|
|
|
# endif
|
|
|
|
#elif defined(HAVE_DL_SHL_LOAD)
|
|
|
|
# if defined(HAVE_DL_H)
|
|
|
|
# include <dl.h>
|
|
|
|
# endif
|
2003-09-07 18:07:33 -04:00
|
|
|
#endif
|
|
|
|
|
2003-09-07 05:55:56 -04:00
|
|
|
#include "kernel.h"
|
|
|
|
|
|
|
|
extern void Free_Symbols (SYMTAB *);
|
|
|
|
extern void Call_Initializers (SYMTAB *, char *, int);
|
|
|
|
|
|
|
|
void Dlopen_File (char *fn) {
|
|
|
|
SYM *sp;
|
|
|
|
|
2003-09-07 18:07:33 -04:00
|
|
|
#if defined(HAVE_DL_DYLD)
|
|
|
|
NSModule handle;
|
|
|
|
NSObjectFileImage image;
|
|
|
|
NSObjectFileImageReturnCode ret;
|
|
|
|
|
|
|
|
if (Verb_Load)
|
|
|
|
printf ("[dyld %s]\n", fn);
|
|
|
|
|
2003-09-09 09:30:23 -04:00
|
|
|
ret = NSCreateObjectFileImageFromFile (fn, &image);
|
2003-09-07 18:07:33 -04:00
|
|
|
|
|
|
|
if (ret != NSObjectFileImageSuccess)
|
|
|
|
Primitive_Error ("could not map `~%~s'",
|
|
|
|
Make_String (fn, strlen (fn)));
|
|
|
|
|
|
|
|
/* Open the dynamic module */
|
2003-09-09 09:30:23 -04:00
|
|
|
handle = NSLinkModule (image, fn, NSLINKMODULE_OPTION_RETURN_ON_ERROR);
|
2003-09-07 18:07:33 -04:00
|
|
|
|
|
|
|
if (!handle) {
|
|
|
|
NSLinkEditErrors errors;
|
2003-09-09 09:30:23 -04:00
|
|
|
const char *file, *err;
|
2003-09-07 18:07:33 -04:00
|
|
|
int errnum;
|
2003-09-09 09:30:23 -04:00
|
|
|
NSLinkEditError (&errors, &errnum, &file, &err);
|
2003-09-07 18:07:33 -04:00
|
|
|
Primitive_Error ("could not dyld `~%~s': ~%~s",
|
|
|
|
Make_String (file, strlen (file)),
|
2003-09-09 09:30:23 -04:00
|
|
|
Make_String (err, strlen (err)));
|
2003-09-07 18:07:33 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
/* Destroy our image, we won't need it */
|
2003-09-09 09:30:23 -04:00
|
|
|
NSDestroyObjectFileImage (image);
|
2003-09-07 18:07:33 -04:00
|
|
|
|
2003-09-09 09:30:23 -04:00
|
|
|
/* NSUnLinkModule (handle, FALSE); */
|
2003-09-07 18:07:33 -04:00
|
|
|
|
2003-09-13 02:31:24 -04:00
|
|
|
#elif defined(WIN32)
|
|
|
|
void *handle;
|
|
|
|
|
|
|
|
if (Verb_Load)
|
|
|
|
printf ("[dll %s]\n", fn);
|
|
|
|
|
|
|
|
handle = LoadLibrary (fn);
|
|
|
|
|
|
|
|
if (handle == NULL) {
|
|
|
|
Primitive_Error ("LoadLibrary failed on ~%~s",
|
|
|
|
Make_String (fn, strlen (fn)));
|
|
|
|
}
|
|
|
|
|
2003-09-07 18:07:33 -04:00
|
|
|
#elif defined(HAVE_DL_DLOPEN)
|
|
|
|
void *handle;
|
|
|
|
|
2003-09-07 05:55:56 -04:00
|
|
|
if (Verb_Load)
|
|
|
|
printf ("[dlopen %s]\n", fn);
|
2003-09-07 18:07:33 -04:00
|
|
|
|
2003-09-09 09:30:23 -04:00
|
|
|
#if defined(RTLD_GLOBAL)
|
|
|
|
handle = dlopen (fn, RTLD_NOW | RTLD_GLOBAL);
|
|
|
|
#elif defined(DL_GLOBAL)
|
|
|
|
handle = dlopen (fn, DL_NOW | DL_GLOBAL);
|
|
|
|
#else
|
|
|
|
handle = dlopen (fn, 0);
|
|
|
|
#endif
|
2003-09-07 18:07:33 -04:00
|
|
|
|
|
|
|
if (handle == NULL) {
|
2003-09-09 09:30:23 -04:00
|
|
|
char *err = dlerror ();
|
2003-09-07 18:07:33 -04:00
|
|
|
Primitive_Error ("dlopen failed: ~%~s",
|
2003-09-09 09:30:23 -04:00
|
|
|
Make_String (err, strlen (err)));
|
|
|
|
}
|
|
|
|
|
|
|
|
#elif defined(HAVE_DL_SHL_LOAD)
|
|
|
|
shl_t handle;
|
|
|
|
|
|
|
|
if (Verb_Load)
|
|
|
|
printf ("[shl_load %s]\n", fn);
|
|
|
|
|
|
|
|
handle = shl_load (fn, BIND_IMMEDIATE | BIND_NONFATAL, NULL);
|
|
|
|
|
|
|
|
if (handle == NULL) {
|
|
|
|
char *err = strerror (errno);
|
|
|
|
Primitive_Error ("shl_load failed: ~%~s",
|
|
|
|
Make_String (err, strlen (err)));
|
2003-09-07 05:55:56 -04:00
|
|
|
}
|
2003-09-07 18:07:33 -04:00
|
|
|
|
|
|
|
#else
|
|
|
|
# error "No dynamic plugins API"
|
|
|
|
#endif
|
|
|
|
|
2003-09-07 05:55:56 -04:00
|
|
|
if (The_Symbols)
|
|
|
|
Free_Symbols (The_Symbols);
|
2003-09-07 18:07:33 -04:00
|
|
|
|
2003-09-07 05:55:56 -04:00
|
|
|
The_Symbols = Open_File_And_Snarf_Symbols (fn);
|
2003-09-07 18:07:33 -04:00
|
|
|
for (sp = The_Symbols->first; sp; sp = sp->next) {
|
|
|
|
#if defined(HAVE_DL_DYLD)
|
2003-09-09 09:30:23 -04:00
|
|
|
NSSymbol sym = NSLookupSymbolInModule (handle, sp->name);
|
2003-09-07 18:07:33 -04:00
|
|
|
if (sym)
|
2003-09-09 09:30:23 -04:00
|
|
|
sp->value = (unsigned long int)(intptr_t)NSAddressOfSymbol (sym);
|
2003-09-07 18:07:33 -04:00
|
|
|
|
2003-09-13 02:31:24 -04:00
|
|
|
#elif defined(WIN32)
|
|
|
|
sp->value = (void *)GetProcAddress (handle, (MYCHAR *)sym);
|
|
|
|
|
2003-09-07 18:07:33 -04:00
|
|
|
#elif defined(HAVE_DL_DLOPEN)
|
|
|
|
/* dlsym() may fail for symbols not exported by object file;
|
|
|
|
* this can be safely ignored. */
|
2003-09-07 09:13:18 -04:00
|
|
|
sp->value = (unsigned long int)(intptr_t)dlsym (handle, sp->name);
|
2003-09-07 18:07:33 -04:00
|
|
|
|
2003-09-09 09:30:23 -04:00
|
|
|
#elif defined(HAVE_DL_SHL_LOAD)
|
|
|
|
void *sym;
|
|
|
|
shl_findsym (&handle, "share", TYPE_UNDEFINED, &sym);
|
|
|
|
sp->value = (unsigned long int)(intptr_t)sym;
|
2003-09-07 18:07:33 -04:00
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
2003-09-07 05:55:56 -04:00
|
|
|
Call_Initializers (The_Symbols, 0, PR_CONSTRUCTOR);
|
|
|
|
Call_Initializers (The_Symbols, 0, PR_EXTENSION);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void Load_Lib (Object libs) {
|
|
|
|
Object port, name;
|
|
|
|
|
|
|
|
if (Nullp (libs))
|
|
|
|
return;
|
|
|
|
|
|
|
|
Load_Lib (Cdr (libs));
|
|
|
|
|
|
|
|
GC_Node2;
|
|
|
|
port = name = Null;
|
|
|
|
GC_Link2 (port, name);
|
|
|
|
port = General_Open_File (Car (libs), P_INPUT, Var_Get (V_Load_Path));
|
|
|
|
name = PORT(port)->name;
|
|
|
|
Dlopen_File (STRING(name)->data);
|
|
|
|
(void)P_Close_Input_Port (port);
|
|
|
|
GC_Unlink;
|
|
|
|
}
|
|
|
|
|
|
|
|
void Load_Library (Object libs) {
|
|
|
|
Disable_Interrupts;
|
|
|
|
Load_Lib (libs);
|
|
|
|
Enable_Interrupts;
|
|
|
|
}
|
|
|
|
|
|
|
|
#endif /* CAN_LOAD_LIB */
|
|
|
|
|