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