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