Home | History | Annotate | Line # | Download | only in aout2hux
aout2hux.c revision 1.10
      1   1.1   itohy /*
      2   1.4   itohy  *	aout2hux - convert a.out/ELF executable to Human68k .x format
      3   1.1   itohy  *
      4   1.4   itohy  *	Read two a.out/ELF format executables with different load addresses
      5   1.1   itohy  *	and generate Human68k .x format executable.
      6   1.1   itohy  *
      7   1.1   itohy  *	written by Yasha (ITOH Yasufumi)
      8   1.1   itohy  *	public domain
      9   1.1   itohy  *
     10   1.1   itohy  * usage:
     11   1.1   itohy  *	aout2hux [ -o output.x ] a.out1 loadaddr1 a.out2 loadaddr2
     12   1.1   itohy  *
     13   1.4   itohy  *	The input files must be static OMAGIC/NMAGIC m68k a.out executables
     14   1.4   itohy  *	or m68k ELF executables.
     15   1.4   itohy  *	Two executables must have different loading addresses.
     16   1.1   itohy  *	Each of the load address must be a hexadecimal number.
     17   1.1   itohy  *	Load address shall be multiple of 4 for as / ld of NetBSD/m68k.
     18   1.1   itohy  *
     19   1.1   itohy  * example:
     20   1.4   itohy  *	% cc -N -static -Wl,-Ttext,0        -o aout1 *.o
     21   1.4   itohy  *	% cc -N -static -Wl,-Ttext,10203040 -o aout2 *.o
     22   1.1   itohy  *	% aout2hux -o foo.x aout1 0 aout2 10203040
     23   1.1   itohy  *
     24  1.10  cegger  *	$NetBSD: aout2hux.c,v 1.10 2009/03/18 16:00:16 cegger Exp $
     25   1.1   itohy  */
     26   1.1   itohy 
     27   1.1   itohy #include <sys/types.h>
     28   1.1   itohy #ifndef NO_UNISTD
     29   1.1   itohy # include <unistd.h>
     30   1.1   itohy #endif
     31   1.1   itohy #ifndef NO_STDLIB
     32   1.1   itohy # include <stdlib.h>
     33   1.1   itohy #endif
     34   1.1   itohy #include <stdio.h>
     35   1.1   itohy #include <string.h>
     36   1.1   itohy 
     37   1.1   itohy #include "type_local.h"
     38   1.1   itohy #include "aout68k.h"
     39   1.1   itohy #include "hux.h"
     40   1.1   itohy 
     41   1.4   itohy /* fseek() offset type */
     42   1.4   itohy typedef long	foff_t;
     43   1.4   itohy 
     44   1.1   itohy #ifndef DEFAULT_OUTPUT_FILE
     45   1.1   itohy # define DEFAULT_OUTPUT_FILE	"out.x"
     46   1.1   itohy #endif
     47   1.1   itohy 
     48   1.1   itohy #ifdef DEBUG
     49   1.1   itohy # define DPRINTF(x)	printf x
     50   1.1   itohy #else
     51   1.1   itohy # define DPRINTF(x)
     52   1.1   itohy #endif
     53   1.1   itohy 
     54   1.4   itohy struct exec_info {
     55   1.4   itohy 	foff_t		text_off;	/* file offset of text section */
     56   1.4   itohy 	foff_t		data_off;	/* file offset of data section */
     57   1.4   itohy 	u_int32_t	text_size;	/* size of text section */
     58   1.4   itohy 	u_int32_t	text_pad;	/* pad between text and data */
     59   1.4   itohy 	u_int32_t	data_size;	/* size of data section */
     60   1.4   itohy 	u_int32_t	bss_size;	/* size of bss */
     61   1.4   itohy 	u_int32_t	entry_addr;	/* entry point address */
     62   1.4   itohy };
     63   1.4   itohy 
     64   1.1   itohy unsigned get_uint16 PROTO((be_uint16_t *be));
     65   1.1   itohy u_int32_t get_uint32 PROTO((be_uint32_t *be));
     66   1.1   itohy void put_uint16 PROTO((be_uint16_t *be, unsigned v));
     67   1.1   itohy void put_uint32 PROTO((be_uint32_t *be, u_int32_t v));
     68   1.1   itohy void *do_realloc PROTO((void *p, size_t s));
     69   1.1   itohy 
     70   1.6     dsl static int open_aout(const char *fn, struct aout_m68k *hdr,
     71   1.6     dsl 		struct exec_info *inf);
     72   1.4   itohy static int open_elf PROTO((const char *fn, FILE *fp, struct elf_m68k_hdr *hdr,
     73   1.4   itohy 		struct exec_info *inf));
     74   1.4   itohy FILE *open_exec PROTO((const char *fn, struct exec_info *inf));
     75   1.4   itohy int check_2_exec_inf PROTO((struct exec_info *inf1, struct exec_info *inf2));
     76   1.1   itohy int aout2hux PROTO((const char *fn1, const char *fn2,
     77   1.1   itohy 		u_int32_t loadadr1, u_int32_t loadadr2, const char *fnx));
     78   1.1   itohy int gethex PROTO((u_int32_t *pval, const char *str));
     79   1.1   itohy void usage PROTO((const char *name));
     80   1.1   itohy int main PROTO((int argc, char *argv[]));
     81   1.1   itohy 
     82   1.1   itohy #if !defined(bzero) && defined(__SVR4)
     83   1.1   itohy # define bzero(d, n)	memset((d), 0, (n))
     84   1.1   itohy #endif
     85   1.1   itohy 
     86   1.1   itohy /*
     87   1.1   itohy  * read/write big-endian integer
     88   1.1   itohy  */
     89   1.1   itohy 
     90   1.1   itohy unsigned
     91   1.7     dsl get_uint16(be_uint16_t *be)
     92   1.1   itohy {
     93   1.1   itohy 
     94   1.1   itohy 	return be->val[0] << 8 | be->val[1];
     95   1.1   itohy }
     96   1.1   itohy 
     97   1.1   itohy u_int32_t
     98   1.7     dsl get_uint32(be_uint32_t *be)
     99   1.1   itohy {
    100   1.1   itohy 
    101   1.1   itohy 	return be->val[0]<<24 | be->val[1]<<16 | be->val[2]<<8 | be->val[3];
    102   1.1   itohy }
    103   1.1   itohy 
    104   1.1   itohy void
    105   1.7     dsl put_uint16(be_uint16_t *be, unsigned v)
    106   1.1   itohy {
    107   1.1   itohy 
    108   1.1   itohy 	be->val[0] = (u_int8_t) (v >> 8);
    109   1.1   itohy 	be->val[1] = (u_int8_t) v;
    110   1.1   itohy }
    111   1.1   itohy 
    112   1.1   itohy void
    113   1.7     dsl put_uint32(be_uint32_t *be, u_int32_t v)
    114   1.1   itohy {
    115   1.1   itohy 
    116   1.1   itohy 	be->val[0] = (u_int8_t) (v >> 24);
    117   1.1   itohy 	be->val[1] = (u_int8_t) (v >> 16);
    118   1.1   itohy 	be->val[2] = (u_int8_t) (v >> 8);
    119   1.1   itohy 	be->val[3] = (u_int8_t) v;
    120   1.1   itohy }
    121   1.1   itohy 
    122   1.1   itohy void *
    123   1.7     dsl do_realloc(void *p, size_t s)
    124   1.1   itohy {
    125   1.1   itohy 
    126   1.1   itohy 	p = p ? realloc(p, s) : malloc(s);	/* for portability */
    127   1.1   itohy 
    128   1.1   itohy 	if (!p) {
    129   1.1   itohy 		fprintf(stderr, "malloc failed\n");
    130   1.1   itohy 		exit(1);
    131   1.1   itohy 	}
    132   1.1   itohy 
    133   1.1   itohy 	return p;
    134   1.1   itohy }
    135   1.1   itohy 
    136   1.1   itohy /*
    137   1.4   itohy  * check a.out header
    138   1.4   itohy  */
    139   1.4   itohy static int
    140   1.7     dsl open_aout(const char *fn, struct aout_m68k *hdr, struct exec_info *inf)
    141   1.4   itohy {
    142   1.4   itohy 	int i;
    143   1.4   itohy 
    144   1.4   itohy 	DPRINTF(("%s: is an a.out\n", fn));
    145   1.4   itohy 
    146   1.4   itohy 	if ((i = AOUT_GET_MID(hdr)) != AOUT_MID_M68K && i != AOUT_MID_M68K4K) {
    147   1.4   itohy 		fprintf(stderr, "%s: wrong architecture (mid %d)\n", fn, i);
    148   1.4   itohy 		return 1;
    149   1.4   itohy 	}
    150   1.4   itohy 
    151   1.4   itohy 	/* if unsolved relocations exist, not an executable but an object */
    152   1.4   itohy 	if (hdr->a_trsize.hostval || hdr->a_drsize.hostval) {
    153   1.4   itohy 		fprintf(stderr, "%s: not an executable (object file?)\n", fn);
    154   1.4   itohy 		return 1;
    155   1.4   itohy 	}
    156   1.4   itohy 
    157   1.4   itohy 	if (AOUT_GET_FLAGS(hdr) & (AOUT_FLAG_PIC | AOUT_FLAG_DYNAMIC)) {
    158   1.4   itohy 		fprintf(stderr, "%s: PIC and DYNAMIC are not supported\n", fn);
    159   1.4   itohy 		return 1;
    160   1.4   itohy 	}
    161   1.4   itohy 
    162   1.4   itohy 	inf->text_size = get_uint32(&hdr->a_text);
    163   1.4   itohy 	inf->data_size = get_uint32(&hdr->a_data);
    164   1.4   itohy 	inf->bss_size = get_uint32(&hdr->a_bss);
    165   1.4   itohy 	inf->entry_addr = get_uint32(&hdr->a_entry);
    166   1.4   itohy 	inf->text_off = sizeof(struct aout_m68k);
    167   1.4   itohy 	inf->data_off = sizeof(struct aout_m68k) + inf->text_size;
    168   1.4   itohy 	inf->text_pad = -inf->text_size & (AOUT_PAGESIZE(hdr) - 1);
    169   1.4   itohy 
    170   1.4   itohy 	return 0;
    171   1.4   itohy }
    172   1.4   itohy 
    173   1.4   itohy /*
    174   1.4   itohy  * digest ELF structure
    175   1.4   itohy  */
    176   1.4   itohy static int
    177   1.7     dsl open_elf(const char *fn, FILE *fp, struct elf_m68k_hdr *hdr, struct exec_info *inf)
    178   1.4   itohy {
    179   1.4   itohy 	int i;
    180   1.4   itohy 	size_t nphdr;
    181   1.4   itohy 	struct elf_m68k_phdr phdr[2];
    182   1.4   itohy 
    183   1.4   itohy 	DPRINTF(("%s: is an ELF\n", fn));
    184   1.4   itohy 
    185   1.4   itohy 	if (hdr->e_ident[EI_VERSION] != EV_CURRENT ||
    186   1.4   itohy 	    get_uint32(&hdr->e_version) != EV_CURRENT) {
    187   1.4   itohy 		fprintf(stderr, "%s: unknown ELF version\n", fn);
    188   1.4   itohy 		return 1;
    189   1.4   itohy 	}
    190   1.4   itohy 
    191   1.5   itohy 	if (get_uint16(&hdr->e_type) != ET_EXEC) {
    192   1.4   itohy 		fprintf(stderr, "%s: not an executable\n", fn);
    193   1.4   itohy 		return 1;
    194   1.4   itohy 	}
    195   1.4   itohy 
    196   1.4   itohy 	if ((i = get_uint16(&hdr->e_machine)) != EM_68K) {
    197   1.4   itohy 		fprintf(stderr, "%s: wrong architecture (%d)\n", fn, i);
    198   1.4   itohy 		return 1;
    199   1.4   itohy 	}
    200   1.4   itohy 
    201   1.4   itohy 	if ((i = get_uint16(&hdr->e_shentsize)) != SIZE_ELF68K_SHDR) {
    202   1.4   itohy 		fprintf(stderr, "%s: size shdr %d should be %d\n", fn, i,
    203   1.4   itohy 			SIZE_ELF68K_SHDR);
    204   1.4   itohy 		return 1;
    205   1.4   itohy 	}
    206   1.4   itohy 
    207   1.4   itohy 	if ((i = get_uint16(&hdr->e_phentsize)) != SIZE_ELF68K_PHDR) {
    208   1.4   itohy 		fprintf(stderr, "%s: size phdr %d should be %d\n", fn, i,
    209   1.4   itohy 			SIZE_ELF68K_PHDR);
    210   1.4   itohy 		return 1;
    211   1.4   itohy 	}
    212   1.4   itohy 
    213   1.4   itohy 	if ((nphdr = get_uint16(&hdr->e_phnum)) != 1 && nphdr != 2) {
    214   1.4   itohy 		fprintf(stderr,
    215   1.4   itohy 			"%s: has %d loadable segments (should be 1 or 2)\n",
    216   1.4   itohy 			fn, nphdr);
    217   1.4   itohy 		return 1;
    218   1.4   itohy 	}
    219   1.4   itohy 
    220   1.4   itohy 	/* Read ELF program header table. */
    221   1.4   itohy 	if (fseek(fp, (foff_t) get_uint32(&hdr->e_phoff), SEEK_SET)) {
    222   1.4   itohy 		perror(fn);
    223   1.4   itohy 		return 1;
    224   1.4   itohy 	}
    225   1.4   itohy 	if (fread(phdr, sizeof phdr[0], nphdr, fp) != nphdr) {
    226   1.4   itohy 		fprintf(stderr, "%s: can't read ELF program header\n", fn);
    227   1.4   itohy 		return 1;
    228   1.4   itohy 	}
    229   1.4   itohy 
    230   1.4   itohy 	/* Just error checking. */
    231   1.4   itohy 	for (i = 0; i < (int) nphdr; i++) {
    232   1.4   itohy 		if (get_uint32(&phdr[i].p_type) != PT_LOAD) {
    233   1.4   itohy 			fprintf(stderr,
    234   1.4   itohy 				"%s: program header #%d is not loadable\n",
    235   1.4   itohy 				fn, i);
    236   1.4   itohy 			return 1;
    237   1.4   itohy 		}
    238   1.4   itohy 	}
    239   1.4   itohy 
    240   1.4   itohy 	if (nphdr == 1 && (get_uint32(&phdr[0].p_flags) & PF_W)) {
    241   1.4   itohy 		/*
    242   1.4   itohy 		 * Only one writable section --- probably "ld -N" executable.
    243   1.4   itohy 		 * Find out the start of data segment.
    244   1.4   itohy 		 */
    245   1.4   itohy 		struct elf_m68k_shdr shdr;
    246   1.4   itohy 		int nshdr;
    247   1.4   itohy 
    248   1.4   itohy 		nshdr = get_uint16(&hdr->e_shnum);
    249   1.4   itohy 
    250   1.4   itohy 		/* section #0 always exists and reserved --- skip */
    251   1.4   itohy 		if (nshdr > 1 &&
    252   1.4   itohy 		    fseek(fp,
    253   1.4   itohy 			  (foff_t) (get_uint32(&hdr->e_shoff) + sizeof shdr),
    254   1.4   itohy 			  SEEK_SET)) {
    255   1.4   itohy 			perror(fn);
    256   1.4   itohy 			return 1;
    257   1.4   itohy 		}
    258   1.4   itohy 		for (i = 1; i < nshdr; i++) {
    259   1.4   itohy 			if (fread(&shdr, sizeof shdr, 1, fp) != 1) {
    260   1.4   itohy 				fprintf(stderr,
    261   1.4   itohy 					"%s: can't read ELF section header\n",
    262   1.4   itohy 					fn);
    263   1.4   itohy 				return 1;
    264   1.4   itohy 			}
    265   1.4   itohy 
    266   1.4   itohy 			DPRINTF(("%s: section header #%d: flags 0x%x\n",
    267   1.4   itohy 				fn, i, get_uint32(&shdr.sh_flags)));
    268   1.4   itohy 
    269   1.4   itohy 			if (ELF68K_ISDATASEG(&shdr)) {
    270   1.4   itohy 				/*
    271   1.4   itohy 				 * data section is found.
    272   1.4   itohy 				 */
    273   1.4   itohy 				DPRINTF(("%s: one section, data found\n", fn));
    274   1.4   itohy 				inf->text_off = get_uint32(&phdr[0].p_offset);
    275   1.4   itohy 				inf->text_size = get_uint32(&shdr.sh_offset) -
    276   1.4   itohy 						 inf->text_off;
    277   1.4   itohy 				inf->text_pad = 0;
    278   1.4   itohy 				inf->data_off = inf->text_off + inf->text_size;
    279   1.4   itohy 				inf->data_size = get_uint32(&phdr[0].p_filesz) -
    280   1.4   itohy 						 inf->text_size;
    281   1.4   itohy 				inf->bss_size = get_uint32(&phdr[0].p_memsz) -
    282   1.4   itohy 						get_uint32(&phdr[0].p_filesz);
    283   1.4   itohy 				inf->entry_addr = get_uint32(&hdr->e_entry);
    284   1.4   itohy 				goto data_found;
    285   1.4   itohy 			}
    286   1.4   itohy 		}
    287   1.4   itohy 		/*
    288   1.4   itohy 		 * No data section found --- probably text + bss.
    289   1.4   itohy 		 */
    290   1.4   itohy 		DPRINTF(("%s: one section, no data section\n", fn));
    291   1.4   itohy 		inf->text_size = get_uint32(&phdr[0].p_filesz);
    292   1.4   itohy 		inf->data_size = 0;
    293   1.4   itohy 		inf->bss_size = get_uint32(&phdr[0].p_memsz) - inf->text_size;
    294   1.4   itohy 		inf->entry_addr = get_uint32(&hdr->e_entry);
    295   1.4   itohy 		inf->text_off = get_uint32(&phdr[0].p_offset);
    296   1.4   itohy 		inf->data_off = 0;
    297   1.4   itohy 		inf->text_pad = 0;
    298   1.4   itohy data_found:;
    299   1.4   itohy 	} else if (nphdr == 1) {
    300   1.4   itohy 		/*
    301   1.4   itohy 		 * Only one non-writable section --- pure text program?
    302   1.4   itohy 		 */
    303   1.4   itohy 		DPRINTF(("%s: one RO section\n", fn));
    304   1.4   itohy 		inf->text_size = get_uint32(&phdr[0].p_filesz);
    305   1.4   itohy 		inf->data_size = 0;
    306   1.4   itohy 		inf->bss_size = 0;
    307   1.4   itohy 		inf->entry_addr = get_uint32(&hdr->e_entry);
    308   1.4   itohy 		inf->text_off = get_uint32(&phdr[0].p_offset);
    309   1.4   itohy 		inf->data_off = 0;
    310   1.4   itohy 		inf->text_pad = get_uint32(&phdr[0].p_memsz) - inf->text_size;
    311   1.4   itohy 	} else {
    312   1.4   itohy 		/*
    313   1.4   itohy 		 * two sections
    314   1.4   itohy 		 * text + data assumed.
    315   1.4   itohy 		 */
    316   1.4   itohy 		int t = 0, d = 1, tmp;	/* first guess */
    317   1.4   itohy #define SWAP_T_D	tmp = t, t = d, d = tmp
    318   1.4   itohy 
    319   1.4   itohy 		DPRINTF(("%s: two sections\n", fn));
    320   1.4   itohy 
    321   1.4   itohy 		/* Find out text and data. */
    322   1.4   itohy 		if (get_uint32(&phdr[t].p_vaddr) > get_uint32(&phdr[d].p_vaddr))
    323   1.4   itohy 			SWAP_T_D;
    324   1.4   itohy 
    325   1.4   itohy 		if ((get_uint32(&phdr[t].p_flags) & PF_X) == 0 &&
    326   1.4   itohy 		    get_uint32(&phdr[d].p_flags) & PF_X)
    327   1.4   itohy 			SWAP_T_D;
    328   1.4   itohy 
    329   1.4   itohy 		if ((get_uint32(&phdr[d].p_flags) & PF_W) == 0 &&
    330   1.4   itohy 		    get_uint32(&phdr[t].p_flags) & PF_W)
    331   1.4   itohy 			SWAP_T_D;
    332   1.4   itohy #undef SWAP_T_D
    333   1.4   itohy 
    334   1.4   itohy 		/* Are the text/data sections correctly detected? */
    335   1.4   itohy 		if (get_uint32(&phdr[t].p_vaddr) >
    336   1.4   itohy 		    get_uint32(&phdr[d].p_vaddr)) {
    337   1.4   itohy 			fprintf(stderr, "%s: program sections not in order\n",
    338   1.4   itohy 				fn);
    339   1.4   itohy 			return 1;
    340   1.4   itohy 		}
    341   1.4   itohy 
    342   1.4   itohy 		if ((get_uint32(&phdr[t].p_flags) & PF_X) == 0)
    343   1.4   itohy 			fprintf(stderr, "%s: warning: text is not executable\n",
    344   1.4   itohy 				fn);
    345   1.4   itohy 
    346   1.4   itohy 		if ((get_uint32(&phdr[d].p_flags) & PF_W) == 0)
    347   1.4   itohy 			fprintf(stderr, "%s: warning: data is not writable\n",
    348   1.4   itohy 				fn);
    349   1.4   itohy 
    350   1.4   itohy 		inf->text_size = get_uint32(&phdr[t].p_filesz);
    351   1.4   itohy 		inf->data_size = get_uint32(&phdr[d].p_filesz);
    352   1.4   itohy 		inf->bss_size = get_uint32(&phdr[d].p_memsz) - inf->data_size;
    353   1.4   itohy 		inf->entry_addr = get_uint32(&hdr->e_entry);
    354   1.4   itohy 		inf->text_off = get_uint32(&phdr[t].p_offset);
    355   1.4   itohy 		inf->data_off = get_uint32(&phdr[d].p_offset);
    356   1.4   itohy 		inf->text_pad = get_uint32(&phdr[d].p_vaddr) -
    357   1.4   itohy 			(get_uint32(&phdr[t].p_vaddr) + inf->text_size);
    358   1.4   itohy 	}
    359   1.4   itohy 
    360   1.4   itohy 	return 0;
    361   1.4   itohy }
    362   1.4   itohy 
    363   1.4   itohy /*
    364   1.4   itohy  * open an executable
    365   1.1   itohy  */
    366   1.1   itohy FILE *
    367   1.7     dsl open_exec(const char *fn, struct exec_info *inf)
    368   1.1   itohy {
    369   1.1   itohy 	FILE *fp;
    370   1.1   itohy 	int i;
    371   1.4   itohy 	union {
    372   1.4   itohy 		struct aout_m68k	u_aout;
    373   1.4   itohy 		struct elf_m68k_hdr	u_elf;
    374   1.4   itohy 	} buf;
    375   1.4   itohy #define hdra	(&buf.u_aout)
    376   1.4   itohy #define hdre	(&buf.u_elf)
    377   1.1   itohy 
    378   1.1   itohy 	if (!(fp = fopen(fn, "r"))) {
    379   1.1   itohy 		perror(fn);
    380   1.1   itohy 		return (FILE *) NULL;
    381   1.1   itohy 	}
    382   1.4   itohy 
    383   1.4   itohy 	/*
    384   1.4   itohy 	 * Check for a.out.
    385   1.4   itohy 	 */
    386   1.4   itohy 
    387   1.4   itohy 	if (fread(hdra, sizeof(struct aout_m68k), 1, fp) != 1) {
    388   1.1   itohy 		fprintf(stderr, "%s: can't read a.out header\n", fn);
    389   1.1   itohy 		goto out;
    390   1.1   itohy 	}
    391   1.1   itohy 
    392   1.4   itohy 	if ((i = AOUT_GET_MAGIC(hdra)) != AOUT_OMAGIC && i != AOUT_NMAGIC)
    393   1.4   itohy 		goto notaout;
    394   1.4   itohy 
    395   1.4   itohy 	if (open_aout(fn, hdra, inf))
    396   1.1   itohy 		goto out;
    397   1.1   itohy 
    398   1.4   itohy 	/* OK! */
    399   1.4   itohy 	return fp;
    400   1.4   itohy 
    401   1.4   itohy notaout:
    402   1.4   itohy 	/*
    403   1.4   itohy 	 * Check for ELF.
    404   1.4   itohy 	 */
    405   1.4   itohy 
    406   1.4   itohy 	if (hdre->e_ident[EI_MAG0] != ELFMAG0 ||
    407   1.4   itohy 	    hdre->e_ident[EI_MAG1] != ELFMAG1 ||
    408   1.4   itohy 	    hdre->e_ident[EI_MAG2] != ELFMAG2 ||
    409   1.4   itohy 	    hdre->e_ident[EI_MAG3] != ELFMAG3 ||
    410   1.4   itohy 	    hdre->e_ident[EI_CLASS] != ELFCLASS32 ||
    411   1.4   itohy 	    hdre->e_ident[EI_DATA] != ELFDATA2MSB) {
    412   1.4   itohy 		fprintf(stderr,
    413   1.4   itohy 		    "%s: not an OMAGIC or NMAGIC a.out, or a 32bit BE ELF\n",
    414   1.4   itohy 		    fn);
    415   1.1   itohy 		goto out;
    416   1.1   itohy 	}
    417   1.1   itohy 
    418   1.4   itohy 	/* ELF header is longer than a.out header.  Read the rest. */
    419   1.4   itohy 	if (fread(hdra + 1,
    420   1.4   itohy 		  sizeof(struct elf_m68k_hdr) - sizeof(struct aout_m68k),
    421   1.4   itohy 		  1, fp) != 1) {
    422   1.4   itohy 		fprintf(stderr, "%s: can't read ELF header\n", fn);
    423   1.1   itohy 		goto out;
    424   1.1   itohy 	}
    425   1.1   itohy 
    426   1.4   itohy 	if (open_elf(fn, fp, hdre, inf))
    427   1.1   itohy 		goto out;
    428   1.1   itohy 
    429   1.1   itohy 	/* OK! */
    430   1.1   itohy 	return fp;
    431   1.1   itohy 
    432   1.1   itohy out:	fclose(fp);
    433   1.1   itohy 	return (FILE *) NULL;
    434   1.4   itohy #undef hdra
    435   1.4   itohy #undef hdre
    436   1.1   itohy }
    437   1.1   itohy 
    438   1.1   itohy /*
    439   1.4   itohy  * compare two executables and check if they are compatible
    440   1.1   itohy  */
    441   1.1   itohy int
    442   1.8     dsl check_2_exec_inf(struct exec_info *inf1, struct exec_info *inf2)
    443   1.1   itohy {
    444   1.1   itohy 
    445   1.4   itohy 	if (inf1->text_size != inf2->text_size ||
    446   1.4   itohy 	    inf1->text_pad != inf2->text_pad ||
    447   1.4   itohy 	    inf1->data_size != inf2->data_size ||
    448   1.4   itohy 	    inf1->bss_size != inf2->bss_size)
    449   1.1   itohy 		return -1;
    450   1.1   itohy 
    451   1.1   itohy 	return 0;
    452   1.1   itohy }
    453   1.1   itohy 
    454   1.1   itohy /* allocation unit (in bytes) of relocation table */
    455   1.1   itohy #define RELTBL_CHUNK	8192
    456   1.1   itohy 
    457   1.1   itohy /*
    458   1.1   itohy  * add an entry to the relocation table
    459   1.1   itohy  */
    460   1.1   itohy #define ADD_RELTBL(adr)	\
    461   1.1   itohy 	if (relsize + sizeof(struct relinf_l) > relallocsize)		    \
    462   1.1   itohy 		reltbl = do_realloc(reltbl, relallocsize += RELTBL_CHUNK);  \
    463   1.1   itohy 	if ((adr) < reladdr + HUX_MINLREL) {				    \
    464   1.1   itohy 		struct relinf_s *r = (struct relinf_s *)(reltbl + relsize); \
    465   1.1   itohy 		put_uint16(&r->locoff_s, (unsigned)((adr) - reladdr));	    \
    466   1.1   itohy 		relsize += sizeof(struct relinf_s);			    \
    467   1.1   itohy 		DPRINTF(("short"));					    \
    468   1.1   itohy 	} else {							    \
    469   1.1   itohy 		struct relinf_l *r = (struct relinf_l *)(reltbl + relsize); \
    470   1.1   itohy 		put_uint16(&r->lrelmag, HUXLRELMAGIC);			    \
    471   1.1   itohy 		put_uint32((be_uint32_t *)r->locoff_l, (adr) - reladdr);    \
    472   1.1   itohy 		relsize += sizeof(struct relinf_l);			    \
    473   1.1   itohy 		DPRINTF(("long "));					    \
    474   1.1   itohy 	}								    \
    475   1.1   itohy 	DPRINTF((" reloc 0x%06x", (adr)));				    \
    476   1.1   itohy 	reladdr = (adr);
    477   1.1   itohy 
    478   1.1   itohy #define ERR1	{ if (ferror(fpa1)) perror(fn1);			\
    479   1.1   itohy 		  else fprintf(stderr, "%s: unexpected EOF\n", fn1);	\
    480   1.1   itohy 		  goto out; }
    481   1.1   itohy #define ERR2	{ if (ferror(fpa2)) perror(fn2);			\
    482   1.1   itohy 		  else fprintf(stderr, "%s: unexpected EOF\n", fn2);	\
    483   1.1   itohy 		  goto out; }
    484   1.1   itohy #define ERRC	{ fprintf(stderr, "files %s and %s are inconsistent\n",	\
    485   1.1   itohy 				  fn1, fn2);				\
    486   1.1   itohy 		  goto out; }
    487   1.1   itohy 
    488   1.1   itohy /*
    489   1.4   itohy  * read input executables and output .x body
    490   1.1   itohy  * and create relocation table
    491   1.1   itohy  */
    492   1.1   itohy #define CREATE_RELOCATION(segsize)	\
    493   1.1   itohy 	while (segsize > 0 || nbuf) {					\
    494   1.1   itohy 		if (nbuf == 0) {					\
    495   1.1   itohy 			if (fread(&b1.half[0], SIZE_16, 1, fpa1) != 1)	\
    496   1.1   itohy 				ERR1					\
    497   1.1   itohy 			if (fread(&b2.half[0], SIZE_16, 1, fpa2) != 1)	\
    498   1.1   itohy 				ERR2					\
    499   1.1   itohy 			nbuf = 1;					\
    500   1.1   itohy 			segsize -= SIZE_16;				\
    501   1.1   itohy 		} else if (nbuf == 1) {					\
    502   1.1   itohy 			if (segsize == 0) {				\
    503   1.1   itohy 				if (b1.half[0].hostval != b2.half[0].hostval) \
    504   1.1   itohy 					ERRC				\
    505   1.1   itohy 				fwrite(&b1.half[0], SIZE_16, 1, fpx);	\
    506   1.1   itohy 				nbuf = 0;				\
    507   1.1   itohy 				addr += SIZE_16;			\
    508   1.1   itohy 			} else {					\
    509   1.1   itohy 				if (fread(&b1.half[1], SIZE_16, 1, fpa1) != 1)\
    510   1.1   itohy 					ERR1				\
    511   1.1   itohy 				if (fread(&b2.half[1], SIZE_16, 1, fpa2) != 1)\
    512   1.1   itohy 					ERR2				\
    513   1.1   itohy 				nbuf = 2;				\
    514   1.1   itohy 				segsize -= SIZE_16;			\
    515   1.1   itohy 			}						\
    516   1.1   itohy 		} else /* if (nbuf == 2) */ {				\
    517   1.1   itohy 			if (b1.hostval != b2.hostval &&			\
    518   1.1   itohy 			    get_uint32(&b1) - loadadr1			\
    519   1.1   itohy 					== get_uint32(&b2) - loadadr2) {\
    520   1.1   itohy 				/* do relocation */			\
    521   1.1   itohy 				ADD_RELTBL(addr)			\
    522   1.1   itohy 									\
    523   1.1   itohy 				put_uint32(&b1, get_uint32(&b1) - loadadr1);  \
    524   1.1   itohy 				DPRINTF((" v 0x%08x\t", get_uint32(&b1)));    \
    525   1.1   itohy 				fwrite(&b1, SIZE_32, 1, fpx);		\
    526   1.1   itohy 				nbuf = 0;				\
    527   1.1   itohy 				addr += SIZE_32;			\
    528   1.1   itohy 			} else if (b1.half[0].hostval == b2.half[0].hostval) {\
    529   1.1   itohy 				fwrite(&b1.half[0], SIZE_16, 1, fpx);	\
    530   1.1   itohy 				addr += SIZE_16;			\
    531   1.1   itohy 				b1.half[0] = b1.half[1];		\
    532   1.1   itohy 				b2.half[0] = b2.half[1];		\
    533   1.1   itohy 				nbuf = 1;				\
    534   1.1   itohy 			} else						\
    535   1.1   itohy 				ERRC					\
    536   1.1   itohy 		}							\
    537   1.1   itohy 	}
    538   1.1   itohy 
    539   1.1   itohy int
    540   1.8     dsl aout2hux(const char *fn1, const char *fn2, u_int32_t loadadr1, u_int32_t loadadr2, const char *fnx)
    541   1.1   itohy {
    542   1.1   itohy 	int status = 1;			/* the default is "failed" */
    543   1.1   itohy 	FILE *fpa1 = NULL, *fpa2 = NULL;
    544   1.4   itohy 	struct exec_info inf1, inf2;
    545   1.1   itohy 	FILE *fpx = NULL;
    546   1.1   itohy 	struct huxhdr xhdr;
    547   1.4   itohy 	u_int32_t textsize, datasize, paddingsize, execoff;
    548   1.1   itohy 
    549   1.1   itohy 	/* for relocation */
    550   1.1   itohy 	be_uint32_t b1, b2;
    551   1.1   itohy 	int nbuf;
    552   1.1   itohy 	u_int32_t addr;
    553   1.1   itohy 
    554   1.1   itohy 	/* for relocation table */
    555   1.1   itohy 	size_t relsize, relallocsize;
    556   1.1   itohy 	u_int32_t reladdr;
    557   1.1   itohy 	char *reltbl = NULL;
    558   1.1   itohy 
    559   1.1   itohy 
    560   1.1   itohy 	/*
    561   1.1   itohy 	 * check load addresses
    562   1.1   itohy 	 */
    563   1.1   itohy 	if (loadadr1 == loadadr2) {
    564   1.1   itohy 		fprintf(stderr, "two load addresses must be different\n");
    565   1.1   itohy 		return 1;
    566   1.1   itohy 	}
    567   1.1   itohy 
    568   1.1   itohy 	/*
    569   1.4   itohy 	 * open input executables and check them
    570   1.1   itohy 	 */
    571   1.4   itohy 	if (!(fpa1 = open_exec(fn1, &inf1)) || !(fpa2 = open_exec(fn2, &inf2)))
    572   1.1   itohy 		goto out;
    573   1.1   itohy 
    574   1.1   itohy 	/*
    575   1.1   itohy 	 * check for consistency
    576   1.1   itohy 	 */
    577   1.4   itohy 	if (check_2_exec_inf(&inf1, &inf2)) {
    578   1.1   itohy 		fprintf(stderr, "files %s and %s are incompatible\n",
    579   1.1   itohy 				fn1, fn2);
    580   1.1   itohy 		goto out;
    581   1.1   itohy 	}
    582   1.1   itohy 	/* check entry address */
    583   1.4   itohy 	if (inf1.entry_addr - loadadr1 != inf2.entry_addr - loadadr2) {
    584   1.1   itohy 		fprintf(stderr, "address of %s or %s may be incorrect\n",
    585   1.1   itohy 				fn1, fn2);
    586   1.1   itohy 		goto out;
    587   1.1   itohy 	}
    588   1.1   itohy 
    589   1.1   itohy 	/*
    590   1.4   itohy 	 * get information of the executables
    591   1.1   itohy 	 */
    592   1.4   itohy 	textsize = inf1.text_size;
    593   1.4   itohy 	paddingsize = inf1.text_pad;
    594   1.4   itohy 	datasize = inf1.data_size;
    595   1.4   itohy 	execoff = inf1.entry_addr - loadadr1;
    596   1.4   itohy 
    597   1.4   itohy 	DPRINTF(("text: %u, data: %u, pad: %u, bss: %u, exec: %u\n",
    598   1.4   itohy 		textsize, datasize, paddingsize, inf1.bss_size, execoff));
    599   1.1   itohy 
    600   1.1   itohy 	if (textsize & 1) {
    601   1.1   itohy 		fprintf(stderr, "text size is not even\n");
    602   1.1   itohy 		goto out;
    603   1.1   itohy 	}
    604   1.1   itohy 	if (datasize & 1) {
    605   1.1   itohy 		fprintf(stderr, "data size is not even\n");
    606   1.1   itohy 		goto out;
    607   1.1   itohy 	}
    608   1.1   itohy 	if (execoff >= textsize &&
    609   1.1   itohy 	    (execoff < textsize + paddingsize ||
    610   1.1   itohy 	     execoff >= textsize + paddingsize + datasize)) {
    611   1.1   itohy 		fprintf(stderr, "exec addr is not in text or data segment\n");
    612   1.1   itohy 		goto out;
    613   1.1   itohy 	}
    614   1.1   itohy 
    615   1.1   itohy 	/*
    616   1.1   itohy 	 * prepare for .x header
    617   1.1   itohy 	 */
    618  1.10  cegger 	memset((void *) &xhdr, 0, sizeof xhdr);
    619   1.1   itohy 	put_uint16(&xhdr.x_magic, HUXMAGIC);
    620   1.1   itohy 	put_uint32(&xhdr.x_entry, execoff);
    621   1.1   itohy 	put_uint32(&xhdr.x_text, textsize + paddingsize);
    622   1.4   itohy 	put_uint32(&xhdr.x_data, inf1.data_size);
    623   1.4   itohy 	put_uint32(&xhdr.x_bss, inf1.bss_size);
    624   1.1   itohy 
    625   1.1   itohy 	/*
    626   1.1   itohy 	 * create output file
    627   1.1   itohy 	 */
    628   1.1   itohy 	if (!(fpx = fopen(fnx, "w")) ||
    629   1.4   itohy 	    fseek(fpx, (foff_t) sizeof xhdr, SEEK_SET)) { /* skip header */
    630   1.1   itohy 		perror(fnx);
    631   1.1   itohy 		goto out;
    632   1.1   itohy 	}
    633   1.1   itohy 
    634   1.1   itohy 	addr = 0;
    635   1.1   itohy 	nbuf = 0;
    636   1.1   itohy 
    637   1.1   itohy 	relsize = relallocsize = 0;
    638   1.1   itohy 	reladdr = 0;
    639   1.1   itohy 
    640   1.1   itohy 	/*
    641   1.1   itohy 	 * text segment
    642   1.1   itohy 	 */
    643   1.4   itohy 	if (fseek(fpa1, inf1.text_off, SEEK_SET)) {
    644   1.4   itohy 		perror(fn1);
    645   1.4   itohy 		goto out;
    646   1.4   itohy 	}
    647   1.4   itohy 	if (fseek(fpa2, inf2.text_off, SEEK_SET)) {
    648   1.4   itohy 		perror(fn2);
    649   1.4   itohy 		goto out;
    650   1.4   itohy 	}
    651   1.1   itohy 	CREATE_RELOCATION(textsize)
    652   1.1   itohy 
    653   1.1   itohy 	/*
    654   1.1   itohy 	 * page boundary
    655   1.1   itohy 	 */
    656   1.1   itohy 	addr += paddingsize;
    657   1.1   itohy 	while (paddingsize--)
    658   1.1   itohy 		putc('\0', fpx);
    659   1.1   itohy 
    660   1.1   itohy 	/*
    661   1.1   itohy 	 * data segment
    662   1.1   itohy 	 */
    663   1.4   itohy 	if (fseek(fpa1, inf1.data_off, SEEK_SET)) {
    664   1.4   itohy 		perror(fn1);
    665   1.4   itohy 		goto out;
    666   1.4   itohy 	}
    667   1.4   itohy 	if (fseek(fpa2, inf2.data_off, SEEK_SET)) {
    668   1.4   itohy 		perror(fn2);
    669   1.4   itohy 		goto out;
    670   1.4   itohy 	}
    671   1.1   itohy 	CREATE_RELOCATION(datasize)
    672   1.1   itohy 
    673   1.1   itohy 	/*
    674   1.1   itohy 	 * error check of the above
    675   1.1   itohy 	 */
    676   1.1   itohy 	if (ferror(fpx)) {
    677   1.1   itohy 		fprintf(stderr, "%s: write failure\n", fnx);
    678   1.1   itohy 		goto out;
    679   1.1   itohy 	}
    680   1.1   itohy 
    681   1.1   itohy 	/*
    682   1.1   itohy 	 * write relocation table
    683   1.1   itohy 	 */
    684   1.1   itohy 	if (relsize > 0) {
    685   1.1   itohy 		DPRINTF(("\n"));
    686   1.1   itohy 		if (fwrite(reltbl, 1, relsize, fpx) != relsize) {
    687   1.1   itohy 			perror(fnx);
    688   1.1   itohy 			goto out;
    689   1.1   itohy 		}
    690   1.1   itohy 	}
    691   1.1   itohy 
    692   1.1   itohy 	/*
    693   1.1   itohy 	 * write .x header at the top of the output file
    694   1.1   itohy 	 */
    695   1.1   itohy 	put_uint32(&xhdr.x_rsize, relsize);
    696   1.4   itohy 	if (fseek(fpx, (foff_t) 0, SEEK_SET) ||
    697   1.1   itohy 	    fwrite(&xhdr, sizeof xhdr, 1, fpx) != 1) {
    698   1.1   itohy 		perror(fnx);
    699   1.1   itohy 		goto out;
    700   1.1   itohy 	}
    701   1.1   itohy 
    702   1.1   itohy 	status = 0;	/* all OK */
    703   1.1   itohy 
    704   1.1   itohy out:	/*
    705   1.1   itohy 	 * cleanup
    706   1.1   itohy 	 */
    707   1.1   itohy 	if (fpa1)
    708   1.1   itohy 		fclose(fpa1);
    709   1.1   itohy 	if (fpa2)
    710   1.1   itohy 		fclose(fpa2);
    711   1.1   itohy 	if (fpx) {
    712   1.1   itohy 		if (fclose(fpx) && status == 0) {
    713   1.1   itohy 			/* Alas, final flush failed! */
    714   1.1   itohy 			perror(fnx);
    715   1.1   itohy 			status = 1;
    716   1.1   itohy 		}
    717   1.1   itohy 		if (status)
    718   1.1   itohy 			remove(fnx);
    719   1.1   itohy 	}
    720   1.1   itohy 	if (reltbl)
    721   1.1   itohy 		free(reltbl);
    722   1.1   itohy 
    723   1.1   itohy 	return status;
    724   1.1   itohy }
    725   1.1   itohy 
    726   1.1   itohy #ifndef NO_BIST
    727   1.1   itohy void bist PROTO((void));
    728   1.1   itohy 
    729   1.1   itohy /*
    730   1.1   itohy  * built-in self test
    731   1.1   itohy  */
    732   1.1   itohy void
    733   1.9  cegger bist(void)
    734   1.1   itohy {
    735   1.1   itohy 	be_uint16_t be16;
    736   1.1   itohy 	be_uint32_t be32;
    737   1.1   itohy 	be_uint32_t be32x2[2];
    738   1.1   itohy 
    739   1.1   itohy 	be16.val[0] = 0x12; be16.val[1] = 0x34;
    740   1.1   itohy 	be32.val[0] = 0xfe; be32.val[1] = 0xdc;
    741   1.1   itohy 	be32.val[2] = 0xba; be32.val[3] = 0x98;
    742   1.1   itohy 
    743   1.1   itohy 	put_uint16(&be32x2[0].half[1], 0x4567);
    744   1.1   itohy 	put_uint32(&be32x2[1], 0xa9876543);
    745   1.1   itohy 
    746   1.1   itohy 	if (sizeof(u_int8_t) != 1 || sizeof(u_int16_t) != 2 ||
    747   1.1   itohy 	    sizeof(u_int32_t) != 4 ||
    748   1.1   itohy 	    SIZE_16 != 2 || SIZE_32 != 4 || sizeof be32x2 != 8 ||
    749   1.1   itohy 	    sizeof(struct relinf_s) != 2 || sizeof(struct relinf_l) != 6 ||
    750   1.4   itohy 	    SIZE_ELF68K_HDR != 52 || SIZE_ELF68K_SHDR != 40 ||
    751   1.4   itohy 	    SIZE_ELF68K_PHDR != 32 ||
    752   1.1   itohy 	    get_uint16(&be16) != 0x1234 || get_uint32(&be32) != 0xfedcba98 ||
    753   1.1   itohy 	    get_uint16(&be32x2[0].half[1]) != 0x4567 ||
    754   1.1   itohy 	    get_uint32(&be32x2[1]) != 0xa9876543) {
    755   1.1   itohy 		fprintf(stderr, "BIST failed\n");
    756   1.1   itohy 		exit(1);
    757   1.1   itohy 	}
    758   1.1   itohy }
    759   1.1   itohy #endif
    760   1.1   itohy 
    761   1.1   itohy int
    762   1.7     dsl gethex(u_int32_t *pval, const char *str)
    763   1.1   itohy {
    764   1.1   itohy 	const unsigned char *p = (const unsigned char *) str;
    765   1.1   itohy 	u_int32_t val;
    766   1.1   itohy 	int over;
    767   1.1   itohy 
    768   1.1   itohy 	/* skip leading "0x" if exists */
    769   1.1   itohy 	if (p[0] == '0' && (p[1] == 'x' || p[1] == 'X'))
    770   1.1   itohy 		p += 2;
    771   1.1   itohy 
    772   1.1   itohy 	if (!*p)
    773   1.1   itohy 		goto bad;
    774   1.1   itohy 
    775   1.1   itohy 	for (val = 0, over = 0; *p; p++) {
    776   1.1   itohy 		int digit;
    777   1.1   itohy 
    778   1.1   itohy 		switch (*p) {
    779   1.1   itohy 		case '0': case '1': case '2': case '3': case '4':
    780   1.1   itohy 		case '5': case '6': case '7': case '8': case '9':
    781   1.1   itohy 			digit = *p - '0';
    782   1.1   itohy 			break;
    783   1.1   itohy 		case 'a': case 'A':	digit = 10; break;
    784   1.1   itohy 		case 'b': case 'B':	digit = 11; break;
    785   1.1   itohy 		case 'c': case 'C':	digit = 12; break;
    786   1.1   itohy 		case 'd': case 'D':	digit = 13; break;
    787   1.1   itohy 		case 'e': case 'E':	digit = 14; break;
    788   1.1   itohy 		case 'f': case 'F':	digit = 15; break;
    789   1.1   itohy 		default:
    790   1.1   itohy 			goto bad;
    791   1.1   itohy 		}
    792   1.4   itohy 		if (val >= 0x10000000)
    793   1.1   itohy 			over = 1;
    794   1.1   itohy 		val = (val << 4) | digit;
    795   1.1   itohy 	}
    796   1.1   itohy 
    797   1.1   itohy 	if (over)
    798   1.1   itohy 		fprintf(stderr, "warning: %s: constant overflow\n", str);
    799   1.1   itohy 
    800   1.1   itohy 	*pval = val;
    801   1.1   itohy 
    802   1.1   itohy 	DPRINTF(("gethex: %s -> 0x%x\n", str, val));
    803   1.1   itohy 
    804   1.1   itohy 	return 0;
    805   1.1   itohy 
    806   1.1   itohy bad:
    807   1.1   itohy 	fprintf(stderr, "%s: not a hexadecimal number\n", str);
    808   1.1   itohy 	return 1;
    809   1.1   itohy }
    810   1.1   itohy 
    811   1.1   itohy void
    812   1.7     dsl usage(const char *name)
    813   1.1   itohy {
    814   1.1   itohy 
    815   1.1   itohy 	fprintf(stderr, "\
    816   1.1   itohy usage: %s [ -o output.x ] a.out1 loadaddr1 a.out2 loadaddr2\n\n\
    817   1.4   itohy The input files must be static OMAGIC/NMAGIC m68k a.out executables\n\
    818   1.4   itohy or m68k ELF executables.\n\
    819   1.4   itohy Two executables must have different loading addresses.\n\
    820   1.1   itohy Each of the load address must be a hexadecimal number.\n\
    821   1.1   itohy The default output filename is \"%s\".\n" ,name, DEFAULT_OUTPUT_FILE);
    822   1.1   itohy 
    823   1.1   itohy 	exit(1);
    824   1.1   itohy }
    825   1.1   itohy 
    826   1.1   itohy int
    827   1.8     dsl main(int argc, char *argv[])
    828   1.1   itohy {
    829   1.1   itohy 	const char *outfile = DEFAULT_OUTPUT_FILE;
    830   1.1   itohy 	u_int32_t adr1, adr2;
    831   1.1   itohy 
    832   1.1   itohy #ifndef NO_BIST
    833   1.1   itohy 	bist();
    834   1.1   itohy #endif
    835   1.1   itohy 
    836   1.1   itohy 	if (argc > 2 && argv[1][0] == '-' && argv[1][1] == 'o' && !argv[1][2]) {
    837   1.1   itohy 		outfile = argv[2];
    838   1.1   itohy 		argv += 2;
    839   1.1   itohy 		argc -= 2;
    840   1.1   itohy 	}
    841   1.1   itohy 
    842   1.1   itohy 	if (argc != 5)
    843   1.1   itohy 		usage(argv[0]);
    844   1.1   itohy 
    845   1.1   itohy 	if (gethex(&adr1, argv[2]) || gethex(&adr2, argv[4]))
    846   1.1   itohy 		usage(argv[0]);
    847   1.1   itohy 
    848   1.1   itohy 	return aout2hux(argv[1], argv[3], adr1, adr2, outfile);
    849   1.1   itohy }
    850