Commit 414fd31b2553aaf160ca9b9afe45aa0372b01b92
Committed by
Rusty Russell
1 parent
b10153fe31
Exists in
master
and in
20 other branches
module: Make find_symbol return a struct kernel_symbol
Impact: Cleanup, internal API change Ksplice needs access to the kernel_symbol structure in order to support modifications to the exported symbol table. Cc: Anders Kaseorg <andersk@mit.edu> Cc: Jeff Arnold <jbarnold@mit.edu> Signed-off-by: Tim Abbott <tabbott@mit.edu> Signed-off-by: Rusty Russell <rusty@rustcorp.com.au> (bugfix and style)
Showing 1 changed file with 37 additions and 38 deletions Side-by-side Diff
kernel/module.c
... | ... | @@ -283,7 +283,7 @@ |
283 | 283 | /* Output */ |
284 | 284 | struct module *owner; |
285 | 285 | const unsigned long *crc; |
286 | - unsigned long value; | |
286 | + const struct kernel_symbol *sym; | |
287 | 287 | }; |
288 | 288 | |
289 | 289 | static bool find_symbol_in_section(const struct symsearch *syms, |
290 | 290 | |
... | ... | @@ -324,17 +324,17 @@ |
324 | 324 | |
325 | 325 | fsa->owner = owner; |
326 | 326 | fsa->crc = symversion(syms->crcs, symnum); |
327 | - fsa->value = syms->start[symnum].value; | |
327 | + fsa->sym = &syms->start[symnum]; | |
328 | 328 | return true; |
329 | 329 | } |
330 | 330 | |
331 | -/* Find a symbol, return value, (optional) crc and (optional) module | |
332 | - * which owns it */ | |
333 | -static unsigned long find_symbol(const char *name, | |
334 | - struct module **owner, | |
335 | - const unsigned long **crc, | |
336 | - bool gplok, | |
337 | - bool warn) | |
331 | +/* Find a symbol and return it, along with, (optional) crc and | |
332 | + * (optional) module which owns it */ | |
333 | +static const struct kernel_symbol *find_symbol(const char *name, | |
334 | + struct module **owner, | |
335 | + const unsigned long **crc, | |
336 | + bool gplok, | |
337 | + bool warn) | |
338 | 338 | { |
339 | 339 | struct find_symbol_arg fsa; |
340 | 340 | |
341 | 341 | |
... | ... | @@ -347,11 +347,11 @@ |
347 | 347 | *owner = fsa.owner; |
348 | 348 | if (crc) |
349 | 349 | *crc = fsa.crc; |
350 | - return fsa.value; | |
350 | + return fsa.sym; | |
351 | 351 | } |
352 | 352 | |
353 | 353 | DEBUGP("Failed to find symbol %s\n", name); |
354 | - return -ENOENT; | |
354 | + return NULL; | |
355 | 355 | } |
356 | 356 | |
357 | 357 | /* Search for module by name: must hold module_mutex. */ |
... | ... | @@ -894,7 +894,7 @@ |
894 | 894 | struct module *owner; |
895 | 895 | |
896 | 896 | preempt_disable(); |
897 | - if (IS_ERR_VALUE(find_symbol(symbol, &owner, NULL, true, false))) | |
897 | + if (!find_symbol(symbol, &owner, NULL, true, false)) | |
898 | 898 | BUG(); |
899 | 899 | module_put(owner); |
900 | 900 | preempt_enable(); |
... | ... | @@ -1057,7 +1057,7 @@ |
1057 | 1057 | { |
1058 | 1058 | const unsigned long *crc; |
1059 | 1059 | |
1060 | - if (IS_ERR_VALUE(find_symbol("struct_module", NULL, &crc, true, false))) | |
1060 | + if (!find_symbol("struct_module", NULL, &crc, true, false)) | |
1061 | 1061 | BUG(); |
1062 | 1062 | return check_version(sechdrs, versindex, "struct_module", mod, crc); |
1063 | 1063 | } |
1064 | 1064 | |
1065 | 1065 | |
1066 | 1066 | |
1067 | 1067 | |
1068 | 1068 | |
... | ... | @@ -1098,25 +1098,25 @@ |
1098 | 1098 | |
1099 | 1099 | /* Resolve a symbol for this module. I.e. if we find one, record usage. |
1100 | 1100 | Must be holding module_mutex. */ |
1101 | -static unsigned long resolve_symbol(Elf_Shdr *sechdrs, | |
1102 | - unsigned int versindex, | |
1103 | - const char *name, | |
1104 | - struct module *mod) | |
1101 | +static const struct kernel_symbol *resolve_symbol(Elf_Shdr *sechdrs, | |
1102 | + unsigned int versindex, | |
1103 | + const char *name, | |
1104 | + struct module *mod) | |
1105 | 1105 | { |
1106 | 1106 | struct module *owner; |
1107 | - unsigned long ret; | |
1107 | + const struct kernel_symbol *sym; | |
1108 | 1108 | const unsigned long *crc; |
1109 | 1109 | |
1110 | - ret = find_symbol(name, &owner, &crc, | |
1110 | + sym = find_symbol(name, &owner, &crc, | |
1111 | 1111 | !(mod->taints & (1 << TAINT_PROPRIETARY_MODULE)), true); |
1112 | - if (!IS_ERR_VALUE(ret)) { | |
1113 | - /* use_module can fail due to OOM, | |
1114 | - or module initialization or unloading */ | |
1112 | + /* use_module can fail due to OOM, | |
1113 | + or module initialization or unloading */ | |
1114 | + if (sym) { | |
1115 | 1115 | if (!check_version(sechdrs, versindex, name, mod, crc) || |
1116 | 1116 | !use_module(mod, owner)) |
1117 | - ret = -EINVAL; | |
1117 | + sym = NULL; | |
1118 | 1118 | } |
1119 | - return ret; | |
1119 | + return sym; | |
1120 | 1120 | } |
1121 | 1121 | |
1122 | 1122 | /* |
1123 | 1123 | |
1124 | 1124 | |
... | ... | @@ -1516,17 +1516,15 @@ |
1516 | 1516 | void *__symbol_get(const char *symbol) |
1517 | 1517 | { |
1518 | 1518 | struct module *owner; |
1519 | - unsigned long value; | |
1519 | + const struct kernel_symbol *sym; | |
1520 | 1520 | |
1521 | 1521 | preempt_disable(); |
1522 | - value = find_symbol(symbol, &owner, NULL, true, true); | |
1523 | - if (IS_ERR_VALUE(value)) | |
1524 | - value = 0; | |
1525 | - else if (strong_try_module_get(owner)) | |
1526 | - value = 0; | |
1522 | + sym = find_symbol(symbol, &owner, NULL, true, true); | |
1523 | + if (sym && strong_try_module_get(owner)) | |
1524 | + sym = NULL; | |
1527 | 1525 | preempt_enable(); |
1528 | 1526 | |
1529 | - return (void *)value; | |
1527 | + return sym ? (void *)sym->value : NULL; | |
1530 | 1528 | } |
1531 | 1529 | EXPORT_SYMBOL_GPL(__symbol_get); |
1532 | 1530 | |
... | ... | @@ -1554,8 +1552,7 @@ |
1554 | 1552 | |
1555 | 1553 | for (i = 0; i < ARRAY_SIZE(arr); i++) { |
1556 | 1554 | for (s = arr[i].sym; s < arr[i].sym + arr[i].num; s++) { |
1557 | - if (!IS_ERR_VALUE(find_symbol(s->name, &owner, | |
1558 | - NULL, true, false))) { | |
1555 | + if (find_symbol(s->name, &owner, NULL, true, false)) { | |
1559 | 1556 | printk(KERN_ERR |
1560 | 1557 | "%s: exports duplicate symbol %s" |
1561 | 1558 | " (owned by %s)\n", |
... | ... | @@ -1579,6 +1576,7 @@ |
1579 | 1576 | unsigned long secbase; |
1580 | 1577 | unsigned int i, n = sechdrs[symindex].sh_size / sizeof(Elf_Sym); |
1581 | 1578 | int ret = 0; |
1579 | + const struct kernel_symbol *ksym; | |
1582 | 1580 | |
1583 | 1581 | for (i = 1; i < n; i++) { |
1584 | 1582 | switch (sym[i].st_shndx) { |
1585 | 1583 | |
1586 | 1584 | |
... | ... | @@ -1598,13 +1596,14 @@ |
1598 | 1596 | break; |
1599 | 1597 | |
1600 | 1598 | case SHN_UNDEF: |
1601 | - sym[i].st_value | |
1602 | - = resolve_symbol(sechdrs, versindex, | |
1603 | - strtab + sym[i].st_name, mod); | |
1604 | - | |
1599 | + ksym = resolve_symbol(sechdrs, versindex, | |
1600 | + strtab + sym[i].st_name, mod); | |
1605 | 1601 | /* Ok if resolved. */ |
1606 | - if (!IS_ERR_VALUE(sym[i].st_value)) | |
1602 | + if (ksym) { | |
1603 | + sym[i].st_value = ksym->value; | |
1607 | 1604 | break; |
1605 | + } | |
1606 | + | |
1608 | 1607 | /* Ok if weak. */ |
1609 | 1608 | if (ELF_ST_BIND(sym[i].st_info) == STB_WEAK) |
1610 | 1609 | break; |