Module Name:    src
Committed By:   christos
Date:           Wed Sep 21 16:25:41 UTC 2016

Modified Files:
        src/usr.sbin/mdsetimage: Makefile exec_aout.c exec_elf32.c extern.h
            mdsetimage.8 mdsetimage.c
Added Files:
        src/usr.sbin/mdsetimage: bin.h bin_bfd.c bin_nlist.c

Log Message:
merge copies...


To generate a diff of this commit:
cvs rdiff -u -r1.16 -r1.17 src/usr.sbin/mdsetimage/Makefile
cvs rdiff -u -r0 -r1.1 src/usr.sbin/mdsetimage/bin.h \
    src/usr.sbin/mdsetimage/bin_bfd.c src/usr.sbin/mdsetimage/bin_nlist.c
cvs rdiff -u -r1.7 -r1.8 src/usr.sbin/mdsetimage/exec_aout.c
cvs rdiff -u -r1.12 -r1.13 src/usr.sbin/mdsetimage/exec_elf32.c
cvs rdiff -u -r1.9 -r1.10 src/usr.sbin/mdsetimage/extern.h
cvs rdiff -u -r1.11 -r1.12 src/usr.sbin/mdsetimage/mdsetimage.8
cvs rdiff -u -r1.20 -r1.21 src/usr.sbin/mdsetimage/mdsetimage.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.sbin/mdsetimage/Makefile
diff -u src/usr.sbin/mdsetimage/Makefile:1.16 src/usr.sbin/mdsetimage/Makefile:1.17
--- src/usr.sbin/mdsetimage/Makefile:1.16	Sun May 18 03:57:39 2003
+++ src/usr.sbin/mdsetimage/Makefile	Wed Sep 21 12:25:41 2016
@@ -1,10 +1,10 @@
-#	$NetBSD: Makefile,v 1.16 2003/05/18 07:57:39 lukem Exp $
+#	$NetBSD: Makefile,v 1.17 2016/09/21 16:25:41 christos Exp $
 
 .include <bsd.own.mk>
 
 PROG=	mdsetimage
 SRCS=	mdsetimage.c exec_aout.c exec_ecoff.c exec_elf32.c exec_elf64.c \
-	exec_coff.c
+	exec_coff.c bin_nlist.c
 MAN=	mdsetimage.8
 
 .if	${MACHINE_ARCH} == "alpha"

Index: src/usr.sbin/mdsetimage/exec_aout.c
diff -u src/usr.sbin/mdsetimage/exec_aout.c:1.7 src/usr.sbin/mdsetimage/exec_aout.c:1.8
--- src/usr.sbin/mdsetimage/exec_aout.c:1.7	Thu Jul 30 11:16:37 2009
+++ src/usr.sbin/mdsetimage/exec_aout.c	Wed Sep 21 12:25:41 2016
@@ -1,4 +1,4 @@
-/* $NetBSD: exec_aout.c,v 1.7 2009/07/30 15:16:37 tsutsui Exp $ */
+/* $NetBSD: exec_aout.c,v 1.8 2016/09/21 16:25:41 christos Exp $ */
 
 /*
  * Copyright (c) 1996 Christopher G. Demetriou
@@ -31,7 +31,7 @@
 
 #include <sys/cdefs.h>
 #ifndef lint
-__RCSID("$NetBSD: exec_aout.c,v 1.7 2009/07/30 15:16:37 tsutsui Exp $");
+__RCSID("$NetBSD: exec_aout.c,v 1.8 2016/09/21 16:25:41 christos Exp $");
 #endif /* not lint */
 
 #include <sys/types.h>
@@ -45,13 +45,8 @@ __RCSID("$NetBSD: exec_aout.c,v 1.7 2009
 #define	check(off, size)	((off < 0) || (off + size > mappedsize))
 #define	BAD			do { rv = -1; goto out; } while (0)
 
-extern int	T_flag_specified;
-extern u_long	text_start;
-
 int
-check_aout(mappedfile, mappedsize)
-	const char *mappedfile;
-	size_t mappedsize;
+check_aout(const char *mappedfile, size_t mappedsize)
 {
 	const struct exec *execp;
 	int rv;
@@ -70,10 +65,8 @@ out:
 }
 
 int
-findoff_aout(mappedfile, mappedsize, vmaddr, fileoffp)
-	const char *mappedfile;
-	size_t mappedsize, *fileoffp;
-	u_long vmaddr;
+findoff_aout(const char *mappedfile, size_t mappedsize, u_long vmaddr,
+    size_t *fileoffp, u_long text_start)
 {
 	const struct exec *execp;
 	int rv;
@@ -87,7 +80,7 @@ findoff_aout(mappedfile, mappedsize, vma
 		    (execp->a_entry & (N_PAGSIZ(*execp)-1)) - execp->a_entry;
 
 	/* apply correction based on the supplied text start address, if any */
-	if (T_flag_specified)
+	if (text_start != (unsigned long)~0)
 		vmaddr += N_TXTADDR(*execp) - text_start;
 
 	if (N_TXTADDR(*execp) <= vmaddr &&

Index: src/usr.sbin/mdsetimage/exec_elf32.c
diff -u src/usr.sbin/mdsetimage/exec_elf32.c:1.12 src/usr.sbin/mdsetimage/exec_elf32.c:1.13
--- src/usr.sbin/mdsetimage/exec_elf32.c:1.12	Sat Aug 28 17:30:03 2010
+++ src/usr.sbin/mdsetimage/exec_elf32.c	Wed Sep 21 12:25:41 2016
@@ -1,4 +1,4 @@
-/* $NetBSD: exec_elf32.c,v 1.12 2010/08/28 21:30:03 joerg Exp $ */
+/* $NetBSD: exec_elf32.c,v 1.13 2016/09/21 16:25:41 christos Exp $ */
 
 /*
  * Copyright (c) 1996 Christopher G. Demetriou
@@ -31,7 +31,7 @@
 
 #include <sys/cdefs.h>
 #ifndef lint
-__RCSID("$NetBSD: exec_elf32.c,v 1.12 2010/08/28 21:30:03 joerg Exp $");
+__RCSID("$NetBSD: exec_elf32.c,v 1.13 2016/09/21 16:25:41 christos Exp $");
 #endif /* not lint */
 
 #ifndef ELFSIZE
@@ -54,9 +54,7 @@ __RCSID("$NetBSD: exec_elf32.c,v 1.12 20
 #define	BAD			do { rv = -1; goto out; } while (0)
 
 int
-ELFNAMEEND(check)(mappedfile, mappedsize)
-	const char *mappedfile;
-	size_t mappedsize;
+ELFNAMEEND(check)(const char *mappedfile, size_t mappedsize)
 {
 	const Elf_Ehdr *ehdrp;
 	int rv;
@@ -83,10 +81,8 @@ out:
 }
 
 int
-ELFNAMEEND(findoff)(mappedfile, mappedsize, vmaddr, fileoffp)
-	const char *mappedfile;
-	size_t mappedsize, *fileoffp;
-	u_long vmaddr;
+ELFNAMEEND(findoff)(const char *mappedfile, size_t mappedsize, u_long vmaddr,
+    size_t *fileoffp, u_long text_addr)
 {
 	const Elf_Ehdr *ehdrp;
 	const Elf_Phdr *phdrp;

Index: src/usr.sbin/mdsetimage/extern.h
diff -u src/usr.sbin/mdsetimage/extern.h:1.9 src/usr.sbin/mdsetimage/extern.h:1.10
--- src/usr.sbin/mdsetimage/extern.h:1.9	Mon Oct  1 19:32:34 2001
+++ src/usr.sbin/mdsetimage/extern.h	Wed Sep 21 12:25:41 2016
@@ -1,4 +1,4 @@
-/* $NetBSD: extern.h,v 1.9 2001/10/01 23:32:34 cgd Exp $ */
+/* $NetBSD: extern.h,v 1.10 2016/09/21 16:25:41 christos Exp $ */
 
 /*
  * Copyright (c) 1996 Christopher G. Demetriou
@@ -30,22 +30,22 @@
  */
 
 #ifdef NLIST_AOUT
-int	check_aout __P((const char *, size_t));
-int	findoff_aout __P((const char *, size_t, u_long, size_t *));
+int	check_aout(const char *, size_t);
+int	findoff_aout(const char *, size_t, u_long, size_t *, u_long);
 #endif
 #ifdef NLIST_ECOFF
-int	check_ecoff __P((const char *, size_t));
-int	findoff_ecoff __P((const char *, size_t, u_long, size_t *));
+int	check_ecoff(const char *, size_t);
+int	findoff_ecoff(const char *, size_t, u_long, size_t *, u_long);
 #endif
 #ifdef NLIST_ELF32
-int	check_elf32 __P((const char *, size_t));
-int	findoff_elf32 __P((const char *, size_t, u_long, size_t *));
+int	check_elf32(const char *, size_t);
+int	findoff_elf32(const char *, size_t, u_long, size_t *, u_long);
 #endif
 #ifdef NLIST_ELF64
-int	check_elf64 __P((const char *, size_t));
-int	findoff_elf64 __P((const char *, size_t, u_long, size_t *));
+int	check_elf64(const char *, size_t);
+int	findoff_elf64(const char *, size_t, u_long, size_t *, u_long);
 #endif
 #ifdef NLIST_COFF
-int	check_coff __P((const char *, size_t));
-int	findoff_coff __P((const char *, size_t, u_long, size_t *));
+int	check_coff(const char *, size_t);
+int	findoff_coff(const char *, size_t, u_long, size_t *, u_long);
 #endif

Index: src/usr.sbin/mdsetimage/mdsetimage.8
diff -u src/usr.sbin/mdsetimage/mdsetimage.8:1.11 src/usr.sbin/mdsetimage/mdsetimage.8:1.12
--- src/usr.sbin/mdsetimage/mdsetimage.8:1.11	Sun Nov  7 06:49:21 2010
+++ src/usr.sbin/mdsetimage/mdsetimage.8	Wed Sep 21 12:25:41 2016
@@ -1,4 +1,4 @@
-.\" $NetBSD: mdsetimage.8,v 1.11 2010/11/07 11:49:21 wiz Exp $
+.\"	$NetBSD: mdsetimage.8,v 1.12 2016/09/21 16:25:41 christos Exp $
 .\"
 .\" Copyright (c) 1996 Christopher G. Demetriou
 .\" All rights reserved.
@@ -27,7 +27,7 @@
 .\"
 .\" <<Id: LICENSE_GC,v 1.1 2001/10/01 23:24:05 cgd Exp>>
 .\"
-.Dd November 4, 2010
+.Dd September 21, 2016
 .Dt MDSETIMAGE 8
 .Os
 .Sh NAME
@@ -35,7 +35,8 @@
 .Nd set kernel RAM disk image
 .Sh SYNOPSIS
 .Nm
-.Op Fl v
+.Op Fl svx
+.Op Fl b Ar bfdname
 .Op Fl I Ar image_symbol
 .Op Fl S Ar size_symbol
 .Op Fl T Ar address
@@ -53,6 +54,10 @@ The file system present in
 will typically be used by the kernel
 as the root file system.
 .Pp
+To recognize kernel executable format, the
+.Fl b
+flag specifies BFD name of kernel.
+.Pp
 The
 .Fl I
 and
@@ -66,11 +71,28 @@ flag specifies the starting address of k
 This flag is ignored for other kernel executable formats.
 .Pp
 If the
+.Fl s
+flags is given,
+.Nm
+will write back the actual disk image size back into
+.Ar kernel .
+.Pp
+If the
 .Fl v
 flag is given,
 .Nm
 will print out status information as
 it is copying the image.
+.Pp
+If the
+.Fl x
+flag is given,
+.Nm
+will extract the disk image from
+.Ar kernel
+into the file
+.Ar image .
+This is the opposite of the default behavior.
 .Sh SEE ALSO
 .Xr md 4 ,
 .Xr mdconfig 8

Index: src/usr.sbin/mdsetimage/mdsetimage.c
diff -u src/usr.sbin/mdsetimage/mdsetimage.c:1.20 src/usr.sbin/mdsetimage/mdsetimage.c:1.21
--- src/usr.sbin/mdsetimage/mdsetimage.c:1.20	Sat Nov  6 12:03:23 2010
+++ src/usr.sbin/mdsetimage/mdsetimage.c	Wed Sep 21 12:25:41 2016
@@ -1,7 +1,7 @@
-/* $NetBSD: mdsetimage.c,v 1.20 2010/11/06 16:03:23 uebayasi Exp $ */
+/*	$NetBSD: mdsetimage.c,v 1.21 2016/09/21 16:25:41 christos Exp $	*/
 
 /*
- * Copyright (c) 1996 Christopher G. Demetriou
+ * Copyright (c) 1996, 2002 Christopher G. Demetriou
  * All rights reserved.
  * 
  * Redistribution and use in source and binary forms, with or without
@@ -29,14 +29,15 @@
  * <<Id: LICENSE_GC,v 1.1 2001/10/01 23:24:05 cgd Exp>>
  */
 
+#if HAVE_NBTOOL_CONFIG_H
+#include "nbtool_config.h"
+#endif
+
 #include <sys/cdefs.h>
-#ifndef lint
+#if !defined(lint)
 __COPYRIGHT("@(#) Copyright (c) 1996\
  Christopher G. Demetriou.  All rights reserved.");
-#endif /* not lint */
-
-#ifndef lint
-__RCSID("$NetBSD: mdsetimage.c,v 1.20 2010/11/06 16:03:23 uebayasi Exp $");
+__RCSID("$NetBSD: mdsetimage.c,v 1.21 2016/09/21 16:25:41 christos Exp $");
 #endif /* not lint */
 
 #include <sys/types.h>
@@ -46,70 +47,68 @@ __RCSID("$NetBSD: mdsetimage.c,v 1.20 20
 #include <err.h>
 #include <fcntl.h>
 #include <limits.h>
-#include <nlist.h>
 #include <stdio.h>
 #include <stdlib.h>
-#include <string.h>
 #include <unistd.h>
+#include <string.h>
 
-#include "extern.h"
+#include "bin.h"
 
-int		main __P((int, char *[]));
-static void	usage __P((void)) __dead;
-static int	find_md_root __P((const char *, const char *, size_t,
-		    const struct nlist *, size_t *, u_int32_t *));
+#define	CHUNKSIZE	(64 * 1024)
 
-#define	X_MD_ROOT_IMAGE		0
-#define	X_MD_ROOT_SIZE		1
+static void	usage(void) __attribute__((noreturn));
 
 int	verbose;
-#ifdef NLIST_AOUT
-/*
- * Since we can't get the text address from an a.out executable, we
- * need to be able to specify it.  Note: there's no way to test to
- * see if the user entered a valid address!
- */
-int	T_flag_specified;	/* the -T flag was specified */
-u_long	text_start;		/* Start of kernel text */
-#endif /* NLIST_AOUT */
+int	extract;
+int	setsize;
+
+static const char *progname;
+#undef setprogname
+#define	setprogname(x)	(void)(progname = (x))
+#undef getprogname
+#define	getprogname()	(progname)
 
 int
-main(argc, argv)
-	int argc;
-	char *argv[];
+main(int argc, char *argv[])
 {
+	int ch, kfd, fsfd, rv;
 	struct stat ksb, fssb;
-	size_t md_root_offset;
-	u_int32_t md_root_size;
+	size_t md_root_image_offset, md_root_size_offset;
+	u_int32_t md_root_size_value;
 	const char *kfile, *fsfile;
 	char *mappedkfile;
-	int ch, kfd, fsfd, rv;
-	struct nlist md_root_nlist[3];
-
-	(void)memset(md_root_nlist, 0, sizeof(md_root_nlist));
-	N_NAME(&md_root_nlist[X_MD_ROOT_IMAGE]) = "_md_root_image";
-	N_NAME(&md_root_nlist[X_MD_ROOT_SIZE]) = "_md_root_size";
+	char *bfdname = NULL;
+	void *bin;
+	ssize_t left_to_copy;
+	const char *md_root_image = "_md_root_image";
+	const char *md_root_size = "_md_root_size";
+	unsigned long text_start = ~0;
 
 	setprogname(argv[0]);
 
-	while ((ch = getopt(argc, argv, "I:S:T:v")) != -1)
+	while ((ch = getopt(argc, argv, "I:S:b:svx")) != -1)
 		switch (ch) {
-		case 'v':
-			verbose = 1;
-			break;
 		case 'I':
-			N_NAME(&md_root_nlist[X_MD_ROOT_IMAGE]) = optarg;
+			md_root_image = optarg;
 			break;
 		case 'S':
-			N_NAME(&md_root_nlist[X_MD_ROOT_SIZE]) = optarg;
+			md_root_size = optarg;
 			break;
 		case 'T':
-#ifdef NLIST_AOUT
-			T_flag_specified = 1;
 			text_start = strtoul(optarg, NULL, 0);
 			break;
-#endif /* NLIST_AOUT */
-			/* FALLTHROUGH */
+		case 'b':
+			bfdname = optarg;
+			break;
+		case 's':
+			setsize = 1;
+			break;
+		case 'v':
+			verbose = 1;
+			break;
+		case 'x':
+			extract = 1;
+			break;
 		case '?':
 		default:
 			usage();
@@ -122,151 +121,134 @@ main(argc, argv)
 	kfile = argv[0];
 	fsfile = argv[1];
 
-	if ((kfd = open(kfile, O_RDWR, 0))  == -1)
-		err(1, "open %s", kfile);
-
-	if ((rv = __fdnlist(kfd, md_root_nlist)) != 0)
-		errx(1, "could not find symbols in %s", kfile);
-	if (verbose)
-		fprintf(stderr, "got symbols from %s\n", kfile);
+	if (extract) {
+		if ((kfd = open(kfile, O_RDONLY, 0))  == -1)
+			err(1, "open %s", kfile);
+	} else {
+		if ((kfd = open(kfile, O_RDWR, 0))  == -1)
+			err(1, "open %s", kfile);
+	}
 
 	if (fstat(kfd, &ksb) == -1)
 		err(1, "fstat %s", kfile);
-	if (ksb.st_size != (size_t)ksb.st_size)
+	if ((uintmax_t)ksb.st_size != (size_t)ksb.st_size)
 		errx(1, "%s too big to map", kfile);
 
-	if ((mappedkfile = mmap(NULL, ksb.st_size, PROT_READ | PROT_WRITE,
-	    MAP_FILE | MAP_SHARED, kfd, 0)) == (caddr_t)-1)
+	if ((mappedkfile = mmap(NULL, ksb.st_size, PROT_READ,
+	    MAP_FILE | MAP_PRIVATE, kfd, 0)) == (caddr_t)-1)
 		err(1, "mmap %s", kfile);
 	if (verbose)
 		fprintf(stderr, "mapped %s\n", kfile);
 
-	if (find_md_root(kfile, mappedkfile, ksb.st_size, md_root_nlist,
-	    &md_root_offset, &md_root_size) != 0)
-		errx(1, "could not find md root buffer in %s", kfile);
-
-	if ((fsfd = open(fsfile, O_RDONLY, 0)) == -1)
-		err(1, "open %s", fsfile);
-	if (fstat(fsfd, &fssb) == -1)
-		err(1, "fstat %s", fsfile);
-	if (fssb.st_size != (size_t)fssb.st_size)
-		errx(1, "fs image is too big");
-	if (fssb.st_size > md_root_size)
-		errx(1, "fs image (%lld bytes) too big for buffer (%lu bytes)",
-		    (long long)fssb.st_size, (unsigned long)md_root_size);
+	bin = bin_open(kfd, kfile, bfdname);
+
+	if (bin_find_md_root(bin, mappedkfile, ksb.st_size, text_start,
+	    md_root_image, md_root_size, &md_root_image_offset,
+	    &md_root_size_offset, &md_root_size_value, verbose) != 0)
+		errx(1, "could not find symbols in %s", kfile);
+	if (verbose)
+		fprintf(stderr, "got symbols from %s\n", kfile);
 
 	if (verbose)
-		fprintf(stderr, "copying image from %s into %s\n", fsfile,
-		    kfile);
-	if ((rv = read(fsfd, mappedkfile + md_root_offset,
-	    fssb.st_size)) != fssb.st_size) {
-		if (rv == -1)
-			err(1, "read %s", fsfile);
-		else
-			errx(1, "unexpected EOF reading %s", fsfile);
+		fprintf(stderr, "root @ %#zx/%u\n",
+		    md_root_image_offset, md_root_size_value);
+
+	munmap(mappedkfile, ksb.st_size);
+
+	if (extract) {
+		if ((fsfd = open(fsfile, O_WRONLY|O_CREAT, 0777)) == -1)
+			err(1, "open %s", fsfile);
+		left_to_copy = md_root_size_value;
+	} else {
+		if ((fsfd = open(fsfile, O_RDONLY, 0)) == -1)
+			err(1, "open %s", fsfile);
+		if (fstat(fsfd, &fssb) == -1)
+			err(1, "fstat %s", fsfile);
+		if ((uintmax_t)fssb.st_size != (size_t)fssb.st_size)
+			errx(1, "fs image is too big");
+		if (fssb.st_size > md_root_size_value)
+			errx(1, "fs image (%td bytes) too big for buffer"
+			    " (%u bytes)", fssb.st_size, md_root_size_value);
+		left_to_copy = fssb.st_size;
+	}
+
+	if (verbose)
+		fprintf(stderr, "copying image %s %s %s (%zd bytes)\n", fsfile,
+		    (extract ? "from" : "into"), kfile, left_to_copy);
+
+	if (lseek(kfd, md_root_image_offset, SEEK_SET) !=
+	    (off_t)md_root_image_offset)
+		err(1, "seek %s", kfile);
+	while (left_to_copy > 0) {
+		char buf[CHUNKSIZE];
+		ssize_t todo;
+		int rfd;
+		int wfd;
+		const char *rfile;
+		const char *wfile;
+		if (extract) {
+			rfd = kfd;
+			rfile = kfile;
+			wfd = fsfd;
+			wfile = fsfile;
+		} else {
+			rfd = fsfd;
+			rfile = fsfile;
+			wfd = kfd;
+			wfile = kfile;
+		}
+
+		todo = (left_to_copy > CHUNKSIZE) ? CHUNKSIZE : left_to_copy;
+		if ((rv = read(rfd, buf, todo)) != todo) {
+			if (rv == -1)
+				err(1, "read %s", rfile);
+			else
+				errx(1, "unexpected EOF reading %s", rfile);
+		}
+		if ((rv = write(wfd, buf, todo)) != todo) {
+			if (rv == -1)
+				err(1, "write %s", wfile);
+			else
+				errx(1, "short write writing %s", wfile);
+		}
+		left_to_copy -= todo;
 	}
 	if (verbose)
 		fprintf(stderr, "done copying image\n");
-	
-	close(fsfd);
+	if (setsize && !extract) {
+		char buf[sizeof(uint32_t)];
 
-	munmap(mappedkfile, ksb.st_size);
+		if (verbose)
+			fprintf(stderr, "setting md_root_size to %llu\n",
+			    (unsigned long long) fssb.st_size);
+		if (lseek(kfd, md_root_size_offset, SEEK_SET) !=
+		    (off_t)md_root_size_offset)
+			err(1, "seek %s", kfile);
+		bin_put_32(bin, fssb.st_size, buf);
+		if (write(kfd, buf, sizeof(buf)) != sizeof(buf))
+			err(1, "write %s", kfile);
+	}
+
+	close(fsfd);
 	close(kfd);
 
 	if (verbose)
 		fprintf(stderr, "exiting\n");
-	exit(0);
+
+	bin_close(bin);
+	return 0;
 }
 
 static void
-usage()
+usage(void)
 {
+	const char **list;
 
-	fprintf(stderr,
-	    "usage: %s kernel_file fsimage_file\n",
-	    getprogname());
+	fprintf(stderr, "Usage: %s [-svx] [-b bfdname] [-I image_symbol] "
+	    "[-S size_symbol] [-T address] kernel image", getprogname());
+	fprintf(stderr, "supported targets:");
+	for (list = bin_supported_targets(); *list != NULL; list++)
+		fprintf(stderr, " %s", *list);
+	fprintf(stderr, "\n");
 	exit(1);
 }
-
-
-struct {
-	const char *name;
-	int	(*check) __P((const char *, size_t));
-	int	(*findoff) __P((const char *, size_t, u_long, size_t *));
-} exec_formats[] = {
-#ifdef NLIST_AOUT
-	{	"a.out",	check_aout,	findoff_aout,	},
-#endif
-#ifdef NLIST_ECOFF
-	{	"ECOFF",	check_ecoff,	findoff_ecoff,	},
-#endif
-#ifdef NLIST_ELF32
-	{	"ELF32",	check_elf32,	findoff_elf32,	},
-#endif
-#ifdef NLIST_ELF64
-	{	"ELF64",	check_elf64,	findoff_elf64,	},
-#endif
-#ifdef NLIST_COFF
-	{	"COFF",		check_coff,	findoff_coff,	},
-#endif
-};
-
-static int
-find_md_root(fname, mappedfile, mappedsize, nl, rootoffp, rootsizep)
-	const char *fname, *mappedfile;
-	size_t mappedsize;
-	const struct nlist *nl;
-	size_t *rootoffp;
-	u_int32_t *rootsizep;
-{
-	int i, n;
-	size_t rootsizeoff;
-
-	n = sizeof exec_formats / sizeof exec_formats[0];
-	for (i = 0; i < n; i++) {
-		if ((*exec_formats[i].check)(mappedfile, mappedsize) == 0)
-			break;
-	}
-	if (i == n) {
-		warnx("%s: unknown executable format", fname);
-		return (1);
-	}
-
-	if (verbose) {
-		fprintf(stderr, "%s is an %s binary\n", fname,
-		    exec_formats[i].name);
-#ifdef NLIST_AOUT
-		if (T_flag_specified)
-			fprintf(stderr, "kernel text loads at 0x%lx\n",
-			    text_start);
-#endif
-	}
-
-	if ((*exec_formats[i].findoff)(mappedfile, mappedsize,
-	    nl[X_MD_ROOT_SIZE].n_value, &rootsizeoff) != 0) {
-		warnx("couldn't find offset for %s in %s",
-		    nl[X_MD_ROOT_SIZE].n_name, fname);
-		return (1);
-	}
-	if (verbose)
-		fprintf(stderr, "%s is at offset %#lx in %s\n",
-			nl[X_MD_ROOT_SIZE].n_name,
-			(unsigned long)rootsizeoff, fname);
-	*rootsizep = *(const u_int32_t *)&mappedfile[rootsizeoff];
-	if (verbose)
-		fprintf(stderr, "%s has value %#x\n",
-		    nl[X_MD_ROOT_SIZE].n_name, *rootsizep);
-
-	if ((*exec_formats[i].findoff)(mappedfile, mappedsize,
-	    nl[X_MD_ROOT_IMAGE].n_value, rootoffp) != 0) {
-		warnx("couldn't find offset for %s in %s",
-		    nl[X_MD_ROOT_IMAGE].n_name, fname);
-		return (1);
-	}
-	if (verbose)
-		fprintf(stderr, "%s is at offset %#lx in %s\n",
-			nl[X_MD_ROOT_IMAGE].n_name,
-			(unsigned long)(*rootoffp), fname);
-
-	return (0);
-}

Added files:

Index: src/usr.sbin/mdsetimage/bin.h
diff -u /dev/null src/usr.sbin/mdsetimage/bin.h:1.1
--- /dev/null	Wed Sep 21 12:25:41 2016
+++ src/usr.sbin/mdsetimage/bin.h	Wed Sep 21 12:25:41 2016
@@ -0,0 +1,34 @@
+/*	$NetBSD: bin.h,v 1.1 2016/09/21 16:25:41 christos Exp $	*/
+
+/*-
+ * Copyright (c) 2016 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+void *bin_open(int, const char *, const char *);
+int bin_find_md_root(void *, const char *, off_t, unsigned long,
+    const char *, const char *, size_t *, size_t *, uint32_t *, int);
+void bin_put_32(void *, off_t, char *);
+void bin_close(void *);
+const char **bin_supported_targets(void);
Index: src/usr.sbin/mdsetimage/bin_bfd.c
diff -u /dev/null src/usr.sbin/mdsetimage/bin_bfd.c:1.1
--- /dev/null	Wed Sep 21 12:25:41 2016
+++ src/usr.sbin/mdsetimage/bin_bfd.c	Wed Sep 21 12:25:41 2016
@@ -0,0 +1,149 @@
+/*	$NetBSD: bin_bfd.c,v 1.1 2016/09/21 16:25:41 christos Exp $	*/
+
+/*
+ * Copyright (c) 1996, 2002 Christopher G. Demetriou
+ * All rights reserved.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ * 
+ * <<Id: LICENSE_GC,v 1.1 2001/10/01 23:24:05 cgd Exp>>
+ */
+
+#if HAVE_NBTOOL_CONFIG_H
+#include "nbtool_config.h"
+#endif
+
+#include <sys/cdefs.h>
+__RCSID("$NetBSD: bin_bfd.c,v 1.1 2016/09/21 16:25:41 christos Exp $");
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <err.h>
+#include <bfd.h>
+#include "bin.h"
+
+void *
+bin_open(int kfd, const char *kfile, const char *bfdname)
+{
+	bfd *abfd;
+	bfd_init();
+	if ((abfd = bfd_fdopenr(kfile, bfdname, kfd)) == NULL) {
+		bfd_perror("open");
+		exit(1);
+	}
+	if (!bfd_check_format(abfd, bfd_object)) {
+		bfd_perror("check format");
+		exit(1);
+	}
+	return abfd;
+}
+
+int
+bin_find_md_root(void *bin, const char *mappedkfile, off_t size,
+    unsigned long text_start,
+    const char *root_name, const char *size_name, size_t *md_root_offset,
+    size_t *md_root_size_offset, uint32_t *md_root_size, int verbose)
+{
+	bfd *abfd = bin;
+	long i;
+	long storage_needed;
+	long number_of_symbols;
+	asymbol **symbol_table = NULL;
+	struct symbols {
+		const char *name;
+		size_t offset;
+	} *s, symbols[3];
+
+	symbols[0].name = root_name;
+	symbols[1].name = size_name;
+	symbols[2].name = NULL;
+
+	storage_needed = bfd_get_symtab_upper_bound(abfd);
+	if (storage_needed <= 0) {
+		warnx("bfd storage needed error");
+		return 1;
+	}
+
+	symbol_table = malloc(storage_needed);
+	if (symbol_table == NULL) {
+		warn("symbol table");
+		return 1;
+	}
+
+	number_of_symbols = bfd_canonicalize_symtab(abfd, symbol_table);
+	if (number_of_symbols <= 0) {
+		warnx("can't canonicalize symbol table");
+		free(symbol_table);
+		return 1;
+	}
+
+	for (i = 0; i < number_of_symbols; i++) {
+		for (s = symbols; s->name != NULL; s++) {
+			const char *sym = symbol_table[i]->name;
+
+			/*
+			 * match symbol prefix '_' or ''.
+			 */
+			if (!strcmp(s->name, sym) ||
+			    !strcmp(s->name + 1, sym)) {
+				s->offset =
+				    (size_t)(symbol_table[i]->section->filepos
+				    + symbol_table[i]->value);
+			}
+		}
+	}
+
+	free(symbol_table);
+
+	for (s = symbols; s->name != NULL; s++) {
+		if (s->offset == 0) {
+			warnx("missing offset for `%s'", s->name);
+			return 1;
+		}
+	}
+
+	*md_root_offset = symbols[0].offset;
+	*md_root_size_offset = symbols[1].offset;
+	*md_root_size = bfd_get_32(abfd, &mappedkfile[*md_root_size_offset]);
+
+	return 0;
+}
+
+void
+bin_put_32(void *bin, off_t size, char *buf)
+{
+	bfd_put_32((struct bfd *)bin, size, buf);
+}
+
+void
+bin_close(void *bin)
+{
+	bfd_close_all_done((struct bfd *)bin);
+}
+
+const char **
+bin_supported_targets(void)
+{
+	return bfd_target_list();
+}
Index: src/usr.sbin/mdsetimage/bin_nlist.c
diff -u /dev/null src/usr.sbin/mdsetimage/bin_nlist.c:1.1
--- /dev/null	Wed Sep 21 12:25:41 2016
+++ src/usr.sbin/mdsetimage/bin_nlist.c	Wed Sep 21 12:25:41 2016
@@ -0,0 +1,190 @@
+/*	$NetBSD: bin_nlist.c,v 1.1 2016/09/21 16:25:41 christos Exp $	*/
+
+/*
+ * Copyright (c) 1996, 2002 Christopher G. Demetriou
+ * All rights reserved.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ * 
+ * <<Id: LICENSE_GC,v 1.1 2001/10/01 23:24:05 cgd Exp>>
+ */
+#include <sys/cdefs.h>
+__RCSID("$NetBSD: bin_nlist.c,v 1.1 2016/09/21 16:25:41 christos Exp $");
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <nlist.h>
+#include <err.h>
+
+#include "bin.h"
+#include "extern.h"
+
+struct bininfo {
+	const char *fname;
+	int kfd;
+};
+
+#define X_MD_ROOT_IMAGE 0
+#define X_MD_ROOT_SIZE 1
+
+struct {
+	const char *name;
+	int	(*check)(const char *, size_t);
+	int	(*findoff)(const char *, size_t, u_long, size_t *, u_long);
+} exec_formats[] = {
+#ifdef NLIST_AOUT
+	{	"a.out",	check_aout,	findoff_aout,	},
+#endif
+#ifdef NLIST_ECOFF
+	{	"ECOFF",	check_ecoff,	findoff_ecoff,	},
+#endif
+#ifdef NLIST_ELF32
+	{	"ELF32",	check_elf32,	findoff_elf32,	},
+#endif
+#ifdef NLIST_ELF64
+	{	"ELF64",	check_elf64,	findoff_elf64,	},
+#endif
+#ifdef NLIST_COFF
+	{	"COFF",		check_coff,	findoff_coff,	},
+#endif
+};
+
+void *
+bin_open(int kfd, const char *kfile, const char *bfdname)
+{
+	struct bininfo *bin;
+
+	if ((bin = malloc(sizeof(*bin))) == NULL) {
+		warn("%s", kfile);
+		return NULL;
+	}
+	bin->kfd = kfd;
+	bin->fname = kfile;
+
+	return bin;
+}
+
+
+int
+bin_find_md_root(void *binp, const char *mappedfile, off_t mappedsize,
+    unsigned long text_start, const char *root_name, const char *size_name,
+    size_t *md_root_image_offset, size_t *md_root_size_offset,
+    uint32_t *md_root_size, int verbose)
+{
+	struct bininfo *bin = binp;
+	struct nlist nl[3];
+	size_t i, n = sizeof exec_formats / sizeof exec_formats[0];
+
+	for (i = 0; i < n; i++) {
+		if ((*exec_formats[i].check)(mappedfile, mappedsize) == 0)
+			break;
+	}
+	if (i == n) {
+		warnx("%s: unknown executable format", bin->fname);
+		return 1;
+	}
+
+	if (verbose) {
+		fprintf(stderr, "%s is an %s binary\n", bin->fname,
+		    exec_formats[i].name);
+#ifdef NLIST_AOUT
+		if (text_start != (unsigned long)~0)
+			fprintf(stderr, "kernel text loads at 0x%lx\n",
+			    text_start);
+#endif
+	}
+
+	(void)memset(nl, 0, sizeof(nl));
+	N_NAME(&nl[X_MD_ROOT_IMAGE]) = root_name;
+	N_NAME(&nl[X_MD_ROOT_SIZE]) = size_name;
+
+	if (__fdnlist(bin->kfd, nl) != 0)
+		return 1;
+
+	if ((*exec_formats[i].findoff)(mappedfile, mappedsize,
+	    nl[1].n_value, md_root_size_offset, text_start) != 0) {
+		warnx("couldn't find offset for %s in %s",
+		    nl[X_MD_ROOT_SIZE].n_name, bin->fname);
+		return 1;
+	}
+	if (verbose)
+		fprintf(stderr, "%s is at offset %#zx in %s\n",
+		    nl[X_MD_ROOT_SIZE].n_name, *md_root_size_offset,
+		    bin->fname);
+	memcpy(md_root_size, &mappedfile[*md_root_size_offset],
+	    sizeof(*md_root_size));
+	if (verbose)
+		fprintf(stderr, "%s has value %#x\n",
+		    nl[X_MD_ROOT_SIZE].n_name, *md_root_size);
+
+	if ((*exec_formats[i].findoff)(mappedfile, mappedsize,
+	    nl[0].n_value, md_root_image_offset, text_start) != 0) {
+		warnx("couldn't find offset for %s in %s",
+		    nl[X_MD_ROOT_IMAGE].n_name, bin->fname);
+		return 1;
+	}
+	if (verbose)
+		fprintf(stderr, "%s is at offset %#zx in %s\n",
+			nl[X_MD_ROOT_IMAGE].n_name,
+			*md_root_image_offset, bin->fname);
+
+	return 0;
+}
+
+void
+bin_put_32(void *bin, off_t size, char *buf)
+{
+	uint32_t s = (uint32_t)size;
+	memcpy(buf, &s, sizeof(s));
+}
+
+void
+bin_close(void *bin)
+{
+}
+
+const char **
+bin_supported_targets(void)
+{
+	static const char *fmts[] = {
+#ifdef NLIST_AOUT
+		"aout",
+#endif
+#ifdef NLIST_ECOFF
+		"ecoff",
+#endif
+#ifdef NLIST_ELF32
+		"elf32",
+#endif
+#ifdef NLIST_ELF64
+		"elf64",
+#endif
+#ifdef NLIST_COFF
+		"coff",
+#endif
+		NULL,
+	};
+
+	return fmts;
+}

Reply via email to