aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--kernel/module.c73
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 */
139static 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 */
139static unsigned long __find_symbol(const char *name, 151static 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
1445int is_exported(const char *name, const struct module *mod) 1459int 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 */