1
/* File: dynaout_xsb_i.h
2
** Author(s): Jiyang Xu, Kostis Sagonas, Steve Dawson
3
** Contact: xsb-contact@cs.sunysb.edu
5
** Copyright (C) The Research Foundation of SUNY, 1986, 1993-1998
6
** Copyright (C) ECRC, Germany, 1990
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)
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
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.
22
** $Id: dynaout_xsb_i.h,v 1.12 2005/11/29 00:02:16 tswift Exp $
29
#include <sys/types.h>
31
/* wind2unix.h must be included after sys/stat.h */
32
#include "wind2unix.h"
39
#include "memory_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"
48
#define BUFFEXTRA 1024
50
char tfile[128]; /* uniquely-named tmp file for "ld" */
52
/*----------------------------------------------------------------------*/
56
xsb_error("Trying to use an undefined foreign procedure");
60
/*----------------------------------------------------------------------*/
62
static void dyn_link_all(char *symtab, Psc cur_mod)
66
struct nlist *sym_entry;
70
count = *(int *)(symtab+4);
72
strtab = symtab + count*sizeof(struct nlist);
73
search_ptr = (Pair)get_data(cur_mod);
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));
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));
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));
93
search_ptr = search_ptr->next;
97
/*----------------------------------------------------------------------*/
99
static byte *load_obj_dyn(char *pofilename, Psc cur_mod, char *ld_option)
101
int buffsize, fd, loadsize;
102
byte *start; /* Changed from int -- Kostis. */
103
int *loc; /* Changed from int -- Kostis. */
105
char buff[3*MAXPATHLEN], subfile[MAXPATHLEN];
106
struct stat statbuff;
107
char *file_extension_ptr;
109
sprintf(tfile, "/tmp/xsb-dyn.%d", (int)getpid());
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 */
114
if (strlen(pofilename) >= 127) return 0;
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");
122
fd = open(subfile, O_RDONLY, 0);
124
xsb_error("Cannot find the C object file: %s", subfile);
127
read(fd, &header, sizeof(struct exec));
130
/* second step: run incremental ld and generate a temporary */
131
/* object file (including orginal *.o and libraries) ready to be */
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);
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);
147
xsb_error("The file is not generated by the loader");
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);
159
fd = open(tfile, O_RDONLY, 0);
160
read(fd, &header, sizeof(struct exec));
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);
173
*(loc+1) = header.a_syms/sizeof(struct nlist);
174
lseek(fd, N_SYMOFF(header), 0);
175
read(fd, loc+2, loadsize);
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);