Commit c53ddacd authored by Kirill Korotaev's avatar Kirill Korotaev Committed by Sam Ravnborg

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: default avatarAndrey Mirkin <amirkin@sw.ru>
Signed-off-by: default avatarKirill Korotaev <dev@openvz.org>
Signed-off-by: default avatarAndrew Morton <akpm@osdl.org>
Signed-off-by: default avatarSam Ravnborg <sam@ravnborg.org>
parent 22126929
...@@ -58,6 +58,7 @@ quiet_cmd_modpost = MODPOST $(words $(filter-out vmlinux FORCE, $^)) modules ...@@ -58,6 +58,7 @@ quiet_cmd_modpost = MODPOST $(words $(filter-out vmlinux FORCE, $^)) modules
$(if $(KBUILD_EXTMOD),-i,-o) $(kernelsymfile) \ $(if $(KBUILD_EXTMOD),-i,-o) $(kernelsymfile) \
$(if $(KBUILD_EXTMOD),-I $(modulesymfile)) \ $(if $(KBUILD_EXTMOD),-I $(modulesymfile)) \
$(if $(KBUILD_EXTMOD),-o $(modulesymfile)) \ $(if $(KBUILD_EXTMOD),-o $(modulesymfile)) \
$(if $(KBUILD_EXTMOD),-w) \
$(wildcard vmlinux) $(filter-out FORCE,$^) $(wildcard vmlinux) $(filter-out FORCE,$^)
PHONY += __modpost PHONY += __modpost
......
...@@ -23,6 +23,8 @@ int have_vmlinux = 0; ...@@ -23,6 +23,8 @@ int have_vmlinux = 0;
static int all_versions = 0; static int all_versions = 0;
/* If we are modposting external module set to 1 */ /* If we are modposting external module set to 1 */
static int external_module = 0; static int external_module = 0;
/* Only warn about unresolved symbols */
static int warn_unresolved = 0;
/* How a symbol is exported */ /* How a symbol is exported */
enum export { enum export {
export_plain, export_unused, export_gpl, export_plain, export_unused, export_gpl,
...@@ -1196,16 +1198,19 @@ static void add_header(struct buffer *b, struct module *mod) ...@@ -1196,16 +1198,19 @@ static void add_header(struct buffer *b, struct module *mod)
/** /**
* Record CRCs for unresolved symbols * Record CRCs for unresolved symbols
**/ **/
static void add_versions(struct buffer *b, struct module *mod) static int add_versions(struct buffer *b, struct module *mod)
{ {
struct symbol *s, *exp; struct symbol *s, *exp;
int err = 0;
for (s = mod->unres; s; s = s->next) { for (s = mod->unres; s; s = s->next) {
exp = find_symbol(s->name); exp = find_symbol(s->name);
if (!exp || exp->module == mod) { if (!exp || exp->module == mod) {
if (have_vmlinux && !s->weak) if (have_vmlinux && !s->weak) {
warn("\"%s\" [%s.ko] undefined!\n", warn("\"%s\" [%s.ko] undefined!\n",
s->name, mod->name); s->name, mod->name);
err = warn_unresolved ? 0 : 1;
}
continue; continue;
} }
s->module = exp->module; s->module = exp->module;
...@@ -1214,7 +1219,7 @@ static void add_versions(struct buffer *b, struct module *mod) ...@@ -1214,7 +1219,7 @@ static void add_versions(struct buffer *b, struct module *mod)
} }
if (!modversions) if (!modversions)
return; return err;
buf_printf(b, "\n"); buf_printf(b, "\n");
buf_printf(b, "static const struct modversion_info ____versions[]\n"); 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,6 +1239,8 @@ static void add_versions(struct buffer *b, struct module *mod)
} }
buf_printf(b, "};\n"); buf_printf(b, "};\n");
return err;
} }
static void add_depends(struct buffer *b, struct module *mod, static void add_depends(struct buffer *b, struct module *mod,
...@@ -1411,8 +1418,9 @@ int main(int argc, char **argv) ...@@ -1411,8 +1418,9 @@ int main(int argc, char **argv)
char *kernel_read = NULL, *module_read = NULL; char *kernel_read = NULL, *module_read = NULL;
char *dump_write = NULL; char *dump_write = NULL;
int opt; int opt;
int err;
while ((opt = getopt(argc, argv, "i:I:mo:a")) != -1) { while ((opt = getopt(argc, argv, "i:I:mo:aw")) != -1) {
switch(opt) { switch(opt) {
case 'i': case 'i':
kernel_read = optarg; kernel_read = optarg;
...@@ -1430,6 +1438,9 @@ int main(int argc, char **argv) ...@@ -1430,6 +1438,9 @@ int main(int argc, char **argv)
case 'a': case 'a':
all_versions = 1; all_versions = 1;
break; break;
case 'w':
warn_unresolved = 1;
break;
default: default:
exit(1); exit(1);
} }
...@@ -1450,6 +1461,8 @@ int main(int argc, char **argv) ...@@ -1450,6 +1461,8 @@ int main(int argc, char **argv)
check_exports(mod); check_exports(mod);
} }
err = 0;
for (mod = modules; mod; mod = mod->next) { for (mod = modules; mod; mod = mod->next) {
if (mod->skip) if (mod->skip)
continue; continue;
...@@ -1457,7 +1470,7 @@ int main(int argc, char **argv) ...@@ -1457,7 +1470,7 @@ int main(int argc, char **argv)
buf.pos = 0; buf.pos = 0;
add_header(&buf, mod); add_header(&buf, mod);
add_versions(&buf, mod); err |= add_versions(&buf, mod);
add_depends(&buf, mod, modules); add_depends(&buf, mod, modules);
add_moddevtable(&buf, mod); add_moddevtable(&buf, mod);
add_srcversion(&buf, mod); add_srcversion(&buf, mod);
...@@ -1469,5 +1482,5 @@ int main(int argc, char **argv) ...@@ -1469,5 +1482,5 @@ int main(int argc, char **argv)
if (dump_write) if (dump_write)
write_dump(dump_write); write_dump(dump_write);
return 0; return err;
} }
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment