Date: Tue, 29 Feb 2000 22:41:17 -0700
From: "Todd C. Miller" <Todd.Miller@courtesan.com>
To: Jim Rees <rees@umich.edu>
Message-Id: <200003010541.WAA31322@xerxes.courtesan.com>
Subject: Re: ddb and lkm 
In-reply-to: Your message of "Wed, 01 Mar 2000 00:35:53 EST."
             <200003010536.WAA15919@xerxes.courtesan.com> 
References: <200003010536.WAA15919@xerxes.courtesan.com> 

In message <200003010536.WAA15919@xerxes.courtesan.com>
	so spake Jim Rees (rees):

> Please send patches.  I'd love to test.

Hmm, didn't I send them earlier this eve?  If not, here they
are.  It's important to use the correct modload and kernel
combo :-)

 - todd

Index: sbin/modload/modload.c
===================================================================
RCS file: /cvs/src/sbin/modload/modload.c,v
retrieving revision 1.20
diff -u -r1.20 modload.c
--- sbin/modload/modload.c	1999/08/17 09:13:14	1.20
+++ sbin/modload/modload.c	2000/03/01 03:16:11
@@ -195,7 +195,6 @@
 	struct lmc_loadbuf ldbuf;
 	int sz, bytesleft, old = 0;
 	char buf[MODIOBUF];
-	char *symbuf;
 
 	while ((c = getopt(argc, argv, "dvsuqA:e:p:o:")) != -1) {
 		switch (c) {
@@ -397,7 +396,8 @@
 	    bytesleft > 0;
 	    bytesleft -= sz) {
 		sz = min(bytesleft, MODIOBUF);
-		read(modfd, buf, sz);
+		if (read(modfd, buf, sz) != sz)
+			err(14, "read");
 		ldbuf.cnt = sz;
 		ldbuf.data = buf;
 		if (ioctl(devfd, LMLOADBUF, &ldbuf) == -1)
@@ -412,54 +412,29 @@
 		err(12, "lseek");
 
 	    /*
-	     * Transfer the symbol table entries.  First, read them all in,
-	     * then adjust their string table pointers, then
-	     * copy in bulk.  Then copy the string table itself.
+	     * Read and load the symbol table entries.
 	     */
-
-	    symbuf = malloc(info_buf.a_syms);
-	    if (symbuf == 0)
-		err(13, "malloc");
-
-	    if (read(modfd, symbuf, info_buf.a_syms) != info_buf.a_syms)
-		err(14, "read");
-	    numsyms = info_buf.a_syms / sizeof(struct nlist);
-	    for (nlp = (struct nlist *)symbuf; 
-		 (char *)nlp < symbuf + info_buf.a_syms;
-		 nlp++) {
-		register int strx;
-		strx = nlp->n_un.n_strx;
-		if (strx != 0) {
-		    /* If a valid name, set the name ptr to point at the
-		     * loaded address for the string in the string table.
-		     */
-		    if (strx > strtablen)
-			nlp->n_un.n_name = 0;
-		    else
-			nlp->n_un.n_name =
-			    (char *)(strx + resrv.sym_addr + info_buf.a_syms);
-		}
-	    }
-	    /*
-	     * we've fixed the symbol table entries, now load them
-	     */
 	    for (bytesleft = info_buf.a_syms;
 		 bytesleft > 0;
 		 bytesleft -= sz) {
 		sz = min(bytesleft, MODIOBUF);
+		if (read(modfd, buf, sz) != sz)
+			err(14, "read");
 		ldbuf.cnt = sz;
-		ldbuf.data = symbuf;
+		ldbuf.data = buf;
 		if (ioctl(devfd, LMLOADSYMS, &ldbuf) == -1)
 		    err(11, "error transferring sym buffer");
-		symbuf += sz;
 	    }
-	    free(symbuf - info_buf.a_syms);
-	    /* and now read the string table and load it. */
+
+	    /*
+	     * Read the string table and load it.
+	     */
 	    for (bytesleft = strtablen;
 		 bytesleft > 0;
 		 bytesleft -= sz) {
 		sz = min(bytesleft, MODIOBUF);
-		read(modfd, buf, sz);
+		if (read(modfd, buf, sz) != sz)
+			err(14, "read");
 		ldbuf.cnt = sz;
 		ldbuf.data = buf;
 		if (ioctl(devfd, LMLOADSYMS, &ldbuf) == -1)
Index: sys/arch/i386/i386/db_trace.c
===================================================================
RCS file: /cvs/src/sys/arch/i386/i386/db_trace.c,v
retrieving revision 1.4
diff -u -r1.4 db_trace.c
--- sys/arch/i386/i386/db_trace.c	1997/03/21 02:10:42	1.4
+++ sys/arch/i386/i386/db_trace.c	2000/03/01 02:20:32
@@ -230,7 +230,7 @@
 		char	*argnames[MAXNARG], **argnp = NULL;
 
 		sym = db_search_symbol(callpc, DB_STGY_ANY, &offset);
-		db_symbol_values(sym, &name, NULL);
+		db_symbol_values(db_last_symtab, sym, &name, NULL);
 
 		if (lastframe == 0 && sym == NULL) {
 			/* Symbol not found, peek at code */
Index: sys/ddb/db_aout.c
===================================================================
RCS file: /cvs/src/sys/ddb/db_aout.c,v
retrieving revision 1.24
diff -u -r1.24 db_aout.c
--- sys/ddb/db_aout.c	1999/09/11 00:44:59	1.24
+++ sys/ddb/db_aout.c	2000/03/01 03:15:28
@@ -68,9 +68,9 @@
 static int slen;
 
 #ifdef	SYMTAB_SPACE
-#define X_db_getname(s)		(s->n_un.n_name)
+#define X_db_getname(t, s)	(s->n_un.n_name)
 #else
-#define X_db_getname(s)	(s->n_un.n_strx > slen ? NULL : strtab + s->n_un.n_strx)
+#define X_db_getname(t, s)	(t->end + s->n_un.n_strx >= t->rend ? NULL : t->end + s->n_un.n_strx)
 #endif
 
 /*
@@ -164,7 +164,7 @@
 	ep = (struct nlist *)stab->end;
 
 	for (; sp < ep; sp++) {
-	    if ((n_name = X_db_getname(sp)) == 0)
+	    if ((n_name = X_db_getname(stab, sp)) == 0)
 		continue;
 	    if ((sp->n_type & N_STAB) == 0 && db_eqname(n_name, symstr, '_'))
 		return ((db_sym_t)sp);
@@ -188,7 +188,7 @@
 	ep = (struct nlist *)symtab->end;
 
 	for (; sp < ep; sp++) {
-	    if (X_db_getname(sp) == 0)
+	    if (X_db_getname(symtab, sp) == 0)
 		continue;
 	    if ((sp->n_type & N_STAB) != 0 || (sp->n_type & N_TYPE) == N_FN)
 		continue;
@@ -225,7 +225,8 @@
  * Return the name and value for a symbol.
  */
 void
-X_db_symbol_values(sym, namep, valuep)
+X_db_symbol_values(stab, sym, namep, valuep)
+	db_symtab_t	stab;
 	db_sym_t	sym;
 	char		**namep;
 	db_expr_t	*valuep;
@@ -235,7 +236,7 @@
 	if ((sp = (struct nlist *)sym) == NULL)
 	    return;
 	if (namep)
-	    *namep = X_db_getname(sp);
+	    *namep = X_db_getname(stab, sp);
 	if (valuep)
 	    *valuep = sp->n_value;
 }
@@ -268,19 +269,20 @@
 	     */
 #if 0
 	    if (sp->n_value <= off && (off - sp->n_value) <= sodiff &&
-		NEWSRC(X_db_getname(sp))) {
+		NEWSRC(X_db_getname(symtab, sp))) {
 #endif
-	    if ((sp->n_type & N_TYPE) == N_FN || NEWSRC(X_db_getname(sp))) {
-		sodiff = lndiff = -1UL;
-		ln = 0;
-		fname = NULL;
+	    if ((sp->n_type & N_TYPE) == N_FN ||
+		NEWSRC(X_db_getname(symtab, sp))) {
+		    sodiff = lndiff = -1UL;
+		    ln = 0;
+		    fname = NULL;
 	    }
 
 	    if (sp->n_type == N_SO) {
 		if ((db_expr_t)sp->n_value <= off &&
 		    (off - sp->n_value) < sodiff) {
 			sodiff = off - sp->n_value;
-			fname = X_db_getname(sp);
+			fname = X_db_getname(symtab, sp);
 		}
 		continue;
 	    }
@@ -331,7 +333,7 @@
 			if (nargs >= maxnarg)
 				break;
 			nargs++;
-			n_name = X_db_getname(sp);
+			n_name = X_db_getname(symtab, sp);
 			*argnamep++ = n_name ? n_name : "???";
 			{
 			/* XXX - remove trailers */
Index: sys/ddb/db_extern.h
===================================================================
RCS file: /cvs/src/sys/ddb/db_extern.h,v
retrieving revision 1.9
diff -u -r1.9 db_extern.h
--- sys/ddb/db_extern.h	1997/07/08 10:48:32	1.9
+++ sys/ddb/db_extern.h	2000/03/01 01:45:21
@@ -39,7 +39,7 @@
 db_sym_t X_db_lookup __P((db_symtab_t, char *));
 db_sym_t X_db_search_symbol __P((db_symtab_t, db_addr_t, db_strategy_t,
 				 db_expr_t *));
-void X_db_symbol_values __P((db_sym_t, char **, db_expr_t *));
+void X_db_symbol_values __P((db_symtab_t, db_sym_t, char **, db_expr_t *));
 void db_printsym __P((db_expr_t, db_strategy_t));
 boolean_t X_db_line_at_pc __P((db_symtab_t, db_sym_t, char **,
 			       int *, db_expr_t));
Index: sys/ddb/db_hangman.c
===================================================================
RCS file: /cvs/src/sys/ddb/db_hangman.c,v
retrieving revision 1.13
diff -u -r1.13 db_hangman.c
--- sys/ddb/db_hangman.c	1998/04/26 21:40:50	1.13
+++ sys/ddb/db_hangman.c	2000/03/01 02:17:31
@@ -79,7 +79,7 @@
 	register db_symtab_t	stab = db_istab(db_random(db_nsymtabs));
 
 		/* choose random symbol from the table */
-	q = db_qualify(X_db_isym(stab, db_random(X_db_nsyms(stab))),stab->name);
+	q = db_qualify(stab, X_db_isym(stab, db_random(X_db_nsyms(stab))));
 
 		/* don't show symtab name if there are less than 3 of 'em */
 	if (db_nsymtabs < 3)
Index: sys/ddb/db_sym.c
===================================================================
RCS file: /cvs/src/sys/ddb/db_sym.c,v
retrieving revision 1.21
diff -u -r1.21 db_sym.c
--- sys/ddb/db_sym.c	1997/07/19 22:31:20	1.21
+++ sys/ddb/db_sym.c	2000/03/01 02:16:15
@@ -140,15 +140,17 @@
  *  overwritten by each call... but in practice this seems okay.
  */
 char *
-db_qualify(sym, symtabname)
+db_qualify(stab, sym)
+	db_symtab_t	stab;
 	db_sym_t	sym;
-	register char	*symtabname;
 {
 	char		*symname;
+	char		*symtabname;
 	static char     tmp[256];
 	register char	*s;
 
-	db_symbol_values(sym, &symname, 0);
+	symtabname = stab->name;
+	db_symbol_values(stab, sym, &symname, 0);
 	s = tmp;
 	while ((*s++ = *symtabname++) != '\0')
 		;
@@ -183,7 +185,7 @@
 	sym = db_lookup(name);
 	if (sym == DB_SYM_NULL)
 	    return (FALSE);
-	db_symbol_values(sym, &name, valuep);
+	db_symbol_values(db_last_symtab, sym, &name, valuep);
 	return (TRUE);
 }
 
@@ -256,8 +258,8 @@
 	if (!db_qualify_ambiguous_names)
 		return FALSE;
 
-	db_symbol_values(sym, &sym_name, 0);
 	for (st = db_symiter(NULL); st != NULL; st = db_symiter(st)) {
+		X_db_symbol_values(st, sym, &sym_name, NULL);
 		if (X_db_lookup(st, sym_name) != NULL) {
 			if (found_once)
 				return TRUE;
@@ -301,7 +303,8 @@
  * Return name and value of a symbol
  */
 void
-db_symbol_values(sym, namep, valuep)
+db_symbol_values(stab, sym, namep, valuep)
+	db_symtab_t	stab;
 	db_sym_t	sym;
 	char		**namep;
 	db_expr_t	*valuep;
@@ -313,10 +316,10 @@
 		return;
 	}
 
-	X_db_symbol_values(sym, namep, &value);
+	X_db_symbol_values(stab, sym, namep, &value);
 
 	if (db_symbol_is_ambiguous(sym))
-		*namep = db_qualify(sym, db_last_symtab->name);
+		*namep = db_qualify(db_last_symtab, sym);
 	if (valuep)
 		*valuep = value;
 }
@@ -359,7 +362,7 @@
 
 	if ((u_long)off <= db_lastsym) {
 		cursym = db_search_symbol(off, strategy, &d);
-		db_symbol_values(cursym, &name, &value);
+		db_symbol_values(db_last_symtab, cursym, &name, &value);
 		if (name && (d < db_maxoff) && value) {
 			db_printf("%s", name);
 			if (d)
Index: sys/ddb/db_sym.h
===================================================================
RCS file: /cvs/src/sys/ddb/db_sym.h,v
retrieving revision 1.11
diff -u -r1.11 db_sym.h
--- sys/ddb/db_sym.h	1997/05/29 03:28:45	1.11
+++ sys/ddb/db_sym.h	2000/03/01 02:04:17
@@ -98,22 +98,24 @@
 
 db_sym_t db_lookup __P((char *));
 
-char *db_qualify __P((db_sym_t, char *));
+char *db_qualify __P((db_symtab_t, db_sym_t));
 
 boolean_t db_symbol_is_ambiguous __P((db_sym_t));
 
 db_sym_t db_search_symbol __P((db_addr_t, db_strategy_t, db_expr_t *));
 					/* find symbol given value */
 
-void db_symbol_values __P((db_sym_t, char **, db_expr_t *));
+void db_symbol_values __P((db_symtab_t, db_sym_t, char **, db_expr_t *));
 					/* return name and value of symbol */
 
 #define db_find_sym_and_offset(val,namep,offp)	\
-	db_symbol_values(db_search_symbol(val,DB_STGY_ANY,offp),namep,0)
+	db_symbol_values(db_last_symtab,	\
+		db_search_symbol(val,DB_STGY_ANY,offp),namep,0)
 					/* find name&value given approx val */
 
 #define db_find_xtrn_sym_and_offset(val,namep,offp)	\
-	db_symbol_values(db_search_symbol(val,DB_STGY_XTRN,offp),namep,0)
+	db_symbol_values(db_last_symtab,		\
+		db_search_symbol(val,DB_STGY_XTRN,offp),namep,0)
 					/* ditto, but no locals */
 
 void db_printsym __P((db_expr_t, db_strategy_t));



