ack/util/int/init.c

203 lines
5 KiB
C

/*
Startup routines
*/
/* $Header$ */
#include <stdio.h>
#include <em_abs.h>
#include "logging.h"
#include "global.h"
#include "log.h"
#include "alloc.h"
#include "warn.h"
#include "mem.h"
#include "shadow.h"
#include "trap.h"
#include "read.h"
/****************************************************************
* The EM-machine is not implemented as a contiguous *
* piece of memory. Instead there are a number of *
* "floating" pieces of memory, each representing a *
* specific part of the machine. There are separate *
* allocations for: *
* - stack and local area (stack), *
* - heap area & global data area (data), *
* - program text & procedure descriptors (text). *
* The names in parenthesis are the names of the global *
* variables used within our program, pointing to *
* the beginning of such an area. The sizes of the global *
* data area and the program text can be determined *
* once and for all in the "rd_header" routine. *
****************************************************************/
extern char **environ;
PRIVATE ptr storestring();
PRIVATE size alignedstrlen();
char *load_name;
init(ac, av)
int ac;
char **av;
{
register char **p;
register size env_vec_size; /* size of environ vector */
register size arg_vec_size; /* size of argument vector */
register size string_size = 0; /* total size arg, env, strings */
register ptr ARGB, vecp, strp;
init_ofiles(1); /* Initialize all output files */
init_signals();
/* Read the load file header, to obtain wsize and psize */
load_name = av[0];
rd_open(load_name); /* Open object file */
rd_header(); /* Read in load file header */
/* Initialize wsize- and psize-dependent variables */
init_rsb();
i_minsw = (wsize == 2) ? I_MINS2 : I_MINS4;
i_maxsw = (wsize == 2) ? I_MAXS2 : I_MAXS4;
i_maxuw = (wsize == 2) ? I_MAXU2 : I_MAXU4;
max_addr = i2p(((psize == 2) ? I_MAXU2 : I_MAXS4) / wsize * wsize) - 1;
min_off = (psize == 2) ? (-MAX_OFF2-1) : (-MAX_OFF4-1);
max_off = (psize == 2) ? MAX_OFF2 : MAX_OFF4;
/* Determine nr of bytes, needed to store arguments/environment */
env_vec_size = 0; /* length of environ vector copy */
for (p = environ; *p != (char *) 0; p++) {
string_size += alignedstrlen(*p);
env_vec_size += psize;
}
env_vec_size += psize; /* terminating zero */
arg_vec_size = 0; /* length of argument vector copy */
for (p = av; *p != (char *) 0; p++) {
string_size += alignedstrlen(*p);
arg_vec_size += psize;
}
arg_vec_size += psize; /* terminating zero */
/* One pseudo-register */
ARGB = i2p(SZDATA); /* command arguments base */
/* Initialize segments */
init_text();
init_data(ARGB + arg_vec_size + env_vec_size + string_size);
init_stack();
init_FRA();
init_AB_list();
/* Initialize trap registers */
TrapPI = 0; /* set Trap Procedure Identifier */
OnTrap = TR_ABORT; /* there cannot be a trap handler yet*/
IgnMask = PreIgnMask; /* copy Ignore Mask from preset */
/* Initialize Exit Status */
ES_def = UNDEFINED; /* set Exit Status illegal */
/* Read partitions */
rd_text();
rd_gda();
rd_proctab();
rd_close();
/* Set up the arguments and environment */
vecp = ARGB; /* start of environ vector copy */
dppush(vecp); /* push address of env pointer */
strp = vecp + env_vec_size; /* start of environ strings */
for (p = environ; *p != (char *) 0; p++) {
dt_stdp(vecp, strp);
strp = storestring(strp, *p);
vecp += psize;
}
dt_stdp(vecp, i2p(0)); /* terminating zero */
vecp = strp; /* start of argument vector copy */
dppush(vecp); /* push address of argv pointer */
strp = vecp + arg_vec_size; /* start of argument strings */
for (p = av; *p != (char *) 0; p++) {
dt_stdp(vecp, strp);
strp = storestring(strp, *p);
vecp += psize;
}
dt_stdp(vecp, i2p(0)); /* terminating zero */
wpush((long) ac); /* push argc */
}
PRIVATE size alignedstrlen(s)
char *s;
{
register size len = strlen(s) + 1;
return (len + wsize - 1) / wsize * wsize;
}
PRIVATE ptr storestring(addr, s)
ptr addr;
char *s;
{
/* Store string, aligned to a fit multiple of wsize bytes.
Return first address on a wordsize boundary after string.
*/
register size oldlen = strlen(s) + 1;
register size newlen = ((oldlen + wsize - 1) / wsize) * wsize;
register long i;
LOG(("@g6 storestring(%lu, %s), oldlen = %ld, newlen = %ld",
addr, s, oldlen, newlen));
ch_in_data(addr, newlen);
ch_aligned(addr, newlen);
/* copy data of source string */
for (i = 0; i < oldlen; i++) {
data_loc(addr + i) = *s++;
dt_int(addr + i);
}
/* pad until newlen */
for (; i < newlen; i++) {
data_loc(addr + i) = (char) 0;
dt_int(addr + i);
}
return (addr + i);
}
#ifdef LOGGING
dt_clear_area(from, to)
ptr from;
register ptr to;
{
/* includes *from but excludes *to */
register ptr a;
for (a = from; a < to; a++) {
dt_undef(a);
}
}
st_clear_area(from, to)
ptr from;
register ptr to;
{
/* includes both *from and *to (since ML+1 is unexpressible) */
register ptr a;
for (a = from; a >= to; a--) {
st_undef(a);
}
}
#endif /* LOGGING */