From 3d1b7d069fe5280f05519523f330f165ea222eae Mon Sep 17 00:00:00 2001 From: sam Date: Sun, 7 Sep 2003 22:07:33 +0000 Subject: [PATCH] * Implemented the dyld plugin loader for OS X. git-svn-id: svn://svn.zoy.org/elk/trunk@125 55e467fa-43c5-0310-a8a2-de718669efc6 --- configure.ac | 10 ++----- src/loadlib.c | 76 ++++++++++++++++++++++++++++++++++++++++++++------- 2 files changed, 68 insertions(+), 18 deletions(-) diff --git a/configure.ac b/configure.ac index 47bb406..964ebfb 100644 --- a/configure.ac +++ b/configure.ac @@ -158,9 +158,10 @@ ac_cv_my_can_load_lib=no AC_CHECK_HEADERS(mach-o/dyld.h, [AC_CHECK_FUNCS(NSLinkModule, [AC_DEFINE(HAVE_DL_DYLD, 1, [Define if you have the Darwin dyld API]) + AC_DEFINE(SYMS_BEGIN_WITH, ['_'], [Define if symbols start with '_']) ac_cv_my_can_load_lib=yes])]) -AC_CHECK_HEADERS(a.out.h, ac_cv_my_can_load_lib=yes) +AC_CHECK_HEADERS(a.out.h) # Only test for dlopen() if the others didn't work if test "${ac_cv_my_can_load_lib}" = "no"; then @@ -185,13 +186,6 @@ AC_DEFINE(CACHECTL_H, , [FIXME HARD]) # a call to _exit. AC_CHECK_FUNCS(atexit) -# Do the names of external functions in the symbol table always begin -# with a special character (such as underline)? If so, syms_begin_with -# should hold this character, otherwise leave it empty. -if false; then - AC_DEFINE(SYMS_BEGIN_WITH, ['_'], [FIXME HARD]) -fi - # The symbol prefixes of extension initialization and finalization # functions (without the initial $syms_begin_with). Do not change # these unless the compiler or linker restricts the length of symbols! diff --git a/src/loadlib.c b/src/loadlib.c index d26ffa8..d2ed371 100644 --- a/src/loadlib.c +++ b/src/loadlib.c @@ -32,36 +32,92 @@ #ifdef CAN_LOAD_LIB -#include #include #include #include +#if defined(HAVE_DL_DYLD) +# include +#elif defined(HAVE_DL_DLOPEN) +# include +#endif + #include "kernel.h" extern void Free_Symbols (SYMTAB *); extern void Call_Initializers (SYMTAB *, char *, int); void Dlopen_File (char *fn) { - void *handle; SYM *sp; +#if defined(HAVE_DL_DYLD) + NSModule handle; + NSObjectFileImage image; + NSObjectFileImageReturnCode ret; + + if (Verb_Load) + printf ("[dyld %s]\n", fn); + + ret = NSCreateObjectFileImageFromFile(fn, &image); + + if (ret != NSObjectFileImageSuccess) + Primitive_Error ("could not map `~%~s'", + Make_String (fn, strlen (fn))); + + /* Open the dynamic module */ + handle = NSLinkModule(image, fn, NSLINKMODULE_OPTION_RETURN_ON_ERROR); + + if (!handle) { + NSLinkEditErrors errors; + const char *file, *errstr; + int errnum; + NSLinkEditError(&errors, &errnum, &file, &errstr); + Primitive_Error ("could not dyld `~%~s': ~%~s", + Make_String (file, strlen (file)), + Make_String (errstr, strlen (errstr))); + } + + /* Destroy our image, we won't need it */ + NSDestroyObjectFileImage(image); + + /* NSUnLinkModule(handle, FALSE); */ + +#elif defined(HAVE_DL_DLOPEN) + void *handle; + if (Verb_Load) printf ("[dlopen %s]\n", fn); - if ((handle = dlopen (fn, RTLD_NOW|RTLD_GLOBAL)) == 0) { + + handle = dlopen (fn, RTLD_NOW|RTLD_GLOBAL); + + if (handle == NULL) { char *errstr = dlerror (); - Primitive_Error ("dlopen failed:~%~s", - Make_String (errstr, strlen (errstr))); + Primitive_Error ("dlopen failed: ~%~s", + Make_String (errstr, strlen (errstr))); } + +#else +# error "No dynamic plugins API" +#endif + if (The_Symbols) Free_Symbols (The_Symbols); + The_Symbols = Open_File_And_Snarf_Symbols (fn); - /* - * dlsym() may fail for symbols not exported by object file; - * this can be safely ignored. - */ - for (sp = The_Symbols->first; sp; sp = sp->next) + for (sp = The_Symbols->first; sp; sp = sp->next) { +#if defined(HAVE_DL_DYLD) + NSSymbol sym = NSLookupSymbolInModule(handle, sp->name); + if (sym) + sp->value = (unsigned long int)(intptr_t)NSAddressOfSymbol(sym); + +#elif defined(HAVE_DL_DLOPEN) + /* dlsym() may fail for symbols not exported by object file; + * this can be safely ignored. */ sp->value = (unsigned long int)(intptr_t)dlsym (handle, sp->name); + +#endif + } + Call_Initializers (The_Symbols, 0, PR_CONSTRUCTOR); Call_Initializers (The_Symbols, 0, PR_EXTENSION); }