00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027 #include <a.out.h>
00028 #include <sys/file.h>
00029 #include <sys/types.h>
00030 #include <sys/stat.h>
00031
00032 #include "wind2unix.h"
00033 #include <errno.h>
00034 #include <stdio.h>
00035 #include <stdio.h>
00036
00037 #include "auxlry.h"
00038 #include "cell_xsb.h"
00039 #include "memory_xsb.h"
00040 #include "inst_xsb.h"
00041 #include "psc_xsb.h"
00042 #include "flags_xsb.h"
00043 #include "error_xsb.h"
00044 #include "io_builtins_xsb.h"
00045 #include "string_xsb.h"
00046 #include "extensions_xsb.h"
00047
00048 #define BUFFEXTRA 1024
00049
00050 char tfile[128];
00051
00052
00053
00054 xsbBool dummy()
00055 {
00056 xsb_error("Trying to use an undefined foreign procedure");
00057 return FALSE;
00058 }
00059
00060
00061
00062 static void dyn_link_all(char *symtab, Psc cur_mod)
00063 {
00064 int count, i;
00065 char *ptr, *strtab;
00066 struct nlist *sym_entry;
00067 char *name;
00068 Pair search_ptr;
00069
00070 count = *(int *)(symtab+4);
00071 symtab += 8;
00072 strtab = symtab + count*sizeof(struct nlist);
00073 search_ptr = (Pair)get_data(cur_mod);
00074 while (search_ptr) {
00075 name = get_name(search_ptr->psc_ptr);
00076
00077
00078
00079 if (get_type(search_ptr->psc_ptr) == T_FORN) {
00080 for (i=0; i<count; i++) {
00081 sym_entry = (struct nlist *)(symtab + i * sizeof(struct nlist));
00082 ptr = strtab + sym_entry->n_un.n_strx;
00083 if (*ptr++ == '_' && strcmp(name, ptr)==0) {
00084 set_forn(search_ptr->psc_ptr, (byte *)(sym_entry->n_value));
00085 break;
00086 }
00087 }
00088 if (i>= count) {
00089 xsb_warn("Cannot find foreign procedure %s", name);
00090 set_forn(search_ptr->psc_ptr, (byte *)(dummy));
00091 }
00092 }
00093 search_ptr = search_ptr->next;
00094 }
00095 }
00096
00097
00098
00099 static byte *load_obj_dyn(char *pofilename, Psc cur_mod, char *ld_option)
00100 {
00101 int buffsize, fd, loadsize;
00102 byte *start;
00103 int *loc;
00104 struct exec header;
00105 char buff[3*MAXPATHLEN], subfile[MAXPATHLEN];
00106 struct stat statbuff;
00107 char *file_extension_ptr;
00108
00109 sprintf(tfile, "/tmp/xsb-dyn.%d", (int)getpid());
00110
00111
00112
00113
00114 if (strlen(pofilename) >= 127) return 0;
00115
00116
00117 strcpy(subfile, pofilename);
00118 file_extension_ptr = xsb_strrstr(subfile, XSB_OBJ_EXTENSION_STRING);
00119
00120 strcpy(file_extension_ptr+1, "o");
00121
00122 fd = open(subfile, O_RDONLY, 0);
00123 if (fd < 0) {
00124 xsb_error("Cannot find the C object file: %s", subfile);
00125 return 0;
00126 }
00127 read(fd, &header, sizeof(struct exec));
00128 close(fd);
00129
00130
00131
00132
00133 buffsize = header.a_text + header.a_data + header.a_bss;
00134 start = mem_alloc(buffsize,FOR_CODE_SPACE);
00135
00136
00137 sprintf(buff, "/usr/bin/ld -N -A %s -T %x -o %s %s %s -lc",
00138 executable_path_gl, (int)start, tfile, subfile, ld_option);
00139 system(buff);
00140
00141
00142
00143
00144
00145 fd = open(tfile, O_RDONLY, 0);
00146 if (fd < 0) {
00147 xsb_error("The file is not generated by the loader");
00148 return 0;
00149 }
00150 read(fd, &header, sizeof(struct exec));
00151 loadsize = header.a_text + header.a_data + header.a_bss;
00152 if (loadsize > buffsize) {
00153 close(fd);
00154 mem_dealloc(start, buffsize,FOR_CODE_SPACE);
00155 start = mem_alloc(loadsize+BUFFEXTRA,FOR_CODE_SPACE);
00156 sprintf(buff, "/usr/bin/ld -N -A %s -T %x -o %s %s %s -lc",
00157 executable_path_gl, (int)start, tfile, subfile, ld_option);
00158 system(buff);
00159 fd = open(tfile, O_RDONLY, 0);
00160 read(fd, &header, sizeof(struct exec));
00161 }
00162
00163
00164
00165 loadsize = header.a_text + header.a_data;
00166 lseek(fd, N_TXTOFF(header), 0);
00167 read(fd, start, loadsize);
00168
00169 fstat(fd, &statbuff);
00170 loadsize = statbuff.st_size-N_SYMOFF(header);
00171 loc = (int *)mem_alloc(loadsize+8,FOR_CODE_SPACE);
00172 *loc = loadsize+8;
00173 *(loc+1) = header.a_syms/sizeof(struct nlist);
00174 lseek(fd, N_SYMOFF(header), 0);
00175 read(fd, loc+2, loadsize);
00176 close(fd);
00177
00178
00179 dyn_link_all((char *)loc, cur_mod);
00180 mem_dealloc((byte *)loc, loadsize+8,FOR_CODE_SPACE);
00181 return (byte *)4;
00182 }