file.c revision 1.6 1 /* $NetBSD: file.c,v 1.6 1998/07/25 06:01:13 mycroft 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.6 1998/07/25 06:01:13 mycroft 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