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