Re: [PATCH v6 12/20] modpost: check static EXPORT_SYMBOL* by modpost again

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Sun, May 21, 2023 at 9:05 AM Masahiro Yamada <masahiroy@xxxxxxxxxx> wrote:
>
> Commit 31cb50b5590f ("kbuild: check static EXPORT_SYMBOL* by script
> instead of modpost") moved the static EXPORT_SYMBOL* check from the
> mostpost to a shell script because I thought it must be checked per
> compilation unit to avoid false negatives.
>
> I came up with an idea to do this in modpost, against combined ELF
> files. The relocation entries in ELF will find the correct exported
> symbol even if there exist symbols with the same name in different
> compilation units.
>
> Again, the same sample code.
>
>   Makefile:
>
>     obj-y += foo1.o foo2.o
>
>   foo1.c:
>
>     #include <linux/export.h>
>     static void foo(void) {}
>     EXPORT_SYMBOL(foo);
>
>   foo2.c:
>
>     void foo(void) {}
>
> Then, modpost can catch it correctly.
>
>     MODPOST Module.symvers
>   ERROR: modpost: vmlinux: local symbol 'foo' was exported
>
> Signed-off-by: Masahiro Yamada <masahiroy@xxxxxxxxxx>

Thanks for the patch!
Reviewed-by: Nick Desaulniers <ndesaulniers@xxxxxxxxxx>

> ---
>
> Changes in v6:
>   - Make the symbol name in the warning more precise
>
>  scripts/Makefile.build     |  4 ---
>  scripts/check-local-export | 70 --------------------------------------
>  scripts/mod/modpost.c      |  7 ++++
>  3 files changed, 7 insertions(+), 74 deletions(-)
>  delete mode 100755 scripts/check-local-export
>
> diff --git a/scripts/Makefile.build b/scripts/Makefile.build
> index 6bf026a304e4..bd4123795299 100644
> --- a/scripts/Makefile.build
> +++ b/scripts/Makefile.build
> @@ -220,8 +220,6 @@ cmd_gen_ksymdeps = \
>         $(CONFIG_SHELL) $(srctree)/scripts/gen_ksymdeps.sh $@ >> $(dot-target).cmd
>  endif
>
> -cmd_check_local_export = $(srctree)/scripts/check-local-export $@
> -
>  ifneq ($(findstring 1, $(KBUILD_EXTRA_WARN)),)
>  cmd_warn_shared_object = $(if $(word 2, $(modname-multi)),$(warning $(kbuild-file): $*.o is added to multiple modules: $(modname-multi)))
>  endif
> @@ -229,7 +227,6 @@ endif
>  define rule_cc_o_c
>         $(call cmd_and_fixdep,cc_o_c)
>         $(call cmd,gen_ksymdeps)
> -       $(call cmd,check_local_export)
>         $(call cmd,checksrc)
>         $(call cmd,checkdoc)
>         $(call cmd,gen_objtooldep)
> @@ -241,7 +238,6 @@ endef
>  define rule_as_o_S
>         $(call cmd_and_fixdep,as_o_S)
>         $(call cmd,gen_ksymdeps)
> -       $(call cmd,check_local_export)
>         $(call cmd,gen_objtooldep)
>         $(call cmd,gen_symversions_S)
>         $(call cmd,warn_shared_object)
> diff --git a/scripts/check-local-export b/scripts/check-local-export
> deleted file mode 100755
> index 969a313b9299..000000000000
> --- a/scripts/check-local-export
> +++ /dev/null
> @@ -1,70 +0,0 @@
> -#!/bin/sh
> -# SPDX-License-Identifier: GPL-2.0-only
> -#
> -# Copyright (C) 2022 Masahiro Yamada <masahiroy@xxxxxxxxxx>
> -# Copyright (C) 2022 Owen Rafferty <owen@xxxxxxxxxxxxxxxx>
> -#
> -# Exit with error if a local exported symbol is found.
> -# EXPORT_SYMBOL should be used for global symbols.
> -
> -set -e
> -pid=$$
> -
> -# If there is no symbol in the object, ${NM} (both GNU nm and llvm-nm) shows
> -# 'no symbols' diagnostic (but exits with 0). It is harmless and hidden by
> -# '2>/dev/null'. However, it suppresses real error messages as well. Add a
> -# hand-crafted error message here.
> -#
> -# TODO:
> -# Use --quiet instead of 2>/dev/null when we upgrade the minimum version of
> -# binutils to 2.37, llvm to 13.0.0.
> -# Then, the following line will be simpler:
> -#   { ${NM} --quiet ${1} || kill 0; } |
> -
> -{ ${NM} ${1} 2>/dev/null || { echo "${0}: ${NM} failed" >&2; kill $pid; } } |
> -${AWK} -v "file=${1}" '
> -BEGIN {
> -       i = 0
> -}
> -
> -# Skip the line if the number of fields is less than 3.
> -#
> -# case 1)
> -#   For undefined symbols, the first field (value) is empty.
> -#   The outout looks like this:
> -#     "                 U _printk"
> -#   It is unneeded to record undefined symbols.
> -#
> -# case 2)
> -#   For Clang LTO, llvm-nm outputs a line with type t but empty name:
> -#     "---------------- t"
> -!length($3) {
> -       next
> -}
> -
> -# save (name, type) in the associative array
> -{ symbol_types[$3]=$2 }
> -
> -# append the exported symbol to the array
> -($3 ~ /^__export_symbol_(gpl)?_.*/) {
> -       export_symbols[i] = $3
> -       sub(/^__export_symbol_(gpl)?_/, "", export_symbols[i])
> -       i++
> -}
> -
> -END {
> -       exit_code = 0
> -       for (j = 0; j < i; ++j) {
> -               name = export_symbols[j]
> -               # nm(3) says "If lowercase, the symbol is usually local"
> -               if (symbol_types[name] ~ /[a-z]/) {
> -                       printf "%s: error: local symbol %s was exported\n",
> -                               file, name | "cat 1>&2"
> -                       exit_code = 1
> -               }
> -       }
> -
> -       exit exit_code
> -}'
> -
> -exit $?
> diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c
> index 8b94090d0743..dd1d066f1214 100644
> --- a/scripts/mod/modpost.c
> +++ b/scripts/mod/modpost.c
> @@ -1235,6 +1235,13 @@ static void check_export_symbol(struct module *mod, struct elf_info *elf,
>                 return;
>         }
>
> +       if (ELF_ST_BIND(sym->st_info) != STB_GLOBAL &&
> +           ELF_ST_BIND(sym->st_info) != STB_WEAK) {
> +               error("%s: local symbol '%s' was exported\n", mod->name,
> +                     label_name + strlen(prefix));
> +               return;
> +       }
> +
>         if (strcmp(label_name + strlen(prefix), name)) {
>                 error("%s: .export_symbol section references '%s', but it does not seem to be an export symbol\n",
>                       mod->name, name);
> --
> 2.39.2
>


-- 
Thanks,
~Nick Desaulniers




[Index of Archives]     [Linux&nblp;USB Development]     [Linux Media]     [Video for Linux]     [Linux Audio Users]     [Yosemite Secrets]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux