1 /* $OpenBSD: file.c,v 1.4 2001/08/12 12:03:03 heko Exp $ */ 2 3 /* 4 * Copyright (c) 1995-96 Mats O Jansson. All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 9 * 1. Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 2. Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * 3. All advertising materials mentioning features or use of this software 15 * must display the following acknowledgement: 16 * This product includes software developed by Mats O Jansson. 17 * 4. The name of the author may not be used to endorse or promote products 18 * derived from this software without specific prior written permission. 19 * 20 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 21 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 22 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 23 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 24 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 25 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 26 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 27 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 28 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 29 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 */ 31 32 #ifndef LINT 33 static char rcsid[] = "$OpenBSD: file.c,v 1.4 2001/08/12 12:03:03 heko Exp $"; 34 #endif 35 36 #include "os.h" 37 #include "common/common.h" 38 #include "common/mopdef.h" 39 40 #ifndef NOAOUT 41 #if defined(__NetBSD__) || defined(__OpenBSD__) 42 #include <sys/exec_aout.h> 43 #endif 44 #if defined(__bsdi__) 45 #define NOAOUT 46 #endif 47 #if defined(__FreeBSD__) 48 #include <sys/imgact_aout.h> 49 #endif 50 #if !defined(MID_I386) 51 #define MID_I386 134 52 #endif 53 #if !defined(MID_SPARC) 54 #define MID_SPARC 138 55 #endif 56 #if !defined(MID_VAX) 57 #define MID_VAX 140 58 #endif 59 #endif 60 61 void 62 mopFilePutLX(buf, index, value, cnt) 63 u_char *buf; 64 int index, cnt; 65 u_long value; 66 { 67 int i; 68 for (i = 0; i < cnt; i++) { 69 buf[index+i] = value % 256; 70 value = value / 256; 71 } 72 } 73 74 void 75 mopFilePutBX(buf, index, value, cnt) 76 u_char *buf; 77 int index, cnt; 78 u_long value; 79 { 80 int i; 81 for (i = 0; i < cnt; i++) { 82 buf[index+cnt-1-i] = value % 256; 83 value = value / 256; 84 } 85 } 86 87 u_long 88 mopFileGetLX(buf, index, cnt) 89 u_char *buf; 90 int index, cnt; 91 { 92 u_long ret = 0; 93 int i; 94 95 for (i = 0; i < cnt; i++) { 96 ret = ret*256 + buf[index+cnt-1-i]; 97 } 98 99 return(ret); 100 } 101 102 u_long 103 mopFileGetBX(buf, index, cnt) 104 u_char *buf; 105 int index, cnt; 106 { 107 u_long ret = 0; 108 int i; 109 110 for (i = 0; i < cnt; i++) { 111 ret = ret*256 + buf[index+i]; 112 } 113 114 return(ret); 115 } 116 117 void 118 mopFileSwapX(buf, index, cnt) 119 u_char *buf; 120 int index, cnt; 121 { 122 int i; 123 u_char c; 124 125 for (i = 0; i < (cnt / 2); i++) { 126 c = buf[index+i]; 127 buf[index+i] = buf[index+cnt-1-i]; 128 buf[index+cnt-1-i] = c; 129 } 130 131 } 132 133 int 134 CheckMopFile(fd) 135 int fd; 136 { 137 u_char header[512]; 138 short image_type; 139 140 if (read(fd, header, 512) != 512) 141 return(-1); 142 143 (void)lseek(fd, (off_t) 0, SEEK_SET); 144 145 image_type = (u_short)(header[IHD_W_ALIAS+1]*256 + 146 header[IHD_W_ALIAS]); 147 148 switch(image_type) { 149 case IHD_C_NATIVE: /* Native mode image (VAX) */ 150 case IHD_C_RSX: /* RSX image produced by TKB */ 151 case IHD_C_BPA: /* BASIC plus analog */ 152 case IHD_C_ALIAS: /* Alias */ 153 case IHD_C_CLI: /* Image is CLI */ 154 case IHD_C_PMAX: /* PMAX system image */ 155 case IHD_C_ALPHA: /* ALPHA system image */ 156 break; 157 default: 158 return(-1); 159 } 160 161 return(0); 162 } 163 164 int 165 GetMopFileInfo(fd, load, xfr) 166 int fd; 167 u_long *load, *xfr; 168 { 169 u_char header[512]; 170 short image_type; 171 u_long load_addr, xfr_addr, isd, iha, hbcnt, isize; 172 173 if (read(fd, header, 512) != 512) 174 return(-1); 175 176 image_type = (u_short)(header[IHD_W_ALIAS+1]*256 + 177 header[IHD_W_ALIAS]); 178 179 switch(image_type) { 180 case IHD_C_NATIVE: /* Native mode image (VAX) */ 181 isd = (header[IHD_W_SIZE+1]*256 + 182 header[IHD_W_SIZE]); 183 iha = (header[IHD_W_ACTIVOFF+1]*256 + 184 header[IHD_W_ACTIVOFF]); 185 hbcnt = (header[IHD_B_HDRBLKCNT]); 186 isize = (header[isd+ISD_W_PAGCNT+1]*256 + 187 header[isd+ISD_W_PAGCNT]) * 512; 188 load_addr = ((header[isd+ISD_V_VPN+1]*256 + 189 header[isd+ISD_V_VPN]) & ISD_M_VPN) 190 * 512; 191 xfr_addr = (header[iha+IHA_L_TFRADR1+3]*0x1000000 + 192 header[iha+IHA_L_TFRADR1+2]*0x10000 + 193 header[iha+IHA_L_TFRADR1+1]*0x100 + 194 header[iha+IHA_L_TFRADR1]) & 0x7fffffff; 195 #ifdef INFO 196 printf("Native Image (VAX)\n"); 197 printf("Header Block Count: %d\n",hbcnt); 198 printf("Image Size: %08x\n",isize); 199 printf("Load Address: %08x\n",load_addr); 200 printf("Transfer Address: %08x\n",xfr_addr); 201 #endif 202 break; 203 case IHD_C_RSX: /* RSX image produced by TKB */ 204 hbcnt = header[L_BBLK+1]*256 + header[L_BBLK]; 205 isize = (header[L_BLDZ+1]*256 + header[L_BLDZ]) * 64; 206 load_addr = header[L_BSA+1]*256 + header[L_BSA]; 207 xfr_addr = header[L_BXFR+1]*256 + header[L_BXFR]; 208 #ifdef INFO 209 printf("RSX Image\n"); 210 printf("Header Block Count: %d\n",hbcnt); 211 printf("Image Size: %08x\n",isize); 212 printf("Load Address: %08x\n",load_addr); 213 printf("Transfer Address: %08x\n",xfr_addr); 214 #endif 215 break; 216 case IHD_C_BPA: /* BASIC plus analog */ 217 #ifdef INFO 218 printf("BASIC-Plus Image, not supported\n"); 219 #endif 220 return(-1); 221 break; 222 case IHD_C_ALIAS: /* Alias */ 223 #ifdef INFO 224 printf("Alias, not supported\n"); 225 #endif 226 return(-1); 227 break; 228 case IHD_C_CLI: /* Image is CLI */ 229 #ifdef INFO 230 printf("CLI, not supported\n"); 231 #endif 232 return(-1); 233 break; 234 case IHD_C_PMAX: /* PMAX system image */ 235 isd = (header[IHD_W_SIZE+1]*256 + 236 header[IHD_W_SIZE]); 237 iha = (header[IHD_W_ACTIVOFF+1]*256 + 238 header[IHD_W_ACTIVOFF]); 239 hbcnt = (header[IHD_B_HDRBLKCNT]); 240 isize = (header[isd+ISD_W_PAGCNT+1]*256 + 241 header[isd+ISD_W_PAGCNT]) * 512; 242 load_addr = (header[isd+ISD_V_VPN+1]*256 + 243 header[isd+ISD_V_VPN]) * 512; 244 xfr_addr = (header[iha+IHA_L_TFRADR1+3]*0x1000000 + 245 header[iha+IHA_L_TFRADR1+2]*0x10000 + 246 header[iha+IHA_L_TFRADR1+1]*0x100 + 247 header[iha+IHA_L_TFRADR1]); 248 #ifdef INFO 249 printf("PMAX Image \n"); 250 printf("Header Block Count: %d\n",hbcnt); 251 printf("Image Size: %08x\n",isize); 252 printf("Load Address: %08x\n",load_addr); 253 printf("Transfer Address: %08x\n",xfr_addr); 254 #endif 255 break; 256 case IHD_C_ALPHA: /* ALPHA system image */ 257 isd = (header[EIHD_L_ISDOFF+3]*0x1000000 + 258 header[EIHD_L_ISDOFF+2]*0x10000 + 259 header[EIHD_L_ISDOFF+1]*0x100 + 260 header[EIHD_L_ISDOFF]); 261 hbcnt = (header[EIHD_L_HDRBLKCNT+3]*0x1000000 + 262 header[EIHD_L_HDRBLKCNT+2]*0x10000 + 263 header[EIHD_L_HDRBLKCNT+1]*0x100 + 264 header[EIHD_L_HDRBLKCNT]); 265 isize = (header[isd+EISD_L_SECSIZE+3]*0x1000000 + 266 header[isd+EISD_L_SECSIZE+2]*0x10000 + 267 header[isd+EISD_L_SECSIZE+1]*0x100 + 268 header[isd+EISD_L_SECSIZE]); 269 load_addr = 0; 270 xfr_addr = 0; 271 #ifdef INFO 272 printf("Alpha Image \n"); 273 printf("Header Block Count: %d\n",hbcnt); 274 printf("Image Size: %08x\n",isize); 275 printf("Load Address: %08x\n",load_addr); 276 printf("Transfer Address: %08x\n",xfr_addr); 277 #endif 278 break; 279 default: 280 #ifdef INFO 281 printf("Unknown Image (%d)\n",image_type); 282 #endif 283 return(-1); 284 } 285 286 if (load != NULL) { 287 *load = load_addr; 288 } 289 290 if (xfr != NULL) { 291 *xfr = xfr_addr; 292 } 293 294 return(0); 295 } 296 297 #ifndef NOAOUT 298 int 299 getMID(old_mid,new_mid) 300 int old_mid, new_mid; 301 { 302 int mid; 303 304 mid = old_mid; 305 306 switch (new_mid) { 307 case MID_I386: 308 mid = MID_I386; 309 break; 310 #ifdef MID_M68K 311 case MID_M68K: 312 mid = MID_M68K; 313 break; 314 #endif 315 #ifdef MID_M68K4K 316 case MID_M68K4K: 317 mid = MID_M68K4K; 318 break; 319 #endif 320 #ifdef MID_NS32532 321 case MID_NS32532: 322 mid = MID_NS32532; 323 break; 324 #endif 325 case MID_SPARC: 326 mid = MID_SPARC; 327 break; 328 #ifdef MID_PMAX 329 case MID_PMAX: 330 mid = MID_PMAX; 331 break; 332 #endif 333 #ifdef MID_VAX 334 case MID_VAX: 335 mid = MID_VAX; 336 break; 337 #endif 338 #ifdef MID_ALPHA 339 case MID_ALPHA: 340 mid = MID_ALPHA; 341 break; 342 #endif 343 #ifdef MID_MIPS 344 case MID_MIPS: 345 mid = MID_MIPS; 346 break; 347 #endif 348 #ifdef MID_ARM6 349 case MID_ARM6: 350 mid = MID_ARM6; 351 break; 352 #endif 353 default: 354 break; 355 } 356 357 return(mid); 358 } 359 360 int 361 getCLBYTES(mid) 362 int mid; 363 { 364 int clbytes; 365 366 switch (mid) { 367 #ifdef MID_VAX 368 case MID_VAX: 369 clbytes = 1024; 370 break; 371 #endif 372 case MID_I386: 373 #ifdef MID_M68K4K 374 case MID_M68K4K: 375 #endif 376 #ifdef MID_NS32532 377 case MID_NS32532: 378 #endif 379 case MID_SPARC: /* It might be 8192 */ 380 #ifdef MID_PMAX 381 case MID_PMAX: 382 #endif 383 #ifdef MID_MIPS 384 case MID_MIPS: 385 #endif 386 #ifdef MID_ARM6 387 case MID_ARM6: 388 #endif 389 clbytes = 4096; 390 break; 391 #ifdef MID_M68K 392 case MID_M68K: 393 #endif 394 #ifdef MID_ALPHA 395 case MID_ALPHA: 396 #endif 397 #if defined(MID_M68K) || defined(MID_ALPHA) 398 clbytes = 8192; 399 break; 400 #endif 401 default: 402 clbytes = 0; 403 } 404 405 return(clbytes); 406 } 407 #endif 408 409 int 410 CheckAOutFile(fd) 411 int fd; 412 { 413 #ifdef NOAOUT 414 return(-1); 415 #else 416 struct exec ex, ex_swap; 417 int mid = -1; 418 419 if (read(fd, (char *)&ex, sizeof(ex)) != sizeof(ex)) 420 return(-1); 421 422 (void)lseek(fd, (off_t) 0, SEEK_SET); 423 424 if (read(fd, (char *)&ex_swap, sizeof(ex_swap)) != sizeof(ex_swap)) 425 return(-1); 426 427 (void)lseek(fd, (off_t) 0, SEEK_SET); 428 429 mid = getMID(mid, N_GETMID (ex)); 430 431 if (mid == -1) { 432 mid = getMID(mid, N_GETMID (ex_swap)); 433 } 434 435 if (mid != -1) { 436 return(0); 437 } else { 438 return(-1); 439 } 440 #endif /* NOAOUT */ 441 } 442 443 int 444 GetAOutFileInfo(fd, load, xfr, a_text, a_text_fill, 445 a_data, a_data_fill, a_bss, a_bss_fill, aout) 446 int fd, *aout; 447 u_long *load, *xfr, *a_text, *a_text_fill; 448 u_long *a_data, *a_data_fill, *a_bss, *a_bss_fill; 449 { 450 #ifdef NOAOUT 451 return(-1); 452 #else 453 struct exec ex, ex_swap; 454 int mid = -1; 455 u_long magic, clbytes, clofset; 456 457 if (read(fd, (char *)&ex, sizeof(ex)) != sizeof(ex)) 458 return(-1); 459 460 (void)lseek(fd, (off_t) 0, SEEK_SET); 461 462 if (read(fd, (char *)&ex_swap, sizeof(ex_swap)) != sizeof(ex_swap)) 463 return(-1); 464 465 mopFileSwapX((u_char *)&ex_swap, 0, 4); 466 467 mid = getMID(mid, N_GETMID (ex)); 468 469 if (mid == -1) { 470 mid = getMID(mid, N_GETMID (ex_swap)); 471 if (mid != -1) { 472 mopFileSwapX((u_char *)&ex, 0, 4); 473 } 474 } 475 476 if (mid == -1) { 477 return(-1); 478 } 479 480 if (N_BADMAG (ex)) { 481 return(-1); 482 } 483 484 switch (mid) { 485 case MID_I386: 486 #ifdef MID_NS32532 487 case MID_NS32532: 488 #endif 489 #ifdef MID_PMAX 490 case MID_PMAX: 491 #endif 492 #ifdef MID_VAX 493 case MID_VAX: 494 #endif 495 #ifdef MID_ALPHA 496 case MID_ALPHA: 497 #endif 498 #ifdef MID_ARM6 499 case MID_ARM6: 500 #endif 501 ex.a_text = mopFileGetLX((u_char *)&ex_swap, 4, 4); 502 ex.a_data = mopFileGetLX((u_char *)&ex_swap, 8, 4); 503 ex.a_bss = mopFileGetLX((u_char *)&ex_swap, 12, 4); 504 ex.a_syms = mopFileGetLX((u_char *)&ex_swap, 16, 4); 505 ex.a_entry = mopFileGetLX((u_char *)&ex_swap, 20, 4); 506 ex.a_trsize= mopFileGetLX((u_char *)&ex_swap, 24, 4); 507 ex.a_drsize= mopFileGetLX((u_char *)&ex_swap, 28, 4); 508 break; 509 #ifdef MID_M68K 510 case MID_M68K: 511 #endif 512 #ifdef MID_M68K4K 513 case MID_M68K4K: 514 #endif 515 case MID_SPARC: 516 #ifdef MID_MIPS 517 case MID_MIPS: 518 #endif 519 ex.a_text = mopFileGetBX((u_char *)&ex_swap, 4, 4); 520 ex.a_data = mopFileGetBX((u_char *)&ex_swap, 8, 4); 521 ex.a_bss = mopFileGetBX((u_char *)&ex_swap, 12, 4); 522 ex.a_syms = mopFileGetBX((u_char *)&ex_swap, 16, 4); 523 ex.a_entry = mopFileGetBX((u_char *)&ex_swap, 20, 4); 524 ex.a_trsize= mopFileGetBX((u_char *)&ex_swap, 24, 4); 525 ex.a_drsize= mopFileGetBX((u_char *)&ex_swap, 28, 4); 526 break; 527 default: 528 break; 529 } 530 531 #ifdef INFO 532 printf("a.out image ("); 533 switch (N_GETMID (ex)) { 534 case MID_I386: 535 printf("i386"); 536 break; 537 #ifdef MID_M68K 538 case MID_M68K: 539 printf("m68k"); 540 break; 541 #endif 542 #ifdef MID_M68K4K 543 case MID_M68K4K: 544 printf("m68k 4k"); 545 break; 546 #endif 547 #ifdef MID_NS32532 548 case MID_NS32532: 549 printf("pc532"); 550 break; 551 #endif 552 case MID_SPARC: 553 printf("sparc"); 554 break; 555 #ifdef MID_PMAX 556 case MID_PMAX: 557 printf("pmax"); 558 break; 559 #endif 560 #ifdef MID_VAX 561 case MID_VAX: 562 printf("vax"); 563 break; 564 #endif 565 #ifdef MID_ALPHA 566 case MID_ALPHA: 567 printf("alpha"); 568 break; 569 #endif 570 #ifdef MID_MIPS 571 case MID_MIPS: 572 printf("mips"); 573 break; 574 #endif 575 #ifdef MID_ARM6 576 case MID_ARM6: 577 printf("arm32"); 578 break; 579 #endif 580 default: 581 } 582 printf(") Magic: "); 583 switch (N_GETMAGIC (ex)) { 584 case OMAGIC: 585 printf("OMAGIC"); 586 break; 587 case NMAGIC: 588 printf("NMAGIC"); 589 break; 590 case ZMAGIC: 591 printf("ZMAGIC"); 592 break; 593 case QMAGIC: 594 printf("QMAGIC"); 595 break; 596 default: 597 printf("Unknown %d",N_GETMAGIC (ex)); 598 } 599 printf("\n"); 600 printf("Size of text: %08x\n",ex.a_text); 601 printf("Size of data: %08x\n",ex.a_data); 602 printf("Size of bss: %08x\n",ex.a_bss); 603 printf("Size of symbol tab: %08x\n",ex.a_syms); 604 printf("Transfer Address: %08x\n",ex.a_entry); 605 printf("Size of reloc text: %08x\n",ex.a_trsize); 606 printf("Size of reloc data: %08x\n",ex.a_drsize); 607 #endif 608 magic = N_GETMAGIC (ex); 609 clbytes = getCLBYTES(mid); 610 clofset = clbytes - 1; 611 612 if (load != NULL) { 613 *load = 0; 614 } 615 616 if (xfr != NULL) { 617 *xfr = ex.a_entry; 618 } 619 620 if (a_text != NULL) { 621 *a_text = ex.a_text; 622 } 623 624 if (a_text_fill != NULL) { 625 if (magic == ZMAGIC || magic == NMAGIC) { 626 *a_text_fill = clbytes - (ex.a_text & clofset); 627 if (*a_text_fill == clbytes) { 628 *a_text_fill = 0; 629 } 630 } else { 631 *a_text_fill = 0; 632 } 633 } 634 635 if (a_data != NULL) { 636 *a_data = ex.a_data; 637 } 638 639 if (a_data_fill != NULL) { 640 if (magic == ZMAGIC || magic == NMAGIC) { 641 *a_data_fill = clbytes - (ex.a_data & clofset); 642 if (*a_data_fill == clbytes) { 643 *a_data_fill = 0; 644 } 645 } else { 646 *a_data_fill = 0; 647 } 648 } 649 650 if (a_bss != NULL) { 651 *a_bss = ex.a_bss; 652 } 653 654 if (a_bss_fill != NULL) { 655 if (magic == ZMAGIC || magic == NMAGIC) { 656 *a_bss_fill = clbytes - (ex.a_bss & clofset); 657 if (*a_bss_fill == clbytes) { 658 *a_bss_fill = 0; 659 } 660 } else { 661 *a_bss_fill = clbytes - 662 ((ex.a_text+ex.a_data+ex.a_bss) & clofset); 663 if (*a_text_fill == clbytes) { 664 *a_text_fill = 0; 665 } 666 } 667 } 668 669 if (aout != NULL) { 670 *aout = mid; 671 } 672 673 return(0); 674 #endif /* NOAOUT */ 675 } 676 677 int 678 GetFileInfo(fd, load, xfr, aout, 679 a_text, a_text_fill, a_data, a_data_fill, a_bss, a_bss_fill) 680 int fd, *aout; 681 u_long *load, *xfr, *a_text, *a_text_fill; 682 u_long *a_data, *a_data_fill, *a_bss, *a_bss_fill; 683 { 684 int err; 685 686 err = CheckAOutFile(fd); 687 688 if (err == 0) { 689 err = GetAOutFileInfo(fd, load, xfr, 690 a_text, a_text_fill, 691 a_data, a_data_fill, 692 a_bss, a_bss_fill, 693 aout); 694 if (err != 0) { 695 return(-1); 696 } 697 } else { 698 err = CheckMopFile(fd); 699 700 if (err == 0) { 701 err = GetMopFileInfo(fd, load, xfr); 702 if (err != 0) { 703 return(-1); 704 } 705 *aout = -1; 706 } else { 707 return(-1); 708 } 709 } 710 711 return(0); 712 } 713 714 ssize_t 715 mopFileRead(dlslot, buf) 716 struct dllist *dlslot; 717 u_char *buf; 718 { 719 ssize_t len, outlen; 720 int bsz; 721 long pos, notdone, total; 722 723 if (dlslot->aout == -1) { 724 len = read(dlslot->ldfd,buf,dlslot->dl_bsz); 725 } else { 726 bsz = dlslot->dl_bsz; 727 pos = dlslot->a_lseek; 728 len = 0; 729 730 total = dlslot->a_text; 731 732 if (pos < total) { 733 notdone = total - pos; 734 if (notdone <= bsz) { 735 outlen = read(dlslot->ldfd,&buf[len],notdone); 736 } else { 737 outlen = read(dlslot->ldfd,&buf[len],bsz); 738 } 739 len = len + outlen; 740 pos = pos + outlen; 741 bsz = bsz - outlen; 742 } 743 744 total = total + dlslot->a_text_fill; 745 746 if ((bsz > 0) && (pos < total)) { 747 notdone = total - pos; 748 if (notdone <= bsz) { 749 outlen = notdone; 750 } else { 751 outlen = bsz; 752 } 753 bzero(&buf[len],outlen); 754 len = len + outlen; 755 pos = pos + outlen; 756 bsz = bsz - outlen; 757 } 758 759 total = total + dlslot->a_data; 760 761 if ((bsz > 0) && (pos < total)) { 762 notdone = total - pos; 763 if (notdone <= bsz) { 764 outlen = read(dlslot->ldfd,&buf[len],notdone); 765 } else { 766 outlen = read(dlslot->ldfd,&buf[len],bsz); 767 } 768 len = len + outlen; 769 pos = pos + outlen; 770 bsz = bsz - outlen; 771 } 772 773 total = total + dlslot->a_data_fill; 774 775 if ((bsz > 0) && (pos < total)) { 776 notdone = total - pos; 777 if (notdone <= bsz) { 778 outlen = notdone; 779 } else { 780 outlen = bsz; 781 } 782 bzero(&buf[len],outlen); 783 len = len + outlen; 784 pos = pos + outlen; 785 bsz = bsz - outlen; 786 } 787 788 total = total + dlslot->a_bss; 789 790 if ((bsz > 0) && (pos < total)) { 791 notdone = total - pos; 792 if (notdone <= bsz) { 793 outlen = notdone; 794 } else { 795 outlen = bsz; 796 } 797 bzero(&buf[len],outlen); 798 len = len + outlen; 799 pos = pos + outlen; 800 bsz = bsz - outlen; 801 } 802 803 total = total + dlslot->a_bss_fill; 804 805 if ((bsz > 0) && (pos < total)) { 806 notdone = total - pos; 807 if (notdone <= bsz) { 808 outlen = notdone; 809 } else { 810 outlen = bsz; 811 } 812 bzero(&buf[len],outlen); 813 len = len + outlen; 814 pos = pos + outlen; 815 bsz = bsz - outlen; 816 } 817 818 dlslot->a_lseek = pos; 819 820 } 821 822 return(len); 823 } 824