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