xref: /netbsd-src/usr.sbin/mopd/common/file.c (revision 1ca5c1b28139779176bd5c13ad7c5f25c0bcd5f8)
1 /*	$NetBSD: file.c,v 1.7 2001/01/16 02:50:31 cgd 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.7 2001/01/16 02:50:31 cgd 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