Annotation of coherent/d/bin/load/main.c, revision 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.