|
@@ -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 */
|