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