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 *
FileTypeName(mopd_imagetype type)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
mopFilePutLX(u_char * buf,int idx,u_int32_t value,int cnt)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
mopFilePutBX(u_char * buf,int idx,u_int32_t value,int cnt)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
mopFileGetLX(u_char * buf,int idx,int cnt)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
mopFileGetBX(u_char * buf,int idx,int cnt)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
mopFileSwapX(u_char * buf,int idx,int cnt)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
CheckMopFile(int fd)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
GetMopFileInfo(struct dllist * dl)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
getMID(int old_mid,int new_mid)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
getCLBYTES(int mid)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
CheckElfFile(int fd)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
GetElfFileInfo(struct dllist * dl)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
CheckAOutFile(int fd)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
GetAOutFileInfo(struct dllist * dl)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
GetFileInfo(struct dllist * dl)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
mopFileRead(struct dllist * dlslot,u_char * buf)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