Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys The way I handled /dev/ksyms requests vs. kernel request...



details:   https://anonhg.NetBSD.org/src/rev/c165a519f092
branches:  trunk
changeset: 573935:c165a519f092
user:      cube <cube%NetBSD.org@localhost>
date:      Tue Feb 15 21:09:57 2005 +0000

description:
The way I handled /dev/ksyms requests vs. kernel requests was completely
broken.  Inside the kernel, we always have to use the real values of the
st_name fields, and only do the math when the request comes from userland.

No need for ksyms_getval_from{kernel,userland} hack anymore.  However, a
different version will be asked for pull-up in -2{,-0}, one that doesn't
break the API, that is.

Fixes PR#29133 from Jens Kessmeier.

diffstat:

 sys/ddb/db_sym.c      |  14 +++++++-------
 sys/kern/kern_ksyms.c |  39 +++++++++++++++++++++++++++------------
 sys/sys/ksyms.h       |   6 ++----
 3 files changed, 36 insertions(+), 23 deletions(-)

diffs (200 lines):

diff -r 2105759a5668 -r c165a519f092 sys/ddb/db_sym.c
--- a/sys/ddb/db_sym.c  Tue Feb 15 21:07:37 2005 +0000
+++ b/sys/ddb/db_sym.c  Tue Feb 15 21:09:57 2005 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: db_sym.c,v 1.47 2005/01/16 23:38:47 chs Exp $  */
+/*     $NetBSD: db_sym.c,v 1.48 2005/02/15 21:09:57 cube Exp $ */
 
 /*
  * Mach Operating System
@@ -27,7 +27,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: db_sym.c,v 1.47 2005/01/16 23:38:47 chs Exp $");
+__KERNEL_RCSID(0, "$NetBSD: db_sym.c,v 1.48 2005/02/15 21:09:57 cube Exp $");
 
 #include "opt_ddbparam.h"
 
@@ -109,12 +109,12 @@
        }
 #endif
        db_symsplit(name, &mod, &sym);
-       if (ksyms_getval_from_kernel(mod, sym, &uval, KSYMS_EXTERN) == 0) {
+       if (ksyms_getval(mod, sym, &uval, KSYMS_EXTERN) == 0) {
                val = (long) uval;
                *valuep = (db_expr_t)val;
                return TRUE;
        }
-       if (ksyms_getval_from_kernel(mod, sym, &uval, KSYMS_ANY) == 0) {
+       if (ksyms_getval(mod, sym, &uval, KSYMS_ANY) == 0) {
                val = (long) uval;
                *valuep = (db_expr_t)val;
                return TRUE;
@@ -229,7 +229,7 @@
 #endif
 
        if (ksyms_getname(&mod, &sym, (vaddr_t)val, strategy) == 0) {
-               (void)ksyms_getval_from_kernel(mod, sym, &naddr, KSYMS_ANY);
+               (void)ksyms_getval(mod, sym, &naddr, KSYMS_ANY);
                diff = val - (db_addr_t)naddr;
                ret = (db_sym_t)naddr;
        } else
@@ -338,7 +338,7 @@
 #endif
        if (ksyms_getname(&mod, &name, (vaddr_t)off,
            strategy|KSYMS_CLOSEST) == 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) {
                        snprintf(buf, buflen, "%s:%s", mod, name);
                        if (off - val) {
@@ -410,7 +410,7 @@
 #endif
        if (ksyms_getname(&mod, &name, (vaddr_t)off,
            strategy|KSYMS_CLOSEST) == 0) {
-               (void)ksyms_getval_from_kernel(mod, name, &uval, KSYMS_ANY);
+               (void)ksyms_getval(mod, name, &uval, KSYMS_ANY);
                val = (long) uval;
                if (((off - val) < db_maxoff) && val) {
                        (*pr)("%s:%s", mod, name);
diff -r 2105759a5668 -r c165a519f092 sys/kern/kern_ksyms.c
--- a/sys/kern/kern_ksyms.c     Tue Feb 15 21:07:37 2005 +0000
+++ b/sys/kern/kern_ksyms.c     Tue Feb 15 21:09:57 2005 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: kern_ksyms.c,v 1.21 2004/02/19 03:42:01 matt Exp $     */
+/*     $NetBSD: kern_ksyms.c,v 1.22 2005/02/15 21:09:57 cube Exp $     */
 /*
  * Copyright (c) 2001, 2003 Anders Magnusson (ragge%ludd.luth.se@localhost).
  * All rights reserved.
@@ -46,7 +46,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: kern_ksyms.c,v 1.21 2004/02/19 03:42:01 matt Exp $");
+__KERNEL_RCSID(0, "$NetBSD: kern_ksyms.c,v 1.22 2005/02/15 21:09:57 cube Exp $");
 
 #ifdef _KERNEL
 #include "opt_ddb.h"
@@ -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 = table->sd_symstart;
        int i, sz = table->sd_symsize/sizeof(Elf_Sym);
        char *np;
-       caddr_t realstart = table->sd_strstart - (userreq ? 0 : table->sd_usroffset);
+       caddr_t realstart = table->sd_strstart - table->sd_usroffset;
 
 #ifdef USE_PTREE
        if (table == &kernel_symtab && (i = ptree_find(name)) != 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 = findsym(sym, st, userreq)) == NULL)
+               if ((es = findsym(sym, st)) == NULL)
                        continue;
 
                /* Skip if bad binding */
@@ -583,6 +583,17 @@
 #if NKSYMS
 static int symsz, strsz;
 
+/*
+ * 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)
 {               
@@ -732,8 +743,7 @@
                        continue;
                        
                /* Check if the symbol exists */
-               if (ksyms_getval_from_kernel(NULL, symname,
-                   &rval, KSYMS_EXTERN) == 0) {
+               if (ksyms_getval(NULL, symname, &rval, KSYMS_EXTERN) == 0) {
                        /* Check (and complain) about differing values */
                        if (sym[i].st_value != rval) {
                                if (specialsym(symname)) {
@@ -777,8 +787,7 @@
                        continue;
                        
                /* Check if the symbol exists */
-               if (ksyms_getval_from_kernel(NULL, symname,
-                   &rval, KSYMS_EXTERN) == 0) {
+               if (ksyms_getval(NULL, symname, &rval, KSYMS_EXTERN) == 0) {
                        if ((sym[i].st_value != rval) && specialsym(symname)) {
                                addsym(&info, &sym[i], symname, mod);
                        }
@@ -1135,7 +1144,7 @@
                 */
                if ((error = copyinstr(kg->kg_name, str, ksyms_maxlen, NULL)))
                        break;
-               if ((error = ksyms_getval_from_userland(NULL, str, &val, KSYMS_EXTERN)))
+               if ((error = ksyms_getval(NULL, str, &val, KSYMS_EXTERN)))
                        break;
                error = copyout(&val, kg->kg_value, sizeof(long));
                break;
@@ -1148,7 +1157,7 @@
                if ((error = copyinstr(kg->kg_name, str, ksyms_maxlen, NULL)))
                        break;
                CIRCLEQ_FOREACH(st, &symtab_queue, sd_queue) {
-                       if ((sym = findsym(str, st, 1)) == NULL) /* from userland */
+                       if ((sym = findsym(str, st)) == NULL) /* from userland */
                                continue;
 
                        /* 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 != NULL)
                        error = copyout(sym, kg->kg_sym, sizeof(Elf_Sym));
                else
diff -r 2105759a5668 -r c165a519f092 sys/sys/ksyms.h
--- a/sys/sys/ksyms.h   Tue Feb 15 21:07:37 2005 +0000
+++ b/sys/sys/ksyms.h   Tue Feb 15 21:09:57 2005 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: ksyms.h,v 1.8 2003/11/17 10:16:18 cube Exp $   */
+/*     $NetBSD: ksyms.h,v 1.9 2005/02/15 21:09:57 cube Exp $   */
 /*
  * Copyright (c) 2001, 2003 Anders Magnusson (ragge%ludd.luth.se@localhost).
  * All rights reserved.
@@ -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*);



Home | Main Index | Thread Index | Old Index