123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202 |
- /*
- Startup routines
- */
- /* $Id$ */
- #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 */
|