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