Home | History | Annotate | Line # | Download | only in common
file.c revision 1.5
      1 /*	$NetBSD: file.c,v 1.5 1998/02/07 00:03:22 cgd 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.5 1998/02/07 00:03:22 cgd 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 	case MID_I386:
    356 #ifdef MID_M68K4K
    357 	case MID_M68K4K:
    358 #endif
    359 #ifdef MID_NS32532
    360 	case MID_NS32532:
    361 #endif
    362 	case MID_SPARC:				/* It might be 8192 */
    363 #ifdef MID_PMAX
    364 	case MID_PMAX:
    365 #endif
    366 #ifdef MID_MIPS
    367 	case MID_MIPS:
    368 #endif
    369 #ifdef MID_ARM6
    370 	case MID_ARM6:
    371 #endif
    372 		clbytes = 4096;
    373 		break;
    374 #ifdef MID_M68K
    375 	case MID_M68K:
    376 #endif
    377 #ifdef MID_ALPHA
    378 	case MID_ALPHA:
    379 #endif
    380 #if defined(MID_M68K) || defined(MID_ALPHA)
    381 		clbytes = 8192;
    382 		break;
    383 #endif
    384 	default:
    385 		clbytes = 0;
    386 	}
    387 
    388 	return(clbytes);
    389 }
    390 #endif
    391 
    392 int
    393 CheckAOutFile(fd)
    394 	int	fd;
    395 {
    396 #ifdef NOAOUT
    397 	return(-1);
    398 #else
    399 	struct exec ex, ex_swap;
    400 	int	mid = -1;
    401 
    402 	if (read(fd, (char *)&ex, sizeof(ex)) != sizeof(ex))
    403 		return(-1);
    404 
    405 	(void)lseek(fd, (off_t) 0, SEEK_SET);
    406 
    407 	if (read(fd, (char *)&ex_swap, sizeof(ex_swap)) != sizeof(ex_swap))
    408 		return(-1);
    409 
    410 	(void)lseek(fd, (off_t) 0, SEEK_SET);
    411 
    412 	mid = getMID(mid, N_GETMID (ex));
    413 
    414 	if (mid == -1) {
    415 		mid = getMID(mid, N_GETMID (ex_swap));
    416 	}
    417 
    418 	if (mid != -1) {
    419 		return(0);
    420 	} else {
    421 		return(-1);
    422 	}
    423 #endif NOAOUT
    424 }
    425 
    426 int
    427 GetAOutFileInfo(fd, load, xfr, a_text, a_text_fill,
    428 		a_data, a_data_fill, a_bss, a_bss_fill, aout)
    429 	int		 fd;
    430 	u_int32_t	*load, *xfr, *a_text, *a_text_fill;
    431 	u_int32_t	*a_data, *a_data_fill, *a_bss, *a_bss_fill;
    432 	int		 *aout;
    433 {
    434 #ifdef NOAOUT
    435 	return(-1);
    436 #else
    437 	struct exec ex, ex_swap;
    438 	u_int32_t	mid = -1;
    439 	u_int32_t	magic, clbytes, clofset;
    440 
    441 	if (read(fd, (char *)&ex, sizeof(ex)) != sizeof(ex))
    442 		return(-1);
    443 
    444 	(void)lseek(fd, (off_t) 0, SEEK_SET);
    445 
    446 	if (read(fd, (char *)&ex_swap, sizeof(ex_swap)) != sizeof(ex_swap))
    447 		return(-1);
    448 
    449 	mopFileSwapX((u_char *)&ex_swap, 0, 4);
    450 
    451 	mid = getMID(mid, N_GETMID (ex));
    452 
    453 	if (mid == -1) {
    454 		mid = getMID(mid, N_GETMID (ex_swap));
    455 		if (mid != -1) {
    456 			mopFileSwapX((u_char *)&ex, 0, 4);
    457 		}
    458 	}
    459 
    460 	if (mid == -1) {
    461 		return(-1);
    462 	}
    463 
    464 	if (N_BADMAG (ex)) {
    465 		return(-1);
    466 	}
    467 
    468 	switch (mid) {
    469 	case MID_I386:
    470 #ifdef MID_NS32532
    471 	case MID_NS32532:
    472 #endif
    473 #ifdef MID_PMAX
    474 	case MID_PMAX:
    475 #endif
    476 #ifdef MID_VAX
    477 	case MID_VAX:
    478 #endif
    479 #ifdef MID_ALPHA
    480 	case MID_ALPHA:
    481 #endif
    482 #ifdef MID_ARM6
    483 	case MID_ARM6:
    484 #endif
    485 		ex.a_text  = mopFileGetLX((u_char *)&ex_swap,  4, 4);
    486 		ex.a_data  = mopFileGetLX((u_char *)&ex_swap,  8, 4);
    487 		ex.a_bss   = mopFileGetLX((u_char *)&ex_swap, 12, 4);
    488 		ex.a_syms  = mopFileGetLX((u_char *)&ex_swap, 16, 4);
    489 		ex.a_entry = mopFileGetLX((u_char *)&ex_swap, 20, 4);
    490 		ex.a_trsize= mopFileGetLX((u_char *)&ex_swap, 24, 4);
    491 		ex.a_drsize= mopFileGetLX((u_char *)&ex_swap, 28, 4);
    492 		break;
    493 #ifdef MID_M68K
    494 	case MID_M68K:
    495 #endif
    496 #ifdef MID_M68K4K
    497 	case MID_M68K4K:
    498 #endif
    499 	case MID_SPARC:
    500 #ifdef MID_MIPS
    501 	case MID_MIPS:
    502 #endif
    503 		ex.a_text  = mopFileGetBX((u_char *)&ex_swap,  4, 4);
    504 		ex.a_data  = mopFileGetBX((u_char *)&ex_swap,  8, 4);
    505 		ex.a_bss   = mopFileGetBX((u_char *)&ex_swap, 12, 4);
    506 		ex.a_syms  = mopFileGetBX((u_char *)&ex_swap, 16, 4);
    507 		ex.a_entry = mopFileGetBX((u_char *)&ex_swap, 20, 4);
    508 		ex.a_trsize= mopFileGetBX((u_char *)&ex_swap, 24, 4);
    509 		ex.a_drsize= mopFileGetBX((u_char *)&ex_swap, 28, 4);
    510 		break;
    511 	default:
    512 		break;
    513 	}
    514 
    515 	printf("a.out image (");
    516 	switch (N_GETMID (ex)) {
    517 	case MID_I386:
    518 		printf("i386");
    519 		break;
    520 #ifdef MID_M68K
    521 	case MID_M68K:
    522 		printf("m68k");
    523 		break;
    524 #endif
    525 #ifdef MID_M68K4K
    526 	case MID_M68K4K:
    527 		printf("m68k 4k");
    528 		break;
    529 #endif
    530 #ifdef MID_NS32532
    531 	case MID_NS32532:
    532 		printf("pc532");
    533 		break;
    534 #endif
    535 	case MID_SPARC:
    536 		printf("sparc");
    537 		break;
    538 #ifdef MID_PMAX
    539 	case MID_PMAX:
    540 		printf("pmax");
    541 		break;
    542 #endif
    543 #ifdef MID_VAX
    544 	case MID_VAX:
    545 		printf("vax");
    546 		break;
    547 #endif
    548 #ifdef MID_ALPHA
    549 	case MID_ALPHA:
    550 		printf("alpha");
    551 		break;
    552 #endif
    553 #ifdef MID_MIPS
    554 	case MID_MIPS:
    555 		printf("mips");
    556 		break;
    557 #endif
    558 #ifdef MID_ARM6
    559 	case MID_ARM6:
    560 		printf("arm32");
    561 		break;
    562 #endif
    563 	default:
    564 		break;
    565 	}
    566 	printf(") Magic: ");
    567 	switch (N_GETMAGIC (ex)) {
    568 	case OMAGIC:
    569 		printf("OMAGIC");
    570 		break;
    571 	case NMAGIC:
    572 		printf("NMAGIC");
    573 		break;
    574 	case ZMAGIC:
    575 		printf("ZMAGIC");
    576 		break;
    577 	case QMAGIC:
    578 		printf("QMAGIC");
    579 		break;
    580 	default:
    581 		printf("Unknown %ld", (long) N_GETMAGIC (ex));
    582 	}
    583 	printf("\n");
    584 	printf("Size of text:       %08lx\n", (long)ex.a_text);
    585 	printf("Size of data:       %08lx\n", (long)ex.a_data);
    586 	printf("Size of bss:        %08lx\n", (long)ex.a_bss);
    587 	printf("Size of symbol tab: %08lx\n", (long)ex.a_syms);
    588 	printf("Transfer Address:   %08lx\n", (long)ex.a_entry);
    589 	printf("Size of reloc text: %08lx\n", (long)ex.a_trsize);
    590 	printf("Size of reloc data: %08lx\n", (long)ex.a_drsize);
    591 
    592 	magic = N_GETMAGIC (ex);
    593 	clbytes = getCLBYTES(mid);
    594 	clofset = clbytes - 1;
    595 
    596 	if (load != NULL) {
    597 		*load   = 0;
    598 	}
    599 
    600 	if (xfr != NULL) {
    601 		*xfr    = ex.a_entry;
    602 	}
    603 
    604 	if (a_text != NULL) {
    605 		*a_text = ex.a_text;
    606 	}
    607 
    608 	if (a_text_fill != NULL) {
    609 		if (magic == ZMAGIC || magic == NMAGIC) {
    610 			*a_text_fill = clbytes - (ex.a_text & clofset);
    611 			if (*a_text_fill == clbytes) {
    612 				*a_text_fill = 0;
    613 			}
    614 		} else {
    615 			*a_text_fill = 0;
    616 	        }
    617 	}
    618 
    619 	if (a_data != NULL) {
    620 		*a_data = ex.a_data;
    621 	}
    622 
    623 	if (a_data_fill != NULL) {
    624 		if (magic == ZMAGIC || magic == NMAGIC) {
    625 			*a_data_fill = clbytes - (ex.a_data & clofset);
    626 			if (*a_data_fill == clbytes) {
    627 				*a_data_fill = 0;
    628 			}
    629 		} else {
    630 			*a_data_fill = 0;
    631 	        }
    632 	}
    633 
    634 	if (a_bss != NULL) {
    635 		*a_bss  = ex.a_bss;
    636 	}
    637 
    638 	if (a_bss_fill != NULL) {
    639 		if (magic == ZMAGIC || magic == NMAGIC) {
    640 			*a_bss_fill = clbytes - (ex.a_bss & clofset);
    641 			if (*a_bss_fill == clbytes) {
    642 				*a_bss_fill = 0;
    643 			}
    644 		} else {
    645 			*a_bss_fill = clbytes -
    646 				((ex.a_text+ex.a_data+ex.a_bss) & clofset);
    647 			if (*a_text_fill == clbytes) {
    648 				*a_text_fill = 0;
    649 			}
    650 	        }
    651 	}
    652 
    653 	if (aout != NULL) {
    654 		*aout = mid;
    655 	}
    656 
    657 	return(0);
    658 #endif NOAOUT
    659 }
    660 
    661 int
    662 GetFileInfo(fd, load, xfr, aout,
    663 	    a_text, a_text_fill, a_data, a_data_fill, a_bss, a_bss_fill)
    664 	int	fd, *aout;
    665 	u_int32_t	*load, *xfr, *a_text, *a_text_fill;
    666 	u_int32_t	*a_data, *a_data_fill, *a_bss, *a_bss_fill;
    667 {
    668 	int	err;
    669 
    670 	err = CheckAOutFile(fd);
    671 
    672 	if (err == 0) {
    673 		err = GetAOutFileInfo(fd, load, xfr,
    674 				      a_text, a_text_fill,
    675 				      a_data, a_data_fill,
    676 				      a_bss, a_bss_fill,
    677 				      aout);
    678 		if (err != 0) {
    679 			return(-1);
    680 		}
    681 	} else {
    682 		err = CheckMopFile(fd);
    683 
    684 		if (err == 0) {
    685 			err = GetMopFileInfo(fd, load, xfr);
    686 			if (err != 0) {
    687 				return(-1);
    688 			}
    689 			*aout = -1;
    690 		} else {
    691 			return(-1);
    692 		}
    693 	}
    694 
    695 	return(0);
    696 }
    697 
    698 ssize_t
    699 mopFileRead(dlslot, buf)
    700 	struct dllist *dlslot;
    701 	u_char	*buf;
    702 {
    703 	ssize_t len, outlen;
    704 	int	bsz;
    705 	int32_t	pos, notdone, total;
    706 
    707 	if (dlslot->aout == -1) {
    708 		len = read(dlslot->ldfd,buf,dlslot->dl_bsz);
    709 	} else {
    710 		bsz = dlslot->dl_bsz;
    711 		pos = dlslot->a_lseek;
    712 		len = 0;
    713 
    714 		total = dlslot->a_text;
    715 
    716 		if (pos < total) {
    717 			notdone = total - pos;
    718 			if (notdone <= bsz) {
    719 				outlen = read(dlslot->ldfd,&buf[len],notdone);
    720 			} else {
    721 				outlen = read(dlslot->ldfd,&buf[len],bsz);
    722 			}
    723 			len = len + outlen;
    724 			pos = pos + outlen;
    725 			bsz = bsz - outlen;
    726 		}
    727 
    728 		total = total + dlslot->a_text_fill;
    729 
    730 		if ((bsz > 0) && (pos < total)) {
    731 			notdone = total - pos;
    732 			if (notdone <= bsz) {
    733 				outlen = notdone;
    734 			} else {
    735 				outlen = bsz;
    736 			}
    737 			memset(&buf[len], 0, outlen);
    738 			len = len + outlen;
    739 			pos = pos + outlen;
    740 			bsz = bsz - outlen;
    741 		}
    742 
    743 		total = total + dlslot->a_data;
    744 
    745 		if ((bsz > 0) && (pos < total)) {
    746 			notdone = total - pos;
    747 			if (notdone <= bsz) {
    748 				outlen = read(dlslot->ldfd,&buf[len],notdone);
    749 			} else {
    750 				outlen = read(dlslot->ldfd,&buf[len],bsz);
    751 			}
    752 			len = len + outlen;
    753 			pos = pos + outlen;
    754 			bsz = bsz - outlen;
    755 		}
    756 
    757 		total = total + dlslot->a_data_fill;
    758 
    759 		if ((bsz > 0) && (pos < total)) {
    760 			notdone = total - pos;
    761 			if (notdone <= bsz) {
    762 				outlen = notdone;
    763 			} else {
    764 				outlen = bsz;
    765 			}
    766 			memset(&buf[len], 0, outlen);
    767 			len = len + outlen;
    768 			pos = pos + outlen;
    769 			bsz = bsz - outlen;
    770 		}
    771 
    772 		total = total + dlslot->a_bss;
    773 
    774 		if ((bsz > 0) && (pos < total)) {
    775 			notdone = total - pos;
    776 			if (notdone <= bsz) {
    777 				outlen = notdone;
    778 			} else {
    779 				outlen = bsz;
    780 			}
    781 			memset(&buf[len], 0, outlen);
    782 			len = len + outlen;
    783 			pos = pos + outlen;
    784 			bsz = bsz - outlen;
    785 		}
    786 
    787 		total = total + dlslot->a_bss_fill;
    788 
    789 		if ((bsz > 0) && (pos < total)) {
    790 			notdone = total - pos;
    791 			if (notdone <= bsz) {
    792 				outlen = notdone;
    793 			} else {
    794 				outlen = bsz;
    795 			}
    796 			memset(&buf[len], 0, outlen);
    797 			len = len + outlen;
    798 			pos = pos + outlen;
    799 			bsz = bsz - outlen;
    800 		}
    801 
    802 		dlslot->a_lseek = pos;
    803 
    804 	}
    805 
    806 	return(len);
    807 }
    808