~burner/xsb/debianized-xsb

« back to all changes in this revision

Viewing changes to emu/dynaout_xsb_i.h

  • Committer: Michael R. Head
  • Date: 2006-09-06 22:11:55 UTC
  • Revision ID: burner@n23-20060906221155-7e398d23438a7ee4
Add the files from the 3.0.1 release package

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* File:      dynaout_xsb_i.h
 
2
** Author(s): Jiyang Xu, Kostis Sagonas, Steve Dawson
 
3
** Contact:   xsb-contact@cs.sunysb.edu
 
4
** 
 
5
** Copyright (C) The Research Foundation of SUNY, 1986, 1993-1998
 
6
** Copyright (C) ECRC, Germany, 1990
 
7
** 
 
8
** XSB is free software; you can redistribute it and/or modify it under the
 
9
** terms of the GNU Library General Public License as published by the Free
 
10
** Software Foundation; either version 2 of the License, or (at your option)
 
11
** any later version.
 
12
** 
 
13
** XSB is distributed in the hope that it will be useful, but WITHOUT ANY
 
14
** WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 
15
** FOR A PARTICULAR PURPOSE.  See the GNU Library General Public License for
 
16
** more details.
 
17
** 
 
18
** You should have received a copy of the GNU Library General Public License
 
19
** along with XSB; if not, write to the Free Software Foundation,
 
20
** Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 
21
**
 
22
** $Id: dynaout_xsb_i.h,v 1.12 2005/11/29 00:02:16 tswift Exp $
 
23
** 
 
24
*/
 
25
 
 
26
 
 
27
#include <a.out.h>
 
28
#include <sys/file.h>
 
29
#include <sys/types.h>
 
30
#include <sys/stat.h>
 
31
/* wind2unix.h must be included after sys/stat.h */
 
32
#include "wind2unix.h"
 
33
#include <errno.h>
 
34
#include <stdio.h>
 
35
#include <stdio.h>
 
36
 
 
37
#include "auxlry.h"
 
38
#include "cell_xsb.h"
 
39
#include "memory_xsb.h"
 
40
#include "inst_xsb.h"
 
41
#include "psc_xsb.h"
 
42
#include "flags_xsb.h"
 
43
#include "error_xsb.h"
 
44
#include "io_builtins_xsb.h"
 
45
#include "string_xsb.h"
 
46
#include "extensions_xsb.h"
 
47
 
 
48
#define BUFFEXTRA 1024
 
49
 
 
50
char tfile[128];        /* uniquely-named tmp file for "ld" */
 
51
 
 
52
/*----------------------------------------------------------------------*/
 
53
 
 
54
xsbBool dummy()
 
55
{
 
56
    xsb_error("Trying to use an undefined foreign procedure");
 
57
    return FALSE;
 
58
}
 
59
 
 
60
/*----------------------------------------------------------------------*/
 
61
 
 
62
static void dyn_link_all(char *symtab, Psc cur_mod)
 
63
{
 
64
  int count, i;
 
65
  char *ptr, *strtab;
 
66
  struct nlist *sym_entry;
 
67
  char *name;
 
68
  Pair search_ptr;
 
69
 
 
70
  count = *(int *)(symtab+4);
 
71
  symtab += 8;
 
72
  strtab = symtab + count*sizeof(struct nlist);
 
73
  search_ptr = (Pair)get_data(cur_mod);
 
74
  while (search_ptr) {
 
75
    name = get_name(search_ptr->psc_ptr);
 
76
/* Jiyang changed it to the form ``module_pred'':
 
77
    sprintf(name, "%s_%s", get_name(cur_mod), get_name(search_ptr->psc_ptr));
 
78
 */
 
79
    if (get_type(search_ptr->psc_ptr) == T_FORN) {
 
80
      for (i=0; i<count; i++) {
 
81
        sym_entry = (struct nlist *)(symtab + i * sizeof(struct nlist));
 
82
        ptr = strtab + sym_entry->n_un.n_strx;
 
83
        if (*ptr++ == '_' && strcmp(name, ptr)==0) { 
 
84
          set_forn(search_ptr->psc_ptr, (byte *)(sym_entry->n_value));
 
85
          break;
 
86
        }
 
87
      }
 
88
      if (i>= count) {          /* does not find the name */
 
89
          xsb_warn("Cannot find foreign procedure %s", name);
 
90
          set_forn(search_ptr->psc_ptr, (byte *)(dummy));
 
91
      }
 
92
    }
 
93
    search_ptr = search_ptr->next;
 
94
  }
 
95
}
 
96
 
 
97
/*----------------------------------------------------------------------*/
 
98
 
 
99
static byte *load_obj_dyn(char *pofilename, Psc cur_mod, char *ld_option)
 
100
{
 
101
  int buffsize, fd, loadsize;
 
102
  byte *start;  /* Changed from int -- Kostis.  */
 
103
  int *loc;     /* Changed from int -- Kostis.  */
 
104
  struct exec header;
 
105
  char buff[3*MAXPATHLEN], subfile[MAXPATHLEN];
 
106
  struct stat statbuff;
 
107
  char  *file_extension_ptr;
 
108
  
 
109
  sprintf(tfile, "/tmp/xsb-dyn.%d", (int)getpid());
 
110
  
 
111
  /* first step: get the header entries of the *.o file, in order       */
 
112
  /* to obtain the size of the object code and then allocate space      */
 
113
  /* for it.                                                    */
 
114
  if (strlen(pofilename) >= 127) return 0;
 
115
 
 
116
  /* create filename.o */
 
117
  strcpy(subfile, pofilename);
 
118
  file_extension_ptr = xsb_strrstr(subfile, XSB_OBJ_EXTENSION_STRING);
 
119
  /* replace the OBJ file suffix with the "o" suffix */
 
120
  strcpy(file_extension_ptr+1, "o");
 
121
 
 
122
  fd = open(subfile, O_RDONLY, 0);
 
123
  if (fd < 0) {
 
124
    xsb_error("Cannot find the C object file: %s", subfile);
 
125
    return 0;
 
126
  }
 
127
  read(fd, &header, sizeof(struct exec));
 
128
  close(fd);
 
129
  
 
130
  /* second step: run incremental ld and generate a temporary   */
 
131
  /* object file (including orginal *.o and libraries) ready to be      */
 
132
  /* read in.                                                   */
 
133
  buffsize = header.a_text + header.a_data + header.a_bss;
 
134
  start = mem_alloc(buffsize,FOR_CODE_SPACE);
 
135
  /* The "-T hex" option of ld starts the text segment at location      */
 
136
  /* hex. Specifying -T is the same as using the -Ttext option. */
 
137
  sprintf(buff, "/usr/bin/ld -N -A %s -T %x -o %s %s %s -lc",
 
138
          executable_path_gl, (int)start, tfile, subfile, ld_option);
 
139
  system(buff);
 
140
  
 
141
  /* third step: check if the size of the buffer just allocated is      */
 
142
  /* big enough to load the object (when the object code uses other     */
 
143
  /* libraries, the buffer may not be big enough). If this is the       */
 
144
  /* case, redo the second step with a bigger buffer.           */
 
145
  fd = open(tfile, O_RDONLY, 0);
 
146
  if (fd < 0) {
 
147
    xsb_error("The file is not generated by the loader");
 
148
    return 0;
 
149
  }
 
150
  read(fd, &header, sizeof(struct exec));
 
151
  loadsize = header.a_text + header.a_data + header.a_bss;
 
152
  if (loadsize > buffsize) {
 
153
    close(fd);                  /* need to reallocate buffer */
 
154
    mem_dealloc(start, buffsize,FOR_CODE_SPACE);
 
155
    start = mem_alloc(loadsize+BUFFEXTRA,FOR_CODE_SPACE);
 
156
    sprintf(buff, "/usr/bin/ld -N -A %s -T %x -o %s %s %s -lc",
 
157
            executable_path_gl, (int)start, tfile, subfile, ld_option);
 
158
    system(buff);
 
159
    fd = open(tfile, O_RDONLY, 0);
 
160
    read(fd, &header, sizeof(struct exec));
 
161
  }
 
162
  
 
163
  /* fourth step: read in the intermediate object files.                */
 
164
  /* load text and data segment */
 
165
  loadsize = header.a_text + header.a_data;
 
166
  lseek(fd, N_TXTOFF(header), 0);
 
167
  read(fd, start, loadsize);
 
168
  /* load symbol table and string table */
 
169
  fstat(fd, &statbuff);
 
170
  loadsize = statbuff.st_size-N_SYMOFF(header);
 
171
  loc = (int *)mem_alloc(loadsize+8,FOR_CODE_SPACE);
 
172
  *loc = loadsize+8;
 
173
  *(loc+1) = header.a_syms/sizeof(struct nlist);
 
174
  lseek(fd, N_SYMOFF(header), 0);
 
175
  read(fd, loc+2, loadsize);
 
176
  close(fd);
 
177
  
 
178
  /* fifth step: link C procedure names with Prolog names.              */
 
179
  dyn_link_all((char *)loc, cur_mod);
 
180
  mem_dealloc((byte *)loc, loadsize+8,FOR_CODE_SPACE);
 
181
  return (byte *)4;
 
182
}