ack/util/int/init.c

187 lines
4.8 KiB
C
Raw Permalink Normal View History

2019-03-17 14:42:00 +00:00
/** @file
Startup routines.
1988-06-22 16:57:09 +00:00
*/
1994-06-24 11:31:16 +00:00
/* $Id$ */
1988-06-22 16:57:09 +00:00
#include <stdio.h>
2019-03-17 14:42:00 +00:00
#include <string.h>
1988-06-22 16:57:09 +00:00
2019-03-17 14:42:00 +00:00
#include "em_abs.h"
1988-06-22 16:57:09 +00:00
#include "logging.h"
#include "global.h"
2019-03-17 14:42:00 +00:00
#include "segment.h"
1988-06-22 16:57:09 +00:00
#include "log.h"
2019-03-17 14:42:00 +00:00
#include "rsb.h"
#include "fra.h"
#include "read.h"
#include "stack.h"
#include "text.h"
#include "data.h"
1988-06-22 16:57:09 +00:00
#include "alloc.h"
#include "warn.h"
#include "mem.h"
#include "m_sigtrp.h"
2019-03-17 14:42:00 +00:00
#include "io.h"
1988-06-22 16:57:09 +00:00
#include "shadow.h"
#include "trap.h"
#include "read.h"
#include "whatever.h"
1988-06-22 16:57:09 +00:00
/****************************************************************
2019-03-17 14:42:00 +00:00
* 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. *
1988-06-22 16:57:09 +00:00
****************************************************************/
extern char **environ;
PRIVATE ptr storestring();
PRIVATE size alignedstrlen();
char *load_name;
2019-03-17 14:42:00 +00:00
void init(int ac, char **av)
1988-06-22 16:57:09 +00:00
{
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 */
1988-06-22 16:57:09 +00:00
}
2019-03-17 14:42:00 +00:00
PRIVATE size alignedstrlen(char *s)
1988-06-22 16:57:09 +00:00
{
register size len = strlen(s) + 1;
return (len + wsize - 1) / wsize * wsize;
}
2019-03-17 14:42:00 +00:00
PRIVATE ptr storestring(ptr addr, char *s)
1988-06-22 16:57:09 +00:00
{
/* 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);
}