[PATCH] Clean up module.c symbol searching logic
authorSam Ravnborg <sam@ravnborg.org>
Wed, 8 Feb 2006 20:16:45 +0000 (21:16 +0100)
committerGreg Kroah-Hartman <gregkh@suse.de>
Mon, 20 Mar 2006 21:42:58 +0000 (13:42 -0800)
Signed-off-by: Sam Ravnborg <sam@ravnborg.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
kernel/module.c

index 5aad477ddc79c94567c02e9ee704f1eb71fa1b66..2a892b20d68f33a8291e8659bea60d4bfd245390 100644 (file)
@@ -135,6 +135,18 @@ extern const unsigned long __start___kcrctab_gpl[];
 #define symversion(base, idx) ((base) ? ((base) + (idx)) : NULL)
 #endif
 
+/* lookup symbol in given range of kernel_symbols */
+static const struct kernel_symbol *lookup_symbol(const char *name,
+       const struct kernel_symbol *start,
+       const struct kernel_symbol *stop)
+{
+       const struct kernel_symbol *ks = start;
+       for (; ks < stop; ks++)
+               if (strcmp(ks->name, name) == 0)
+                       return ks;
+       return NULL;
+}
+
 /* Find a symbol, return value, crc and module which owns it */
 static unsigned long __find_symbol(const char *name,
                                   struct module **owner,
@@ -142,39 +154,41 @@ static unsigned long __find_symbol(const char *name,
                                   int gplok)
 {
        struct module *mod;
-       unsigned int i;
+       const struct kernel_symbol *ks;
 
        /* Core kernel first. */ 
        *owner = NULL;
-       for (i = 0; __start___ksymtab+i < __stop___ksymtab; i++) {
-               if (strcmp(__start___ksymtab[i].name, name) == 0) {
-                       *crc = symversion(__start___kcrctab, i);
-                       return __start___ksymtab[i].value;
-               }
+       ks = lookup_symbol(name, __start___ksymtab, __stop___ksymtab);
+       if (ks) {
+               *crc = symversion(__start___kcrctab, (ks - __start___ksymtab));
+               return ks->value;
        }
        if (gplok) {
-               for (i = 0; __start___ksymtab_gpl+i<__stop___ksymtab_gpl; i++)
-                       if (strcmp(__start___ksymtab_gpl[i].name, name) == 0) {
-                               *crc = symversion(__start___kcrctab_gpl, i);
-                               return __start___ksymtab_gpl[i].value;
-                       }
+               ks = lookup_symbol(name, __start___ksymtab_gpl,
+                                        __stop___ksymtab_gpl);
+               if (ks) {
+                       *crc = symversion(__start___kcrctab_gpl,
+                                         (ks - __start___ksymtab_gpl));
+                       return ks->value;
+               }
        }
 
        /* Now try modules. */ 
        list_for_each_entry(mod, &modules, list) {
                *owner = mod;
-               for (i = 0; i < mod->num_syms; i++)
-                       if (strcmp(mod->syms[i].name, name) == 0) {
-                               *crc = symversion(mod->crcs, i);
-                               return mod->syms[i].value;
-                       }
+               ks = lookup_symbol(name, mod->syms, mod->syms + mod->num_syms);
+               if (ks) {
+                       *crc = symversion(mod->crcs, (ks - mod->syms));
+                       return ks->value;
+               }
 
                if (gplok) {
-                       for (i = 0; i < mod->num_gpl_syms; i++) {
-                               if (strcmp(mod->gpl_syms[i].name, name) == 0) {
-                                       *crc = symversion(mod->gpl_crcs, i);
-                                       return mod->gpl_syms[i].value;
-                               }
+                       ks = lookup_symbol(name, mod->gpl_syms,
+                                          mod->gpl_syms + mod->num_gpl_syms);
+                       if (ks) {
+                               *crc = symversion(mod->gpl_crcs,
+                                                 (ks - mod->gpl_syms));
+                               return ks->value;
                        }
                }
        }
@@ -1444,18 +1458,13 @@ static void setup_modinfo(struct module *mod, Elf_Shdr *sechdrs,
 #ifdef CONFIG_KALLSYMS
 int is_exported(const char *name, const struct module *mod)
 {
-       unsigned int i;
-
-       if (!mod) {
-               for (i = 0; __start___ksymtab+i < __stop___ksymtab; i++)
-                       if (strcmp(__start___ksymtab[i].name, name) == 0)
-                               return 1;
-               return 0;
-       }
-       for (i = 0; i < mod->num_syms; i++)
-               if (strcmp(mod->syms[i].name, name) == 0)
+       if (!mod && lookup_symbol(name, __start___ksymtab, __stop___ksymtab))
+               return 1;
+       else
+               if (lookup_symbol(name, mod->syms, mod->syms + mod->num_syms))
                        return 1;
-       return 0;
+               else
+                       return 0;
 }
 
 /* As per nm */