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