Pristine Ack-5.5
[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          *      |      TEXT              |        zero filled
102          *      |                        |        if not word multiple
103          *      |________________________|
104          *      |                        |
105          *      |      DATA              |
106          *      |                        |
107          *      |________________________|
108          *      |                        |
109          *      |      PROCTABLE         |
110          *      |                        |
111          *      |________________________|
112          *
113          *
114          */
115
116         remtext = textbytes%wordsize ;
117         if ( remtext != 0 ) remtext = wordsize-remtext ;
118
119         if ((ifile = fopen(eout,"w")) == 0 )
120                 fatal("can't create e.out");
121 #ifdef  CPM
122         fclose(tfile); tfile=fopen("TFILE.$$$", "r");
123         fclose(dfile); dfile=fopen("DFILE.$$$", "r");
124 #else
125         tfile=frewind(tfile);
126         dfile=frewind(dfile);
127 #endif
128         xput16(as_magic,ifile);
129         xput16(intflags,ifile);
130         xput16(unresolved,ifile);
131         xput16(VERSION,ifile);
132         xput16(wordsize,ifile);
133         xput16(ptrsize,ifile);
134         xput16(0,ifile);
135         xput16(0,ifile);
136         xputa(textbytes+remtext ,ifile);
137         xputa((cons_t)datablocks,ifile);
138         xputa((cons_t)procnum,ifile);
139         xputa((cons_t)searchproc(MAIN,xprocs,oursize->n_xproc)->p_num,
140                 ifile);
141         xputa((cons_t)sourcelines,ifile);
142         xputa((cons_t)databytes,ifile);
143         xputa((cons_t)0,ifile);
144         xputa((cons_t)0,ifile);
145
146         textprocess(tfile,ifile);
147         while ( remtext-- ) xputc(0,ifile) ;
148
149         dataprocess(dfile,ifile);
150         for (i=0;i<procnum;i++) {
151                 xputarb(ptrsize,proctab[i].pr_loc,ifile);
152                 xputarb(ptrsize,proctab[i].pr_off,ifile);
153         }
154         if ( fclose(ifile)==EOF ) ;
155 }
156
157 dataprocess(f1,f2) FILE *f1,*f2; {
158         relc_t datareloc;
159         FOFFSET i;
160         register ieof ;
161
162 #ifdef  CPM
163         fclose(rdfile); rdfile=fopen("RDFILE.$$$", "r");
164 #else
165         rdfile=frewind(rdfile) ;
166 #endif
167         ieof=getblk(rdfile,(char *)(&datareloc.r_off),
168                 sizeof datareloc - sizeof datareloc.r_next) ;
169         for (i=0 ; i<dataoff && !ieof ; i++) {
170                 if (i==datareloc.r_off) {
171                         switch(datareloc.r_typ) {
172                         case RELADR:
173                                 xputa(xgeta(f1)+datareloc.r_val.rel_i,f2) ;
174                                 i += ptrsize-1 ;
175                                 break ;
176                         case RELGLO:
177                                 if (datareloc.r_val.rel_gp->g_status&DEF) {
178                                 xputa(xgeta(f1)+
179                                         datareloc.r_val.rel_gp->g_val.g_addr,
180                                                 f2);
181                                         i+= ptrsize-1 ;
182                                         break ;
183                                 }
184                                 if ( unresolved == 0 )
185                                         fatal("Definition botch") ;
186                         case RELHEAD:
187                                 xputc((int)(xgetc(f1)+datareloc.r_val.rel_i),
188                                         f2);
189                                 break;
190                         default:
191                                 fatal("Bad r_typ in dataprocess");
192                         }
193                         ieof=getblk(rdfile,(char *)(&datareloc.r_off),
194                                 sizeof datareloc - sizeof datareloc.r_next) ;
195                 } else
196                         xputc(xgetc(f1),f2);
197         }
198         for ( ; i<dataoff ; i++ ) xputc(xgetc(f1),f2) ;
199         if ( !ieof && !getblk(rdfile,(char *)&datareloc,1) )
200                 fatal("data relocation botch") ;
201 }
202
203 textprocess(f1,f2) FILE *f1,*f2; {
204         relc_t textreloc;
205         cons_t n;
206         FOFFSET i;
207         FILE *otfile ;
208         int insl ;  register int ieof ;
209         char *op_curr ;
210         register FOFFSET keep ;
211
212 #ifdef  CPM
213         fclose(rtfile); rtfile=fopen("RTFILE.$$$", "r");
214 #else
215         rtfile=frewind(rtfile) ;
216 #endif
217         keep = textoff ; textoff=0 ; otfile=tfile ; tfile=f2 ;
218         /* This redirects the output of genop */
219         ieof=getblk(rtfile,(char *)(&textreloc.r_off),
220                 sizeof textreloc - sizeof textreloc.r_next) ;
221         for(i=0;i<keep && !ieof ;i++) {
222                 if( i == textreloc.r_off ) {
223                         if (textreloc.r_typ&RELMNS) {
224                                 n=textreloc.r_val.rel_i;
225                         } else {
226                                 if (textreloc.r_val.rel_gp->g_status&DEF) {
227                                       n=textreloc.r_val.rel_gp->g_val.g_addr;
228                                 } else {
229                                         if ( unresolved==0 )
230                                                 fatal("Definition botch") ;
231                                         xputc(xgetc(f1),f2) ;
232                                 ieof=getblk(rtfile,(char *)(&textreloc.r_off),
233                                 sizeof textreloc-sizeof textreloc.r_next);
234                                         continue ;
235                                 }
236                         }
237                         op_curr = &opchoice[textreloc.r_typ& ~RELMNS] ;
238                         insl = oplength(*op_curr) ;
239                         genop(op_curr, n+xgetarb(insl,f1), PAR_G);
240                         i += insl-1 ;
241                         ieof=getblk(rtfile,(char *)(&textreloc.r_off),
242                                 sizeof textreloc - sizeof textreloc.r_next) ;
243                 } else {
244                         xputc(xgetc(f1),f2) ;
245                 }
246         }
247         for ( ; i<keep ; i++ ) xputc(xgetc(f1),f2) ;
248         if ( !ieof && !getblk(rtfile,(char *)&textreloc,1) )
249                 fatal("text relocation botch") ;
250         textoff = keep ;
251         tfile = otfile ;
252 }
253
254 upd_reloc() {
255         register relc_t *p;
256         register glob_t *gbp;
257
258         /*
259          * Change reloc-tables such that for every pointer into mglobs
260          * either the corresponding pointer into xglobs or its value
261          * is substituted.
262          *
263          * Use is made of the known order of mglobs and xglobs
264          * see also getcore()
265          */
266
267         while ( p= f_text ) {
268                 gbp= p->r_val.rel_gp ;
269                 if( gbp->g_status&DEF ) {
270                         p->r_typ |= RELMNS;
271                         p->r_val.rel_i = gbp->g_val.g_addr;
272                 } else
273                         p->r_val.rel_gp = gbp->g_val.g_gp;
274                 putblk(rtfile,(char *)(&(p->r_off)),sizeof *p - sizeof p) ;
275                 f_text= p->r_next ; freearea( (area_t) p , sizeof *p ) ;
276         }
277
278         while( p= f_data ) {
279                 if (p->r_typ == RELGLO) {
280                         gbp= p->r_val.rel_gp ;
281                         if(gbp->g_status&DEF) {
282                                 p->r_typ = RELADR;
283                                 p->r_val.rel_i = gbp->g_val.g_addr;
284                         } else
285                                 p->r_val.rel_gp = gbp->g_val.g_gp;
286                 }
287                 putblk(rdfile,(char *)(&(p->r_off)),sizeof *p - sizeof p) ;
288                 f_data= p->r_next ; freearea( (area_t) p , sizeof *p ) ;
289         }
290         l_data= rlp_cast 0 ;
291 }