Skip to content

Commit

Permalink
kbuild: fix false-positive modpost warning when all symbols are trimmed
Browse files Browse the repository at this point in the history
Nathan reports that the mips defconfig emits the following warning:

  WARNING: modpost: Symbol info of vmlinux is missing. Unresolved symbol check will be entirely skipped.

This false-positive happens when CONFIG_TRIM_UNUSED_KSYMS is enabled,
but no CONFIG option is set to 'm'.

Commit a059047 ("nfs: fix PNFS_FLEXFILE_LAYOUT Kconfig default")
turned the last 'm' into 'y' for the mips defconfig, and uncovered
this issue.

In this case, the module feature itself is enabled, but we have no
module to build. As a result, CONFIG_TRIM_UNUSED_KSYMS drops all the
instances of EXPORT_SYMBOL. Then, modpost wrongly assumes vmlinux is
missing because vmlinux.symvers is empty. (As another false-positive
case, you can create a module that does not use any symbol of vmlinux).

The current behavior is to entirely suppress the unresolved symbol
warnings when vmlinux is missing just because there are too many.
I found the origin of this code in the historical git tree. [1]

If this is a matter of noisiness, I think modpost can display the
first 10 warnings, and the number of suppressed warnings at the end.

You will get a bit noisier logs when you run 'make modules' without
vmlinux, but such warnings are better to show because you never know
the resulting modules are actually loadable or not.

This commit changes the following:

 - If any of input *.symver files is missing, pass -w option to let
   the module build keep going with warnings instead of errors.

 - If there are too many (10+) unresolved symbol warnings, show only
   the first 10, and also the number of suppressed warnings.

[1]: https://git.kernel.org/pub/scm/linux/kernel/git/history/history.git/commit/?id=1cc0e0529569bf6a94f6d49770aa6d4b599d2c46

Reported-by: Nathan Chancellor <[email protected]>
Signed-off-by: Masahiro Yamada <[email protected]>
  • Loading branch information
masahir0y committed Apr 24, 2021
1 parent 5ab70ff commit 4475dff
Show file tree
Hide file tree
Showing 2 changed files with 17 additions and 15 deletions.
7 changes: 5 additions & 2 deletions scripts/Makefile.modpost
Original file line number Diff line number Diff line change
Expand Up @@ -98,9 +98,11 @@ output-symdump := $(KBUILD_EXTMOD)/Module.symvers

endif

existing-input-symdump := $(wildcard $(input-symdump))

# modpost options for modules (both in-kernel and external)
MODPOST += \
$(addprefix -i ,$(wildcard $(input-symdump))) \
$(addprefix -i ,$(existing-input-symdump)) \
$(if $(KBUILD_NSDEPS),-d $(MODULES_NSDEPS)) \
$(if $(CONFIG_MODULE_ALLOW_MISSING_NAMESPACE_IMPORTS)$(KBUILD_NSDEPS),-N)

Expand All @@ -114,6 +116,7 @@ VPATH :=
$(input-symdump):
@echo >&2 'WARNING: Symbol version dump "$@" is missing.'
@echo >&2 ' Modules may not have dependencies or modversions.'
@echo >&2 ' You may get many unresolved symbol warnings.'

ifdef CONFIG_LTO_CLANG
# With CONFIG_LTO_CLANG, .o files might be LLVM bitcode, so we need to run
Expand All @@ -134,7 +137,7 @@ endif
modules := $(sort $(shell cat $(MODORDER)))

# KBUILD_MODPOST_WARN can be set to avoid error out in case of undefined symbols
ifneq ($(KBUILD_MODPOST_WARN),)
ifneq ($(KBUILD_MODPOST_WARN)$(filter-out $(existing-input-symdump), $(input-symdump)),)
MODPOST += -w
endif

Expand Down
25 changes: 12 additions & 13 deletions scripts/mod/modpost.c
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,6 @@

/* Are we using CONFIG_MODVERSIONS? */
static int modversions = 0;
/* Warn about undefined symbols? (do so if we have vmlinux) */
static int have_vmlinux = 0;
/* Is CONFIG_MODULE_SRCVERSION_ALL set? */
static int all_versions = 0;
/* If we are modposting external module set to 1 */
Expand All @@ -41,6 +39,13 @@ static int allow_missing_ns_imports;

static bool error_occurred;

/*
* Cut off the warnings when there are too many. This typically occurs when
* vmlinux is missing. ('make modules' without building vmlinux.)
*/
#define MAX_UNRESOLVED_REPORTS 10
static unsigned int nr_unresolved;

enum export {
export_plain,
export_gpl,
Expand Down Expand Up @@ -177,9 +182,6 @@ static struct module *new_module(const char *modname)
mod->next = modules;
modules = mod;

if (mod->is_vmlinux)
have_vmlinux = 1;

return mod;
}

Expand Down Expand Up @@ -2141,7 +2143,7 @@ static void check_exports(struct module *mod)
const char *basename;
exp = find_symbol(s->name);
if (!exp || exp->module == mod) {
if (have_vmlinux && !s->weak)
if (!s->weak && nr_unresolved++ < MAX_UNRESOLVED_REPORTS)
modpost_log(warn_unresolved ? LOG_WARN : LOG_ERROR,
"\"%s\" [%s.ko] undefined!\n",
s->name, mod->name);
Expand Down Expand Up @@ -2545,13 +2547,6 @@ int main(int argc, char **argv)
if (files_source)
read_symbols_from_files(files_source);

/*
* When there's no vmlinux, don't print warnings about
* unresolved symbols (since there'll be too many ;)
*/
if (!have_vmlinux)
warn("Symbol info of vmlinux is missing. Unresolved symbol check will be entirely skipped.\n");

for (mod = modules; mod; mod = mod->next) {
char fname[PATH_MAX];

Expand Down Expand Up @@ -2595,6 +2590,10 @@ int main(int argc, char **argv)
}
}

if (nr_unresolved > MAX_UNRESOLVED_REPORTS)
warn("suppressed %u unresolved symbol warnings because there were too many)\n",
nr_unresolved - MAX_UNRESOLVED_REPORTS);

free(buf.p);

return error_occurred ? 1 : 0;
Expand Down

0 comments on commit 4475dff

Please sign in to comment.