* Implemented the dyld plugin loader for OS X.

git-svn-id: svn://svn.zoy.org/elk/trunk@125 55e467fa-43c5-0310-a8a2-de718669efc6
This commit is contained in:
sam 2003-09-07 22:07:33 +00:00
parent 9b0193fa91
commit 3d1b7d069f
2 changed files with 68 additions and 18 deletions

View File

@ -158,9 +158,10 @@ ac_cv_my_can_load_lib=no
AC_CHECK_HEADERS(mach-o/dyld.h, AC_CHECK_HEADERS(mach-o/dyld.h,
[AC_CHECK_FUNCS(NSLinkModule, [AC_CHECK_FUNCS(NSLinkModule,
[AC_DEFINE(HAVE_DL_DYLD, 1, [Define if you have the Darwin dyld API]) [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_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 # Only test for dlopen() if the others didn't work
if test "${ac_cv_my_can_load_lib}" = "no"; then if test "${ac_cv_my_can_load_lib}" = "no"; then
@ -185,13 +186,6 @@ AC_DEFINE(CACHECTL_H, <sys/cachectl.h>, [FIXME HARD])
# a call to _exit. # a call to _exit.
AC_CHECK_FUNCS(atexit) 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 # The symbol prefixes of extension initialization and finalization
# functions (without the initial $syms_begin_with). Do not change # functions (without the initial $syms_begin_with). Do not change
# these unless the compiler or linker restricts the length of symbols! # these unless the compiler or linker restricts the length of symbols!

View File

@ -32,36 +32,92 @@
#ifdef CAN_LOAD_LIB #ifdef CAN_LOAD_LIB
#include <dlfcn.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <unistd.h> #include <unistd.h>
#if defined(HAVE_DL_DYLD)
# include <mach-o/dyld.h>
#elif defined(HAVE_DL_DLOPEN)
# include <dlfcn.h>
#endif
#include "kernel.h" #include "kernel.h"
extern void Free_Symbols (SYMTAB *); extern void Free_Symbols (SYMTAB *);
extern void Call_Initializers (SYMTAB *, char *, int); extern void Call_Initializers (SYMTAB *, char *, int);
void Dlopen_File (char *fn) { void Dlopen_File (char *fn) {
void *handle;
SYM *sp; 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) if (Verb_Load)
printf ("[dlopen %s]\n", fn); 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 (); char *errstr = dlerror ();
Primitive_Error ("dlopen failed:~%~s", Primitive_Error ("dlopen failed: ~%~s",
Make_String (errstr, strlen (errstr))); Make_String (errstr, strlen (errstr)));
} }
#else
# error "No dynamic plugins API"
#endif
if (The_Symbols) if (The_Symbols)
Free_Symbols (The_Symbols); Free_Symbols (The_Symbols);
The_Symbols = Open_File_And_Snarf_Symbols (fn); The_Symbols = Open_File_And_Snarf_Symbols (fn);
/* for (sp = The_Symbols->first; sp; sp = sp->next) {
* dlsym() may fail for symbols not exported by object file; #if defined(HAVE_DL_DYLD)
* this can be safely ignored. NSSymbol sym = NSLookupSymbolInModule(handle, sp->name);
*/ if (sym)
for (sp = The_Symbols->first; sp; sp = sp->next) 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); 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_CONSTRUCTOR);
Call_Initializers (The_Symbols, 0, PR_EXTENSION); Call_Initializers (The_Symbols, 0, PR_EXTENSION);
} }