* 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:
		
							parent
							
								
									9b0193fa91
								
							
						
					
					
						commit
						3d1b7d069f
					
				
							
								
								
									
										10
									
								
								configure.ac
								
								
								
								
							
							
						
						
									
										10
									
								
								configure.ac
								
								
								
								
							| 
						 | 
					@ -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!
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -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);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in New Issue