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