Home | History | Annotate | Line # | Download | only in common
file.c revision 1.6
      1 /*	$NetBSD: file.c,v 1.6 1998/07/25 06:01:13 mycroft 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  * 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.
     19  *
     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.
     30  */
     31 
     32 #include <sys/cdefs.h>
     33 #ifndef lint
     34 __RCSID("$NetBSD: file.c,v 1.6 1998/07/25 06:01:13 mycroft Exp $");
     35 #endif
     36 
     37 #include "os.h"
     38 #include "common.h"
     39 #include "file.h"
     40 #include "mopdef.h"
     41 
     42 #ifndef NOAOUT
     43 #if 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 140
     54 #endif
     55 #endif
     56 
     57 int	getCLBYTES __P((int));
     58 int	getMID __P((int, int));
     59 
     60 void
     61 mopFilePutLX(buf, index, value, cnt)
     62 	u_char	       *buf;
     63 	int		index, cnt;
     64 	u_int32_t	value;
     65 {
     66 	int i;
     67 	for (i = 0; i < cnt; i++) {
     68 		buf[index+i] = value % 256;
     69 		value = value / 256;
     70 	}
     71 }
     72 
     73 void
     74 mopFilePutBX(buf, index, value, cnt)
     75 	u_char	       *buf;
     76 	int		index, cnt;
     77 	u_int32_t	value;
     78 {
     79 	int i;
     80 	for (i = 0; i < cnt; i++) {
     81 		buf[index+cnt-1-i] = value % 256;
     82 		value = value / 256;
     83 	}
     84 }
     85 
     86 u_int32_t
     87 mopFileGetLX(buf, index, cnt)
     88 	u_char	*buf;
     89 	int	index, cnt;
     90 {
     91 	u_int32_t ret = 0;
     92 	int i;
     93 
     94 	for (i = 0; i < cnt; i++) {
     95 		ret = ret*256 + buf[index+cnt-1-i];
     96 	}
     97 
     98 	return(ret);
     99 }
    100 
    101 u_int32_t
    102 mopFileGetBX(buf, index, cnt)
    103 	u_char	*buf;
    104 	int	index, cnt;
    105 {
    106 	u_int32_t ret = 0;
    107 	int i;
    108 
    109 	for (i = 0; i < cnt; i++) {
    110 		ret = ret*256 + buf[index+i];
    111 	}
    112 
    113 	return(ret);
    114 }
    115 
    116 void
    117 mopFileSwapX(buf, index, cnt)
    118 	u_char	*buf;
    119 	int	index, cnt;
    120 {
    121 	int i;
    122 	u_char c;
    123 
    124 	for (i = 0; i < (cnt / 2); i++) {
    125 		c = buf[index+i];
    126 		buf[index+i] = buf[index+cnt-1-i];
    127 		buf[index+cnt-1-i] = c;
    128 	}
    129 
    130 }
    131 
    132 int
    133 CheckMopFile(fd)
    134 	int	fd;
    135 {
    136 	u_char	header[512];
    137 	short	image_type;
    138 
    139 	if (read(fd, header, 512) != 512)
    140 		return(-1);
    141 
    142 	(void)lseek(fd, (off_t) 0, SEEK_SET);
    143 
    144 	image_type = (u_short)(header[IHD_W_ALIAS+1]*256 +
    145 			       header[IHD_W_ALIAS]);
    146 
    147 	switch(image_type) {
    148 		case IHD_C_NATIVE:		/* Native mode image (VAX)   */
    149 		case IHD_C_RSX:			/* RSX image produced by TKB */
    150 		case IHD_C_BPA:			/* BASIC plus analog         */
    151 		case IHD_C_ALIAS:		/* Alias		     */
    152 		case IHD_C_CLI:			/* Image is CLI		     */
    153 		case IHD_C_PMAX:		/* PMAX system image	     */
    154 		case IHD_C_ALPHA:		/* ALPHA system image	     */
    155 			break;
    156 		default:
    157 			return(-1);
    158 	}
    159 
    160 	return(0);
    161 }
    162 
    163 int
    164 GetMopFileInfo(fd, load, xfr)
    165 	int		fd;
    166 	u_int32_t      *load, *xfr;
    167 {
    168 	u_char		header[512];
    169 	short		image_type;
    170 	u_int32_t	load_addr, xfr_addr, isd, iha, hbcnt, isize;
    171 
    172 	if (read(fd, header, 512) != 512)
    173 		return(-1);
    174 
    175 	image_type = (u_short)(header[IHD_W_ALIAS+1]*256 +
    176 			       header[IHD_W_ALIAS]);
    177 
    178 	switch(image_type) {
    179 		case IHD_C_NATIVE:		/* Native mode image (VAX)   */
    180 			isd = (header[IHD_W_SIZE+1]*256 +
    181 			       header[IHD_W_SIZE]);
    182 			iha = (header[IHD_W_ACTIVOFF+1]*256 +
    183 			       header[IHD_W_ACTIVOFF]);
    184 			hbcnt = (header[IHD_B_HDRBLKCNT]);
    185 			isize = (header[isd+ISD_W_PAGCNT+1]*256 +
    186 				 header[isd+ISD_W_PAGCNT]) * 512;
    187 			load_addr = ((header[isd+ISD_V_VPN+1]*256 +
    188 				      header[isd+ISD_V_VPN]) & ISD_M_VPN)
    189 					* 512;
    190 			xfr_addr = (header[iha+IHA_L_TFRADR1+3]*0x1000000 +
    191 				    header[iha+IHA_L_TFRADR1+2]*0x10000 +
    192 				    header[iha+IHA_L_TFRADR1+1]*0x100 +
    193 				    header[iha+IHA_L_TFRADR1]) & 0x7fffffff;
    194 			printf("Native Image (VAX)\n");
    195 			printf("Header Block Count: %d\n",hbcnt);
    196 			printf("Image Size:         %08x\n",isize);
    197 			printf("Load Address:       %08x\n",load_addr);
    198 			printf("Transfer Address:   %08x\n",xfr_addr);
    199 			break;
    200 		case IHD_C_RSX:			/* RSX image produced by TKB */
    201 			hbcnt = header[L_BBLK+1]*256 + header[L_BBLK];
    202 			isize = (header[L_BLDZ+1]*256 + header[L_BLDZ]) * 64;
    203 			load_addr = header[L_BSA+1]*256 + header[L_BSA];
    204 			xfr_addr  = header[L_BXFR+1]*256 + header[L_BXFR];
    205 			printf("RSX Image\n");
    206 			printf("Header Block Count: %d\n",hbcnt);
    207 			printf("Image Size:         %08x\n",isize);
    208 			printf("Load Address:       %08x\n",load_addr);
    209 			printf("Transfer Address:   %08x\n",xfr_addr);
    210 			break;
    211 		case IHD_C_BPA:			/* BASIC plus analog         */
    212 			printf("BASIC-Plus Image, not supported\n");
    213 			return(-1);
    214 			break;
    215 		case IHD_C_ALIAS:		/* Alias		     */
    216 			printf("Alias, not supported\n");
    217 			return(-1);
    218 			break;
    219 		case IHD_C_CLI:			/* Image is CLI		     */
    220 			printf("CLI, not supported\n");
    221 			return(-1);
    222 			break;
    223 		case IHD_C_PMAX:		/* PMAX system image	     */
    224 			isd = (header[IHD_W_SIZE+1]*256 +
    225 			       header[IHD_W_SIZE]);
    226 			iha = (header[IHD_W_ACTIVOFF+1]*256 +
    227 			       header[IHD_W_ACTIVOFF]);
    228 			hbcnt = (header[IHD_B_HDRBLKCNT]);
    229 			isize = (header[isd+ISD_W_PAGCNT+1]*256 +
    230 				 header[isd+ISD_W_PAGCNT]) * 512;
    231 			load_addr = (header[isd+ISD_V_VPN+1]*256 +
    232 				     header[isd+ISD_V_VPN]) * 512;
    233 			xfr_addr = (header[iha+IHA_L_TFRADR1+3]*0x1000000 +
    234 				    header[iha+IHA_L_TFRADR1+2]*0x10000 +
    235 				    header[iha+IHA_L_TFRADR1+1]*0x100 +
    236 				    header[iha+IHA_L_TFRADR1]);
    237 			printf("PMAX Image \n");
    238 			printf("Header Block Count: %d\n",hbcnt);
    239 			printf("Image Size:         %08x\n",isize);
    240 			printf("Load Address:       %08x\n",load_addr);
    241 			printf("Transfer Address:   %08x\n",xfr_addr);
    242 			break;
    243 		case IHD_C_ALPHA:		/* ALPHA system image	     */
    244 			isd = (header[EIHD_L_ISDOFF+3]*0x1000000 +
    245 			       header[EIHD_L_ISDOFF+2]*0x10000 +
    246 			       header[EIHD_L_ISDOFF+1]*0x100 +
    247 			       header[EIHD_L_ISDOFF]);
    248 			hbcnt = (header[EIHD_L_HDRBLKCNT+3]*0x1000000 +
    249 				 header[EIHD_L_HDRBLKCNT+2]*0x10000 +
    250 				 header[EIHD_L_HDRBLKCNT+1]*0x100 +
    251 				 header[EIHD_L_HDRBLKCNT]);
    252 			isize = (header[isd+EISD_L_SECSIZE+3]*0x1000000 +
    253 				 header[isd+EISD_L_SECSIZE+2]*0x10000 +
    254 				 header[isd+EISD_L_SECSIZE+1]*0x100 +
    255 				 header[isd+EISD_L_SECSIZE]);
    256 			load_addr = 0;
    257 			xfr_addr = 0;
    258 			printf("Alpha Image \n");
    259 			printf("Header Block Count: %d\n",hbcnt);
    260 			printf("Image Size:         %08x\n",isize);
    261 			printf("Load Address:       %08x\n",load_addr);
    262 			printf("Transfer Address:   %08x\n",xfr_addr);
    263 			break;
    264 		default:
    265 			printf("Unknown Image (%d)\n",image_type);
    266 			return(-1);
    267 	}
    268 
    269 	if (load != NULL) {
    270 		*load = load_addr;
    271 	}
    272 
    273 	if (xfr != NULL) {
    274 		*xfr  = xfr_addr;
    275 	}
    276 
    277 	return(0);
    278 }
    279 
    280 #ifndef NOAOUT
    281 int
    282 getMID(old_mid,new_mid)
    283 	int	old_mid, new_mid;
    284 {
    285 	int	mid;
    286 
    287 	mid = old_mid;
    288 
    289 	switch (new_mid) {
    290 	case MID_I386:
    291 		mid = MID_I386;
    292 		break;
    293 #ifdef MID_M68K
    294 	case MID_M68K:
    295 		mid = MID_M68K;
    296 		break;
    297 #endif
    298 #ifdef MID_M68K4K
    299 	case MID_M68K4K:
    300 		mid = MID_M68K4K;
    301 		break;
    302 #endif
    303 #ifdef MID_NS32532
    304 	case MID_NS32532:
    305 		mid = MID_NS32532;
    306 		break;
    307 #endif
    308 	case MID_SPARC:
    309 		mid = MID_SPARC;
    310 		break;
    311 #ifdef MID_PMAX
    312 	case MID_PMAX:
    313 		mid = MID_PMAX;
    314 		break;
    315 #endif
    316 #ifdef MID_VAX
    317 	case MID_VAX:
    318 		mid = MID_VAX;
    319 		break;
    320 #endif
    321 #ifdef MID_ALPHA
    322 	case MID_ALPHA:
    323 		mid = MID_ALPHA;
    324 		break;
    325 #endif
    326 #ifdef MID_MIPS
    327 	case MID_MIPS:
    328 		mid = MID_MIPS;
    329 		break;
    330 #endif
    331 #ifdef MID_ARM6
    332 	case MID_ARM6:
    333 		mid = MID_ARM6;
    334 		break;
    335 #endif
    336 	default:
    337 		break;
    338 	}
    339 
    340 	return(mid);
    341 }
    342 
    343 int
    344 getCLBYTES(mid)
    345 	int	mid;
    346 {
    347 	int	clbytes;
    348 
    349 	switch (mid) {
    350 #ifdef MID_VAX
    351 	case MID_VAX:
    352 		clbytes = 1024;
    353 		break;
    354 #endif
    355 #ifdef MID_I386
    356 	case MID_I386:
    357 #endif
    358 #ifdef MID_M68K4K
    359 	case MID_M68K4K:
    360 #endif
    361 #ifdef MID_NS32532
    362 	case MID_NS32532:
    363 #endif
    364 #ifdef MID_PMAX
    365 	case MID_PMAX:
    366 #endif
    367 #ifdef MID_MIPS
    368 	case MID_MIPS:
    369 #endif
    370 #ifdef MID_ARM6
    371 	case MID_ARM6:
    372 #endif
    373 #if defined(MID_I386) || defined(MID_M68K4K) || defined(MID_NS32532) || \
    374     defined(MID_PMAX) || defined(MID_MIPS) || defined(MID_ARM6)
    375 		clbytes = 4096;
    376 		break;
    377 #endif
    378 #ifdef MID_M68K
    379 	case MID_M68K:
    380 #endif
    381 #ifdef MID_ALPHA
    382 	case MID_ALPHA:
    383 #endif
    384 #ifdef MID_SPARC
    385 	case MID_SPARC:
    386 #endif
    387 #if defined(MID_M68K) || defined(MID_ALPHA) || defined(MID_SPARC)
    388 		clbytes = 8192;
    389 		break;
    390 #endif
    391 	default:
    392 		clbytes = 0;
    393 	}
    394 
    395 	return(clbytes);
    396 }
    397 #endif
    398 
    399 int
    400 CheckAOutFile(fd)
    401 	int	fd;
    402 {
    403 #ifdef NOAOUT
    404 	return(-1);
    405 #else
    406 	struct exec ex, ex_swap;
    407 	int	mid = -1;
    408 
    409 	if (read(fd, (char *)&ex, sizeof(ex)) != sizeof(ex))
    410 		return(-1);
    411 
    412 	(void)lseek(fd, (off_t) 0, SEEK_SET);
    413 
    414 	if (read(fd, (char *)&ex_swap, sizeof(ex_swap)) != sizeof(ex_swap))
    415 		return(-1);
    416 
    417 	(void)lseek(fd, (off_t) 0, SEEK_SET);
    418 
    419 	mid = getMID(mid, N_GETMID (ex));
    420 
    421 	if (mid == -1) {
    422 		mid = getMID(mid, N_GETMID (ex_swap));
    423 	}
    424 
    425 	if (mid != -1) {
    426 		return(0);
    427 	} else {
    428 		return(-1);
    429 	}
    430 #endif NOAOUT
    431 }
    432 
    433 int
    434 GetAOutFileInfo(fd, load, xfr, a_text, a_text_fill,
    435 		a_data, a_data_fill, a_bss, a_bss_fill, aout)
    436 	int		 fd;
    437 	u_int32_t	*load, *xfr, *a_text, *a_text_fill;
    438 	u_int32_t	*a_data, *a_data_fill, *a_bss, *a_bss_fill;
    439 	int		 *aout;
    440 {
    441 #ifdef NOAOUT
    442 	return(-1);
    443 #else
    444 	struct exec ex, ex_swap;
    445 	u_int32_t	mid = -1;
    446 	u_int32_t	magic, clbytes, clofset;
    447 
    448 	if (read(fd, (char *)&ex, sizeof(ex)) != sizeof(ex))
    449 		return(-1);
    450 
    451 	(void)lseek(fd, (off_t) 0, SEEK_SET);
    452 
    453 	if (read(fd, (char *)&ex_swap, sizeof(ex_swap)) != sizeof(ex_swap))
    454 		return(-1);
    455 
    456 	mopFileSwapX((u_char *)&ex_swap, 0, 4);
    457 
    458 	mid = getMID(mid, N_GETMID (ex));
    459 
    460 	if (mid == -1) {
    461 		mid = getMID(mid, N_GETMID (ex_swap));
    462 		if (mid != -1) {
    463 			mopFileSwapX((u_char *)&ex, 0, 4);
    464 		}
    465 	}
    466 
    467 	if (mid == -1) {
    468 		return(-1);
    469 	}
    470 
    471 	if (N_BADMAG (ex)) {
    472 		return(-1);
    473 	}
    474 
    475 	switch (mid) {
    476 	case MID_I386:
    477 #ifdef MID_NS32532
    478 	case MID_NS32532:
    479 #endif
    480 #ifdef MID_PMAX
    481 	case MID_PMAX:
    482 #endif
    483 #ifdef MID_VAX
    484 	case MID_VAX:
    485 #endif
    486 #ifdef MID_ALPHA
    487 	case MID_ALPHA:
    488 #endif
    489 #ifdef MID_ARM6
    490 	case MID_ARM6:
    491 #endif
    492 		ex.a_text  = mopFileGetLX((u_char *)&ex_swap,  4, 4);
    493 		ex.a_data  = mopFileGetLX((u_char *)&ex_swap,  8, 4);
    494 		ex.a_bss   = mopFileGetLX((u_char *)&ex_swap, 12, 4);
    495 		ex.a_syms  = mopFileGetLX((u_char *)&ex_swap, 16, 4);
    496 		ex.a_entry = mopFileGetLX((u_char *)&ex_swap, 20, 4);
    497 		ex.a_trsize= mopFileGetLX((u_char *)&ex_swap, 24, 4);
    498 		ex.a_drsize= mopFileGetLX((u_char *)&ex_swap, 28, 4);
    499 		break;
    500 #ifdef MID_M68K
    501 	case MID_M68K:
    502 #endif
    503 #ifdef MID_M68K4K
    504 	case MID_M68K4K:
    505 #endif
    506 	case MID_SPARC:
    507 #ifdef MID_MIPS
    508 	case MID_MIPS:
    509 #endif
    510 		ex.a_text  = mopFileGetBX((u_char *)&ex_swap,  4, 4);
    511 		ex.a_data  = mopFileGetBX((u_char *)&ex_swap,  8, 4);
    512 		ex.a_bss   = mopFileGetBX((u_char *)&ex_swap, 12, 4);
    513 		ex.a_syms  = mopFileGetBX((u_char *)&ex_swap, 16, 4);
    514 		ex.a_entry = mopFileGetBX((u_char *)&ex_swap, 20, 4);
    515 		ex.a_trsize= mopFileGetBX((u_char *)&ex_swap, 24, 4);
    516 		ex.a_drsize= mopFileGetBX((u_char *)&ex_swap, 28, 4);
    517 		break;
    518 	default:
    519 		break;
    520 	}
    521 
    522 	printf("a.out image (");
    523 	switch (N_GETMID (ex)) {
    524 	case MID_I386:
    525 		printf("i386");
    526 		break;
    527 #ifdef MID_M68K
    528 	case MID_M68K:
    529 		printf("m68k");
    530 		break;
    531 #endif
    532 #ifdef MID_M68K4K
    533 	case MID_M68K4K:
    534 		printf("m68k 4k");
    535 		break;
    536 #endif
    537 #ifdef MID_NS32532
    538 	case MID_NS32532:
    539 		printf("pc532");
    540 		break;
    541 #endif
    542 	case MID_SPARC:
    543 		printf("sparc");
    544 		break;
    545 #ifdef MID_PMAX
    546 	case MID_PMAX:
    547 		printf("pmax");
    548 		break;
    549 #endif
    550 #ifdef MID_VAX
    551 	case MID_VAX:
    552 		printf("vax");
    553 		break;
    554 #endif
    555 #ifdef MID_ALPHA
    556 	case MID_ALPHA:
    557 		printf("alpha");
    558 		break;
    559 #endif
    560 #ifdef MID_MIPS
    561 	case MID_MIPS:
    562 		printf("mips");
    563 		break;
    564 #endif
    565 #ifdef MID_ARM6
    566 	case MID_ARM6:
    567 		printf("arm32");
    568 		break;
    569 #endif
    570 	default:
    571 		break;
    572 	}
    573 	printf(") Magic: ");
    574 	switch (N_GETMAGIC (ex)) {
    575 	case OMAGIC:
    576 		printf("OMAGIC");
    577 		break;
    578 	case NMAGIC:
    579 		printf("NMAGIC");
    580 		break;
    581 	case ZMAGIC:
    582 		printf("ZMAGIC");
    583 		break;
    584 	case QMAGIC:
    585 		printf("QMAGIC");
    586 		break;
    587 	default:
    588 		printf("Unknown %ld", (long) N_GETMAGIC (ex));
    589 	}
    590 	printf("\n");
    591 	printf("Size of text:       %08lx\n", (long)ex.a_text);
    592 	printf("Size of data:       %08lx\n", (long)ex.a_data);
    593 	printf("Size of bss:        %08lx\n", (long)ex.a_bss);
    594 	printf("Size of symbol tab: %08lx\n", (long)ex.a_syms);
    595 	printf("Transfer Address:   %08lx\n", (long)ex.a_entry);
    596 	printf("Size of reloc text: %08lx\n", (long)ex.a_trsize);
    597 	printf("Size of reloc data: %08lx\n", (long)ex.a_drsize);
    598 
    599 	magic = N_GETMAGIC (ex);
    600 	clbytes = getCLBYTES(mid);
    601 	clofset = clbytes - 1;
    602 
    603 	if (load != NULL) {
    604 		*load   = 0;
    605 	}
    606 
    607 	if (xfr != NULL) {
    608 		*xfr    = ex.a_entry;
    609 	}
    610 
    611 	if (a_text != NULL) {
    612 		*a_text = ex.a_text;
    613 	}
    614 
    615 	if (a_text_fill != NULL) {
    616 		if (magic == ZMAGIC || magic == NMAGIC) {
    617 			*a_text_fill = clbytes - (ex.a_text & clofset);
    618 			if (*a_text_fill == clbytes) {
    619 				*a_text_fill = 0;
    620 			}
    621 		} else {
    622 			*a_text_fill = 0;
    623 	        }
    624 	}
    625 
    626 	if (a_data != NULL) {
    627 		*a_data = ex.a_data;
    628 	}
    629 
    630 	if (a_data_fill != NULL) {
    631 		if (magic == ZMAGIC || magic == NMAGIC) {
    632 			*a_data_fill = clbytes - (ex.a_data & clofset);
    633 			if (*a_data_fill == clbytes) {
    634 				*a_data_fill = 0;
    635 			}
    636 		} else {
    637 			*a_data_fill = 0;
    638 	        }
    639 	}
    640 
    641 	if (a_bss != NULL) {
    642 		*a_bss  = ex.a_bss;
    643 	}
    644 
    645 	if (a_bss_fill != NULL) {
    646 		if (magic == ZMAGIC || magic == NMAGIC) {
    647 			*a_bss_fill = clbytes - (ex.a_bss & clofset);
    648 			if (*a_bss_fill == clbytes) {
    649 				*a_bss_fill = 0;
    650 			}
    651 		} else {
    652 			*a_bss_fill = clbytes -
    653 				((ex.a_text+ex.a_data+ex.a_bss) & clofset);
    654 			if (*a_text_fill == clbytes) {
    655 				*a_text_fill = 0;
    656 			}
    657 	        }
    658 	}
    659 
    660 	if (aout != NULL) {
    661 		*aout = mid;
    662 	}
    663 
    664 	return(0);
    665 #endif NOAOUT
    666 }
    667 
    668 int
    669 GetFileInfo(fd, load, xfr, aout,
    670 	    a_text, a_text_fill, a_data, a_data_fill, a_bss, a_bss_fill)
    671 	int	fd, *aout;
    672 	u_int32_t	*load, *xfr, *a_text, *a_text_fill;
    673 	u_int32_t	*a_data, *a_data_fill, *a_bss, *a_bss_fill;
    674 {
    675 	int	err;
    676 
    677 	err = CheckAOutFile(fd);
    678 
    679 	if (err == 0) {
    680 		err = GetAOutFileInfo(fd, load, xfr,
    681 				      a_text, a_text_fill,
    682 				      a_data, a_data_fill,
    683 				      a_bss, a_bss_fill,
    684 				      aout);
    685 		if (err != 0) {
    686 			return(-1);
    687 		}
    688 	} else {
    689 		err = CheckMopFile(fd);
    690 
    691 		if (err == 0) {
    692 			err = GetMopFileInfo(fd, load, xfr);
    693 			if (err != 0) {
    694 				return(-1);
    695 			}
    696 			*aout = -1;
    697 		} else {
    698 			return(-1);
    699 		}
    700 	}
    701 
    702 	return(0);
    703 }
    704 
    705 ssize_t
    706 mopFileRead(dlslot, buf)
    707 	struct dllist *dlslot;
    708 	u_char	*buf;
    709 {
    710 	ssize_t len, outlen;
    711 	int	bsz;
    712 	int32_t	pos, notdone, total;
    713 
    714 	if (dlslot->aout == -1) {
    715 		len = read(dlslot->ldfd,buf,dlslot->dl_bsz);
    716 	} else {
    717 		bsz = dlslot->dl_bsz;
    718 		pos = dlslot->a_lseek;
    719 		len = 0;
    720 
    721 		total = dlslot->a_text;
    722 
    723 		if (pos < total) {
    724 			notdone = total - pos;
    725 			if (notdone <= bsz) {
    726 				outlen = read(dlslot->ldfd,&buf[len],notdone);
    727 			} else {
    728 				outlen = read(dlslot->ldfd,&buf[len],bsz);
    729 			}
    730 			len = len + outlen;
    731 			pos = pos + outlen;
    732 			bsz = bsz - outlen;
    733 		}
    734 
    735 		total = total + dlslot->a_text_fill;
    736 
    737 		if ((bsz > 0) && (pos < total)) {
    738 			notdone = total - pos;
    739 			if (notdone <= bsz) {
    740 				outlen = notdone;
    741 			} else {
    742 				outlen = bsz;
    743 			}
    744 			memset(&buf[len], 0, outlen);
    745 			len = len + outlen;
    746 			pos = pos + outlen;
    747 			bsz = bsz - outlen;
    748 		}
    749 
    750 		total = total + dlslot->a_data;
    751 
    752 		if ((bsz > 0) && (pos < total)) {
    753 			notdone = total - pos;
    754 			if (notdone <= bsz) {
    755 				outlen = read(dlslot->ldfd,&buf[len],notdone);
    756 			} else {
    757 				outlen = read(dlslot->ldfd,&buf[len],bsz);
    758 			}
    759 			len = len + outlen;
    760 			pos = pos + outlen;
    761 			bsz = bsz - outlen;
    762 		}
    763 
    764 		total = total + dlslot->a_data_fill;
    765 
    766 		if ((bsz > 0) && (pos < total)) {
    767 			notdone = total - pos;
    768 			if (notdone <= bsz) {
    769 				outlen = notdone;
    770 			} else {
    771 				outlen = bsz;
    772 			}
    773 			memset(&buf[len], 0, outlen);
    774 			len = len + outlen;
    775 			pos = pos + outlen;
    776 			bsz = bsz - outlen;
    777 		}
    778 
    779 		total = total + dlslot->a_bss;
    780 
    781 		if ((bsz > 0) && (pos < total)) {
    782 			notdone = total - pos;
    783 			if (notdone <= bsz) {
    784 				outlen = notdone;
    785 			} else {
    786 				outlen = bsz;
    787 			}
    788 			memset(&buf[len], 0, outlen);
    789 			len = len + outlen;
    790 			pos = pos + outlen;
    791 			bsz = bsz - outlen;
    792 		}
    793 
    794 		total = total + dlslot->a_bss_fill;
    795 
    796 		if ((bsz > 0) && (pos < total)) {
    797 			notdone = total - pos;
    798 			if (notdone <= bsz) {
    799 				outlen = notdone;
    800 			} else {
    801 				outlen = bsz;
    802 			}
    803 			memset(&buf[len], 0, outlen);
    804 			len = len + outlen;
    805 			pos = pos + outlen;
    806 			bsz = bsz - outlen;
    807 		}
    808 
    809 		dlslot->a_lseek = pos;
    810 
    811 	}
    812 
    813 	return(len);
    814 }
    815