aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/module.c
diff options
context:
space:
mode:
authorChristoph Lameter <clameter@sgi.com>2008-02-08 07:18:41 -0500
committerLinus Torvalds <torvalds@woody.linux-foundation.org>2008-02-08 12:22:24 -0500
commit88173507e4fc1e7ecd111b0565e8cba0cb7dae6d (patch)
treeed1a3f61f95b6e253afe8e330a668a12ad56a4e2 /kernel/module.c
parent596f56018df3ed7de20f6038f72177b3674ebbd4 (diff)
Modules: handle symbols that have a zero value
The module subsystem cannot handle symbols that are zero. If symbols are present that have a zero value then the module resolver prints out a message that these symbols are unresolved. [akinobu.mita@gmail.com: fix __find_symbl() error checks] Cc: Mathieu Desnoyers <mathieu.desnoyers@polymtl.ca> Cc: Kay Sievers <kay.sievers@vrfy.org Signed-off-by: Christoph Lameter <clameter@sgi.com> Cc: Rusty Russell <rusty@rustcorp.com.au> Cc: Andi Kleen <ak@suse.de> Signed-off-by: Akinobu Mita <akinobu.mita@gmail.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'kernel/module.c')
-rw-r--r--kernel/module.c23
1 files changed, 14 insertions, 9 deletions
diff --git a/kernel/module.c b/kernel/module.c
index bd60278ee703..dc04d4d88d02 100644
--- a/kernel/module.c
+++ b/kernel/module.c
@@ -290,7 +290,7 @@ static unsigned long __find_symbol(const char *name,
290 } 290 }
291 } 291 }
292 DEBUGP("Failed to find symbol %s\n", name); 292 DEBUGP("Failed to find symbol %s\n", name);
293 return 0; 293 return -ENOENT;
294} 294}
295 295
296/* Search for module by name: must hold module_mutex. */ 296/* Search for module by name: must hold module_mutex. */
@@ -783,7 +783,7 @@ void __symbol_put(const char *symbol)
783 const unsigned long *crc; 783 const unsigned long *crc;
784 784
785 preempt_disable(); 785 preempt_disable();
786 if (!__find_symbol(symbol, &owner, &crc, 1)) 786 if (IS_ERR_VALUE(__find_symbol(symbol, &owner, &crc, 1)))
787 BUG(); 787 BUG();
788 module_put(owner); 788 module_put(owner);
789 preempt_enable(); 789 preempt_enable();
@@ -929,7 +929,8 @@ static inline int check_modstruct_version(Elf_Shdr *sechdrs,
929 const unsigned long *crc; 929 const unsigned long *crc;
930 struct module *owner; 930 struct module *owner;
931 931
932 if (!__find_symbol("struct_module", &owner, &crc, 1)) 932 if (IS_ERR_VALUE(__find_symbol("struct_module",
933 &owner, &crc, 1)))
933 BUG(); 934 BUG();
934 return check_version(sechdrs, versindex, "struct_module", mod, 935 return check_version(sechdrs, versindex, "struct_module", mod,
935 crc); 936 crc);
@@ -978,12 +979,12 @@ static unsigned long resolve_symbol(Elf_Shdr *sechdrs,
978 979
979 ret = __find_symbol(name, &owner, &crc, 980 ret = __find_symbol(name, &owner, &crc,
980 !(mod->taints & TAINT_PROPRIETARY_MODULE)); 981 !(mod->taints & TAINT_PROPRIETARY_MODULE));
981 if (ret) { 982 if (!IS_ERR_VALUE(ret)) {
982 /* use_module can fail due to OOM, 983 /* use_module can fail due to OOM,
983 or module initialization or unloading */ 984 or module initialization or unloading */
984 if (!check_version(sechdrs, versindex, name, mod, crc) || 985 if (!check_version(sechdrs, versindex, name, mod, crc) ||
985 !use_module(mod, owner)) 986 !use_module(mod, owner))
986 ret = 0; 987 ret = -EINVAL;
987 } 988 }
988 return ret; 989 return ret;
989} 990}
@@ -1371,7 +1372,9 @@ void *__symbol_get(const char *symbol)
1371 1372
1372 preempt_disable(); 1373 preempt_disable();
1373 value = __find_symbol(symbol, &owner, &crc, 1); 1374 value = __find_symbol(symbol, &owner, &crc, 1);
1374 if (value && strong_try_module_get(owner) != 0) 1375 if (IS_ERR_VALUE(value))
1376 value = 0;
1377 else if (strong_try_module_get(owner))
1375 value = 0; 1378 value = 0;
1376 preempt_enable(); 1379 preempt_enable();
1377 1380
@@ -1391,14 +1394,16 @@ static int verify_export_symbols(struct module *mod)
1391 const unsigned long *crc; 1394 const unsigned long *crc;
1392 1395
1393 for (i = 0; i < mod->num_syms; i++) 1396 for (i = 0; i < mod->num_syms; i++)
1394 if (__find_symbol(mod->syms[i].name, &owner, &crc, 1)) { 1397 if (!IS_ERR_VALUE(__find_symbol(mod->syms[i].name,
1398 &owner, &crc, 1))) {
1395 name = mod->syms[i].name; 1399 name = mod->syms[i].name;
1396 ret = -ENOEXEC; 1400 ret = -ENOEXEC;
1397 goto dup; 1401 goto dup;
1398 } 1402 }
1399 1403
1400 for (i = 0; i < mod->num_gpl_syms; i++) 1404 for (i = 0; i < mod->num_gpl_syms; i++)
1401 if (__find_symbol(mod->gpl_syms[i].name, &owner, &crc, 1)) { 1405 if (!IS_ERR_VALUE(__find_symbol(mod->gpl_syms[i].name,
1406 &owner, &crc, 1))) {
1402 name = mod->gpl_syms[i].name; 1407 name = mod->gpl_syms[i].name;
1403 ret = -ENOEXEC; 1408 ret = -ENOEXEC;
1404 goto dup; 1409 goto dup;
@@ -1448,7 +1453,7 @@ static int simplify_symbols(Elf_Shdr *sechdrs,
1448 strtab + sym[i].st_name, mod); 1453 strtab + sym[i].st_name, mod);
1449 1454
1450 /* Ok if resolved. */ 1455 /* Ok if resolved. */
1451 if (sym[i].st_value != 0) 1456 if (!IS_ERR_VALUE(sym[i].st_value))
1452 break; 1457 break;
1453 /* Ok if weak. */ 1458 /* Ok if weak. */
1454 if (ELF_ST_BIND(sym[i].st_info) == STB_WEAK) 1459 if (ELF_ST_BIND(sym[i].st_info) == STB_WEAK)