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;
+}