file.c revision 1.8 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