| 
									
										
										
										
											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_aout.c						 * | 
					
						
							|  |  |  | * comments:	aout based dynamic loader of external routines		 * | 
					
						
							|  |  |  | *									 * | 
					
						
							|  |  |  | *************************************************************************/ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include "Yap.h"
 | 
					
						
							|  |  |  | #include "yapio.h"
 | 
					
						
							|  |  |  | #include "Foreign.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #ifdef A_OUT
 | 
					
						
							| 
									
										
										
										
											2011-05-25 16:40:36 +01:00
										 |  |  | this code is no being maintained anymore | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  | #include <stdio.h>
 | 
					
						
							|  |  |  | #if STDC_HEADERS
 | 
					
						
							|  |  |  | #include <stdlib.h>
 | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | #if HAVE_UNISTD_H
 | 
					
						
							|  |  |  | #include <unistd.h>
 | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | #if HAVE_FCNTL_H
 | 
					
						
							|  |  |  | #include <fcntl.h>
 | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | #if HAVE_SYS_TYPES_H
 | 
					
						
							|  |  |  | #include <sys/types.h>
 | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | #if HAVE_SYS_FILE_H
 | 
					
						
							|  |  |  | #include <sys/file.h>
 | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | #if HAVE_SYS_PARAM_H
 | 
					
						
							|  |  |  | #include <sys/param.h>
 | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | #if HAVE_SYS_STAT_H
 | 
					
						
							|  |  |  | #include <sys/stat.h>
 | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | #include <a.out.h>
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-05-25 16:40:36 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2002-09-23 17:06:13 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  | #define oktox(n) \
 | 
					
						
							|  |  |  | 	(0==stat(n,&stbuf)&&(stbuf.st_mode&S_IFMT)==S_IFREG&&0==access(n,X_OK)) | 
					
						
							|  |  |  | #define oktow(n) \
 | 
					
						
							|  |  |  | 	(0==stat(n,&stbuf)&&(stbuf.st_mode&S_IFMT)==S_IFDIR&&0==access(n,W_OK)) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /*
 | 
					
						
							| 
									
										
										
										
											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 | 
					
						
							|  |  |  | */ | 
					
						
							| 
									
										
										
										
											2013-01-13 17:55:13 +00:00
										 |  |  | char * | 
					
						
							|  |  |  | Yap_FindExecutable(void) | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  | { | 
					
						
							|  |  |  |   register char  *cp, *cp2; | 
					
						
							|  |  |  |   struct stat     stbuf; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   cp = (char *)getenv("PATH"); | 
					
						
							|  |  |  |   if (cp == NULL) | 
					
						
							|  |  |  |     cp = ".:/usr/ucb:/bin:/usr/bin:/usr/local/bin"; | 
					
						
							| 
									
										
										
										
											2011-05-25 16:40:36 +01:00
										 |  |  |   if (*GLOBAL_argv[0] == '/') { | 
					
						
							|  |  |  |     if (oktox(GLOBAL_argv[0])) { | 
					
						
							|  |  |  |       strcpy(LOCAL_FileNameBuf, GLOBAL_argv[0]); | 
					
						
							| 
									
										
										
										
											2016-02-11 06:00:56 -08:00
										 |  |  |       Yap_AbsoluteFileInBuffer(LOCAL_FileNameBuf, true); | 
					
						
							|  |  |  |       strncpy( GLOBAL_Executable, LOCAL_FileNameBuf, YAP_MAXPATHLEN); | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |       return; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   if (*cp == ':') | 
					
						
							|  |  |  |     cp++; | 
					
						
							|  |  |  |   for (; *cp;) { | 
					
						
							|  |  |  |     /*
 | 
					
						
							|  |  |  |      * copy over current directory and then append | 
					
						
							|  |  |  |      * argv[0]  | 
					
						
							|  |  |  |      */ | 
					
						
							|  |  |  |        | 
					
						
							| 
									
										
										
										
											2011-05-23 16:19:47 +01:00
										 |  |  |     for (cp2 = LOCAL_FileNameBuf; (*cp) != 0 && (*cp) != ':';) | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |       *cp2++ = *cp++; | 
					
						
							|  |  |  |     *cp2++ = '/'; | 
					
						
							| 
									
										
										
										
											2011-05-25 16:40:36 +01:00
										 |  |  |     strcpy(cp2, GLOBAL_argv[0]); | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |     if (*cp) | 
					
						
							|  |  |  |       cp++; | 
					
						
							| 
									
										
										
										
											2011-05-23 16:19:47 +01:00
										 |  |  |     if (!oktox(LOCAL_FileNameBuf)) | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |       continue; | 
					
						
							| 
									
										
										
										
											2016-02-11 06:00:56 -08:00
										 |  |  |     Yap_AbsoluteFileInBuffer(Yap_AbsoluteFileInBuffer(LOCAL_FileNameBuf, GLOBAL_Executable, TRUE); | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |     return; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   /* one last try for dual systems */ | 
					
						
							| 
									
										
										
										
											2016-02-11 06:00:56 -08:00
										 |  |  |       strcpy(LOCAL_FileNameBuf, GLOBAL_argv[0]); | 
					
						
							|  |  |  |     Yap_AbsoluteFileInBuffer(Yap_AbsoluteFileInBuffer(LOCAL_FileNameBuf, GLOBAL_Executable, TRUE); | 
					
						
							| 
									
										
										
										
											2011-05-25 16:40:36 +01:00
										 |  |  |   if (oktox(GLOBAL_Executable)) | 
					
						
							| 
									
										
										
										
											2013-01-13 17:55:13 +00:00
										 |  |  |     return GLOBAL_Executable; | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |   else | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |     Yap_Error(SYSTEM_ERROR_INTERNAL,MkAtomTerm(Yap_LookupAtom(GLOBAL_Executable)), | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  | 	  "cannot find file being executed"); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-06-17 00:29:01 +01:00
										 |  |  | void * | 
					
						
							|  |  |  | Yap_LoadForeignFile(char *file, int flags) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   /* not implemented */ | 
					
						
							|  |  |  |   return NULL; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | int | 
					
						
							|  |  |  | Yap_CallForeignFile(void *handle, char *f) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   return FALSE; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | int | 
					
						
							|  |  |  | Yap_CloseForeignFile(void *handle) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   return -1; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											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) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   char		  command[2*MAXPATHLEN]; | 
					
						
							|  |  |  |   char            o_files[1024];    /* list of objects we want to load
 | 
					
						
							|  |  |  | 				       */ | 
					
						
							|  |  |  |   char            l_files[1024];    /* list of libraries we want to
 | 
					
						
							|  |  |  | 				       load */  | 
					
						
							|  |  |  |   char            tmp_buff[32] = "/tmp/YAP_TMP_XXXXXX";    /* used for
 | 
					
						
							|  |  |  | 							 mktemp */ | 
					
						
							|  |  |  |   char           *tfile;	    /* name of temporary file */ | 
					
						
							|  |  |  |   int             fildes;	    /* temp file descriptor */ | 
					
						
							|  |  |  |   struct exec     header;	    /* header for loaded file */ | 
					
						
							|  |  |  |   unsigned long   loadImageSize, firstloadImSz;  /* size of image we will load */ | 
					
						
							|  |  |  |   char           *FCodeBase;  /* where we load foreign code */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   /*
 | 
					
						
							|  |  |  |    * put in a string the names of the files you want to load and of any | 
					
						
							|  |  |  |    * libraries you want to use  | 
					
						
							|  |  |  |    */ | 
					
						
							|  |  |  |   /* files first */ | 
					
						
							|  |  |  |   *o_files = '\0'; | 
					
						
							|  |  |  |   { | 
					
						
							|  |  |  |     StringList tmp = ofiles; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     while(tmp != NULL) { | 
					
						
							|  |  |  |       strcat(o_files," "); | 
					
						
							| 
									
										
										
										
											2010-12-12 18:28:55 +00:00
										 |  |  |       strcat(o_files,AtomName(tmp->name)); | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |       tmp = tmp->next; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   /* same_trick for libraries */ | 
					
						
							|  |  |  |   *l_files = '\0'; | 
					
						
							|  |  |  |   { | 
					
						
							|  |  |  |     StringList tmp = libs; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     while(tmp != NULL) { | 
					
						
							|  |  |  |       strcat(l_files," "); | 
					
						
							| 
									
										
										
										
											2010-12-12 18:28:55 +00:00
										 |  |  |       strcat(l_files,AtomName(tmp->name)); | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |       tmp = tmp->next; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   /* next, create a temp file to serve as loader output */ | 
					
						
							|  |  |  |   tfile = mktemp(tmp_buff); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   /* prepare the magic */ | 
					
						
							|  |  |  |   if (strlen(o_files) + strlen(l_files) + strlen(proc_name) + | 
					
						
							| 
									
										
										
										
											2011-05-25 16:40:36 +01:00
										 |  |  | 	    strlen(GLOBAL_Executable) > 2*MAXPATHLEN) { | 
					
						
							| 
									
										
										
										
											2011-05-23 16:19:47 +01:00
										 |  |  |     strcpy(LOCAL_ErrorSay, " too many parameters in load_foreign/3 "); | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |     return LOAD_FAILLED; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   sprintf(command, "/usr/bin/ld -N -A %s -o %s -u _%s %s %s -lc", | 
					
						
							| 
									
										
										
										
											2011-05-25 16:40:36 +01:00
										 |  |  | 	  GLOBAL_Executable, | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  | 	  tfile, proc_name, o_files, l_files); | 
					
						
							|  |  |  |   /* now, do the magic */ | 
					
						
							|  |  |  |   if (system(command) != 0) { | 
					
						
							|  |  |  |     unlink(tfile); | 
					
						
							| 
									
										
										
										
											2011-05-23 16:19:47 +01:00
										 |  |  |     strcpy(LOCAL_ErrorSay," ld returned error status in load_foreign_files "); | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |     return LOAD_FAILLED; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   /* now check the music has played */ | 
					
						
							|  |  |  |   if ((fildes = open(tfile, O_RDONLY)) < 0) { | 
					
						
							| 
									
										
										
										
											2011-05-23 16:19:47 +01:00
										 |  |  |     strcpy(LOCAL_ErrorSay," unable to open temp file in load_foreign_files "); | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |     return LOAD_FAILLED; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   /* it did, get the mice */ | 
					
						
							|  |  |  |   /* first, get the header */ | 
					
						
							|  |  |  |   read(fildes, (char *) &header, sizeof(header)); | 
					
						
							|  |  |  |   close(fildes); | 
					
						
							|  |  |  |   /* get the full size of what we need to load */ | 
					
						
							|  |  |  |   loadImageSize = header.a_text + header.a_data + header.a_bss; | 
					
						
							|  |  |  |   /* add 16 just to play it safe */ | 
					
						
							|  |  |  |   loadImageSize += 16; | 
					
						
							|  |  |  |   /* keep this copy */ | 
					
						
							|  |  |  |   firstloadImSz = loadImageSize; | 
					
						
							|  |  |  |   /* now fetch the space we need */ | 
					
						
							| 
									
										
										
										
											2002-11-18 18:18:05 +00:00
										 |  |  |   if (!(FCodeBase = Yap_AllocCodeSpace((int) loadImageSize))) { | 
					
						
							| 
									
										
										
										
											2011-05-23 16:19:47 +01:00
										 |  |  |     strcpy(LOCAL_ErrorSay," unable to allocate space for external code "); | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |     return LOAD_FAILLED; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   /* now, a new incantation to load the new foreign code */ | 
					
						
							|  |  |  |   sprintf(command, "/usr/bin/ld -N -A %s -T %lx -o %s -u _%s %s %s -lc", | 
					
						
							| 
									
										
										
										
											2011-05-25 16:40:36 +01:00
										 |  |  | 	  GLOBAL_Executable, | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  | 	  (unsigned long) FCodeBase, | 
					
						
							|  |  |  | 	  tfile, proc_name, o_files, l_files); | 
					
						
							|  |  |  |   /* and do it */  | 
					
						
							|  |  |  |   if (system(command) != 0) { | 
					
						
							|  |  |  |     unlink(tfile); | 
					
						
							| 
									
										
										
										
											2011-05-23 16:19:47 +01:00
										 |  |  |     strcpy(LOCAL_ErrorSay," ld returned error status in load_foreign_files "); | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |     return LOAD_FAILLED; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   if ((fildes = open(tfile, O_RDONLY)) < 0) { | 
					
						
							| 
									
										
										
										
											2011-05-23 16:19:47 +01:00
										 |  |  |     strcpy(LOCAL_ErrorSay," unable to open temp file in load_foreign_files "); | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |     return LOAD_FAILLED; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   read(fildes, (char *) &header, sizeof(header)); | 
					
						
							|  |  |  |   loadImageSize = header.a_text + header.a_data + header.a_bss; | 
					
						
							|  |  |  |   if (firstloadImSz < loadImageSize) { | 
					
						
							| 
									
										
										
										
											2011-05-23 16:19:47 +01:00
										 |  |  |     strcpy(LOCAL_ErrorSay," miscalculation in load_foreign/3 "); | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |     return LOAD_FAILLED; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   /* now search for our init function */ | 
					
						
							|  |  |  |   { | 
					
						
							|  |  |  |     char entry_fun[256]; | 
					
						
							|  |  |  |     struct nlist    func_info[2]; | 
					
						
							|  |  |  |     sprintf(entry_fun, "_%s", proc_name); | 
					
						
							|  |  |  |     func_info[0].n_un.n_name = entry_fun; | 
					
						
							|  |  |  |     func_info[1].n_un.n_name = NULL; | 
					
						
							|  |  |  |     if (nlist(tfile, func_info) == -1) { | 
					
						
							| 
									
										
										
										
											2011-05-23 16:19:47 +01:00
										 |  |  |       strcpy(LOCAL_ErrorSay," in nlist(3) "); | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |       return LOAD_FAILLED; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     if (func_info[0].n_type == 0) { | 
					
						
							| 
									
										
										
										
											2011-05-23 16:19:47 +01:00
										 |  |  |       strcpy(LOCAL_ErrorSay," in nlist(3) "); | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |       return LOAD_FAILLED; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     *init_proc = (YapInitProc)(func_info[0].n_value); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   /* ok, we got our init point */ | 
					
						
							|  |  |  |   /* now read our text */ | 
					
						
							|  |  |  |   lseek(fildes, (long)(N_TXTOFF(header)), 0); | 
					
						
							|  |  |  |   { | 
					
						
							|  |  |  |     unsigned int u1 = header.a_text + header.a_data; | 
					
						
							|  |  |  |     read(fildes, (char *) FCodeBase, u1); | 
					
						
							|  |  |  |     /* zero the BSS segment */ | 
					
						
							|  |  |  |     while (u1 < loadImageSize) | 
					
						
							|  |  |  |       FCodeBase[u1++] = 0; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   close(fildes); | 
					
						
							|  |  |  |   unlink(tfile); | 
					
						
							|  |  |  |   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
										 |  |  | { | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 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
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 |