1 /* $NetBSD: file.c,v 1.5 1998/02/07 00:03:22 cgd Exp $ */
4 * Copyright (c) 1995-96 Mats O Jansson. All rights reserved.
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * 3. All advertising materials mentioning features or use of this software
15 * must display the following acknowledgement:
16 * This product includes software developed by Mats O Jansson.
17 * 4. The name of the author may not be used to endorse or promote products
18 * derived from this software without specific prior written permission.
20 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
21 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
22 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
23 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
24 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
25 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
29 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 #include <sys/cdefs.h>
34 static char rcsid
[]="$NetBSD: file.c,v 1.5 1998/02/07 00:03:22 cgd Exp $";
43 #if defined(__NetBSD__) || defined(__OpenBSD__)
44 #include <sys/exec_aout.h>
49 #if defined(__FreeBSD__)
50 #include <sys/imgact_aout.h>
55 #if defined(__linux__)
63 int getCLBYTES
__P((int));
64 int getMID
__P((int, int));
67 mopFilePutLX(buf
, index
, value
, cnt
)
73 for (i
= 0; i
< cnt
; i
++) {
74 buf
[index
+i
] = value
% 256;
80 mopFilePutBX(buf
, index
, value
, cnt
)
86 for (i
= 0; i
< cnt
; i
++) {
87 buf
[index
+cnt
-1-i
] = value
% 256;
93 mopFileGetLX(buf
, index
, cnt
)
100 for (i
= 0; i
< cnt
; i
++) {
101 ret
= ret
*256 + buf
[index
+cnt
-1-i
];
108 mopFileGetBX(buf
, index
, cnt
)
115 for (i
= 0; i
< cnt
; i
++) {
116 ret
= ret
*256 + buf
[index
+i
];
123 mopFileSwapX(buf
, index
, cnt
)
130 for (i
= 0; i
< (cnt
/ 2); i
++) {
132 buf
[index
+i
] = buf
[index
+cnt
-1-i
];
133 buf
[index
+cnt
-1-i
] = c
;
145 if (read(fd
, header
, 512) != 512)
148 (void)lseek(fd
, (off_t
) 0, SEEK_SET
);
150 image_type
= (u_short
)(header
[IHD_W_ALIAS
+1]*256 +
151 header
[IHD_W_ALIAS
]);
154 case IHD_C_NATIVE
: /* Native mode image (VAX) */
155 case IHD_C_RSX
: /* RSX image produced by TKB */
156 case IHD_C_BPA
: /* BASIC plus analog */
157 case IHD_C_ALIAS
: /* Alias */
158 case IHD_C_CLI
: /* Image is CLI */
159 case IHD_C_PMAX
: /* PMAX system image */
160 case IHD_C_ALPHA
: /* ALPHA system image */
170 GetMopFileInfo(fd
, load
, xfr
)
172 u_int32_t
*load
, *xfr
;
176 u_int32_t load_addr
, xfr_addr
, isd
, iha
, hbcnt
, isize
;
178 if (read(fd
, header
, 512) != 512)
181 image_type
= (u_short
)(header
[IHD_W_ALIAS
+1]*256 +
182 header
[IHD_W_ALIAS
]);
185 case IHD_C_NATIVE
: /* Native mode image (VAX) */
186 isd
= (header
[IHD_W_SIZE
+1]*256 +
188 iha
= (header
[IHD_W_ACTIVOFF
+1]*256 +
189 header
[IHD_W_ACTIVOFF
]);
190 hbcnt
= (header
[IHD_B_HDRBLKCNT
]);
191 isize
= (header
[isd
+ISD_W_PAGCNT
+1]*256 +
192 header
[isd
+ISD_W_PAGCNT
]) * 512;
193 load_addr
= ((header
[isd
+ISD_V_VPN
+1]*256 +
194 header
[isd
+ISD_V_VPN
]) & ISD_M_VPN
)
196 xfr_addr
= (header
[iha
+IHA_L_TFRADR1
+3]*0x1000000 +
197 header
[iha
+IHA_L_TFRADR1
+2]*0x10000 +
198 header
[iha
+IHA_L_TFRADR1
+1]*0x100 +
199 header
[iha
+IHA_L_TFRADR1
]) & 0x7fffffff;
200 printf("Native Image (VAX)\n");
201 printf("Header Block Count: %d\n",hbcnt
);
202 printf("Image Size: %08x\n",isize
);
203 printf("Load Address: %08x\n",load_addr
);
204 printf("Transfer Address: %08x\n",xfr_addr
);
206 case IHD_C_RSX
: /* RSX image produced by TKB */
207 hbcnt
= header
[L_BBLK
+1]*256 + header
[L_BBLK
];
208 isize
= (header
[L_BLDZ
+1]*256 + header
[L_BLDZ
]) * 64;
209 load_addr
= header
[L_BSA
+1]*256 + header
[L_BSA
];
210 xfr_addr
= header
[L_BXFR
+1]*256 + header
[L_BXFR
];
211 printf("RSX Image\n");
212 printf("Header Block Count: %d\n",hbcnt
);
213 printf("Image Size: %08x\n",isize
);
214 printf("Load Address: %08x\n",load_addr
);
215 printf("Transfer Address: %08x\n",xfr_addr
);
217 case IHD_C_BPA
: /* BASIC plus analog */
218 printf("BASIC-Plus Image, not supported\n");
221 case IHD_C_ALIAS
: /* Alias */
222 printf("Alias, not supported\n");
225 case IHD_C_CLI
: /* Image is CLI */
226 printf("CLI, not supported\n");
229 case IHD_C_PMAX
: /* PMAX system image */
230 isd
= (header
[IHD_W_SIZE
+1]*256 +
232 iha
= (header
[IHD_W_ACTIVOFF
+1]*256 +
233 header
[IHD_W_ACTIVOFF
]);
234 hbcnt
= (header
[IHD_B_HDRBLKCNT
]);
235 isize
= (header
[isd
+ISD_W_PAGCNT
+1]*256 +
236 header
[isd
+ISD_W_PAGCNT
]) * 512;
237 load_addr
= (header
[isd
+ISD_V_VPN
+1]*256 +
238 header
[isd
+ISD_V_VPN
]) * 512;
239 xfr_addr
= (header
[iha
+IHA_L_TFRADR1
+3]*0x1000000 +
240 header
[iha
+IHA_L_TFRADR1
+2]*0x10000 +
241 header
[iha
+IHA_L_TFRADR1
+1]*0x100 +
242 header
[iha
+IHA_L_TFRADR1
]);
243 printf("PMAX Image \n");
244 printf("Header Block Count: %d\n",hbcnt
);
245 printf("Image Size: %08x\n",isize
);
246 printf("Load Address: %08x\n",load_addr
);
247 printf("Transfer Address: %08x\n",xfr_addr
);
249 case IHD_C_ALPHA
: /* ALPHA system image */
250 isd
= (header
[EIHD_L_ISDOFF
+3]*0x1000000 +
251 header
[EIHD_L_ISDOFF
+2]*0x10000 +
252 header
[EIHD_L_ISDOFF
+1]*0x100 +
253 header
[EIHD_L_ISDOFF
]);
254 hbcnt
= (header
[EIHD_L_HDRBLKCNT
+3]*0x1000000 +
255 header
[EIHD_L_HDRBLKCNT
+2]*0x10000 +
256 header
[EIHD_L_HDRBLKCNT
+1]*0x100 +
257 header
[EIHD_L_HDRBLKCNT
]);
258 isize
= (header
[isd
+EISD_L_SECSIZE
+3]*0x1000000 +
259 header
[isd
+EISD_L_SECSIZE
+2]*0x10000 +
260 header
[isd
+EISD_L_SECSIZE
+1]*0x100 +
261 header
[isd
+EISD_L_SECSIZE
]);
264 printf("Alpha Image \n");
265 printf("Header Block Count: %d\n",hbcnt
);
266 printf("Image Size: %08x\n",isize
);
267 printf("Load Address: %08x\n",load_addr
);
268 printf("Transfer Address: %08x\n",xfr_addr
);
271 printf("Unknown Image (%d)\n",image_type
);
288 getMID(old_mid
,new_mid
)
289 int old_mid
, new_mid
;
379 #if defined(MID_I386) || defined(MID_M68K4K) || defined(MID_NS32532) || \
380 defined(MID_PMAX) || defined(MID_MIPS) || defined(MID_ARM6)
393 #if defined(MID_M68K) || defined(MID_ALPHA) || defined(MID_SPARC)
412 struct exec ex
, ex_swap
;
415 if (read(fd
, (char *)&ex
, sizeof(ex
)) != sizeof(ex
))
418 (void)lseek(fd
, (off_t
) 0, SEEK_SET
);
420 if (read(fd
, (char *)&ex_swap
, sizeof(ex_swap
)) != sizeof(ex_swap
))
423 (void)lseek(fd
, (off_t
) 0, SEEK_SET
);
425 mid
= getMID(mid
, N_GETMID (ex
));
428 mid
= getMID(mid
, N_GETMID (ex_swap
));
440 GetAOutFileInfo(fd
, load
, xfr
, a_text
, a_text_fill
,
441 a_data
, a_data_fill
, a_bss
, a_bss_fill
, aout
)
443 u_int32_t
*load
, *xfr
, *a_text
, *a_text_fill
;
444 u_int32_t
*a_data
, *a_data_fill
, *a_bss
, *a_bss_fill
;
450 struct exec ex
, ex_swap
;
452 u_int32_t magic
, clbytes
, clofset
;
454 if (read(fd
, (char *)&ex
, sizeof(ex
)) != sizeof(ex
))
457 (void)lseek(fd
, (off_t
) 0, SEEK_SET
);
459 if (read(fd
, (char *)&ex_swap
, sizeof(ex_swap
)) != sizeof(ex_swap
))
462 mopFileSwapX((u_char
*)&ex_swap
, 0, 4);
464 mid
= getMID(mid
, N_GETMID (ex
));
467 mid
= getMID(mid
, N_GETMID (ex_swap
));
469 mopFileSwapX((u_char
*)&ex
, 0, 4);
498 ex
.a_text
= mopFileGetLX((u_char
*)&ex_swap
, 4, 4);
499 ex
.a_data
= mopFileGetLX((u_char
*)&ex_swap
, 8, 4);
500 ex
.a_bss
= mopFileGetLX((u_char
*)&ex_swap
, 12, 4);
501 ex
.a_syms
= mopFileGetLX((u_char
*)&ex_swap
, 16, 4);
502 ex
.a_entry
= mopFileGetLX((u_char
*)&ex_swap
, 20, 4);
503 ex
.a_trsize
= mopFileGetLX((u_char
*)&ex_swap
, 24, 4);
504 ex
.a_drsize
= mopFileGetLX((u_char
*)&ex_swap
, 28, 4);
516 ex
.a_text
= mopFileGetBX((u_char
*)&ex_swap
, 4, 4);
517 ex
.a_data
= mopFileGetBX((u_char
*)&ex_swap
, 8, 4);
518 ex
.a_bss
= mopFileGetBX((u_char
*)&ex_swap
, 12, 4);
519 ex
.a_syms
= mopFileGetBX((u_char
*)&ex_swap
, 16, 4);
520 ex
.a_entry
= mopFileGetBX((u_char
*)&ex_swap
, 20, 4);
521 ex
.a_trsize
= mopFileGetBX((u_char
*)&ex_swap
, 24, 4);
522 ex
.a_drsize
= mopFileGetBX((u_char
*)&ex_swap
, 28, 4);
528 printf("a.out image (");
529 switch (N_GETMID (ex
)) {
580 switch (N_GETMAGIC (ex
)) {
594 printf("Unknown %ld", (long) N_GETMAGIC (ex
));
597 printf("Size of text: %08lx\n", (long)ex
.a_text
);
598 printf("Size of data: %08lx\n", (long)ex
.a_data
);
599 printf("Size of bss: %08lx\n", (long)ex
.a_bss
);
600 printf("Size of symbol tab: %08lx\n", (long)ex
.a_syms
);
601 printf("Transfer Address: %08lx\n", (long)ex
.a_entry
);
602 printf("Size of reloc text: %08lx\n", (long)ex
.a_trsize
);
603 printf("Size of reloc data: %08lx\n", (long)ex
.a_drsize
);
605 magic
= N_GETMAGIC (ex
);
606 clbytes
= getCLBYTES(mid
);
607 clofset
= clbytes
- 1;
617 if (a_text
!= NULL
) {
621 if (a_text_fill
!= NULL
) {
622 if (magic
== ZMAGIC
|| magic
== NMAGIC
) {
623 *a_text_fill
= clbytes
- (ex
.a_text
& clofset
);
624 if (*a_text_fill
== clbytes
) {
632 if (a_data
!= NULL
) {
636 if (a_data_fill
!= NULL
) {
637 if (magic
== ZMAGIC
|| magic
== NMAGIC
) {
638 *a_data_fill
= clbytes
- (ex
.a_data
& clofset
);
639 if (*a_data_fill
== clbytes
) {
651 if (a_bss_fill
!= NULL
) {
652 if (magic
== ZMAGIC
|| magic
== NMAGIC
) {
653 *a_bss_fill
= clbytes
- (ex
.a_bss
& clofset
);
654 if (*a_bss_fill
== clbytes
) {
658 *a_bss_fill
= clbytes
-
659 ((ex
.a_text
+ex
.a_data
+ex
.a_bss
) & clofset
);
660 if (*a_text_fill
== clbytes
) {
675 GetFileInfo(fd
, load
, xfr
, aout
,
676 a_text
, a_text_fill
, a_data
, a_data_fill
, a_bss
, a_bss_fill
)
678 u_int32_t
*load
, *xfr
, *a_text
, *a_text_fill
;
679 u_int32_t
*a_data
, *a_data_fill
, *a_bss
, *a_bss_fill
;
683 err
= CheckAOutFile(fd
);
686 err
= GetAOutFileInfo(fd
, load
, xfr
,
695 err
= CheckMopFile(fd
);
698 err
= GetMopFileInfo(fd
, load
, xfr
);
712 mopFileRead(dlslot
, buf
)
713 struct dllist
*dlslot
;
718 int32_t pos
, notdone
, total
;
720 if (dlslot
->aout
== -1) {
721 len
= read(dlslot
->ldfd
,buf
,dlslot
->dl_bsz
);
723 bsz
= dlslot
->dl_bsz
;
724 pos
= dlslot
->a_lseek
;
727 total
= dlslot
->a_text
;
730 notdone
= total
- pos
;
731 if (notdone
<= bsz
) {
732 outlen
= read(dlslot
->ldfd
,&buf
[len
],notdone
);
734 outlen
= read(dlslot
->ldfd
,&buf
[len
],bsz
);
741 total
= total
+ dlslot
->a_text_fill
;
743 if ((bsz
> 0) && (pos
< total
)) {
744 notdone
= total
- pos
;
745 if (notdone
<= bsz
) {
750 memset(&buf
[len
], 0, outlen
);
756 total
= total
+ dlslot
->a_data
;
758 if ((bsz
> 0) && (pos
< total
)) {
759 notdone
= total
- pos
;
760 if (notdone
<= bsz
) {
761 outlen
= read(dlslot
->ldfd
,&buf
[len
],notdone
);
763 outlen
= read(dlslot
->ldfd
,&buf
[len
],bsz
);
770 total
= total
+ dlslot
->a_data_fill
;
772 if ((bsz
> 0) && (pos
< total
)) {
773 notdone
= total
- pos
;
774 if (notdone
<= bsz
) {
779 memset(&buf
[len
], 0, outlen
);
785 total
= total
+ dlslot
->a_bss
;
787 if ((bsz
> 0) && (pos
< total
)) {
788 notdone
= total
- pos
;
789 if (notdone
<= bsz
) {
794 memset(&buf
[len
], 0, outlen
);
800 total
= total
+ dlslot
->a_bss_fill
;
802 if ((bsz
> 0) && (pos
< total
)) {
803 notdone
= total
- pos
;
804 if (notdone
<= bsz
) {
809 memset(&buf
[len
], 0, outlen
);
815 dlslot
->a_lseek
= pos
;