file.c revision 1.12 1 /* $NetBSD: file.c,v 1.12 2009/10/20 00:51:13 snj 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 *
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.
25 */
26
27 #include <sys/cdefs.h>
28 #ifndef lint
29 __RCSID("$NetBSD: file.c,v 1.12 2009/10/20 00:51:13 snj Exp $");
30 #endif
31
32 #include "os.h"
33 #include "common.h"
34 #include "file.h"
35 #include "mopdef.h"
36 #include <stddef.h>
37
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 */
52
53 #ifndef NOELF
54 # if defined(__NetBSD__)
55 # include <sys/exec_elf.h>
56 # else
57 # define NOELF
58 # endif
59 #endif /* NOELF */
60
61 int getCLBYTES __P((int));
62 int getMID __P((int, int));
63
64 const char *
65 FileTypeName(type)
66 mopd_imagetype type;
67 {
68
69 switch (type) {
70 case IMAGE_TYPE_MOP:
71 return ("MOP");
72
73 case IMAGE_TYPE_ELF32:
74 return ("Elf32");
75
76 case IMAGE_TYPE_AOUT:
77 return ("a.out");
78 }
79
80 abort();
81 }
82
83 void
84 mopFilePutLX(buf, idx, value, cnt)
85 u_char *buf;
86 int idx, cnt;
87 u_int32_t value;
88 {
89 int i;
90 for (i = 0; i < cnt; i++) {
91 buf[idx+i] = value % 256;
92 value = value / 256;
93 }
94 }
95
96 void
97 mopFilePutBX(buf, idx, value, cnt)
98 u_char *buf;
99 int idx, cnt;
100 u_int32_t value;
101 {
102 int i;
103 for (i = 0; i < cnt; i++) {
104 buf[idx+cnt-1-i] = value % 256;
105 value = value / 256;
106 }
107 }
108
109 u_int32_t
110 mopFileGetLX(buf, idx, cnt)
111 u_char *buf;
112 int idx, cnt;
113 {
114 u_int32_t ret = 0;
115 int i;
116
117 for (i = 0; i < cnt; i++) {
118 ret = ret*256 + buf[idx+cnt-1-i];
119 }
120
121 return(ret);
122 }
123
124 u_int32_t
125 mopFileGetBX(buf, idx, cnt)
126 u_char *buf;
127 int idx, cnt;
128 {
129 u_int32_t ret = 0;
130 int i;
131
132 for (i = 0; i < cnt; i++) {
133 ret = ret*256 + buf[idx+i];
134 }
135
136 return(ret);
137 }
138
139 void
140 mopFileSwapX(buf, idx, cnt)
141 u_char *buf;
142 int idx, cnt;
143 {
144 int i;
145 u_char c;
146
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;
151 }
152
153 }
154
155 int
156 CheckMopFile(fd)
157 int fd;
158 {
159 u_char header[512];
160 short image_type;
161
162 if (read(fd, header, 512) != 512)
163 return(-1);
164
165 (void)lseek(fd, (off_t) 0, SEEK_SET);
166
167 image_type = (u_short)(header[IHD_W_ALIAS+1]*256 +
168 header[IHD_W_ALIAS]);
169
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);
181 }
182
183 return(0);
184 }
185
186 int
187 GetMopFileInfo(dl)
188 struct dllist *dl;
189 {
190 u_char header[512];
191 short image_type;
192 u_int32_t load_addr, xfr_addr, isd, iha, hbcnt, isize;
193
194 if (read(dl->ldfd, header, 512) != 512)
195 return(-1);
196
197 image_type = (u_short)(header[IHD_W_ALIAS+1]*256 +
198 header[IHD_W_ALIAS]);
199
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);
289 }
290
291 dl->image_type = IMAGE_TYPE_MOP;
292 dl->loadaddr = load_addr;
293 dl->xferaddr = xfr_addr;
294
295 return(0);
296 }
297
298 #ifndef NOAOUT
299 int
300 getMID(old_mid,new_mid)
301 int old_mid, new_mid;
302 {
303 int mid;
304
305 mid = old_mid;
306
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;
356 }
357
358 return(mid);
359 }
360
361 int
362 getCLBYTES(mid)
363 int mid;
364 {
365 int clbytes;
366
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;
411 }
412
413 return(clbytes);
414 }
415 #endif
416
417 int
418 CheckElfFile(fd)
419 int fd;
420 {
421 #ifdef NOELF
422 return(-1);
423 #else
424 Elf32_Ehdr ehdr;
425
426 (void)lseek(fd, (off_t) 0, SEEK_SET);
427
428 if (read(fd, (char *)&ehdr, sizeof(ehdr)) != sizeof(ehdr))
429 return(-1);
430
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);
436
437 /* Must be Elf32... */
438 if (ehdr.e_ident[EI_CLASS] != ELFCLASS32)
439 return(-1);
440
441 return(0);
442 #endif /* NOELF */
443 }
444
445 int
446 GetElfFileInfo(dl)
447 struct dllist *dl;
448 {
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;
457
458 (void)lseek(dl->ldfd, (off_t) 0, SEEK_SET);
459
460 if (read(dl->ldfd, (char *)&ehdr, sizeof(ehdr)) != sizeof(ehdr))
461 return(-1);
462
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);
468
469 /* Must be Elf32... */
470 if (ehdr.e_ident[EI_CLASS] != ELFCLASS32)
471 return(-1);
472
473 ei_data = ehdr.e_ident[EI_DATA];
474
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));
483
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;
494
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));
502
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;
513
514 default:
515 return(-1);
516 }
517
518 dl->image_type = IMAGE_TYPE_ELF32;
519 dl->loadaddr = 0;
520 dl->xferaddr = e_entry; /* will relocate itself if necessary */
521
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);
532
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;
552
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;
571
572 default:
573 return(-1);
574 }
575 }
576 /*
577 * In addition to padding between segments, this also
578 * takes care of memsz > filesz.
579 */
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);
584 }
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;
588 /*
589 * Now compute the logical offsets for each section.
590 */
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;
597 }
598
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;
610 }
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);
619 }
620 dl->e_machine = e_machine;
621
622 dl->e_curpos = 0;
623 dl->e_cursec = 0;
624
625 return(0);
626 #endif /* NOELF */
627 }
628
629 int
630 CheckAOutFile(fd)
631 int fd;
632 {
633 #ifdef NOAOUT
634 return(-1);
635 #else
636 struct exec ex, ex_swap;
637 int mid = -1;
638
639 if (read(fd, (char *)&ex, sizeof(ex)) != sizeof(ex))
640 return(-1);
641
642 (void)lseek(fd, (off_t) 0, SEEK_SET);
643
644 if (read(fd, (char *)&ex_swap, sizeof(ex_swap)) != sizeof(ex_swap))
645 return(-1);
646
647 (void)lseek(fd, (off_t) 0, SEEK_SET);
648
649 mid = getMID(mid, N_GETMID (ex));
650
651 if (mid == -1) {
652 mid = getMID(mid, N_GETMID (ex_swap));
653 }
654
655 if (mid != -1) {
656 return(0);
657 } else {
658 return(-1);
659 }
660 #endif /* NOAOUT */
661 }
662
663 int
664 GetAOutFileInfo(dl)
665 struct dllist *dl;
666 {
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;
673
674 if (read(dl->ldfd, (char *)&ex, sizeof(ex)) != sizeof(ex))
675 return(-1);
676
677 (void)lseek(dl->ldfd, (off_t) 0, SEEK_SET);
678
679 if (read(dl->ldfd, (char *)&ex_swap,
680 sizeof(ex_swap)) != sizeof(ex_swap))
681 return(-1);
682
683 mopFileSwapX((u_char *)&ex_swap, 0, 4);
684
685 mid = getMID(mid, N_GETMID (ex));
686
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);
691 }
692 }
693
694 if (mid == (uint32_t)-1) {
695 return(-1);
696 }
697
698 if (N_BADMAG (ex)) {
699 return(-1);
700 }
701
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;
747 }
748
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;
799 }
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));
816 }
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);
825
826 magic = N_GETMAGIC (ex);
827 clbytes = getCLBYTES(mid);
828 clofset = clbytes - 1;
829
830 dl->image_type = IMAGE_TYPE_AOUT;
831 dl->loadaddr = 0;
832 dl->xferaddr = ex.a_entry;
833
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;
858 }
859 dl->a_mid = mid;
860
861 return(0);
862 #endif /* NOAOUT */
863 }
864
865 int
866 GetFileInfo(dl)
867 struct dllist *dl;
868 {
869 int error;
870
871 error = CheckElfFile(dl->ldfd);
872 if (error == 0) {
873 error = GetElfFileInfo(dl);
874 if (error != 0) {
875 return(-1);
876 }
877 return (0);
878 }
879
880 error = CheckAOutFile(dl->ldfd);
881 if (error == 0) {
882 error = GetAOutFileInfo(dl);
883 if (error != 0) {
884 return(-1);
885 }
886 return (0);
887 }
888
889 error = CheckMopFile(dl->ldfd);
890 if (error == 0) {
891 error = GetMopFileInfo(dl);
892 if (error != 0) {
893 return(-1);
894 }
895 return (0);
896 }
897
898 /* Unknown file format. */
899 return(-1);
900 }
901
902 ssize_t
903 mopFileRead(dlslot, buf)
904 struct dllist *dlslot;
905 u_char *buf;
906 {
907 ssize_t len, outlen;
908 int bsz, sec;
909 int32_t pos, notdone, total;
910 uint32_t secoff;
911
912 switch (dlslot->image_type) {
913 case IMAGE_TYPE_MOP:
914 len = read(dlslot->ldfd,buf,dlslot->dl_bsz);
915 break;
916
917 case IMAGE_TYPE_ELF32:
918 sec = dlslot->e_cursec;
919
920 /*
921 * We're pretty simplistic here. We do only file-backed
922 * or only zero-fill.
923 */
924
925 /* Determine offset into section. */
926 secoff = dlslot->e_curpos - dlslot->e_sections[sec].s_loff;
927
928 /*
929 * If we're in the file-backed part of the section,
930 * transmit some of the file.
931 */
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);
941 }
942 /*
943 * Otherwise, if we're in the zero-fill part of the
944 * section, transmit some zeros.
945 */
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));
953 }
954 /*
955 * ...and if we haven't hit either of those cases,
956 * that's the end of the image.
957 */
958 else {
959 return (0);
960 }
961 /*
962 * Advance the logical image pointer.
963 */
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;
970
971 case IMAGE_TYPE_AOUT:
972 bsz = dlslot->dl_bsz;
973 pos = dlslot->a_lseek;
974 len = 0;
975
976 total = dlslot->a_text;
977
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);
984 }
985 len = len + outlen;
986 pos = pos + outlen;
987 bsz = bsz - outlen;
988 }
989
990 total = total + dlslot->a_text_fill;
991
992 if ((bsz > 0) && (pos < total)) {
993 notdone = total - pos;
994 if (notdone <= bsz) {
995 outlen = notdone;
996 } else {
997 outlen = bsz;
998 }
999 memset(&buf[len], 0, outlen);
1000 len = len + outlen;
1001 pos = pos + outlen;
1002 bsz = bsz - outlen;
1003 }
1004
1005 total = total + dlslot->a_data;
1006
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);
1013 }
1014 len = len + outlen;
1015 pos = pos + outlen;
1016 bsz = bsz - outlen;
1017 }
1018
1019 total = total + dlslot->a_data_fill;
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;
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 total = total + dlslot->a_bss_fill;
1050
1051 if ((bsz > 0) && (pos < total)) {
1052 notdone = total - pos;
1053 if (notdone <= bsz) {
1054 outlen = notdone;
1055 } else {
1056 outlen = bsz;
1057 }
1058 memset(&buf[len], 0, outlen);
1059 len = len + outlen;
1060 pos = pos + outlen;
1061 bsz = bsz - outlen;
1062 }
1063
1064 dlslot->a_lseek = pos;
1065 break;
1066
1067 default:
1068 abort();
1069 }
1070
1071 return(len);
1072 }
1073