Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src Change the ksyms ioctls to more compat_netbsd32 friendly. U...
details: https://anonhg.NetBSD.org/src/rev/d26aa126be60
branches: trunk
changeset: 338359:d26aa126be60
user: matt <matt%NetBSD.org@localhost>
date: Wed May 20 02:45:20 2015 +0000
description:
Change the ksyms ioctls to more compat_netbsd32 friendly. Use _IOWR ioctls
to avoid extra copyouts. With these changes, netstat and vmstat work on
mips64eb with the normal N32 userland and a N64 kernel.
diffstat:
lib/libc/gen/nlist_elf32.c | 46 ++++++++++++++++++++------
sys/compat/netbsd32/netbsd32_ioctl.c | 52 +++++++++++++++++++++++++++++-
sys/compat/netbsd32/netbsd32_ioctl.h | 16 ++++++++-
sys/kern/kern_ksyms.c | 62 +++++++++++++++++++++++++++++++----
sys/sys/ksyms.h | 26 +++++++++++---
5 files changed, 174 insertions(+), 28 deletions(-)
diffs (truncated from 402 to 300 lines):
diff -r 2b5e1af39cb3 -r d26aa126be60 lib/libc/gen/nlist_elf32.c
--- a/lib/libc/gen/nlist_elf32.c Wed May 20 01:30:42 2015 +0000
+++ b/lib/libc/gen/nlist_elf32.c Wed May 20 02:45:20 2015 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: nlist_elf32.c,v 1.36 2015/05/19 06:09:15 matt Exp $ */
+/* $NetBSD: nlist_elf32.c,v 1.37 2015/05/20 02:45:20 matt Exp $ */
/*
* Copyright (c) 1996 Christopher G. Demetriou
@@ -36,7 +36,7 @@
#include <sys/cdefs.h>
#if defined(LIBC_SCCS) && !defined(lint)
-__RCSID("$NetBSD: nlist_elf32.c,v 1.36 2015/05/19 06:09:15 matt Exp $");
+__RCSID("$NetBSD: nlist_elf32.c,v 1.37 2015/05/20 02:45:20 matt Exp $");
#endif /* LIBC_SCCS and not lint */
/* If not included by nlist_elf64.c, ELFSIZE won't be defined. */
@@ -77,14 +77,14 @@
{
struct stat st;
Elf_Ehdr ehdr;
-#if defined(_LP64) || ELFSIZE == 32 || defined(__mips_n32)
+#if defined(_LP64) || ELFSIZE == 32 || defined(ELF64_MACHDEP_ID)
#if (ELFSIZE == 32)
Elf32_Half nshdr;
#elif (ELFSIZE == 64)
Elf64_Word nshdr;
#endif
- /* Only support 64+32 mode on LP64 and MIPS N32 */
- /* No support for 64 mode on ILP32 */
+ /* Only support 64+32 mode on LP64 and those that have defined */
+ /* ELF64_MACHDEP_ID, otherwise no support for 64 mode on ILP32 */
Elf_Ehdr *ehdrp;
Elf_Shdr *shdrp, *symshdrp, *symstrshdrp;
Elf_Sym *symp;
@@ -138,14 +138,13 @@
default:
BAD;
}
-#if defined(_LP64) || ELFSIZE == 32 || defined(__mips_n32)
+#if defined(_LP64) || ELFSIZE == 32 || defined(ELF64_MACHDEP_ID)
symshdrp = symstrshdrp = NULL;
- /* Only support 64+32 mode on LP64 and MIPS N32 */
- /* No support for 64 mode on ILP32 */
+ /* Only support 64+32 mode on LP64 and those that have defined */
+ /* ELF64_MACHDEP_ID, otherwise no support for 64 mode on ILP32 */
if (S_ISCHR(st.st_mode)) {
const char *nlistname;
- struct ksyms_gsymbol kg;
Elf_Sym sym;
/*
@@ -153,6 +152,8 @@
*/
nent = 0;
for (p = list; !ISLAST(p); ++p) {
+ struct ksyms_gsymbol kg;
+ int error;
p->n_other = 0;
p->n_desc = 0;
@@ -160,9 +161,32 @@
if (*nlistname == '_')
nlistname++;
+ memset(&kg, 0, sizeof(kg));
kg.kg_name = nlistname;
+#ifdef OKIOCGSYMBOL
+ struct ksyms_ogsymbol okg;
+ error = ioctl(fd, KIOCGSYMBOL, &kg);
+ if (error == 0) {
+ sym = kg.kg_sym;
+ } else if (error && errno == ENOTTY) {
+ memset(&okg, 0, sizeof(okg));
+ okg.kg_name = nlistname;
+ okg.kg_sym = &sym;
+ error = ioctl(fd, OKIOCGSYMBOL, &okg);
+ }
+#else
kg.kg_sym = &sym;
- if (ioctl(fd, KIOCGSYMBOL, &kg) == 0) {
+ error = ioctl(fd, KIOCGSYMBOL, &kg);
+#endif
+ if (error == 0
+#if !defined(_LP64) && ELFSIZE == 64
+#if __mips__
+ && (intptr_t)sym.st_value == (intmax_t)sym.st_value
+#else
+ && (uintptr_t)sym.st_value == sym.st_value
+#endif
+#endif
+ && 1) {
p->n_value = (uintptr_t)sym.st_value;
switch (ELF_ST_TYPE(sym.st_info)) {
case STT_NOTYPE:
@@ -310,7 +334,7 @@
rv = nent;
unmap:
munmap(mappedfile, mappedsize);
-#endif /* _LP64 || ELFSIZE == 32 || __mips_n32 */
+#endif /* _LP64 || ELFSIZE == 32 || ELF64_MACHDEP_ID */
out:
return (rv);
}
diff -r 2b5e1af39cb3 -r d26aa126be60 sys/compat/netbsd32/netbsd32_ioctl.c
--- a/sys/compat/netbsd32/netbsd32_ioctl.c Wed May 20 01:30:42 2015 +0000
+++ b/sys/compat/netbsd32/netbsd32_ioctl.c Wed May 20 02:45:20 2015 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: netbsd32_ioctl.c,v 1.70 2015/05/18 06:38:59 martin Exp $ */
+/* $NetBSD: netbsd32_ioctl.c,v 1.71 2015/05/20 02:45:20 matt Exp $ */
/*
* Copyright (c) 1998, 2001 Matthew R. Green
@@ -31,7 +31,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: netbsd32_ioctl.c,v 1.70 2015/05/18 06:38:59 martin Exp $");
+__KERNEL_RCSID(0, "$NetBSD: netbsd32_ioctl.c,v 1.71 2015/05/20 02:45:20 matt Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@@ -54,6 +54,7 @@
#include <sys/envsys.h>
#include <sys/wdog.h>
#include <sys/clockctl.h>
+#include <sys/ksyms.h>
#ifdef __sparc__
#include <dev/sun/fbio.h>
@@ -390,6 +391,26 @@
p->retval = s32p->retval;
}
+static inline void
+netbsd32_to_ksyms_gsymbol(
+ const struct netbsd32_ksyms_gsymbol *s32p,
+ struct ksyms_gsymbol *p,
+ u_long cmd)
+{
+
+ p->kg_name = NETBSD32PTR64(s32p->kg_name);
+}
+
+static inline void
+netbsd32_to_ksyms_gvalue(
+ const struct netbsd32_ksyms_gvalue *s32p,
+ struct ksyms_gvalue *p,
+ u_long cmd)
+{
+
+ p->kv_name = NETBSD32PTR64(s32p->kv_name);
+}
+
/*
* handle ioctl conversions from 64-bit kernel -> netbsd32
*/
@@ -711,6 +732,28 @@
s32p->retval = p->retval;
}
+static inline void
+netbsd32_from_ksyms_gsymbol(
+ const struct ksyms_gsymbol *p,
+ struct netbsd32_ksyms_gsymbol *s32p,
+ u_long cmd)
+{
+
+ NETBSD32PTR32(s32p->kg_name, p->kg_name);
+ s32p->kg_sym = p->kg_sym;
+}
+
+static inline void
+netbsd32_from_ksyms_gvalue(
+ const struct ksyms_gvalue *p,
+ struct netbsd32_ksyms_gvalue *s32p,
+ u_long cmd)
+{
+
+ NETBSD32PTR32(s32p->kv_name, p->kv_name);
+ s32p->kv_value = p->kv_value;
+}
+
/*
* main ioctl syscall.
*
@@ -1075,6 +1118,11 @@
IOCTL_STRUCT_CONV_TO(CLOCKCTL_NTP_ADJTIME,
clockctl_ntp_adjtime);
+ case KIOCGSYMBOL32:
+ IOCTL_STRUCT_CONV_TO(KIOCGSYMBOL, ksyms_gsymbol);
+ case KIOCGVALUE32:
+ IOCTL_STRUCT_CONV_TO(KIOCGVALUE, ksyms_gvalue);
+
default:
#ifdef NETBSD32_MD_IOCTL
error = netbsd32_md_ioctl(fp, com, data32, l);
diff -r 2b5e1af39cb3 -r d26aa126be60 sys/compat/netbsd32/netbsd32_ioctl.h
--- a/sys/compat/netbsd32/netbsd32_ioctl.h Wed May 20 01:30:42 2015 +0000
+++ b/sys/compat/netbsd32/netbsd32_ioctl.h Wed May 20 02:45:20 2015 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: netbsd32_ioctl.h,v 1.45 2015/05/18 06:38:59 martin Exp $ */
+/* $NetBSD: netbsd32_ioctl.h,v 1.46 2015/05/20 02:45:20 matt Exp $ */
/*
* Copyright (c) 1998, 2001 Matthew R. Green
@@ -533,3 +533,17 @@
#define CLOCKCTL_NTP_ADJTIME32 _IOWR('C', 0x8, \
struct netbsd32_clockctl_ntp_adjtime)
+struct netbsd32_ksyms_gsymbol {
+ netbsd32_charp kg_name;
+ union {
+ Elf64_Sym ku_sym;
+ } _un;
+};
+
+struct netbsd32_ksyms_gvalue {
+ netbsd32_charp kv_name;
+ uint64_t kv_value;
+};
+
+#define KIOCGVALUE32 _IOWR('l', 4, struct netbsd32_ksyms_gvalue)
+#define KIOCGSYMBOL32 _IOWR('l', 5, struct netbsd32_ksyms_gsymbol)
diff -r 2b5e1af39cb3 -r d26aa126be60 sys/kern/kern_ksyms.c
--- a/sys/kern/kern_ksyms.c Wed May 20 01:30:42 2015 +0000
+++ b/sys/kern/kern_ksyms.c Wed May 20 02:45:20 2015 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: kern_ksyms.c,v 1.75 2014/12/15 13:50:10 christos Exp $ */
+/* $NetBSD: kern_ksyms.c,v 1.76 2015/05/20 02:45:20 matt Exp $ */
/*-
* Copyright (c) 2008 The NetBSD Foundation, Inc.
@@ -71,7 +71,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: kern_ksyms.c,v 1.75 2014/12/15 13:50:10 christos Exp $");
+__KERNEL_RCSID(0, "$NetBSD: kern_ksyms.c,v 1.76 2015/05/20 02:45:20 matt Exp $");
#if defined(_KERNEL) && defined(_KERNEL_OPT)
#include "opt_ddb.h"
@@ -1065,10 +1065,15 @@
return EROFS;
}
+__CTASSERT(offsetof(struct ksyms_ogsymbol, kg_name) == offsetof(struct ksyms_gsymbol, kg_name));
+__CTASSERT(offsetof(struct ksyms_gvalue, kv_name) == offsetof(struct ksyms_gsymbol, kg_name));
+
static int
ksymsioctl(dev_t dev, u_long cmd, void *data, int fflag, struct lwp *l)
{
+ struct ksyms_ogsymbol *okg = (struct ksyms_ogsymbol *)data;
struct ksyms_gsymbol *kg = (struct ksyms_gsymbol *)data;
+ struct ksyms_gvalue *kv = (struct ksyms_gvalue *)data;
struct ksyms_symtab *st;
Elf_Sym *sym = NULL, copy;
unsigned long val;
@@ -1079,7 +1084,8 @@
/* Read ksyms_maxlen only once while not holding the lock. */
len = ksyms_maxlen;
- if (cmd == KIOCGVALUE || cmd == KIOCGSYMBOL) {
+ if (cmd == OKIOCGVALUE || cmd == OKIOCGSYMBOL
+ || cmd == KIOCGVALUE || cmd == KIOCGSYMBOL) {
str = kmem_alloc(len, KM_SLEEP);
if ((error = copyinstr(kg->kg_name, str, len, NULL)) != 0) {
kmem_free(str, len);
@@ -1088,6 +1094,48 @@
}
switch (cmd) {
+ case OKIOCGVALUE:
+ /*
+ * Use the in-kernel symbol lookup code for fast
+ * retreival of a value.
+ */
+ error = ksyms_getval(NULL, str, &val, KSYMS_EXTERN);
+ if (error == 0)
+ error = copyout(&val, okg->kg_value, sizeof(long));
+ kmem_free(str, len);
+ break;
+
+ case OKIOCGSYMBOL:
+ /*
+ * Use the in-kernel symbol lookup code for fast
+ * retreival of a symbol.
+ */
+ mutex_enter(&ksyms_lock);
+ TAILQ_FOREACH(st, &ksyms_symtabs, sd_queue) {
+ if (st->sd_gone)
+ continue;
+ if ((sym = findsym(str, st, KSYMS_ANY)) == NULL)
+ continue;
+#ifdef notdef
+ /* Skip if bad binding */
+ if (ELF_ST_BIND(sym->st_info) != STB_GLOBAL) {
Home |
Main Index |
Thread Index |
Old Index