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>
This commit is contained in:
parent
2212692913
commit
c53ddacdc0
|
@ -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;
|
||||||
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)
|
||||||
/**
|
/**
|
||||||
* 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)
|
||||||
}
|
}
|
||||||
|
|
||||||
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)
|
||||||
}
|
}
|
||||||
|
|
||||||
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)
|
||||||
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)
|
||||||
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)
|
||||||
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)
|
||||||
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)
|
||||||
if (dump_write)
|
if (dump_write)
|
||||||
write_dump(dump_write);
|
write_dump(dump_write);
|
||||||
|
|
||||||
return 0;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue