assrl.c 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291
  1. /*
  2. * (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
  3. * See the copyright notice in the ACK home directory, in the file "Copyright".
  4. *
  5. */
  6. #include "ass00.h"
  7. #include "assex.h"
  8. #ifndef NORCSID
  9. static char rcs_id[] = "$Id$" ;
  10. #endif
  11. #define COPYFINAL 1
  12. #define COPYTEMP 0
  13. /*
  14. * collection of routines to deal with relocation business
  15. */
  16. void dataprocess();
  17. void textprocess();
  18. relc_t *
  19. text_reloc(glosym,off,typ) glob_t *glosym; FOFFSET off ; int typ ; {
  20. /*
  21. * prepare the relocation that has to be done at text-offset off
  22. * according to global symbol glosym.
  23. * NOTE: The pointer glosym will point into mglobs[], while at
  24. * the time copyout() is called all the symbols here
  25. * will have disappeared.
  26. * The procedure upd_reloc() will change this pointer
  27. * into the one in xglobs[] later.
  28. */
  29. register relc_t *nxtextreloc ;
  30. nxtextreloc= rlp_cast getarea(sizeof *nxtextreloc) ;
  31. if ( !f_text ) {
  32. f_text= nxtextreloc ;
  33. } else {
  34. l_text->r_next= nxtextreloc ;
  35. }
  36. nxtextreloc->r_next= rlp_cast 0 ;
  37. l_text= nxtextreloc ;
  38. nxtextreloc->r_off = off;
  39. nxtextreloc->r_val.rel_gp = glosym;
  40. nxtextreloc->r_typ = typ; /* flags of instruction */
  41. return(nxtextreloc);
  42. }
  43. relc_t *
  44. data_reloc(arg,off,typ) char *arg ; FOFFSET off ; int typ ; {
  45. /*
  46. * Same as above.
  47. */
  48. register relc_t *nxdatareloc ;
  49. nxdatareloc= rlp_cast getarea(sizeof *nxdatareloc) ;
  50. if ( !f_data ) {
  51. f_data= nxdatareloc ;
  52. } else {
  53. l_data->r_next= nxdatareloc ;
  54. }
  55. nxdatareloc->r_next= rlp_cast 0 ;
  56. l_data= nxdatareloc ;
  57. nxdatareloc->r_off = off;
  58. nxdatareloc->r_val.rel_lp = lbp_cast arg;
  59. nxdatareloc->r_typ = typ;
  60. return(nxdatareloc);
  61. }
  62. copyout() {
  63. register i;
  64. int remtext ;
  65. /*
  66. * Make the e.out file that looks as follows:
  67. *
  68. * __________________________
  69. * | MAGIC | \
  70. * | FLAGS | \
  71. * | UNRESOLVED | \
  72. * | VERSION | | 8*(2-byte word) header
  73. * | WORDSIZE | | for interpreter selection
  74. * | PTRSIZE | /
  75. * | <UNUSED> | /
  76. * | <UNUSED> | /
  77. * | NTEXT | \
  78. * | NDATA | \
  79. * | NPROC | \
  80. * | ENTRY-POINT | | 8*(wordsize-word) header
  81. * | NLINES | | for interpreter proper
  82. * | <UNUSED> | /
  83. * | <UNUSED> | /
  84. * | <UNUSED> | /
  85. * |________________________|
  86. * | |
  87. * | TEXT | zero filled
  88. * | | if not word multiple
  89. * |________________________|
  90. * | |
  91. * | DATA |
  92. * | |
  93. * |________________________|
  94. * | |
  95. * | PROCTABLE |
  96. * | |
  97. * |________________________|
  98. *
  99. *
  100. */
  101. remtext = textbytes%wordsize ;
  102. if ( remtext != 0 ) remtext = wordsize-remtext ;
  103. if ((ifile = fopen(eout,"w")) == 0 )
  104. fatal("can't create e.out");
  105. #ifdef CPM
  106. fclose(tfile); tfile=fopen("TFILE.$$$", "r");
  107. fclose(dfile); dfile=fopen("DFILE.$$$", "r");
  108. #else
  109. tfile=frewind(tfile);
  110. dfile=frewind(dfile);
  111. #endif
  112. xput16(as_magic,ifile);
  113. xput16(intflags,ifile);
  114. xput16(unresolved,ifile);
  115. xput16(VERSION,ifile);
  116. xput16(wordsize,ifile);
  117. xput16(ptrsize,ifile);
  118. xput16(0,ifile);
  119. xput16(0,ifile);
  120. xputa(textbytes+remtext ,ifile);
  121. xputa((cons_t)datablocks,ifile);
  122. xputa((cons_t)procnum,ifile);
  123. xputa((cons_t)searchproc(MAIN,xprocs,oursize->n_xproc)->p_num,
  124. ifile);
  125. xputa((cons_t)sourcelines,ifile);
  126. xputa((cons_t)databytes,ifile);
  127. xputa((cons_t)0,ifile);
  128. xputa((cons_t)0,ifile);
  129. textprocess(tfile,ifile);
  130. while ( remtext-- ) xputc(0,ifile) ;
  131. dataprocess(dfile,ifile);
  132. for (i=0;i<procnum;i++) {
  133. xputarb(ptrsize,proctab[i].pr_loc,ifile);
  134. xputarb(ptrsize,proctab[i].pr_off,ifile);
  135. }
  136. if ( fclose(ifile)==EOF ) ;
  137. }
  138. dataprocess(f1,f2) FILE *f1,*f2; {
  139. relc_t datareloc;
  140. FOFFSET i;
  141. register ieof ;
  142. #ifdef CPM
  143. fclose(rdfile); rdfile=fopen("RDFILE.$$$", "r");
  144. #else
  145. rdfile=frewind(rdfile) ;
  146. #endif
  147. ieof=getblk(rdfile,(char *)(&datareloc.r_off),
  148. sizeof datareloc - sizeof datareloc.r_next) ;
  149. for (i=0 ; i<dataoff && !ieof ; i++) {
  150. if (i==datareloc.r_off) {
  151. switch(datareloc.r_typ) {
  152. case RELADR:
  153. xputa(xgeta(f1)+datareloc.r_val.rel_i,f2) ;
  154. i += ptrsize-1 ;
  155. break ;
  156. case RELGLO:
  157. if (datareloc.r_val.rel_gp->g_status&DEF) {
  158. xputa(xgeta(f1)+
  159. datareloc.r_val.rel_gp->g_val.g_addr,
  160. f2);
  161. i+= ptrsize-1 ;
  162. break ;
  163. }
  164. if ( unresolved == 0 )
  165. fatal("Definition botch") ;
  166. case RELHEAD:
  167. xputc((int)(xgetc(f1)+datareloc.r_val.rel_i),
  168. f2);
  169. break;
  170. default:
  171. fatal("Bad r_typ in dataprocess");
  172. }
  173. ieof=getblk(rdfile,(char *)(&datareloc.r_off),
  174. sizeof datareloc - sizeof datareloc.r_next) ;
  175. } else
  176. xputc(xgetc(f1),f2);
  177. }
  178. for ( ; i<dataoff ; i++ ) xputc(xgetc(f1),f2) ;
  179. if ( !ieof && !getblk(rdfile,(char *)&datareloc,1) )
  180. fatal("data relocation botch") ;
  181. }
  182. textprocess(f1,f2) FILE *f1,*f2; {
  183. relc_t textreloc;
  184. cons_t n;
  185. FOFFSET i;
  186. FILE *otfile ;
  187. int insl ; register int ieof ;
  188. char *op_curr ;
  189. register FOFFSET keep ;
  190. #ifdef CPM
  191. fclose(rtfile); rtfile=fopen("RTFILE.$$$", "r");
  192. #else
  193. rtfile=frewind(rtfile) ;
  194. #endif
  195. keep = textoff ; textoff=0 ; otfile=tfile ; tfile=f2 ;
  196. /* This redirects the output of genop */
  197. ieof=getblk(rtfile,(char *)(&textreloc.r_off),
  198. sizeof textreloc - sizeof textreloc.r_next) ;
  199. for(i=0;i<keep && !ieof ;i++) {
  200. if( i == textreloc.r_off ) {
  201. if (textreloc.r_typ&RELMNS) {
  202. n=textreloc.r_val.rel_i;
  203. } else {
  204. if (textreloc.r_val.rel_gp->g_status&DEF) {
  205. n=textreloc.r_val.rel_gp->g_val.g_addr;
  206. } else {
  207. if ( unresolved==0 )
  208. fatal("Definition botch") ;
  209. xputc(xgetc(f1),f2) ;
  210. ieof=getblk(rtfile,(char *)(&textreloc.r_off),
  211. sizeof textreloc-sizeof textreloc.r_next);
  212. continue ;
  213. }
  214. }
  215. op_curr = &opchoice[textreloc.r_typ& ~RELMNS] ;
  216. insl = oplength(*op_curr) ;
  217. genop(op_curr, n+xgetarb(insl,f1), PAR_G);
  218. i += insl-1 ;
  219. ieof=getblk(rtfile,(char *)(&textreloc.r_off),
  220. sizeof textreloc - sizeof textreloc.r_next) ;
  221. } else {
  222. xputc(xgetc(f1),f2) ;
  223. }
  224. }
  225. for ( ; i<keep ; i++ ) xputc(xgetc(f1),f2) ;
  226. if ( !ieof && !getblk(rtfile,(char *)&textreloc,1) )
  227. fatal("text relocation botch") ;
  228. textoff = keep ;
  229. tfile = otfile ;
  230. }
  231. upd_reloc() {
  232. register relc_t *p;
  233. register glob_t *gbp;
  234. /*
  235. * Change reloc-tables such that for every pointer into mglobs
  236. * either the corresponding pointer into xglobs or its value
  237. * is substituted.
  238. *
  239. * Use is made of the known order of mglobs and xglobs
  240. * see also getcore()
  241. */
  242. while ( p= f_text ) {
  243. gbp= p->r_val.rel_gp ;
  244. if( gbp->g_status&DEF ) {
  245. p->r_typ |= RELMNS;
  246. p->r_val.rel_i = gbp->g_val.g_addr;
  247. } else
  248. p->r_val.rel_gp = gbp->g_val.g_gp;
  249. putblk(rtfile,(char *)(&(p->r_off)),sizeof *p - sizeof p) ;
  250. f_text= p->r_next ; freearea( (area_t) p , sizeof *p ) ;
  251. }
  252. while( p= f_data ) {
  253. if (p->r_typ == RELGLO) {
  254. gbp= p->r_val.rel_gp ;
  255. if(gbp->g_status&DEF) {
  256. p->r_typ = RELADR;
  257. p->r_val.rel_i = gbp->g_val.g_addr;
  258. } else
  259. p->r_val.rel_gp = gbp->g_val.g_gp;
  260. }
  261. putblk(rdfile,(char *)(&(p->r_off)),sizeof *p - sizeof p) ;
  262. f_data= p->r_next ; freearea( (area_t) p , sizeof *p ) ;
  263. }
  264. l_data= rlp_cast 0 ;
  265. }