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