Module Name:    src
Committed By:   christos
Date:           Sat May 18 21:16:12 UTC 2019

Modified Files:
        src/usr.bin/elf2aout: elf2aout.1 elf2aout.c

Log Message:
- add flag to produce OMAGIC
- factor out complicated inline code into simpler functions
- add options parsing


To generate a diff of this commit:
cvs rdiff -u -r1.10 -r1.11 src/usr.bin/elf2aout/elf2aout.1
cvs rdiff -u -r1.21 -r1.22 src/usr.bin/elf2aout/elf2aout.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/usr.bin/elf2aout/elf2aout.1
diff -u src/usr.bin/elf2aout/elf2aout.1:1.10 src/usr.bin/elf2aout/elf2aout.1:1.11
--- src/usr.bin/elf2aout/elf2aout.1:1.10	Mon Mar  5 05:57:18 2012
+++ src/usr.bin/elf2aout/elf2aout.1	Sat May 18 17:16:12 2019
@@ -1,4 +1,4 @@
-.\"	$NetBSD: elf2aout.1,v 1.10 2012/03/05 10:57:18 njoly Exp $
+.\"	$NetBSD: elf2aout.1,v 1.11 2019/05/18 21:16:12 christos Exp $
 .\"
 .\" Copyright 1996 The Board of Trustees of The Leland Stanford
 .\" Junior University. All Rights Reserved.
@@ -19,7 +19,8 @@
 .Nm elf2aout
 .Nd convert a NetBSD ELF-format executable to NetBSD a.out format
 .Sh SYNOPSIS
-.Nm elf2aout
+.Nm
+.Op Fl \&Os
 .Ar elf-file
 .Ar aout-file
 .Sh DESCRIPTION
@@ -35,6 +36,18 @@ to a.out format, for compatibility with 
 utilities like
 .Xr kvm 3 ,
 which currently expect an a.out format kernel.
+.Pp
+The following options are available:
+.Bl -tag -width flag
+.It Fl O
+Produce
+.Dv OMAGIC
+instead of
+.Dv ZMAGIC
+binaries which is the default.
+.It Fl s
+Preserve the symbol table.
+.El
 .\" .Sh DIAGNOSTICS
 .Sh SEE ALSO
 .Xr elf2ecoff 1 ,

Index: src/usr.bin/elf2aout/elf2aout.c
diff -u src/usr.bin/elf2aout/elf2aout.c:1.21 src/usr.bin/elf2aout/elf2aout.c:1.22
--- src/usr.bin/elf2aout/elf2aout.c:1.21	Sat Apr 27 11:43:09 2019
+++ src/usr.bin/elf2aout/elf2aout.c	Sat May 18 17:16:12 2019
@@ -1,4 +1,4 @@
-/*	$NetBSD: elf2aout.c,v 1.21 2019/04/27 15:43:09 skrll Exp $	*/
+/*	$NetBSD: elf2aout.c,v 1.22 2019/05/18 21:16:12 christos Exp $	*/
 
 /*
  * Copyright (c) 1995
@@ -63,17 +63,131 @@ struct sect {
 	uint32_t len;
 };
 
-void	combine(struct sect *, struct sect *, int);
-int	phcmp(const void *, const void *);
-void   *saveRead(int file, off_t offset, size_t len, const char *name);
-void	copy(int, int, off_t, off_t);
-void	translate_syms(int, int, off_t, off_t, off_t, off_t);
+static void	combine(struct sect *, struct sect *, int);
+static int	phcmp(const void *, const void *);
+static void   *saveRead(int file, off_t offset, size_t len, const char *name);
+static void	copy(int, int, off_t, off_t);
+static void	translate_syms(int, int, off_t, off_t, off_t, off_t);
 
 #if TARGET_BYTE_ORDER != BYTE_ORDER
-void	bswap32_region(int32_t* , int);
+static void	bswap32_region(int32_t* , int);
 #endif
 
-int    *symTypeTable;
+static int    *symTypeTable;
+static int     debug;
+
+static __dead void
+usage(void)
+{
+	fprintf(stderr, "Usage: %s [-sO] <elf executable> <a.out executable>\n",
+	    getprogname());
+	exit(EXIT_FAILURE);
+}
+
+static const struct {
+	const char *n;
+	int v;
+} nv[] = {
+	{ ".text", N_TEXT },
+	{ ".rodata", N_TEXT },
+	{ ".data", N_DATA },
+	{ ".sdata", N_DATA },
+	{ ".lit4", N_DATA },
+	{ ".lit8", N_DATA },
+	{ ".bss", N_BSS },
+	{ ".sbss", N_BSS },
+};
+
+static int
+get_symtab_type(const char *name)
+{
+	size_t i;
+	for (i = 0; i < __arraycount(nv); i++) {
+		if (strcmp(name, nv[i].n) == 0)
+			return nv[i].v;
+	}
+	if (debug)
+		warnx("section `%s' is not handled\n", name);
+	return 0;
+}
+
+static uint32_t
+get_mid(const Elf32_Ehdr *ex)
+{
+	switch (ex->e_machine) {
+#ifdef notyet
+	case EM_AARCH64:
+		return MID_AARCH64;
+	case EM_ALPHA:
+		return MID_ALPHA;
+#endif
+	case EM_ARM:
+		return MID_ARM6;
+#ifdef notyet
+	case EM_PARISC:
+		return MID_HPPA;
+#endif
+	case EM_386:
+		return MID_I386;
+	case EM_68K:
+		return MID_M68K;
+	case EM_OR1K:
+		return MID_OR1K;
+	case EM_MIPS:
+		if (ex->e_ident[EI_DATA] == ELFDATA2LSB)
+			return MID_PMAX;
+		else
+			return MID_MIPS;
+	case EM_PPC:
+		return MID_POWERPC;
+#ifdef notyet
+	case EM_PPC64:
+		return MID_POWERPC64;
+		break;
+#endif
+	case EM_RISCV:
+		return MID_RISCV;
+	case EM_SH:
+		return MID_SH3;
+	case EM_SPARC:
+	case EM_SPARC32PLUS:
+	case EM_SPARCV9:
+		if (ex->e_ident[EI_CLASS] == ELFCLASS32)
+			return MID_SPARC;
+#ifdef notyet
+		return MID_SPARC64;
+	case EM_X86_64:
+		return MID_X86_64;
+#else
+		break;
+#endif
+	case EM_VAX:
+		return MID_VAX;
+	case EM_NONE:
+		return MID_ZERO;
+	default:
+		break;
+	}
+	if (debug)
+		warnx("Unsupported machine `%d'", ex->e_machine);
+	return MID_ZERO;
+}
+
+static unsigned char
+get_type(Elf32_Half shndx)
+{
+	switch (shndx) {
+	case SHN_UNDEF:
+		return N_UNDF;
+	case SHN_ABS:
+		return N_ABS;
+	case SHN_COMMON:
+	case SHN_MIPS_ACOMMON:
+		return N_COMM;
+	default:
+		return (unsigned char)symTypeTable[shndx];
+	}
+}
 
 int
 main(int argc, char **argv)
@@ -88,28 +202,42 @@ main(int argc, char **argv)
 	int     infile, outfile;
 	uint32_t cur_vma = UINT32_MAX;
 	uint32_t mid;
-	int     symflag = 0;
+	int symflag = 0, c;
+	unsigned long magic = ZMAGIC;
 
 	strtabix = symtabix = 0;
 	text.len = data.len = bss.len = 0;
 	text.vaddr = data.vaddr = bss.vaddr = 0;
 
-	/* Check args... */
-	if (argc < 3 || argc > 4) {
-usage:
-		fprintf(stderr,
-		    "Usage: %s <elf executable> <a.out executable> [-s]\n",
-		    getprogname());
-		exit(EXIT_FAILURE);
-	}
-	if (argc == 4) {
-		if (strcmp(argv[3], "-s"))
-			goto usage;
-		symflag = 1;
+	while ((c = getopt(argc, argv, "dOs")) != -1) {
+		switch (c) {
+		case 'd':
+			debug++;
+			break;
+		case 's':
+			symflag = 1;
+			break;
+		case 'O':
+			magic = OMAGIC;
+			break;
+		case '?':
+		default:
+		usage:
+			usage();
+		}
 	}
+
+	argc -= optind;
+	argv += optind;
+
+	/* Check args... */
+	if (argc != 2)
+		goto usage;
+
+
 	/* Try the input file... */
-	if ((infile = open(argv[1], O_RDONLY)) < 0)
-		err(EXIT_FAILURE, "Can't open `%s' for read", argv[1]);
+	if ((infile = open(argv[0], O_RDONLY)) < 0)
+		err(EXIT_FAILURE, "Can't open `%s' for read", argv[0]);
 
 	/* Read the header, which is at the beginning of the file... */
 	i = read(infile, &ex, sizeof ex);
@@ -134,6 +262,10 @@ usage:
 	ex.e_shnum	= bswap16(ex.e_shnum);
 	ex.e_shstrndx	= bswap16(ex.e_shstrndx);
 #endif
+	// Not yet
+	if (ex.e_ident[EI_CLASS] == ELFCLASS64)
+		errx(EXIT_FAILURE, "Only 32 bit is supported");
+
 	/* Read the program headers... */
 	ph = saveRead(infile, ex.e_phoff,
 	    (size_t)ex.e_phnum * sizeof(Elf32_Phdr), "ph");
@@ -163,19 +295,10 @@ usage:
 		char   *name = shstrtab + sh[i].sh_name;
 		if (!strcmp(name, ".symtab"))
 			symtabix = i;
+		else if (!strcmp(name, ".strtab"))
+			strtabix = i;
 		else
-			if (!strcmp(name, ".strtab"))
-				strtabix = i;
-			else
-				if (!strcmp(name, ".text") || !strcmp(name, ".rodata"))
-					symTypeTable[i] = N_TEXT;
-				else
-					if (!strcmp(name, ".data") || !strcmp(name, ".sdata") ||
-					    !strcmp(name, ".lit4") || !strcmp(name, ".lit8"))
-						symTypeTable[i] = N_DATA;
-					else
-						if (!strcmp(name, ".bss") || !strcmp(name, ".sbss"))
-							symTypeTable[i] = N_BSS;
+			symTypeTable[i] = get_symtab_type(name);
 	}
 
 	/* Figure out if we can cram the program header into an a.out
@@ -192,11 +315,14 @@ usage:
 		    ph[i].p_type == PT_PHDR || ph[i].p_type == PT_MIPS_REGINFO)
 			continue;
 		/* Section types we can't handle... */
-		else
-			if (ph[i].p_type != PT_LOAD)
-				errx(EXIT_FAILURE, "Program header %zd "
-				    "type %d can't be converted.",
-				    i, ph[i].p_type);
+		if (ph[i].p_type == PT_TLS) {
+			if (debug)
+				warnx("Can't handle TLS section");
+			continue;
+		}
+		if (ph[i].p_type != PT_LOAD)
+			errx(EXIT_FAILURE, "Program header %zd "
+			    "type %d can't be converted.", i, ph[i].p_type);
 		/* Writable (data) segment? */
 		if (ph[i].p_flags & PF_W) {
 			struct sect ndata, nbss;
@@ -243,45 +369,16 @@ usage:
 		text.len = data.vaddr - text.vaddr;
 
 	/* We now have enough information to cons up an a.out header... */
-	switch (ex.e_machine) {
-	case EM_SPARC:
-		mid = MID_SPARC;
-		break;
-	case EM_386:
-		mid = MID_PC386;
-		break;
-	case EM_68K:
-		mid = MID_M68K;
-		break;
-	case EM_MIPS:
-		if (ex.e_ident[EI_DATA] == ELFDATA2LSB)
-			mid = MID_PMAX;
-		else
-			mid = MID_MIPS;
-		break;
-	case EM_PPC:
-		mid = MID_POWERPC;
-		break;
-	case EM_ARM:
-		mid = MID_ARM6;
-		break;
-	case EM_VAX:
-		mid = MID_VAX;
-		break;
-	case EM_NONE:
-	default:
-		mid = MID_ZERO;
-	}
+	mid = get_mid(&ex);
 	aex.a_midmag = (u_long)htonl(((u_long)symflag << 26)
-	    | ((u_long)mid << 16) | ZMAGIC);
+	    | ((u_long)mid << 16) | magic);
 
 	aex.a_text = text.len;
 	aex.a_data = data.len;
 	aex.a_bss = bss.len;
 	aex.a_entry = ex.e_entry;
 	aex.a_syms = (sizeof(struct nlist) *
-	    (symtabix != -1
-		? sh[symtabix].sh_size / sizeof(Elf32_Sym) : 0));
+	    (symtabix != -1 ? sh[symtabix].sh_size / sizeof(Elf32_Sym) : 0));
 	aex.a_trsize = 0;
 	aex.a_drsize = 0;
 #if TARGET_BYTE_ORDER != BYTE_ORDER
@@ -295,16 +392,16 @@ usage:
 #endif
 
 	/* Make the output file... */
-	if ((outfile = open(argv[2], O_WRONLY | O_CREAT, 0777)) < 0)
-		err(EXIT_FAILURE, "Unable to create `%s'", argv[2]);
+	if ((outfile = open(argv[1], O_WRONLY | O_CREAT, 0777)) < 0)
+		err(EXIT_FAILURE, "Unable to create `%s'", argv[1]);
 	/* Truncate file... */
 	if (ftruncate(outfile, 0)) {
-		warn("ftruncate %s", argv[2]);
+		warn("ftruncate %s", argv[1]);
 	}
 	/* Write the header... */
 	i = write(outfile, &aex, sizeof aex);
 	if (i != sizeof aex)
-		err(EXIT_FAILURE, "Can't write `%s'", argv[2]);
+		err(EXIT_FAILURE, "Can't write `%s'", argv[1]);
 	/* Copy the loadable sections.   Zero-fill any gaps less than 64k;
 	 * complain about any zero-filling, and die if we're asked to
 	 * zero-fill more than 64k. */
@@ -318,9 +415,8 @@ usage:
 				if (gap > 65536)
 					errx(EXIT_FAILURE,
 			"Intersegment gap (%u bytes) too large", gap);
-#ifdef DEBUG
-				warnx("%u byte intersegment gap", gap);
-#endif
+				if (debug)
+					warnx("%u byte intersegment gap", gap);
 				memset(obuf, 0, sizeof obuf);
 				while (gap) {
 					ssize_t count = write(outfile, obuf,
@@ -445,17 +541,7 @@ translate_syms(int out, int in, off_t sy
 			if (type == STT_FILE)
 				outbuf[i].n_type = N_FN;
 			else
-				if (inbuf[i].st_shndx == SHN_UNDEF)
-					outbuf[i].n_type = N_UNDF;
-				else
-					if (inbuf[i].st_shndx == SHN_ABS)
-						outbuf[i].n_type = N_ABS;
-					else
-						if (inbuf[i].st_shndx == SHN_COMMON ||
-						    inbuf[i].st_shndx == SHN_MIPS_ACOMMON)
-							outbuf[i].n_type = N_COMM;
-						else
-							outbuf[i].n_type = (unsigned char)symTypeTable[inbuf[i].st_shndx];
+				outbuf[i].n_type = get_type(inbuf[i].st_shndx);
 			if (binding == STB_GLOBAL)
 				outbuf[i].n_type |= N_EXT;
 			/* Symbol values in executables should be compatible. */
@@ -486,7 +572,7 @@ translate_syms(int out, int in, off_t sy
 	free(oldstrings);
 }
 
-void
+static void
 copy(int out, int in, off_t offset, off_t size)
 {
 	char    ibuf[4096];
@@ -514,9 +600,10 @@ copy(int out, int in, off_t offset, off_
 			err(EXIT_FAILURE, "%s: write failed", __func__);
 	}
 }
+
 /* Combine two segments, which must be contiguous.   If pad is true, it's
    okay for there to be padding between. */
-void
+static void
 combine(struct sect *base, struct sect *new, int pad)
 {
 
@@ -535,7 +622,7 @@ combine(struct sect *base, struct sect *
 		}
 }
 
-int
+static int
 phcmp(const void *vh1, const void *vh2)
 {
 	const Elf32_Phdr *h1, *h2;
@@ -552,7 +639,7 @@ phcmp(const void *vh1, const void *vh2)
 			return 0;
 }
 
-void *
+static void *
 saveRead(int file, off_t offset, size_t len, const char *name)
 {
 	char   *tmp;
@@ -577,7 +664,7 @@ saveRead(int file, off_t offset, size_t 
 
 #if TARGET_BYTE_ORDER != BYTE_ORDER
 /* swap a 32bit region */
-void
+static void
 bswap32_region(int32_t* p, int len)
 {
 	size_t i;

Reply via email to