init.c 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202
  1. /*
  2. Startup routines
  3. */
  4. /* $Id$ */
  5. #include <stdio.h>
  6. #include <em_abs.h>
  7. #include "logging.h"
  8. #include "global.h"
  9. #include "log.h"
  10. #include "alloc.h"
  11. #include "warn.h"
  12. #include "mem.h"
  13. #include "shadow.h"
  14. #include "trap.h"
  15. #include "read.h"
  16. /****************************************************************
  17. * The EM-machine is not implemented as a contiguous *
  18. * piece of memory. Instead there are a number of *
  19. * "floating" pieces of memory, each representing a *
  20. * specific part of the machine. There are separate *
  21. * allocations for: *
  22. * - stack and local area (stack), *
  23. * - heap area & global data area (data), *
  24. * - program text & procedure descriptors (text). *
  25. * The names in parenthesis are the names of the global *
  26. * variables used within our program, pointing to *
  27. * the beginning of such an area. The sizes of the global *
  28. * data area and the program text can be determined *
  29. * once and for all in the "rd_header" routine. *
  30. ****************************************************************/
  31. extern char **environ;
  32. PRIVATE ptr storestring();
  33. PRIVATE size alignedstrlen();
  34. char *load_name;
  35. init(ac, av)
  36. int ac;
  37. char **av;
  38. {
  39. register char **p;
  40. register size env_vec_size; /* size of environ vector */
  41. register size arg_vec_size; /* size of argument vector */
  42. register size string_size = 0; /* total size arg, env, strings */
  43. register ptr ARGB, vecp, strp;
  44. init_ofiles(1); /* Initialize all output files */
  45. init_signals();
  46. /* Read the load file header, to obtain wsize and psize */
  47. load_name = av[0];
  48. rd_open(load_name); /* Open object file */
  49. rd_header(); /* Read in load file header */
  50. /* Initialize wsize- and psize-dependent variables */
  51. init_rsb();
  52. i_minsw = (wsize == 2) ? I_MINS2 : I_MINS4;
  53. i_maxsw = (wsize == 2) ? I_MAXS2 : I_MAXS4;
  54. i_maxuw = (wsize == 2) ? I_MAXU2 : I_MAXU4;
  55. max_addr = i2p(((psize == 2) ? I_MAXU2 : I_MAXS4) / wsize * wsize) - 1;
  56. min_off = (psize == 2) ? (-MAX_OFF2-1) : (-MAX_OFF4-1);
  57. max_off = (psize == 2) ? MAX_OFF2 : MAX_OFF4;
  58. /* Determine nr of bytes, needed to store arguments/environment */
  59. env_vec_size = 0; /* length of environ vector copy */
  60. for (p = environ; *p != (char *) 0; p++) {
  61. string_size += alignedstrlen(*p);
  62. env_vec_size += psize;
  63. }
  64. env_vec_size += psize; /* terminating zero */
  65. arg_vec_size = 0; /* length of argument vector copy */
  66. for (p = av; *p != (char *) 0; p++) {
  67. string_size += alignedstrlen(*p);
  68. arg_vec_size += psize;
  69. }
  70. arg_vec_size += psize; /* terminating zero */
  71. /* One pseudo-register */
  72. ARGB = i2p(SZDATA); /* command arguments base */
  73. /* Initialize segments */
  74. init_text();
  75. init_data(ARGB + arg_vec_size + env_vec_size + string_size);
  76. init_stack();
  77. init_FRA();
  78. init_AB_list();
  79. /* Initialize trap registers */
  80. TrapPI = 0; /* set Trap Procedure Identifier */
  81. OnTrap = TR_ABORT; /* there cannot be a trap handler yet*/
  82. IgnMask = PreIgnMask; /* copy Ignore Mask from preset */
  83. /* Initialize Exit Status */
  84. ES_def = UNDEFINED; /* set Exit Status illegal */
  85. /* Read partitions */
  86. rd_text();
  87. rd_gda();
  88. rd_proctab();
  89. rd_close();
  90. /* Set up the arguments and environment */
  91. vecp = ARGB; /* start of environ vector copy */
  92. dppush(vecp); /* push address of env pointer */
  93. strp = vecp + env_vec_size; /* start of environ strings */
  94. for (p = environ; *p != (char *) 0; p++) {
  95. dt_stdp(vecp, strp);
  96. strp = storestring(strp, *p);
  97. vecp += psize;
  98. }
  99. dt_stdp(vecp, i2p(0)); /* terminating zero */
  100. vecp = strp; /* start of argument vector copy */
  101. dppush(vecp); /* push address of argv pointer */
  102. strp = vecp + arg_vec_size; /* start of argument strings */
  103. for (p = av; *p != (char *) 0; p++) {
  104. dt_stdp(vecp, strp);
  105. strp = storestring(strp, *p);
  106. vecp += psize;
  107. }
  108. dt_stdp(vecp, i2p(0)); /* terminating zero */
  109. wpush((long) ac); /* push argc */
  110. }
  111. PRIVATE size alignedstrlen(s)
  112. char *s;
  113. {
  114. register size len = strlen(s) + 1;
  115. return (len + wsize - 1) / wsize * wsize;
  116. }
  117. PRIVATE ptr storestring(addr, s)
  118. ptr addr;
  119. char *s;
  120. {
  121. /* Store string, aligned to a fit multiple of wsize bytes.
  122. Return first address on a wordsize boundary after string.
  123. */
  124. register size oldlen = strlen(s) + 1;
  125. register size newlen = ((oldlen + wsize - 1) / wsize) * wsize;
  126. register long i;
  127. LOG(("@g6 storestring(%lu, %s), oldlen = %ld, newlen = %ld",
  128. addr, s, oldlen, newlen));
  129. ch_in_data(addr, newlen);
  130. ch_aligned(addr, newlen);
  131. /* copy data of source string */
  132. for (i = 0; i < oldlen; i++) {
  133. data_loc(addr + i) = *s++;
  134. dt_int(addr + i);
  135. }
  136. /* pad until newlen */
  137. for (; i < newlen; i++) {
  138. data_loc(addr + i) = (char) 0;
  139. dt_int(addr + i);
  140. }
  141. return (addr + i);
  142. }
  143. #ifdef LOGGING
  144. dt_clear_area(from, to)
  145. ptr from;
  146. register ptr to;
  147. {
  148. /* includes *from but excludes *to */
  149. register ptr a;
  150. for (a = from; a < to; a++) {
  151. dt_undef(a);
  152. }
  153. }
  154. st_clear_area(from, to)
  155. ptr from;
  156. register ptr to;
  157. {
  158. /* includes both *from and *to (since ML+1 is unexpressible) */
  159. register ptr a;
  160. for (a = from; a >= to; a--) {
  161. st_undef(a);
  162. }
  163. }
  164. #endif /* LOGGING */