Subject: Re: kern/29133: Fault in Kernelfunction findsym
To: None <gnats-bugs@netbsd.org>
From: Quentin Garnier <cube@cubidou.net>
List: netbsd-bugs
Date: 01/27/2005 22:16:39
--rdeY6f/ml8+xnc5C
Content-Type: multipart/mixed; boundary="YGQsgxOP0v8GKjPA"
Content-Disposition: inline


--YGQsgxOP0v8GKjPA
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline
Content-Transfer-Encoding: quoted-printable

On Thu, Jan 27, 2005 at 01:54:00PM +0000, kessi@teles.de wrote:
> >Number:         29133
> >Category:       kern
> >Synopsis:       Fault in Kernelfunction findsym

Please try the attached patch.

--=20
Quentin Garnier - cube@cubidou.net - cube@NetBSD.org
"Commala-come-five! / Even when the shadows rise!
To see the world and walk the world / Makes ya glad to be alive."
Susannah's Song, The Dark Tower VI, Stephen King, 2004.

--YGQsgxOP0v8GKjPA
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment; filename="29133.-2-0.diff"
Content-Transfer-Encoding: quoted-printable

Index: ddb/db_sym.c
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
RCS file: /cvsroot/src/sys/ddb/db_sym.c,v
retrieving revision 1.45
diff -u -r1.45 db_sym.c
--- ddb/db_sym.c	17 Nov 2003 10:16:18 -0000	1.45
+++ ddb/db_sym.c	27 Jan 2005 21:13:42 -0000
@@ -109,12 +109,12 @@
 	}
 #endif
 	db_symsplit(name, &mod, &sym);
-	if (ksyms_getval_from_kernel(mod, sym, &uval, KSYMS_EXTERN) =3D=3D 0) {
+	if (ksyms_getval(mod, sym, &uval, KSYMS_EXTERN) =3D=3D 0) {
 		val =3D (long) uval;
 		*valuep =3D (db_expr_t)val;
 		return TRUE;
 	}
-	if (ksyms_getval_from_kernel(mod, sym, &uval, KSYMS_ANY) =3D=3D 0) {
+	if (ksyms_getval(mod, sym, &uval, KSYMS_ANY) =3D=3D 0) {
 		val =3D (long) uval;
 		*valuep =3D (db_expr_t)val;
 		return TRUE;
@@ -229,7 +229,7 @@
 #endif
=20
 	if (ksyms_getname(&mod, &sym, (vaddr_t)val, strategy) =3D=3D 0) {
-		(void)ksyms_getval_from_kernel(mod, sym, &naddr, KSYMS_ANY);
+		(void)ksyms_getval(mod, sym, &naddr, KSYMS_ANY);
 		diff =3D val - (db_addr_t)naddr;
 		ret =3D (db_sym_t)naddr;
 	} else
@@ -337,7 +337,7 @@
 #endif
 	if (ksyms_getname(&mod, &name, (vaddr_t)off,
 	    strategy|KSYMS_CLOSEST) =3D=3D 0) {
-		(void)ksyms_getval_from_kernel(mod, name, &val, KSYMS_ANY);
+		(void)ksyms_getval(mod, name, &val, KSYMS_ANY);
 		if (((off - val) < db_maxoff) && val) {
 			sprintf(buf, "%s:%s", mod, name);
 			if (off - val) {
@@ -407,7 +407,7 @@
 #endif
 	if (ksyms_getname(&mod, &name, (vaddr_t)off,
 	    strategy|KSYMS_CLOSEST) =3D=3D 0) {
-		(void)ksyms_getval_from_kernel(mod, name, &uval, KSYMS_ANY);
+		(void)ksyms_getval(mod, name, &uval, KSYMS_ANY);
 		val =3D (long) uval;
 		if (((off - val) < db_maxoff) && val) {
 			(*pr)("%s:%s", mod, name);
Index: kern/kern_ksyms.c
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
RCS file: /cvsroot/src/sys/kern/kern_ksyms.c,v
retrieving revision 1.21
diff -u -r1.21 kern_ksyms.c
--- kern/kern_ksyms.c	19 Feb 2004 03:42:01 -0000	1.21
+++ kern/kern_ksyms.c	27 Jan 2005 21:13:42 -0000
@@ -269,12 +269,12 @@
  * Finds a certain symbol name in a certain symbol table.
  */
 static Elf_Sym *
-findsym(char *name, struct symtab *table, int userreq)
+findsym(char *name, struct symtab *table)
 {
 	Elf_Sym *start =3D table->sd_symstart;
 	int i, sz =3D table->sd_symsize/sizeof(Elf_Sym);
 	char *np;
-	caddr_t realstart =3D table->sd_strstart - (userreq ? 0 : table->sd_usrof=
fset);
+	caddr_t realstart =3D table->sd_strstart - table->sd_usroffset;
=20
 #ifdef USE_PTREE
 	if (table =3D=3D &kernel_symtab && (i =3D ptree_find(name)) !=3D 0)
@@ -497,7 +497,7 @@
  * Returns 0 if success or ENOENT if no such entry.
  */
 int
-ksyms_getval(const char *mod, char *sym, unsigned long *val, int type, int=
 userreq)
+ksyms_getval(const char *mod, char *sym, unsigned long *val, int type)
 {
 	struct symtab *st;
 	Elf_Sym *es;
@@ -513,7 +513,7 @@
 	CIRCLEQ_FOREACH(st, &symtab_queue, sd_queue) {
 		if (mod && strcmp(st->sd_name, mod))
 			continue;
-		if ((es =3D findsym(sym, st, userreq)) =3D=3D NULL)
+		if ((es =3D findsym(sym, st)) =3D=3D NULL)
 			continue;
=20
 		/* Skip if bad binding */
@@ -583,6 +583,17 @@
 #if NKSYMS
 static int symsz, strsz;
=20
+/*
+ * In case we exposing the symbol table to the userland using the pseudo-
+ * device /dev/ksyms, it is easier to provide all the tables as one.
+ * However, it means we have to change all the st_name fields for the
+ * symbols so they match the ELF image that the userland will read
+ * through the device.
+ *
+ * The actual (correct) value of st_name is preserved through a global
+ * offset stored in the symbol table structure.
+ */
+
 static void
 ksyms_sizes_calc(void)
 {              =20
@@ -732,8 +743,7 @@
 			continue;
 		=09
 		/* Check if the symbol exists */
-		if (ksyms_getval_from_kernel(NULL, symname,
-		    &rval, KSYMS_EXTERN) =3D=3D 0) {
+		if (ksyms_getval(NULL, symname, &rval, KSYMS_EXTERN) =3D=3D 0) {
 			/* Check (and complain) about differing values */
 			if (sym[i].st_value !=3D rval) {
 				if (specialsym(symname)) {
@@ -777,8 +787,7 @@
 			continue;
 		=09
 		/* Check if the symbol exists */
-		if (ksyms_getval_from_kernel(NULL, symname,
-		    &rval, KSYMS_EXTERN) =3D=3D 0) {
+		if (ksyms_getval(NULL, symname, &rval, KSYMS_EXTERN) =3D=3D 0) {
 			if ((sym[i].st_value !=3D rval) && specialsym(symname)) {
 				addsym(&info, &sym[i], symname, mod);
 			}
@@ -1135,7 +1144,7 @@
 		 */
 		if ((error =3D copyinstr(kg->kg_name, str, ksyms_maxlen, NULL)))
 			break;
-		if ((error =3D ksyms_getval_from_userland(NULL, str, &val, KSYMS_EXTERN)=
))
+		if ((error =3D ksyms_getval(NULL, str, &val, KSYMS_EXTERN)))
 			break;
 		error =3D copyout(&val, kg->kg_value, sizeof(long));
 		break;
@@ -1148,7 +1157,7 @@
 		if ((error =3D copyinstr(kg->kg_name, str, ksyms_maxlen, NULL)))
 			break;
 		CIRCLEQ_FOREACH(st, &symtab_queue, sd_queue) {
-			if ((sym =3D findsym(str, st, 1)) =3D=3D NULL) /* from userland */
+			if ((sym =3D findsym(str, st)) =3D=3D NULL) /* from userland */
 				continue;
=20
 			/* Skip if bad binding */
@@ -1158,6 +1167,12 @@
 			}
 			break;
 		}
+		/*
+		 * XXX which value of sym->st_name should be returned?  The real
+		 * one, or the one that matches what reading /dev/ksyms get?
+		 *
+		 * Currently, we're returning the /dev/ksyms one.
+		 */
 		if (sym !=3D NULL)
 			error =3D copyout(sym, kg->kg_sym, sizeof(Elf_Sym));
 		else
Index: kern/kern_sysctl.c
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
RCS file: /cvsroot/src/sys/kern/kern_sysctl.c,v
retrieving revision 1.169.2.6
diff -u -r1.169.2.6 kern_sysctl.c
--- kern/kern_sysctl.c	14 May 2004 06:18:39 -0000	1.169.2.6
+++ kern/kern_sysctl.c	27 Jan 2005 21:13:44 -0000
@@ -1006,8 +1006,8 @@
 					    sizeof(symname), &symlen);
 					if (error)
 						return (error);
-					error =3D ksyms_getval_from_kernel(NULL,
-					    symname, &symaddr, KSYMS_EXTERN);
+					error =3D ksyms_getval(NULL, symname,
+					    &symaddr, KSYMS_EXTERN);
 					if (error)
 						return (error); /* EINVAL? */
 					nnode.sysctl_data =3D (void*)symaddr;
Index: sys/ksyms.h
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
RCS file: /cvsroot/src/sys/sys/ksyms.h,v
retrieving revision 1.8
diff -u -r1.8 ksyms.h
--- sys/ksyms.h	17 Nov 2003 10:16:18 -0000	1.8
+++ sys/ksyms.h	27 Jan 2005 21:13:44 -0000
@@ -60,9 +60,7 @@
  * Prototypes
  */
 int ksyms_getname(const char **, char **, vaddr_t, int);
-int ksyms_getval(const char *, char *, unsigned long *, int, int);
-#define	ksyms_getval_from_kernel(a,b,c,d)	ksyms_getval(a,b,c,d,0)
-#define	ksyms_getval_from_userland(a,b,c,d)	ksyms_getval(a,b,c,d,1)
+int ksyms_getval(const char *, char *, unsigned long *, int);
 int ksyms_addsymtab(const char *, void *, vsize_t, char *, vsize_t);
 int ksyms_delsymtab(const char *);
 int ksyms_rensymtab(const char *, const char*);

--YGQsgxOP0v8GKjPA--

--rdeY6f/ml8+xnc5C
Content-Type: application/pgp-signature
Content-Disposition: inline

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.2.6 (NetBSD)

iQEVAwUBQflaN9goQloHrPnoAQLJBwgAiGwphIKd57N0BrlbSTetZ43oQzikMkRn
SeccfI+TuirR+vuXhWJKgGJMzVBMtJZxM+hdFH4wPbG5yYleipW/ymMjTQm1tShZ
rXy+FzoMjeOLLcqh33wZ9R22IC1jfITA+fQphf+GPqpOXoJukAU8VBwBP5AIjcZr
VQgk2uQysii/YkJMzCc/Fh+tr1rClt//CRQYEbnQL3ZqA/MWk9RLZkhQUuINo68b
n/4pktWMRQZy5nKHQvcAzubO2zoTvhzppANmR1o9eB2s/PohETW/aM7w3Wn4N4ZI
JkvGQcP60NCRkaQ9WqpN0ZZAZBH16IgNIoIF1H6ssI2ifJlI01yRyQ==
=utis
-----END PGP SIGNATURE-----

--rdeY6f/ml8+xnc5C--