version 1.48, 1996/12/23 15:07:45
|
version 1.49, 1996/12/28 17:19:25
|
Line 31
|
Line 31
|
#include <fcntl.h> |
#include <fcntl.h> |
#include <assert.h> |
#include <assert.h> |
#include <stdlib.h> |
#include <stdlib.h> |
|
#if HAVE_SYS_MMAN_H |
|
#include <sys/mman.h> |
|
#endif |
#include "forth.h" |
#include "forth.h" |
#include "io.h" |
#include "io.h" |
#include "getopt.h" |
#include "getopt.h" |
Line 61 static Cell rsize=0;
|
Line 64 static Cell rsize=0;
|
static Cell fsize=0; |
static Cell fsize=0; |
static Cell lsize=0; |
static Cell lsize=0; |
static int image_offset=0; |
static int image_offset=0; |
|
static int clear_dictionary=0; |
|
static int debug=0; |
|
static size_t pagesize=0; |
char *progname; |
char *progname; |
|
|
/* image file format: |
/* image file format: |
Line 98 typedef struct {
|
Line 104 typedef struct {
|
UCell locals_stack_size; |
UCell locals_stack_size; |
Xt *boot_entry; /* initial ip for booting (in BOOT) */ |
Xt *boot_entry; /* initial ip for booting (in BOOT) */ |
Xt *throw_entry; /* ip after signal (in THROW) */ |
Xt *throw_entry; /* ip after signal (in THROW) */ |
|
Cell unused1; /* possibly tib stack size */ |
|
Cell unused2; |
|
Address data_stack_base; /* this and the following fields are initialized by the loader */ |
|
Address fp_stack_base; |
|
Address return_stack_base; |
|
Address locals_stack_base; |
} ImageHeader; |
} ImageHeader; |
/* the image-header is created in main.fs */ |
/* the image-header is created in main.fs */ |
|
|
Line 158 UCell checksum(Label symbols[])
|
Line 170 UCell checksum(Label symbols[])
|
return r; |
return r; |
} |
} |
|
|
|
Address my_alloc(Cell size) |
|
{ |
|
static Address next_address=0; |
|
Address r; |
|
|
|
#if HAVE_MMAP && defined(MAP_ANON) |
|
if (debug) |
|
fprintf(stderr,"try mmap($%lx, $%lx, ...); ", (long)next_address, (long)size); |
|
r=mmap(next_address, size, PROT_EXEC|PROT_READ|PROT_WRITE, MAP_ANON|MAP_PRIVATE, -1, 0); |
|
if (r != (Address)-1) { |
|
if (debug) |
|
fprintf(stderr, "success, address=$%lx\n", (long) r); |
|
if (pagesize != 0) |
|
next_address = (Address)(((((Cell)r)+size-1)&-pagesize)+2*pagesize); /* leave one page unmapped */ |
|
return r; |
|
} |
|
if (debug) |
|
fprintf(stderr, "failed: %s\n", strerror(errno)); |
|
#endif |
|
/* use malloc as fallback, leave a little room (64B) for stack underflows */ |
|
if ((r = malloc(size+64))==NULL) { |
|
perror(progname); |
|
exit(1); |
|
} |
|
if (debug) |
|
fprintf(stderr, "malloc succeeds, address=$%lx\n", (long)r); |
|
return r; |
|
} |
|
|
Address loader(FILE *imagefile, char* filename) |
Address loader(FILE *imagefile, char* filename) |
/* returns the address of the image proper (after the preamble) */ |
/* returns the address of the image proper (after the preamble) */ |
{ |
{ |
Line 165 Address loader(FILE *imagefile, char* fi
|
Line 206 Address loader(FILE *imagefile, char* fi
|
Address image; |
Address image; |
Address imp; /* image+preamble */ |
Address imp; /* image+preamble */ |
Char magic[8]; |
Char magic[8]; |
Cell wholesize; |
|
Cell imagesize; /* everything needed by the image */ |
|
Cell preamblesize=0; |
Cell preamblesize=0; |
Label *symbols=engine(0,0,0,0,0); |
Label *symbols=engine(0,0,0,0,0); |
UCell check_sum=checksum(symbols); |
UCell check_sum=checksum(symbols); |
Line 181 Address loader(FILE *imagefile, char* fi
|
Line 220 Address loader(FILE *imagefile, char* fi
|
exit(1); |
exit(1); |
} |
} |
preamblesize+=8; |
preamblesize+=8; |
#ifdef DEBUG |
|
fprintf(stderr,"Magic found: %-8s\n",magic); |
|
#endif |
|
} |
} |
while(memcmp(magic,"Gforth1",7)); |
while(memcmp(magic,"Gforth1",7)); |
|
if (debug) |
|
fprintf(stderr,"Magic found: %-8s\n",magic); |
|
|
if(magic[7] != sizeof(Cell) + |
if(magic[7] != sizeof(Cell) + |
#ifdef WORDS_BIGENDIAN |
#ifdef WORDS_BIGENDIAN |
Line 223 Address loader(FILE *imagefile, char* fi
|
Line 261 Address loader(FILE *imagefile, char* fi
|
lsize=maxaligned(lsize); |
lsize=maxaligned(lsize); |
fsize=maxaligned(fsize); |
fsize=maxaligned(fsize); |
|
|
wholesize = preamblesize+dictsize+dsize+rsize+fsize+lsize; |
#if HAVE_GETPAGESIZE |
imagesize = preamblesize+header.image_size+((header.image_size-1)/sizeof(Cell))/8+1; |
pagesize=getpagesize(); /* Linux/GNU libc offers this */ |
image=malloc(((wholesize>imagesize?wholesize:imagesize)+image_offset) |
#elif HAVE_SYSCONF && defined(_SC_PAGESIZE) |
#ifdef FUZZ |
pagesize=sysconf(_SC_PAGESIZE); /* POSIX.4 */ |
+FUZZ |
#elif PAGESIZE |
#endif |
pagesize=PAGESIZE; /* in limits.h accoring to Gallmeister's POSIX.4 book */ |
)+image_offset; |
#endif |
/*image = maxaligned(image);*/ |
if (debug) |
/* memset(image,0,wholesize); */ |
fprintf(stderr,"pagesize=%d\n",pagesize); |
|
|
#ifdef FUZZ |
image = my_alloc(preamblesize+dictsize+image_offset+FUZZ)+image_offset; |
if(header.base==0) image += FUZZ/2; |
if(header.base==0) |
else if((UCell)(header.base - (Cell)image + preamblesize) < FUZZ) |
image += FUZZ/2; |
image = header.base - preamblesize; |
else |
#endif |
if((UCell)(header.base - (Cell)image + preamblesize) < FUZZ) |
|
image = header.base - preamblesize; |
rewind(imagefile); /* fseek(imagefile,0L,SEEK_SET); */ |
rewind(imagefile); /* fseek(imagefile,0L,SEEK_SET); */ |
fread(image,1,imagesize,imagefile); |
if (clear_dictionary) |
fclose(imagefile); |
memset(image,0,dictsize); |
|
fread(image,1,preamblesize+header.image_size,imagefile); |
imp=image+preamblesize; |
imp=image+preamblesize; |
|
|
if(header.base==0) { |
if(header.base==0) { |
relocate((Cell *)imp,imp+header.image_size,header.image_size,symbols); |
Cell reloc_size=((header.image_size-1)/sizeof(Cell))/8+1; |
|
char reloc_bits[reloc_size]; |
|
fread(reloc_bits,1,reloc_size,imagefile); |
|
relocate((Cell *)imp,reloc_bits,header.image_size,symbols); |
#if 0 |
#if 0 |
{ /* let's see what the relocator did */ |
{ /* let's see what the relocator did */ |
FILE *snapshot=fopen("snapshot.fi","wb"); |
FILE *snapshot=fopen("snapshot.fi","wb"); |
Line 265 Address loader(FILE *imagefile, char* fi
|
Line 307 Address loader(FILE *imagefile, char* fi
|
progname, (unsigned long)(header.checksum),(unsigned long)check_sum); |
progname, (unsigned long)(header.checksum),(unsigned long)check_sum); |
exit(1); |
exit(1); |
} |
} |
|
fclose(imagefile); |
|
|
((ImageHeader *)imp)->dict_size=dictsize; |
((ImageHeader *)imp)->dict_size=dictsize; |
((ImageHeader *)imp)->data_stack_size=dsize; |
((ImageHeader *)imp)->data_stack_size=dsize; |
((ImageHeader *)imp)->return_stack_size=rsize; |
|
((ImageHeader *)imp)->fp_stack_size=fsize; |
((ImageHeader *)imp)->fp_stack_size=fsize; |
|
((ImageHeader *)imp)->return_stack_size=rsize; |
((ImageHeader *)imp)->locals_stack_size=lsize; |
((ImageHeader *)imp)->locals_stack_size=lsize; |
|
|
|
((ImageHeader *)imp)->data_stack_base=my_alloc(dsize); |
|
((ImageHeader *)imp)->fp_stack_base=my_alloc(fsize); |
|
((ImageHeader *)imp)->return_stack_base=my_alloc(rsize); |
|
((ImageHeader *)imp)->locals_stack_base=my_alloc(lsize); |
|
|
CACHE_FLUSH(imp, header.image_size); |
CACHE_FLUSH(imp, header.image_size); |
|
|
return imp; |
return imp; |
Line 279 Address loader(FILE *imagefile, char* fi
|
Line 327 Address loader(FILE *imagefile, char* fi
|
|
|
int go_forth(Address image, int stack, Cell *entries) |
int go_forth(Address image, int stack, Cell *entries) |
{ |
{ |
Cell *sp=(Cell*)(image+dictsize+dsize); |
Cell *sp=(Cell*)(((ImageHeader *)image)->data_stack_base + dsize); |
Address lp=(Address)((void *)sp+lsize); |
Float *fp=(Float *)(((ImageHeader *)image)->fp_stack_base + fsize); |
Float *fp=(Float *)((void *)lp+fsize); |
Cell *rp=(Cell *)(((ImageHeader *)image)->return_stack_base + rsize); |
Cell *rp=(Cell*)((void *)fp+rsize); |
Address lp=((ImageHeader *)image)->locals_stack_base + lsize; |
Xt *ip=(Xt *)(((ImageHeader *)image)->boot_entry); |
Xt *ip=(Xt *)(((ImageHeader *)image)->boot_entry); |
int throw_code; |
int throw_code; |
|
|
|
/* ensure that the cached elements (if any) are accessible */ |
|
IF_TOS(sp--); |
|
IF_FTOS(fp--); |
|
|
for(;stack>0;stack--) |
for(;stack>0;stack--) |
*--sp=entries[stack-1]; |
*--sp=entries[stack-1]; |
Line 370 int main(int argc, char **argv, char **e
|
Line 422 int main(int argc, char **argv, char **e
|
/* put something != 0 into image_offset; it should be a |
/* put something != 0 into image_offset; it should be a |
not-too-large max-aligned number */ |
not-too-large max-aligned number */ |
{"offset-image", no_argument, &image_offset, 28*sizeof(Cell)}, |
{"offset-image", no_argument, &image_offset, 28*sizeof(Cell)}, |
|
{"clear-dictionary", no_argument, &clear_dictionary, 1}, |
|
{"debug", no_argument, &debug, 1}, |
{0,0,0,0} |
{0,0,0,0} |
/* no-init-file, no-rc? */ |
/* no-init-file, no-rc? */ |
}; |
}; |
Line 394 int main(int argc, char **argv, char **e
|
Line 448 int main(int argc, char **argv, char **e
|
case 'h': |
case 'h': |
fprintf(stderr, "Usage: %s [engine options] [image arguments]\n\ |
fprintf(stderr, "Usage: %s [engine options] [image arguments]\n\ |
Engine Options:\n\ |
Engine Options:\n\ |
|
--clear-dictionary Initialize the dictionary with 0 bytes\n\ |
-d SIZE, --data-stack-size=SIZE Specify data stack size\n\ |
-d SIZE, --data-stack-size=SIZE Specify data stack size\n\ |
|
--debug Print debugging information during startup\n\ |
-f SIZE, --fp-stack-size=SIZE Specify floating point stack size\n\ |
-f SIZE, --fp-stack-size=SIZE Specify floating point stack size\n\ |
-h, --help Print this message and exit\n\ |
-h, --help Print this message and exit\n\ |
-i FILE, --image-file=FILE Use image FILE instead of `gforth.fi'\n\ |
-i FILE, --image-file=FILE Use image FILE instead of `gforth.fi'\n\ |
-l SIZE, --locals-stack-size=SIZE Specify locals stack size\n\ |
-l SIZE, --locals-stack-size=SIZE Specify locals stack size\n\ |
-m SIZE, --dictionary-size=SIZE Specify Forth dictionary size\n\ |
-m SIZE, --dictionary-size=SIZE Specify Forth dictionary size\n\ |
--offset-image load image at a different position\n\ |
--offset-image Load image at a different position\n\ |
-p PATH, --path=PATH Search path for finding image and sources\n\ |
-p PATH, --path=PATH Search path for finding image and sources\n\ |
-r SIZE, --return-stack-size=SIZE Specify return stack size\n\ |
-r SIZE, --return-stack-size=SIZE Specify return stack size\n\ |
-v, --version Print version and exit\n\ |
-v, --version Print version and exit\n\ |