xref: /netbsd-src/usr.sbin/mopd/common/file.c (revision 7c7c171d130af9949261bc7dce2150a03c3d239c)
1 /*	$NetBSD: file.c,v 1.5 1998/02/07 00:03:22 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.5 1998/02/07 00:03:22 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 	case MID_I386:
356 #ifdef MID_M68K4K
357 	case MID_M68K4K:
358 #endif
359 #ifdef MID_NS32532
360 	case MID_NS32532:
361 #endif
362 	case MID_SPARC:				/* It might be 8192 */
363 #ifdef MID_PMAX
364 	case MID_PMAX:
365 #endif
366 #ifdef MID_MIPS
367 	case MID_MIPS:
368 #endif
369 #ifdef MID_ARM6
370 	case MID_ARM6:
371 #endif
372 		clbytes = 4096;
373 		break;
374 #ifdef MID_M68K
375 	case MID_M68K:
376 #endif
377 #ifdef MID_ALPHA
378 	case MID_ALPHA:
379 #endif
380 #if defined(MID_M68K) || defined(MID_ALPHA)
381 		clbytes = 8192;
382 		break;
383 #endif
384 	default:
385 		clbytes = 0;
386 	}
387 
388 	return(clbytes);
389 }
390 #endif
391 
392 int
393 CheckAOutFile(fd)
394 	int	fd;
395 {
396 #ifdef NOAOUT
397 	return(-1);
398 #else
399 	struct exec ex, ex_swap;
400 	int	mid = -1;
401 
402 	if (read(fd, (char *)&ex, sizeof(ex)) != sizeof(ex))
403 		return(-1);
404 
405 	(void)lseek(fd, (off_t) 0, SEEK_SET);
406 
407 	if (read(fd, (char *)&ex_swap, sizeof(ex_swap)) != sizeof(ex_swap))
408 		return(-1);
409 
410 	(void)lseek(fd, (off_t) 0, SEEK_SET);
411 
412 	mid = getMID(mid, N_GETMID (ex));
413 
414 	if (mid == -1) {
415 		mid = getMID(mid, N_GETMID (ex_swap));
416 	}
417 
418 	if (mid != -1) {
419 		return(0);
420 	} else {
421 		return(-1);
422 	}
423 #endif NOAOUT
424 }
425 
426 int
427 GetAOutFileInfo(fd, load, xfr, a_text, a_text_fill,
428 		a_data, a_data_fill, a_bss, a_bss_fill, aout)
429 	int		 fd;
430 	u_int32_t	*load, *xfr, *a_text, *a_text_fill;
431 	u_int32_t	*a_data, *a_data_fill, *a_bss, *a_bss_fill;
432 	int		 *aout;
433 {
434 #ifdef NOAOUT
435 	return(-1);
436 #else
437 	struct exec ex, ex_swap;
438 	u_int32_t	mid = -1;
439 	u_int32_t	magic, clbytes, clofset;
440 
441 	if (read(fd, (char *)&ex, sizeof(ex)) != sizeof(ex))
442 		return(-1);
443 
444 	(void)lseek(fd, (off_t) 0, SEEK_SET);
445 
446 	if (read(fd, (char *)&ex_swap, sizeof(ex_swap)) != sizeof(ex_swap))
447 		return(-1);
448 
449 	mopFileSwapX((u_char *)&ex_swap, 0, 4);
450 
451 	mid = getMID(mid, N_GETMID (ex));
452 
453 	if (mid == -1) {
454 		mid = getMID(mid, N_GETMID (ex_swap));
455 		if (mid != -1) {
456 			mopFileSwapX((u_char *)&ex, 0, 4);
457 		}
458 	}
459 
460 	if (mid == -1) {
461 		return(-1);
462 	}
463 
464 	if (N_BADMAG (ex)) {
465 		return(-1);
466 	}
467 
468 	switch (mid) {
469 	case MID_I386:
470 #ifdef MID_NS32532
471 	case MID_NS32532:
472 #endif
473 #ifdef MID_PMAX
474 	case MID_PMAX:
475 #endif
476 #ifdef MID_VAX
477 	case MID_VAX:
478 #endif
479 #ifdef MID_ALPHA
480 	case MID_ALPHA:
481 #endif
482 #ifdef MID_ARM6
483 	case MID_ARM6:
484 #endif
485 		ex.a_text  = mopFileGetLX((u_char *)&ex_swap,  4, 4);
486 		ex.a_data  = mopFileGetLX((u_char *)&ex_swap,  8, 4);
487 		ex.a_bss   = mopFileGetLX((u_char *)&ex_swap, 12, 4);
488 		ex.a_syms  = mopFileGetLX((u_char *)&ex_swap, 16, 4);
489 		ex.a_entry = mopFileGetLX((u_char *)&ex_swap, 20, 4);
490 		ex.a_trsize= mopFileGetLX((u_char *)&ex_swap, 24, 4);
491 		ex.a_drsize= mopFileGetLX((u_char *)&ex_swap, 28, 4);
492 		break;
493 #ifdef MID_M68K
494 	case MID_M68K:
495 #endif
496 #ifdef MID_M68K4K
497 	case MID_M68K4K:
498 #endif
499 	case MID_SPARC:
500 #ifdef MID_MIPS
501 	case MID_MIPS:
502 #endif
503 		ex.a_text  = mopFileGetBX((u_char *)&ex_swap,  4, 4);
504 		ex.a_data  = mopFileGetBX((u_char *)&ex_swap,  8, 4);
505 		ex.a_bss   = mopFileGetBX((u_char *)&ex_swap, 12, 4);
506 		ex.a_syms  = mopFileGetBX((u_char *)&ex_swap, 16, 4);
507 		ex.a_entry = mopFileGetBX((u_char *)&ex_swap, 20, 4);
508 		ex.a_trsize= mopFileGetBX((u_char *)&ex_swap, 24, 4);
509 		ex.a_drsize= mopFileGetBX((u_char *)&ex_swap, 28, 4);
510 		break;
511 	default:
512 		break;
513 	}
514 
515 	printf("a.out image (");
516 	switch (N_GETMID (ex)) {
517 	case MID_I386:
518 		printf("i386");
519 		break;
520 #ifdef MID_M68K
521 	case MID_M68K:
522 		printf("m68k");
523 		break;
524 #endif
525 #ifdef MID_M68K4K
526 	case MID_M68K4K:
527 		printf("m68k 4k");
528 		break;
529 #endif
530 #ifdef MID_NS32532
531 	case MID_NS32532:
532 		printf("pc532");
533 		break;
534 #endif
535 	case MID_SPARC:
536 		printf("sparc");
537 		break;
538 #ifdef MID_PMAX
539 	case MID_PMAX:
540 		printf("pmax");
541 		break;
542 #endif
543 #ifdef MID_VAX
544 	case MID_VAX:
545 		printf("vax");
546 		break;
547 #endif
548 #ifdef MID_ALPHA
549 	case MID_ALPHA:
550 		printf("alpha");
551 		break;
552 #endif
553 #ifdef MID_MIPS
554 	case MID_MIPS:
555 		printf("mips");
556 		break;
557 #endif
558 #ifdef MID_ARM6
559 	case MID_ARM6:
560 		printf("arm32");
561 		break;
562 #endif
563 	default:
564 		break;
565 	}
566 	printf(") Magic: ");
567 	switch (N_GETMAGIC (ex)) {
568 	case OMAGIC:
569 		printf("OMAGIC");
570 		break;
571 	case NMAGIC:
572 		printf("NMAGIC");
573 		break;
574 	case ZMAGIC:
575 		printf("ZMAGIC");
576 		break;
577 	case QMAGIC:
578 		printf("QMAGIC");
579 		break;
580 	default:
581 		printf("Unknown %ld", (long) N_GETMAGIC (ex));
582 	}
583 	printf("\n");
584 	printf("Size of text:       %08lx\n", (long)ex.a_text);
585 	printf("Size of data:       %08lx\n", (long)ex.a_data);
586 	printf("Size of bss:        %08lx\n", (long)ex.a_bss);
587 	printf("Size of symbol tab: %08lx\n", (long)ex.a_syms);
588 	printf("Transfer Address:   %08lx\n", (long)ex.a_entry);
589 	printf("Size of reloc text: %08lx\n", (long)ex.a_trsize);
590 	printf("Size of reloc data: %08lx\n", (long)ex.a_drsize);
591 
592 	magic = N_GETMAGIC (ex);
593 	clbytes = getCLBYTES(mid);
594 	clofset = clbytes - 1;
595 
596 	if (load != NULL) {
597 		*load   = 0;
598 	}
599 
600 	if (xfr != NULL) {
601 		*xfr    = ex.a_entry;
602 	}
603 
604 	if (a_text != NULL) {
605 		*a_text = ex.a_text;
606 	}
607 
608 	if (a_text_fill != NULL) {
609 		if (magic == ZMAGIC || magic == NMAGIC) {
610 			*a_text_fill = clbytes - (ex.a_text & clofset);
611 			if (*a_text_fill == clbytes) {
612 				*a_text_fill = 0;
613 			}
614 		} else {
615 			*a_text_fill = 0;
616 	        }
617 	}
618 
619 	if (a_data != NULL) {
620 		*a_data = ex.a_data;
621 	}
622 
623 	if (a_data_fill != NULL) {
624 		if (magic == ZMAGIC || magic == NMAGIC) {
625 			*a_data_fill = clbytes - (ex.a_data & clofset);
626 			if (*a_data_fill == clbytes) {
627 				*a_data_fill = 0;
628 			}
629 		} else {
630 			*a_data_fill = 0;
631 	        }
632 	}
633 
634 	if (a_bss != NULL) {
635 		*a_bss  = ex.a_bss;
636 	}
637 
638 	if (a_bss_fill != NULL) {
639 		if (magic == ZMAGIC || magic == NMAGIC) {
640 			*a_bss_fill = clbytes - (ex.a_bss & clofset);
641 			if (*a_bss_fill == clbytes) {
642 				*a_bss_fill = 0;
643 			}
644 		} else {
645 			*a_bss_fill = clbytes -
646 				((ex.a_text+ex.a_data+ex.a_bss) & clofset);
647 			if (*a_text_fill == clbytes) {
648 				*a_text_fill = 0;
649 			}
650 	        }
651 	}
652 
653 	if (aout != NULL) {
654 		*aout = mid;
655 	}
656 
657 	return(0);
658 #endif NOAOUT
659 }
660 
661 int
662 GetFileInfo(fd, load, xfr, aout,
663 	    a_text, a_text_fill, a_data, a_data_fill, a_bss, a_bss_fill)
664 	int	fd, *aout;
665 	u_int32_t	*load, *xfr, *a_text, *a_text_fill;
666 	u_int32_t	*a_data, *a_data_fill, *a_bss, *a_bss_fill;
667 {
668 	int	err;
669 
670 	err = CheckAOutFile(fd);
671 
672 	if (err == 0) {
673 		err = GetAOutFileInfo(fd, load, xfr,
674 				      a_text, a_text_fill,
675 				      a_data, a_data_fill,
676 				      a_bss, a_bss_fill,
677 				      aout);
678 		if (err != 0) {
679 			return(-1);
680 		}
681 	} else {
682 		err = CheckMopFile(fd);
683 
684 		if (err == 0) {
685 			err = GetMopFileInfo(fd, load, xfr);
686 			if (err != 0) {
687 				return(-1);
688 			}
689 			*aout = -1;
690 		} else {
691 			return(-1);
692 		}
693 	}
694 
695 	return(0);
696 }
697 
698 ssize_t
699 mopFileRead(dlslot, buf)
700 	struct dllist *dlslot;
701 	u_char	*buf;
702 {
703 	ssize_t len, outlen;
704 	int	bsz;
705 	int32_t	pos, notdone, total;
706 
707 	if (dlslot->aout == -1) {
708 		len = read(dlslot->ldfd,buf,dlslot->dl_bsz);
709 	} else {
710 		bsz = dlslot->dl_bsz;
711 		pos = dlslot->a_lseek;
712 		len = 0;
713 
714 		total = dlslot->a_text;
715 
716 		if (pos < total) {
717 			notdone = total - pos;
718 			if (notdone <= bsz) {
719 				outlen = read(dlslot->ldfd,&buf[len],notdone);
720 			} else {
721 				outlen = read(dlslot->ldfd,&buf[len],bsz);
722 			}
723 			len = len + outlen;
724 			pos = pos + outlen;
725 			bsz = bsz - outlen;
726 		}
727 
728 		total = total + dlslot->a_text_fill;
729 
730 		if ((bsz > 0) && (pos < total)) {
731 			notdone = total - pos;
732 			if (notdone <= bsz) {
733 				outlen = notdone;
734 			} else {
735 				outlen = bsz;
736 			}
737 			memset(&buf[len], 0, outlen);
738 			len = len + outlen;
739 			pos = pos + outlen;
740 			bsz = bsz - outlen;
741 		}
742 
743 		total = total + dlslot->a_data;
744 
745 		if ((bsz > 0) && (pos < total)) {
746 			notdone = total - pos;
747 			if (notdone <= bsz) {
748 				outlen = read(dlslot->ldfd,&buf[len],notdone);
749 			} else {
750 				outlen = read(dlslot->ldfd,&buf[len],bsz);
751 			}
752 			len = len + outlen;
753 			pos = pos + outlen;
754 			bsz = bsz - outlen;
755 		}
756 
757 		total = total + dlslot->a_data_fill;
758 
759 		if ((bsz > 0) && (pos < total)) {
760 			notdone = total - pos;
761 			if (notdone <= bsz) {
762 				outlen = notdone;
763 			} else {
764 				outlen = bsz;
765 			}
766 			memset(&buf[len], 0, outlen);
767 			len = len + outlen;
768 			pos = pos + outlen;
769 			bsz = bsz - outlen;
770 		}
771 
772 		total = total + dlslot->a_bss;
773 
774 		if ((bsz > 0) && (pos < total)) {
775 			notdone = total - pos;
776 			if (notdone <= bsz) {
777 				outlen = notdone;
778 			} else {
779 				outlen = bsz;
780 			}
781 			memset(&buf[len], 0, outlen);
782 			len = len + outlen;
783 			pos = pos + outlen;
784 			bsz = bsz - outlen;
785 		}
786 
787 		total = total + dlslot->a_bss_fill;
788 
789 		if ((bsz > 0) && (pos < total)) {
790 			notdone = total - pos;
791 			if (notdone <= bsz) {
792 				outlen = notdone;
793 			} else {
794 				outlen = bsz;
795 			}
796 			memset(&buf[len], 0, outlen);
797 			len = len + outlen;
798 			pos = pos + outlen;
799 			bsz = bsz - outlen;
800 		}
801 
802 		dlslot->a_lseek = pos;
803 
804 	}
805 
806 	return(len);
807 }
808