Annotation of 3BSD/cmd/lisp/rfasl.c, revision 1.1

1.1     ! root        1: #include "global.h"
        !             2: #include <stdio.h>
        !             3: #include <a.out.h>
        !             4: #include "chkrtab.h"
        !             5: 
        !             6: /* rfasl  - really fast loader         j.k.foderaro
        !             7:  * this loader is tuned for the lisp fast loading application
        !             8:  * any changes in the system loading procedure will require changes
        !             9:  * to this file
        !            10:  * Nov 4, 1979 - this now becomes fasl to the lisp world
        !            11:  */
        !            12: 
        !            13: 
        !            14: 
        !            15: /* global variables to keep track of allocation */
        !            16: 
        !            17: int curps ;
        !            18: 
        !            19: /* external functions called or referenced */
        !            20: 
        !            21: int _qf0(), _qf1(), _qf2(), _qf3(), _qf4(), _qfuncl(), svkludg();
        !            22: lispval Lread(), Lcons(), Lminus(), Ladd1(), Lsub1(), Lplist(), Lputprop();
        !            23: lispval Lprint(), Lpatom(), Lconcat(), Lget(), Lmapc(), Lmapcan();
        !            24: lispval Llist(), Ladd(), Lgreaterp(), Lequal(), Ltimes(), Lsub();
        !            25: lispval Lncons();
        !            26: lispval Idothrow(),error();
        !            27: extern lispval *tynames[];
        !            28: extern int errp;
        !            29: extern char _erthrow[];
        !            30: extern char setsav[];
        !            31: 
        !            32: extern int initflag;           /* when TRUE, inhibits gc */
        !            33: /* prelud to linker table in data segment  
        !            34:  * these locations always begin the data segment, if there is any change
        !            35:  * to the compiler, this must be fixed up.
        !            36:  *
        !            37:  */
        !            38: 
        !            39: 
        !            40: #define PRESIZ (8*4)
        !            41: 
        !            42: struct prelud
        !            43: {
        !            44:        int dummy[PRESIZ/4];
        !            45: } prel = {
        !            46:        (int) &bnp,
        !            47:        (int) _qfuncl,
        !            48:        (int) _qf4,
        !            49:        (int) _qf3,
        !            50:        (int) _qf2,
        !            51:        (int) _qf1,
        !            52:        (int) _qf0,
        !            53:        (int) 0 };
        !            54: /* mini symbol table, contains the only external symbols compiled code
        !            55:    is allowed to reference
        !            56:  */
        !            57: 
        !            58: #define SYMMAX 35
        !            59: struct ssym { char *fnam;      /* pointer to string containing name */
        !            60:              int  floc;        /* address of symbol */
        !            61:              int  ord;         /* ordinal number within cur sym tab */
        !            62: 
        !            63:              } symbtb[SYMMAX] 
        !            64:                          = {
        !            65:                             "_Lminus",   (int) Lminus,   -1,
        !            66:                             "_Ladd1",    (int) Ladd1,    -1,
        !            67:                             "_Lsub1",    (int) Lsub1,    -1,
        !            68:                             "_Lplist",   (int) Lplist,   -1,
        !            69:                             "_Lcons",    (int) Lcons,    -1,
        !            70:                             "_Lputpro", (int) Lputprop, -1,
        !            71:                             "_Lprint",   (int) Lprint,   -1,
        !            72:                             "_Lpatom",   (int) Lpatom,   -1,
        !            73:                             "_Lread",    (int) Lread,    -1,
        !            74:                             "_Lconcat",  (int) Lconcat,  -1,
        !            75:                             "_Lget",     (int) Lget,     -1,
        !            76:                             "_Lmapc",    (int) Lmapc,    -1,
        !            77:                             "_Lmapcan",  (int) Lmapcan,  -1,
        !            78:                             "_Llist",    (int) Llist,    -1,
        !            79:                             "_Ladd",     (int) Ladd,     -1,
        !            80:                             "_Lgreate",(int) Lgreaterp,-1,
        !            81:                             "_Lequal",   (int) Lequal,   -1,
        !            82:                             "_Ltimes",   (int) Ltimes,   -1,
        !            83:                             "_Lsub",     (int) Lsub,     -1,
        !            84:                             "_Lncons",   (int) Lncons,   -1,
        !            85:                             "_typetab",  (int) typetab,  -1,
        !            86:                             "_tynames",  (int) tynames,  -1,
        !            87:                             "_errp",     (int) &errp,     -1,
        !            88:                             "_Idothro",  (int) Idothrow, -1,
        !            89:                             "__erthro",  (int) _erthrow,  -1,
        !            90:                             "_error",    (int) error,    -1,
        !            91:                             "_bnp",      (int) &bnp,     -1,
        !            92:                             "__qfuncl",  (int) _qfuncl,  -1,
        !            93:                             "__qf4",     (int) _qf4,     -1,
        !            94:                             "__qf3",     (int) _qf3,     -1,
        !            95:                             "__qf2",     (int) _qf2,     -1,
        !            96:                             "__qf1",     (int) _qf1,     -1,
        !            97:                             "__qf0",     (int) _qf0,     -1,
        !            98:                             "_setsav",   (int) setsav,   -1,
        !            99:                             "_svkludg",  (int) svkludg,  -1
        !           100:                             };
        !           101: 
        !           102: struct nlist syml;             /* to read a.out symb tab */
        !           103: extern lispval *bind_lists;    /* gc binding lists       */
        !           104: 
        !           105: /* bindage structure:
        !           106:  *  the bindage structure describes the linkages of functions and name,
        !           107:  *  and tells which functions should be evaluated.  It is mainly used 
        !           108:  *  for the non-fasl'ing of files, we only use one of the fields in fasl
        !           109:  */
        !           110: struct bindage
        !           111: {
        !           112:      lispval (*b_entry)();             /* function entry point */
        !           113:      int     b_atmlnk;                 /* pointer to string    */
        !           114:      int     b_type;                   /* type code, as described below */
        !           115: };
        !           116: 
        !           117: /* the possible values of b_type
        !           118:  * -1 - this is the end of the bindage entries
        !           119:  * 0  - this is a lambda function
        !           120:  * 1  - this is a nlambda function
        !           121:  * 2  - this is a macro function
        !           122:  * 99 - evaluate the string
        !           123:  *
        !           124:  */
        !           125: 
        !           126: /* maximum number of functions */
        !           127: #define MAXFNS 500             
        !           128: 
        !           129: lispval Lfasl()
        !           130: {
        !           131:        register int orgtx,orgdt,orgps;
        !           132:        register struct argent *svnp, *lbot, *np;
        !           133:        struct exec exblk;      /* stores a.out header */
        !           134:        FILE *filp, *p, *map;   /* file pointer */
        !           135:        int domap;
        !           136:        lispval handy;
        !           137:        struct relocation_info reloc;
        !           138:        struct prelud *ppre;
        !           139:        lispval disp;
        !           140:        int i,j,times, *iptr, oldinitflag;
        !           141:        int  funloc[MAXFNS];    /* addresses of functions rel to txt org */
        !           142:        int funcnt = 0;
        !           143: 
        !           144:                        /* unrelocated start and end of litteral table */
        !           145:        int litstrt = 0 , litend = 0;
        !           146: 
        !           147:        int segdif;
        !           148:        struct bindage *bindorg, *curbind;
        !           149:        int linkerloc, bindloc = 0 , typer,linkstrt,linkend;
        !           150:        lispval rdform, *linktab;
        !           151:        int segsiz;
        !           152:        int debug = 0;
        !           153:        lispval currtab,curibase;
        !           154:        char ch;
        !           155: 
        !           156: 
        !           157:        chkarg(2);
        !           158:        if (TYPE(lbot->val) != ATOM) error("non atom arg",FALSE);
        !           159: 
        !           160:        if ( (filp = fopen((lbot->val)->pname,"r")) == NULL)
        !           161:            errorh(Vermisc,"Can't open file",nil,FALSE,9797,lbot->val);
        !           162: 
        !           163:        domap = FALSE;
        !           164:        if ((handy = (lbot+1)->val) != nil )
        !           165:        {
        !           166:            if((TYPE(handy) != ATOM )   ||
        !           167:               (map = fopen(handy->pname,"w"))  == NULL)
        !           168:                error("rfasl: can't open map file",FALSE);
        !           169:            else 
        !           170:            {   domap = TRUE;
        !           171:                fprintf(map,"Map of file %s\n",lbot->val->pname);
        !           172:            }
        !           173:        }
        !           174: 
        !           175:        printf("[fasl %s]",lbot->val->pname);
        !           176:        fflush(stdout);
        !           177:        svnp = np;
        !           178: 
        !           179:        lbot = np;              /* set up base for later calls */
        !           180: 
        !           181: 
        !           182:        /* clear the ords in the symbol table */
        !           183:        for(i=0 ; i < SYMMAX ; i++) symbtb[i].ord = -1;
        !           184: 
        !           185:        if( fread(&exblk,sizeof(struct exec),1,filp) != 1)
        !           186:          error("Read failed",FALSE);
        !           187:          
        !           188: 
        !           189:        /* read in symbol table and set the ordinal values */
        !           190: 
        !           191:        fseek(filp,
        !           192:              (long)(32+exblk.a_text+exblk.a_data+exblk.a_trsize+exblk.a_drsize)
        !           193:              ,0);
        !           194: 
        !           195:        times = exblk.a_syms/sizeof(struct nlist);
        !           196:        if(debug) printf(" %d symbols in symbol table\n",times);
        !           197: 
        !           198:        for(i=0; i < times ; i++)
        !           199:        {
        !           200:           if( fread(&syml,sizeof(struct nlist),1,filp) != 1)
        !           201: 
        !           202: 
        !           203:               error("Symb tab read error",FALSE);
        !           204:        
        !           205:           if (syml.n_type == N_EXT) 
        !           206:           { 
        !           207:              for(j=0; j< SYMMAX; j++)
        !           208:              {
        !           209:                 if((symbtb[j].ord < 0) 
        !           210:                          && strcmpn(symbtb[j].fnam,syml.n_name,8)==0)
        !           211:                 {    symbtb[j].ord = i;
        !           212:                      if(debug)printf("symbol %s ord is %d\n",syml.n_name,i);
        !           213:                      break;
        !           214:                 };
        !           215: 
        !           216:              };
        !           217: 
        !           218:              if( j>=SYMMAX )  printf("Unknown symbol %s\n",syml.n_name);
        !           219:           }
        !           220:           else if (((ch = syml.n_name[0]) == 's')
        !           221:                     || (ch == 'L')
        !           222:                     || (ch == '.') )  ;                /* skip this */
        !           223:           else if (syml.n_name[0] == 'F')
        !           224:               funloc[funcnt++] = syml.n_value;         /* seeing function */
        !           225:           else if (!bindloc && (strcmp(syml.n_name, "BINDER") == 0))
        !           226:             bindloc = syml.n_value;
        !           227:           else if (strcmp(syml.n_name, "litstrt") == 0)
        !           228:             litstrt = syml.n_value;
        !           229:           else if (strcmp(syml.n_name, "litend") == 0)
        !           230:             litend = syml.n_value;
        !           231:        }
        !           232: 
        !           233:        /* check to make sure we are working with the right format */
        !           234:        if((litstrt == 0) || (litend == 0))
        !           235:           errorh(Vermisc,"File not in new fasl format",nil,FALSE,0,lbot->val);
        !           236: 
        !           237:         /*----------------*/
        !           238: 
        !           239:        /* read in text segment */
        !           240: 
        !           241: 
        !           242:        fseek(filp,(long)32,0);
        !           243:        segsiz = exblk.a_text + exblk.a_data;
        !           244:        if(fread(curps = (int) csegment(int_name,segsiz/sizeof(int))
        !           245:                 ,1,exblk.a_text,filp) != exblk.a_text)
        !           246:            error("Read error in text and data read",FALSE);
        !           247: 
        !           248:        orgtx = curps;
        !           249:        orgdt = curps + exblk.a_text;
        !           250: 
        !           251:        linkstrt = orgdt + PRESIZ;              /* start of linker table */
        !           252:        linkend  = orgdt + exblk.a_data - 4;    /* end of linker table */
        !           253: 
        !           254:        /* the object file is a 410 file and thus has seperate text and
        !           255:           data segments.  The data is assumed to be loaded at the start
        !           256:           of the next PAGSIZ byte boundary, we must calculate the difference
        !           257:           between where the data segment begins and where the loader
        !           258:           thinks it begins.  Caclulate by rounding up the text size and
        !           259:           seeing how much is skipped
        !           260:        */
        !           261:        segdif = ((exblk.a_text + PAGRND) & ~PAGRND) - exblk.a_text;
        !           262:        if(debug) printf("funcs %d, orgtx %x, orgdt %x, linkstrt %x, linkend %x segdif %x",
        !           263:                      funcnt,orgtx,orgdt,linkstrt,linkend,segdif);
        !           264: 
        !           265:        /* set the linker table to all -1's so we can put in the gc table */
        !           266:        for( iptr = (int *)linkstrt ; iptr <= (int *)linkend ; iptr++)
        !           267:          *iptr = -1;
        !           268: 
        !           269:        /* copy in the prelud */
        !           270:        ppre = (struct prelud *) orgdt;         /* use structure to copy */
        !           271:        *ppre = prel;                           /* copy over prelud */
        !           272: 
        !           273:        /* link our table into the gc tables */
        !           274:        *( ((int *)linkstrt) -1) = (int)bind_lists;     /* point to current */
        !           275:        bind_lists = (lispval *) linkstrt;
        !           276: 
        !           277:        /* new relocate the necessary symbols in the text segment */
        !           278: 
        !           279:        orgps = orgtx;
        !           280:        fseek(filp,(long)(32+exblk.a_text+exblk.a_data),0);
        !           281:        times = (exblk.a_trsize)/sizeof(struct relocation_info);
        !           282:                
        !           283:        /* the only symbols we will relocate are references to  lisp
        !           284:           1) functions like _Lcons 
        !           285:           2) the symbol linker in the data segment
        !           286: 
        !           287:          type (1) can be recognized by extern and pcrel, while
        !           288:          type (2) can be recognized by !extern and pcrel and data segment
        !           289:         */
        !           290: 
        !           291:         for( i=1; i<=times ; i++)
        !           292:            {
        !           293:                if( fread(&reloc,sizeof(struct relocation_info),1,filp) != 1)
        !           294:                   error("Bad text reloc read",FALSE);
        !           295:             if(reloc.r_extern && reloc.r_pcrel)
        !           296:             {
        !           297:                for(j=0; j < SYMMAX; j++)
        !           298:                {
        !           299: 
        !           300:                   if(symbtb[j].ord == reloc.r_symbolnum)  /* look for this sym */
        !           301:                    {
        !           302:                      if(debug) printf("Relocating %d (ord %d) at %x\n",
        !           303:                                         j, symbtb[j].ord, reloc.r_address);
        !           304:                            *(int *)(orgps+reloc.r_address) 
        !           305:                               += symbtb[j].floc - orgtx; 
        !           306:                          
        !           307:                            break;
        !           308:                      
        !           309:                          }
        !           310:                 };
        !           311:                 if( j >= SYMMAX) if(debug) printf("Couldnt find ord # %d\n",
        !           312:                                                   reloc.r_symbolnum);
        !           313:             }
        !           314:             else if(!reloc.r_extern && reloc.r_pcrel && 
        !           315:                                     (reloc.r_symbolnum == N_DATA))
        !           316:             {  if(debug) printf("relocing at addr %x \n",reloc.r_address);
        !           317:                *(int *)(orgps + reloc.r_address) -= segdif;
        !           318:             }
        !           319: 
        !           320:            }
        !           321:        
        !           322:         putchar('\n');
        !           323:        fflush(stdout);
        !           324: 
        !           325:        /* set up a fake port so we can read from core */
        !           326:        /* first find a free port                      */
        !           327: 
        !           328:        p = stdin;
        !           329:        for( ; p->_flag & (_IOREAD|_IOWRT) ; p++)
        !           330:           if( p >= _iob + _NFILE)
        !           331:               error(" No free file descriptor for fasl ",FALSE);
        !           332:               
        !           333:        p->_flag = _IOREAD | _IOSTRG;
        !           334:        p->_base = p->_ptr = (char *) (orgtx + litstrt);   /* start at beginning of lit */
        !           335:        p->_cnt = litend - litstrt;
        !           336: 
        !           337:        if(debug)printf("litstrt %d, charstrt  %d\n",litstrt, p->_base);
        !           338:        /* the first forms we wish to read are those literals in the 
        !           339:         * literal table, that is those forms referenced by an offset
        !           340:         * from r8 in  compiled code
        !           341:         */
        !           342: 
        !           343:        /* to read in the forms correctly, we must set up the read table
        !           344:         */
        !           345:        currtab = Vreadtable->clb;
        !           346:        Vreadtable->clb = strtab;               /* standard read table */
        !           347:        curibase = ibase->clb;
        !           348:        ibase->clb = inewint(10);               /* read in decimal */
        !           349: 
        !           350:        linktab = (lispval *)linkstrt;
        !           351: 
        !           352:        oldinitflag = initflag;                 /* remember current val */
        !           353:        initflag = TRUE;                        /* turn OFF gc */
        !           354:        
        !           355:        while (linktab < (lispval *)linkend)
        !           356:        {
        !           357:           np = svnp;
        !           358:           protect(P(p));
        !           359:           handy = Lread();
        !           360:           getc(p);                     /* eat trailing blank */
        !           361:           if(debug)
        !           362:           {   printf("one form read: ");
        !           363:               printr(handy,stdout); fflush(stdout);
        !           364:           }
        !           365:           *linktab++ = handy;
        !           366:        }
        !           367: 
        !           368:        /* now process the binder table, which contains pointers to 
        !           369:           functions to link in and forms to evaluate.
        !           370:        */
        !           371:        bindorg = (struct bindage *) (orgtx + bindloc);
        !           372:        funcnt = 0;
        !           373:        if(debug) printf("binding loc %d, orgin : %d\n",bindloc,bindorg);
        !           374: 
        !           375:        for( curbind = bindorg; curbind->b_type != -1 ; curbind++) 
        !           376:        {
        !           377:            np = svnp;
        !           378:            protect(P(p));
        !           379:            rdform = Lread();
        !           380:            getc(p);                    /* eat trailing null */
        !           381:            protect(rdform);
        !           382:            if(curbind->b_type <= 2)    /* if function type */
        !           383:            { 
        !           384:               handy = newfunct();
        !           385:               rdform->fnbnd = handy;
        !           386:               handy->entry = (lispval (*)())(orgtx + funloc[funcnt++]);
        !           387:               handy->discipline =
        !           388:                  (curbind->b_type == 0 ? lambda :
        !           389:                       curbind->b_type == 1 ? nlambda :
        !           390:                          macro);
        !           391:               if(domap) fprintf(map,"%s\n%x\n",rdform->pname,handy->entry);
        !           392:            }
        !           393:            else {
        !           394:                Vreadtable->clb = currtab;
        !           395:                ibase->clb = curibase;
        !           396: 
        !           397:                eval(rdform);           /* otherwise eval it */
        !           398: 
        !           399:                curibase = ibase->clb;
        !           400:                ibase->clb = inewint(10);
        !           401:                Vreadtable->clb = strtab;
        !           402:           }
        !           403:        };
        !           404:              
        !           405:        p->_flag = 0;                   /* give up file descriptor */
        !           406:        initflag = oldinitflag;         /* restore state of gc */
        !           407:        Vreadtable->clb = currtab;
        !           408:        chkrtab(currtab);
        !           409:        ibase->clb = curibase;
        !           410: 
        !           411:        fclose(filp);
        !           412:        if(domap) fclose(map);
        !           413:        return(tatom);
        !           414: }
        !           415: 

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.