file.c revision 1.20 1 /* $NetBSD: file.c,v 1.20 2024/12/03 05:57:02 kalvisd 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 #if defined (HAVE_NBTOOL_CONFIG_H)
28 # include "nbtool_config.h"
29 #else
30 # include "port.h"
31 #endif /* defined (HAVE_NBTOOL_CONFIG_H) */
32 #ifndef lint
33 __RCSID("$NetBSD: file.c,v 1.20 2024/12/03 05:57:02 kalvisd Exp $");
34 #endif
35
36 #include "os.h"
37 #include "common.h"
38 #include "file.h"
39 #include "mopdef.h"
40 #include <stddef.h>
41
42 #ifndef NOAOUT
43 # if defined (HAVE_NBTOOL_CONFIG_H) || defined(__NetBSD__) || defined(__OpenBSD__)
44 # include <sys/exec_aout.h>
45 # endif
46 # if defined(__bsdi__)
47 # define NOAOUT
48 # endif
49 # if defined(__FreeBSD__)
50 # include <sys/imgact_aout.h>
51 # endif
52 # if !defined(MID_VAX)
53 # define MID_VAX 150
54 # endif
55 # if !defined(MID_VAX1K)
56 # define MID_VAX1K 140
57 # endif
58 #endif /* NOAOUT */
59
60 #ifndef NOELF
61 # if defined (HAVE_NBTOOL_CONFIG_H) || defined(__NetBSD__)
62 # include <sys/exec_elf.h>
63 # else
64 # define NOELF
65 # endif
66 #endif /* NOELF */
67
68 #ifndef NOAOUT
69 static int getCLBYTES(int);
70 static int getMID(int, int);
71 #endif
72
73 const char *
74 FileTypeName(mopd_imagetype type)
75 {
76
77 switch (type) {
78 case IMAGE_TYPE_MOP:
79 return ("MOP");
80
81 case IMAGE_TYPE_ELF32:
82 return ("Elf32");
83
84 case IMAGE_TYPE_AOUT:
85 return ("a.out");
86 }
87
88 abort();
89 }
90
91 void
92 mopFilePutLX(u_char *buf, int idx, u_int32_t value, int cnt)
93 {
94 int i;
95 for (i = 0; i < cnt; i++) {
96 buf[idx+i] = value % 256;
97 value = value / 256;
98 }
99 }
100
101 void
102 mopFilePutBX(u_char *buf, int idx, u_int32_t value, int cnt)
103 {
104 int i;
105 for (i = 0; i < cnt; i++) {
106 buf[idx+cnt-1-i] = value % 256;
107 value = value / 256;
108 }
109 }
110
111 u_int32_t
112 mopFileGetLX(u_char *buf, int idx, int 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(u_char *buf, int idx, int cnt)
129 {
130 u_int32_t ret = 0;
131 int i;
132
133 for (i = 0; i < cnt; i++) {
134 int j = idx + i;
135 if (j < 0)
136 abort();
137 ret = ret * 256 + buf[j];
138 }
139
140 return(ret);
141 }
142
143 void
144 mopFileSwapX(u_char *buf, int idx, int cnt)
145 {
146 int i;
147 u_char c;
148
149 for (i = 0; i < (cnt / 2); i++) {
150 c = buf[idx+i];
151 buf[idx+i] = buf[idx+cnt-1-i];
152 buf[idx+cnt-1-i] = c;
153 }
154
155 }
156
157 int
158 CheckMopFile(int fd)
159 {
160 u_char header[512];
161 short image_type;
162
163 if (read(fd, header, 512) != 512)
164 return(-1);
165
166 (void)lseek(fd, (off_t) 0, SEEK_SET);
167
168 image_type = (u_short)(header[IHD_W_ALIAS+1]*256 +
169 header[IHD_W_ALIAS]);
170
171 switch(image_type) {
172 case IHD_C_NATIVE: /* Native mode image (VAX) */
173 case IHD_C_RSX: /* RSX image produced by TKB */
174 case IHD_C_BPA: /* BASIC plus analog */
175 case IHD_C_ALIAS: /* Alias */
176 case IHD_C_CLI: /* Image is CLI */
177 case IHD_C_PMAX: /* PMAX system image */
178 case IHD_C_ALPHA: /* ALPHA system image */
179 break;
180 default:
181 return(-1);
182 }
183
184 return(0);
185 }
186
187 int
188 GetMopFileInfo(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 static int
300 getMID(int old_mid, int new_mid)
301 {
302 int mid;
303
304 mid = old_mid;
305
306 switch (new_mid) {
307 case MID_I386:
308 mid = MID_I386;
309 break;
310 #ifdef MID_M68K
311 case MID_M68K:
312 mid = MID_M68K;
313 break;
314 #endif
315 #ifdef MID_M68K4K
316 case MID_M68K4K:
317 mid = MID_M68K4K;
318 break;
319 #endif
320 #ifdef MID_NS32532
321 case MID_NS32532:
322 mid = MID_NS32532;
323 break;
324 #endif
325 case MID_SPARC:
326 mid = MID_SPARC;
327 break;
328 #ifdef MID_PMAX
329 case MID_PMAX:
330 mid = MID_PMAX;
331 break;
332 #endif
333 #ifdef MID_VAX
334 case MID_VAX:
335 mid = MID_VAX;
336 break;
337 #endif
338 #ifdef MID_VAX1K
339 case MID_VAX1K:
340 mid = MID_VAX1K;
341 break;
342 #endif
343 #ifdef MID_ALPHA
344 case MID_ALPHA:
345 mid = MID_ALPHA;
346 break;
347 #endif
348 #ifdef MID_MIPS
349 case MID_MIPS:
350 mid = MID_MIPS;
351 break;
352 #endif
353 #ifdef MID_ARM6
354 case MID_ARM6:
355 mid = MID_ARM6;
356 break;
357 #endif
358 default:
359 break;
360 }
361
362 return(mid);
363 }
364
365 static int
366 getCLBYTES(int mid)
367 {
368 int clbytes;
369
370 switch (mid) {
371 #ifdef MID_VAX1K
372 case MID_VAX1K:
373 clbytes = 1024;
374 break;
375 #endif
376 #ifdef MID_I386
377 case MID_I386:
378 #endif
379 #ifdef MID_M68K4K
380 case MID_M68K4K:
381 #endif
382 #ifdef MID_NS32532
383 case MID_NS32532:
384 #endif
385 #ifdef MID_PMAX
386 case MID_PMAX:
387 #endif
388 #ifdef MID_MIPS
389 case MID_MIPS:
390 #endif
391 #ifdef MID_ARM6
392 case MID_ARM6:
393 #endif
394 #ifdef MID_VAX
395 case MID_VAX:
396 #endif
397 #if defined(MID_I386) || defined(MID_M68K4K) || defined(MID_NS32532) || \
398 defined(MID_PMAX) || defined(MID_MIPS) || defined(MID_ARM6) || \
399 defined(MID_VAX)
400 clbytes = 4096;
401 break;
402 #endif
403 #ifdef MID_M68K
404 case MID_M68K:
405 #endif
406 #ifdef MID_ALPHA
407 case MID_ALPHA:
408 #endif
409 #ifdef MID_SPARC
410 case MID_SPARC:
411 #endif
412 #if defined(MID_M68K) || defined(MID_ALPHA) || defined(MID_SPARC)
413 clbytes = 8192;
414 break;
415 #endif
416 default:
417 clbytes = 0;
418 }
419
420 return(clbytes);
421 }
422 #endif
423
424 int
425 CheckElfFile(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(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(int fd)
636 {
637 #ifdef NOAOUT
638 return(-1);
639 #else
640 struct exec ex, ex_swap;
641 int mid = -1;
642
643 if (read(fd, (char *)&ex, sizeof(ex)) != sizeof(ex))
644 return(-1);
645
646 (void)lseek(fd, (off_t) 0, SEEK_SET);
647
648 if (read(fd, (char *)&ex_swap, sizeof(ex_swap)) != sizeof(ex_swap))
649 return(-1);
650
651 (void)lseek(fd, (off_t) 0, SEEK_SET);
652
653 mid = getMID(mid, N_GETMID (ex));
654
655 if (mid == -1) {
656 mid = getMID(mid, N_GETMID (ex_swap));
657 }
658
659 if (mid != -1) {
660 return(0);
661 } else {
662 return(-1);
663 }
664 #endif /* NOAOUT */
665 }
666
667 int
668 GetAOutFileInfo(struct dllist *dl)
669 {
670 #ifdef NOAOUT
671 return(-1);
672 #else
673 struct exec ex, ex_swap;
674 u_int32_t mid = -1;
675 u_int32_t magic, clbytes, clofset;
676
677 if (read(dl->ldfd, (char *)&ex, sizeof(ex)) != sizeof(ex))
678 return(-1);
679
680 (void)lseek(dl->ldfd, (off_t) 0, SEEK_SET);
681
682 if (read(dl->ldfd, (char *)&ex_swap,
683 sizeof(ex_swap)) != sizeof(ex_swap))
684 return(-1);
685
686 mopFileSwapX((u_char *)&ex_swap, 0, 4);
687
688 mid = getMID(mid, N_GETMID (ex));
689
690 if (mid == (uint32_t)-1) {
691 mid = getMID(mid, N_GETMID (ex_swap));
692 if (mid != (uint32_t)-1) {
693 mopFileSwapX((u_char *)&ex, 0, 4);
694 }
695 }
696
697 if (mid == (uint32_t)-1) {
698 return(-1);
699 }
700
701 if (N_BADMAG (ex)) {
702 return(-1);
703 }
704
705 switch (mid) {
706 case MID_I386:
707 #ifdef MID_NS32532
708 case MID_NS32532:
709 #endif
710 #ifdef MID_PMAX
711 case MID_PMAX:
712 #endif
713 #ifdef MID_VAX
714 case MID_VAX:
715 #endif
716 #ifdef MID_VAX1K
717 case MID_VAX1K:
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_VAX1K
789 case MID_VAX1K:
790 printf("vax 1k");
791 break;
792 #endif
793 #ifdef MID_ALPHA
794 case MID_ALPHA:
795 printf("alpha");
796 break;
797 #endif
798 #ifdef MID_MIPS
799 case MID_MIPS:
800 printf("mips");
801 break;
802 #endif
803 #ifdef MID_ARM6
804 case MID_ARM6:
805 printf("arm32");
806 break;
807 #endif
808 default:
809 break;
810 }
811 printf(") Magic: ");
812 switch (N_GETMAGIC (ex)) {
813 case OMAGIC:
814 printf("OMAGIC");
815 break;
816 case NMAGIC:
817 printf("NMAGIC");
818 break;
819 case ZMAGIC:
820 printf("ZMAGIC");
821 break;
822 case QMAGIC:
823 printf("QMAGIC");
824 break;
825 default:
826 printf("Unknown %ld", (long) N_GETMAGIC (ex));
827 }
828 printf("\n");
829 printf("Size of text: %08lx\n", (long)ex.a_text);
830 printf("Size of data: %08lx\n", (long)ex.a_data);
831 printf("Size of bss: %08lx\n", (long)ex.a_bss);
832 printf("Size of symbol tab: %08lx\n", (long)ex.a_syms);
833 printf("Transfer Address: %08lx\n", (long)ex.a_entry);
834 printf("Size of reloc text: %08lx\n", (long)ex.a_trsize);
835 printf("Size of reloc data: %08lx\n", (long)ex.a_drsize);
836
837 magic = N_GETMAGIC (ex);
838 clbytes = getCLBYTES(mid);
839 clofset = clbytes - 1;
840
841 dl->image_type = IMAGE_TYPE_AOUT;
842 dl->loadaddr = 0;
843 dl->xferaddr = ex.a_entry;
844
845 dl->a_text = ex.a_text;
846 if (magic == ZMAGIC || magic == NMAGIC) {
847 dl->a_text_fill = clbytes - (ex.a_text & clofset);
848 if (dl->a_text_fill == clbytes)
849 dl->a_text_fill = 0;
850 } else
851 dl->a_text_fill = 0;
852 dl->a_data = ex.a_data;
853 if (magic == ZMAGIC || magic == NMAGIC) {
854 dl->a_data_fill = clbytes - (ex.a_data & clofset);
855 if (dl->a_data_fill == clbytes)
856 dl->a_data_fill = 0;
857 } else
858 dl->a_data_fill = 0;
859 dl->a_bss = ex.a_bss;
860 if (magic == ZMAGIC || magic == NMAGIC) {
861 dl->a_bss_fill = clbytes - (ex.a_bss & clofset);
862 if (dl->a_bss_fill == clbytes)
863 dl->a_bss_fill = 0;
864 } else {
865 dl->a_bss_fill = clbytes -
866 ((ex.a_text+ex.a_data+ex.a_bss) & clofset);
867 if (dl->a_bss_fill == clbytes)
868 dl->a_bss_fill = 0;
869 }
870 dl->a_mid = mid;
871
872 return(0);
873 #endif /* NOAOUT */
874 }
875
876 int
877 GetFileInfo(struct dllist *dl)
878 {
879 int error;
880
881 error = CheckElfFile(dl->ldfd);
882 if (error == 0) {
883 error = GetElfFileInfo(dl);
884 if (error != 0) {
885 return(-1);
886 }
887 return (0);
888 }
889
890 error = CheckAOutFile(dl->ldfd);
891 if (error == 0) {
892 error = GetAOutFileInfo(dl);
893 if (error != 0) {
894 return(-1);
895 }
896 return (0);
897 }
898
899 error = CheckMopFile(dl->ldfd);
900 if (error == 0) {
901 error = GetMopFileInfo(dl);
902 if (error != 0) {
903 return(-1);
904 }
905 return (0);
906 }
907
908 /* Unknown file format. */
909 return(-1);
910 }
911
912 ssize_t
913 mopFileRead(struct dllist *dlslot, u_char *buf)
914 {
915 ssize_t len, outlen;
916 int bsz, sec;
917 int32_t pos, notdone, total;
918 uint32_t secoff;
919
920 switch (dlslot->image_type) {
921 case IMAGE_TYPE_MOP:
922 len = read(dlslot->ldfd,buf,dlslot->dl_bsz);
923 break;
924
925 case IMAGE_TYPE_ELF32:
926 sec = dlslot->e_cursec;
927
928 /*
929 * We're pretty simplistic here. We do only file-backed
930 * or only zero-fill.
931 */
932
933 /* Determine offset into section. */
934 secoff = dlslot->e_curpos - dlslot->e_sections[sec].s_loff;
935
936 /*
937 * If we're in the file-backed part of the section,
938 * transmit some of the file.
939 */
940 if (secoff < dlslot->e_sections[sec].s_fsize) {
941 bsz = dlslot->e_sections[sec].s_fsize - secoff;
942 if (bsz > dlslot->dl_bsz)
943 bsz = dlslot->dl_bsz;
944 if (lseek(dlslot->ldfd,
945 dlslot->e_sections[sec].s_foff + secoff,
946 SEEK_SET) == (off_t) -1)
947 return (-1);
948 len = read(dlslot->ldfd, buf, bsz);
949 }
950 /*
951 * Otherwise, if we're in the zero-fill part of the
952 * section, transmit some zeros.
953 */
954 else if (secoff < (dlslot->e_sections[sec].s_fsize +
955 dlslot->e_sections[sec].s_pad)) {
956 bsz = dlslot->e_sections[sec].s_pad -
957 (secoff - dlslot->e_sections[sec].s_fsize);
958 if (bsz > dlslot->dl_bsz)
959 bsz = dlslot->dl_bsz;
960 memset(buf, 0, (len = bsz));
961 }
962 /*
963 * ...and if we haven't hit either of those cases,
964 * that's the end of the image.
965 */
966 else {
967 return (0);
968 }
969 /*
970 * Advance the logical image pointer.
971 */
972 dlslot->e_curpos += bsz;
973 if (dlslot->e_curpos >= (dlslot->e_sections[sec].s_loff +
974 dlslot->e_sections[sec].s_fsize +
975 dlslot->e_sections[sec].s_pad))
976 if (++dlslot->e_cursec >= dlslot->e_nsec)
977 return (0);
978 break;
979
980 case IMAGE_TYPE_AOUT:
981 bsz = dlslot->dl_bsz;
982 pos = dlslot->a_lseek;
983 len = 0;
984
985 total = dlslot->a_text;
986
987 if (pos < total) {
988 notdone = total - pos;
989 if (notdone <= bsz) {
990 outlen = read(dlslot->ldfd,&buf[len],notdone);
991 } else {
992 outlen = read(dlslot->ldfd,&buf[len],bsz);
993 }
994 len = len + outlen;
995 pos = pos + outlen;
996 bsz = bsz - outlen;
997 }
998
999 total = total + dlslot->a_text_fill;
1000
1001 if ((bsz > 0) && (pos < total)) {
1002 notdone = total - pos;
1003 if (notdone <= bsz) {
1004 outlen = notdone;
1005 } else {
1006 outlen = bsz;
1007 }
1008 memset(&buf[len], 0, outlen);
1009 len = len + outlen;
1010 pos = pos + outlen;
1011 bsz = bsz - outlen;
1012 }
1013
1014 total = total + dlslot->a_data;
1015
1016 if ((bsz > 0) && (pos < total)) {
1017 notdone = total - pos;
1018 if (notdone <= bsz) {
1019 outlen = read(dlslot->ldfd,&buf[len],notdone);
1020 } else {
1021 outlen = read(dlslot->ldfd,&buf[len],bsz);
1022 }
1023 len = len + outlen;
1024 pos = pos + outlen;
1025 bsz = bsz - outlen;
1026 }
1027
1028 total = total + dlslot->a_data_fill;
1029
1030 if ((bsz > 0) && (pos < total)) {
1031 notdone = total - pos;
1032 if (notdone <= bsz) {
1033 outlen = notdone;
1034 } else {
1035 outlen = bsz;
1036 }
1037 memset(&buf[len], 0, outlen);
1038 len = len + outlen;
1039 pos = pos + outlen;
1040 bsz = bsz - outlen;
1041 }
1042
1043 total = total + dlslot->a_bss;
1044
1045 if ((bsz > 0) && (pos < total)) {
1046 notdone = total - pos;
1047 if (notdone <= bsz) {
1048 outlen = notdone;
1049 } else {
1050 outlen = bsz;
1051 }
1052 memset(&buf[len], 0, outlen);
1053 len = len + outlen;
1054 pos = pos + outlen;
1055 bsz = bsz - outlen;
1056 }
1057
1058 total = total + dlslot->a_bss_fill;
1059
1060 if ((bsz > 0) && (pos < total)) {
1061 notdone = total - pos;
1062 if (notdone <= bsz) {
1063 outlen = notdone;
1064 } else {
1065 outlen = bsz;
1066 }
1067 memset(&buf[len], 0, outlen);
1068 len = len + outlen;
1069 pos = pos + outlen;
1070 bsz = bsz - outlen;
1071 }
1072
1073 dlslot->a_lseek = pos;
1074 break;
1075
1076 default:
1077 abort();
1078 }
1079
1080 return(len);
1081 }
1082