Annotation of coherent/d/bin/load/main.c, revision 1.1.1.1

1.1       root        1: /* ld/main.c */
                      2: 
                      3: #include "data.h"
                      4: 
                      5: extern char    *mktemp();
                      6: 
                      7: main( argc, argv )
                      8: int    argc;
                      9: char   *argv[];
                     10: {
                     11:        flag_t  dcomm = 0,              /* define commons even if reloc out */
                     12:                nosym = 0,              /* do not output symbol table */
                     13:                memld = 0,              /* do in-memory load */
                     14:                reloc = 0;              /* output relocation info */
                     15:        char    *ofname = "l.out",
                     16:                *entrys = NULL,
                     17:                *mfn,
                     18:                *lp;
                     19:        seg_t   *sgp;
                     20:        sym_t   *sp;
                     21:        mod_t   *mp;
                     22:        FILE    *ofp;
                     23:        struct  stat    statbuf;
                     24:        int     i, segn;
                     25:        unsigned int    symno;
                     26:        fsize_t daddr;
                     27:        uaddr_t addr;
                     28: #if BREADBOX
                     29:        int     abort();
                     30: #endif
                     31: 
                     32:        setbuf( stdout, NULL );
                     33:        setbuf( stderr, NULL );
                     34: 
                     35:        /*
                     36:         * set separate code/data flag (required for 286 protected mode)
                     37:         */
                     38:        oldh.l_flag |= LF_SEP;
                     39: 
                     40:        nmod = mxmsym = mdisk = 0;
                     41: 
                     42:        if ( argc <= 1 )
                     43:                usage( "no args" );
                     44: 
                     45:        /*
                     46:         * Pass 1: Scan argument list.
                     47:         */
                     48:        for ( i = 1; i < argc; i++ ) {
                     49: 
                     50:                /*
                     51:                 * Not -option; attempt to read file
                     52:                 */
                     53:                if ( *argv[i] != '-' ) {
                     54:                        if ( !rdfile(argv[i]) )
                     55:                                fatal( "can't open %s", argv[i] );
                     56:                }
                     57: 
                     58:                /*
                     59:                 * Decode options
                     60:                 */
                     61:                else switch ( argv[i][1] ) {
                     62: 
                     63:                default:
                     64:                        usage( "unknown option %s", argv[i] );
                     65:                        continue;
                     66: 
                     67:                case 'b':
                     68:                        /*
                     69:                         * -b: undocumented option
                     70:                         *      big link stores module structs on disk
                     71:                         */
                     72:                        mdisk++;
                     73: 
                     74:                        if ( (mfp = fopen(mfn=mktemp("/tmp/ldXXXXXX"),"wr") )
                     75:                           ==NULL) {
                     76:                                unlink( mfn );
                     77:                                fatal( "can't open temp file" );
                     78:                        }
                     79: 
                     80:                        mtemp = malloc( sizeof(mod_t) );
                     81:                        continue;
                     82: 
                     83:                case 'd':
                     84:                        /*
                     85:                         * -d: Define commons (even if undefined symbols).
                     86:                         */
                     87:                        dcomm++;
                     88:                        continue;
                     89: 
                     90:                case 'e':
                     91:                        /*
                     92:                         * -e ent: Set entry point to given symbol/octal number.
                     93:                         */
                     94:                        if ( ++i >= argc )
                     95:                                usage( "Bad -e option" );
                     96: 
                     97:                        else {
                     98:                                undef( argv[i] );
                     99:                                entrys = argv[i];
                    100:                        }
                    101:                        continue;
                    102: 
                    103:                case 'i':
                    104:                        continue;
                    105: 
                    106:                case 'k':
                    107:                        /*
                    108:                         * -k[sys]: Kernel process - use system symbol table.
                    109:                         */
                    110:                        oldh.l_flag |= LF_KER;
                    111: 
                    112:                        if ( argv[i][2] != '\0' )
                    113:                                rdsystem( &argv[i][2] );
                    114:                        else
                    115:                                rdsystem( "/coherent" );
                    116:                        continue;
                    117: 
                    118:                case 'l':
                    119:                        /*
                    120:                         * -l<lib>: Use standard library <lib>.
                    121:                         */
                    122:                        lp = malloc( strlen(argv[i])+16 );
                    123:                        sprintf( lp, "/lib/lib%s.a", &argv[i][2] );
                    124: 
                    125:                        if ( rdfile(lp) )
                    126:                                ;
                    127: 
                    128:                        else {
                    129:                                sprintf( lp, "/usr/lib/lib%s.a", &argv[i][2] );
                    130:                                if ( rdfile(lp) )
                    131:                                        ;
                    132:                                else
                    133:                                        fatal(  "can't open lib%s.a",
                    134:                                                &argv[i][2]);
                    135:                        }
                    136:                        continue;
                    137: 
                    138:                case 'm':
                    139:                        /*
                    140:                         * -m: Perform in-memory load if possible.
                    141:                         */
                    142:                        memld++;
                    143:                        continue;
                    144: 
                    145:                case 'n':
                    146:                        /*
                    147:                         * -n: Bind output shared.
                    148:                         */
                    149:                        oldh.l_flag |= LF_SHR;
                    150: #ifdef IAPX86
                    151:                        /*
                    152:                         * Special case, no -n without -i on IBM PC
                    153:                         */
                    154:                        oldh.l_flag |= LF_SEP;
                    155: #endif
                    156:                        continue;
                    157: 
                    158:                case 'o':
                    159:                        /*
                    160:                         * -o file: Place output in named file (default l.out).
                    161:                         */
                    162:                        if ( ++i >= argc )
                    163:                                usage( "bad -o option" );
                    164:                        else
                    165:                                ofname = argv[i];
                    166:                        continue;
                    167: 
                    168:                case 'r':
                    169:                        /*
                    170:                         * -r: Retain relocation information.
                    171:                         */
                    172:                        reloc++;
                    173: #ifdef IAPX86
                    174:                        /*
                    175:                         * Special case, -r disables -i.
                    176:                         */
                    177:                        oldh.l_flag &= ~LF_SEP;
                    178: #endif
                    179:                        continue;
                    180: 
                    181:                case 's':
                    182:                        /*
                    183:                         * -s: Discard symbol table.
                    184:                         */
                    185:                        nosym++;
                    186:                        continue;
                    187: 
                    188:                case 'u':
                    189:                        /*
                    190:                         * -u sym: Undefine 'sym' (forcing library search).
                    191:                         */
                    192:                        if ( ++i >= argc )
                    193:                                usage( "bad -u option" );
                    194:                        else
                    195:                                undef( argv[i] );
                    196:                        continue;
                    197: 
                    198:                case 'w':
                    199:                        /*
                    200:                         * -w: Watch everything happen.
                    201:                         */
                    202:                        watch++;
                    203:                        message( "watch!" );
                    204:                        continue;
                    205: 
                    206:                case 'X':
                    207:                        /*
                    208:                         * -X: Discard C internal local symbols.
                    209:                         */
                    210:                        noilcl++;
                    211:                        continue;
                    212: 
                    213:                case 'x':
                    214:                        /*
                    215:                         * -x: Discard all local symbols.
                    216:                         */
                    217:                        nolcl++;
                    218:                        continue;
                    219: 
                    220:                case 'C':
                    221:                        /*
                    222:                         * -C: Bind output combined code/data.
                    223:                         * (otherwise it will be separate code/data as
                    224:                         * required in 286 protected mode)
                    225:                         */
                    226:                        oldh.l_flag &= ~LF_SEP;
                    227:                        continue;
                    228:                }
                    229:        }
                    230: 
                    231:        if ( oldh.l_machine == 0 )
                    232:                fatal( "no input found" );
                    233: 
                    234:        /*
                    235:         * all modules have been read
                    236:         * resolve meanings of various flags
                    237:         */
                    238: 
                    239:        /*
                    240:         * Relocation or undefined symbols...
                    241:         */
                    242:        if ( reloc || nundef ) {
                    243: 
                    244:                /*
                    245:                 * Requires symbol table be retained
                    246:                 */
                    247:                nosym = 0;
                    248: 
                    249:                if ( oldh.l_flag & LF_SEP ) {
                    250: 
                    251:                        message("link failed, the following symbols are undefined:");
                    252: 
                    253:                        for ( i = 0; i < NHASH; i++ ) {
                    254:                                for ( sp=symtable[i]; sp!=NULL; sp=sp->next ) {
                    255:                                        if(sp->s.ls_type==(L_GLOBAL|L_REF)
                    256:                                           && sp->s.ls_addr==0)
                    257:                                                spmsg(sp,"");
                    258:                                }
                    259:                        }
                    260: 
                    261:                        if ( nundef )
                    262:                                exit( 1 );
                    263:                }
                    264:        }
                    265: 
                    266:        /*
                    267:         * No relocation, no undefined symbols
                    268:         */
                    269:        else {
                    270:                /*
                    271:                 * Must define commons
                    272:                 */
                    273:                dcomm++;
                    274: 
                    275:                /*
                    276:                 * Discarding reloc info
                    277:                 */
                    278:                if ( oseg[L_REL].size != 0 ) {
                    279:                        oldh.l_flag |= LF_NRB;          /* make note */
                    280:                        oseg[L_REL].size = 0;
                    281:                }
                    282:        }
                    283: 
                    284:        /*
                    285:         * To define common symbols...
                    286:         */
                    287:        if ( dcomm )
                    288:                oseg[L_BSSD].size += commons;   /* we need this much room */
                    289: 
                    290:        /*
                    291:         * Discard symbol table.
                    292:         */
                    293:        if ( nosym )
                    294:                oseg[L_SYM].size = 0;
                    295: 
                    296:        if ( watch )
                    297:                message( "# undefined=%d", nundef );
                    298: 
                    299:        /*
                    300:         * Set segment bases
                    301:         */
                    302:        baseall( oseg, &oldh );
                    303: 
                    304: #ifdef IAPX86
                    305:        if ( oldh.l_machine == M_8086 ) {
                    306:                if ( (oseg[L_SHRI].size +
                    307:                      oseg[L_PRVI].size +
                    308:                      oseg[L_BSSI].size) >= MAXSEG86 )
                    309:                        fatal("FATAL: code segment too large");
                    310: 
                    311:                if ( (oseg[L_SHRD].size +
                    312:                      oseg[L_PRVD].size +
                    313:                      oseg[L_BSSD].size) >= (MAXSEG86 - DEFSTACK) )
                    314:                        fatal("FATAL: data segment too large");
                    315: 
                    316:                if ( (oseg[L_SHRD].size +
                    317:                      oseg[L_PRVD].size +
                    318:                      oseg[L_BSSD].size) >= (MAXSEG86 - DEFSTACK - WARNSIZE) )
                    319:                        message(
                    320:                           "Warning: data segment may be too large to execute");
                    321:        }
                    322: #endif
                    323: 
                    324:        /*
                    325:         * Open output file
                    326:         */
                    327:        if ( ((ofp = fopen(ofname, "w")) == NULL)
                    328:         &&  ((unlink(ofname) != 0) || ((ofp = fopen(ofname, "w")) == NULL)) )
                    329:                fatal( "cannot create %s", ofname );
                    330: 
                    331:        stat( ofname, &statbuf );
                    332:        chmod( ofname, statbuf.st_mode & ~(S_IEXEC|(S_IEXEC>>3)|(S_IEXEC>>6)));
                    333:        setbuf( ofp, NULL );
                    334: 
                    335:        /*
                    336:         * set disk offsets of segments
                    337:         * if not bigger than a breadbox, build output file in memory;
                    338:         * otherwise, open the file for each segment,
                    339:         * to get independent buffering
                    340:         */
                    341:        daddr = segoffs( oseg, 0L );
                    342: 
                    343:        if ( watch )
                    344:                message( "size: %ld", daddr );
                    345: 
                    346: #if BREADBOX
                    347:        if ( memld || (daddr < BREADBOX) )
                    348:                outbuf = malloc( (int) daddr );
                    349: #endif
                    350:        for ( i = 0; i < NLSEG; i++ ) {
                    351: 
                    352:                if ( (i == L_BSSI) || (i == L_BSSD) )
                    353:                        continue;
                    354: 
                    355:                sgp = &oseg[i];
                    356: 
                    357:                if ( sgp->size == 0 )
                    358:                        continue;
                    359: 
                    360: #if BREADBOX
                    361:                if ( outbuf != NULL ) {
                    362:                        if ( (outputf[i] = malloc(sizeof(FILE))) == NULL )
                    363:                                fatal("out of space");
                    364: 
                    365:                        outputf[i]->_cc = sgp->size;
                    366:                        outputf[i]->_cp = &outbuf[sgp->daddr];
                    367:                        outputf[i]->_pt = &abort;
                    368:                }
                    369:                else
                    370: #endif
                    371:                {
                    372:                        if ( (outputf[i] = fopen(ofname, "r+w")) == NULL )
                    373:                                fatal( "cannot open %s (seg %d)", ofname, i );
                    374: 
                    375:                        fseek( outputf[i], sgp->daddr, 0 );
                    376: 
                    377:                        if ( i == L_SHRI )
                    378:                                setbuf( outputf[i], pbuf1 );
                    379: 
                    380:                        if ( i == L_PRVD )
                    381:                                setbuf( outputf[i], pbuf2 );
                    382:                }
                    383:        }
                    384: 
                    385:        /*
                    386:         * Define internal symbols which have been referenced
                    387:         */
                    388:        if ( dcomm ) {
                    389:                i = oldh.l_flag & LF_KER;
                    390:                endbind( etext_s, L_PRVI, i );
                    391:                endbind( edata_s, L_PRVD, i );
                    392:                endbind( end_s,   L_BSSD, i );
                    393:        }
                    394: 
                    395:        /*
                    396:         * Run through symbol table fixing everything up
                    397:         */
                    398:        symno = 0;
                    399:        for ( i=0; i < NHASH; i++ ) {
                    400: 
                    401:                for ( sp = symtable[i]; sp != NULL; sp = sp->next ) {
                    402: 
                    403:                        /*
                    404:                         * Make defined symbol relative to virtual 0
                    405:                         */
                    406:                        if ( (segn = sp->s.ls_type & ~L_GLOBAL) < L_SYM ) {
                    407:                                sp->s.ls_addr += oseg[segn].vbase;
                    408:                        }
                    409: 
                    410:                        else if ( segn == L_SYM ) {
                    411:                                spmsg( sp, "references symbol segment" );
                    412:                        }
                    413: 
                    414:                        /*
                    415:                         * Leave absolutes alone
                    416:                         */
                    417:                        else if ( sp->s.ls_type != (L_GLOBAL|L_REF) ) {
                    418:                                ;
                    419:                        }
                    420: 
                    421:                        /*
                    422:                         * Undefined global
                    423:                         */
                    424:                        else if ( sp->s.ls_addr == 0 ) {
                    425:                                if ( ! reloc )
                    426:                                        spmsg( sp, "undefined" );
                    427:                        }
                    428: 
                    429:                        /*
                    430:                         * Define commons
                    431:                         */
                    432:                        else if ( dcomm ) {
                    433:                                addr = sp->s.ls_addr;
                    434:                                sp->s.ls_addr = oseg[L_BSSD].vbase
                    435:                                                +oseg[L_BSSD].size
                    436:                                                -commons;
                    437:                                commons -= addr;
                    438:                                sp->s.ls_type = L_GLOBAL | L_BSSD;
                    439:                        }
                    440: 
                    441:                        /*
                    442:                         * Assign symbol number
                    443:                         */
                    444:                        sp->symno = symno++;
                    445: 
                    446:                        /*
                    447:                         * Output to symbol segment
                    448:                         */
                    449:                        if ( ! nosym ) {
                    450:                                canint( sp->s.ls_type );
                    451:                                canvaddr( sp->s.ls_addr );
                    452:                                putstruc( &sp->s, sizeof(sp->s),
                    453:                                        outputf[L_SYM], &oseg[L_SYM] );
                    454:                                canint( sp->s.ls_type );
                    455:                                canvaddr( sp->s.ls_addr );
                    456:                        }
                    457:                }
                    458:        }
                    459: 
                    460:        /*
                    461:         * get entry point (cannot precede symbol table fixup)
                    462:         */
                    463:        oldh.l_entry = (entrys != NULL)
                    464:                        ? lentry(entrys)
                    465:                        : (oldh.l_flag & LF_KER) ? drvbase[oldh.l_machine] : 0;
                    466:        /*
                    467:         * Pass 2
                    468:         */
                    469:        if ( mdisk ) {
                    470: 
                    471:                free( mtemp );
                    472: 
                    473:                if ((mp=malloc(sizeof(mod_t)+ mxmsym*sizeof(sym_t *))) == NULL)
                    474:                        fatal("out of space - M");
                    475: 
                    476:                rewind( mfp );
                    477: 
                    478:                for ( i = 0; i < nmod; i++ ) {
                    479: 
                    480:                        if ( fread( mp, sizeof(mod_t), 1 ,mfp ) != 1 )
                    481: baddisk:                       fatal( "disk error" );
                    482: 
                    483:                        if ( fread( mp->sym, sizeof(sym_t *), mp->nsym, mfp )
                    484:                           != mp->nsym)
                    485:                                goto baddisk;
                    486: 
                    487:                        loadmod( mp );
                    488:                }
                    489: 
                    490:                unlink( mfn );
                    491:        }
                    492:        
                    493:        else {
                    494:                for ( mp = modhead; mp != NULL; mp = mp->next )
                    495:                        loadmod( mp );
                    496:        }
                    497: 
                    498:        /*
                    499:         * All over but the flushing
                    500:         */
                    501:        canint( oldh.l_magic );
                    502:        canint( oldh.l_flag );
                    503:        canint( oldh.l_machine );
                    504:        canvaddr( oldh.l_entry );
                    505: 
                    506:        for ( i = 0; i < NLSEG; i++ ) {
                    507:                oldh.l_ssize[i] = oseg[i].size;
                    508:                cansize(oldh.l_ssize[i]);
                    509:        }
                    510: 
                    511:        if ( outbuf == NULL )
                    512:                fwrite(&oldh, sizeof(oldh), 1, ofp);
                    513: 
                    514:        else {
                    515:                for ( i = 0; i < sizeof(oldh); i++ )
                    516:                        outbuf[i] = *((char *)&oldh + i);
                    517:                fwrite( outbuf, 1, (int)daddr, ofp );
                    518:        }
                    519: 
                    520:        /*
                    521:         * Make executable if no undefined symbols, and common storage defined.
                    522:         */
                    523:        if ( (nundef == 0) || (dcomm != 0) ) {
                    524:                chmod(ofname, statbuf.st_mode|S_IEXEC|(S_IEXEC>>3)|(S_IEXEC>>6));
                    525:                return( 0 );
                    526:        }
                    527: 
                    528:        /*
                    529:         * Supposed to be left relocatable.
                    530:         */
                    531:        else if ( reloc )
                    532:                return( 0 );
                    533: 
                    534:        /*
                    535:         * Undefined symbols left.
                    536:         */
                    537:        else
                    538:                return( nundef );
                    539: }
                    540: 
                    541: /*
                    542:  * Set virtual bases in array of segments
                    543:  * according to flags in header.
                    544:  */
                    545: void
                    546: baseall( sega, ldhp )
                    547: register seg_t sega[];
                    548: register ldh_t *ldhp;
                    549: {
                    550:        register uaddr_t addr;
                    551: 
                    552:        addr = (ldhp->l_flag & LF_KER) ? drvbase[ldhp->l_machine] : 0;
                    553: 
                    554:        /*
                    555:         * Shared code segment first.
                    556:         */
                    557:        addr = setbase( &sega[L_SHRI], ldhp, addr );
                    558: 
                    559:        /*
                    560:         * Shared data segment next if shared but not separate.
                    561:         */
                    562:        if ( (ldhp->l_flag & (LF_SHR|LF_SEP)) == LF_SHR )
                    563:                addr = setbase( &sega[L_SHRD], ldhp, addr );
                    564: 
                    565:        /*
                    566:         * Round up to page boundary if shared.
                    567:         */
                    568:        if ( ldhp->l_flag & LF_SHR )
                    569:                addr = newpage(ldhp, addr);
                    570: 
                    571:        /*
                    572:         * Private code segment next.
                    573:         */
                    574:        addr = setbase( &sega[L_PRVI], ldhp, addr );
                    575: 
                    576:        /*
                    577:         * Private data segment next if shared but not separate.
                    578:         */
                    579:        if ( (ldhp->l_flag & (LF_SHR|LF_SEP)) == LF_SHR )
                    580:                addr = setbase( &sega[L_PRVD], ldhp, addr );
                    581: 
                    582:        /*
                    583:         * Uninitialized code segment next.
                    584:         */
                    585:        addr = setbase( &sega[L_BSSI], ldhp, addr );
                    586: 
                    587:        /*
                    588:         * Set data offset if separate code/data.
                    589:         */
                    590:        if ( ldhp->l_flag & LF_SEP )
                    591:                addr = (ldhp->l_flag & LF_KER) ? drvbase[ldhp->l_machine] : 0;
                    592: 
                    593:        /*
                    594:         * Shared data segment next if not shared.
                    595:         */
                    596:        if ( (ldhp->l_flag & (LF_SHR|LF_SEP)) != LF_SHR )
                    597:                addr = setbase( &sega[L_SHRD], ldhp, addr );
                    598: 
                    599:        /*
                    600:         * Round up to page boundary if shared and separate.
                    601:         */
                    602:        if ( (ldhp->l_flag & (LF_SHR|LF_SEP)) == (LF_SHR|LF_SEP) )
                    603:                addr = newpage( ldhp, addr );
                    604: 
                    605:        /*
                    606:         * Private data segment next unless shared and not separate.
                    607:         */
                    608:        if ( (ldhp->l_flag & (LF_SHR|LF_SEP)) != LF_SHR )
                    609:                addr = setbase( &sega[L_PRVD], ldhp, addr );
                    610: 
                    611:        /*
                    612:         * Uninitialized data segment next.
                    613:         */
                    614:        setbase( &sega[L_BSSD], ldhp, addr );
                    615: }
                    616: 
                    617: /*
                    618:  * Set virtual base in given segment and return next address
                    619:  * Check for wraparound and driver space overflow
                    620:  */
                    621: uaddr_t
                    622: setbase( segp, ldhp, addr )
                    623: register seg_t *segp;
                    624: register ldh_t *ldhp;
                    625: register uaddr_t addr;
                    626: {
                    627:        segp->vbase = addr;
                    628:        addr += segp->size;
                    629: 
                    630:        /*
                    631:         * Address wrap-around.
                    632:         */
                    633:        if ( addr < segp->vbase ) {
                    634:                fatal("address wraparound");
                    635:        }
                    636:        
                    637:        /*
                    638:         * User process.
                    639:         */
                    640:        else if ( ! (ldhp->l_flag & LF_KER) ) {
                    641:                ;
                    642:        }
                    643:        
                    644:        /*
                    645:         * Invalid kernel process.
                    646:         */
                    647:        else if (addr > drvtop[ldhp->l_machine]) {
                    648:                fatal("driver larger than %dKb",
                    649:                        (drvtop[ldhp->l_machine]
                    650:                        -drvbase[ldhp->l_machine])/1024);
                    651:        }
                    652: 
                    653:        return (addr);
                    654: }
                    655: 
                    656: /*
                    657:  * Set segment disk offsets, given sizes
                    658:  * return size of module
                    659:  */
                    660: fsize_t
                    661: segoffs(sega, offs)
                    662: seg_t  sega[];
                    663: register fsize_t       offs;
                    664: {
                    665:        register seg_t  *sgp;
                    666: 
                    667:        offs += sizeof(ldh_t);
                    668: 
                    669:        for ( sgp = &sega[0]; sgp < &sega[NLSEG]; sgp++ ) {
                    670: 
                    671:                /*
                    672:                 * Uninitialized code/data do not affect module size.
                    673:                 */
                    674:                if ( (sgp == &sega[L_BSSI]) || (sgp == &sega[L_BSSD]) )
                    675:                        continue;
                    676: 
                    677:                /*
                    678:                 * Record segment address.
                    679:                 * Calculate module size.
                    680:                 */
                    681:                else {
                    682:                        sgp->daddr = offs;
                    683:                        offs += sgp->size;
                    684:                }
                    685:        }
                    686: 
                    687:        /*
                    688:         * Return module size.
                    689:         */
                    690:        return (offs);
                    691: }
                    692: 
                    693: /*
                    694:  * Bump address to next hardware segment boundary
                    695:  */
                    696: uaddr_t
                    697: newpage( ldhp, addr )
                    698: ldh_t  *ldhp;
                    699: uaddr_t        addr;
                    700: {
                    701:        register uaddr_t inc = segsize[ldhp->l_machine]-1;
                    702: 
                    703:        return ((addr+inc)&~inc);
                    704: }
                    705: 
                    706: /*
                    707:  * Determine entry point; either octal address or symbol name.
                    708:  */
                    709: uaddr_t
                    710: lentry(str)
                    711: char   *str;
                    712: {
                    713:        char    id[NCPLN], *s = &id[0];
                    714:        uaddr_t oaddr=0;
                    715:        int     notoct=0;
                    716:        register sym_t  *sp;
                    717: 
                    718:        /*
                    719:         * Scan string.
                    720:         */
                    721:        for ( ; *str; str++ ) {
                    722: 
                    723:                if ( s < &id[NCPLN] )
                    724:                        *s++ = *str;
                    725: 
                    726:                /*
                    727:                 * Accumulate octal digits.
                    728:                 */
                    729:                if ( ('0' <= *str) && (*str <= '7') )
                    730:                        oaddr = oaddr*8 + *str - '0';
                    731: 
                    732:                /*
                    733:                 * Not an octal digit.
                    734:                 */
                    735:                else
                    736:                        ++notoct;
                    737:        }
                    738: 
                    739:        /*
                    740:         * Octal string: return numeric value.
                    741:         */
                    742:        if (!notoct)
                    743:                return (oaddr);
                    744: 
                    745:        /*
                    746:         * Extend string with nulls.
                    747:         */
                    748:        while ( s < &id[NCPLN] )
                    749:                *s++ = 0;
                    750: 
                    751:        /*
                    752:         * Search for string in symbol table.
                    753:         */
                    754:        for ( sp = symtable[hash(id)]; sp != NULL; sp = sp->next ) {
                    755:                if ( (sp->s.ls_type & L_GLOBAL)
                    756:                 &&  (sp->s.ls_type != (L_GLOBAL|L_REF))
                    757:                 &&  eq(sp->s.ls_id, id) )
                    758:                        return( sp->s.ls_addr );
                    759:        }
                    760: 
                    761:        /*
                    762:         * Symbol not found.
                    763:         */
                    764:        message("entry point %.*s undefined", NCPLN, id);
                    765:        return (0);
                    766: }
                    767: 
                    768: /*
                    769:  * Define referenced internal symbol (as end of given segment)
                    770:  */
                    771: void
                    772: endbind( sp, sn, ldrv )
                    773: register sym_t *sp;
                    774: int    sn, ldrv;
                    775: {
                    776:        if ( sp == NULL ) {
                    777:                return;
                    778:        }
                    779: 
                    780:        else if ((sp->s.ls_type == (L_GLOBAL|L_REF)) && (sp->s.ls_addr == 0)) {
                    781:                sp->s.ls_type = L_GLOBAL|sn;
                    782:                sp->s.ls_addr = oseg[sn].size;
                    783:        }
                    784: 
                    785:        else if ( ldrv ) {
                    786:                return;
                    787:        }
                    788: 
                    789:        else {
                    790:                spmsg(sp, "redefines builtin");
                    791:        }
                    792: }
                    793: 
                    794: /*
                    795:  * Add reference to symbol table
                    796:  */
                    797: void
                    798: undef( s )
                    799: char * s;
                    800: {
                    801:        lds_t   lds;
                    802:        int     i;
                    803: 
                    804:        /*
                    805:         * Copy reference, extending with NULL.
                    806:         */
                    807:        for ( i = 0; i < NCPLN; i++ ) {
                    808:                lds.ls_id[i] = *s;
                    809:                if ( *s != '\0' )
                    810:                        s++;
                    811:        }
                    812: 
                    813:        /*
                    814:         * Define symbol as global reference.
                    815:         */
                    816:        lds.ls_type = L_GLOBAL|L_REF;
                    817:        lds.ls_addr = 0;
                    818: 
                    819:        /*
                    820:         * Add [undefined] to symbol table.
                    821:         */
                    822:        addsym(&lds, NULL);
                    823: }

unix.superglobalmegacorp.com

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