diff --git a/usr.sbin/kvm_mkdb/Makefile b/usr.sbin/kvm_mkdb/Makefile index 1fbdc56f2b08..cdab120e80ac 100644 --- a/usr.sbin/kvm_mkdb/Makefile +++ b/usr.sbin/kvm_mkdb/Makefile @@ -1,9 +1,9 @@ -# $NetBSD: Makefile,v 1.7 1996/09/30 18:26:58 thorpej Exp $ +# $NetBSD: Makefile,v 1.8 1999/09/12 16:08:15 itojun Exp $ # from: @(#)Makefile 8.1 (Berkeley) 6/6/93 PROG= kvm_mkdb -SRCS= kvm_mkdb.c nlist.c nlist_aout.c nlist_ecoff.c nlist_elf32.c \ - nlist_elf64.c testdb.c +SRCS= kvm_mkdb.c nlist.c nlist_aout.c nlist_coff.c nlist_ecoff.c \ + nlist_elf32.c nlist_elf64.c testdb.c MAN= kvm_mkdb.8 .include diff --git a/usr.sbin/kvm_mkdb/extern.h b/usr.sbin/kvm_mkdb/extern.h index dbea991295d2..eb37a649e9c9 100644 --- a/usr.sbin/kvm_mkdb/extern.h +++ b/usr.sbin/kvm_mkdb/extern.h @@ -1,4 +1,4 @@ -/* $NetBSD: extern.h,v 1.9 1999/01/29 22:23:36 thorpej Exp $ */ +/* $NetBSD: extern.h,v 1.10 1999/09/12 16:08:15 itojun Exp $ */ /*- * Copyright (c) 1996 Christopher G. Demetriou. All rights reserved. @@ -50,6 +50,9 @@ # define NLIST_AOUT # define NLIST_ELF32 # define NLIST_ELF64 +#elif defined(__sh3__) +# define NLIST_COFF +# define NLIST_ELF32 #else # define NLIST_AOUT /* #define NLIST_ECOFF */ @@ -64,6 +67,9 @@ int testdb __P((void)); #ifdef NLIST_AOUT int create_knlist_aout __P((const char *, DB *)); #endif +#ifdef NLIST_COFF +int create_knlist_coff __P((const char *, DB *)); +#endif #ifdef NLIST_ECOFF int create_knlist_ecoff __P((const char *, DB *)); #endif diff --git a/usr.sbin/kvm_mkdb/nlist.c b/usr.sbin/kvm_mkdb/nlist.c index 4abd3ca59d0b..cbeeed0d4e03 100644 --- a/usr.sbin/kvm_mkdb/nlist.c +++ b/usr.sbin/kvm_mkdb/nlist.c @@ -1,4 +1,4 @@ -/* $NetBSD: nlist.c,v 1.16 1997/10/17 10:15:14 lukem Exp $ */ +/* $NetBSD: nlist.c,v 1.17 1999/09/12 16:08:15 itojun Exp $ */ /*- * Copyright (c) 1996 Christopher G. Demetriou. All rights reserved. @@ -39,7 +39,7 @@ #if 0 static char sccsid[] = "from: @(#)nlist.c 8.1 (Berkeley) 6/6/93"; #else -__RCSID("$NetBSD: nlist.c,v 1.16 1997/10/17 10:15:14 lukem Exp $"); +__RCSID("$NetBSD: nlist.c,v 1.17 1999/09/12 16:08:15 itojun Exp $"); #endif #endif /* not lint */ @@ -65,6 +65,9 @@ static struct { #ifdef NLIST_AOUT { create_knlist_aout }, #endif +#ifdef NLIST_COFF + { create_knlist_coff }, +#endif #ifdef NLIST_ECOFF { create_knlist_ecoff }, #endif diff --git a/usr.sbin/kvm_mkdb/nlist_coff.c b/usr.sbin/kvm_mkdb/nlist_coff.c new file mode 100644 index 000000000000..51e0ab5426bf --- /dev/null +++ b/usr.sbin/kvm_mkdb/nlist_coff.c @@ -0,0 +1,346 @@ +/* $NetBSD: nlist_coff.c,v 1.1 1999/09/12 16:08:15 itojun Exp $ */ + +/* + * Copyright (c) 1996 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. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by Christopher G. Demetriou + * for the NetBSD Project. + * 4. 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. + */ + +#include +#ifndef lint +__RCSID("$NetBSD: nlist_coff.c,v 1.1 1999/09/12 16:08:15 itojun Exp $"); +#endif /* not lint */ + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "extern.h" + +#ifdef NLIST_COFF +#include + +typedef struct nlist NLIST; +#define _strx n_un.n_strx +#define _name n_un.n_name + +#define badfmt(str) \ + do { \ + warnx("%s: %s: %s", kfile, str, strerror(EFTYPE)); \ + punt(); \ + } while (0) + +#define check(off, size) ((off < 0) || (off + size > mappedsize)) +#define BAD do { rv = -1; goto out; } while (0) +#define BADUNMAP do { rv = -1; goto unmap; } while (0) + +static const char *kfile; + +int +create_knlist_coff(name, db) + const char *name; + DB *db; +{ + struct coff_filehdr *filehdrp; + struct coff_aouthdr *aouthdrp; + struct stat st; + struct nlist nbuf; + DBT key, data; + char *mappedfile, *symname, *fsymname; + size_t mappedsize, symnamesize, fsymnamesize; + u_long symhdroff, extrstroff; + u_long symhdrsize, i, nesyms; + int fd, rv; + struct external_syment *syment; + u_long soff; + u_long val; + char snamebuf[16]; + + rv = -1; + + /* + * Open and map the whole file. If we can't open/stat it, + * something bad is going on so we punt. + */ + kfile = name; + if ((fd = open(name, O_RDONLY, 0)) < 0) { + warn("%s", kfile); + punt(); + } + if (fstat(fd, &st) < 0) { + warn("%s", kfile); + punt(); + } + if (st.st_size > SIZE_T_MAX) + BAD; + + /* + * Map the file in its entirety. + */ + mappedsize = st.st_size; + mappedfile = mmap(NULL, mappedsize, PROT_READ, MAP_FILE|MAP_PRIVATE, + fd, 0); + if (mappedfile == (char *)-1) + BAD; + + /* + * Make sure we can access the executable's header + * directly, and make sure the recognize the executable + * as an COFF binary. + */ + if (check(0, sizeof *filehdrp)) + BADUNMAP; + filehdrp = (struct coff_filehdr *)&mappedfile[0]; + + if (COFF_BADMAG(filehdrp)) + BADUNMAP; + + /* + * We've recognized it as an COFF binary. From here + * on out, all errors are fatal. + */ + + aouthdrp = (struct coff_aouthdr *) + &mappedfile[sizeof(struct coff_filehdr)]; + + /* + * Find the symbol list and string table. + */ + symhdroff = filehdrp->f_symptr; + symhdrsize = filehdrp->f_nsyms; + extrstroff = symhdroff + symhdrsize*COFF_ES_SYMENTSZ; + +#ifdef DEGBU + printf("sizeof syment = %d\n",sizeof(struct external_syment )); + printf("symhdroff = 0x%lx,symhdrsize=%ld,stroff = 0x%lx", + symhdroff,symhdrsize, extrstroff); +#endif + + if (symhdrsize == 0) + badfmt("stripped"); + + /* + * Set up the data item, pointing to a nlist structure. + * which we fill in for each symbol. + */ + data.data = (u_char *)&nbuf; + data.size = sizeof(nbuf); + + /* + * Create a buffer (to be expanded later, if necessary) + * to hold symbol names after we've added underscores + * to them. + */ + symnamesize = 1024; + if ((symname = malloc(symnamesize)) == NULL) { + warn("malloc"); + punt(); + } + + nesyms = filehdrp->f_nsyms; + + /* + * Read each symbol and enter it into the database. + */ + for (i = 0; i < nesyms; i++) { + + /* + * Find symbol name, copy it (with added underscore) to + * temporary buffer, and prepare the database key for + * insertion. + */ + syment = (struct external_syment *)&mappedfile[symhdroff + + COFF_ES_SYMENTSZ*i]; + + if(syment->e_sclass[0] != 2){ + continue; + } + + if(syment->e.e.e_zeroes[0]){ + if( syment->e.e_name[COFF_ES_SYMNMLEN-1] ){ + memcpy( snamebuf, syment->e.e_name, + COFF_ES_SYMNMLEN); + snamebuf[COFF_ES_SYMNMLEN] = '\0'; + fsymname = snamebuf; + } + else{ + fsymname = syment->e.e_name ; + } + fsymnamesize = strlen(fsymname) + 1; + +#ifdef DEBUG + printf("%s\n",fsymname ); +#endif + } + else{ + memcpy(&soff, syment->e.e.e_offset, sizeof(long)); + fsymname = &mappedfile[extrstroff+soff]; + fsymnamesize = strlen(fsymname) + 1; + +#ifdef DEBUG + printf("*%s\n",fsymname ); +#endif + } + + while (symnamesize < fsymnamesize + 1) { + symnamesize *= 2; + if ((symname = realloc(symname, symnamesize)) == NULL){ + warn("malloc"); + punt(); + } + } +#if 0 + strcpy(symname, "_"); + strcat(symname, fsymname); +#else + strcpy(symname, fsymname); +#endif + + key.data = symname; + key.size = strlen((char *)key.data); + + /* + * Convert the symbol information into an nlist structure, + * as best we can. + */ + memcpy(&val, syment->e_value, sizeof( long )); + nbuf.n_value = val; + nbuf.n_type = N_EXT; /* XXX */ + nbuf.n_desc = 0; /* XXX */ + nbuf.n_other = 0; /* XXX */ + + /* + * Enter the symbol into the database. + */ + if (db->put(db, &key, &data, 0)) { + warn("record enter"); + punt(); + } + /* + * If it's the kernel version string, we've gotta keep + * some extra data around. Under a seperate key, + * we enter the first line (i.e. up to the first newline, + * with the newline replaced by a NUL to terminate the + * entered string) of the version string. + */ + if (strcmp((char *)key.data, VRS_SYM) == 0) { + unsigned long vma; + char *tmpcp; + struct coff_scnhdr *sh; + int i; + + key.data = (u_char *)VRS_KEY; + key.size = sizeof(VRS_KEY) - 1; + + /* Find the version string, relative to start */ + vma = nbuf.n_value; + +#ifdef DEBUG + printf("vma = %lx,tstart = %lx, dstart=%lx\n", + vma, aouthdrp->a_tstart, + aouthdrp->a_dstart); + printf("tsize = %lx, dsize=%lx\n", + aouthdrp->a_tsize, + aouthdrp->a_dsize); +#endif + if (aouthdrp->a_tstart <= vma && + vma < (aouthdrp->a_tstart + aouthdrp->a_tsize)){ + for(i=0;if_nscns;i++){ + sh = (struct coff_scnhdr *) + &mappedfile[COFF_HDR_SIZE+ + i*sizeof(struct + coff_scnhdr)]; + if( sh->s_flags == COFF_STYP_TEXT ){ + break; + } + } + vma = vma - sh->s_vaddr + sh->s_scnptr; + } + else if (aouthdrp->a_dstart <= vma && + vma < (aouthdrp->a_dstart + aouthdrp->a_dsize)){ + for(i=0;if_nscns;i++){ + sh = (struct coff_scnhdr *) + &mappedfile[COFF_HDR_SIZE+ + i*sizeof(struct + coff_scnhdr)]; + if( sh->s_flags == COFF_STYP_DATA ){ + break; + } + } + vma = vma - sh->s_vaddr + sh->s_scnptr; + } + else { + warn("version string neither text nor data"); + punt(); + } + data.data = strdup(&mappedfile[vma]); + +#ifdef DEBUG + printf("vma = %lx,version = %s\n", + vma, (char *)data.data); +#endif + + /* assumes newline terminates version. */ + if ((tmpcp = strchr(data.data, '\n')) != NULL) + *tmpcp = '\0'; + data.size = strlen((char *)data.data); + + if (db->put(db, &key, &data, 0)) { + warn("record enter"); + punt(); + } + + /* free pointer created by strdup(). */ + free(data.data); + + /* Restore to original values */ + data.data = (u_char *)&nbuf; + data.size = sizeof(nbuf); + } + } /* End of for() */ + + rv = 0; + +unmap: + munmap(mappedfile, mappedsize); +out: + return (rv); +} + +#endif /* NLIST_COFF */ diff --git a/usr.sbin/mdsetimage/Makefile b/usr.sbin/mdsetimage/Makefile index f68ed7d5453b..f0dd80f0c660 100644 --- a/usr.sbin/mdsetimage/Makefile +++ b/usr.sbin/mdsetimage/Makefile @@ -1,7 +1,8 @@ -# $NetBSD: Makefile,v 1.2 1997/01/02 00:33:34 pk Exp $ +# $NetBSD: Makefile,v 1.3 1999/09/12 16:08:13 itojun Exp $ PROG= mdsetimage -SRCS= mdsetimage.c exec_aout.c exec_ecoff.c exec_elf32.c exec_elf64.c +SRCS= mdsetimage.c exec_aout.c exec_ecoff.c exec_elf32.c exec_elf64.c \ + exec_coff.c MAN= mdsetimage.8 .include diff --git a/usr.sbin/mdsetimage/exec_coff.c b/usr.sbin/mdsetimage/exec_coff.c new file mode 100644 index 000000000000..a23e49831c53 --- /dev/null +++ b/usr.sbin/mdsetimage/exec_coff.c @@ -0,0 +1,108 @@ +/* $NetBSD: exec_coff.c,v 1.1 1999/09/12 16:08:14 itojun Exp $ */ + +/* + * Copyright (c) 1996 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. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by Christopher G. Demetriou + * for the NetBSD Project. + * 4. 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. + */ + +#include +#ifndef lint +__RCSID("$NetBSD: exec_coff.c,v 1.1 1999/09/12 16:08:14 itojun Exp $"); +#endif /* not lint */ + +#include +#include +#include +#include +#include +#include +#include "extern.h" + +#if defined(NLIST_COFF) +#include /* XXX sys/exec_coff.h? */ + +#define check(off, size) ((off < 0) || (off + size > mappedsize)) +#define BAD do { rv = -1; goto out; } while (0) + +int +check_coff(mappedfile, mappedsize) + const char *mappedfile; + size_t mappedsize; +{ + struct coff_exechdr *exechdrp; + int rv; + + rv = 0; + + if (check(0, sizeof *exechdrp)) + BAD; + exechdrp = (struct coff_exechdr *)&mappedfile[0]; + + if (COFF_BADMAG(&(exechdrp->f))) + BAD; + +out: + return (rv); +} + +int +findoff_coff(mappedfile, mappedsize, vmaddr, fileoffp) + const char *mappedfile; + size_t mappedsize, *fileoffp; + u_long vmaddr; +{ + struct coff_exechdr *exechdrp; + int rv; + + rv = 0; + exechdrp = (struct coff_exechdr *)&mappedfile[0]; + +#define COFF_TXTOFF_XXX(fp, ap) \ + (COFF_ROUND(COFF_HDR_SIZE + (fp)->f_nscns * \ + sizeof(struct coff_scnhdr), \ + COFF_SEGMENT_ALIGNMENT(fp, ap))) + +#define COFF_DATOFF_XXX(fp, ap) \ + (COFF_TXTOFF_XXX(fp, ap) + (ap)->a_tsize) + + if (exechdrp->a.a_tstart <= vmaddr && + vmaddr < (exechdrp->a.a_tstart + exechdrp->a.a_tsize)) + *fileoffp = vmaddr - exechdrp->a.a_tstart + + COFF_TXTOFF(&exechdrp->f, &(exechdrp->a)); + else if (exechdrp->a.a_dstart <= vmaddr && + vmaddr < (exechdrp->a.a_dstart + exechdrp->a.a_dsize)) + *fileoffp = vmaddr - exechdrp->a.a_dstart + + COFF_DATOFF_XXX(&exechdrp->f, &(exechdrp->a)); + else + BAD; + +out: + return (rv); +} + +#endif /* NLIST_COFF */ diff --git a/usr.sbin/mdsetimage/extern.h b/usr.sbin/mdsetimage/extern.h index 263de91a248a..558d4ed9ea3e 100644 --- a/usr.sbin/mdsetimage/extern.h +++ b/usr.sbin/mdsetimage/extern.h @@ -1,4 +1,4 @@ -/* $NetBSD: extern.h,v 1.4 1999/03/03 12:26:07 christos Exp $ */ +/* $NetBSD: extern.h,v 1.5 1999/09/12 16:08:14 itojun Exp $ */ /* * Copyright (c) 1996 Christopher G. Demetriou. All rights reserved. @@ -42,11 +42,15 @@ #elif defined(__i386__) || defined(__sparc__) # define NLIST_ELF32 # define NLIST_AOUT +#elif defined(__sh3__) +# define NLIST_COFF +# define NLIST_ELF32 #else # define NLIST_AOUT /* #define NLIST_ECOFF */ /* #define NLIST_ELF32 */ /* #define NLIST_ELF64 */ +/* #define NLIST_COFF */ #endif #ifdef NLIST_AOUT @@ -65,3 +69,7 @@ int findoff_elf32 __P((const char *, size_t, u_long, size_t *)); int check_elf64 __P((const char *, size_t)); int findoff_elf64 __P((const char *, size_t, u_long, size_t *)); #endif +#ifdef NLIST_COFF +int check_coff __P((const char *, size_t)); +int findoff_coff __P((const char *, size_t, u_long, size_t *)); +#endif diff --git a/usr.sbin/mdsetimage/mdsetimage.c b/usr.sbin/mdsetimage/mdsetimage.c index fb2be79dc3d9..bcdf3aa2536c 100644 --- a/usr.sbin/mdsetimage/mdsetimage.c +++ b/usr.sbin/mdsetimage/mdsetimage.c @@ -1,4 +1,4 @@ -/* $NetBSD: mdsetimage.c,v 1.7 1998/08/27 18:03:44 ross Exp $ */ +/* $NetBSD: mdsetimage.c,v 1.8 1999/09/12 16:08:14 itojun Exp $ */ /* * Copyright (c) 1996 Christopher G. Demetriou. All rights reserved. @@ -38,7 +38,7 @@ __COPYRIGHT( #endif /* not lint */ #ifndef lint -__RCSID("$NetBSD: mdsetimage.c,v 1.7 1998/08/27 18:03:44 ross Exp $"); +__RCSID("$NetBSD: mdsetimage.c,v 1.8 1999/09/12 16:08:14 itojun Exp $"); #endif /* not lint */ #include @@ -198,6 +198,9 @@ struct { #ifdef NLIST_ELF64 { "ELF64", check_elf64, findoff_elf64, }, #endif +#ifdef NLIST_COFF + { "COFF", check_coff, findoff_coff, }, +#endif }; static int