Adding kallsyms_lookupname()

Rusty Russell rusty at au1.ibm.com
Thu Feb 26 17:51:08 EST 2004


In message <Pine.A41.4.44.0402251618360.28842-200000 at forte.austin.ibm.com> you write:
> Rusty,
>
> Attached patch adds a kallsyms_lookupname() function for lookups of a
> symbol name to an address.

OK, I simplified it a bit, and gave it some prototype love:

> +unsigned long kallsyms_lookupname(char *name);
....
> +static inline const unsigned long kallsyms_lookupname(unsigned long addr)

How's this:

Name: kallsyms_lookupname() Function For Debuggers
Author: Olof Johansson, Rusty Russell
Status: Experimental

Attached patch adds a kallsyms_lookupname() function for lookups of a
symbol name to an address.

It's intentionally not exported as a symbol for module use, since it
can be used to circumvent other symbol export restrictions.

diff -urpN --exclude TAGS -X /home/rusty/devel/kernel/kernel-patches/current-dontdiff --minimal .32130-linux-2.6.3-bk7/include/linux/kallsyms.h .32130-linux-2.6.3-bk7.updated/include/linux/kallsyms.h
--- .32130-linux-2.6.3-bk7/include/linux/kallsyms.h	2003-09-22 09:47:17.000000000 +1000
+++ .32130-linux-2.6.3-bk7.updated/include/linux/kallsyms.h	2004-02-26 13:57:39.000000000 +1100
@@ -8,6 +8,9 @@
 #include <linux/config.h>

 #ifdef CONFIG_KALLSYMS
+/* Lookup the address for a symbol. Returns 0 if not found. */
+unsigned long kallsyms_lookup_name(const char *name);
+
 /* Lookup an address.  modname is set to NULL if it's in the kernel. */
 const char *kallsyms_lookup(unsigned long addr,
 			    unsigned long *symbolsize,
@@ -19,6 +22,11 @@ extern void __print_symbol(const char *f

 #else /* !CONFIG_KALLSYMS */

+static inline unsigned long kallsyms_lookup_name(const char *name)
+{
+	return 0;
+}
+
 static inline const char *kallsyms_lookup(unsigned long addr,
 					  unsigned long *symbolsize,
 					  unsigned long *offset,
diff -urpN --exclude TAGS -X /home/rusty/devel/kernel/kernel-patches/current-dontdiff --minimal .32130-linux-2.6.3-bk7/include/linux/module.h .32130-linux-2.6.3-bk7.updated/include/linux/module.h
--- .32130-linux-2.6.3-bk7/include/linux/module.h	2004-02-04 15:39:14.000000000 +1100
+++ .32130-linux-2.6.3-bk7.updated/include/linux/module.h	2004-02-26 15:20:29.000000000 +1100
@@ -282,6 +282,10 @@ struct module *module_get_kallsym(unsign
 				  unsigned long *value,
 				  char *type,
 				  char namebuf[128]);
+
+/* Look for this name: can be of form module:name. */
+unsigned long module_kallsyms_lookup_name(const char *name);
+
 int is_exported(const char *name, const struct module *mod);

 extern void __module_put_and_exit(struct module *mod, long code)
@@ -434,6 +438,11 @@ static inline struct module *module_get_
 	return NULL;
 }

+static inline unsigned long module_kallsyms_lookup_name(const char *name)
+{
+	return 0;
+}
+
 static inline int is_exported(const char *name, const struct module *mod)
 {
 	return 0;
diff -urpN --exclude TAGS -X /home/rusty/devel/kernel/kernel-patches/current-dontdiff --minimal .32130-linux-2.6.3-bk7/kernel/kallsyms.c .32130-linux-2.6.3-bk7.updated/kernel/kallsyms.c
--- .32130-linux-2.6.3-bk7/kernel/kallsyms.c	2003-09-22 10:28:13.000000000 +1000
+++ .32130-linux-2.6.3-bk7.updated/kernel/kallsyms.c	2004-02-26 14:22:37.000000000 +1100
@@ -37,6 +37,25 @@ static inline int is_kernel_text(unsigne
 	return 0;
 }

+/* Lookup the address for this symbol. Returns 0 if not found. */
+unsigned long kallsyms_lookup_name(const char *name)
+{
+	char namebuf[128];
+	unsigned long i;
+	char *knames;
+
+	for (i = 0, knames = kallsyms_names; i < kallsyms_num_syms; i++) {
+		unsigned prefix = *knames++;
+
+		strlcpy(namebuf + prefix, knames, 127 - prefix);
+		if (strcmp(namebuf, name) == 0)
+			return kallsyms_addresses[i];
+
+		knames += strlen(knames) + 1;
+	}
+	return module_kallsyms_lookup_name(name);
+}
+
 /* Lookup an address.  modname is set to NULL if it's in the kernel. */
 const char *kallsyms_lookup(unsigned long addr,
 			    unsigned long *symbolsize,
diff -urpN --exclude TAGS -X /home/rusty/devel/kernel/kernel-patches/current-dontdiff --minimal .32130-linux-2.6.3-bk7/kernel/module.c .32130-linux-2.6.3-bk7.updated/kernel/module.c
--- .32130-linux-2.6.3-bk7/kernel/module.c	2004-02-26 11:53:26.000000000 +1100
+++ .32130-linux-2.6.3-bk7.updated/kernel/module.c	2004-02-26 14:40:25.000000000 +1100
@@ -1892,6 +1892,37 @@ struct module *module_get_kallsym(unsign
 	up(&module_mutex);
 	return NULL;
 }
+
+static unsigned long mod_find_symname(struct module *mod, const char *name)
+{
+	unsigned int i;
+
+	for (i = 0; i < mod->num_symtab; i++)
+		if (strcmp(name, mod->strtab+mod->symtab[i].st_name) == 0)
+			return mod->symtab[i].st_value;
+	return 0;
+}
+
+/* Look for this name: can be of form module:name. */
+unsigned long module_kallsyms_lookup_name(const char *name)
+{
+	struct module *mod;
+	char *colon;
+	unsigned long ret = 0;
+
+	/* Don't lock: we're in enough trouble already. */
+	if ((colon = strchr(name, ':')) != NULL) {
+		*colon = '\0';
+		if ((mod = find_module(name)) != NULL)
+			ret = mod_find_symname(mod, colon+1);
+		*colon = ':';
+	} else {
+		list_for_each_entry(mod, &modules, list)
+			if ((ret = mod_find_symname(mod, name)) != 0)
+				break;
+	}
+	return ret;
+}
 #endif /* CONFIG_KALLSYMS */

 /* Called by the /proc file system to return a list of modules. */

--
  Anyone who quotes me in their sig is an idiot. -- Rusty Russell.

** Sent via the linuxppc64-dev mail list. See http://lists.linuxppc.org/





More information about the Linuxppc64-dev mailing list