Subject: Re: kern/29133: Fault in Kernelfunction findsym
To: None <cube@netbsd.org, gnats-admin@netbsd.org, netbsd-bugs@netbsd.org>
From: Quentin Garnier <cube@cubidou.net>
List: netbsd-bugs
Date: 01/27/2005 21:17:01
The following reply was made to PR kern/29133; it has been noted by GNATS.

From: Quentin Garnier <cube@cubidou.net>
To: gnats-bugs@netbsd.org
Cc: kern-bug-people@netbsd.org, gnats-admin@netbsd.org,
	netbsd-bugs@netbsd.org
Subject: Re: kern/29133: Fault in Kernelfunction findsym
Date: Thu, 27 Jan 2005 22:16:39 +0100

 --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--