| 
									
										
										
										
											2001-04-09 19:54:03 +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	 * | 
					
						
							|  |  |  | *									 * | 
					
						
							|  |  |  | ************************************************************************** | 
					
						
							|  |  |  | *									 * | 
					
						
							|  |  |  | * File:		load_dl.c						 * | 
					
						
							|  |  |  | * comments:	dl based dynamic loaderr of external routines		 * | 
					
						
							|  |  |  | *               tested on i486-linuxelf					 * | 
					
						
							|  |  |  | *************************************************************************/ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include "Yap.h"
 | 
					
						
							|  |  |  | #include "Yatom.h"
 | 
					
						
							| 
									
										
										
										
											2009-10-23 14:22:17 +01:00
										 |  |  | #include "YapHeap.h"
 | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  | #include "yapio.h"
 | 
					
						
							|  |  |  | #include "Foreign.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #if LOAD_DL
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include <dlfcn.h>
 | 
					
						
							|  |  |  | #include <string.h>
 | 
					
						
							|  |  |  | #include <stdio.h>
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-11-03 07:51:34 +09:00
										 |  |  | typedef void (*prismf)(void); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* only works for dlls */ | 
					
						
							|  |  |  | int | 
					
						
							|  |  |  | Yap_CallFunctionByName(const char *thing_string); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | int | 
					
						
							|  |  |  | Yap_CallFunctionByName(const char *thing_string) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2012-04-18 14:14:56 -05:00
										 |  |  |   void * handle = dlopen(NULL, RTLD_LAZY | 
					
						
							|  |  |  | #ifndef __CYGWIN__
 | 
					
						
							| 
									
										
										
										
											2012-09-07 07:40:18 +02:00
										 |  |  | #ifdef RTLD_NOLOAD
 | 
					
						
							| 
									
										
										
										
											2012-04-18 14:14:56 -05:00
										 |  |  | 			 | RTLD_NOLOAD | 
					
						
							| 
									
										
										
										
											2012-09-07 07:40:18 +02:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2012-04-18 14:14:56 -05:00
										 |  |  | #endif
 | 
					
						
							|  |  |  | 			 ); | 
					
						
							| 
									
										
										
										
											2011-11-03 07:51:34 +09:00
										 |  |  |   // you could do RTLD_NOW as well.  shouldn't matter
 | 
					
						
							|  |  |  |   if (!handle) { | 
					
						
							|  |  |  |     CACHE_REGS | 
					
						
							|  |  |  |     Yap_Error(SYSTEM_ERROR, ARG1, "Dynamic linking on main module : %s\n", dlerror()); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   prismf * addr = (prismf *)dlsym(handle, thing_string); | 
					
						
							|  |  |  |   if (addr) | 
					
						
							|  |  |  |     (*addr)(); | 
					
						
							| 
									
										
										
										
											2012-09-07 07:40:18 +02:00
										 |  |  |   dlclose(handle); | 
					
						
							| 
									
										
										
										
											2011-11-03 07:51:34 +09:00
										 |  |  |   return TRUE; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  | /*
 | 
					
						
							| 
									
										
										
										
											2002-09-23 17:06:13 +00:00
										 |  |  |  *   YAP_FindExecutable(argv[0]) should be called on yap initialization to | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |  *   locate the executable of Yap | 
					
						
							|  |  |  | */ | 
					
						
							|  |  |  | void | 
					
						
							| 
									
										
										
										
											2002-11-18 18:18:05 +00:00
										 |  |  | Yap_FindExecutable(char *name) | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  | { | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-06-17 00:29:01 +01:00
										 |  |  | void * | 
					
						
							|  |  |  | Yap_LoadForeignFile(char *file, int flags) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   int dlflag; | 
					
						
							| 
									
										
										
										
											2010-06-18 10:30:23 +01:00
										 |  |  |   void *out; | 
					
						
							| 
									
										
										
										
											2010-06-17 00:29:01 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |   if (flags &  EAGER_LOADING) | 
					
						
							|  |  |  |     dlflag = RTLD_NOW; | 
					
						
							|  |  |  |   else | 
					
						
							|  |  |  |     dlflag = RTLD_LAZY; | 
					
						
							|  |  |  |   if (flags &  GLOBAL_LOADING) | 
					
						
							|  |  |  |     dlflag |= RTLD_GLOBAL; | 
					
						
							| 
									
										
										
										
											2010-08-03 01:11:13 +01:00
										 |  |  | #ifndef __CYGWIN__
 | 
					
						
							| 
									
										
										
										
											2010-06-17 00:29:01 +01:00
										 |  |  |   else  | 
					
						
							|  |  |  |     dlflag |= RTLD_LOCAL; | 
					
						
							| 
									
										
										
										
											2010-08-03 01:11:13 +01:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2010-06-17 00:29:01 +01:00
										 |  |  |    | 
					
						
							| 
									
										
										
										
											2010-06-18 10:30:23 +01:00
										 |  |  |   out = (void *)dlopen(file,dlflag); | 
					
						
							|  |  |  |   if (!out) { | 
					
						
							| 
									
										
										
										
											2011-03-07 16:02:55 +00:00
										 |  |  |     CACHE_REGS | 
					
						
							| 
									
										
										
										
											2012-01-09 23:26:57 +00:00
										 |  |  |     Yap_Error(SYSTEM_ERROR, ARG1, "dlopen error for %s: %s\n", file, dlerror()); | 
					
						
							| 
									
										
										
										
											2010-06-18 10:30:23 +01:00
										 |  |  |   } | 
					
						
							|  |  |  |   return out; | 
					
						
							| 
									
										
										
										
											2010-06-17 00:29:01 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | int | 
					
						
							|  |  |  | Yap_CallForeignFile(void *handle, char *f) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   YapInitProc proc = (YapInitProc) dlsym(handle, f); | 
					
						
							| 
									
										
										
										
											2010-06-18 10:30:23 +01:00
										 |  |  |   if (!proc) { | 
					
						
							| 
									
										
										
										
											2010-06-23 11:46:16 +01:00
										 |  |  |     /* Yap_Error(SYSTEM_ERROR, ARG1, "dlsym error %s\n", dlerror());*/ | 
					
						
							| 
									
										
										
										
											2010-06-17 00:29:01 +01:00
										 |  |  |     return FALSE; | 
					
						
							| 
									
										
										
										
											2010-06-18 10:30:23 +01:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2010-06-17 00:29:01 +01:00
										 |  |  |   (*proc) (); | 
					
						
							|  |  |  |   return TRUE; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | int | 
					
						
							|  |  |  | Yap_CloseForeignFile(void *handle) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2010-06-18 10:30:23 +01:00
										 |  |  |   if ( dlclose(handle) < 0) { | 
					
						
							| 
									
										
										
										
											2011-03-07 16:02:55 +00:00
										 |  |  |     CACHE_REGS | 
					
						
							| 
									
										
										
										
											2010-06-18 10:30:23 +01:00
										 |  |  |     Yap_Error(SYSTEM_ERROR, ARG1, "dlclose error %s\n", dlerror()); | 
					
						
							|  |  |  |     return -1; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   return 0; | 
					
						
							| 
									
										
										
										
											2010-06-17 00:29:01 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +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 | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  | LoadForeign(StringList ofiles, StringList libs, | 
					
						
							|  |  |  | 	       char *proc_name,	YapInitProc *init_proc) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2011-03-07 16:02:55 +00:00
										 |  |  |   CACHE_REGS | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-05-24 19:54:45 +00:00
										 |  |  |   while (libs) { | 
					
						
							| 
									
										
										
										
											2011-05-23 16:19:47 +01:00
										 |  |  |     if (!Yap_TrueFileName(AtomName(libs->name), LOCAL_FileNameBuf, TRUE)) { | 
					
						
							| 
									
										
										
										
											2007-05-24 19:54:45 +00:00
										 |  |  |       /* use LD_LIBRARY_PATH */ | 
					
						
							| 
									
										
										
										
											2011-05-23 16:19:47 +01:00
										 |  |  |       strncpy(LOCAL_FileNameBuf, AtomName(libs->name), YAP_FILENAME_MAX); | 
					
						
							| 
									
										
										
										
											2007-05-24 19:54:45 +00:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #ifdef __osf__
 | 
					
						
							| 
									
										
										
										
											2011-05-23 16:19:47 +01:00
										 |  |  |     if((libs->handle=dlopen(LOCAL_FileNameBuf,RTLD_LAZY)) == NULL) | 
					
						
							| 
									
										
										
										
											2007-05-24 19:54:45 +00:00
										 |  |  | #else
 | 
					
						
							| 
									
										
										
										
											2011-05-23 16:19:47 +01:00
										 |  |  |     if((libs->handle=dlopen(LOCAL_FileNameBuf,RTLD_LAZY|RTLD_GLOBAL)) == NULL) | 
					
						
							| 
									
										
										
										
											2007-05-24 19:54:45 +00:00
										 |  |  | #endif
 | 
					
						
							|  |  |  |     { | 
					
						
							| 
									
										
										
										
											2011-05-23 16:19:47 +01:00
										 |  |  |       strcpy(LOCAL_ErrorSay,dlerror()); | 
					
						
							| 
									
										
										
										
											2007-05-24 19:54:45 +00:00
										 |  |  |       return LOAD_FAILLED; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     libs = libs->next; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |   while (ofiles) { | 
					
						
							|  |  |  |     void *handle; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-05-24 19:54:45 +00:00
										 |  |  |   /* load libraries first so that their symbols are available to
 | 
					
						
							|  |  |  |      other routines */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |     /* dlopen wants to follow the LD_CONFIG_PATH */ | 
					
						
							| 
									
										
										
										
											2011-05-23 16:19:47 +01:00
										 |  |  |     if (!Yap_TrueFileName(AtomName(ofiles->name), LOCAL_FileNameBuf, TRUE)) { | 
					
						
							|  |  |  |       strcpy(LOCAL_ErrorSay, "%% Trying to open unexisting file in LoadForeign"); | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |       return LOAD_FAILLED; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | #ifdef __osf__
 | 
					
						
							| 
									
										
										
										
											2011-05-23 16:19:47 +01:00
										 |  |  |     if((handle=dlopen(LOCAL_FileNameBuf,RTLD_LAZY)) == 0) | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  | #else
 | 
					
						
							| 
									
										
										
										
											2011-05-23 16:19:47 +01:00
										 |  |  |     if((handle=dlopen(LOCAL_FileNameBuf,RTLD_LAZY|RTLD_GLOBAL)) == 0) | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  | #endif
 | 
					
						
							|  |  |  |     { | 
					
						
							| 
									
										
										
										
											2011-05-23 16:19:47 +01:00
										 |  |  |       fprintf(stderr,"dlopen of %s failed with error %s\n", LOCAL_FileNameBuf, dlerror()); | 
					
						
							|  |  |  | /*      strcpy(LOCAL_ErrorSay,dlerror());*/ | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |       return LOAD_FAILLED; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     ofiles->handle = handle; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-11-22 21:47:17 +00:00
										 |  |  |     if (proc_name && !*init_proc) | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |       *init_proc = (YapInitProc) dlsym(handle,proc_name); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     ofiles = ofiles->next; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if(! *init_proc) { | 
					
						
							| 
									
										
										
										
											2011-05-23 16:19:47 +01:00
										 |  |  |     strcpy(LOCAL_ErrorSay,"Could not locate initialization routine"); | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +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); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  | void  | 
					
						
							| 
									
										
										
										
											2002-11-18 18:18:05 +00:00
										 |  |  | Yap_ShutdownLoadForeign(void) | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  | { | 
					
						
							|  |  |  |   ForeignObj *f_code; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   f_code = ForeignCodeLoaded; | 
					
						
							|  |  |  |   while (f_code != NULL) { | 
					
						
							|  |  |  |     StringList objs, libs; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     objs = f_code->objs; | 
					
						
							|  |  |  |     while (objs != NULL) { | 
					
						
							|  |  |  |       if (dlclose(objs->handle) != 0) | 
					
						
							| 
									
										
										
										
											2011-09-04 19:24:53 +02:00
										 |  |  |       	return; /* ERROR */ | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |       objs = objs->next; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     libs = f_code->libs; | 
					
						
							|  |  |  |     while (libs != NULL) { | 
					
						
							|  |  |  |       if (dlclose(libs->handle) != 0) | 
					
						
							|  |  |  | 	return; /* ERROR */ | 
					
						
							|  |  |  |       objs = libs->next; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     f_code = f_code->next; | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2003-02-07 12:05:39 +00:00
										 |  |  |   /*
 | 
					
						
							|  |  |  |     make sure that we don't try to close foreign code several times, eg, | 
					
						
							|  |  |  |     from within an error handler | 
					
						
							|  |  |  |   */ | 
					
						
							|  |  |  |   ForeignCodeLoaded = NULL; | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Int | 
					
						
							| 
									
										
										
										
											2002-11-18 18:18:05 +00:00
										 |  |  | Yap_ReLoadForeign(StringList ofiles, StringList libs, | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  | 	       char *proc_name,	YapInitProc *init_proc) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   return(LoadForeign(ofiles,libs, proc_name, init_proc)); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #if SIMICS
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void dlopen(void) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void dlclose(void) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void dlsym(void) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 |