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