| 
									
										
										
										
											2002-09-24 14:20:56 +00:00
										 |  |  | /*************************************************************************
 | 
					
						
							|  |  |  | *									 * | 
					
						
							|  |  |  | *	 YAP Prolog 							 * | 
					
						
							|  |  |  | *									 * | 
					
						
							|  |  |  | *	Yap Prolog was developed at NCCUP - Universidade do Porto	 * | 
					
						
							|  |  |  | *									 * | 
					
						
							|  |  |  | * Copyright L.Damas, V.S.Costa and Universidade do Porto 1985-1997	 * | 
					
						
							|  |  |  | *									 * | 
					
						
							|  |  |  | ************************************************************************** | 
					
						
							|  |  |  | *									 * | 
					
						
							| 
									
										
										
										
											2002-09-24 15:38:17 +00:00
										 |  |  | * File:		load_dyld.c						 * | 
					
						
							|  |  |  | * comments:	dyld based dynamic loaderr of external routines		 * | 
					
						
							|  |  |  | *               tested on MacOS						 * | 
					
						
							| 
									
										
										
										
											2002-09-24 14:20:56 +00:00
										 |  |  | *************************************************************************/ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include "Yap.h"
 | 
					
						
							|  |  |  | #include "Yatom.h"
 | 
					
						
							|  |  |  | #include "Heap.h"
 | 
					
						
							|  |  |  | #include "yapio.h"
 | 
					
						
							|  |  |  | #include "Foreign.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2002-09-24 15:38:17 +00:00
										 |  |  | #if LOAD_DYLD
 | 
					
						
							| 
									
										
										
										
											2002-09-24 14:20:56 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | #include <string.h>
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2002-09-24 15:38:17 +00:00
										 |  |  | /* Code originally  from Rex A. Dieter's posting in comp.sys.next.programmer
 | 
					
						
							|  |  |  |    and from dynload_next.c in the Python sources  | 
					
						
							|  |  |  | */ | 
					
						
							| 
									
										
										
										
											2002-09-24 14:20:56 +00:00
										 |  |  | #import <mach-o/dyld.h>
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2002-09-24 15:38:17 +00:00
										 |  |  | static int dl_errno; | 
					
						
							| 
									
										
										
										
											2002-09-24 14:20:56 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | static char * | 
					
						
							| 
									
										
										
										
											2002-09-24 15:38:17 +00:00
										 |  |  | mydlerror(void) | 
					
						
							| 
									
										
										
										
											2002-09-24 14:20:56 +00:00
										 |  |  | { | 
					
						
							|  |  |  |   char *errString; | 
					
						
							|  |  |  |   switch(dl_errno) { | 
					
						
							|  |  |  |   default: | 
					
						
							|  |  |  |   case NSObjectFileImageFailure: | 
					
						
							|  |  |  |   case NSObjectFileImageFormat: | 
					
						
							|  |  |  |     /* for these a message is printed on stderr by dyld */ | 
					
						
							|  |  |  |     errString = "Can't create object file image"; | 
					
						
							|  |  |  |     break; | 
					
						
							|  |  |  |   case NSObjectFileImageSuccess: | 
					
						
							|  |  |  |     errString = NULL; | 
					
						
							|  |  |  |     break; | 
					
						
							|  |  |  |   case NSObjectFileImageInappropriateFile: | 
					
						
							|  |  |  |     errString = "Inappropriate file type for dynamic loading"; | 
					
						
							|  |  |  |     break; | 
					
						
							|  |  |  |   case NSObjectFileImageArch: | 
					
						
							|  |  |  |     errString = "Wrong CPU type in object file"; | 
					
						
							|  |  |  |     break; | 
					
						
							|  |  |  |   case NSObjectFileImageAccess: | 
					
						
							|  |  |  |     errString = "Can't read object file (no access)"; | 
					
						
							|  |  |  |     break; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   return(errString); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2002-09-24 15:38:17 +00:00
										 |  |  | /*
 | 
					
						
							|  |  |  |  *   YAP_FindExecutable(argv[0]) should be called on yap initialization to | 
					
						
							|  |  |  |  *   locate the executable of Yap | 
					
						
							|  |  |  | */ | 
					
						
							|  |  |  | void | 
					
						
							| 
									
										
										
										
											2002-11-18 18:18:05 +00:00
										 |  |  | Yap_FindExecutable(char *name) | 
					
						
							| 
									
										
										
										
											2002-09-24 15:38:17 +00:00
										 |  |  | { | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2002-09-24 14:20:56 +00:00
										 |  |  | static void * | 
					
						
							|  |  |  | mydlopen(char *path) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     int dyld_result; | 
					
						
							|  |  |  |     NSObjectFileImage ofile; | 
					
						
							|  |  |  |     NSModule handle = NULL; | 
					
						
							|  |  |  |     dyld_result = NSCreateObjectFileImageFromFile(path, &ofile); | 
					
						
							|  |  |  |     if (dyld_result != NSObjectFileImageSuccess) { | 
					
						
							|  |  |  |       dl_errno = dyld_result; | 
					
						
							|  |  |  |     } else { | 
					
						
							|  |  |  |       /* NSLinkModule will cause the run to abort on any link error's */ | 
					
						
							|  |  |  |       /* not very friendly but the error recovery functionality is limited */ | 
					
						
							|  |  |  |         handle = NSLinkModule(ofile, path, TRUE); | 
					
						
							|  |  |  |     } return handle; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static void * | 
					
						
							|  |  |  | mydlsym(char *symbol) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     void *addr; | 
					
						
							| 
									
										
										
										
											2002-09-24 15:38:17 +00:00
										 |  |  |     char funcname[256]; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #if HAVE_SNPRINTF
 | 
					
						
							| 
									
										
										
										
											2002-09-27 20:04:49 +00:00
										 |  |  |     snprintf(funcname, sizeof(funcname), "_%.200s", symbol); | 
					
						
							| 
									
										
										
										
											2002-09-24 15:38:17 +00:00
										 |  |  | #else
 | 
					
						
							|  |  |  |     sprintf(funcname, "_%.200s", symbol); | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  |     if (NSIsSymbolNameDefined(funcname)) | 
					
						
							|  |  |  |         addr = NSAddressOfSymbol(NSLookupAndBindSymbol(funcname)); | 
					
						
							| 
									
										
										
										
											2002-09-24 14:20:56 +00:00
										 |  |  |     else | 
					
						
							|  |  |  |         addr = NULL; | 
					
						
							|  |  |  |     return addr; | 
					
						
							|  |  |  | }  | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2002-09-24 15:38:17 +00:00
										 |  |  | static int | 
					
						
							| 
									
										
										
										
											2002-09-24 14:20:56 +00:00
										 |  |  | mydlclose(void *handle) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   NSUnLinkModule(handle, NSUNLINKMODULE_OPTION_NONE); | 
					
						
							| 
									
										
										
										
											2002-09-24 15:38:17 +00:00
										 |  |  |   return TRUE; | 
					
						
							| 
									
										
										
										
											2002-09-24 14:20:56 +00:00
										 |  |  | }  | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /*
 | 
					
						
							|  |  |  |  * LoadForeign(ofiles,libs,proc_name,init_proc) dynamically loads foreign | 
					
						
							|  |  |  |  * code files and libraries and locates an initialization routine | 
					
						
							|  |  |  | */ | 
					
						
							| 
									
										
										
										
											2002-11-11 17:38:10 +00:00
										 |  |  | static Int | 
					
						
							| 
									
										
										
										
											2002-09-24 14:20:56 +00:00
										 |  |  | LoadForeign(StringList ofiles, StringList libs, | 
					
						
							|  |  |  | 	       char *proc_name,	YapInitProc *init_proc) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   while (ofiles) { | 
					
						
							|  |  |  |     void *handle; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /* mydlopen wants to follow the LD_CONFIG_PATH */ | 
					
						
							| 
									
										
										
										
											2002-11-18 18:18:05 +00:00
										 |  |  |     if (!Yap_TrueFileName(ofiles->s, Yap_FileNameBuf, TRUE)) { | 
					
						
							| 
									
										
										
										
											2004-06-23 17:24:20 +00:00
										 |  |  |       strcpy(Yap_ErrorSay, "%% Trying to open unexisting file in LoadForeign"); | 
					
						
							| 
									
										
										
										
											2002-09-24 14:20:56 +00:00
										 |  |  |       return LOAD_FAILLED; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2002-11-18 18:18:05 +00:00
										 |  |  |     if((handle=mydlopen(Yap_FileNameBuf)) == 0) | 
					
						
							| 
									
										
										
										
											2002-09-24 14:20:56 +00:00
										 |  |  |     { | 
					
						
							|  |  |  |       fprintf(stderr,"calling dlopen with error %s\n", mydlerror()); | 
					
						
							| 
									
										
										
										
											2002-11-18 18:18:05 +00:00
										 |  |  | /*      strcpy(Yap_ErrorSay,dlerror());*/ | 
					
						
							| 
									
										
										
										
											2002-09-24 14:20:56 +00:00
										 |  |  |       return LOAD_FAILLED; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     ofiles->handle = handle; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     ofiles = ofiles->next; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   /* load libraries first so that their symbols are available to
 | 
					
						
							|  |  |  |      other routines */ | 
					
						
							|  |  |  |   while (libs) { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (libs->s[0] == '-') { | 
					
						
							| 
									
										
										
										
											2002-11-18 18:18:05 +00:00
										 |  |  |       strcpy(Yap_FileNameBuf,"lib"); | 
					
						
							|  |  |  |       strcat(Yap_FileNameBuf,libs->s+2); | 
					
						
							|  |  |  |       strcat(Yap_FileNameBuf,".so"); | 
					
						
							| 
									
										
										
										
											2002-09-24 14:20:56 +00:00
										 |  |  |     } else { | 
					
						
							| 
									
										
										
										
											2002-11-18 18:18:05 +00:00
										 |  |  |       strcpy(Yap_FileNameBuf,libs->s); | 
					
						
							| 
									
										
										
										
											2002-09-24 14:20:56 +00:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2002-11-18 18:18:05 +00:00
										 |  |  |     if((libs->handle=mydlopen(Yap_FileNameBuf)) == NULL) | 
					
						
							| 
									
										
										
										
											2002-09-24 14:20:56 +00:00
										 |  |  |     { | 
					
						
							| 
									
										
										
										
											2002-11-18 18:18:05 +00:00
										 |  |  |       strcpy(Yap_ErrorSay,mydlerror()); | 
					
						
							| 
									
										
										
										
											2002-09-24 14:20:56 +00:00
										 |  |  |       return LOAD_FAILLED; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     libs = libs->next; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   *init_proc = (YapInitProc) mydlsym(proc_name); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if(! *init_proc) { | 
					
						
							| 
									
										
										
										
											2002-11-18 18:18:05 +00:00
										 |  |  |     strcpy(Yap_ErrorSay,"Could not locate initialization routine"); | 
					
						
							| 
									
										
										
										
											2002-09-24 14:20:56 +00:00
										 |  |  |     return LOAD_FAILLED; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   return LOAD_SUCCEEDED; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2002-11-11 17:38:10 +00:00
										 |  |  | Int | 
					
						
							| 
									
										
										
										
											2002-11-18 18:18:05 +00:00
										 |  |  | Yap_LoadForeign(StringList ofiles, StringList libs, | 
					
						
							| 
									
										
										
										
											2002-11-11 17:38:10 +00:00
										 |  |  | 	       char *proc_name,	YapInitProc *init_proc) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   return LoadForeign(ofiles, libs, proc_name, init_proc); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2002-09-24 14:20:56 +00:00
										 |  |  | void  | 
					
						
							| 
									
										
										
										
											2002-11-18 18:18:05 +00:00
										 |  |  | Yap_ShutdownLoadForeign(void) | 
					
						
							| 
									
										
										
										
											2002-09-24 14:20:56 +00:00
										 |  |  | { | 
					
						
							|  |  |  |   ForeignObj *f_code; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   f_code = ForeignCodeLoaded; | 
					
						
							|  |  |  |   while (f_code != NULL) { | 
					
						
							|  |  |  |     StringList objs, libs; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     objs = f_code->objs; | 
					
						
							|  |  |  |     while (objs != NULL) { | 
					
						
							|  |  |  |       if (mydlclose(objs->handle) != 0) | 
					
						
							|  |  |  | 	return; /* ERROR */ | 
					
						
							|  |  |  |       objs = objs->next; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     libs = f_code->libs; | 
					
						
							|  |  |  |     while (libs != NULL) { | 
					
						
							|  |  |  |       if (mydlclose(libs->handle) != 0) | 
					
						
							|  |  |  | 	return; /* ERROR */ | 
					
						
							|  |  |  |       objs = libs->next; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     f_code = f_code->next; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Int | 
					
						
							| 
									
										
										
										
											2002-11-18 18:18:05 +00:00
										 |  |  | Yap_ReLoadForeign(StringList ofiles, StringList libs, | 
					
						
							| 
									
										
										
										
											2002-09-24 14:20:56 +00:00
										 |  |  | 	       char *proc_name,	YapInitProc *init_proc) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   return(LoadForeign(ofiles,libs, proc_name, init_proc)); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #endif
 |