|
|
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: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.