From 9ec36c01e0be23b3ab13447b78a89eacbd37497e Mon Sep 17 00:00:00 2001 From: Raghavendra Rao Ananta Date: Tue, 14 Apr 2020 22:31:15 -0700 Subject: [PATCH] kbuild: Add support for CONFIG_UNUSED_KSYMS_WHITELIST_ONLY CONFIG_UNUSED_KSYMS_WHITELIST_ONLY extends the support for the existing CONFIG_UNUSED_KSYMS_WHITELIST in a way that, if enabled, it would allow the kbuild to export ONLY the symbols that are supplied as a part of whitelist (and of course the ones exported by modules). That is, the build would break for modules during modpost with: ERROR: "" [.ko] undefined! When enabled, the option is quite useful in build integration systems to detect if the whitelist file needs an update. Change-Id: Ica0a270214d4d51f6e2269fdc591fb86acbc4f97 Signed-off-by: Raghavendra Rao Ananta --- Makefile | 2 ++ init/Kconfig | 11 +++++++++ scripts/adjust_autoksyms.sh | 5 ++++ scripts/gen_autoksyms.sh | 46 ++++++++++++++++++++++++++++++------- 4 files changed, 56 insertions(+), 8 deletions(-) diff --git a/Makefile b/Makefile index d16251b1f8d8..8348e298d7b7 100644 --- a/Makefile +++ b/Makefile @@ -1362,6 +1362,8 @@ all: modules PHONY += modules modules: $(if $(KBUILD_BUILTIN),vmlinux) modules.order modules.builtin + $(Q)$(CONFIG_SHELL) $(srctree)/scripts/adjust_autoksyms.sh \ + "$(MAKE) -f $(srctree)/Makefile vmlinux" $(Q)$(MAKE) -f $(srctree)/scripts/Makefile.modpost $(Q)$(CONFIG_SHELL) $(srctree)/scripts/modules-check.sh diff --git a/init/Kconfig b/init/Kconfig index 6a6e169b998a..e43065f1e802 100644 --- a/init/Kconfig +++ b/init/Kconfig @@ -2250,6 +2250,17 @@ config UNUSED_KSYMS_WHITELIST one per line. The path can be absolute, or relative to the kernel source tree. +config UNUSED_KSYMS_WHITELIST_ONLY + bool "Export ONLY the symbols that are a part of whitelist" + depends on UNUSED_KSYMS_WHITELIST != "" + help + Keep ONLY the symbols that are defined in the whitelist. The + CONFIG works on top of CONFIG_UNUSED_KSYMS_WHITELIST which takes + whitelist file(s) as its settings, and would export only the + symbols listed in these file(s). + This is mainly used to detect if drivers are using the symbols + outside of the whitelist. + endif # MODULES config MODULES_TREE_LOOKUP diff --git a/scripts/adjust_autoksyms.sh b/scripts/adjust_autoksyms.sh index 2b366d945ccb..7028a5a56d66 100755 --- a/scripts/adjust_autoksyms.sh +++ b/scripts/adjust_autoksyms.sh @@ -40,6 +40,11 @@ esac # Generate a new symbol list file $CONFIG_SHELL $srctree/scripts/gen_autoksyms.sh "$new_ksyms_file" +if [ -n "$CONFIG_UNUSED_KSYMS_WHITELIST_ONLY" ] && [ -f "vmlinux" ] ; then + info "WARNING" "CONFIG_UNUSED_KSYMS_WHITELIST_ONLY is enabled. "\ +"Non-whitelisted symbols will be undefined!" +fi + # Extract changes between old and new list and touch corresponding # dependency files. changed=$( diff --git a/scripts/gen_autoksyms.sh b/scripts/gen_autoksyms.sh index 679c9f05e4b4..d780dde5136d 100755 --- a/scripts/gen_autoksyms.sh +++ b/scripts/gen_autoksyms.sh @@ -21,13 +21,18 @@ esac ksym_wl=/dev/null if [ -n "$CONFIG_UNUSED_KSYMS_WHITELIST" ]; then - # Use 'eval' to expand the whitelist path and check if it is relative - eval ksym_wl="$CONFIG_UNUSED_KSYMS_WHITELIST" - [ "${ksym_wl}" != "${ksym_wl#/}" ] || ksym_wl="$abs_srctree/$ksym_wl" - if [ ! -f "$ksym_wl" ]; then - echo "ERROR: '$ksym_wl' whitelist file not found" >&2 - exit 1 - fi + for UNUSED_KSYMS_WHITELIST_FILE in $CONFIG_UNUSED_KSYMS_WHITELIST; do + # Use 'eval' to expand the whitelist path and + # check if it is relative + eval ksym_wl="$UNUSED_KSYMS_WHITELIST_FILE" + [ "${ksym_wl}" != "${ksym_wl#/}" ] || + ksym_wl="$abs_srctree/$ksym_wl" + if [ ! -f "$ksym_wl" ]; then + echo "ERROR: '$ksym_wl' whitelist file not found" >&2 + exit 1 + fi + ksym_wls="$ksym_wls $ksym_wl" + done fi # Generate a new ksym list file with symbols needed by the current @@ -42,7 +47,8 @@ EOT [ -f modules.order ] && modlist=modules.order || modlist=/dev/null sed 's/ko$/mod/' $modlist | xargs -n1 sed -n -e '2{s/ /\n/g;/^$/!p;}' -- | -cat - "$ksym_wl" | +cat - $ksym_wls | +sed 's/^#.*//;s/^ *//;/[[abi_whitelist]]/g' | sort -u | sed -e 's/\(.*\)/#define __KSYM_\1 1/' >> "$output_file" @@ -50,3 +56,27 @@ sed -e 's/\(.*\)/#define __KSYM_\1 1/' >> "$output_file" if [ -n "$CONFIG_MODVERSIONS" ]; then echo "#define __KSYM_module_layout 1" >> "$output_file" fi + +if [ -n "$CONFIG_UNUSED_KSYMS_WHITELIST_ONLY" ] && [ -f "vmlinux" ] ; then + syms_from_whitelist="$(mktemp)" + syms_from_vmlinux="$(mktemp)" + + cat $ksym_wls | + sed 's/^#.*//;s/^ *//;/[[abi_whitelist]]/g' | + sort -u > "$syms_from_whitelist" + + $NM --defined-only vmlinux | + grep "__ksymtab_" | + sed 's/^.*__ksymtab_//' | + sort -u > "$syms_from_vmlinux" + + # Forcefully unexport the symbols that are not declared in the whitelist + syms_to_unexport=$(comm -13 "$syms_from_whitelist" "$syms_from_vmlinux") + + for sym_to_unexport in $syms_to_unexport; do + sed -i "/^#define __KSYM_${sym_to_unexport} 1/d" \ + "$output_file" + done + + rm -f "$syms_from_whitelist" "$syms_from_vmlinux" +fi