Annotation of coherent/d/etc/drvld.c, revision 1.1.1.1

1.1       root        1: /*
                      2:  * INETCO Coherent Driver Load Program
                      3:  *
                      4:  * $Log:       drvld.c,v $
                      5:  * Revision 1.2  91/08/01  12:34:08  bin
                      6:  * updated by stevesf to include :/etc/drvld in error messages
                      7:  * produced by drvld
                      8:  * 
                      9:  * Revision 1.3        91/07/31  13:44:11      bin
                     10:  * steve 7/31/91
                     11:  * Corrected additional fatal error message.
                     12:  * 
                     13:  * Revision 1.2        91/07/31  13:40:09      bin
                     14:  * steve 7/31/91
                     15:  * In warn(), added line to print "/etc/drvld: " preceding warnings
                     16:  * or fatal error messages.
                     17:  * 
                     18:  * Revision 1.1        91/07/31  13:38:11      bin
                     19:  * Initial revision
                     20:  * 
                     21:  * Revision 1.2        88/07/07  09:30:37      src
                     22:  * Bug:        Drivers whose prefix consisted had a numeric third character
                     23:  *     were not recognized by the drvld(1M) command.
                     24:  * Fix:        A numeric third digit is ignored in driver symbol aliasing.
                     25:  *     ie: rs0con_ will be recognized when searching for con_.
                     26:  * 
                     27:  * Revision 1.1        88/07/07  08:49:44      src
                     28:  * Initial revision
                     29:  * 
                     30:  * 87/12/01    Allan Cornish           /usr/src/cmd/etc/drvld.c
                     31:  * relocate() now properly relocates uninitialized data.
                     32:  */
                     33: #include <stdio.h>
                     34: #include <canon.h>
                     35: #include <errno.h>
                     36: #include <l.out.h>
                     37: #include <signal.h>
                     38: #include <sys/fcntl.h>
                     39: 
                     40: extern long lseek();
                     41: 
                     42: /*
                     43:  * The following three variables are obtained from kernel data space.
                     44:  */
                     45: static int      NSLOT;         /* Number of driver data slots  */
                     46: static int      slotsz;        /* Number of bytes per slot     */
                     47: static int  *   slotp;         /* Slot offset in kernel data   */
                     48: 
                     49: /*
                     50:  * Local Variables.
                     51:  */
                     52: char *  ksym_file = "/coherent";/* Kernel symbol file name     */
                     53: char *  kmem_file = "/dev/kmem";/* Kernel data file name       */
                     54: char *  text_file;             /* Driver code file name        */
                     55: char *  dsym_file;
                     56: unsigned kmem_end;             /* End of kernel data space     */
                     57: int     verbose;               /* Non-zero for verbose debug   */
                     58: int     ksym_fd = -1;          /* Kernel obj file descriptor   */
                     59: int     dsym_fd = -1;          /* Driver obj file descriptor   */
                     60: int     kmem_fd = -1;          /* Kernel data file descriptor  */
                     61: int     text_fd = -1;          /* Driver text file descriptor  */
                     62: int     slot;                  /* First slot in current driver */
                     63: int     nslot;                 /* Number slots for curr driver */
                     64: unsigned datap;                        /* Ptr to driver data in kernel */
                     65: struct ldsym * dsym_tab;       /* Driver symbol table          */
                     66: struct ldsym * ksym_tab;       /* Kernel symbol table          */
                     67: int     dsym_cnt;              /* Number of driver symbols     */
                     68: int     ksym_cnt;              /* Number of kernel symbols     */
                     69: int     dsym_len;              /* Number of bytes of symbols   */
                     70: unsigned char * drel_tab;      /* Driver relocation table      */
                     71: int     drel_len;              /* Number of relocation bytes   */
                     72: int     dflag;                 /* Enable debugging output      */
                     73: int     rflag;                 /* Remove output file after exec*/
                     74: int     sflag;                 /* Strip symbols from output    */
                     75: struct  ldheader ldh_ker;      /* Kernel load header           */
                     76: struct  ldheader ldh_drv;      /* Driver load header           */
                     77: 
                     78: /*
                     79:  * Forward referenced functions.
                     80:  */
                     81: void   startup();
                     82: void   cleanup();
                     83: void   warn();
                     84: void   fatal();
                     85: void   canldh();
                     86: void   relocate();
                     87: long   symoff();
                     88: void   symsave();
                     89: struct ldsym * drvalias();
                     90: struct ldsym * ksymbol();
                     91: char * basename();
                     92: 
                     93: main( argc, argv )
                     94: int argc;
                     95: char ** argv;
                     96: {
                     97:        /*
                     98:         * Perform system initialization.
                     99:         */
                    100:        startup( argv );
                    101: 
                    102:        /*
                    103:         * Load drivers.
                    104:         */
                    105:        for ( argc = 0; dsym_file = *++argv; ) {
                    106:                if ( **argv != '-' ) {
                    107:                        drvload();
                    108:                        argc++;
                    109:                }
                    110:        }
                    111: 
                    112:        /*
                    113:         * No drivers loaded.
                    114:         */
                    115:        if ( argc == 0 )
                    116:                fatal( "usage", ": drv [-k/coherent] [-r] [-s] file ..." );
                    117: 
                    118:        /*
                    119:         * Perform system cleanup.
                    120:         */
                    121:        cleanup( 0 );
                    122: }
                    123: 
                    124: /**
                    125:  *
                    126:  * void
                    127:  * startup( argv )     -- perform system initialization.
                    128:  * char ** argv;
                    129:  *
                    130:  *     Input:  argv = pointer to null-terminated list of arguments.
                    131:  *
                    132:  *     Action: Process flag arguments.
                    133:  *             Obtain kernel symbolic information.
                    134:  *             Obtain kernel loadable driver characteristics.
                    135:  */
                    136: void
                    137: startup( argv )
                    138: register char ** argv;
                    139: {
                    140:        register struct ldsym * ksymp;
                    141:        register char * cp;
                    142:        register int sig;
                    143: 
                    144: #if EBUG > 0
                    145:        static char obuf[BUFSIZ];
                    146:        setbuf( stdout, obuf );
                    147: #endif
                    148: 
                    149:        /*
                    150:         * Only super-use can load drivers.
                    151:         */
                    152:        if ( getuid() != 0 )
                    153:                fatal( "not super-user", "" );
                    154: 
                    155:        /*
                    156:         * Trap non-ignored signals.
                    157:         */
                    158:        for ( sig = 1; sig <= NSIG; sig++ )
                    159:                if ( signal( sig, SIG_IGN ) != SIG_IGN )
                    160:                        signal( sig, cleanup );
                    161: 
                    162:        /*
                    163:         * Trap alarm signal.
                    164:         */
                    165:        signal( SIGALRM, cleanup );
                    166: 
                    167:        /*
                    168:         * Scan argument list for flags.
                    169:         */
                    170:        while ( cp = *++argv ) {
                    171: 
                    172:                /*
                    173:                 * Ignore drivers to be loaded.
                    174:                 */
                    175:                if ( *cp != '-' )
                    176:                        continue;
                    177: 
                    178:                while ( *++cp ) {
                    179:                        switch ( *cp ) {
                    180: 
                    181:                        case 'd':
                    182:                                /*
                    183:                                 * -d specifies debugging output.
                    184:                                 */
                    185:                                dflag = 1;
                    186:                                break;
                    187: 
                    188:                        case 'k':
                    189:                                /*
                    190:                                 * -k <KERNEL> specifies kernel to load against.
                    191:                                 */
                    192:                                if ( argv[1] == NULL )
                    193:                                        fatal( "Missing file arg after ", "-k" );
                    194:                                if ( argv[1][0] == '-' )
                    195:                                        fatal( "Invalid kernel file: ", *argv );
                    196:                                ksym_file = *++argv;
                    197:                                *argv = "-";
                    198:                                break;
                    199: 
                    200:                        case 'o':
                    201:                                /*
                    202:                                 * -o outputfile
                    203:                                 */
                    204:                                if ( argv[1] == NULL )
                    205:                                fatal( "Missing file arg after ", "-o" );
                    206:                                if ( argv[1][0] == '-' )
                    207:                                        fatal( "Invalid output file: ", *argv );
                    208:                                text_file = *++argv;
                    209:                                *argv = "-";
                    210:                                break;
                    211: 
                    212:                        case 'r':
                    213:                                /*
                    214:                                 * -r removes output file after loading.
                    215:                                 */
                    216:                                rflag = 1;
                    217:                                break;
                    218: 
                    219:                        case 's':
                    220:                                /*
                    221:                                 * -s strips symbols from output file.
                    222:                                 */
                    223:                                sflag = 1;
                    224:                                break;
                    225: 
                    226:                        case 'v':
                    227:                                /*
                    228:                                 * -v turns verbose monitoring on.
                    229:                                 */
                    230:                                verbose++;
                    231:                                break;
                    232: 
                    233:                        default:
                    234:                                fatal( "Invalid flag: -", cp );
                    235:                        }
                    236:                }
                    237:        }
                    238: 
                    239:        /*
                    240:         * Obtain kernel object module header.
                    241:         */
                    242:        ksym_fd = get_ldh( ksym_file, &ldh_ker );
                    243: 
                    244:        /*
                    245:         * Kernel must not be relocatable.
                    246:         */
                    247:        if ( (ldh_ker.l_flag & LF_NRB) == 0 )
                    248:                fatal( ksym_file, ": relocatable" );
                    249: 
                    250:        /*
                    251:         * Allocate memory space for kernel symbol table.
                    252:         */
                    253:        ksym_cnt = ldh_ker.l_ssize[L_SYM] / sizeof(struct ldsym);
                    254:        if ( (ksym_tab = malloc( (int) ldh_ker.l_ssize[L_SYM])) == NULL )
                    255:                fatal( ksym_file, ": symbol table too large" );
                    256: 
                    257: #if EBUG > 0
                    258:        if ( dflag ) {
                    259:                printf("startup: ksym_cnt=%d ksym_len=%d ksym_tab=%04x\n",
                    260:                        ksym_cnt, (int) ldh_ker.l_ssize[L_SYM], ksym_tab );
                    261:        }
                    262: #endif
                    263: 
                    264:        /*
                    265:         * Extract kernel symbol table from object module.
                    266:         */
                    267:        if ( lseek( ksym_fd, (long) symoff(&ldh_ker), 0 ) < 0 )
                    268:                fatal( ksym_file, ": bad seek" );
                    269:        if ( read( ksym_fd, ksym_tab, (int) ldh_ker.l_ssize[L_SYM] ) <= 0 )
                    270:                fatal( ksym_file, ": bad read" );
                    271: 
                    272:        /*
                    273:         * Open kernel data space.
                    274:         */
                    275:        if ((kmem_fd = open( kmem_file, O_RDWR )) < 0 )
                    276:                fatal( kmem_file, ": can't open.");
                    277: 
                    278:        /*
                    279:         * Obtain address of end of kernel data space - end.
                    280:         */
                    281:        if ( (ksymp = ksymbol( "end_" )) == NULL )
                    282:                fatal( ksym_file, ": symbol 'end' not found" );
                    283:        kmem_end = ksymp->ls_addr;
                    284: 
                    285:        /*
                    286:         * Read NSLOT kernel variable.
                    287:         */
                    288:        if ( (ksymp = ksymbol( "NSLOT_" )) == NULL )
                    289:                fatal( ksym_file, ": symbol NSLOT not found" );
                    290:        if ( (lseek( kmem_fd, (long) ksymp->ls_addr, 0 ) < 0)
                    291:          || (read( kmem_fd, &NSLOT, sizeof(NSLOT) ) < 0) )
                    292:                fatal( kmem_file, ": can't access NSLOT var");
                    293: 
                    294:        /*
                    295:         * Read slotsz kernel variable.
                    296:         */
                    297:        if ( (ksymp = ksymbol( "slotsz_" )) == NULL )
                    298:                fatal( ksym_file, ": symbol slotsz not found" );
                    299:        if ( (lseek( kmem_fd, (long) ksymp->ls_addr, 0 ) < 0)
                    300:          || (read( kmem_fd, &slotsz, sizeof(slotsz) ) < 0) )
                    301:                fatal( kmem_file, ": can't access slotsz var");
                    302: 
                    303:        /*
                    304:         * Read slotp kernel variable.
                    305:         */
                    306:        if ( (ksymp = ksymbol( "slotp_" )) == NULL )
                    307:                fatal( ksym_file, ": symbol slotp not found" );
                    308:        if ( (lseek( kmem_fd, (long) ksymp->ls_addr, 0 ) < 0)
                    309:          || (read( kmem_fd, &slotp, sizeof(slotp) ) < 0) )
                    310:                fatal( kmem_file, ": can't access slotp var");
                    311: 
                    312: #if EBUG > 0
                    313:        if ( dflag )
                    314:        printf("NSLOT=%d slotsz=%d slotp=%04x end=%04x\n",
                    315:                NSLOT, slotsz, slotp, kmem_end );
                    316: #endif
                    317: 
                    318:        /*
                    319:         * Validate kernel variables - NSLOT, slotsz, slotp.
                    320:         */
                    321:        if ( (NSLOT <= 0) || (slotsz <= 0) || (slotp == NULL) )
                    322:                fatal(  kmem_file, ": loadable drivers disabled." );
                    323: }
                    324: 
                    325: /**
                    326:  *
                    327:  * void
                    328:  * cleanup( sig )      -- clean up and terminate.
                    329:  * int sig;
                    330:  *
                    331:  *     Input:  sig = signal causing termination, or 0.
                    332:  *
                    333:  *     Action: Close special files.
                    334:  *             Exit.
                    335:  */
                    336: void
                    337: cleanup( sig )
                    338: int sig;
                    339: {
                    340:        /*
                    341:         * Quietly accept alarm signals.
                    342:         */
                    343:        if ( sig == SIGALRM ) {
                    344:                signal( sig, cleanup );
                    345:                return;
                    346:        }
                    347: 
                    348:        /*
                    349:         * Remove output files.
                    350:         */
                    351:        if ( (sig != 0) || (rflag != 0) && (text_file[0] != 0) )
                    352:                unlink( text_file );
                    353: 
                    354:        exit( sig );
                    355: }
                    356: 
                    357: /**
                    358:  *
                    359:  * void
                    360:  * warn( s1, s2 )      -- print error message.
                    361:  * char * s1;
                    362:  * char * s2;
                    363:  *
                    364:  *     Input:  s1 = pointer to null-terminated error string.
                    365:  *             s2 = pointer to null-terminated error string.
                    366:  *
                    367:  *     Action: Output error messages.
                    368:  *             Output new-line.
                    369:  */
                    370: void
                    371: warn( s1, s2 )
                    372: char * s1;
                    373: char * s2;
                    374: {
                    375: #if EBUG > 0
                    376:        fflush( stdout );
                    377:        fflush( stderr );
                    378: #endif
                    379: 
                    380:        write( 2, "/etc/drvld: ", 12);
                    381:        write( 2, s1, strlen(s1) );
                    382:        write( 2, s2, strlen(s2) );
                    383:        write( 2, "\n", 1 );
                    384: }
                    385: 
                    386: /**
                    387:  *
                    388:  * void
                    389:  * fatal( s1, s2 )     -- print fatal error message, terminate.
                    390:  * char * s1;
                    391:  * char * s2;
                    392:  *
                    393:  *     Input:  s1 = pointer to null-terminated error string.
                    394:  *             s2 = pointer to null-terminated error string.
                    395:  *
                    396:  *     Action: Output error messages.
                    397:  *             Output new-line.
                    398:  *             Exit with status 100.
                    399:  */
                    400: void
                    401: fatal( s1, s2 )
                    402: char * s1;
                    403: char * s2;
                    404: {
                    405:        warn( s1, s2 );
                    406:        cleanup( 100 );
                    407: }
                    408: 
                    409: /**
                    410:  * 
                    411:  * void
                    412:  * canldh( ldp )       - Convert a load file header from canonical form.
                    413:  * ldheader * ldp;
                    414:  *
                    415:  *     Input:  ldp = pointer to load file header to be [de]canonized.
                    416:  *
                    417:  *     Action: Convert load file header to/from canonical form.
                    418:  */
                    419: void
                    420: canldh( ldp )
                    421: register struct ldheader * ldp;
                    422: {
                    423:        register int seg;
                    424: 
                    425:        canint( ldp->l_magic   );
                    426:        canint( ldp->l_flag    );
                    427:        canint( ldp->l_machine );
                    428:        canvaddr( ldp->l_entry   );
                    429: 
                    430:        for ( seg = 0; seg < NLSEG; seg++ )
                    431:                cansize( ldp->l_ssize[seg] );
                    432: }
                    433: 
                    434: /**
                    435:  *
                    436:  * int
                    437:  * drvload()   - Spawn a kernel process.
                    438:  *
                    439:  *     Action: Validate object module.
                    440:  *             Allocate and initialize kernel data slots for driver.
                    441:  *             Create and initialize driver code file.
                    442:  *             Create driver symbol table.
                    443:  *             Apply relocation to driver code and data.
                    444:  *             Fork and execute the driver code.
                    445:  */
                    446: drvload()
                    447: {
                    448:        register int n;
                    449:        int cpid;
                    450:        long off;
                    451:        static char buf[BUFSIZ];
                    452:        static char nambuf[64];
                    453: 
                    454:        /*
                    455:         * Define name of driver code file if not already specified.
                    456:         */
                    457:        if ( (text_file == NULL) || (text_file == nambuf) ) {
                    458:                text_file = nambuf;
                    459:                strcpy( nambuf, "/tmp/" );
                    460:                strcat( nambuf, basename(dsym_file) );
                    461:        }
                    462: 
                    463:        /*
                    464:         * Obtain driver object module header.
                    465:         */
                    466:        dsym_fd = get_ldh( dsym_file, &ldh_drv );
                    467: 
                    468:        /*
                    469:         * Driver must be relocatable.
                    470:         */
                    471:        if ( ldh_drv.l_flag & LF_NRB )
                    472:                fatal( dsym_file, ": not relocatable" );
                    473: 
                    474:        /*
                    475:         * Build symbol table from driver and referenced kernel symbols.
                    476:         * Allocate kernel data space.
                    477:         * Adjust data relative symbols.
                    478:         */
                    479:        symload();
                    480:        drvalloc();
                    481:        symadjust();
                    482: 
                    483:        /*
                    484:         * Prepare to install driver data into allocated slots.
                    485:         */
                    486:        off = sizeof(ldh_drv)+ldh_drv.l_ssize[L_SHRI]+ldh_drv.l_ssize[L_PRVI];
                    487:        if ( lseek( dsym_fd, (long) off, 0 ) < 0 )
                    488:                fatal( dsym_file, ": bad seek" );
                    489:        if ( lseek( kmem_fd, (long) datap, 0 ) < 0 )
                    490:                fatal( kmem_file, ": bad seek" );
                    491: 
                    492: #if EBUG > 0
                    493:        if ( dflag )
                    494:                printf("driver data at kernel offset %04x\n", datap );
                    495: #endif
                    496: 
                    497:        /*
                    498:         * Install initialized driver data.
                    499:         */
                    500:        off = ldh_drv.l_ssize[L_SHRD] + ldh_drv.l_ssize[L_PRVD];
                    501: #if EBUG > 0
                    502:        if ( dflag ) printf("initialized data = %ld bytes\n", off );
                    503: #endif
                    504:        while ( off > 0 ) {
                    505:                n = (off > BUFSIZ) ? BUFSIZ : off;
                    506:                if ( read( dsym_fd, buf, n ) != n ) 
                    507:                        fatal( dsym_file, ": truncated" );
                    508:                if ( write( kmem_fd, buf, n ) != n )
                    509:                        fatal( kmem_file, ": bad write" );
                    510: #if EBUG > 0
                    511:                if ( dflag ) printf("write %d bytes\n", n );
                    512: #endif
                    513:                off -= n;
                    514:        }
                    515: 
                    516:        /*
                    517:         * Erase uninitialized driver data.
                    518:         */
                    519:        memset( buf, 0, sizeof(buf) );
                    520:        off = ldh_drv.l_ssize[L_BSSD];
                    521: #if EBUG > 0
                    522:        if ( dflag ) printf("uninitialized data = %ld bytes\n", off );
                    523: #endif
                    524:        while ( off > 0 ) {
                    525:                n = (off > BUFSIZ) ? BUFSIZ : off;
                    526:                if ( write( kmem_fd, buf, n ) != n )
                    527:                        fatal( kmem_file, ": bad write" );
                    528: #if EBUG > 0
                    529:                if ( dflag ) printf("clear %d bytes\n", n );
                    530: #endif
                    531:                off -= n;
                    532:        }
                    533: 
                    534:        /*
                    535:         * Create driver code file.
                    536:         */
                    537:        unlink( text_file );
                    538:        if ( (text_fd = creat( text_file, 0700)) < 0 )
                    539:                fatal( text_file, ": can't create" );
                    540:        close( text_fd );
                    541:        if ( (text_fd = open( text_file, O_RDWR)) < 0 )
                    542:                fatal( text_file, ": can't reopen" );
                    543: 
                    544:        /*
                    545:         * Prepare to install driver code into new file.
                    546:         */
                    547:        if ( lseek( dsym_fd, (long) sizeof(ldh_drv), 0 ) < 0 )
                    548:                fatal( dsym_file, ": bad seek" );
                    549:        if ( lseek( text_fd, (long) sizeof(ldh_drv), 0 ) < 0 )
                    550:                fatal( text_file, ": bad seek" );
                    551: 
                    552:        /*
                    553:         * Install initialized driver code.
                    554:         */
                    555:        off = ldh_drv.l_ssize[L_SHRI] + ldh_drv.l_ssize[L_PRVI];
                    556: #if EBUG > 0
                    557:        if ( dflag ) printf("initialized code = %ld bytes\n", off );
                    558: #endif
                    559:        while ( off > 0 ) {
                    560:                n = (off > BUFSIZ) ? BUFSIZ : off;
                    561:                if ( read( dsym_fd, buf, n ) != n ) 
                    562:                        fatal( dsym_file, ": truncated" );
                    563:                if ( write( text_fd, buf, n ) != n )
                    564:                        fatal( text_file, ": bad write" );
                    565:                off -= n;
                    566:        }
                    567: 
                    568:        /*
                    569:         * Apply relocation directives to driver code and data.
                    570:         */
                    571:        relocate();
                    572: 
                    573:        /*
                    574:         * Save symbol table in driver code file.
                    575:         */
                    576:        symsave();
                    577: 
                    578:        /*
                    579:         * Close driver files.
                    580:         */
                    581:        close( dsym_fd );
                    582:        close( text_fd );
                    583:        fflush( stdout );
                    584:        sync();
                    585: 
                    586:        /*
                    587:         * Load driver - spawning kernel process.
                    588:         */
                    589:        if ( (cpid = sload(text_file)) < 0 )
                    590:                fatal( text_file, ": can't load driver\n" );
                    591: 
                    592:        /*
                    593:         * Lock all data slots required by server process.
                    594:         */
                    595:        for ( n = slot + nslot; --n >= slot; ) {
                    596:                /*
                    597:                 * Lock data slot or kill server and terminate.
                    598:                 */
                    599:                if ( skword( &slotp[n], cpid ) < 0 ) {
                    600:                        kill( cpid, SIGKILL );
                    601:                        fatal( kmem_file, ": bad write" );
                    602:                }
                    603:        }
                    604: 
                    605: #if EBUG > 0 )
                    606:        if ( dflag )
                    607:                printf("Driver process id = %d\n", cpid );
                    608: #endif
                    609: 
                    610:        /*
                    611:         * Remove text file.
                    612:         */
                    613:        if ( rflag )
                    614:                unlink( text_file );
                    615: }
                    616: 
                    617: /**
                    618:  *
                    619:  * int
                    620:  * drvalloc()          - Allocate kernel data slots.
                    621:  */
                    622: int
                    623: drvalloc()
                    624: {
                    625:        int baseslot = 0;
                    626:        int pid;
                    627: 
                    628:        /*
                    629:         * Determine number of required driver data slots.
                    630:         */
                    631:        nslot = (ldh_drv.l_ssize[L_SHRD] + ldh_drv.l_ssize[L_PRVD] +
                    632:                 ldh_drv.l_ssize[L_BSSD] + slotsz - 1) / slotsz;
                    633: 
                    634: #if EBUG > 0
                    635:        if ( dflag )
                    636:                printf( "drvalloc: nslot=%d\n", nslot );
                    637: #endif
                    638: 
                    639:        /*
                    640:         * No data space required.
                    641:         */
                    642:        if ( nslot == 0 ) {
                    643:                datap = (unsigned) (&slotp[NSLOT]);
                    644:                slot = 0;
                    645:                return;
                    646:        }
                    647: 
                    648:        /*
                    649:         * Allocate driver data slots.
                    650:         */
                    651:        for ( slot = 0; slot < NSLOT; ) {
                    652: 
                    653: #if EBUG > 0
                    654:                if ( dflag )
                    655:                        printf( "checking slot %d ", slot );
                    656: #endif
                    657: 
                    658:                /*
                    659:                 * Obtain slot process id.
                    660:                 */
                    661:                if ( fkword( &slotp[slot], &pid ) < 0 )
                    662:                        fatal( kmem_file, ": bad slot pid read." );
                    663: 
                    664: #if EBUG > 0
                    665:                if ( dflag )
                    666:                        printf("pid=%d\n", pid );
                    667: #endif
                    668: 
                    669:                /*
                    670:                 * Slot is not allocated.
                    671:                 */
                    672:                if ( pid == 0 )
                    673:                        ;
                    674: 
                    675:                /*
                    676:                 * Validate process id and existence.
                    677:                 */
                    678:                else if ( (pid < 0) || (kill(pid,0) < 0) ) {
                    679: 
                    680: #if EBUG > 0
                    681:                        if ( dflag )
                    682:                                printf( "clearing slot %d\n", slot );
                    683: #endif
                    684: 
                    685:                        /*
                    686:                         * Erase slot process id - this makes the slot empty.
                    687:                         */
                    688:                        if ( skword( &slotp[slot], 0 ) < 0 )
                    689:                                fatal( kmem_file, ": can't free slot." );
                    690: 
                    691:                        pid = 0;
                    692:                }
                    693: 
                    694:                /*
                    695:                 * Ignore busy slots.
                    696:                 */
                    697:                if ( pid != 0 ) {
                    698:                        baseslot = ++slot;
                    699:                        continue;
                    700:                }
                    701: 
                    702:                /*
                    703:                 * Sufficient contiguous slots found.
                    704:                 */
                    705:                if ( (++slot - baseslot) >= nslot )
                    706:                        break;
                    707:        }
                    708: 
                    709:        /*
                    710:         * Insufficient contiguous slot space.
                    711:         */
                    712:        if ( (slot - baseslot) < nslot )
                    713:                fatal( dsym_file, ": out of driver memory" );
                    714: 
                    715: #if EBUG > 0
                    716:                if ( dflag )
                    717:                        printf("%d slots allocated starting at slot %d\n",
                    718:                                nslot, baseslot );
                    719: #endif
                    720: 
                    721:        /*
                    722:         * Compute offset of driver data in kernel memory.
                    723:         */
                    724:        datap = (unsigned) (&slotp[NSLOT]) + (baseslot * slotsz);
                    725:        slot  = baseslot;
                    726: }
                    727: 
                    728: /**
                    729:  *
                    730:  * int
                    731:  * get_ldh( filename, ldp )
                    732:  * char * filename;
                    733:  * struct ldheader * ldp;
                    734:  *
                    735:  *     Input:  filename = name of object file to be accessed.
                    736:  *             ldp = pointer to load header to be initialized.
                    737:  *
                    738:  *     Return: Read-only file descriptor on object file.
                    739:  */
                    740: int
                    741: get_ldh( filename, ldp )
                    742: char * filename;
                    743: register struct ldheader * ldp;
                    744: {
                    745:        register int fd;
                    746: 
                    747:        /*
                    748:         * Obtain kernel object module header.
                    749:         */
                    750:        if ( (fd = open(filename, O_RDONLY)) < 0 )
                    751:                fatal( filename, ": can't open" );
                    752:        if ( read( fd, ldp, sizeof(*ldp) ) < 0 )
                    753:                fatal( filename, ": truncated" );
                    754: 
                    755:        /*
                    756:         * Convert from canonical to machine format.
                    757:         */
                    758:        canldh( ldp );
                    759: 
                    760:        /*
                    761:         * Validate object module.
                    762:         */
                    763:        if ( ldp->l_magic != L_MAGIC )
                    764:                fatal( filename, ": not an object file" );
                    765:        if ( ldp->l_machine != M_8086 )
                    766:                fatal( filename, ": not an iAPX-86 object file" );
                    767: 
                    768:        /*
                    769:         * Return read-only file descriptor.
                    770:         */
                    771:        return( fd );
                    772: }
                    773: 
                    774: /**
                    775:  *
                    776:  * void
                    777:  * relocate()  - apply relocation directives to driver code and data.
                    778:  *
                    779:  * NOTE: This function only works on a iAPX-86 relocating iAPX-86 code.
                    780:  */
                    781: void
                    782: relocate()
                    783: {
                    784:        register unsigned char * cp;
                    785:        long off;
                    786:        unsigned char  opcode;
                    787:        unsigned short addr;
                    788:        unsigned short symno;
                    789:        unsigned short bias;
                    790:        int txtlen;
                    791: 
                    792: #if EBUG > 0
                    793:        if ( dflag )
                    794:                printf("relocate()\n");
                    795: #endif
                    796: 
                    797:        /*
                    798:         * No relocation directives.
                    799:         */
                    800:        if ( (drel_len = ldh_drv.l_ssize[L_REL]) == 0 )
                    801:                return;
                    802: 
                    803:        /*
                    804:         * Calculate offset of relocation information.
                    805:         */
                    806:        off = sizeof(ldh_drv) + ldh_drv.l_ssize[L_SHRI ] +
                    807:                                ldh_drv.l_ssize[L_PRVI ] +
                    808:                                ldh_drv.l_ssize[L_SHRD ] +
                    809:                                ldh_drv.l_ssize[L_PRVD ] +
                    810:                                ldh_drv.l_ssize[L_DEBUG] +
                    811:                                ldh_drv.l_ssize[L_SYM  ];
                    812: 
                    813:        /*
                    814:         * Compute boundary location between code and data relocation.
                    815:         */
                    816:        txtlen = ldh_drv.l_ssize[L_SHRI] +
                    817:                 ldh_drv.l_ssize[L_PRVI] +
                    818:                 ldh_drv.l_ssize[L_BSSI];
                    819: 
                    820:        /*
                    821:         * Obtain in-memory copy of driver relocation directives.
                    822:         */
                    823:        if ( (drel_tab = malloc( drel_len )) == NULL )
                    824:                fatal( dsym_file, ": too many relocation directives" );
                    825:        if ( lseek( dsym_fd, off, 0 ) < 0 )
                    826:                fatal( dsym_file, ": bad seek" );
                    827:        if ( read( dsym_fd, drel_tab, drel_len ) != drel_len )
                    828:                fatal( dsym_file, ": bad read" );
                    829: 
                    830: #if EBUG > 0
                    831:        if ( dflag )
                    832:                printf("drel_tab=%04x drel_len=%d\n", drel_tab, drel_len );
                    833: #endif
                    834: 
                    835:        /*
                    836:         * Scan driver relocation directives.
                    837:         */
                    838:        for ( cp = drel_tab; drel_len >= 3; ) {
                    839: 
                    840:                /*
                    841:                 * Clear bias [high byte may not be read]
                    842:                 */
                    843:                bias = 0;
                    844: 
                    845:                /*
                    846:                 * Read opcode and address.
                    847:                 */
                    848:                opcode = cp[0];
                    849:                addr   = (cp[2] << 8) + cp[1];
                    850:                drel_len -= 3;
                    851:                cp += 3;
                    852: 
                    853:                /*
                    854:                 * Obtain code to be relocated.
                    855:                 */
                    856:                if ( addr < txtlen ) {
                    857:                        off = sizeof(struct ldheader) + addr;
                    858:                        if ( lseek( text_fd, off, 0 ) < 0 )
                    859:                                fatal( text_file, ": bad seek" );
                    860:                        if (read(text_fd, &bias, (opcode & LR_WORD)?2:1) < 0)
                    861:                                fatal( text_file, ": bad read" );
                    862:                }
                    863: 
                    864:                /*
                    865:                 * Obtain data to be relocated.
                    866:                 */
                    867:                else {
                    868:                        off = datap + addr - txtlen;
                    869:                        if ( lseek( kmem_fd, off, 0 ) < 0 )
                    870:                                fatal( kmem_file, ": bad seek" );
                    871:                        if (read(kmem_fd, &bias, (opcode & LR_WORD)?2:1) < 0)
                    872:                                fatal( kmem_file, ": bad read" );
                    873:                }
                    874: 
                    875: #if EBUG > 0
                    876:                if ( dflag )
                    877:                        printf("opcode=%02x, addr=%04x, offset=%04x, bias=%04x",
                    878:                                opcode, addr, (int) off, bias );
                    879: #endif
                    880: 
                    881:                /*
                    882:                 * Perform relocation.
                    883:                 * NOTE: Program Counter Relative relocation is ignored,
                    884:                 *       since no code is being inserted.
                    885:                 */
                    886:                switch ( opcode & LR_SEG ) {
                    887: 
                    888:                case L_SHRI:
                    889:                case L_PRVI:
                    890:                case L_BSSI:
                    891:                        /*
                    892:                         * No relocation required - no code was inserted.
                    893:                         */
                    894: #if EBUG > 0
                    895:                        if ( dflag )
                    896:                                printf("\n");
                    897: #endif
                    898:                        continue;
                    899: 
                    900:                case L_BSSD:
                    901:                case L_PRVD:
                    902:                case L_SHRD:
                    903:                        bias -= txtlen;
                    904:                        bias += datap;
                    905:                        break;
                    906: 
                    907:                case L_SYM:
                    908:                        /*
                    909:                         * Obtain symbol number.
                    910:                         */
                    911:                        symno  = (cp[1] << 8) + cp[0];
                    912:                        drel_len -= 2;
                    913:                        cp += 2;
                    914: 
                    915:                        /*
                    916:                         * Validate symbol number.
                    917:                         */
                    918:                        if ( (symno < 0) || (symno >= dsym_cnt) )
                    919:                                fatal( dsym_file, ": bad relocation" );
                    920: 
                    921: #if EBUG > 0
                    922:                        if ( dflag )
                    923:                                printf("\n\t\t\t\tsymid=%.*s symaddr=%04x ",
                    924:                                        NCPLN, dsym_tab[symno].ls_id,
                    925:                                        dsym_tab[symno].ls_addr );
                    926: #endif
                    927: 
                    928:                        /*
                    929:                         * Access symbol.
                    930:                         */
                    931:                        bias += dsym_tab[symno].ls_addr;
                    932:                        break;
                    933:                }
                    934: 
                    935: #if EBUG > 0
                    936:                if ( dflag )
                    937:                        printf(" --> %04x\n", bias );
                    938: #endif
                    939: 
                    940:                /*
                    941:                 * Save relocated code.
                    942:                 */
                    943:                if ( addr < txtlen ) {
                    944:                        if ( lseek( text_fd, off, 0 ) < 0 )
                    945:                                fatal( text_file, ": bad seek" );
                    946:                        if (write(text_fd, &bias, (opcode & LR_WORD)?2:1) < 0)
                    947:                                fatal( text_file, ": bad write" );
                    948:                }
                    949: 
                    950:                /*
                    951:                 * Save relocated data.
                    952:                 */
                    953:                else {
                    954:                        if ( lseek( kmem_fd, off, 0 ) < 0 )
                    955:                                fatal( kmem_file, ": bad seek" );
                    956:                        if (write(kmem_fd, &bias, (opcode & LR_WORD)?2:1) < 0)
                    957:                                fatal( kmem_file, ": bad write" );
                    958:                }
                    959:        }
                    960: 
                    961:        /*
                    962:         * Release malloc'ed storage.
                    963:         */
                    964:        free( drel_tab );
                    965: }
                    966: 
                    967: /**
                    968:  *
                    969:  * int
                    970:  * symload()   - load driver symbol table
                    971:  */
                    972: symload()
                    973: {
                    974:        register struct ldsym * dsymp;
                    975:        register struct ldsym * ksymp;
                    976:        long off;
                    977:        int undef;
                    978: 
                    979:        /*
                    980:         * Allocate memory space for driver symbol table.
                    981:         */
                    982:        dsym_cnt = ldh_drv.l_ssize[L_SYM] / sizeof(struct ldsym);
                    983:        dsym_len = ldh_drv.l_ssize[L_SYM];
                    984:        if ( (dsym_cnt != 0) && ((dsym_tab = malloc(dsym_len)) == NULL) )
                    985:                fatal( dsym_file, ": symbol table too large" );
                    986: 
                    987: #if EBUG > 0
                    988:        if ( dflag ) {
                    989:                printf("symload: dsym_cnt=%d dsym_len=%d\n", dsym_cnt, dsym_len );
                    990:                printf("dsym_tab=%04x\n", dsym_tab );
                    991:        }
                    992: #endif
                    993: 
                    994:        if ( dsym_cnt == 0 )
                    995:                return;
                    996: 
                    997:        /*
                    998:         * Extract driver symbol table from object module.
                    999:         */
                   1000:        if ( lseek( dsym_fd, (long) symoff(&ldh_drv), 0 ) < 0 )
                   1001:                fatal( dsym_file, ": bad seek" );
                   1002:        if (read(dsym_fd, dsym_tab, (int) ldh_drv.l_ssize[L_SYM]) <= 0)
                   1003:                fatal( dsym_file, ": bad read" );
                   1004: 
                   1005:        /*
                   1006:         * 1st Pass: Adjust symbol offsets.
                   1007:         */
                   1008:        for ( dsymp = &dsym_tab[dsym_cnt]; --dsymp >= dsym_tab; ) {
                   1009: 
                   1010:                switch ( dsymp->ls_type & LR_SEG ) {
                   1011: 
                   1012:                case L_SHRI:
                   1013:                case L_PRVI:
                   1014:                case L_BSSI:
                   1015:                case L_ABS:
                   1016:                        /*
                   1017:                         * Leave code/absolute data references alone.
                   1018:                         */
                   1019:                        break;
                   1020: 
                   1021:                case L_SHRD:
                   1022:                case L_PRVD:
                   1023:                case L_BSSD:
                   1024:                        /*
                   1025:                         * Convert data references to uninitialized data ref.
                   1026:                         */
                   1027:                        dsymp->ls_type &= ~LR_SEG;
                   1028:                        dsymp->ls_type |= L_BSSD;
                   1029: #if EBUG > 0
                   1030:                        if ( dflag )
                   1031:                        printf("%.*s: DRIVER type=%d addr=%04x\n",
                   1032:                                NCPLN, dsymp->ls_id,
                   1033:                                dsymp->ls_type, dsymp->ls_addr );
                   1034: #endif
                   1035:                        break;
                   1036:                }
                   1037:        }
                   1038: 
                   1039:        /*
                   1040:         * 2nd Pass: Resolve undefined references.
                   1041:         */
                   1042:        for ( undef = 0, dsymp = &dsym_tab[dsym_cnt]; --dsymp >= dsym_tab; ) {
                   1043: 
                   1044:                if ( (dsymp->ls_type & LR_SEG) != L_REF )
                   1045:                        continue;
                   1046: 
                   1047:                /*
                   1048:                 * Check for aliased driver configuration.
                   1049:                 * ie: 'con_' is an alias for '??con_'
                   1050:                 */
                   1051:                if ( ksymp = drvalias(dsymp->ls_id) ) {
                   1052: 
                   1053: #if EBUG > 0
                   1054:                        if ( dflag )
                   1055:                                printf("Driver prefix = '%.2s'\n",
                   1056:                                        ksymp->ls_id );
                   1057: #endif
                   1058: 
                   1059:                        /*
                   1060:                         * Update symbol information.
                   1061:                         */
                   1062:                        dsymp->ls_type = ksymp->ls_type;
                   1063:                        dsymp->ls_addr = ksymp->ls_addr;
                   1064: 
                   1065: #if EBUG > 0
                   1066:                        if ( dflag )
                   1067:                                printf("%.*s: ALIAS %.*s type=%d addr=%04x\n",
                   1068:                                        NCPLN, dsymp->ls_id,
                   1069:                                        NCPLN, ksymp->ls_id,
                   1070:                                        dsymp->ls_type, dsymp->ls_addr );
                   1071: #endif
                   1072:                }
                   1073: 
                   1074:                /*
                   1075:                 * Search for undefined symbol in kernel symbol table.
                   1076:                 */
                   1077:                else if ( ksymp = ksymbol( dsymp->ls_id ) ) {
                   1078:                        /*
                   1079:                         * Update symbol information.
                   1080:                         */
                   1081:                        dsymp->ls_type = ksymp->ls_type;
                   1082:                        dsymp->ls_addr = ksymp->ls_addr;
                   1083: 
                   1084:                        /*
                   1085:                         * Convert kernel data references to absolute.
                   1086:                         */
                   1087:                        if ( ((dsymp->ls_type & LR_SEG) >= L_SHRD)
                   1088:                          && ((dsymp->ls_type & LR_SEG) <= L_BSSD) ) {
                   1089:                                dsymp->ls_type &= ~LR_SEG;
                   1090:                                dsymp->ls_type |= L_ABS;
                   1091:                        }
                   1092: 
                   1093: #if EBUG > 0
                   1094:                        if ( dflag )
                   1095:                                printf("%.*s: KERNEL type=%d addr=%04x\n",
                   1096:                                        NCPLN, dsymp->ls_id,
                   1097:                                        dsymp->ls_type, dsymp->ls_addr );
                   1098: #endif
                   1099:                }
                   1100: 
                   1101:                /*
                   1102:                 * Define commons as uninitialized data.
                   1103:                 */
                   1104:                else if ( dsymp->ls_addr > 0 ) {
                   1105:                        /*
                   1106:                         * Ensure data size is even.
                   1107:                         */
                   1108:                        dsymp->ls_addr +=  1;
                   1109:                        dsymp->ls_addr &= ~1;
                   1110: 
                   1111:                        /*
                   1112:                         * Convert symbol to uninitialized data.
                   1113:                         */
                   1114:                        dsymp->ls_type &= ~LR_SEG;
                   1115:                        dsymp->ls_type |=  L_BSSD;
                   1116: 
                   1117:                        /*
                   1118:                         * Calculate new location of symbol.
                   1119:                         */
                   1120:                        off =   ldh_drv.l_ssize[L_SHRI] +
                   1121:                                ldh_drv.l_ssize[L_PRVI] +
                   1122:                                ldh_drv.l_ssize[L_BSSI] +
                   1123:                                ldh_drv.l_ssize[L_SHRD] +
                   1124:                                ldh_drv.l_ssize[L_PRVD] +
                   1125:                                ldh_drv.l_ssize[L_BSSD];
                   1126: 
                   1127:                        /*
                   1128:                         * Adjust size of uninitialized data.
                   1129:                         * Record new location of symbol.
                   1130:                         */
                   1131:                        ldh_drv.l_ssize[L_BSSD] += dsymp->ls_addr;
                   1132:                        dsymp->ls_addr = off;
                   1133: 
                   1134: #if EBUG > 0
                   1135:                        if ( dflag )
                   1136:                                printf("%.*s: COMMON type=%d addr=%04x\n",
                   1137:                                        NCPLN, dsymp->ls_id,
                   1138:                                        dsymp->ls_type, dsymp->ls_addr );
                   1139: #endif
                   1140:                }
                   1141: 
                   1142:                /*
                   1143:                 * Undefined symbol.
                   1144:                 */
                   1145:                else {
                   1146:                        undef++;
                   1147:                        dsymp->ls_id[NCPLN] = 0;
                   1148:                        warn( dsymp->ls_id, ": undefined symbol" );
                   1149:                }
                   1150:        }
                   1151: 
                   1152:        /*
                   1153:         * Terminate if symbols undefined.
                   1154:         */
                   1155:        if ( undef )
                   1156:                cleanup( 100 );
                   1157: }
                   1158: 
                   1159: /**
                   1160:  *
                   1161:  * void
                   1162:  * symadjust()         -- Adjust addresses of driver data symbols.
                   1163:  *
                   1164:  *     NOTE:   Has to be done AFTER kernel data space allocation.
                   1165:  */
                   1166: symadjust()
                   1167: {
                   1168:        register struct ldsym * dsymp;
                   1169:        register unsigned txtlen;
                   1170: 
                   1171:        if ( dsym_cnt == 0 )
                   1172:                return;
                   1173: 
                   1174:        txtlen = ldh_drv.l_ssize[L_SHRI] +
                   1175:                 ldh_drv.l_ssize[L_PRVI] +
                   1176:                 ldh_drv.l_ssize[L_BSSI];
                   1177: 
                   1178:        /*
                   1179:         * Search driver symbol table.
                   1180:         */
                   1181:        for ( dsymp = &dsym_tab[ dsym_cnt ]; --dsymp >= dsym_tab; ) {
                   1182: 
                   1183:                /*
                   1184:                 * All driver data references are specified as uninitialized.
                   1185:                 * All kernel data references are specified as absolute.
                   1186:                 */
                   1187:                if ( (dsymp->ls_type & LR_SEG) != L_BSSD )
                   1188:                        continue;
                   1189: 
                   1190: #if EBUG > 0
                   1191:                if ( dflag )
                   1192:                printf("adjusting %.*s [type %d] from %04x by %04x\n",
                   1193:                        NCPLN, dsymp->ls_id,
                   1194:                        dsymp->ls_type,
                   1195:                        dsymp->ls_addr,
                   1196:                        datap );
                   1197: #endif
                   1198: 
                   1199:                /*
                   1200:                 * Validate data address.
                   1201:                 */
                   1202:                if ( dsymp->ls_addr < txtlen ) {
                   1203:                        dsymp->ls_id[NCPLN] = 0;
                   1204:                        fatal( dsymp->ls_id, ": invalid address" );
                   1205:                }
                   1206: 
                   1207:                /*
                   1208:                 * Adjust address of data symbol.
                   1209:                 * Separate code/data eliminates relocation after code.
                   1210:                 * Insertion into kernel data adds slot relocation.
                   1211:                 */
                   1212:                dsymp->ls_addr -= txtlen;
                   1213:                dsymp->ls_addr += datap;
                   1214:        }
                   1215: }
                   1216: 
                   1217: /**
                   1218:  *
                   1219:  * struct ldsym *
                   1220:  * drvalias( s )       - Search driver for alias for undefined symbol.
                   1221:  * char * s;
                   1222:  */
                   1223: struct ldsym *
                   1224: drvalias( sym_id )
                   1225: register char * sym_id;
                   1226: {
                   1227:        register struct ldsym * symp;
                   1228: 
                   1229:        /*
                   1230:         * No driver symbols.
                   1231:         */
                   1232:        if ( dsym_cnt == 0 )
                   1233:                return( NULL );
                   1234: 
                   1235:        /*
                   1236:         * Not a symbol which can be aliased.
                   1237:         */
                   1238:        if ( strncmp("con_", sym_id, NCPLN ) != 0 )
                   1239:                return( NULL );
                   1240: 
                   1241:        /*
                   1242:         * Scan driver symbol table [backwards for efficiency].
                   1243:         */
                   1244:        for ( symp = &dsym_tab[dsym_cnt]; --symp >= dsym_tab; ) {
                   1245: 
                   1246:                /*
                   1247:                 * Ignore all except code/data declarations.
                   1248:                 */
                   1249:                if ( (symp->ls_type & LR_SEG) > L_BSSD )
                   1250:                        continue;
                   1251: 
                   1252:                /*
                   1253:                 * Check id after discarding two char driver prefix.
                   1254:                 */
                   1255:                if ( strncmp( sym_id, &symp->ls_id[2], NCPLN-2 ) == 0 )
                   1256:                        return( symp );
                   1257: 
                   1258:                /*
                   1259:                 * Bypass id if 3rd char is not a numeric digit.
                   1260:                 */
                   1261:                if ( (symp->ls_id[2] < '0') || (symp->ls_id[2] > '9') )
                   1262:                        continue;
                   1263: 
                   1264:                /*
                   1265:                 * Check id after discarding three char driver prefix.
                   1266:                 */
                   1267:                if ( strncmp( sym_id, &symp->ls_id[3], NCPLN-3 ) == 0 )
                   1268:                        return( symp );
                   1269:        }
                   1270: 
                   1271:        return( NULL );
                   1272: }
                   1273: 
                   1274: /**
                   1275:  *
                   1276:  * struct ldsym *
                   1277:  * ksymbol( s )        - Search kernel for undefined symbol.
                   1278:  * char * s;
                   1279:  */
                   1280: struct ldsym *
                   1281: ksymbol( sym_id )
                   1282: register char * sym_id;
                   1283: {
                   1284:        register struct ldsym * ksymp;
                   1285:        register int i;
                   1286:        char id[NCPLN];
                   1287: 
                   1288:        /*
                   1289:         * Find last character in symbol identifier.
                   1290:         */
                   1291:        for ( i = NCPLN-1; (i > 0) && (sym_id[i] == 0); --i );
                   1292:                ;
                   1293: 
                   1294:        /*
                   1295:         * Scan kernel symbol table [backwards for efficiency].
                   1296:         */
                   1297:        for ( ksymp = &ksym_tab[ksym_cnt]; --ksymp >= ksym_tab; ) {
                   1298: 
                   1299:                if ( strncmp( sym_id, ksymp->ls_id, NCPLN ) != 0 )
                   1300:                        continue;
                   1301: 
                   1302:                /*
                   1303:                 * Disallow references to C-callable kernel code symbols.
                   1304:                 */
                   1305:                if((sym_id[i] == '_') && ((ksymp->ls_type & LR_SEG) == L_SHRI))
                   1306:                        return( NULL );
                   1307: 
                   1308:                return( ksymp );
                   1309:        }
                   1310: 
                   1311:        /*
                   1312:         * Check symbol for 'K' prefix.
                   1313:         * If found, try again after discarding prefix.
                   1314:         */
                   1315:        if ( (i < 3) || (sym_id[0] != 'K') )
                   1316:                return( NULL );
                   1317:        strncpy( &id[0], &sym_id[1], NCPLN-1 );
                   1318:        id[NCPLN-1] = 0;
                   1319: 
                   1320:        /*
                   1321:         * Scan kernel symbol table [backwards for efficiency].
                   1322:         */
                   1323:        for ( ksymp = &ksym_tab[ksym_cnt]; --ksymp >= ksym_tab; ) {
                   1324: 
                   1325:                /*
                   1326:                 * Only shared kernel code symbols accessible via K prefix.
                   1327:                 */
                   1328:                if ( (ksymp->ls_type & LR_SEG) != L_SHRI)
                   1329:                        continue;
                   1330: 
                   1331:                if ( strncmp( id, ksymp->ls_id, NCPLN ) == 0 )
                   1332:                        return( ksymp );
                   1333:        }
                   1334: 
                   1335:        return( NULL );
                   1336: }
                   1337: 
                   1338: /**
                   1339:  *
                   1340:  * void
                   1341:  * symsave()   -- save revised driver symbol table in code file.
                   1342:  */
                   1343: void
                   1344: symsave()
                   1345: {
                   1346:        /*
                   1347:         * Format driver code header.
                   1348:         */
                   1349:        ldh_drv.l_flag  = LF_SEP  | LF_NRB | LF_KER;
                   1350:        ldh_drv.l_ssize[L_SHRD]  = 0;
                   1351:        ldh_drv.l_ssize[L_PRVD]  = 0;
                   1352:        ldh_drv.l_ssize[L_BSSD]  = kmem_end;
                   1353:        ldh_drv.l_ssize[L_DEBUG] = 0;
                   1354:        ldh_drv.l_ssize[L_SYM ]  = 0;
                   1355:        ldh_drv.l_ssize[L_REL ]  = 0;
                   1356: 
                   1357:        /*
                   1358:         * Save symbol table BEFORE canonizing header.
                   1359:         * NOTE: Reversing sequence will cause errors with symoff().
                   1360:         *       Don't save if removing or stripping object.
                   1361:         */
                   1362:        if ( (rflag == 0) && (sflag == 0) && (dsym_cnt != 0) ) {
                   1363: 
                   1364:                ldh_drv.l_ssize[L_SYM] = dsym_len;
                   1365: 
                   1366:                if ( lseek( text_fd, (long) symoff(&ldh_drv), 0 ) < 0 )
                   1367:                        fatal( text_file, ": bad seek" );
                   1368: 
                   1369:                if ( write( text_fd, (char *) dsym_tab, dsym_len ) < 0 )
                   1370:                        fatal( text_file, ": bad write" );
                   1371:        }
                   1372: 
                   1373:        /*
                   1374:         * Canonize and save driver code header AFTER saving symbol table.
                   1375:         */
                   1376:        canldh( &ldh_drv );
                   1377:        if ( lseek( text_fd, 0L, 0 ) < 0 )
                   1378:                fatal( text_file, ": bad seek" );
                   1379:        if ( write( text_fd, &ldh_drv, sizeof(ldh_drv) ) < 0 )
                   1380:                fatal( text_file, ": bad write" );
                   1381: 
                   1382:        /*
                   1383:         * Release the malloc'ed storage.
                   1384:         */
                   1385:        if ( dsym_tab != NULL ) {
                   1386:                free( dsym_tab );
                   1387:                dsym_tab = NULL;
                   1388:        }
                   1389: }
                   1390: 
                   1391: /**
                   1392:  *
                   1393:  * long
                   1394:  * symoff( ldp )       -- compute offset of symbol table in object module
                   1395:  * struct ldheadr * ldp;
                   1396:  */
                   1397: long
                   1398: symoff( ldp )
                   1399: register struct ldheader * ldp;
                   1400: {
                   1401:        return( sizeof(*ldp) +
                   1402:                ldp->l_ssize[L_SHRI] +
                   1403:                ldp->l_ssize[L_PRVI] +
                   1404:                ldp->l_ssize[L_SHRD] +
                   1405:                ldp->l_ssize[L_PRVD] +
                   1406:                ldp->l_ssize[L_DEBUG] );
                   1407: }
                   1408:        
                   1409: /**
                   1410:  *
                   1411:  * int
                   1412:  * fkword( kp, up )    - Fetch word from kernel locn 'kp' to user locn 'up'.
                   1413:  * int * ip;
                   1414:  * int * up;
                   1415:  */
                   1416: int
                   1417: fkword( kp, up )
                   1418: int * kp;
                   1419: int * up;
                   1420: {
                   1421:        if ( lseek( kmem_fd,  (long) kp, 0 ) < 0 )
                   1422:                return( -1 );
                   1423: 
                   1424:        if ( read( kmem_fd, up, sizeof(*up) ) < 0 )
                   1425:                return( -1 );
                   1426: 
                   1427:        return( 0 );
                   1428: }
                   1429: 
                   1430: /**
                   1431:  *
                   1432:  * int
                   1433:  * skword( kp, w )     - Store word 'w' into kernel locn 'kp'.
                   1434:  * int * kp;
                   1435:  * int w;
                   1436:  */
                   1437: int
                   1438: skword( kp, w )
                   1439: int * kp;
                   1440: int w;
                   1441: {
                   1442:        if ( lseek( kmem_fd, (long) kp, 0 ) < 0 )
                   1443:                return( -1 );
                   1444: 
                   1445:        if ( write( kmem_fd, &w, sizeof(w) ) < 0 )
                   1446:                return( -1 );
                   1447: 
                   1448:        return( 0 );
                   1449: }
                   1450: 
                   1451: char *
                   1452: basename( s )
                   1453: register char * s;
                   1454: {
                   1455:        register char * base;
                   1456: 
                   1457:        for ( base = s; *s != '\0'; s++ ) {
                   1458:                if ( (s[0] == '/') && (s[1] != '/') && (s[1] != '\0') )
                   1459:                        base = s+1;
                   1460:        }
                   1461: 
                   1462:        return( base );
                   1463: }

unix.superglobalmegacorp.com

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