xref: /netbsd/usr.sbin/mopd/common/file.c (revision bf9ec67e)
1 /*	$NetBSD: file.c,v 1.8 2002/02/18 22:00:36 thorpej 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.8 2002/02/18 22:00:36 thorpej Exp $");
35 #endif
36 
37 #include "os.h"
38 #include "common.h"
39 #include "file.h"
40 #include "mopdef.h"
41 #include <stddef.h>
42 
43 #ifndef NOAOUT
44 # if defined(__NetBSD__) || defined(__OpenBSD__)
45 #  include <sys/exec_aout.h>
46 # endif
47 # if defined(__bsdi__)
48 #  define NOAOUT
49 # endif
50 # if defined(__FreeBSD__)
51 #  include <sys/imgact_aout.h>
52 # endif
53 # if !defined(MID_VAX)
54 #  define MID_VAX 140
55 # endif
56 #endif /* NOAOUT */
57 
58 #ifndef NOELF
59 # if defined(__NetBSD__)
60 #  include <sys/exec_elf.h>
61 # else
62 #  define NOELF
63 # endif
64 #endif /* NOELF */
65 
66 int	getCLBYTES __P((int));
67 int	getMID __P((int, int));
68 
69 void
70 mopFilePutLX(buf, index, value, cnt)
71 	u_char	       *buf;
72 	int		index, cnt;
73 	u_int32_t	value;
74 {
75 	int i;
76 	for (i = 0; i < cnt; i++) {
77 		buf[index+i] = value % 256;
78 		value = value / 256;
79 	}
80 }
81 
82 void
83 mopFilePutBX(buf, index, value, cnt)
84 	u_char	       *buf;
85 	int		index, cnt;
86 	u_int32_t	value;
87 {
88 	int i;
89 	for (i = 0; i < cnt; i++) {
90 		buf[index+cnt-1-i] = value % 256;
91 		value = value / 256;
92 	}
93 }
94 
95 u_int32_t
96 mopFileGetLX(buf, index, cnt)
97 	u_char	*buf;
98 	int	index, cnt;
99 {
100 	u_int32_t ret = 0;
101 	int i;
102 
103 	for (i = 0; i < cnt; i++) {
104 		ret = ret*256 + buf[index+cnt-1-i];
105 	}
106 
107 	return(ret);
108 }
109 
110 u_int32_t
111 mopFileGetBX(buf, index, cnt)
112 	u_char	*buf;
113 	int	index, cnt;
114 {
115 	u_int32_t ret = 0;
116 	int i;
117 
118 	for (i = 0; i < cnt; i++) {
119 		ret = ret*256 + buf[index+i];
120 	}
121 
122 	return(ret);
123 }
124 
125 void
126 mopFileSwapX(buf, index, cnt)
127 	u_char	*buf;
128 	int	index, cnt;
129 {
130 	int i;
131 	u_char c;
132 
133 	for (i = 0; i < (cnt / 2); i++) {
134 		c = buf[index+i];
135 		buf[index+i] = buf[index+cnt-1-i];
136 		buf[index+cnt-1-i] = c;
137 	}
138 
139 }
140 
141 int
142 CheckMopFile(fd)
143 	int	fd;
144 {
145 	u_char	header[512];
146 	short	image_type;
147 
148 	if (read(fd, header, 512) != 512)
149 		return(-1);
150 
151 	(void)lseek(fd, (off_t) 0, SEEK_SET);
152 
153 	image_type = (u_short)(header[IHD_W_ALIAS+1]*256 +
154 			       header[IHD_W_ALIAS]);
155 
156 	switch(image_type) {
157 		case IHD_C_NATIVE:		/* Native mode image (VAX)   */
158 		case IHD_C_RSX:			/* RSX image produced by TKB */
159 		case IHD_C_BPA:			/* BASIC plus analog         */
160 		case IHD_C_ALIAS:		/* Alias		     */
161 		case IHD_C_CLI:			/* Image is CLI		     */
162 		case IHD_C_PMAX:		/* PMAX system image	     */
163 		case IHD_C_ALPHA:		/* ALPHA system image	     */
164 			break;
165 		default:
166 			return(-1);
167 	}
168 
169 	return(0);
170 }
171 
172 int
173 GetMopFileInfo(dl)
174 	struct		dllist *dl;
175 {
176 	u_char		header[512];
177 	short		image_type;
178 	u_int32_t	load_addr, xfr_addr, isd, iha, hbcnt, isize;
179 
180 	if (read(dl->ldfd, header, 512) != 512)
181 		return(-1);
182 
183 	image_type = (u_short)(header[IHD_W_ALIAS+1]*256 +
184 			       header[IHD_W_ALIAS]);
185 
186 	switch(image_type) {
187 		case IHD_C_NATIVE:		/* Native mode image (VAX)   */
188 			isd = (header[IHD_W_SIZE+1]*256 +
189 			       header[IHD_W_SIZE]);
190 			iha = (header[IHD_W_ACTIVOFF+1]*256 +
191 			       header[IHD_W_ACTIVOFF]);
192 			hbcnt = (header[IHD_B_HDRBLKCNT]);
193 			isize = (header[isd+ISD_W_PAGCNT+1]*256 +
194 				 header[isd+ISD_W_PAGCNT]) * 512;
195 			load_addr = ((header[isd+ISD_V_VPN+1]*256 +
196 				      header[isd+ISD_V_VPN]) & ISD_M_VPN)
197 					* 512;
198 			xfr_addr = (header[iha+IHA_L_TFRADR1+3]*0x1000000 +
199 				    header[iha+IHA_L_TFRADR1+2]*0x10000 +
200 				    header[iha+IHA_L_TFRADR1+1]*0x100 +
201 				    header[iha+IHA_L_TFRADR1]) & 0x7fffffff;
202 			printf("Native Image (VAX)\n");
203 			printf("Header Block Count: %d\n",hbcnt);
204 			printf("Image Size:         %08x\n",isize);
205 			printf("Load Address:       %08x\n",load_addr);
206 			printf("Transfer Address:   %08x\n",xfr_addr);
207 			break;
208 		case IHD_C_RSX:			/* RSX image produced by TKB */
209 			hbcnt = header[L_BBLK+1]*256 + header[L_BBLK];
210 			isize = (header[L_BLDZ+1]*256 + header[L_BLDZ]) * 64;
211 			load_addr = header[L_BSA+1]*256 + header[L_BSA];
212 			xfr_addr  = header[L_BXFR+1]*256 + header[L_BXFR];
213 			printf("RSX Image\n");
214 			printf("Header Block Count: %d\n",hbcnt);
215 			printf("Image Size:         %08x\n",isize);
216 			printf("Load Address:       %08x\n",load_addr);
217 			printf("Transfer Address:   %08x\n",xfr_addr);
218 			break;
219 		case IHD_C_BPA:			/* BASIC plus analog         */
220 			printf("BASIC-Plus Image, not supported\n");
221 			return(-1);
222 			break;
223 		case IHD_C_ALIAS:		/* Alias		     */
224 			printf("Alias, not supported\n");
225 			return(-1);
226 			break;
227 		case IHD_C_CLI:			/* Image is CLI		     */
228 			printf("CLI, not supported\n");
229 			return(-1);
230 			break;
231 		case IHD_C_PMAX:		/* PMAX system image	     */
232 			isd = (header[IHD_W_SIZE+1]*256 +
233 			       header[IHD_W_SIZE]);
234 			iha = (header[IHD_W_ACTIVOFF+1]*256 +
235 			       header[IHD_W_ACTIVOFF]);
236 			hbcnt = (header[IHD_B_HDRBLKCNT]);
237 			isize = (header[isd+ISD_W_PAGCNT+1]*256 +
238 				 header[isd+ISD_W_PAGCNT]) * 512;
239 			load_addr = (header[isd+ISD_V_VPN+1]*256 +
240 				     header[isd+ISD_V_VPN]) * 512;
241 			xfr_addr = (header[iha+IHA_L_TFRADR1+3]*0x1000000 +
242 				    header[iha+IHA_L_TFRADR1+2]*0x10000 +
243 				    header[iha+IHA_L_TFRADR1+1]*0x100 +
244 				    header[iha+IHA_L_TFRADR1]);
245 			printf("PMAX Image \n");
246 			printf("Header Block Count: %d\n",hbcnt);
247 			printf("Image Size:         %08x\n",isize);
248 			printf("Load Address:       %08x\n",load_addr);
249 			printf("Transfer Address:   %08x\n",xfr_addr);
250 			break;
251 		case IHD_C_ALPHA:		/* ALPHA system image	     */
252 			isd = (header[EIHD_L_ISDOFF+3]*0x1000000 +
253 			       header[EIHD_L_ISDOFF+2]*0x10000 +
254 			       header[EIHD_L_ISDOFF+1]*0x100 +
255 			       header[EIHD_L_ISDOFF]);
256 			hbcnt = (header[EIHD_L_HDRBLKCNT+3]*0x1000000 +
257 				 header[EIHD_L_HDRBLKCNT+2]*0x10000 +
258 				 header[EIHD_L_HDRBLKCNT+1]*0x100 +
259 				 header[EIHD_L_HDRBLKCNT]);
260 			isize = (header[isd+EISD_L_SECSIZE+3]*0x1000000 +
261 				 header[isd+EISD_L_SECSIZE+2]*0x10000 +
262 				 header[isd+EISD_L_SECSIZE+1]*0x100 +
263 				 header[isd+EISD_L_SECSIZE]);
264 			load_addr = 0;
265 			xfr_addr = 0;
266 			printf("Alpha Image \n");
267 			printf("Header Block Count: %d\n",hbcnt);
268 			printf("Image Size:         %08x\n",isize);
269 			printf("Load Address:       %08x\n",load_addr);
270 			printf("Transfer Address:   %08x\n",xfr_addr);
271 			break;
272 		default:
273 			printf("Unknown Image (%d)\n",image_type);
274 			return(-1);
275 	}
276 
277 	dl->image_type = IMAGE_TYPE_MOP;
278 	dl->loadaddr = load_addr;
279 	dl->xferaddr = xfr_addr;
280 
281 	return(0);
282 }
283 
284 #ifndef NOAOUT
285 int
286 getMID(old_mid,new_mid)
287 	int	old_mid, new_mid;
288 {
289 	int	mid;
290 
291 	mid = old_mid;
292 
293 	switch (new_mid) {
294 	case MID_I386:
295 		mid = MID_I386;
296 		break;
297 #ifdef MID_M68K
298 	case MID_M68K:
299 		mid = MID_M68K;
300 		break;
301 #endif
302 #ifdef MID_M68K4K
303 	case MID_M68K4K:
304 		mid = MID_M68K4K;
305 		break;
306 #endif
307 #ifdef MID_NS32532
308 	case MID_NS32532:
309 		mid = MID_NS32532;
310 		break;
311 #endif
312 	case MID_SPARC:
313 		mid = MID_SPARC;
314 		break;
315 #ifdef MID_PMAX
316 	case MID_PMAX:
317 		mid = MID_PMAX;
318 		break;
319 #endif
320 #ifdef MID_VAX
321 	case MID_VAX:
322 		mid = MID_VAX;
323 		break;
324 #endif
325 #ifdef MID_ALPHA
326 	case MID_ALPHA:
327 		mid = MID_ALPHA;
328 		break;
329 #endif
330 #ifdef MID_MIPS
331 	case MID_MIPS:
332 		mid = MID_MIPS;
333 		break;
334 #endif
335 #ifdef MID_ARM6
336 	case MID_ARM6:
337 		mid = MID_ARM6;
338 		break;
339 #endif
340 	default:
341 		break;
342 	}
343 
344 	return(mid);
345 }
346 
347 int
348 getCLBYTES(mid)
349 	int	mid;
350 {
351 	int	clbytes;
352 
353 	switch (mid) {
354 #ifdef MID_VAX
355 	case MID_VAX:
356 		clbytes = 1024;
357 		break;
358 #endif
359 #ifdef MID_I386
360 	case MID_I386:
361 #endif
362 #ifdef MID_M68K4K
363 	case MID_M68K4K:
364 #endif
365 #ifdef MID_NS32532
366 	case MID_NS32532:
367 #endif
368 #ifdef MID_PMAX
369 	case MID_PMAX:
370 #endif
371 #ifdef MID_MIPS
372 	case MID_MIPS:
373 #endif
374 #ifdef MID_ARM6
375 	case MID_ARM6:
376 #endif
377 #if defined(MID_I386) || defined(MID_M68K4K) || defined(MID_NS32532) || \
378     defined(MID_PMAX) || defined(MID_MIPS) || defined(MID_ARM6)
379 		clbytes = 4096;
380 		break;
381 #endif
382 #ifdef MID_M68K
383 	case MID_M68K:
384 #endif
385 #ifdef MID_ALPHA
386 	case MID_ALPHA:
387 #endif
388 #ifdef MID_SPARC
389 	case MID_SPARC:
390 #endif
391 #if defined(MID_M68K) || defined(MID_ALPHA) || defined(MID_SPARC)
392 		clbytes = 8192;
393 		break;
394 #endif
395 	default:
396 		clbytes = 0;
397 	}
398 
399 	return(clbytes);
400 }
401 #endif
402 
403 int
404 CheckElfFile(fd)
405 	int	fd;
406 {
407 #ifdef NOELF
408 	return(-1);
409 #else
410 	Elf32_Ehdr ehdr;
411 
412 	(void)lseek(fd, (off_t) 0, SEEK_SET);
413 
414 	if (read(fd, (char *)&ehdr, sizeof(ehdr)) != sizeof(ehdr))
415 		return(-1);
416 
417 	if (ehdr.e_ident[0] != ELFMAG0 ||
418 	    ehdr.e_ident[1] != ELFMAG1 ||
419 	    ehdr.e_ident[2] != ELFMAG2 ||
420 	    ehdr.e_ident[3] != ELFMAG3)
421 		return(-1);
422 
423 	/* Must be Elf32... */
424 	if (ehdr.e_ident[EI_CLASS] != ELFCLASS32)
425 		return(-1);
426 
427 	return(0);
428 #endif /* NOELF */
429 }
430 
431 int
432 GetElfFileInfo(dl)
433 	struct dllist	*dl;
434 {
435 #ifdef NOELF
436 	return(-1);
437 #else
438 	Elf32_Ehdr ehdr;
439 	Elf32_Phdr phdr;
440 	uint32_t e_machine, e_entry;
441 	uint32_t e_phoff, e_phentsize, e_phnum;
442 	int ei_data, i;
443 
444 	(void)lseek(dl->ldfd, (off_t) 0, SEEK_SET);
445 
446 	if (read(dl->ldfd, (char *)&ehdr, sizeof(ehdr)) != sizeof(ehdr))
447 		return(-1);
448 
449 	if (ehdr.e_ident[0] != ELFMAG0 ||
450 	    ehdr.e_ident[1] != ELFMAG1 ||
451 	    ehdr.e_ident[2] != ELFMAG2 ||
452 	    ehdr.e_ident[3] != ELFMAG3)
453 		return(-1);
454 
455 	/* Must be Elf32... */
456 	if (ehdr.e_ident[EI_CLASS] != ELFCLASS32)
457 		return(-1);
458 
459 	ei_data = ehdr.e_ident[EI_DATA];
460 
461 	switch (ei_data) {
462 	case ELFDATA2LSB:
463 		e_machine = mopFileGetLX((u_char *) &ehdr,
464 		    offsetof(Elf32_Ehdr, e_machine),
465 		    sizeof(ehdr.e_machine));
466 		e_entry = mopFileGetLX((u_char *) &ehdr,
467 		    offsetof(Elf32_Ehdr, e_entry),
468 		    sizeof(ehdr.e_entry));
469 
470 		e_phoff = mopFileGetLX((u_char *) &ehdr,
471 		    offsetof(Elf32_Ehdr, e_phoff),
472 		    sizeof(ehdr.e_phoff));
473 		e_phentsize = mopFileGetLX((u_char *) &ehdr,
474 		    offsetof(Elf32_Ehdr, e_phentsize),
475 		    sizeof(ehdr.e_phentsize));
476 		e_phnum = mopFileGetLX((u_char *) &ehdr,
477 		    offsetof(Elf32_Ehdr, e_phnum),
478 		    sizeof(ehdr.e_phnum));
479 		break;
480 
481 	case ELFDATA2MSB:
482 		e_machine = mopFileGetBX((u_char *) &ehdr,
483 		    offsetof(Elf32_Ehdr, e_machine),
484 		    sizeof(ehdr.e_machine));
485 		e_entry = mopFileGetBX((u_char *) &ehdr,
486 		    offsetof(Elf32_Ehdr, e_entry),
487 		    sizeof(ehdr.e_entry));
488 
489 		e_phoff = mopFileGetBX((u_char *) &ehdr,
490 		    offsetof(Elf32_Ehdr, e_phoff),
491 		    sizeof(ehdr.e_phoff));
492 		e_phentsize = mopFileGetBX((u_char *) &ehdr,
493 		    offsetof(Elf32_Ehdr, e_phentsize),
494 		    sizeof(ehdr.e_phentsize));
495 		e_phnum = mopFileGetBX((u_char *) &ehdr,
496 		    offsetof(Elf32_Ehdr, e_phnum),
497 		    sizeof(ehdr.e_phnum));
498 		break;
499 
500 	default:
501 		return(-1);
502 	}
503 
504 	dl->image_type = IMAGE_TYPE_ELF32;
505 	dl->loadaddr = e_entry;		/* We assume the standalone program */
506 	dl->xferaddr = e_entry;		/* will relocate itself if necessary */
507 
508 	if (e_phnum > SEC_MAX)
509 		return(-1);
510 	dl->e_nsec = e_phnum;
511 	for (i = 0; i < dl->e_nsec; i++) {
512 		if (lseek(dl->ldfd, (off_t) e_phoff + (i * e_phentsize),
513 		    SEEK_SET) == (off_t) -1)
514 			return(-1);
515 		if (read(dl->ldfd, (char *) &phdr, sizeof(phdr)) !=
516 		    sizeof(phdr))
517 			return(-1);
518 
519 		switch (ei_data) {
520 		case ELFDATA2LSB:
521 			dl->e_sections[i].s_foff =
522 			    mopFileGetLX((u_char *) &phdr,
523 			    offsetof(Elf32_Phdr, p_offset),
524 			    sizeof(phdr.p_offset));
525 			dl->e_sections[i].s_vaddr =
526 			    mopFileGetLX((u_char *) &phdr,
527 			    offsetof(Elf32_Phdr, p_vaddr),
528 			    sizeof(phdr.p_vaddr));
529 			dl->e_sections[i].s_fsize =
530 			    mopFileGetLX((u_char *) &phdr,
531 			    offsetof(Elf32_Phdr, p_filesz),
532 			    sizeof(phdr.p_filesz));
533 			dl->e_sections[i].s_msize =
534 			    mopFileGetLX((u_char *) &phdr,
535 			    offsetof(Elf32_Phdr, p_memsz),
536 			    sizeof(phdr.p_memsz));
537 			break;
538 
539 		case ELFDATA2MSB:
540 			dl->e_sections[i].s_foff =
541 			    mopFileGetBX((u_char *) &phdr,
542 			    offsetof(Elf32_Phdr, p_offset),
543 			    sizeof(phdr.p_offset));
544 			dl->e_sections[i].s_vaddr =
545 			    mopFileGetBX((u_char *) &phdr,
546 			    offsetof(Elf32_Phdr, p_vaddr),
547 			    sizeof(phdr.p_vaddr));
548 			dl->e_sections[i].s_fsize =
549 			    mopFileGetBX((u_char *) &phdr,
550 			    offsetof(Elf32_Phdr, p_filesz),
551 			    sizeof(phdr.p_filesz));
552 			dl->e_sections[i].s_msize =
553 			    mopFileGetBX((u_char *) &phdr,
554 			    offsetof(Elf32_Phdr, p_memsz),
555 			    sizeof(phdr.p_memsz));
556 			break;
557 
558 		default:
559 			return(-1);
560 		}
561 	}
562 	/*
563 	 * In addition to padding between segments, this also
564 	 * takes care of memsz > filesz.
565 	 */
566 	for (i = 0; i < dl->e_nsec - 1; i++) {
567 		dl->e_sections[i].s_pad =
568 		    dl->e_sections[i + 1].s_vaddr -
569 		    (dl->e_sections[i].s_vaddr + dl->e_sections[i].s_fsize);
570 	}
571 	dl->e_sections[dl->e_nsec - 1].s_pad =
572 	    dl->e_sections[dl->e_nsec - 1].s_msize -
573 	    dl->e_sections[dl->e_nsec - 1].s_fsize;
574 	/*
575 	 * Now compute the logical offsets for each section.
576 	 */
577 	dl->e_sections[0].s_loff = 0;
578 	for (i = 1; i < dl->e_nsec; i++) {
579 		dl->e_sections[i].s_loff =
580 		    dl->e_sections[i - 1].s_loff +
581 		    dl->e_sections[i - 1].s_fsize +
582 		    dl->e_sections[i - 1].s_pad;
583 	}
584 
585 	/* Print info about the image. */
586 	printf("Elf32 image (");
587 	switch (e_machine) {
588 #ifdef EM_VAX
589 	case EM_VAX:
590 		printf("VAX");
591 		break;
592 #endif
593 	default:
594 		printf("machine %d", e_machine);
595 		break;
596 	}
597 	printf(")\n");
598 	printf("Transfer Address:   %08x\n", dl->xferaddr);
599 	printf("Program Sections:   %d\n", dl->e_nsec);
600 	for (i = 0; i < dl->e_nsec; i++) {
601 		printf(" S%d File Size:      %08x\n", i,
602 		    dl->e_sections[i].s_fsize);
603 		printf(" S%d Pad Size:       %08x\n", i,
604 		    dl->e_sections[i].s_pad);
605 	}
606 
607 	dl->e_curpos = 0;
608 	dl->e_cursec = 0;
609 
610 	return(0);
611 #endif /* NOELF */
612 }
613 
614 int
615 CheckAOutFile(fd)
616 	int	fd;
617 {
618 #ifdef NOAOUT
619 	return(-1);
620 #else
621 	struct exec ex, ex_swap;
622 	int	mid = -1;
623 
624 	if (read(fd, (char *)&ex, sizeof(ex)) != sizeof(ex))
625 		return(-1);
626 
627 	(void)lseek(fd, (off_t) 0, SEEK_SET);
628 
629 	if (read(fd, (char *)&ex_swap, sizeof(ex_swap)) != sizeof(ex_swap))
630 		return(-1);
631 
632 	(void)lseek(fd, (off_t) 0, SEEK_SET);
633 
634 	mid = getMID(mid, N_GETMID (ex));
635 
636 	if (mid == -1) {
637 		mid = getMID(mid, N_GETMID (ex_swap));
638 	}
639 
640 	if (mid != -1) {
641 		return(0);
642 	} else {
643 		return(-1);
644 	}
645 #endif /* NOAOUT */
646 }
647 
648 int
649 GetAOutFileInfo(dl)
650 	struct dllist	*dl;
651 {
652 #ifdef NOAOUT
653 	return(-1);
654 #else
655 	struct exec ex, ex_swap;
656 	u_int32_t	mid = -1;
657 	u_int32_t	magic, clbytes, clofset;
658 
659 	if (read(dl->ldfd, (char *)&ex, sizeof(ex)) != sizeof(ex))
660 		return(-1);
661 
662 	(void)lseek(dl->ldfd, (off_t) 0, SEEK_SET);
663 
664 	if (read(dl->ldfd, (char *)&ex_swap,
665 		 sizeof(ex_swap)) != sizeof(ex_swap))
666 		return(-1);
667 
668 	mopFileSwapX((u_char *)&ex_swap, 0, 4);
669 
670 	mid = getMID(mid, N_GETMID (ex));
671 
672 	if (mid == -1) {
673 		mid = getMID(mid, N_GETMID (ex_swap));
674 		if (mid != -1) {
675 			mopFileSwapX((u_char *)&ex, 0, 4);
676 		}
677 	}
678 
679 	if (mid == -1) {
680 		return(-1);
681 	}
682 
683 	if (N_BADMAG (ex)) {
684 		return(-1);
685 	}
686 
687 	switch (mid) {
688 	case MID_I386:
689 #ifdef MID_NS32532
690 	case MID_NS32532:
691 #endif
692 #ifdef MID_PMAX
693 	case MID_PMAX:
694 #endif
695 #ifdef MID_VAX
696 	case MID_VAX:
697 #endif
698 #ifdef MID_ALPHA
699 	case MID_ALPHA:
700 #endif
701 #ifdef MID_ARM6
702 	case MID_ARM6:
703 #endif
704 		ex.a_text  = mopFileGetLX((u_char *)&ex_swap,  4, 4);
705 		ex.a_data  = mopFileGetLX((u_char *)&ex_swap,  8, 4);
706 		ex.a_bss   = mopFileGetLX((u_char *)&ex_swap, 12, 4);
707 		ex.a_syms  = mopFileGetLX((u_char *)&ex_swap, 16, 4);
708 		ex.a_entry = mopFileGetLX((u_char *)&ex_swap, 20, 4);
709 		ex.a_trsize= mopFileGetLX((u_char *)&ex_swap, 24, 4);
710 		ex.a_drsize= mopFileGetLX((u_char *)&ex_swap, 28, 4);
711 		break;
712 #ifdef MID_M68K
713 	case MID_M68K:
714 #endif
715 #ifdef MID_M68K4K
716 	case MID_M68K4K:
717 #endif
718 	case MID_SPARC:
719 #ifdef MID_MIPS
720 	case MID_MIPS:
721 #endif
722 		ex.a_text  = mopFileGetBX((u_char *)&ex_swap,  4, 4);
723 		ex.a_data  = mopFileGetBX((u_char *)&ex_swap,  8, 4);
724 		ex.a_bss   = mopFileGetBX((u_char *)&ex_swap, 12, 4);
725 		ex.a_syms  = mopFileGetBX((u_char *)&ex_swap, 16, 4);
726 		ex.a_entry = mopFileGetBX((u_char *)&ex_swap, 20, 4);
727 		ex.a_trsize= mopFileGetBX((u_char *)&ex_swap, 24, 4);
728 		ex.a_drsize= mopFileGetBX((u_char *)&ex_swap, 28, 4);
729 		break;
730 	default:
731 		break;
732 	}
733 
734 	printf("a.out image (");
735 	switch (N_GETMID (ex)) {
736 	case MID_I386:
737 		printf("i386");
738 		break;
739 #ifdef MID_M68K
740 	case MID_M68K:
741 		printf("m68k");
742 		break;
743 #endif
744 #ifdef MID_M68K4K
745 	case MID_M68K4K:
746 		printf("m68k 4k");
747 		break;
748 #endif
749 #ifdef MID_NS32532
750 	case MID_NS32532:
751 		printf("pc532");
752 		break;
753 #endif
754 	case MID_SPARC:
755 		printf("sparc");
756 		break;
757 #ifdef MID_PMAX
758 	case MID_PMAX:
759 		printf("pmax");
760 		break;
761 #endif
762 #ifdef MID_VAX
763 	case MID_VAX:
764 		printf("vax");
765 		break;
766 #endif
767 #ifdef MID_ALPHA
768 	case MID_ALPHA:
769 		printf("alpha");
770 		break;
771 #endif
772 #ifdef MID_MIPS
773 	case MID_MIPS:
774 		printf("mips");
775 		break;
776 #endif
777 #ifdef MID_ARM6
778 	case MID_ARM6:
779 		printf("arm32");
780 		break;
781 #endif
782 	default:
783 		break;
784 	}
785 	printf(") Magic: ");
786 	switch (N_GETMAGIC (ex)) {
787 	case OMAGIC:
788 		printf("OMAGIC");
789 		break;
790 	case NMAGIC:
791 		printf("NMAGIC");
792 		break;
793 	case ZMAGIC:
794 		printf("ZMAGIC");
795 		break;
796 	case QMAGIC:
797 		printf("QMAGIC");
798 		break;
799 	default:
800 		printf("Unknown %ld", (long) N_GETMAGIC (ex));
801 	}
802 	printf("\n");
803 	printf("Size of text:       %08lx\n", (long)ex.a_text);
804 	printf("Size of data:       %08lx\n", (long)ex.a_data);
805 	printf("Size of bss:        %08lx\n", (long)ex.a_bss);
806 	printf("Size of symbol tab: %08lx\n", (long)ex.a_syms);
807 	printf("Transfer Address:   %08lx\n", (long)ex.a_entry);
808 	printf("Size of reloc text: %08lx\n", (long)ex.a_trsize);
809 	printf("Size of reloc data: %08lx\n", (long)ex.a_drsize);
810 
811 	magic = N_GETMAGIC (ex);
812 	clbytes = getCLBYTES(mid);
813 	clofset = clbytes - 1;
814 
815 	dl->image_type = IMAGE_TYPE_AOUT;
816 	dl->loadaddr = 0;
817 	dl->xferaddr = ex.a_entry;
818 
819 	dl->a_text = ex.a_text;
820 	if (magic == ZMAGIC || magic == NMAGIC) {
821 		dl->a_text_fill = clbytes - (ex.a_text & clofset);
822 		if (dl->a_text_fill == clbytes)
823 			dl->a_text_fill = 0;
824 	} else
825 		dl->a_text_fill = 0;
826 	dl->a_data = ex.a_data;
827 	if (magic == ZMAGIC || magic == NMAGIC) {
828 		dl->a_data_fill = clbytes - (ex.a_data & clofset);
829 		if (dl->a_data_fill == clbytes)
830 			dl->a_data_fill = 0;
831 	} else
832 		dl->a_data_fill = 0;
833 	dl->a_bss = ex.a_bss;
834 	if (magic == ZMAGIC || magic == NMAGIC) {
835 		dl->a_bss_fill = clbytes - (ex.a_bss & clofset);
836 		if (dl->a_bss_fill == clbytes)
837 			dl->a_bss_fill = 0;
838 	} else {
839 		dl->a_bss_fill = clbytes -
840 		    ((ex.a_text+ex.a_data+ex.a_bss) & clofset);
841 		if (dl->a_bss_fill == clbytes)
842 			dl->a_bss_fill = 0;
843 	}
844 	dl->a_mid = mid;
845 
846 	return(0);
847 #endif /* NOAOUT */
848 }
849 
850 int
851 GetFileInfo(dl)
852 	struct dllist	*dl;
853 {
854 	int	err;
855 
856 	err = CheckElfFile(dl->ldfd);
857 	if (err == 0) {
858 		err = GetElfFileInfo(dl);
859 		if (err != 0) {
860 			return(-1);
861 		}
862 		return (0);
863 	}
864 
865 	err = CheckAOutFile(dl->ldfd);
866 	if (err == 0) {
867 		err = GetAOutFileInfo(dl);
868 		if (err != 0) {
869 			return(-1);
870 		}
871 		return (0);
872 	}
873 
874 	err = CheckMopFile(dl->ldfd);
875 	if (err == 0) {
876 		err = GetMopFileInfo(dl);
877 		if (err != 0) {
878 			return(-1);
879 		}
880 		return (0);
881 	}
882 
883 	/* Unknown file format. */
884 	return(-1);
885 }
886 
887 ssize_t
888 mopFileRead(dlslot, buf)
889 	struct dllist *dlslot;
890 	u_char	*buf;
891 {
892 	ssize_t len, outlen;
893 	int	bsz, sec;
894 	int32_t	pos, notdone, total;
895 	uint32_t secoff;
896 
897 	switch (dlslot->image_type) {
898 	case IMAGE_TYPE_MOP:
899 		len = read(dlslot->ldfd,buf,dlslot->dl_bsz);
900 		break;
901 
902 	case IMAGE_TYPE_ELF32:
903 		sec = dlslot->e_cursec;
904 
905 		/*
906 		 * We're pretty simplistic here.  We do only file-backed
907 		 * or only zero-fill.
908 		 */
909 
910 		/* Determine offset into section. */
911 		secoff = dlslot->e_curpos - dlslot->e_sections[sec].s_loff;
912 
913 		/*
914 		 * If we're in the file-backed part of the section,
915 		 * transmit some of the file.
916 		 */
917 		if (secoff < dlslot->e_sections[sec].s_fsize) {
918 			bsz = dlslot->e_sections[sec].s_fsize - secoff;
919 			if (bsz > dlslot->dl_bsz)
920 				bsz = dlslot->dl_bsz;
921 			if (lseek(dlslot->ldfd,
922 			    dlslot->e_sections[sec].s_foff + secoff,
923 			    SEEK_SET) == (off_t) -1)
924 				return (-1);
925 			len = read(dlslot->ldfd, buf, bsz);
926 		}
927 		/*
928 		 * Otherwise, if we're in the zero-fill part of the
929 		 * section, transmit some zeros.
930 		 */
931 		else if (secoff < (dlslot->e_sections[sec].s_fsize +
932 				   dlslot->e_sections[sec].s_pad)) {
933 			bsz = dlslot->e_sections[sec].s_pad -
934 			    (secoff - dlslot->e_sections[sec].s_fsize);
935 			if (bsz > dlslot->dl_bsz)
936 				bsz = dlslot->dl_bsz;
937 			memset(buf, 0, (len = bsz));
938 		}
939 		/*
940 		 * ...and if we haven't hit either of those cases,
941 		 * that's the end of the image.
942 		 */
943 		else {
944 			return (0);
945 		}
946 		/*
947 		 * Advance the logical image pointer.
948 		 */
949 		dlslot->e_curpos += bsz;
950 		if (dlslot->e_curpos >= (dlslot->e_sections[sec].s_loff +
951 					 dlslot->e_sections[sec].s_fsize +
952 					 dlslot->e_sections[sec].s_pad))
953 			dlslot->e_cursec++;
954 		break;
955 
956 	case IMAGE_TYPE_AOUT:
957 		bsz = dlslot->dl_bsz;
958 		pos = dlslot->a_lseek;
959 		len = 0;
960 
961 		total = dlslot->a_text;
962 
963 		if (pos < total) {
964 			notdone = total - pos;
965 			if (notdone <= bsz) {
966 				outlen = read(dlslot->ldfd,&buf[len],notdone);
967 			} else {
968 				outlen = read(dlslot->ldfd,&buf[len],bsz);
969 			}
970 			len = len + outlen;
971 			pos = pos + outlen;
972 			bsz = bsz - outlen;
973 		}
974 
975 		total = total + dlslot->a_text_fill;
976 
977 		if ((bsz > 0) && (pos < total)) {
978 			notdone = total - pos;
979 			if (notdone <= bsz) {
980 				outlen = notdone;
981 			} else {
982 				outlen = bsz;
983 			}
984 			memset(&buf[len], 0, outlen);
985 			len = len + outlen;
986 			pos = pos + outlen;
987 			bsz = bsz - outlen;
988 		}
989 
990 		total = total + dlslot->a_data;
991 
992 		if ((bsz > 0) && (pos < total)) {
993 			notdone = total - pos;
994 			if (notdone <= bsz) {
995 				outlen = read(dlslot->ldfd,&buf[len],notdone);
996 			} else {
997 				outlen = read(dlslot->ldfd,&buf[len],bsz);
998 			}
999 			len = len + outlen;
1000 			pos = pos + outlen;
1001 			bsz = bsz - outlen;
1002 		}
1003 
1004 		total = total + dlslot->a_data_fill;
1005 
1006 		if ((bsz > 0) && (pos < total)) {
1007 			notdone = total - pos;
1008 			if (notdone <= bsz) {
1009 				outlen = notdone;
1010 			} else {
1011 				outlen = bsz;
1012 			}
1013 			memset(&buf[len], 0, outlen);
1014 			len = len + outlen;
1015 			pos = pos + outlen;
1016 			bsz = bsz - outlen;
1017 		}
1018 
1019 		total = total + dlslot->a_bss;
1020 
1021 		if ((bsz > 0) && (pos < total)) {
1022 			notdone = total - pos;
1023 			if (notdone <= bsz) {
1024 				outlen = notdone;
1025 			} else {
1026 				outlen = bsz;
1027 			}
1028 			memset(&buf[len], 0, outlen);
1029 			len = len + outlen;
1030 			pos = pos + outlen;
1031 			bsz = bsz - outlen;
1032 		}
1033 
1034 		total = total + dlslot->a_bss_fill;
1035 
1036 		if ((bsz > 0) && (pos < total)) {
1037 			notdone = total - pos;
1038 			if (notdone <= bsz) {
1039 				outlen = notdone;
1040 			} else {
1041 				outlen = bsz;
1042 			}
1043 			memset(&buf[len], 0, outlen);
1044 			len = len + outlen;
1045 			pos = pos + outlen;
1046 			bsz = bsz - outlen;
1047 		}
1048 
1049 		dlslot->a_lseek = pos;
1050 		break;
1051 	}
1052 
1053 	return(len);
1054 }
1055