diff options
author | Kirill Korotaev <dev@openvz.org> | 2006-09-07 16:08:54 -0400 |
---|---|---|
committer | Sam Ravnborg <sam@neptun.ravnborg.org> | 2006-09-25 03:14:30 -0400 |
commit | c53ddacdc08d41f812f1e637d214251d14c07a3d (patch) | |
tree | f049bfa5703ecaac0f9694d2f8f60bfed8845c78 /scripts/mod | |
parent | 2212692913281e5fddb1c50c8c123378cfc42169 (diff) |
kbuild: fail kernel compilation in case of unresolved module symbols
At stage 2 modpost utility is used to check modules. In case of unresolved
symbols modpost only prints warning.
IMHO it is a good idea to fail compilation process in case of unresolved
symbols (at least in modules coming with kernel), since usually such errors
are left unnoticed, but kernel modules are broken.
- new option '-w' is added to modpost:
if option is specified, modpost only warns about unresolved symbols
- modpost is called with '-w' for external modules in Makefile.modpost
Signed-off-by: Andrey Mirkin <amirkin@sw.ru>
Signed-off-by: Kirill Korotaev <dev@openvz.org>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Sam Ravnborg <sam@ravnborg.org>
Diffstat (limited to 'scripts/mod')
-rw-r--r-- | scripts/mod/modpost.c | 25 |
1 files changed, 19 insertions, 6 deletions
diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c index 16a19353c67f..41277963f47a 100644 --- a/scripts/mod/modpost.c +++ b/scripts/mod/modpost.c | |||
@@ -23,6 +23,8 @@ int have_vmlinux = 0; | |||
23 | static int all_versions = 0; | 23 | static int all_versions = 0; |
24 | /* If we are modposting external module set to 1 */ | 24 | /* If we are modposting external module set to 1 */ |
25 | static int external_module = 0; | 25 | static int external_module = 0; |
26 | /* Only warn about unresolved symbols */ | ||
27 | static int warn_unresolved = 0; | ||
26 | /* How a symbol is exported */ | 28 | /* How a symbol is exported */ |
27 | enum export { | 29 | enum export { |
28 | export_plain, export_unused, export_gpl, | 30 | export_plain, export_unused, export_gpl, |
@@ -1196,16 +1198,19 @@ static void add_header(struct buffer *b, struct module *mod) | |||
1196 | /** | 1198 | /** |
1197 | * Record CRCs for unresolved symbols | 1199 | * Record CRCs for unresolved symbols |
1198 | **/ | 1200 | **/ |
1199 | static void add_versions(struct buffer *b, struct module *mod) | 1201 | static int add_versions(struct buffer *b, struct module *mod) |
1200 | { | 1202 | { |
1201 | struct symbol *s, *exp; | 1203 | struct symbol *s, *exp; |
1204 | int err = 0; | ||
1202 | 1205 | ||
1203 | for (s = mod->unres; s; s = s->next) { | 1206 | for (s = mod->unres; s; s = s->next) { |
1204 | exp = find_symbol(s->name); | 1207 | exp = find_symbol(s->name); |
1205 | if (!exp || exp->module == mod) { | 1208 | if (!exp || exp->module == mod) { |
1206 | if (have_vmlinux && !s->weak) | 1209 | if (have_vmlinux && !s->weak) { |
1207 | warn("\"%s\" [%s.ko] undefined!\n", | 1210 | warn("\"%s\" [%s.ko] undefined!\n", |
1208 | s->name, mod->name); | 1211 | s->name, mod->name); |
1212 | err = warn_unresolved ? 0 : 1; | ||
1213 | } | ||
1209 | continue; | 1214 | continue; |
1210 | } | 1215 | } |
1211 | s->module = exp->module; | 1216 | s->module = exp->module; |
@@ -1214,7 +1219,7 @@ static void add_versions(struct buffer *b, struct module *mod) | |||
1214 | } | 1219 | } |
1215 | 1220 | ||
1216 | if (!modversions) | 1221 | if (!modversions) |
1217 | return; | 1222 | return err; |
1218 | 1223 | ||
1219 | buf_printf(b, "\n"); | 1224 | buf_printf(b, "\n"); |
1220 | buf_printf(b, "static const struct modversion_info ____versions[]\n"); | 1225 | buf_printf(b, "static const struct modversion_info ____versions[]\n"); |
@@ -1234,6 +1239,8 @@ static void add_versions(struct buffer *b, struct module *mod) | |||
1234 | } | 1239 | } |
1235 | 1240 | ||
1236 | buf_printf(b, "};\n"); | 1241 | buf_printf(b, "};\n"); |
1242 | |||
1243 | return err; | ||
1237 | } | 1244 | } |
1238 | 1245 | ||
1239 | static void add_depends(struct buffer *b, struct module *mod, | 1246 | static void add_depends(struct buffer *b, struct module *mod, |
@@ -1411,8 +1418,9 @@ int main(int argc, char **argv) | |||
1411 | char *kernel_read = NULL, *module_read = NULL; | 1418 | char *kernel_read = NULL, *module_read = NULL; |
1412 | char *dump_write = NULL; | 1419 | char *dump_write = NULL; |
1413 | int opt; | 1420 | int opt; |
1421 | int err; | ||
1414 | 1422 | ||
1415 | while ((opt = getopt(argc, argv, "i:I:mo:a")) != -1) { | 1423 | while ((opt = getopt(argc, argv, "i:I:mo:aw")) != -1) { |
1416 | switch(opt) { | 1424 | switch(opt) { |
1417 | case 'i': | 1425 | case 'i': |
1418 | kernel_read = optarg; | 1426 | kernel_read = optarg; |
@@ -1430,6 +1438,9 @@ int main(int argc, char **argv) | |||
1430 | case 'a': | 1438 | case 'a': |
1431 | all_versions = 1; | 1439 | all_versions = 1; |
1432 | break; | 1440 | break; |
1441 | case 'w': | ||
1442 | warn_unresolved = 1; | ||
1443 | break; | ||
1433 | default: | 1444 | default: |
1434 | exit(1); | 1445 | exit(1); |
1435 | } | 1446 | } |
@@ -1450,6 +1461,8 @@ int main(int argc, char **argv) | |||
1450 | check_exports(mod); | 1461 | check_exports(mod); |
1451 | } | 1462 | } |
1452 | 1463 | ||
1464 | err = 0; | ||
1465 | |||
1453 | for (mod = modules; mod; mod = mod->next) { | 1466 | for (mod = modules; mod; mod = mod->next) { |
1454 | if (mod->skip) | 1467 | if (mod->skip) |
1455 | continue; | 1468 | continue; |
@@ -1457,7 +1470,7 @@ int main(int argc, char **argv) | |||
1457 | buf.pos = 0; | 1470 | buf.pos = 0; |
1458 | 1471 | ||
1459 | add_header(&buf, mod); | 1472 | add_header(&buf, mod); |
1460 | add_versions(&buf, mod); | 1473 | err |= add_versions(&buf, mod); |
1461 | add_depends(&buf, mod, modules); | 1474 | add_depends(&buf, mod, modules); |
1462 | add_moddevtable(&buf, mod); | 1475 | add_moddevtable(&buf, mod); |
1463 | add_srcversion(&buf, mod); | 1476 | add_srcversion(&buf, mod); |
@@ -1469,5 +1482,5 @@ int main(int argc, char **argv) | |||
1469 | if (dump_write) | 1482 | if (dump_write) |
1470 | write_dump(dump_write); | 1483 | write_dump(dump_write); |
1471 | 1484 | ||
1472 | return 0; | 1485 | return err; |
1473 | } | 1486 | } |