symbol_put_addr() works only for exported function names (symbols present
in text section). This for example means thatsymbol_put_addr(__symbol_get("any_exported_variable_name"))
triggers a BUG, which really seems wrong.
This patch introduces generic lookup_symbol_address(), which performs
lookup on symbol tables of all modules according to the address, and makes
symbol_put_addr() use this interface to find the module owner instead.Signed-off-by: Jiri Kosina <jkosina@suse.cz>
diff --git a/kernel/module.c b/kernel/module.c
index 5f80478..77ff23e 100644
--- a/kernel/module.c
+++ b/kernel/module.c
@@ -302,6 +302,64 @@ static unsigned long find_symbol(const char *name,
return -ENOENT;
}+/* Lookup module symbol by address */
+const static struct kernel_symbol *lookup_symbol_address(unsigned long addr,
+ struct module **owner)
+{
+ struct module *mod;
+ const struct kernel_symbol *s;
+ unsigned int i;
+
+ /* Core kernel first */
+ struct {
+ const struct kernel_symbol *s_start;
+ const struct kernel_symbol *s_end;
+ } kern_syms[] = {
+ { __start___ksymtab, __stop___ksymtab },
+ { __start___ksymtab_gpl, __stop___ksymtab_gpl },
+ { __start___ksymtab_gpl_future, __stop___ksymtab_gpl_future },
+ { __start___ksymtab_unused, __stop___ksymtab_unused },
+ { __start___ksymtab_unused_gpl, __stop___ksymtab_unused_gpl },
+ };
+
+ for (i = 0; i < ARRAY_SIZE(kern_syms); i++) {
+ for (s = kern_syms[i].s_start; s < kern_syms[i].s_end; s++) {
+ if (s->value == addr) {
+ if (owner)
+ *owner = NULL;
+ return s;
+ }
+ }
+ }
+
+ /* Now try modules */
+ list_for_each_entry(mod, &modules, list) {
+ struct {
+ const struct kernel_symbol *sym;
+ unsigned int num;
+ } arr[] = {
+ { mod->syms, mod->num_syms },
+ { mod->gpl_syms, mod->num_gpl_syms },
+ { mod->gpl_future_syms, mod->num_gpl_future_syms },
+ { mod->unused_syms, mod->num_unused_syms },
+ { mod->unused_gpl_syms, mo...
Hi Jiri,
It might be better to centralize all these iterators, and create a proper
iterator function. Any chance you could rewrite it on top of this patch?
(Lightly tested)Thanks!
Rusty.module: generic each_symbol iterator function
Introduce an each_symbol() iterator to avoid duplicating the knowledge
about the 5 different sections containing symbols. Currently only
used by find_symbol(), but will be used by symbol_put_addr() too.Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
diff -r 909eac180d25 kernel/module.c
--- a/kernel/module.c Fri Jun 20 15:56:43 2008 +1000
+++ b/kernel/module.c Mon Jun 23 13:40:43 2008 +1000
@@ -152,6 +152,167 @@ extern const unsigned long __start___kcr
#define symversion(base, idx) ((base != NULL) ? ((base) + (idx)) : NULL)
#endif+struct symsearch {
+ const struct kernel_symbol *start, *stop;
+ const unsigned long *crcs;
+ enum {
+ NOT_GPL_ONLY,
+ GPL_ONLY,
+ WILL_BE_GPL_ONLY,
+ } licence;
+ bool unused;
+};
+
+static bool each_symbol_in_section(const struct symsearch *arr,
+ unsigned int arrsize,
+ struct module *owner,
+ bool (*fn)(const struct symsearch *syms,
+ struct module *owner,
+ unsigned int symnum, void *data),
+ void *data)
+{
+ unsigned int i, j;
+
+ for (j = 0; j < arrsize; j++) {
+ for (i = 0; i < arr[j].stop - arr[j].start; i++)
+ if (fn(&arr[j], owner, i, data))
+ return true;
+ }
+
+ return false;
+}
+
+/* Returns true as soon as fn returns true, otherwise false. */
+static bool each_symbol(bool (*fn)(const struct symsearch *arr,
+ struct module *owner,
+ unsigned int symnum, void *data),
+ void *data)
+{
+ struct module *mod;
+ const struct symsearch arr[] = {
+ { __start___ksymtab, __stop___ksymtab, __start___kcrctab,
+ NOT_GPL_ONLY, false },
+ { __start___ksymtab_gpl, __stop___ksymtab_gpl,
+ __start___kcrctab_gpl,
+ GPL_ONLY, false },
+ { __start___ksymtab_gpl_future, __stop__...
Hi Rusty,
I see two options how to do this -- either I can make 'value' input
parameter too, so that find_symbol_in_section() could perform lookup
either according to address or according to name (whatever is specified in
the passed struct find_symbol_arg), or I can do a completely new lookup
function for address-wise lookups. What would you prefer? I don't have any
strong preference either way.Thanks,
--
Jiri Kosina
SUSE Labs
--
A new lookup function (and hence a new structure) I think. It'll be clearer.
Cheers,
Rusty.
--
| James Bottomley | Re: Integration of SCST in the mainstream Linux kernel |
| David Miller | Slow DOWN, please!!! |
| Mark Lord | PCIe Hotplug: NFG unless I boot with card already inserted. |
| Pavel Roskin | ndiswrapper and GPL-only symbols redux |
git: | |
| Jarek Poplawski | [PATCH] pkt_sched: Destroy gen estimators under rtnl_lock(). |
| Frans Pop | svc: failed to register lockdv1 RPC service (errno 97). |
| Gerrit Renker | [PATCH 03/37] dccp: List management for new feature negotiation |
| Andrew Morton | Re: [BUG] New Kernel Bugs |
