dynaout_xsb_i.h

00001 /* File:      dynaout_xsb_i.h
00002 ** Author(s): Jiyang Xu, Kostis Sagonas, Steve Dawson
00003 ** Contact:   xsb-contact@cs.sunysb.edu
00004 ** 
00005 ** Copyright (C) The Research Foundation of SUNY, 1986, 1993-1998
00006 ** Copyright (C) ECRC, Germany, 1990
00007 ** 
00008 ** XSB is free software; you can redistribute it and/or modify it under the
00009 ** terms of the GNU Library General Public License as published by the Free
00010 ** Software Foundation; either version 2 of the License, or (at your option)
00011 ** any later version.
00012 ** 
00013 ** XSB is distributed in the hope that it will be useful, but WITHOUT ANY
00014 ** WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
00015 ** FOR A PARTICULAR PURPOSE.  See the GNU Library General Public License for
00016 ** more details.
00017 ** 
00018 ** You should have received a copy of the GNU Library General Public License
00019 ** along with XSB; if not, write to the Free Software Foundation,
00020 ** Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
00021 **
00022 ** $Id: dynaout_xsb_i.h,v 1.12 2005/11/29 00:02:16 tswift Exp $
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 /* wind2unix.h must be included after sys/stat.h */
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];        /* uniquely-named tmp file for "ld" */
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 /* Jiyang changed it to the form ``module_pred'':
00077     sprintf(name, "%s_%s", get_name(cur_mod), get_name(search_ptr->psc_ptr));
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) {          /* does not find the name */
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;  /* Changed from int -- Kostis.  */
00103   int *loc;     /* Changed from int -- Kostis.  */
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   /* first step: get the header entries of the *.o file, in order       */
00112   /* to obtain the size of the object code and then allocate space      */
00113   /* for it.                                                    */
00114   if (strlen(pofilename) >= 127) return 0;
00115 
00116   /* create filename.o */
00117   strcpy(subfile, pofilename);
00118   file_extension_ptr = xsb_strrstr(subfile, XSB_OBJ_EXTENSION_STRING);
00119   /* replace the OBJ file suffix with the "o" suffix */
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   /* second step: run incremental ld and generate a temporary   */
00131   /* object file (including orginal *.o and libraries) ready to be      */
00132   /* read in.                                                   */
00133   buffsize = header.a_text + header.a_data + header.a_bss;
00134   start = mem_alloc(buffsize,FOR_CODE_SPACE);
00135   /* The "-T hex" option of ld starts the text segment at location      */
00136   /* hex. Specifying -T is the same as using the -Ttext option. */
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   /* third step: check if the size of the buffer just allocated is      */
00142   /* big enough to load the object (when the object code uses other     */
00143   /* libraries, the buffer may not be big enough). If this is the       */
00144   /* case, redo the second step with a bigger buffer.           */
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);                  /* need to reallocate buffer */
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   /* fourth step: read in the intermediate object files.                */
00164   /* load text and data segment */
00165   loadsize = header.a_text + header.a_data;
00166   lseek(fd, N_TXTOFF(header), 0);
00167   read(fd, start, loadsize);
00168   /* load symbol table and string table */
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   /* fifth step: link C procedure names with Prolog names.              */
00179   dyn_link_all((char *)loc, cur_mod);
00180   mem_dealloc((byte *)loc, loadsize+8,FOR_CODE_SPACE);
00181   return (byte *)4;
00182 }

Generated on Wed Jul 26 13:30:40 2006 for XSB by  doxygen 1.4.5