read.c 7.0 KB

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