Annotation of 43BSDTahoe/ucb/lisp/franz/fasl.c, revision 1.1.1.1

1.1       root        1: #ifndef lint
                      2: static char *rcsid =
                      3:    "$Header: fasl.c,v 1.11 87/12/14 16:49:06 sklower Exp $";
                      4: #endif
                      5: 
                      6: /*                                     -[Thu Jun  2 21:44:26 1983 by jkf]-
                      7:  *     fasl.c                          $Locker:  $
                      8:  * compiled lisp loader
                      9:  *
                     10:  * (c) copyright 1982, Regents of the University of California
                     11:  */
                     12: 
                     13: #include "global.h"
                     14: #include <sys/types.h>
                     15: #include "lispo.h"
                     16: #include "chkrtab.h"
                     17: #include "structs.h"
                     18: #include "frame.h"
                     19: 
                     20: /* fasl  -  fast loader                                j.k.foderaro
                     21:  * this loader is tuned for the lisp fast loading application
                     22:  * any changes in the system loading procedure will require changes
                     23:  * to this file
                     24:  *
                     25:  *  The format of the object file we read as input:
                     26:  *  text segment:
                     27:  *    1) program text - this comes first.
                     28:  *    2) binder table - one word entries, see struct bindage
                     29:  *                     begins with symbol:  bind_org
                     30:  *    3) litterals - exploded lisp objects. 
                     31:  *                     begins with symbol:  lit_org
                     32:  *                     ends with symbol:    lit_end
                     33:  * data segment:
                     34:  *     not used
                     35:  *
                     36:  *
                     37:  *  these segments are created permanently in memory:
                     38:  *     code segment - contains machine codes to evaluate lisp functions.
                     39:  *     linker segment - a list of pointers to lispvals.  This allows the
                     40:  *                     compiled code to reference constant lisp objects.
                     41:  *                     The first word of the linker segment is a gc link
                     42:  *                     pointer and does not point to a literal.  The
                     43:  *                     symbol binder is assumed to point to the second
                     44:  *                     longword in this segment.  The last word in the
                     45:  *                     table is -1 as a sentinal to the gc marker.
                     46:  *                     The number of real entries in the linker segment 
                     47:  *                     is given as the value of the linker_size symbol.  
                     48:  *                     Taking into account the 2 words required for the
                     49:  *                     gc, there are 4*linker_size + 8 bytes in this segment.
                     50:  *     transfer segment - this is a transfer table block.  It is used to
                     51:  *                     allow compiled code to call other functions 
                     52:  *                     quickly.  The number of entries in the transfer table is
                     53:  *                     given as the value of the trans_size symbol.
                     54:  *
                     55:  *  the following segments are set up in memory temporarily then flushed
                     56:  *     binder segment -  a list of struct bindage entries.  They describe
                     57:  *                     what to do with the literals read from the literal
                     58:  *                     table.  The binder segment begins in the file
                     59:  *                     following the bindorg symbol.
                     60:  *     literal segment - a list of characters which _Lread will read to 
                     61:  *                     create the lisp objects.  The order of the literals
                     62:  *                     is:
                     63:  *                      linker literals - used to fill the linker segment.
                     64:  *                      transfer table literals - used to fill the 
                     65:  *                        transfer segment
                     66:  *                      binder literals - these include names of functions
                     67:  *                        to bind interspersed with forms to evaluate.
                     68:  *                        The meanings of the binder literals is given by
                     69:  *                        the values in the binder segment.
                     70:  *     string segment - this is the string table from the file.  We have
                     71:  *                      to allocate space for it in core to speed up
                     72:  *                      symbol referencing.
                     73:  *
                     74:  */
                     75: 
                     76: 
                     77: /* external functions called or referenced */
                     78: 
                     79: lispval qcons(),qlinker(),qget();
                     80: int _qf0(), _qf1(), _qf2(), _qf3(), _qf4(), _qfuncl(), svkludg(),qnewint();
                     81: int qnewdoub(),qoneplus(),qoneminus(), wnaerr();
                     82: lispval Lread(), Lcons(), Lminus(), Ladd1(), Lsub1(), Lplist(), Lputprop();
                     83: lispval Lprint(), Lpatom(), Lconcat(), Lget(), Lmapc(), Lmapcan();
                     84: lispval Llist(), Ladd(), Lgreaterp(), Lequal(), Ltimes(), Lsub(), Ipurcopy();
                     85: lispval Lncons(), Ibindvars(), Iunbindvars(),error();
                     86: int Inonlocalgo();
                     87: lispval Istsrch();
                     88: int mcount(), qpushframe();
                     89: extern int mcnts[],mcntp,doprof;
                     90: 
                     91: extern lispval *tynames[];
                     92: extern struct frame *errp;
                     93: extern char _erthrow[];
                     94: 
                     95: extern int initflag;           /* when TRUE, inhibits gc */
                     96: 
                     97: char *alloca();                        /* stack space allocator */
                     98: 
                     99: /* mini symbol table, contains the only external symbols compiled code
                    100:    is allowed to reference
                    101:  */
                    102: 
                    103: 
                    104: struct ssym { char *fnam;      /* pointer to string containing name */
                    105:              int  floc;        /* address of symbol */
                    106:              int  ord;         /* ordinal number within cur sym tab */
                    107: 
                    108:              } Symbtb[] 
                    109:                          = {
                    110:                             "trantb",  0,      -1,   /* must be first */
                    111:                             "linker",  0,      -1,   /* must be second */
                    112:                             "mcount",    (int) mcount,   -1,
                    113:                             "mcnts",     (int) mcnts,  -1,
                    114:                             "_wnaerr",   (int) wnaerr, -1,
                    115:                             "_qnewint",   (int) qnewint,  -1,
                    116:                             "_qnewdoub",   (int) qnewdoub,  -1,
                    117:                             "_qcons",    (int) qcons,    -1,
                    118:                             "_qoneplus", (int) qoneplus, -1,
                    119:                             "_qoneminus", (int) qoneminus, -1,
                    120:                             "_typetable",  (int) typetable,  -1,
                    121:                             "_tynames",  (int) tynames,  -1,
                    122:                             "_qget",     (int) qget,     -1,
                    123:                             "_errp",     (int) &errp,          -1,
                    124:                             "_Inonlocalgo",  (int) Inonlocalgo, -1,
                    125:                             "__erthrow",  (int) _erthrow,      -1,
                    126:                             "_error",    (int) error,          -1,
                    127:                             "_qpushframe",  (int) qpushframe,  -1,
                    128:                             "_retval",         (int)&retval,   -1,
                    129:                             "_lispretval",     (int)&lispretval,-1,
                    130: #ifndef NPINREG
                    131:                             "_np",       (int) &np,      -1,
                    132:                             "_lbot",     (int) &lbot,    -1,
                    133: #endif
                    134: #ifndef NILIS0
                    135:                             "_nilatom",  (int) &nilatom, -1,
                    136: #endif
                    137:                             "_bnp",      (int) &bnp,     -1,
                    138:                             "_Ibindvars", (int) Ibindvars, -1,
                    139:                             "_Iunbindvars", (int) Iunbindvars, -1
                    140:                             };
                    141: 
                    142: #define SYMMAX ((sizeof Symbtb) / (sizeof (struct ssym)))
                    143: 
                    144: #define roundup(x) (char *)(((int)x + 3) & ~3) /* round to longword boundary */
                    145: 
                    146: struct nlist syml;             /* to read a.out symb tab */
                    147: extern int *bind_lists;                /* gc binding lists       */
                    148: 
                    149: /* bindage structure:
                    150:  *  the bindage structure describes the linkages of functions and name,
                    151:  *  and tells which functions should be evaluated.  It is mainly used 
                    152:  *  for the non-fasl'ing of files, we only use one of the fields in fasl
                    153:  */
                    154: struct bindage
                    155: {
                    156:      int     b_type;                   /* type code, as described below */
                    157: };
                    158: 
                    159: /* the possible values of b_type
                    160:  * -1 - this is the end of the bindage entries
                    161:  * 0  - this is a lambda function
                    162:  * 1  - this is a nlambda function
                    163:  * 2  - this is a macro function
                    164:  * 99 - evaluate the string
                    165:  *
                    166:  */
                    167: 
                    168: 
                    169: extern struct trtab *trhead;   /* head of list of transfer tables          */
                    170: extern struct trent *trcur;    /* next entry to allocate                   */
                    171: extern int trleft;             /* # of entries left in this transfer table */
                    172: 
                    173: struct trent *gettran();       /* function to allocate entries */
                    174: 
                    175: /* maximum number of functions */
                    176: #define MAXFNS 2000
                    177: 
                    178: lispval Lfasl()
                    179: {
                    180:        extern int holend,usehole;
                    181:        extern int uctolc;
                    182:        extern char *curhbeg;
                    183:        struct argent *svnp;
                    184:        struct exec exblk;      /* stores a.out header */
                    185:        FILE *filp, *p, *map, *fstopen();       /* file pointer */
                    186:        int domap,note_redef;
                    187:        lispval handy,debugmode;
                    188:        struct relocation_info reloc;
                    189:        struct trent *tranloc;
                    190:        int trsize;
                    191:        int i,j,times, *iptr;
                    192:        int  funloc[MAXFNS];    /* addresses of functions rel to txt org */
                    193:        int funcnt = 0;
                    194: 
                    195:        /* symbols whose values are taken from symbol table of .o file */
                    196:        int bind_org = 0;               /* beginning of bind table */
                    197:        int lit_org = 0;        /* beginning of literal table */
                    198:        int lit_end;            /* end of literal table  */
                    199:        int trans_size = 0;     /* size in entries of transfer table */
                    200:        int linker_size;        /* size in bytes   of linker table 
                    201:                                        (not counting gc ptr) */
                    202: 
                    203:        /* symbols which hold the locations of the segments in core and 
                    204:        * in the file
                    205:        */
                    206:        char *code_core_org,    /* beginning of code segment */
                    207:             *lc_org,  /* beginning of linker segment */
                    208:             *lc_end,  /* last word in linker segment */
                    209:             *literal_core_org, /* beginning of literal table   */
                    210:             *binder_core_org,  /* beginning of binder table   */
                    211:             *string_core_org;
                    212: 
                    213:        int /*string_file_org,  /* location of string table in file */
                    214:            string_size,        /* number of chars in string table */
                    215:            segsiz;             /* size of permanent incore segment */
                    216: 
                    217:        char *symbol_name;
                    218:        struct bindage *curbind;
                    219:        lispval rdform, *linktab;
                    220:        int ouctolc;
                    221:        int debug = 0;
                    222:        lispval currtab,curibase;
                    223:        char ch,*filnm,*nfilnm;
                    224:        char tempfilbf[100];
                    225:        char *strcat();
                    226:        long lseek();
                    227:        Keepxs();
                    228:        
                    229: 
                    230:        switch(np-lbot) {
                    231:        case 0:
                    232:                protect(nil);
                    233:        case 1:
                    234:                protect(nil);
                    235:        case 2:
                    236:                protect(nil);
                    237:        case 3:
                    238:                break;
                    239:        default:
                    240:                argerr("fasl");
                    241:        }
                    242:        filnm = (char *) verify(lbot->val,"fasl: non atom arg");
                    243: 
                    244: 
                    245:        domap = FALSE;
                    246:        /* debugging */
                    247:        debugmode = Istsrch(matom("debugging"))->d.cdr->d.cdr->d.cdr;
                    248:        if (debugmode != nil) debug = 1;
                    249:         /* end debugging */
                    250: 
                    251: 
                    252:        /* insure that the given file name ends in .o
                    253:           if it doesnt, copy to a new buffer and add a .o
                    254:           but Allow non .o file names (5mar80 jkf)
                    255:        */
                    256:        tempfilbf[0] = '\0';
                    257:        nfilnm = filnm;         /* same file name for now */
                    258:        if( (i = strlen(filnm)) < 2 ||
                    259:             strcmp(filnm+i-2,".o") != 0)
                    260:        {
                    261:                strncat(tempfilbf,filnm,96);
                    262:                strcat(tempfilbf,".o");
                    263:                nfilnm = tempfilbf;
                    264:        }
                    265: 
                    266:        if ( (filp = fopen(nfilnm,"r")) == NULL)
                    267:           if ((filnm == nfilnm) || ((filp = fopen(filnm,"r")) == NULL))
                    268:               errorh1(Vermisc,"Can't open file",nil,FALSE,9797,lbot->val);
                    269: 
                    270:        if ((handy = (lbot+1)->val) != nil )
                    271:        {
                    272:            if((TYPE(handy) != ATOM )   ||
                    273:               (map = fopen(handy->a.pname,
                    274:                            (Istsrch(matom("appendmap"))->d.cdr->d.cdr->d.cdr == nil 
                    275:                                    ? "w" : "a")))  == NULL)
                    276:                error("fasl: can't open map file",FALSE);
                    277:            else 
                    278:            {   domap = TRUE;
                    279:                /* fprintf(map,"Map of file %s\n",lbot->val->a.pname); */
                    280:            }
                    281:        }
                    282: 
                    283:        /* set the note redefinition flag */
                    284:        if((lbot+2)->val != nil) note_redef = TRUE;
                    285:        else    note_redef = FALSE;
                    286: 
                    287:        /* if nil don't print fasl message */
                    288:        if ( Vldprt->a.clb != nil ) {
                    289:                printf("[fasl %s]",filnm);
                    290:                fflush(stdout);
                    291:        }
                    292:        svnp = np;
                    293: 
                    294: 
                    295: 
                    296:        /* clear the ords in the symbol table */
                    297:        for(i=0 ; i < SYMMAX ; i++) Symbtb[i].ord = -1;
                    298: 
                    299:        if( read(fileno(filp),(char *)&exblk,sizeof(struct exec)) 
                    300:                != sizeof(struct exec))
                    301:          error("fasl: header read failed",FALSE);
                    302:          
                    303:        /* check that the magic number is valid */
                    304: 
                    305:        if(exblk.a_magic != 0407)
                    306:           errorh1(Vermisc,"fasl: file is not a lisp object file (bad magic number): ",
                    307:                nil,FALSE,0,lbot->val);
                    308: 
                    309:        /* read in string table */
                    310:        lseek(fileno(filp),(long)(/*string_file_org =*/N_STROFF(exblk)),0);
                    311:        if( read(fileno(filp), (char *)&string_size , 4) != 4)
                    312:          error("fasl: string table read error, probably old fasl format", FALSE);
                    313:        
                    314:        lbot = np;              /* set up base for later calls */
                    315:         /* allocate space for string table on the stack */
                    316:        string_core_org = alloca(string_size - 4);
                    317: 
                    318:        if( read(fileno(filp), string_core_org , string_size - 4)
                    319:                != string_size -4) error("fasl: string table read error ",FALSE);
                    320:        /* read in symbol table and set the ordinal values */
                    321: 
                    322:        fseek(filp,(long) (N_SYMOFF(exblk)),0);
                    323: 
                    324:        times = exblk.a_syms/sizeof(struct nlist);
                    325:        if(debug) printf(" %d symbols in symbol table\n",times);
                    326: 
                    327:        for(i=0; i < times ; i++)
                    328:        {
                    329:           if( fread((char *)&syml,sizeof(struct nlist),1,filp) != 1)
                    330:               error("fasl: Symb tab read error",FALSE);
                    331:        
                    332:           symbol_name = syml.n_un.n_strx - 4 + string_core_org;
                    333:           if(debug) printf("symbol %s\n read\n",symbol_name);
                    334:           if (syml.n_type == N_EXT) 
                    335:           { 
                    336:              for(j=0; j< SYMMAX; j++)
                    337:              {
                    338:                 if((Symbtb[j].ord < 0) 
                    339:                          && strcmp(Symbtb[j].fnam,symbol_name)==0)
                    340:                 {    Symbtb[j].ord = i;
                    341:                      if(debug)printf("symbol %s ord is %d\n",symbol_name,i);
                    342:                      break;
                    343:                 };
                    344: 
                    345:              };
                    346: 
                    347:              if( j>=SYMMAX )  printf("Unknown symbol %s\n",symbol_name);
                    348:           }
                    349:           else if (((ch = symbol_name[0]) == 's')
                    350:                     || (ch == 'L')
                    351:                     || (ch == '.') )  ;                /* skip this */
                    352:           else if (symbol_name[0] == 'F')
                    353:           {
                    354:               if(funcnt >= MAXFNS)
                    355:                        error("fasl: too many function in file",FALSE);
                    356:               funloc[funcnt++] = syml.n_value;         /* seeing function */
                    357:           }
                    358:           else if (!bind_org && (strcmp(symbol_name, "bind_org") == 0))
                    359:             bind_org = syml.n_value;
                    360:           else if (strcmp(symbol_name, "lit_org") == 0)
                    361:             lit_org = syml.n_value;
                    362:           else if (strcmp(symbol_name, "lit_end") == 0)
                    363:             lit_end = syml.n_value;
                    364:           else if (strcmp(symbol_name, "trans_size") == 0)
                    365:             trans_size = syml.n_value;
                    366:           else if (strcmp(symbol_name, "linker_size") == 0)
                    367:             linker_size = syml.n_value;
                    368:        }
                    369: 
                    370: #if m_68k
                    371:        /* 68k only, on the vax the symbols appear in the correct order */
                    372:        { int compar();
                    373:          qsort(funloc,funcnt,sizeof(int),compar);
                    374:        }
                    375: #endif
                    376: 
                    377:        if (debug)
                    378:          printf("lit_org %x,  lit_end %x, bind_org %x, linker_size %x\n",
                    379:                lit_org, lit_end, bind_org, linker_size);
                    380:        /* check to make sure we are working with the right format */
                    381:        if((lit_org == 0) || (lit_end == 0))
                    382:           errorh1(Vermisc,"File not in new fasl format",nil,FALSE,0,lbot->val);
                    383: 
                    384:         /*----------------*/
                    385: 
                    386:        /* read in text segment  up to beginning of binder table */
                    387: 
                    388:        segsiz = bind_org + 4*linker_size + 8 + 3; /* size is core segment size
                    389:                                                 * plus linker table size
                    390:                                                 * plus 2 for gc list
                    391:                                                 * plus 3 to round up to word
                    392:                                                 */
                    393: 
                    394:        lseek(fileno(filp),(long)sizeof(struct exec),0);
                    395:        code_core_org = (char *) csegment(OTHER,segsiz,TRUE);
                    396:        if(read(fileno(filp),code_core_org,bind_org) != bind_org)
                    397:            error("Read error in text ",FALSE);
                    398: 
                    399:   if(debug) {
                    400:        printf("Read %d bytes of text into 0x%x\n",bind_org,code_core_org);
                    401:         printf(" incore segment size: %d (0x%x)\n",segsiz,segsiz);
                    402:         }
                    403:         
                    404:        /* linker table is 2 entries (8 bytes) larger than the number of
                    405:         * entries given by linker_size .  There must be a gc word at
                    406:         * the beginning and a -1 at the end
                    407:         */
                    408:        lc_org = roundup(code_core_org + bind_org);
                    409:        lc_end = lc_org + 4*linker_size + 4; 
                    410:                                        /* address of gc sentinal last */
                    411: 
                    412:        if(debug)printf("lin_cor_org: %x, link_cor_end %x\n",
                    413:                                      lc_org,
                    414:                                      lc_end);
                    415:        Symbtb[1].floc = (int) (lc_org + 4);
                    416: 
                    417:        /* set the linker table to all -1's so we can put in the gc table */
                    418:        for( iptr = (int *)(lc_org + 4 ); 
                    419:             iptr <= (int *)(lc_end); 
                    420:             iptr++)
                    421:          *iptr = -1;
                    422: 
                    423: 
                    424:        /* link our table into the gc tables */
                    425:        /* only do so if we will not purcopy these tables */
                    426:        if(Vpurcopylits->a.clb == nil)
                    427:        {
                    428:            *(int *)lc_org = (int)bind_lists;   /* point to current */
                    429:            bind_lists = (int *) (lc_org + 4); /* point to first
                    430:                                                                item */
                    431:        }
                    432: 
                    433:        /* read the binder table and literals onto the stack */
                    434: 
                    435:        binder_core_org =  alloca(lit_end - bind_org);
                    436:        read(fileno(filp),binder_core_org,lit_end-bind_org);
                    437: 
                    438:        literal_core_org = binder_core_org + lit_org - bind_org;
                    439: 
                    440:        /* check if there is a transfer table required for this
                    441:         * file, and if so allocate one of the necessary size
                    442:         */
                    443: 
                    444:        if(trans_size > 0)
                    445:        {
                    446:            tranloc = gettran(trans_size);
                    447:            Symbtb[0].floc = (int) tranloc;
                    448:        }
                    449: 
                    450:        /* now relocate the necessary symbols in the text segment */
                    451: 
                    452:        fseek(filp,(long)(sizeof(struct exec) + exblk.a_text + exblk.a_data),0);
                    453:        times = (exblk.a_trsize)/sizeof(struct relocation_info);
                    454:                
                    455:        /* the only symbols we will relocate are references to  
                    456:                external symbols.  They are recognized by 
                    457:                extern and pcrel set.
                    458:         */
                    459: 
                    460:         for( i=1; i<=times ; i++)
                    461:            {
                    462:                if( fread((char *)&reloc,sizeof(struct relocation_info),1,filp) != 1)
                    463:                   error("Bad text reloc read",FALSE);
                    464:             if(reloc.r_extern)
                    465:             {
                    466:                for(j=0; j < SYMMAX; j++)
                    467:                {
                    468: 
                    469:                   if(Symbtb[j].ord == reloc.r_symbolnum)  /* look for this sym */
                    470:                    {
                    471: #define offset(p) (((p).r_pcrel) ? ((int) code_core_org): 0)
                    472:                      if(debug) printf("Relocating %d (ord %d) at %x\n",
                    473:                                         j, Symbtb[j].ord, reloc.r_address);
                    474:                        if (Symbtb[j].floc == (int)  mcnts) {
                    475:                            add_offset((int *)(code_core_org + reloc.r_address),
                    476:                                        mcntp - offset(reloc)); 
                    477:                            if(doprof){
                    478:                             if (mcntp == (int) &mcnts[NMCOUNT-2])
                    479:                                printf("Ran out of counters; increas NMCOUNT in fasl.c\n");
                    480:                             if (mcntp < (int) &mcnts[NMCOUNT-1])
                    481:                                mcntp += 4;
                    482:                            }
                    483:                        } else
                    484:                            add_offset((int *)(code_core_org + reloc.r_address),
                    485:                                        Symbtb[j].floc - offset(reloc)); 
                    486:                          
                    487:                        break;
                    488:                      
                    489:                      }
                    490:                 };
                    491:                 if( j >= SYMMAX) if(debug) printf("Couldnt find ord # %d\n",
                    492:                                                   reloc.r_symbolnum);
                    493:             }
                    494: 
                    495:            }
                    496:        
                    497:        if ( Vldprt->a.clb != nil ) {
                    498:                putchar('\n');
                    499:                fflush(stdout);
                    500:        }
                    501: 
                    502:        /* set up a fake port so we can read from core */
                    503:        /* first find a free port                      */
                    504: 
                    505:        p = fstopen((char *) literal_core_org, lit_end - lit_org, "r");
                    506: 
                    507:        if(debug)printf("lit_org %d, charstrt  %d\n",lit_org, p->_base);
                    508:        /* the first forms we wish to read are those literals in the 
                    509:         * literal table, that is those forms referenced by an offset
                    510:         * from r8 in  compiled code
                    511:         */
                    512: 
                    513:        /* to read in the forms correctly, we must set up the read table
                    514:         */
                    515:        currtab = Vreadtable->a.clb;
                    516:        Vreadtable->a.clb = strtab;             /* standard read table */
                    517:        curibase = ibase->a.clb;
                    518:        ibase->a.clb = inewint(10);             /* read in decimal */
                    519:        ouctolc = uctolc;       /* remember value of uctolc flag */
                    520: 
                    521:        PUSHDOWN(gcdis,tatom);                  /* turn off gc */
                    522: 
                    523:        i = 1;  
                    524:        linktab = (lispval *)(lc_org +4);
                    525:        while (linktab < (lispval *)lc_end)
                    526:        {
                    527:           np = svnp;
                    528:           protect(P(p));
                    529:           uctolc = FALSE;
                    530:           handy = (lispval)Lread();
                    531:           if (Vpurcopylits->a.clb != nil) {
                    532:                handy = Ipurcopy(handy);
                    533:           }
                    534:           uctolc = ouctolc;
                    535:           getc(p);                     /* eat trailing blank */
                    536:           if(debugmode != nil)
                    537:           {   printf("form %d read: ",i++);
                    538:               printr(handy,stdout); 
                    539:               putchar('\n');
                    540:               fflush(stdout);
                    541:           }
                    542:           *linktab++ = handy;
                    543:        }
                    544: 
                    545:        /* process the transfer table if one is used            */
                    546:        trsize = trans_size;
                    547:        while(trsize--)
                    548:        {
                    549:            np = svnp;
                    550:            protect(P(p));
                    551:            uctolc = FALSE;
                    552:            handy = Lread();        /* get function name */
                    553:            uctolc = ouctolc;
                    554:            getc(p);
                    555:            tranloc->name = handy;
                    556:            tranloc->fcn = qlinker;     /* initially go to qlinker */
                    557:            tranloc++;
                    558:        }
                    559: 
                    560: 
                    561: 
                    562:        /* now process the binder table, which contains pointers to 
                    563:           functions to link in and forms to evaluate.
                    564:        */
                    565:        funcnt = 0;
                    566: 
                    567:        curbind = (struct bindage *) binder_core_org;
                    568:        for( ; curbind->b_type != -1 ; curbind++) 
                    569:        {
                    570:            np = svnp;
                    571:            protect(P(p));
                    572:            uctolc = FALSE;             /* inhibit uctolc conversion */
                    573:            rdform = Lread();
                    574:            /* debugging */
                    575:            if(debugmode != nil) { printf("link form read: ");
                    576:                        printr(rdform,stdout);
                    577:                        printf("  ,type: %d\n",
                    578:                                 curbind->b_type);
                    579:                        fflush(stdout);
                    580:                      }
                    581:            /* end debugging */
                    582:            uctolc = ouctolc;           /* restore previous state */
                    583:            getc(p);                    /* eat trailing null */
                    584:            protect(rdform);
                    585:            if(curbind->b_type <= 2)    /* if function type */
                    586:            { 
                    587:               handy = newfunct();
                    588:               if (note_redef && (rdform->a.fnbnd != nil))
                    589:               {
                    590:                   printr(rdform,stdout);
                    591:                   printf(" redefined\n");
                    592:               }
                    593:               rdform->a.fnbnd = handy;
                    594:               handy->bcd.start = (lispval (*)())(code_core_org + funloc[funcnt++]);
                    595:               handy->bcd.discipline =
                    596:                  (curbind->b_type == 0 ? lambda :
                    597:                       curbind->b_type == 1 ? nlambda :
                    598:                          macro);
                    599:               if(domap) {
                    600:                   fprintf(map,"%s\n%x\n",rdform->a.pname,handy->bcd.start);
                    601:               }
                    602:            }
                    603:            else {
                    604:                Vreadtable->a.clb = currtab;
                    605:                ibase->a.clb = curibase;
                    606: 
                    607:                /* debugging */
                    608:                if(debugmode != nil) {
                    609:                        printf("Eval: ");
                    610:                        printr(rdform,stdout);
                    611:                        printf("\n");
                    612:                        fflush(stdout);
                    613:                };
                    614:                /* end debugging */
                    615: 
                    616:                eval(rdform);           /* otherwise eval it */
                    617: 
                    618:                if(uctolc) ouctolc = TRUE; /* if changed by eval, remember */
                    619:                curibase = ibase->a.clb;
                    620:                ibase->a.clb = inewint(10);
                    621:                Vreadtable->a.clb = strtab;
                    622:           }
                    623:        };
                    624:              
                    625:        fclose(p);      /* give up file descriptor */
                    626: 
                    627:        POP;                    /* restore state of gcdisable variable */
                    628: 
                    629:        Vreadtable->a.clb = currtab;
                    630:        chkrtab(currtab);
                    631:        ibase->a.clb = curibase;
                    632: 
                    633:        fclose(filp);
                    634:        if(domap) fclose(map);
                    635:        Freexs();
                    636:        return(tatom);
                    637: }
                    638: 
                    639: #if m_68k
                    640: /* function used in qsort for 68k version only */
                    641: compar(arg1,arg2)
                    642: int *arg1,*arg2;
                    643: {
                    644:        if(*arg1 < *arg2) return (-1);
                    645:         else if (*arg1 == *arg2) return (0);
                    646:        else return(1);
                    647: }
                    648: #endif
                    649: 
                    650: /* gettran :: allocate a segment of transfer table of the given size   */
                    651: 
                    652: struct trent *
                    653: gettran(size)
                    654: {
                    655:        struct trtab *trp;
                    656:        struct trent *retv;
                    657:        int ousehole;
                    658:        extern int usehole;
                    659: 
                    660:        if(size > TRENTS)
                    661:          error("transfer table too large",FALSE);
                    662:        
                    663:        if(size > trleft)
                    664:        {
                    665:            /* allocate a new transfer table */
                    666:            /* must not allocate in the hole or we cant modify it */
                    667:            ousehole = usehole; /* remember old value */
                    668:            usehole = FALSE;
                    669:            trp = (struct trtab *)csegment(OTHER,sizeof(struct trtab),FALSE);
                    670:            usehole = ousehole;
                    671: 
                    672:            trp->sentinal = 0;          /* make sure the sentinal is 0 */
                    673:            trp->nxtt = trhead; /* link at beginning of table  */
                    674:            trhead = trp;
                    675:            trcur = &(trp->trentrs[0]); /* begin allocating here        */
                    676:            trleft = TRENTS;
                    677:        }
                    678: 
                    679:        trleft = trleft - size;
                    680:        retv = trcur;
                    681:        trcur = trcur + size;
                    682:        return(retv);
                    683: }
                    684: 
                    685: /* clrtt :: clear transfer tables, or link them all up;
                    686:  * this has two totally opposite functions:
                    687:  * 1) all transfer tables are reset so that all function calls will go
                    688:  * through qlinker
                    689:  * 2) as many transfer tables are set up to point to bcd functions
                    690:  *    as possible
                    691:  */
                    692: clrtt(flag)
                    693: {
                    694:        /*  flag = 0 :: set to qlinker
                    695:         *  flag = 1 :: set to function bcd binding if possible
                    696:         */
                    697:        register struct trtab *temptt;
                    698:        register struct trent *tement;
                    699:        register lispval fnb;
                    700: 
                    701:        for (temptt = trhead; temptt != 0 ; temptt = temptt->nxtt)
                    702:        { 
                    703:            for(tement = &temptt->trentrs[0] ; tement->fcn != 0 ; tement++)
                    704:            {   if(flag == 0 || TYPE(fnb=tement->name->a.fnbnd) != BCD
                    705:                             || TYPE(fnb->bcd.discipline) == STRNG)
                    706:                tement->fcn =  qlinker;
                    707:                else tement->fcn = fnb->bcd.start;
                    708:            }
                    709:        }
                    710: }
                    711: 
                    712: /* chktt - builds a list of transfer table entries which don't yet have
                    713:   a function associated with them, i.e if this transfer table entry
                    714:   were used, an undefined function error would result
                    715:  */
                    716: lispval 
                    717: chktt()
                    718: {
                    719:        register struct trtab *temptt;
                    720:        register struct trent *tement;
                    721:        register lispval retlst,curv;
                    722:        Savestack(4);
                    723: 
                    724:        retlst = newdot();              /* build list of undef functions */
                    725:        protect(retlst);
                    726:        for (temptt = trhead; temptt != 0 ; temptt = temptt->nxtt)
                    727:        { 
                    728:             for(tement = &temptt->trentrs[0] ; tement->fcn != 0 ; tement++)
                    729:            {
                    730:               if(tement->name->a.fnbnd == nil)
                    731:               {
                    732:                  curv= newdot();
                    733:                  curv->d.car = tement->name;
                    734:                  curv->d.cdr = retlst->d.cdr;
                    735:                  retlst->d.cdr = curv;
                    736:                }
                    737:             }
                    738:         }
                    739:         Restorestack();
                    740:         return(retlst->d.cdr);
                    741: }
                    742: 
                    743: /* since the tahoe machine is picky about word/longword alignment
                    744: ** when it is doing data access but not when doing instruction fetches,
                    745: ** we have to add the relocation offset in a slightly different manner.
                    746: */
                    747: #ifdef tahoe
                    748: add_offset(addr, relocoffset)
                    749: register int *addr;
                    750: {register int r11, r10, r9, r8;
                    751:  asm(" cvtbl   (r12), r0");
                    752:  asm(" cvtbl   8(fp), r1");
                    753:  asm(" cvtbl   1(r12), r8");
                    754:  asm(" cvtbl   9(fp), r9");
                    755:  asm(" cvtbl   2(r12), r10");
                    756:  asm(" cvtbl   10(fp), r11");
                    757:  asm(" addb2   11(fp), 3(r12)");       /* add least sig. bytes */
                    758:  asm(" adwc    r11, r10");
                    759:  asm(" adwc    r9, r8");
                    760:  asm(" adwc    r1, r0");
                    761:  asm(" cvtlb   r10, 2(r12)");
                    762:  asm(" cvtlb   r8, 1(r12)");
                    763:  asm(" cvtlb   r0,(r12)");
                    764: }
                    765: #else
                    766: add_offset(addr, relocoffset)
                    767: register int *addr;
                    768: {
                    769:  *addr += relocoffset;
                    770: }
                    771: #endif

unix.superglobalmegacorp.com

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