/* * (c) copyright 1983 by the Vrije Universiteit, Amsterdam, The Netherlands. * * This product is part of the Amsterdam Compiler Kit. * * Permission to use, sell, duplicate or disclose this software must be * obtained in writing. Requests for such permissions may be sent to * * Dr. Andrew S. Tanenbaum * Wiskundig Seminarium * Vrije Universiteit * Postbox 7161 * 1007 MC Amsterdam * The Netherlands * */ #include "ass00.h" #include "assex.h" #ifndef NORCSID static char rcs_id[] = "$Header$" ; #endif #define COPYFINAL 1 #define COPYTEMP 0 /* * collection of routines to deal with relocation business */ void dataprocess(); void textprocess(); relc_t * text_reloc(glosym,off,typ) glob_t *glosym; FOFFSET off ; int typ ; { /* * prepare the relocation that has to be done at text-offset off * according to global symbol glosym. * NOTE: The pointer glosym will point into mglobs[], while at * the time copyout() is called all the symbols here * will have disappeared. * The procedure upd_reloc() will change this pointer * into the one in xglobs[] later. */ register relc_t *nxtextreloc ; nxtextreloc= rlp_cast getarea(sizeof *nxtextreloc) ; if ( !f_text ) { f_text= nxtextreloc ; } else { l_text->r_next= nxtextreloc ; } nxtextreloc->r_next= rlp_cast 0 ; l_text= nxtextreloc ; nxtextreloc->r_off = off; nxtextreloc->r_val.rel_gp = glosym; nxtextreloc->r_typ = typ; /* flags of instruction */ return(nxtextreloc); } relc_t * data_reloc(arg,off,typ) char *arg ; FOFFSET off ; int typ ; { /* * Same as above. */ register relc_t *nxdatareloc ; nxdatareloc= rlp_cast getarea(sizeof *nxdatareloc) ; if ( !f_data ) { f_data= nxdatareloc ; } else { l_data->r_next= nxdatareloc ; } nxdatareloc->r_next= rlp_cast 0 ; l_data= nxdatareloc ; nxdatareloc->r_off = off; nxdatareloc->r_val.rel_lp = lbp_cast arg; nxdatareloc->r_typ = typ; return(nxdatareloc); } copyout() { register i; int remtext ; /* * Make the e.out file that looks as follows: * * __________________________ * | MAGIC | \ * | FLAGS | \ * | UNRESOLVED | \ * | VERSION | | 8*(2-byte word) header * | WORDSIZE | | for interpreter selection * | PTRSIZE | / * | <UNUSED> | / * | <UNUSED> | / * | NTEXT | \ * | NDATA | \ * | NPROC | \ * | ENTRY-POINT | | 8*(wordsize-word) header * | NLINES | | for interpreter proper * | <UNUSED> | / * | <UNUSED> | / * | <UNUSED> | / * |________________________| * | | * | TEXT | zero filled * | | if not word multiple * |________________________| * | | * | DATA | * | | * |________________________| * | | * | PROCTABLE | * | | * |________________________| * * */ remtext = textbytes%wordsize ; if ( remtext != 0 ) remtext = wordsize-remtext ; if ((ifile = fopen(eout,"w")) == NULL ) fatal("can't create e.out"); #ifdef CPM fclose(tfile); tfile=fopen("TFILE.$$$, "r"); fclose(dfile); dfile=fopen("DFILE.$$$, "r"); #else tfile=frewind(tfile); dfile=frewind(dfile); #endif xput16(as_magic,ifile); xput16(intflags,ifile); xput16(unresolved,ifile); xput16(VERSION,ifile); xput16(wordsize,ifile); xput16(ptrsize,ifile); xput16(0,ifile); xput16(0,ifile); xputa(textbytes+remtext ,ifile); xputa((cons_t)datablocks,ifile); xputa((cons_t)procnum,ifile); xputa((cons_t)searchproc(MAIN,xprocs,oursize->n_xproc)->p_num, ifile); xputa((cons_t)sourcelines,ifile); xputa((cons_t)databytes,ifile); xputa((cons_t)0,ifile); xputa((cons_t)0,ifile); textprocess(tfile,ifile); while ( remtext-- ) xputc(0,ifile) ; dataprocess(dfile,ifile); for (i=0;i<procnum;i++) { xputarb(ptrsize,proctab[i].pr_loc,ifile); xputarb(ptrsize,proctab[i].pr_off,ifile); } if ( fclose(ifile)==EOF ) ; } dataprocess(f1,f2) FILE *f1,*f2; { relc_t datareloc; FOFFSET i; register ieof ; #ifdef CPM fclose(rdfile); rdfile=fopen("RDFILE.$$$, "r"); #else rdfile=frewind(rdfile) ; #endif ieof=getblk(rdfile,(char *)(&datareloc.r_off), sizeof datareloc - sizeof datareloc.r_next) ; for (i=0 ; i<dataoff && !ieof ; i++) { if (i==datareloc.r_off) { switch(datareloc.r_typ) { case RELADR: xputa(xgeta(f1)+datareloc.r_val.rel_i,f2) ; i += ptrsize-1 ; break ; case RELGLO: if (datareloc.r_val.rel_gp->g_status&DEF) { xputa(xgeta(f1)+ datareloc.r_val.rel_gp->g_val.g_addr, f2); i+= ptrsize-1 ; break ; } if ( unresolved == 0 ) fatal("Definition botch") ; case RELHEAD: xputc((int)(xgetc(f1)+datareloc.r_val.rel_i), f2); break; default: fatal("Bad r_typ in dataprocess"); } ieof=getblk(rdfile,(char *)(&datareloc.r_off), sizeof datareloc - sizeof datareloc.r_next) ; } else xputc(xgetc(f1),f2); } for ( ; i<dataoff ; i++ ) xputc(xgetc(f1),f2) ; if ( !ieof && !getblk(rdfile,(char *)&datareloc,1) ) fatal("data relocation botch") ; } textprocess(f1,f2) FILE *f1,*f2; { relc_t textreloc; cons_t n; FOFFSET i; FILE *otfile ; int insl ; register int ieof ; char *op_curr ; register FOFFSET keep ; #ifdef CPM fclose(rtfile); rtfile=fopen("RTFILE.$$$, "r"); #else rtfile=frewind(rtfile) ; #endif keep = textoff ; textoff=0 ; otfile=tfile ; tfile=f2 ; /* This redirects the output of genop */ ieof=getblk(rtfile,(char *)(&textreloc.r_off), sizeof textreloc - sizeof textreloc.r_next) ; for(i=0;i<keep && !ieof ;i++) { if( i == textreloc.r_off ) { if (textreloc.r_typ&RELMNS) { n=textreloc.r_val.rel_i; } else { if (textreloc.r_val.rel_gp->g_status&DEF) { n=textreloc.r_val.rel_gp->g_val.g_addr; } else { if ( unresolved==0 ) fatal("Definition botch") ; xputc(xgetc(f1),f2) ; ieof=getblk(rtfile,(char *)(&textreloc.r_off), sizeof textreloc-sizeof textreloc.r_next); continue ; } } op_curr = &opchoice[textreloc.r_typ& ~RELMNS] ; insl = oplength(*op_curr) ; genop(op_curr, n+xgetarb(insl,f1), PAR_G); i += insl-1 ; ieof=getblk(rtfile,(char *)(&textreloc.r_off), sizeof textreloc - sizeof textreloc.r_next) ; } else { xputc(xgetc(f1),f2) ; } } for ( ; i<keep ; i++ ) xputc(xgetc(f1),f2) ; if ( !ieof && !getblk(rtfile,(char *)&textreloc,1) ) fatal("text relocation botch") ; textoff = keep ; tfile = otfile ; } upd_reloc() { register relc_t *p; register glob_t *gbp; /* * Change reloc-tables such that for every pointer into mglobs * either the corresponding pointer into xglobs or its value * is substituted. * * Use is made of the known order of mglobs and xglobs * see also getcore() */ while ( p= f_text ) { gbp= p->r_val.rel_gp ; if( gbp->g_status&DEF ) { p->r_typ |= RELMNS; p->r_val.rel_i = gbp->g_val.g_addr; } else p->r_val.rel_gp = gbp->g_val.g_gp; putblk(rtfile,(char *)(&(p->r_off)),sizeof *p - sizeof p) ; f_text= p->r_next ; freearea( (area_t) p , sizeof *p ) ; } while( p= f_data ) { if (p->r_typ == RELGLO) { gbp= p->r_val.rel_gp ; if(gbp->g_status&DEF) { p->r_typ = RELADR; p->r_val.rel_i = gbp->g_val.g_addr; } else p->r_val.rel_gp = gbp->g_val.g_gp; } putblk(rdfile,(char *)(&(p->r_off)),sizeof *p - sizeof p) ; f_data= p->r_next ; freearea( (area_t) p , sizeof *p ) ; } l_data= rlp_cast 0 ; }