read.c 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321
  1. /*
  2. Reading the EM object file
  3. */
  4. /* $Id$ */
  5. #include <stdio.h>
  6. #include <local.h> /* for VERSION */
  7. #include <em_spec.h>
  8. #include <as_spec.h> /* for as_magic */
  9. #include "logging.h"
  10. #include "nofloat.h"
  11. #include "global.h"
  12. #include "log.h"
  13. #include "warn.h"
  14. #include "mem.h"
  15. #include "shadow.h"
  16. #include "read.h"
  17. #include "text.h"
  18. #ifndef NOFLOAT
  19. extern double str2double();
  20. #endif /* NOFLOAT */
  21. /************************************************************************
  22. * Read object file contents. *
  23. ************************************************************************
  24. * *
  25. * rd_open() - open object file. *
  26. * rd_header() - read object file header. *
  27. * rd_text() - read program text. *
  28. * rd_gda() - read global data area. *
  29. * rd_proctab() - read procedure descriptors, *
  30. * rd_close() - close object file. *
  31. * *
  32. ************************************************************************/
  33. /* EM header Part 1 variables */
  34. int FLAGS;
  35. /* EM header Part 2 variables */
  36. size NTEXT;
  37. size NDATA;
  38. long NPROC;
  39. long ENTRY;
  40. long NLINE;
  41. size SZDATA;
  42. PRIVATE FILE *load_fp; /* Filepointer of load file */
  43. PRIVATE ptr rd_repeat();
  44. PRIVATE ptr rd_descr();
  45. PRIVATE int rd_byte();
  46. PRIVATE long rd_int();
  47. rd_open(fname)
  48. char *fname;
  49. { /* Open loadfile */
  50. if ((load_fp = fopen(fname, "r")) == NULL) {
  51. fatal("Cannot open loadfile '%s'", fname);
  52. }
  53. }
  54. rd_header()
  55. {
  56. /* Part 1 */
  57. if (rd_int(2L) != as_magic)
  58. fatal("Bad magic number in loadfile");
  59. FLAGS = rd_int(2L);
  60. if (rd_int(2L) != 0)
  61. fatal("Unresolved references in loadfile");
  62. if (rd_int(2L) != VERSION)
  63. fatal("Incorrect version number in loadfile");
  64. /* We only allow the following wordsize/pointersize combinations: */
  65. /* 2/2, 2/4, 4/4 */
  66. /* A fatal error will be generated if other combinations occur. */
  67. wsize = rd_int(2L);
  68. if (!(wsize == 2 || wsize == 4))
  69. fatal("Bad wordsize in loadfile");
  70. dwsize = 2 * wsize; /* set double wordsize */
  71. wsizem1 = wsize - 1; /* wordsize - 1 used often */
  72. psize = rd_int(2L);
  73. if (!(psize == 2 || psize == 4) || psize < wsize)
  74. fatal("Bad pointersize in loadfile");
  75. if (2 * psize > FRALimit)
  76. fatal("FRA maximum size too small");
  77. rd_int(2L); /* Entry 7 is unused */
  78. rd_int(2L); /* Entry 8 is unused */
  79. /* Part 2 */
  80. NTEXT = rd_int(psize);
  81. NDATA = rd_int(psize);
  82. NPROC = rd_int(psize);
  83. ENTRY = rd_int(psize);
  84. if (ENTRY < 0 || ENTRY >= NPROC)
  85. fatal("Bad entry point");
  86. NLINE = rd_int(psize);
  87. if (NLINE == 0) {
  88. warning(WNLINEZR);
  89. NLINE = I_MAXS4;
  90. }
  91. SZDATA = rd_int(psize);
  92. rd_int(psize); /* entry 7 is unused */
  93. rd_int(psize); /* entry 8 is unused */
  94. }
  95. rd_text()
  96. {
  97. fread(text, 1, (int) DB, load_fp);
  98. }
  99. rd_gda()
  100. {
  101. register int type, prev_type;
  102. register ptr pos, prev_pos; /* prev_pos invalid if prev_type==0 */
  103. register long i;
  104. type = prev_type = 0;
  105. pos = prev_pos = i2p(0);
  106. for (i = 1; i <= NDATA; i++) {
  107. type = btol(rd_byte());
  108. LOG((" r6 rd_gda(), i = %ld, pos = %u", i, pos));
  109. if (type == 0) {
  110. /* repetition descriptor */
  111. register size count = rd_int(psize);
  112. LOG((" r6 rd_gda(), case 0: count = %lu", count));
  113. if (prev_type == 0) {
  114. fatal("Type 0 initialisation on type 0");
  115. }
  116. pos = rd_repeat(pos, count, prev_pos);
  117. prev_type = 0;
  118. }
  119. else {
  120. /* filling descriptor */
  121. register size count = btol(rd_byte());
  122. LOG((" r6 rd_gda(), case %d: count = %lu",
  123. type, count));
  124. prev_pos = pos;
  125. pos = rd_descr(type, count, prev_pos);
  126. prev_type = type;
  127. }
  128. }
  129. /* now protect the LIN and FIL area */
  130. dt_prot(i2p(0), (long)LINSIZE);
  131. dt_prot(i2p(4), psize);
  132. }
  133. rd_proctab()
  134. {
  135. register long p;
  136. init_proctab();
  137. for (p = 0; p < NPROC; p++) {
  138. register long nloc = rd_int(psize);
  139. register ptr ep = i2p(rd_int(psize));
  140. add_proc(nloc, ep);
  141. }
  142. end_init_proctab();
  143. }
  144. rd_close()
  145. {
  146. fclose(load_fp);
  147. load_fp = 0;
  148. }
  149. /************************************************************************
  150. * Read functions for several types. *
  151. ************************************************************************
  152. * *
  153. * rd_repeat() - repeat the previous initialisation *
  154. * rd_descr() - read a descriptor *
  155. * rd_byte() - read one byte, return a int. *
  156. * rd_int(n) - read n byte integer, return a long. *
  157. * *
  158. ************************************************************************/
  159. /************************************************************************
  160. * Reading a floating point number *
  161. * *
  162. * A double is 8 bytes, so it can contain 4- and 8-byte (EM) *
  163. * floating point numbers. That's why a 4-byte floating point *
  164. * number is also stored in a double. *
  165. ************************************************************************/
  166. PRIVATE ptr rd_repeat(pos, count, prev_pos)
  167. ptr pos, prev_pos;
  168. size count;
  169. {
  170. register size diff = pos - prev_pos;
  171. register size j;
  172. for (j = 0; j < count; j++) {
  173. register long i;
  174. for (i = 0; i < diff; i++) {
  175. data_loc(pos) = data_loc(pos - diff);
  176. #ifdef LOGGING
  177. /* copy shadow byte, including protection bit */
  178. dt_sh(pos) = dt_sh(pos - diff);
  179. #endif /* LOGGING */
  180. pos++;
  181. }
  182. }
  183. return pos;
  184. }
  185. PRIVATE ptr rd_descr(type, count, pos)
  186. int type;
  187. size count;
  188. ptr pos;
  189. {
  190. register size j;
  191. char fl_rep[128]; /* fp number representation */
  192. register int fl_cnt;
  193. switch (type) {
  194. case 1: /* m uninitialized words */
  195. j = count;
  196. while (j--) {
  197. dt_stw(pos, 0L);
  198. pos += wsize;
  199. }
  200. break;
  201. case 2: /* m initialized bytes */
  202. j = count;
  203. while (j--) {
  204. dt_stn(pos++, btol(rd_byte()), 1L);
  205. }
  206. break;
  207. case 3: /* m initialized wordsize integers */
  208. for (j = 0; j < count; j++) {
  209. dt_stw(pos, rd_int(wsize));
  210. pos += wsize;
  211. }
  212. break;
  213. case 4: /* m initialized data pointers */
  214. for (j = 0; j < count; j++) {
  215. dt_stdp(pos, i2p(rd_int(psize)));
  216. pos += psize;
  217. }
  218. break;
  219. case 5: /* m initialized instruction pointers */
  220. for (j = 0; j < count; j++) {
  221. dt_stip(pos, i2p(rd_int(psize)));
  222. pos += psize;
  223. }
  224. break;
  225. case 6: /* initialized integer of size m */
  226. case 7: /* initialized unsigned int of size m */
  227. if ((j = count) != 1 && j != 2 && j != 4)
  228. fatal("Bad integersize during initialisation");
  229. dt_stn(pos, rd_int(j), j);
  230. pos += j;
  231. break;
  232. case 8: /* initialized float of size m */
  233. if ((j = count) != 4 && j != 8)
  234. fatal("Bad floatsize during initialisation");
  235. /* get fp representation */
  236. fl_cnt = 0;
  237. while (fl_rep[fl_cnt] = rd_byte()) {
  238. fl_cnt++;
  239. if (fl_cnt >= sizeof (fl_rep)) {
  240. fatal("Initialized float longer than %d chars",
  241. sizeof (fl_rep));
  242. }
  243. }
  244. #ifndef NOFLOAT
  245. /* store the float */
  246. dt_stf(pos, str2double(fl_rep), j);
  247. #else /* NOFLOAT */
  248. /* we cannot store the float */
  249. warning(WFLINIT);
  250. #endif /* NOFLOAT */
  251. pos += j;
  252. break;
  253. default:
  254. fatal("Unknown initializer type in global data.");
  255. break;
  256. }
  257. return pos;
  258. }
  259. PRIVATE int rd_byte()
  260. {
  261. register int i;
  262. if ((i = getc(load_fp)) == EOF)
  263. fatal("EOF reached during initialization");
  264. return (i);
  265. }
  266. PRIVATE long rd_int(n)
  267. size n;
  268. {
  269. register long l;
  270. register int i;
  271. l = btol(rd_byte());
  272. for (i = 1; i < n; i++) {
  273. l |= (btol(rd_byte()) << (i*8));
  274. }
  275. return (l);
  276. }