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"
|
Cut down some clang warnings
Edit C code to reduce warnings from clang. Most warnings are for
implicit declarations of functions, but some warnings want me to add
parentheses or curly braces, or to cast arguments for printf().
Make a few other changes, like declaring float_cst() in h/con_float to
be static, and using C99 bool in ego/ra/makeitems.c and
ego/share/makecldef.c. Such changes don't silence warnings; I make
such changes while I silence warnings in the same file. In
float_cst(), rename parameter `str` to `float_str`, so it doesn't
share a name with the global variable `str`.
Remove `const` from `newmodule(const char *)` in mach/proto/as to
silence a warning. I wrongly added the `const` in d347207.
For warnings about implicit declarations of functions, the fix is to
declare the function before calling it. For example, my OpenBSD
system needs <sys/wait.h> to declare wait().
In util/int, add "whatever.h" to declare more functions. Remove old
declarations from "mem.h", to prefer the newer declarations of the
same functions in "data.h" and "stack.h".
2019-10-23 20:06:36 +00:00
|
|
|
#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"
|
Cut down some clang warnings
Edit C code to reduce warnings from clang. Most warnings are for
implicit declarations of functions, but some warnings want me to add
parentheses or curly braces, or to cast arguments for printf().
Make a few other changes, like declaring float_cst() in h/con_float to
be static, and using C99 bool in ego/ra/makeitems.c and
ego/share/makecldef.c. Such changes don't silence warnings; I make
such changes while I silence warnings in the same file. In
float_cst(), rename parameter `str` to `float_str`, so it doesn't
share a name with the global variable `str`.
Remove `const` from `newmodule(const char *)` in mach/proto/as to
silence a warning. I wrongly added the `const` in d347207.
For warnings about implicit declarations of functions, the fix is to
declare the function before calling it. For example, my OpenBSD
system needs <sys/wait.h> to declare wait().
In util/int, add "whatever.h" to declare more functions. Remove old
declarations from "mem.h", to prefer the newer declarations of the
same functions in "data.h" and "stack.h".
2019-10-23 20:06:36 +00:00
|
|
|
#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 */
|
|
|
|
|
1989-11-13 15:36:12 +00:00
|
|
|
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);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|