From: Masahiro Yamada <masahiroy@kernel.org>
To: linux-kbuild@vger.kernel.org
Cc: linux-kernel@vger.kernel.org,
Nathan Chancellor <nathan@kernel.org>,
Nick Desaulniers <ndesaulniers@google.com>,
Nicolas Schier <nicolas@fjasle.eu>,
linux-um@lists.infradead.org,
Masahiro Yamada <masahiroy@kernel.org>
Subject: [PATCH v8 08/11] kbuild: implement CONFIG_TRIM_UNUSED_KSYMS without recursion
Date: Sat, 10 Jun 2023 18:13:17 +0900 [thread overview]
Message-ID: <20230610091320.1054554-9-masahiroy@kernel.org> (raw)
In-Reply-To: <20230610091320.1054554-1-masahiroy@kernel.org>
When CONFIG_TRIM_UNUSED_KSYMS is enabled, Kbuild recursively traverses
the directory tree to determine which EXPORT_SYMBOL to trim. If an
EXPORT_SYMBOL turns out to be unused by anyone, Kbuild begins the
second traverse, where some source files are recompiled with their
EXPORT_SYMBOL() tuned into a no-op.
Linus stated negative opinions about this slowness in commits:
- 5cf0fd591f2e ("Kbuild: disable TRIM_UNUSED_KSYMS option")
- a555bdd0c58c ("Kbuild: enable TRIM_UNUSED_KSYMS again, with some guarding")
We can do this better now. The final data structures of EXPORT_SYMBOL
are generated by the modpost stage, so modpost can selectively emit
KSYMTAB entries that are really used by modules.
Commit f73edc8951b2 ("kbuild: unify two modpost invocations") is another
ground-work to do this in a one-pass algorithm. With the list of modules,
modpost sets sym->used if it is used by a module. modpost emits KSYMTAB
only for symbols with sym->used==true.
BTW, Nicolas explained why the trimming was implemented with recursion:
https://lore.kernel.org/all/2o2rpn97-79nq-p7s2-nq5-8p83391473r@syhkavp.arg/
Actually, we never achieved that level of optimization where the chain
reaction of trimming comes into play because:
- CONFIG_LTO_CLANG cannot remove any unused symbols
- CONFIG_LD_DEAD_CODE_DATA_ELIMINATION is enabled only for vmlinux,
but not modules
If deeper trimming is required, we need to revisit this, but I guess
that is unlikely to happen.
Signed-off-by: Masahiro Yamada <masahiroy@kernel.org>
---
(no changes since v7)
Changes in v7:
- Remove *.usyms
Changes in v5:
- Clean up more
.gitignore | 2 -
Makefile | 22 ++---------
include/linux/export.h | 67 +++++-----------------------------
scripts/Makefile.build | 15 +-------
scripts/Makefile.modpost | 7 ++++
scripts/adjust_autoksyms.sh | 73 -------------------------------------
scripts/basic/fixdep.c | 3 +-
scripts/gen_autoksyms.sh | 62 -------------------------------
scripts/gen_ksymdeps.sh | 30 ---------------
scripts/mod/modpost.c | 54 ++++++++++++++++++++++++---
scripts/remove-stale-files | 4 ++
11 files changed, 75 insertions(+), 264 deletions(-)
delete mode 100755 scripts/adjust_autoksyms.sh
delete mode 100755 scripts/gen_autoksyms.sh
delete mode 100755 scripts/gen_ksymdeps.sh
diff --git a/.gitignore b/.gitignore
index 7f86e0837909..c3ce78ca20d2 100644
--- a/.gitignore
+++ b/.gitignore
@@ -51,7 +51,6 @@
*.symversions
*.tab.[ch]
*.tar
-*.usyms
*.xz
*.zst
Module.symvers
@@ -112,7 +111,6 @@ modules.order
#
/include/config/
/include/generated/
-/include/ksym/
/arch/*/include/generated/
# stgit generated dirs
diff --git a/Makefile b/Makefile
index f836936fb4d8..cc3fe09c4dec 100644
--- a/Makefile
+++ b/Makefile
@@ -1193,28 +1193,12 @@ endif
export KBUILD_VMLINUX_LIBS
export KBUILD_LDS := arch/$(SRCARCH)/kernel/vmlinux.lds
-# Recurse until adjust_autoksyms.sh is satisfied
-PHONY += autoksyms_recursive
ifdef CONFIG_TRIM_UNUSED_KSYMS
# For the kernel to actually contain only the needed exported symbols,
# we have to build modules as well to determine what those symbols are.
-# (this can be evaluated only once include/config/auto.conf has been included)
KBUILD_MODULES := 1
-
-autoksyms_recursive: $(build-dir) modules.order
- $(Q)$(CONFIG_SHELL) $(srctree)/scripts/adjust_autoksyms.sh \
- "$(MAKE) -f $(srctree)/Makefile autoksyms_recursive"
endif
-autoksyms_h := $(if $(CONFIG_TRIM_UNUSED_KSYMS), include/generated/autoksyms.h)
-
-quiet_cmd_autoksyms_h = GEN $@
- cmd_autoksyms_h = mkdir -p $(dir $@); \
- $(CONFIG_SHELL) $(srctree)/scripts/gen_autoksyms.sh $@
-
-$(autoksyms_h):
- $(call cmd,autoksyms_h)
-
# '$(AR) mPi' needs 'T' to workaround the bug of llvm-ar <= 14
quiet_cmd_ar_vmlinux.a = AR $@
cmd_ar_vmlinux.a = \
@@ -1223,7 +1207,7 @@ quiet_cmd_ar_vmlinux.a = AR $@
$(AR) mPiT $$($(AR) t $@ | sed -n 1p) $@ $$($(AR) t $@ | grep -F -f $(srctree)/scripts/head-object-list.txt)
targets += vmlinux.a
-vmlinux.a: $(KBUILD_VMLINUX_OBJS) scripts/head-object-list.txt autoksyms_recursive FORCE
+vmlinux.a: $(KBUILD_VMLINUX_OBJS) scripts/head-object-list.txt FORCE
$(call if_changed,ar_vmlinux.a)
PHONY += vmlinux_o
@@ -1279,7 +1263,7 @@ scripts: scripts_basic scripts_dtc
PHONY += prepare archprepare
archprepare: outputmakefile archheaders archscripts scripts include/config/kernel.release \
- asm-generic $(version_h) $(autoksyms_h) include/generated/utsrelease.h \
+ asm-generic $(version_h) include/generated/utsrelease.h \
include/generated/compile.h include/generated/autoconf.h remove-stale-files
prepare0: archprepare
@@ -2039,7 +2023,7 @@ clean: $(clean-dirs)
-o -name '*.dtb.S' -o -name '*.dtbo.S' \
-o -name '*.dt.yaml' \
-o -name '*.dwo' -o -name '*.lst' \
- -o -name '*.su' -o -name '*.mod' -o -name '*.usyms' \
+ -o -name '*.su' -o -name '*.mod' \
-o -name '.*.d' -o -name '.*.tmp' -o -name '*.mod.c' \
-o -name '*.lex.c' -o -name '*.tab.[ch]' \
-o -name '*.asn1.[ch]' \
diff --git a/include/linux/export.h b/include/linux/export.h
index 245ecd342772..8a9b72386fff 100644
--- a/include/linux/export.h
+++ b/include/linux/export.h
@@ -37,31 +37,13 @@ extern struct module __this_module;
#define __EXPORT_SYMBOL_REF(sym) .balign 4; .long sym
#endif
-#define ____EXPORT_SYMBOL(sym, license, ns) \
+#define ___EXPORT_SYMBOL(sym, license, ns) \
.section ".export_symbol","a" ; \
__export_symbol_##license##_##sym: ; \
.asciz ns ; \
__EXPORT_SYMBOL_REF(sym) ; \
.previous
-#ifdef __GENKSYMS__
-
-#define ___EXPORT_SYMBOL(sym, sec, ns) __GENKSYMS_EXPORT_SYMBOL(sym)
-
-#elif defined(__ASSEMBLY__)
-
-#define ___EXPORT_SYMBOL(sym, license, ns) \
- ____EXPORT_SYMBOL(sym, license, ns)
-
-#else
-
-#define ___EXPORT_SYMBOL(sym, license, ns) \
- extern typeof(sym) sym; \
- __ADDRESSABLE(sym) \
- asm(__stringify(____EXPORT_SYMBOL(sym, license, ns)))
-
-#endif
-
#if !defined(CONFIG_MODULES) || defined(__DISABLE_EXPORTS)
/*
@@ -71,50 +53,21 @@ extern struct module __this_module;
*/
#define __EXPORT_SYMBOL(sym, sec, ns)
-#elif defined(CONFIG_TRIM_UNUSED_KSYMS)
+#elif defined(__GENKSYMS__)
-#include <generated/autoksyms.h>
+#define __EXPORT_SYMBOL(sym, sec, ns) __GENKSYMS_EXPORT_SYMBOL(sym)
-/*
- * For fine grained build dependencies, we want to tell the build system
- * about each possible exported symbol even if they're not actually exported.
- * We use a symbol pattern __ksym_marker_<symbol> that the build system filters
- * from the $(NM) output (see scripts/gen_ksymdeps.sh). These symbols are
- * discarded in the final link stage.
- */
+#elif defined(__ASSEMBLY__)
-#ifdef __ASSEMBLY__
-
-#define __ksym_marker(sym) \
- .section ".discard.ksym","a" ; \
-__ksym_marker_##sym: ; \
- .previous
+#define __EXPORT_SYMBOL(sym, license, ns) \
+ ___EXPORT_SYMBOL(sym, license, ns)
#else
-#define __ksym_marker(sym) \
- static int __ksym_marker_##sym[0] __section(".discard.ksym") __used
-
-#endif
-
-#define __EXPORT_SYMBOL(sym, sec, ns) \
- __ksym_marker(sym); \
- __cond_export_sym(sym, sec, ns, __is_defined(__KSYM_##sym))
-#define __cond_export_sym(sym, sec, ns, conf) \
- ___cond_export_sym(sym, sec, ns, conf)
-#define ___cond_export_sym(sym, sec, ns, enabled) \
- __cond_export_sym_##enabled(sym, sec, ns)
-#define __cond_export_sym_1(sym, sec, ns) ___EXPORT_SYMBOL(sym, sec, ns)
-
-#ifdef __GENKSYMS__
-#define __cond_export_sym_0(sym, sec, ns) __GENKSYMS_EXPORT_SYMBOL(sym)
-#else
-#define __cond_export_sym_0(sym, sec, ns) /* nothing */
-#endif
-
-#else
-
-#define __EXPORT_SYMBOL(sym, sec, ns) ___EXPORT_SYMBOL(sym, sec, ns)
+#define __EXPORT_SYMBOL(sym, license, ns) \
+ extern typeof(sym) sym; \
+ __ADDRESSABLE(sym) \
+ asm(__stringify(___EXPORT_SYMBOL(sym, license, ns)))
#endif /* CONFIG_MODULES */
diff --git a/scripts/Makefile.build b/scripts/Makefile.build
index d676bc15e4e7..51477dd71427 100644
--- a/scripts/Makefile.build
+++ b/scripts/Makefile.build
@@ -82,7 +82,7 @@ ifdef need-builtin
targets-for-builtin += $(obj)/built-in.a
endif
-targets-for-modules := $(foreach x, o mod $(if $(CONFIG_TRIM_UNUSED_KSYMS), usyms), \
+targets-for-modules := $(foreach x, o mod, \
$(patsubst %.o, %.$x, $(filter %.o, $(obj-m))))
ifdef need-modorder
@@ -217,18 +217,12 @@ is-standard-object = $(if $(filter-out y%, $(OBJECT_FILES_NON_STANDARD_$(basetar
$(obj)/%.o: objtool-enabled = $(if $(is-standard-object),$(if $(delay-objtool),$(is-single-obj-m),y))
-ifdef CONFIG_TRIM_UNUSED_KSYMS
-cmd_gen_ksymdeps = \
- $(CONFIG_SHELL) $(srctree)/scripts/gen_ksymdeps.sh $@ >> $(dot-target).cmd
-endif
-
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
define rule_cc_o_c
$(call cmd_and_fixdep,cc_o_c)
- $(call cmd,gen_ksymdeps)
$(call cmd,checksrc)
$(call cmd,checkdoc)
$(call cmd,gen_objtooldep)
@@ -239,7 +233,6 @@ endef
define rule_as_o_S
$(call cmd_and_fixdep,as_o_S)
- $(call cmd,gen_ksymdeps)
$(call cmd,gen_objtooldep)
$(call cmd,gen_symversions_S)
$(call cmd,warn_shared_object)
@@ -258,12 +251,6 @@ cmd_mod = printf '%s\n' $(call real-search, $*.o, .o, -objs -y -m) | \
$(obj)/%.mod: FORCE
$(call if_changed,mod)
-# List module undefined symbols
-cmd_undefined_syms = $(NM) $< | sed -n 's/^ *U //p' > $@
-
-$(obj)/%.usyms: $(obj)/%.o FORCE
- $(call if_changed,undefined_syms)
-
quiet_cmd_cc_lst_c = MKLST $@
cmd_cc_lst_c = $(CC) $(c_flags) -g -c -o $*.o $< && \
$(CONFIG_SHELL) $(srctree)/scripts/makelst $*.o \
diff --git a/scripts/Makefile.modpost b/scripts/Makefile.modpost
index 074e27c0c140..65133fcdd5b8 100644
--- a/scripts/Makefile.modpost
+++ b/scripts/Makefile.modpost
@@ -91,6 +91,13 @@ targets += .vmlinux.objs
.vmlinux.objs: vmlinux.a $(KBUILD_VMLINUX_LIBS) FORCE
$(call if_changed,vmlinux_objs)
+ifdef CONFIG_TRIM_UNUSED_KSYMS
+ksym-wl := $(CONFIG_UNUSED_KSYMS_WHITELIST)
+ksym-wl := $(if $(filter-out /%, $(ksym-wl)),$(srctree)/)$(ksym-wl)
+modpost-args += -t $(addprefix -u, $(ksym-wl))
+modpost-deps += $(ksym-wl)
+endif
+
ifeq ($(wildcard vmlinux.o),)
missing-input := vmlinux.o
output-symdump := modules-only.symvers
diff --git a/scripts/adjust_autoksyms.sh b/scripts/adjust_autoksyms.sh
deleted file mode 100755
index f1b5ac818411..000000000000
--- a/scripts/adjust_autoksyms.sh
+++ /dev/null
@@ -1,73 +0,0 @@
-#!/bin/sh
-# SPDX-License-Identifier: GPL-2.0-only
-
-# Script to update include/generated/autoksyms.h and dependency files
-#
-# Copyright: (C) 2016 Linaro Limited
-# Created by: Nicolas Pitre, January 2016
-#
-
-# Update the include/generated/autoksyms.h file.
-#
-# For each symbol being added or removed, the corresponding dependency
-# file's timestamp is updated to force a rebuild of the affected source
-# file. All arguments passed to this script are assumed to be a command
-# to be exec'd to trigger a rebuild of those files.
-
-set -e
-
-cur_ksyms_file="include/generated/autoksyms.h"
-new_ksyms_file="include/generated/autoksyms.h.tmpnew"
-
-info() {
- if [ "$quiet" != "silent_" ]; then
- printf " %-7s %s\n" "$1" "$2"
- fi
-}
-
-info "CHK" "$cur_ksyms_file"
-
-# Use "make V=1" to debug this script.
-case "$KBUILD_VERBOSE" in
-*1*)
- set -x
- ;;
-esac
-
-# Generate a new symbol list file
-$CONFIG_SHELL $srctree/scripts/gen_autoksyms.sh --modorder "$new_ksyms_file"
-
-# Extract changes between old and new list and touch corresponding
-# dependency files.
-changed=$(
-count=0
-sort "$cur_ksyms_file" "$new_ksyms_file" | uniq -u |
-sed -n 's/^#define __KSYM_\(.*\) 1/\1/p' |
-while read sympath; do
- if [ -z "$sympath" ]; then continue; fi
- depfile="include/ksym/${sympath}"
- mkdir -p "$(dirname "$depfile")"
- touch "$depfile"
- # Filesystems with coarse time precision may create timestamps
- # equal to the one from a file that was very recently built and that
- # needs to be rebuild. Let's guard against that by making sure our
- # dep files are always newer than the first file we created here.
- while [ ! "$depfile" -nt "$new_ksyms_file" ]; do
- touch "$depfile"
- done
- echo $((count += 1))
-done | tail -1 )
-changed=${changed:-0}
-
-if [ $changed -gt 0 ]; then
- # Replace the old list with tne new one
- old=$(grep -c "^#define __KSYM_" "$cur_ksyms_file" || true)
- new=$(grep -c "^#define __KSYM_" "$new_ksyms_file" || true)
- info "KSYMS" "symbols: before=$old, after=$new, changed=$changed"
- info "UPD" "$cur_ksyms_file"
- mv -f "$new_ksyms_file" "$cur_ksyms_file"
- # Then trigger a rebuild of affected source files
- exec $@
-else
- rm -f "$new_ksyms_file"
-fi
diff --git a/scripts/basic/fixdep.c b/scripts/basic/fixdep.c
index fa562806c2be..84b6efa849f4 100644
--- a/scripts/basic/fixdep.c
+++ b/scripts/basic/fixdep.c
@@ -246,8 +246,7 @@ static void *read_file(const char *filename)
/* Ignore certain dependencies */
static int is_ignored_file(const char *s, int len)
{
- return str_ends_with(s, len, "include/generated/autoconf.h") ||
- str_ends_with(s, len, "include/generated/autoksyms.h");
+ return str_ends_with(s, len, "include/generated/autoconf.h");
}
/* Do not parse these files */
diff --git a/scripts/gen_autoksyms.sh b/scripts/gen_autoksyms.sh
deleted file mode 100755
index 12bcfae940ee..000000000000
--- a/scripts/gen_autoksyms.sh
+++ /dev/null
@@ -1,62 +0,0 @@
-#!/bin/sh
-# SPDX-License-Identifier: GPL-2.0-only
-
-# Create an autoksyms.h header file from the list of all module's needed symbols
-# as recorded in *.usyms files and the user-provided symbol whitelist.
-
-set -e
-
-# Use "make V=1" to debug this script.
-case "$KBUILD_VERBOSE" in
-*1*)
- set -x
- ;;
-esac
-
-read_modorder=
-
-if [ "$1" = --modorder ]; then
- shift
- read_modorder=1
-fi
-
-output_file="$1"
-
-needed_symbols=
-
-# Special case for modversions (see modpost.c)
-if grep -q "^CONFIG_MODVERSIONS=y$" include/config/auto.conf; then
- needed_symbols="$needed_symbols module_layout"
-fi
-
-ksym_wl=$(sed -n 's/^CONFIG_UNUSED_KSYMS_WHITELIST=\(.*\)$/\1/p' include/config/auto.conf)
-if [ -n "$ksym_wl" ]; then
- [ "${ksym_wl}" != "${ksym_wl#/}" ] || ksym_wl="$abs_srctree/$ksym_wl"
- if [ ! -f "$ksym_wl" ] || [ ! -r "$ksym_wl" ]; then
- echo "ERROR: '$ksym_wl' whitelist file not found" >&2
- exit 1
- fi
-fi
-
-# Generate a new ksym list file with symbols needed by the current
-# set of modules.
-cat > "$output_file" << EOT
-/*
- * Automatically generated file; DO NOT EDIT.
- */
-
-EOT
-
-{
- [ -n "${read_modorder}" ] && sed 's/o$/usyms/' modules.order | xargs cat
- echo "$needed_symbols"
- [ -n "$ksym_wl" ] && cat "$ksym_wl"
-} | sed -e 's/ /\n/g' | sed -n -e '/^$/!p' |
-# Remove the dot prefix for ppc64; symbol names with a dot (.) hold entry
-# point addresses.
-sed -e 's/^\.//' |
-sort -u |
-# Ignore __this_module. It's not an exported symbol, and will be resolved
-# when the final .ko's are linked.
-grep -v '^__this_module$' |
-sed -e 's/\(.*\)/#define __KSYM_\1 1/' >> "$output_file"
diff --git a/scripts/gen_ksymdeps.sh b/scripts/gen_ksymdeps.sh
deleted file mode 100755
index 8ee533f33659..000000000000
--- a/scripts/gen_ksymdeps.sh
+++ /dev/null
@@ -1,30 +0,0 @@
-#!/bin/sh
-# SPDX-License-Identifier: GPL-2.0
-
-set -e
-
-# List of exported symbols
-#
-# If the object has no symbol, $NM warns 'no symbols'.
-# Suppress the stderr.
-# TODO:
-# Use -q instead of 2>/dev/null when we upgrade the minimum version of
-# binutils to 2.37, llvm to 13.0.0.
-ksyms=$($NM $1 2>/dev/null | sed -n 's/.*__ksym_marker_\(.*\)/\1/p')
-
-if [ -z "$ksyms" ]; then
- exit 0
-fi
-
-echo
-echo "ksymdeps_$1 := \\"
-
-for s in $ksyms
-do
- printf ' $(wildcard include/ksym/%s) \\\n' "$s"
-done
-
-echo
-echo "$1: \$(ksymdeps_$1)"
-echo
-echo "\$(ksymdeps_$1):"
diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c
index 7044b257424a..decb7d23ef9f 100644
--- a/scripts/mod/modpost.c
+++ b/scripts/mod/modpost.c
@@ -35,6 +35,9 @@ static bool warn_unresolved;
static int sec_mismatch_count;
static bool sec_mismatch_warn_only = true;
+/* Trim EXPORT_SYMBOLs that are unused by in-tree modules */
+static bool trim_unused_exports;
+
/* ignore missing files */
static bool ignore_missing_files;
/* If set to 1, only warn (instead of error) about missing ns imports */
@@ -219,6 +222,7 @@ struct symbol {
bool weak;
bool is_func;
bool is_gpl_only; /* exported by EXPORT_SYMBOL_GPL */
+ bool used; /* there exists a user of this symbol */
char name[];
};
@@ -1820,6 +1824,7 @@ static void check_exports(struct module *mod)
continue;
}
+ exp->used = true;
s->module = exp->module;
s->crc_valid = exp->crc_valid;
s->crc = exp->crc;
@@ -1843,6 +1848,23 @@ static void check_exports(struct module *mod)
}
}
+static void handle_white_list_exports(const char *white_list)
+{
+ char *buf, *p, *name;
+
+ buf = read_text_file(white_list);
+ p = buf;
+
+ while ((name = strsep(&p, "\n"))) {
+ struct symbol *sym = find_symbol(name);
+
+ if (sym)
+ sym->used = true;
+ }
+
+ free(buf);
+}
+
static void check_modname_len(struct module *mod)
{
const char *mod_name;
@@ -1913,10 +1935,14 @@ static void add_exported_symbols(struct buffer *buf, struct module *mod)
/* generate struct for exported symbols */
buf_printf(buf, "\n");
- list_for_each_entry(sym, &mod->exported_symbols, list)
+ list_for_each_entry(sym, &mod->exported_symbols, list) {
+ if (trim_unused_exports && !sym->used)
+ continue;
+
buf_printf(buf, "KSYMTAB_%s(%s, \"%s\", \"%s\");\n",
sym->is_func ? "FUNC" : "DATA", sym->name,
sym->is_gpl_only ? "_gpl" : "", sym->namespace);
+ }
if (!modversions)
return;
@@ -1924,6 +1950,9 @@ static void add_exported_symbols(struct buffer *buf, struct module *mod)
/* record CRCs for exported symbols */
buf_printf(buf, "\n");
list_for_each_entry(sym, &mod->exported_symbols, list) {
+ if (trim_unused_exports && !sym->used)
+ continue;
+
if (!sym->crc_valid)
warn("EXPORT symbol \"%s\" [%s%s] version generation failed, symbol will not be versioned.\n"
"Is \"%s\" prototyped in <asm/asm-prototypes.h>?\n",
@@ -2087,9 +2116,6 @@ static void write_mod_c_file(struct module *mod)
char fname[PATH_MAX];
int ret;
- check_modname_len(mod);
- check_exports(mod);
-
add_header(&buf, mod);
add_exported_symbols(&buf, mod);
add_versions(&buf, mod);
@@ -2223,12 +2249,13 @@ int main(int argc, char **argv)
{
struct module *mod;
char *missing_namespace_deps = NULL;
+ char *unused_exports_white_list = NULL;
char *dump_write = NULL, *files_source = NULL;
int opt;
LIST_HEAD(dump_lists);
struct dump_list *dl, *dl2;
- while ((opt = getopt(argc, argv, "ei:mnT:o:aWwENd:")) != -1) {
+ while ((opt = getopt(argc, argv, "ei:mnTt:o:auWwENd:")) != -1) {
switch (opt) {
case 'e':
external_module = true;
@@ -2253,6 +2280,12 @@ int main(int argc, char **argv)
case 'T':
files_source = optarg;
break;
+ case 't':
+ trim_unused_exports = true;
+ break;
+ case 'u':
+ unused_exports_white_list = optarg;
+ break;
case 'W':
extra_warn = true;
break;
@@ -2285,6 +2318,17 @@ int main(int argc, char **argv)
if (files_source)
read_symbols_from_files(files_source);
+ list_for_each_entry(mod, &modules, list) {
+ if (mod->from_dump || mod->is_vmlinux)
+ continue;
+
+ check_modname_len(mod);
+ check_exports(mod);
+ }
+
+ if (unused_exports_white_list)
+ handle_white_list_exports(unused_exports_white_list);
+
list_for_each_entry(mod, &modules, list) {
if (mod->from_dump)
continue;
diff --git a/scripts/remove-stale-files b/scripts/remove-stale-files
index 7f432900671a..f3659ea0335b 100755
--- a/scripts/remove-stale-files
+++ b/scripts/remove-stale-files
@@ -33,3 +33,7 @@ rm -f rust/target.json
rm -f scripts/bin2c
rm -f .scmversion
+
+rm -rf include/ksym
+
+find . -name '*.usyms' | xargs rm -f
--
2.39.2
WARNING: multiple messages have this Message-ID (diff)
From: Masahiro Yamada <masahiroy@kernel.org>
To: linux-kbuild@vger.kernel.org
Cc: linux-kernel@vger.kernel.org,
Nathan Chancellor <nathan@kernel.org>,
Nick Desaulniers <ndesaulniers@google.com>,
Nicolas Schier <nicolas@fjasle.eu>,
linux-um@lists.infradead.org,
Masahiro Yamada <masahiroy@kernel.org>
Subject: [PATCH v8 08/11] kbuild: implement CONFIG_TRIM_UNUSED_KSYMS without recursion
Date: Sat, 10 Jun 2023 18:13:17 +0900 [thread overview]
Message-ID: <20230610091320.1054554-9-masahiroy@kernel.org> (raw)
In-Reply-To: <20230610091320.1054554-1-masahiroy@kernel.org>
When CONFIG_TRIM_UNUSED_KSYMS is enabled, Kbuild recursively traverses
the directory tree to determine which EXPORT_SYMBOL to trim. If an
EXPORT_SYMBOL turns out to be unused by anyone, Kbuild begins the
second traverse, where some source files are recompiled with their
EXPORT_SYMBOL() tuned into a no-op.
Linus stated negative opinions about this slowness in commits:
- 5cf0fd591f2e ("Kbuild: disable TRIM_UNUSED_KSYMS option")
- a555bdd0c58c ("Kbuild: enable TRIM_UNUSED_KSYMS again, with some guarding")
We can do this better now. The final data structures of EXPORT_SYMBOL
are generated by the modpost stage, so modpost can selectively emit
KSYMTAB entries that are really used by modules.
Commit f73edc8951b2 ("kbuild: unify two modpost invocations") is another
ground-work to do this in a one-pass algorithm. With the list of modules,
modpost sets sym->used if it is used by a module. modpost emits KSYMTAB
only for symbols with sym->used==true.
BTW, Nicolas explained why the trimming was implemented with recursion:
https://lore.kernel.org/all/2o2rpn97-79nq-p7s2-nq5-8p83391473r@syhkavp.arg/
Actually, we never achieved that level of optimization where the chain
reaction of trimming comes into play because:
- CONFIG_LTO_CLANG cannot remove any unused symbols
- CONFIG_LD_DEAD_CODE_DATA_ELIMINATION is enabled only for vmlinux,
but not modules
If deeper trimming is required, we need to revisit this, but I guess
that is unlikely to happen.
Signed-off-by: Masahiro Yamada <masahiroy@kernel.org>
---
(no changes since v7)
Changes in v7:
- Remove *.usyms
Changes in v5:
- Clean up more
.gitignore | 2 -
Makefile | 22 ++---------
include/linux/export.h | 67 +++++-----------------------------
scripts/Makefile.build | 15 +-------
scripts/Makefile.modpost | 7 ++++
scripts/adjust_autoksyms.sh | 73 -------------------------------------
scripts/basic/fixdep.c | 3 +-
scripts/gen_autoksyms.sh | 62 -------------------------------
scripts/gen_ksymdeps.sh | 30 ---------------
scripts/mod/modpost.c | 54 ++++++++++++++++++++++++---
scripts/remove-stale-files | 4 ++
11 files changed, 75 insertions(+), 264 deletions(-)
delete mode 100755 scripts/adjust_autoksyms.sh
delete mode 100755 scripts/gen_autoksyms.sh
delete mode 100755 scripts/gen_ksymdeps.sh
diff --git a/.gitignore b/.gitignore
index 7f86e0837909..c3ce78ca20d2 100644
--- a/.gitignore
+++ b/.gitignore
@@ -51,7 +51,6 @@
*.symversions
*.tab.[ch]
*.tar
-*.usyms
*.xz
*.zst
Module.symvers
@@ -112,7 +111,6 @@ modules.order
#
/include/config/
/include/generated/
-/include/ksym/
/arch/*/include/generated/
# stgit generated dirs
diff --git a/Makefile b/Makefile
index f836936fb4d8..cc3fe09c4dec 100644
--- a/Makefile
+++ b/Makefile
@@ -1193,28 +1193,12 @@ endif
export KBUILD_VMLINUX_LIBS
export KBUILD_LDS := arch/$(SRCARCH)/kernel/vmlinux.lds
-# Recurse until adjust_autoksyms.sh is satisfied
-PHONY += autoksyms_recursive
ifdef CONFIG_TRIM_UNUSED_KSYMS
# For the kernel to actually contain only the needed exported symbols,
# we have to build modules as well to determine what those symbols are.
-# (this can be evaluated only once include/config/auto.conf has been included)
KBUILD_MODULES := 1
-
-autoksyms_recursive: $(build-dir) modules.order
- $(Q)$(CONFIG_SHELL) $(srctree)/scripts/adjust_autoksyms.sh \
- "$(MAKE) -f $(srctree)/Makefile autoksyms_recursive"
endif
-autoksyms_h := $(if $(CONFIG_TRIM_UNUSED_KSYMS), include/generated/autoksyms.h)
-
-quiet_cmd_autoksyms_h = GEN $@
- cmd_autoksyms_h = mkdir -p $(dir $@); \
- $(CONFIG_SHELL) $(srctree)/scripts/gen_autoksyms.sh $@
-
-$(autoksyms_h):
- $(call cmd,autoksyms_h)
-
# '$(AR) mPi' needs 'T' to workaround the bug of llvm-ar <= 14
quiet_cmd_ar_vmlinux.a = AR $@
cmd_ar_vmlinux.a = \
@@ -1223,7 +1207,7 @@ quiet_cmd_ar_vmlinux.a = AR $@
$(AR) mPiT $$($(AR) t $@ | sed -n 1p) $@ $$($(AR) t $@ | grep -F -f $(srctree)/scripts/head-object-list.txt)
targets += vmlinux.a
-vmlinux.a: $(KBUILD_VMLINUX_OBJS) scripts/head-object-list.txt autoksyms_recursive FORCE
+vmlinux.a: $(KBUILD_VMLINUX_OBJS) scripts/head-object-list.txt FORCE
$(call if_changed,ar_vmlinux.a)
PHONY += vmlinux_o
@@ -1279,7 +1263,7 @@ scripts: scripts_basic scripts_dtc
PHONY += prepare archprepare
archprepare: outputmakefile archheaders archscripts scripts include/config/kernel.release \
- asm-generic $(version_h) $(autoksyms_h) include/generated/utsrelease.h \
+ asm-generic $(version_h) include/generated/utsrelease.h \
include/generated/compile.h include/generated/autoconf.h remove-stale-files
prepare0: archprepare
@@ -2039,7 +2023,7 @@ clean: $(clean-dirs)
-o -name '*.dtb.S' -o -name '*.dtbo.S' \
-o -name '*.dt.yaml' \
-o -name '*.dwo' -o -name '*.lst' \
- -o -name '*.su' -o -name '*.mod' -o -name '*.usyms' \
+ -o -name '*.su' -o -name '*.mod' \
-o -name '.*.d' -o -name '.*.tmp' -o -name '*.mod.c' \
-o -name '*.lex.c' -o -name '*.tab.[ch]' \
-o -name '*.asn1.[ch]' \
diff --git a/include/linux/export.h b/include/linux/export.h
index 245ecd342772..8a9b72386fff 100644
--- a/include/linux/export.h
+++ b/include/linux/export.h
@@ -37,31 +37,13 @@ extern struct module __this_module;
#define __EXPORT_SYMBOL_REF(sym) .balign 4; .long sym
#endif
-#define ____EXPORT_SYMBOL(sym, license, ns) \
+#define ___EXPORT_SYMBOL(sym, license, ns) \
.section ".export_symbol","a" ; \
__export_symbol_##license##_##sym: ; \
.asciz ns ; \
__EXPORT_SYMBOL_REF(sym) ; \
.previous
-#ifdef __GENKSYMS__
-
-#define ___EXPORT_SYMBOL(sym, sec, ns) __GENKSYMS_EXPORT_SYMBOL(sym)
-
-#elif defined(__ASSEMBLY__)
-
-#define ___EXPORT_SYMBOL(sym, license, ns) \
- ____EXPORT_SYMBOL(sym, license, ns)
-
-#else
-
-#define ___EXPORT_SYMBOL(sym, license, ns) \
- extern typeof(sym) sym; \
- __ADDRESSABLE(sym) \
- asm(__stringify(____EXPORT_SYMBOL(sym, license, ns)))
-
-#endif
-
#if !defined(CONFIG_MODULES) || defined(__DISABLE_EXPORTS)
/*
@@ -71,50 +53,21 @@ extern struct module __this_module;
*/
#define __EXPORT_SYMBOL(sym, sec, ns)
-#elif defined(CONFIG_TRIM_UNUSED_KSYMS)
+#elif defined(__GENKSYMS__)
-#include <generated/autoksyms.h>
+#define __EXPORT_SYMBOL(sym, sec, ns) __GENKSYMS_EXPORT_SYMBOL(sym)
-/*
- * For fine grained build dependencies, we want to tell the build system
- * about each possible exported symbol even if they're not actually exported.
- * We use a symbol pattern __ksym_marker_<symbol> that the build system filters
- * from the $(NM) output (see scripts/gen_ksymdeps.sh). These symbols are
- * discarded in the final link stage.
- */
+#elif defined(__ASSEMBLY__)
-#ifdef __ASSEMBLY__
-
-#define __ksym_marker(sym) \
- .section ".discard.ksym","a" ; \
-__ksym_marker_##sym: ; \
- .previous
+#define __EXPORT_SYMBOL(sym, license, ns) \
+ ___EXPORT_SYMBOL(sym, license, ns)
#else
-#define __ksym_marker(sym) \
- static int __ksym_marker_##sym[0] __section(".discard.ksym") __used
-
-#endif
-
-#define __EXPORT_SYMBOL(sym, sec, ns) \
- __ksym_marker(sym); \
- __cond_export_sym(sym, sec, ns, __is_defined(__KSYM_##sym))
-#define __cond_export_sym(sym, sec, ns, conf) \
- ___cond_export_sym(sym, sec, ns, conf)
-#define ___cond_export_sym(sym, sec, ns, enabled) \
- __cond_export_sym_##enabled(sym, sec, ns)
-#define __cond_export_sym_1(sym, sec, ns) ___EXPORT_SYMBOL(sym, sec, ns)
-
-#ifdef __GENKSYMS__
-#define __cond_export_sym_0(sym, sec, ns) __GENKSYMS_EXPORT_SYMBOL(sym)
-#else
-#define __cond_export_sym_0(sym, sec, ns) /* nothing */
-#endif
-
-#else
-
-#define __EXPORT_SYMBOL(sym, sec, ns) ___EXPORT_SYMBOL(sym, sec, ns)
+#define __EXPORT_SYMBOL(sym, license, ns) \
+ extern typeof(sym) sym; \
+ __ADDRESSABLE(sym) \
+ asm(__stringify(___EXPORT_SYMBOL(sym, license, ns)))
#endif /* CONFIG_MODULES */
diff --git a/scripts/Makefile.build b/scripts/Makefile.build
index d676bc15e4e7..51477dd71427 100644
--- a/scripts/Makefile.build
+++ b/scripts/Makefile.build
@@ -82,7 +82,7 @@ ifdef need-builtin
targets-for-builtin += $(obj)/built-in.a
endif
-targets-for-modules := $(foreach x, o mod $(if $(CONFIG_TRIM_UNUSED_KSYMS), usyms), \
+targets-for-modules := $(foreach x, o mod, \
$(patsubst %.o, %.$x, $(filter %.o, $(obj-m))))
ifdef need-modorder
@@ -217,18 +217,12 @@ is-standard-object = $(if $(filter-out y%, $(OBJECT_FILES_NON_STANDARD_$(basetar
$(obj)/%.o: objtool-enabled = $(if $(is-standard-object),$(if $(delay-objtool),$(is-single-obj-m),y))
-ifdef CONFIG_TRIM_UNUSED_KSYMS
-cmd_gen_ksymdeps = \
- $(CONFIG_SHELL) $(srctree)/scripts/gen_ksymdeps.sh $@ >> $(dot-target).cmd
-endif
-
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
define rule_cc_o_c
$(call cmd_and_fixdep,cc_o_c)
- $(call cmd,gen_ksymdeps)
$(call cmd,checksrc)
$(call cmd,checkdoc)
$(call cmd,gen_objtooldep)
@@ -239,7 +233,6 @@ endef
define rule_as_o_S
$(call cmd_and_fixdep,as_o_S)
- $(call cmd,gen_ksymdeps)
$(call cmd,gen_objtooldep)
$(call cmd,gen_symversions_S)
$(call cmd,warn_shared_object)
@@ -258,12 +251,6 @@ cmd_mod = printf '%s\n' $(call real-search, $*.o, .o, -objs -y -m) | \
$(obj)/%.mod: FORCE
$(call if_changed,mod)
-# List module undefined symbols
-cmd_undefined_syms = $(NM) $< | sed -n 's/^ *U //p' > $@
-
-$(obj)/%.usyms: $(obj)/%.o FORCE
- $(call if_changed,undefined_syms)
-
quiet_cmd_cc_lst_c = MKLST $@
cmd_cc_lst_c = $(CC) $(c_flags) -g -c -o $*.o $< && \
$(CONFIG_SHELL) $(srctree)/scripts/makelst $*.o \
diff --git a/scripts/Makefile.modpost b/scripts/Makefile.modpost
index 074e27c0c140..65133fcdd5b8 100644
--- a/scripts/Makefile.modpost
+++ b/scripts/Makefile.modpost
@@ -91,6 +91,13 @@ targets += .vmlinux.objs
.vmlinux.objs: vmlinux.a $(KBUILD_VMLINUX_LIBS) FORCE
$(call if_changed,vmlinux_objs)
+ifdef CONFIG_TRIM_UNUSED_KSYMS
+ksym-wl := $(CONFIG_UNUSED_KSYMS_WHITELIST)
+ksym-wl := $(if $(filter-out /%, $(ksym-wl)),$(srctree)/)$(ksym-wl)
+modpost-args += -t $(addprefix -u, $(ksym-wl))
+modpost-deps += $(ksym-wl)
+endif
+
ifeq ($(wildcard vmlinux.o),)
missing-input := vmlinux.o
output-symdump := modules-only.symvers
diff --git a/scripts/adjust_autoksyms.sh b/scripts/adjust_autoksyms.sh
deleted file mode 100755
index f1b5ac818411..000000000000
--- a/scripts/adjust_autoksyms.sh
+++ /dev/null
@@ -1,73 +0,0 @@
-#!/bin/sh
-# SPDX-License-Identifier: GPL-2.0-only
-
-# Script to update include/generated/autoksyms.h and dependency files
-#
-# Copyright: (C) 2016 Linaro Limited
-# Created by: Nicolas Pitre, January 2016
-#
-
-# Update the include/generated/autoksyms.h file.
-#
-# For each symbol being added or removed, the corresponding dependency
-# file's timestamp is updated to force a rebuild of the affected source
-# file. All arguments passed to this script are assumed to be a command
-# to be exec'd to trigger a rebuild of those files.
-
-set -e
-
-cur_ksyms_file="include/generated/autoksyms.h"
-new_ksyms_file="include/generated/autoksyms.h.tmpnew"
-
-info() {
- if [ "$quiet" != "silent_" ]; then
- printf " %-7s %s\n" "$1" "$2"
- fi
-}
-
-info "CHK" "$cur_ksyms_file"
-
-# Use "make V=1" to debug this script.
-case "$KBUILD_VERBOSE" in
-*1*)
- set -x
- ;;
-esac
-
-# Generate a new symbol list file
-$CONFIG_SHELL $srctree/scripts/gen_autoksyms.sh --modorder "$new_ksyms_file"
-
-# Extract changes between old and new list and touch corresponding
-# dependency files.
-changed=$(
-count=0
-sort "$cur_ksyms_file" "$new_ksyms_file" | uniq -u |
-sed -n 's/^#define __KSYM_\(.*\) 1/\1/p' |
-while read sympath; do
- if [ -z "$sympath" ]; then continue; fi
- depfile="include/ksym/${sympath}"
- mkdir -p "$(dirname "$depfile")"
- touch "$depfile"
- # Filesystems with coarse time precision may create timestamps
- # equal to the one from a file that was very recently built and that
- # needs to be rebuild. Let's guard against that by making sure our
- # dep files are always newer than the first file we created here.
- while [ ! "$depfile" -nt "$new_ksyms_file" ]; do
- touch "$depfile"
- done
- echo $((count += 1))
-done | tail -1 )
-changed=${changed:-0}
-
-if [ $changed -gt 0 ]; then
- # Replace the old list with tne new one
- old=$(grep -c "^#define __KSYM_" "$cur_ksyms_file" || true)
- new=$(grep -c "^#define __KSYM_" "$new_ksyms_file" || true)
- info "KSYMS" "symbols: before=$old, after=$new, changed=$changed"
- info "UPD" "$cur_ksyms_file"
- mv -f "$new_ksyms_file" "$cur_ksyms_file"
- # Then trigger a rebuild of affected source files
- exec $@
-else
- rm -f "$new_ksyms_file"
-fi
diff --git a/scripts/basic/fixdep.c b/scripts/basic/fixdep.c
index fa562806c2be..84b6efa849f4 100644
--- a/scripts/basic/fixdep.c
+++ b/scripts/basic/fixdep.c
@@ -246,8 +246,7 @@ static void *read_file(const char *filename)
/* Ignore certain dependencies */
static int is_ignored_file(const char *s, int len)
{
- return str_ends_with(s, len, "include/generated/autoconf.h") ||
- str_ends_with(s, len, "include/generated/autoksyms.h");
+ return str_ends_with(s, len, "include/generated/autoconf.h");
}
/* Do not parse these files */
diff --git a/scripts/gen_autoksyms.sh b/scripts/gen_autoksyms.sh
deleted file mode 100755
index 12bcfae940ee..000000000000
--- a/scripts/gen_autoksyms.sh
+++ /dev/null
@@ -1,62 +0,0 @@
-#!/bin/sh
-# SPDX-License-Identifier: GPL-2.0-only
-
-# Create an autoksyms.h header file from the list of all module's needed symbols
-# as recorded in *.usyms files and the user-provided symbol whitelist.
-
-set -e
-
-# Use "make V=1" to debug this script.
-case "$KBUILD_VERBOSE" in
-*1*)
- set -x
- ;;
-esac
-
-read_modorder=
-
-if [ "$1" = --modorder ]; then
- shift
- read_modorder=1
-fi
-
-output_file="$1"
-
-needed_symbols=
-
-# Special case for modversions (see modpost.c)
-if grep -q "^CONFIG_MODVERSIONS=y$" include/config/auto.conf; then
- needed_symbols="$needed_symbols module_layout"
-fi
-
-ksym_wl=$(sed -n 's/^CONFIG_UNUSED_KSYMS_WHITELIST=\(.*\)$/\1/p' include/config/auto.conf)
-if [ -n "$ksym_wl" ]; then
- [ "${ksym_wl}" != "${ksym_wl#/}" ] || ksym_wl="$abs_srctree/$ksym_wl"
- if [ ! -f "$ksym_wl" ] || [ ! -r "$ksym_wl" ]; then
- echo "ERROR: '$ksym_wl' whitelist file not found" >&2
- exit 1
- fi
-fi
-
-# Generate a new ksym list file with symbols needed by the current
-# set of modules.
-cat > "$output_file" << EOT
-/*
- * Automatically generated file; DO NOT EDIT.
- */
-
-EOT
-
-{
- [ -n "${read_modorder}" ] && sed 's/o$/usyms/' modules.order | xargs cat
- echo "$needed_symbols"
- [ -n "$ksym_wl" ] && cat "$ksym_wl"
-} | sed -e 's/ /\n/g' | sed -n -e '/^$/!p' |
-# Remove the dot prefix for ppc64; symbol names with a dot (.) hold entry
-# point addresses.
-sed -e 's/^\.//' |
-sort -u |
-# Ignore __this_module. It's not an exported symbol, and will be resolved
-# when the final .ko's are linked.
-grep -v '^__this_module$' |
-sed -e 's/\(.*\)/#define __KSYM_\1 1/' >> "$output_file"
diff --git a/scripts/gen_ksymdeps.sh b/scripts/gen_ksymdeps.sh
deleted file mode 100755
index 8ee533f33659..000000000000
--- a/scripts/gen_ksymdeps.sh
+++ /dev/null
@@ -1,30 +0,0 @@
-#!/bin/sh
-# SPDX-License-Identifier: GPL-2.0
-
-set -e
-
-# List of exported symbols
-#
-# If the object has no symbol, $NM warns 'no symbols'.
-# Suppress the stderr.
-# TODO:
-# Use -q instead of 2>/dev/null when we upgrade the minimum version of
-# binutils to 2.37, llvm to 13.0.0.
-ksyms=$($NM $1 2>/dev/null | sed -n 's/.*__ksym_marker_\(.*\)/\1/p')
-
-if [ -z "$ksyms" ]; then
- exit 0
-fi
-
-echo
-echo "ksymdeps_$1 := \\"
-
-for s in $ksyms
-do
- printf ' $(wildcard include/ksym/%s) \\\n' "$s"
-done
-
-echo
-echo "$1: \$(ksymdeps_$1)"
-echo
-echo "\$(ksymdeps_$1):"
diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c
index 7044b257424a..decb7d23ef9f 100644
--- a/scripts/mod/modpost.c
+++ b/scripts/mod/modpost.c
@@ -35,6 +35,9 @@ static bool warn_unresolved;
static int sec_mismatch_count;
static bool sec_mismatch_warn_only = true;
+/* Trim EXPORT_SYMBOLs that are unused by in-tree modules */
+static bool trim_unused_exports;
+
/* ignore missing files */
static bool ignore_missing_files;
/* If set to 1, only warn (instead of error) about missing ns imports */
@@ -219,6 +222,7 @@ struct symbol {
bool weak;
bool is_func;
bool is_gpl_only; /* exported by EXPORT_SYMBOL_GPL */
+ bool used; /* there exists a user of this symbol */
char name[];
};
@@ -1820,6 +1824,7 @@ static void check_exports(struct module *mod)
continue;
}
+ exp->used = true;
s->module = exp->module;
s->crc_valid = exp->crc_valid;
s->crc = exp->crc;
@@ -1843,6 +1848,23 @@ static void check_exports(struct module *mod)
}
}
+static void handle_white_list_exports(const char *white_list)
+{
+ char *buf, *p, *name;
+
+ buf = read_text_file(white_list);
+ p = buf;
+
+ while ((name = strsep(&p, "\n"))) {
+ struct symbol *sym = find_symbol(name);
+
+ if (sym)
+ sym->used = true;
+ }
+
+ free(buf);
+}
+
static void check_modname_len(struct module *mod)
{
const char *mod_name;
@@ -1913,10 +1935,14 @@ static void add_exported_symbols(struct buffer *buf, struct module *mod)
/* generate struct for exported symbols */
buf_printf(buf, "\n");
- list_for_each_entry(sym, &mod->exported_symbols, list)
+ list_for_each_entry(sym, &mod->exported_symbols, list) {
+ if (trim_unused_exports && !sym->used)
+ continue;
+
buf_printf(buf, "KSYMTAB_%s(%s, \"%s\", \"%s\");\n",
sym->is_func ? "FUNC" : "DATA", sym->name,
sym->is_gpl_only ? "_gpl" : "", sym->namespace);
+ }
if (!modversions)
return;
@@ -1924,6 +1950,9 @@ static void add_exported_symbols(struct buffer *buf, struct module *mod)
/* record CRCs for exported symbols */
buf_printf(buf, "\n");
list_for_each_entry(sym, &mod->exported_symbols, list) {
+ if (trim_unused_exports && !sym->used)
+ continue;
+
if (!sym->crc_valid)
warn("EXPORT symbol \"%s\" [%s%s] version generation failed, symbol will not be versioned.\n"
"Is \"%s\" prototyped in <asm/asm-prototypes.h>?\n",
@@ -2087,9 +2116,6 @@ static void write_mod_c_file(struct module *mod)
char fname[PATH_MAX];
int ret;
- check_modname_len(mod);
- check_exports(mod);
-
add_header(&buf, mod);
add_exported_symbols(&buf, mod);
add_versions(&buf, mod);
@@ -2223,12 +2249,13 @@ int main(int argc, char **argv)
{
struct module *mod;
char *missing_namespace_deps = NULL;
+ char *unused_exports_white_list = NULL;
char *dump_write = NULL, *files_source = NULL;
int opt;
LIST_HEAD(dump_lists);
struct dump_list *dl, *dl2;
- while ((opt = getopt(argc, argv, "ei:mnT:o:aWwENd:")) != -1) {
+ while ((opt = getopt(argc, argv, "ei:mnTt:o:auWwENd:")) != -1) {
switch (opt) {
case 'e':
external_module = true;
@@ -2253,6 +2280,12 @@ int main(int argc, char **argv)
case 'T':
files_source = optarg;
break;
+ case 't':
+ trim_unused_exports = true;
+ break;
+ case 'u':
+ unused_exports_white_list = optarg;
+ break;
case 'W':
extra_warn = true;
break;
@@ -2285,6 +2318,17 @@ int main(int argc, char **argv)
if (files_source)
read_symbols_from_files(files_source);
+ list_for_each_entry(mod, &modules, list) {
+ if (mod->from_dump || mod->is_vmlinux)
+ continue;
+
+ check_modname_len(mod);
+ check_exports(mod);
+ }
+
+ if (unused_exports_white_list)
+ handle_white_list_exports(unused_exports_white_list);
+
list_for_each_entry(mod, &modules, list) {
if (mod->from_dump)
continue;
diff --git a/scripts/remove-stale-files b/scripts/remove-stale-files
index 7f432900671a..f3659ea0335b 100755
--- a/scripts/remove-stale-files
+++ b/scripts/remove-stale-files
@@ -33,3 +33,7 @@ rm -f rust/target.json
rm -f scripts/bin2c
rm -f .scmversion
+
+rm -rf include/ksym
+
+find . -name '*.usyms' | xargs rm -f
--
2.39.2
_______________________________________________
linux-um mailing list
linux-um@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-um
next prev parent reply other threads:[~2023-06-10 9:14 UTC|newest]
Thread overview: 31+ messages / expand[flat|nested] mbox.gz Atom feed top
2023-06-10 9:13 [PATCH v8 00/11] Unify <linux/export.h> and <asm/export.h>, remove EXPORT_DATA_SYMBOL(), faster TRIM_UNUSED_KSYMS Masahiro Yamada
2023-06-10 9:13 ` Masahiro Yamada
2023-06-10 9:13 ` [PATCH v8 01/11] Revert "[PATCH] uml: export symbols added by GCC hardened" Masahiro Yamada
2023-06-10 9:13 ` Masahiro Yamada
2023-06-10 9:13 ` [PATCH v8 02/11] modpost: pass struct module pointer to check_section_mismatch() Masahiro Yamada
2023-06-10 9:13 ` Masahiro Yamada
2023-06-10 9:13 ` [PATCH v8 03/11] kbuild: generate KSYMTAB entries by modpost Masahiro Yamada
2023-06-10 9:13 ` Masahiro Yamada
2023-06-10 9:13 ` [PATCH v8 04/11] ia64,export.h: replace EXPORT_DATA_SYMBOL* with EXPORT_SYMBOL* Masahiro Yamada
2023-06-10 9:13 ` Masahiro Yamada
2023-06-10 9:13 ` [PATCH v8 05/11] modpost: check static EXPORT_SYMBOL* by modpost again Masahiro Yamada
2023-06-10 9:13 ` Masahiro Yamada
2023-06-10 9:13 ` [PATCH v8 06/11] modpost: squash sym_update_namespace() into sym_add_exported() Masahiro Yamada
2023-06-10 9:13 ` Masahiro Yamada
2023-06-10 9:13 ` [PATCH v8 07/11] modpost: use null string instead of NULL pointer for default namespace Masahiro Yamada
2023-06-10 9:13 ` Masahiro Yamada
2023-06-10 9:13 ` Masahiro Yamada [this message]
2023-06-10 9:13 ` [PATCH v8 08/11] kbuild: implement CONFIG_TRIM_UNUSED_KSYMS without recursion Masahiro Yamada
2023-06-10 16:29 ` kernel test robot
2023-06-11 15:48 ` Masahiro Yamada
2023-06-10 16:40 ` kernel test robot
2023-06-10 18:24 ` kernel test robot
2023-06-11 15:50 ` Masahiro Yamada
2023-06-10 9:13 ` [PATCH v8 09/11] modpost: merge two similar section mismatch warnings Masahiro Yamada
2023-06-10 9:13 ` Masahiro Yamada
2023-06-10 9:13 ` [PATCH v8 10/11] modpost: show offset from symbol for " Masahiro Yamada
2023-06-10 9:13 ` Masahiro Yamada
2023-06-10 9:13 ` [PATCH v8 11/11] linux/export.h: rename 'sec' argument to 'license' Masahiro Yamada
2023-06-10 9:13 ` Masahiro Yamada
2023-06-11 15:33 ` [PATCH v8 00/11] Unify <linux/export.h> and <asm/export.h>, remove EXPORT_DATA_SYMBOL(), faster TRIM_UNUSED_KSYMS Masahiro Yamada
2023-06-11 15:33 ` Masahiro Yamada
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20230610091320.1054554-9-masahiroy@kernel.org \
--to=masahiroy@kernel.org \
--cc=linux-kbuild@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-um@lists.infradead.org \
--cc=nathan@kernel.org \
--cc=ndesaulniers@google.com \
--cc=nicolas@fjasle.eu \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.