Module Name:    src
Committed By:   christos
Date:           Sun Mar  6 16:13:22 UTC 2016

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

Log Message:
PR/50897: David Binderman: fix memory leaks. While here, modernize error
handling, and types.


To generate a diff of this commit:
cvs rdiff -u -r1.10 -r1.11 src/usr.bin/elf2aout/Makefile
cvs rdiff -u -r1.16 -r1.17 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/Makefile
diff -u src/usr.bin/elf2aout/Makefile:1.10 src/usr.bin/elf2aout/Makefile:1.11
--- src/usr.bin/elf2aout/Makefile:1.10	Tue Mar 18 14:20:44 2014
+++ src/usr.bin/elf2aout/Makefile	Sun Mar  6 11:13:21 2016
@@ -1,7 +1,8 @@
-#	$NetBSD: Makefile,v 1.10 2014/03/18 18:20:44 riastradh Exp $
+#	$NetBSD: Makefile,v 1.11 2016/03/06 16:13:21 christos Exp $
 #	from: @(#)Makefile	5.4 (Berkeley) 5/11/90
 
 .include <bsd.own.mk>	# for MACHINE_CPU
+WARNS=6
 
 # Build ELF to {ecoff, aout} tools on m68k/powerpc, for kernels with old amigappc bootblocks.
 .if (${MACHINE_CPU} == "m68k" || \

Index: src/usr.bin/elf2aout/elf2aout.c
diff -u src/usr.bin/elf2aout/elf2aout.c:1.16 src/usr.bin/elf2aout/elf2aout.c:1.17
--- src/usr.bin/elf2aout/elf2aout.c:1.16	Sun Mar  6 10:44:06 2016
+++ src/usr.bin/elf2aout/elf2aout.c	Sun Mar  6 11:13:21 2016
@@ -1,4 +1,4 @@
-/*	$NetBSD: elf2aout.c,v 1.16 2016/03/06 15:44:06 martin Exp $	*/
+/*	$NetBSD: elf2aout.c,v 1.17 2016/03/06 16:13:21 christos Exp $	*/
 
 /*
  * Copyright (c) 1995
@@ -65,7 +65,7 @@ struct sect {
 
 void	combine(struct sect *, struct sect *, int);
 int	phcmp(const void *, const void *);
-char   *saveRead(int file, off_t offset, off_t len, const char *name);
+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);
 
@@ -82,8 +82,7 @@ main(int argc, char **argv)
 	Elf32_Phdr *ph;
 	Elf32_Shdr *sh;
 	char   *shstrtab;
-	int     strtabix, symtabix;
-	int     i;
+	ssize_t i, strtabix, symtabix;
 	struct sect text, data, bss;
 	struct exec aex;
 	int     infile, outfile;
@@ -99,8 +98,9 @@ main(int argc, char **argv)
 	if (argc < 3 || argc > 4) {
 usage:
 		fprintf(stderr,
-		    "usage: elf2aout <elf executable> <a.out executable> [-s]\n");
-		exit(1);
+		    "Usage: %s <elf executable> <a.out executable> [-s]\n",
+		    getprogname());
+		exit(EXIT_FAILURE);
 	}
 	if (argc == 4) {
 		if (strcmp(argv[3], "-s"))
@@ -108,17 +108,16 @@ usage:
 		symflag = 1;
 	}
 	/* Try the input file... */
-	if ((infile = open(argv[1], O_RDONLY)) < 0) {
-		fprintf(stderr, "Can't open %s for read: %s\n",
-		    argv[1], strerror(errno));
-		exit(1);
-	}
+	if ((infile = open(argv[1], O_RDONLY)) < 0)
+		err(EXIT_FAILURE, "Can't open `%s' for read", argv[1]);
+
 	/* Read the header, which is at the beginning of the file... */
 	i = read(infile, &ex, sizeof ex);
 	if (i != sizeof ex) {
-		fprintf(stderr, "ex: %s: %s.\n",
-		    argv[1], i ? strerror(errno) : "End of file reached");
-		exit(1);
+		if (i == -1)
+			err(EXIT_FAILURE, "Error reading `%s'", argv[1]);
+		else
+			errx(EXIT_FAILURE, "End of file reading `%s'", argv[1]);
 	}
 #if TARGET_BYTE_ORDER != BYTE_ORDER
 	ex.e_type	= bswap16(ex.e_type);
@@ -136,28 +135,26 @@ usage:
 	ex.e_shstrndx	= bswap16(ex.e_shstrndx);
 #endif
 	/* Read the program headers... */
-	ph = (Elf32_Phdr *) saveRead(infile, ex.e_phoff,
-	    ex.e_phnum * sizeof(Elf32_Phdr), "ph");
+	ph = saveRead(infile, ex.e_phoff,
+	    (size_t)ex.e_phnum * sizeof(Elf32_Phdr), "ph");
 #if TARGET_BYTE_ORDER != BYTE_ORDER
 	bswap32_region((int32_t*)ph, sizeof(Elf32_Phdr) * ex.e_phnum);
 #endif
 	/* Read the section headers... */
-	sh = (Elf32_Shdr *) saveRead(infile, ex.e_shoff,
-	    ex.e_shnum * sizeof(Elf32_Shdr), "sh");
+	sh = saveRead(infile, ex.e_shoff,
+	    (size_t)ex.e_shnum * sizeof(Elf32_Shdr), "sh");
 #if TARGET_BYTE_ORDER != BYTE_ORDER
 	bswap32_region((int32_t*)sh, sizeof(Elf32_Shdr) * ex.e_shnum);
 #endif
 	/* Read in the section string table. */
 	shstrtab = saveRead(infile, sh[ex.e_shstrndx].sh_offset,
-	    sh[ex.e_shstrndx].sh_size, "shstrtab");
+	    (size_t)sh[ex.e_shstrndx].sh_size, "shstrtab");
 
 	/* Find space for a table matching ELF section indices to a.out symbol
 	 * types. */
 	symTypeTable = malloc(ex.e_shnum * sizeof(int));
-	if (symTypeTable == NULL) {
-		fprintf(stderr, "symTypeTable: can't allocate.\n");
-		exit(1);
-	}
+	if (symTypeTable == NULL)
+		err(EXIT_FAILURE, "symTypeTable: can't allocate");
 	memset(symTypeTable, 0, ex.e_shnum * sizeof(int));
 
 	/* Look for the symbol table and string table... Also map section
@@ -197,7 +194,9 @@ usage:
 		/* Section types we can't handle... */
 		else
 			if (ph[i].p_type != PT_LOAD)
-				errx(1, "Program header %d type %d can't be converted.", i, ph[i].p_type);
+				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;
@@ -224,10 +223,10 @@ usage:
 
 	/* Sections must be in order to be converted... */
 	if (text.vaddr > data.vaddr || data.vaddr > bss.vaddr ||
-	    text.vaddr + text.len > data.vaddr || data.vaddr + data.len > bss.vaddr) {
-		fprintf(stderr, "Sections ordering prevents a.out conversion.\n");
-		exit(1);
-	}
+	    text.vaddr + text.len > data.vaddr ||
+	    data.vaddr + data.len > bss.vaddr)
+		errx(EXIT_FAILURE, "Sections ordering prevents a.out "
+		    "conversion.");
 	/* If there's a data section but no text section, then the loader
 	 * combined everything into one section.   That needs to be the text
 	 * section, so just make the data section zero length following text. */
@@ -273,7 +272,8 @@ usage:
 	default:
 		mid = MID_ZERO;
 	}
-	aex.a_midmag = htonl((symflag << 26) | (mid << 16) | OMAGIC);
+	aex.a_midmag = (u_long)htonl(((u_long)symflag << 26) 
+	    | ((u_long)mid << 16) | OMAGIC);
 
 	aex.a_text = text.len;
 	aex.a_data = data.len;
@@ -295,20 +295,16 @@ usage:
 #endif
 
 	/* Make the output file... */
-	if ((outfile = open(argv[2], O_WRONLY | O_CREAT, 0777)) < 0) {
-		fprintf(stderr, "Unable to create %s: %s\n", argv[2], strerror(errno));
-		exit(1);
-	}
+	if ((outfile = open(argv[2], O_WRONLY | O_CREAT, 0777)) < 0)
+		err(EXIT_FAILURE, "Unable to create `%s'", argv[2]);
 	/* Truncate file... */
 	if (ftruncate(outfile, 0)) {
 		warn("ftruncate %s", argv[2]);
 	}
 	/* Write the header... */
 	i = write(outfile, &aex, sizeof aex);
-	if (i != sizeof aex) {
-		perror("aex: write");
-		exit(1);
-	}
+	if (i != sizeof aex)
+		err(EXIT_FAILURE, "Can't write `%s'", argv[2]);
 	/* 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. */
@@ -320,22 +316,20 @@ usage:
 				uint32_t gap = ph[i].p_vaddr - cur_vma;
 				char    obuf[1024];
 				if (gap > 65536)
-					errx(1,
-			"Intersegment gap (%ld bytes) too large.", (long) gap);
+					errx(EXIT_FAILURE,
+			"Intersegment gap (%u bytes) too large", gap);
 #ifdef DEBUG
-				warnx("Warning: %ld byte intersegment gap.",
-				    (long)gap);
+				warnx("%u byte intersegment gap", gap);
 #endif
 				memset(obuf, 0, sizeof obuf);
 				while (gap) {
-					int     count = write(outfile, obuf, (gap > sizeof obuf
-						? sizeof obuf : gap));
-					if (count < 0) {
-						fprintf(stderr, "Error writing gap: %s\n",
-						    strerror(errno));
-						exit(1);
-					}
-					gap -= count;
+					ssize_t count = write(outfile, obuf,
+					    (gap > sizeof obuf
+					    ? sizeof obuf : gap));
+					if (count < 0)
+						err(EXIT_FAILURE,
+						    "Error writing gap");
+					gap -= (uint32_t)count;
 				}
 			}
 			copy(outfile, infile, ph[i].p_offset, ph[i].p_filesz);
@@ -348,8 +342,12 @@ usage:
 	    sh[symtabix].sh_offset, sh[symtabix].sh_size,
 	    sh[strtabix].sh_offset, sh[strtabix].sh_size);
 
+	free(ph);
+	free(sh);
+	free(shstrtab);
+	free(symTypeTable);
 	/* Looks like we won... */
-	exit(0);
+	return EXIT_SUCCESS;
 }
 /* translate_syms (out, in, offset, size)
 
@@ -363,51 +361,47 @@ translate_syms(int out, int in, off_t sy
 #define SYMS_PER_PASS	64
 	Elf32_Sym inbuf[64];
 	struct nlist outbuf[64];
-	int     i, remaining, cur;
+	ssize_t i, remaining, cur;
 	char   *oldstrings;
 	char   *newstrings, *nsp;
-	int     newstringsize, stringsizebuf;
+	size_t  newstringsize, stringsizebuf;
 
 	/* Zero the unused fields in the output buffer.. */
 	memset(outbuf, 0, sizeof outbuf);
 
 	/* Find number of symbols to process... */
-	remaining = symsize / sizeof(Elf32_Sym);
+	remaining = symsize / (ssize_t)sizeof(Elf32_Sym);
 
 	/* Suck in the old string table... */
-	oldstrings = saveRead(in, stroff, strsize, "string table");
+	oldstrings = saveRead(in, stroff, (size_t)strsize, "string table");
 
 	/* Allocate space for the new one.   XXX We make the wild assumption
 	 * that no two symbol table entries will point at the same place in
 	 * the string table - if that assumption is bad, this could easily
 	 * blow up. */
-	newstringsize = strsize + remaining;
+	newstringsize = (size_t)(strsize + remaining);
 	newstrings = malloc(newstringsize);
-	if (newstrings == NULL) {
-		fprintf(stderr, "No memory for new string table!\n");
-		exit(1);
-	}
+	if (newstrings == NULL)
+		err(EXIT_FAILURE, "No memory for new string table!");
 	/* Initialize the table pointer... */
 	nsp = newstrings;
 
 	/* Go the start of the ELF symbol table... */
-	if (lseek(in, symoff, SEEK_SET) < 0) {
-		perror("translate_syms: lseek");
-		exit(1);
-	}
+	if (lseek(in, symoff, SEEK_SET) < 0)
+		err(EXIT_FAILURE, "Can't seek");
 	/* Translate and copy symbols... */
 	while (remaining) {
 		cur = remaining;
 		if (cur > SYMS_PER_PASS)
 			cur = SYMS_PER_PASS;
 		remaining -= cur;
-		if ((i = read(in, inbuf, cur * sizeof(Elf32_Sym)))
+		if ((i = read(in, inbuf, (size_t)cur * sizeof(Elf32_Sym)))
 		    != cur * (ssize_t)sizeof(Elf32_Sym)) {
 			if (i < 0)
-				perror("translate_syms");
+				err(EXIT_FAILURE, "%s: read error", __func__);
 			else
-				fprintf(stderr, "translate_syms: premature end of file.\n");
-			exit(1);
+				errx(EXIT_FAILURE, "%s: premature end of file",
+					__func__);
 		}
 		/* Do the translation... */
 		for (i = 0; i < cur; i++) {
@@ -444,7 +438,7 @@ translate_syms(int out, int in, off_t sy
 						    inbuf[i].st_shndx == SHN_MIPS_ACOMMON)
 							outbuf[i].n_type = N_COMM;
 						else
-							outbuf[i].n_type = symTypeTable[inbuf[i].st_shndx];
+							outbuf[i].n_type = (unsigned char)symTypeTable[inbuf[i].st_shndx];
 			if (binding == STB_GLOBAL)
 				outbuf[i].n_type |= N_EXT;
 			/* Symbol values in executables should be compatible. */
@@ -456,11 +450,9 @@ translate_syms(int out, int in, off_t sy
 #endif
 		}
 		/* Write out the symbols... */
-		if ((i = write(out, outbuf, cur * sizeof(struct nlist)))
-		    != cur * (ssize_t)sizeof(struct nlist)) {
-			fprintf(stderr, "translate_syms: write: %s\n", strerror(errno));
-			exit(1);
-		}
+		if ((i = write(out, outbuf, (size_t)cur * sizeof(struct nlist)))
+		    != cur * (ssize_t)sizeof(struct nlist))
+			err(EXIT_FAILURE, "%s: write failed", __func__);
 	}
 	/* Write out the string table length... */
 	stringsizebuf = newstringsize;
@@ -468,16 +460,12 @@ translate_syms(int out, int in, off_t sy
 	stringsizebuf = bswap32(stringsizebuf);
 #endif
 	if (write(out, &stringsizebuf, sizeof stringsizebuf)
-	    != sizeof stringsizebuf) {
-		fprintf(stderr,
-		    "translate_syms: newstringsize: %s\n", strerror(errno));
-		exit(1);
-	}
+	    != sizeof stringsizebuf)
+		err(EXIT_FAILURE, "%s: newstringsize: write failed", __func__);
 	/* Write out the string table... */
-	if (write(out, newstrings, newstringsize) != newstringsize) {
-		fprintf(stderr, "translate_syms: newstrings: %s\n", strerror(errno));
-		exit(1);
-	}
+	if (write(out, newstrings, newstringsize) != (ssize_t)newstringsize)
+		err(EXIT_FAILURE, "%s: newstrings: write failed", __func__);
+	free(newstrings);
 	free(oldstrings);
 }
 
@@ -485,28 +473,26 @@ void
 copy(int out, int in, off_t offset, off_t size)
 {
 	char    ibuf[4096];
-	int     remaining, cur, count;
+	ssize_t remaining, cur, count;
 
 	/* Go to the start of the ELF symbol table... */
-	if (lseek(in, offset, SEEK_SET) < 0) {
-		perror("copy: lseek");
-		exit(1);
-	}
+	if (lseek(in, offset, SEEK_SET) < 0)
+		err(EXIT_FAILURE, "%s: lseek failed", __func__);
 	remaining = size;
 	while (remaining) {
 		cur = remaining;
 		if (cur > (int)sizeof ibuf)
 			cur = sizeof ibuf;
 		remaining -= cur;
-		if ((count = read(in, ibuf, cur)) != cur) {
-			fprintf(stderr, "copy: read: %s\n",
-			    count ? strerror(errno) : "premature end of file");
-			exit(1);
-		}
-		if ((count = write(out, ibuf, cur)) != cur) {
-			perror("copy: write");
-			exit(1);
+		if ((count = read(in, ibuf, (size_t)cur)) != cur) {
+			if (count < 0)
+				err(EXIT_FAILURE, "%s: read error", __func__);
+			else
+				errx(EXIT_FAILURE, "%s: premature end of file",
+					__func__);
 		}
+		if ((count = write(out, ibuf, (size_t)cur)) != cur)
+			err(EXIT_FAILURE, "%s: write failed", __func__);
 	}
 }
 /* Combine two segments, which must be contiguous.   If pad is true, it's
@@ -522,11 +508,9 @@ combine(struct sect *base, struct sect *
 			if (base->vaddr + base->len != new->vaddr) {
 				if (pad)
 					base->len = new->vaddr - base->vaddr;
-				else {
-					fprintf(stderr,
-					    "Non-contiguous data can't be converted.\n");
-					exit(1);
-				}
+				else
+					errx(EXIT_FAILURE, "Non-contiguous "
+					    "data can't be converted");
 			}
 			base->len += new->len;
 		}
@@ -549,23 +533,25 @@ phcmp(const void *vh1, const void *vh2)
 			return 0;
 }
 
-char *
-saveRead(int file, off_t offset, off_t len, const char *name)
+void *
+saveRead(int file, off_t offset, size_t len, const char *name)
 {
 	char   *tmp;
-	int     count;
+	ssize_t count;
 	off_t   off;
-	if ((off = lseek(file, offset, SEEK_SET)) < 0) {
-		fprintf(stderr, "%s: fseek: %s\n", name, strerror(errno));
-		exit(1);
-	}
+
+	if ((off = lseek(file, offset, SEEK_SET)) < 0)
+		errx(EXIT_FAILURE, "%s: seek failed", name);
 	if ((tmp = malloc(len)) == NULL)
-		errx(1, "%s: Can't allocate %ld bytes.", name, (long)len);
+		errx(EXIT_FAILURE,
+		    "%s: Can't allocate %jd bytes.", name, (intmax_t)len);
 	count = read(file, tmp, len);
-	if (count != len) {
-		fprintf(stderr, "%s: read: %s.\n",
-		    name, count ? strerror(errno) : "End of file reached");
-		exit(1);
+	if ((size_t)count != len) {
+		if (count < 0)
+			err(EXIT_FAILURE, "%s: read error", name);
+		else
+			errx(EXIT_FAILURE, "%s: premature end of file",
+			    name);
 	}
 	return tmp;
 }

Reply via email to