diff options
Diffstat (limited to 'kernel/module.c')
-rw-r--r-- | kernel/module.c | 73 |
1 files changed, 41 insertions, 32 deletions
diff --git a/kernel/module.c b/kernel/module.c index 5aad477ddc79..2a892b20d68f 100644 --- a/kernel/module.c +++ b/kernel/module.c | |||
@@ -135,6 +135,18 @@ extern const unsigned long __start___kcrctab_gpl[]; | |||
135 | #define symversion(base, idx) ((base) ? ((base) + (idx)) : NULL) | 135 | #define symversion(base, idx) ((base) ? ((base) + (idx)) : NULL) |
136 | #endif | 136 | #endif |
137 | 137 | ||
138 | /* lookup symbol in given range of kernel_symbols */ | ||
139 | static const struct kernel_symbol *lookup_symbol(const char *name, | ||
140 | const struct kernel_symbol *start, | ||
141 | const struct kernel_symbol *stop) | ||
142 | { | ||
143 | const struct kernel_symbol *ks = start; | ||
144 | for (; ks < stop; ks++) | ||
145 | if (strcmp(ks->name, name) == 0) | ||
146 | return ks; | ||
147 | return NULL; | ||
148 | } | ||
149 | |||
138 | /* Find a symbol, return value, crc and module which owns it */ | 150 | /* Find a symbol, return value, crc and module which owns it */ |
139 | static unsigned long __find_symbol(const char *name, | 151 | static unsigned long __find_symbol(const char *name, |
140 | struct module **owner, | 152 | struct module **owner, |
@@ -142,39 +154,41 @@ static unsigned long __find_symbol(const char *name, | |||
142 | int gplok) | 154 | int gplok) |
143 | { | 155 | { |
144 | struct module *mod; | 156 | struct module *mod; |
145 | unsigned int i; | 157 | const struct kernel_symbol *ks; |
146 | 158 | ||
147 | /* Core kernel first. */ | 159 | /* Core kernel first. */ |
148 | *owner = NULL; | 160 | *owner = NULL; |
149 | for (i = 0; __start___ksymtab+i < __stop___ksymtab; i++) { | 161 | ks = lookup_symbol(name, __start___ksymtab, __stop___ksymtab); |
150 | if (strcmp(__start___ksymtab[i].name, name) == 0) { | 162 | if (ks) { |
151 | *crc = symversion(__start___kcrctab, i); | 163 | *crc = symversion(__start___kcrctab, (ks - __start___ksymtab)); |
152 | return __start___ksymtab[i].value; | 164 | return ks->value; |
153 | } | ||
154 | } | 165 | } |
155 | if (gplok) { | 166 | if (gplok) { |
156 | for (i = 0; __start___ksymtab_gpl+i<__stop___ksymtab_gpl; i++) | 167 | ks = lookup_symbol(name, __start___ksymtab_gpl, |
157 | if (strcmp(__start___ksymtab_gpl[i].name, name) == 0) { | 168 | __stop___ksymtab_gpl); |
158 | *crc = symversion(__start___kcrctab_gpl, i); | 169 | if (ks) { |
159 | return __start___ksymtab_gpl[i].value; | 170 | *crc = symversion(__start___kcrctab_gpl, |
160 | } | 171 | (ks - __start___ksymtab_gpl)); |
172 | return ks->value; | ||
173 | } | ||
161 | } | 174 | } |
162 | 175 | ||
163 | /* Now try modules. */ | 176 | /* Now try modules. */ |
164 | list_for_each_entry(mod, &modules, list) { | 177 | list_for_each_entry(mod, &modules, list) { |
165 | *owner = mod; | 178 | *owner = mod; |
166 | for (i = 0; i < mod->num_syms; i++) | 179 | ks = lookup_symbol(name, mod->syms, mod->syms + mod->num_syms); |
167 | if (strcmp(mod->syms[i].name, name) == 0) { | 180 | if (ks) { |
168 | *crc = symversion(mod->crcs, i); | 181 | *crc = symversion(mod->crcs, (ks - mod->syms)); |
169 | return mod->syms[i].value; | 182 | return ks->value; |
170 | } | 183 | } |
171 | 184 | ||
172 | if (gplok) { | 185 | if (gplok) { |
173 | for (i = 0; i < mod->num_gpl_syms; i++) { | 186 | ks = lookup_symbol(name, mod->gpl_syms, |
174 | if (strcmp(mod->gpl_syms[i].name, name) == 0) { | 187 | mod->gpl_syms + mod->num_gpl_syms); |
175 | *crc = symversion(mod->gpl_crcs, i); | 188 | if (ks) { |
176 | return mod->gpl_syms[i].value; | 189 | *crc = symversion(mod->gpl_crcs, |
177 | } | 190 | (ks - mod->gpl_syms)); |
191 | return ks->value; | ||
178 | } | 192 | } |
179 | } | 193 | } |
180 | } | 194 | } |
@@ -1444,18 +1458,13 @@ static void setup_modinfo(struct module *mod, Elf_Shdr *sechdrs, | |||
1444 | #ifdef CONFIG_KALLSYMS | 1458 | #ifdef CONFIG_KALLSYMS |
1445 | int is_exported(const char *name, const struct module *mod) | 1459 | int is_exported(const char *name, const struct module *mod) |
1446 | { | 1460 | { |
1447 | unsigned int i; | 1461 | if (!mod && lookup_symbol(name, __start___ksymtab, __stop___ksymtab)) |
1448 | 1462 | return 1; | |
1449 | if (!mod) { | 1463 | else |
1450 | for (i = 0; __start___ksymtab+i < __stop___ksymtab; i++) | 1464 | if (lookup_symbol(name, mod->syms, mod->syms + mod->num_syms)) |
1451 | if (strcmp(__start___ksymtab[i].name, name) == 0) | ||
1452 | return 1; | ||
1453 | return 0; | ||
1454 | } | ||
1455 | for (i = 0; i < mod->num_syms; i++) | ||
1456 | if (strcmp(mod->syms[i].name, name) == 0) | ||
1457 | return 1; | 1465 | return 1; |
1458 | return 0; | 1466 | else |
1467 | return 0; | ||
1459 | } | 1468 | } |
1460 | 1469 | ||
1461 | /* As per nm */ | 1470 | /* As per nm */ |