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