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