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