From 30a7729771731971839cc969d2a321e6ea7a144b Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Thu, 23 Apr 2020 23:23:53 +0900 Subject: kbuild: use -MMD instead of -MD to exclude system headers from dependency This omits system headers from the generated header dependency. System headers are not updated unless you upgrade the compiler. Nor do they contain CONFIG options, so fixdep does not need to parse them. Having said that, the effect of this optimization will be quite small because the kernel code generally does not include system headers except . Host programs include a lot of system headers, but there are not so many in the kernel tree. At first, keeping system headers in .*.cmd files might be useful to detect the compiler update, but there is no guarantee that is included from every file. So, I implemented a more reliable way in the previous commit. Signed-off-by: Masahiro Yamada --- scripts/Kbuild.include | 2 +- scripts/Makefile.host | 4 ++-- scripts/Makefile.lib | 8 ++++---- 3 files changed, 7 insertions(+), 7 deletions(-) (limited to 'scripts') diff --git a/scripts/Kbuild.include b/scripts/Kbuild.include index 6cabf20ce66a..0c3dc983439b 100644 --- a/scripts/Kbuild.include +++ b/scripts/Kbuild.include @@ -16,7 +16,7 @@ pound := \# dot-target = $(dir $@).$(notdir $@) ### -# The temporary file to save gcc -MD generated dependencies must not +# The temporary file to save gcc -MMD generated dependencies must not # contain a comma depfile = $(subst $(comma),_,$(dot-target).d) diff --git a/scripts/Makefile.host b/scripts/Makefile.host index 2045855d0b75..c8a4a033dc3e 100644 --- a/scripts/Makefile.host +++ b/scripts/Makefile.host @@ -88,8 +88,8 @@ _hostcxx_flags += -I $(objtree)/$(obj) endif endif -hostc_flags = -Wp,-MD,$(depfile) $(_hostc_flags) -hostcxx_flags = -Wp,-MD,$(depfile) $(_hostcxx_flags) +hostc_flags = -Wp,-MMD,$(depfile) $(_hostc_flags) +hostcxx_flags = -Wp,-MMD,$(depfile) $(_hostcxx_flags) ##### # Compile programs on the host diff --git a/scripts/Makefile.lib b/scripts/Makefile.lib index 4b799737722c..12f6a331a8f3 100644 --- a/scripts/Makefile.lib +++ b/scripts/Makefile.lib @@ -171,22 +171,22 @@ modkern_aflags = $(if $(part-of-module), \ $(KBUILD_AFLAGS_MODULE) $(AFLAGS_MODULE), \ $(KBUILD_AFLAGS_KERNEL) $(AFLAGS_KERNEL)) -c_flags = -Wp,-MD,$(depfile) $(NOSTDINC_FLAGS) $(LINUXINCLUDE) \ +c_flags = -Wp,-MMD,$(depfile) $(NOSTDINC_FLAGS) $(LINUXINCLUDE) \ -include $(srctree)/include/linux/compiler_types.h \ $(_c_flags) $(modkern_cflags) \ $(basename_flags) $(modname_flags) -a_flags = -Wp,-MD,$(depfile) $(NOSTDINC_FLAGS) $(LINUXINCLUDE) \ +a_flags = -Wp,-MMD,$(depfile) $(NOSTDINC_FLAGS) $(LINUXINCLUDE) \ $(_a_flags) $(modkern_aflags) -cpp_flags = -Wp,-MD,$(depfile) $(NOSTDINC_FLAGS) $(LINUXINCLUDE) \ +cpp_flags = -Wp,-MMD,$(depfile) $(NOSTDINC_FLAGS) $(LINUXINCLUDE) \ $(_cpp_flags) ld_flags = $(KBUILD_LDFLAGS) $(ldflags-y) $(LDFLAGS_$(@F)) DTC_INCLUDE := $(srctree)/scripts/dtc/include-prefixes -dtc_cpp_flags = -Wp,-MD,$(depfile).pre.tmp -nostdinc \ +dtc_cpp_flags = -Wp,-MMD,$(depfile).pre.tmp -nostdinc \ $(addprefix -I,$(DTC_INCLUDE)) \ -undef -D__DTS__ -- cgit v1.2.3 From 9a950154668729a472d17b8e307d92e7c60f45f7 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Thu, 23 Apr 2020 23:23:54 +0900 Subject: kbuild: use CONFIG_CC_VERSION_TEXT to construct LINUX_COMPILER macro scripts/mkcompile_h runs $(CC) just for getting the version string. Reuse CONFIG_CC_VERSION_TEXT for optimization. For GCC, this slightly changes the version string. I do not think it is a big deal as we do not have the defined format for LINUX_COMPILER. In fact, the recent commit 4dcc9a88448a ("kbuild: mkcompile_h: Include $LD version in /proc/version") added the linker version. Signed-off-by: Masahiro Yamada --- init/Makefile | 2 +- scripts/mkcompile_h | 3 +-- 2 files changed, 2 insertions(+), 3 deletions(-) (limited to 'scripts') diff --git a/init/Makefile b/init/Makefile index d45e967483b2..57499b1ff471 100644 --- a/init/Makefile +++ b/init/Makefile @@ -35,4 +35,4 @@ include/generated/compile.h: FORCE @$($(quiet)chk_compile.h) $(Q)$(CONFIG_SHELL) $(srctree)/scripts/mkcompile_h $@ \ "$(UTS_MACHINE)" "$(CONFIG_SMP)" "$(CONFIG_PREEMPT)" \ - "$(CONFIG_PREEMPT_RT)" "$(CC)" "$(LD)" + "$(CONFIG_PREEMPT_RT)" $(CONFIG_CC_VERSION_TEXT) "$(LD)" diff --git a/scripts/mkcompile_h b/scripts/mkcompile_h index 5b80a4699740..baf3ab8d9d49 100755 --- a/scripts/mkcompile_h +++ b/scripts/mkcompile_h @@ -6,7 +6,7 @@ ARCH=$2 SMP=$3 PREEMPT=$4 PREEMPT_RT=$5 -CC=$6 +CC_VERSION="$6" LD=$7 vecho() { [ "${quiet}" = "silent_" ] || echo "$@" ; } @@ -62,7 +62,6 @@ UTS_VERSION="$(echo $UTS_VERSION $CONFIG_FLAGS $TIMESTAMP | cut -b -$UTS_LEN)" printf '#define LINUX_COMPILE_BY "%s"\n' "$LINUX_COMPILE_BY" echo \#define LINUX_COMPILE_HOST \"$LINUX_COMPILE_HOST\" - CC_VERSION=$($CC -v 2>&1 | grep ' version ' | sed 's/[[:space:]]*$//') LD_VERSION=$($LD -v | head -n1 | sed 's/(compatible with [^)]*)//' \ | sed 's/[[:space:]]*$//') printf '#define LINUX_COMPILER "%s"\n' "$CC_VERSION, $LD_VERSION" -- cgit v1.2.3 From 78046fabe6e7807a271aad09cde0522d80bd2985 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Mon, 27 Apr 2020 22:49:30 +0900 Subject: kbuild: determine the output format of DTC by the target suffix cmd_dtc takes the additional parameter $(2) to select the target format, dtb or yaml. This makes things complicated when it is used with cmd_and_fixdep and if_changed_rule. I actually stumbled on this. See commit 3d4b2238684a ("kbuild: fix DT binding schema rule again to avoid needless rebuilds"). Extract the suffix part of the target instead of passing the parameter. Fortunately, this works for both $(obj)/%.dtb and $(obj)/%.dt.yaml . Signed-off-by: Masahiro Yamada --- scripts/Makefile.lib | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'scripts') diff --git a/scripts/Makefile.lib b/scripts/Makefile.lib index 12f6a331a8f3..cd52a8c6428f 100644 --- a/scripts/Makefile.lib +++ b/scripts/Makefile.lib @@ -287,13 +287,13 @@ $(obj)/%.dtb.S: $(obj)/%.dtb FORCE quiet_cmd_dtc = DTC $@ cmd_dtc = mkdir -p $(dir ${dtc-tmp}) ; \ $(HOSTCC) -E $(dtc_cpp_flags) -x assembler-with-cpp -o $(dtc-tmp) $< ; \ - $(DTC) -O $(2) -o $@ -b 0 \ + $(DTC) -O $(patsubst .%,%,$(suffix $@)) -o $@ -b 0 \ $(addprefix -i,$(dir $<) $(DTC_INCLUDE)) $(DTC_FLAGS) \ -d $(depfile).dtc.tmp $(dtc-tmp) ; \ cat $(depfile).pre.tmp $(depfile).dtc.tmp > $(depfile) $(obj)/%.dtb: $(src)/%.dts $(DTC) FORCE - $(call if_changed_dep,dtc,dtb) + $(call if_changed_dep,dtc) DT_CHECKER ?= dt-validate DT_BINDING_DIR := Documentation/devicetree/bindings @@ -304,7 +304,7 @@ quiet_cmd_dtb_check = CHECK $@ cmd_dtb_check = $(DT_CHECKER) -u $(srctree)/$(DT_BINDING_DIR) -p $(DT_TMP_SCHEMA) $@ define rule_dtc - $(call cmd_and_fixdep,dtc,yaml) + $(call cmd_and_fixdep,dtc) $(call cmd,dtb_check) endef -- cgit v1.2.3 From 59721d4eb7f66f27440ad74f875b97e64133ee3b Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Tue, 28 Apr 2020 01:03:57 +0900 Subject: kbuild: warn if always, hostprogs-y, or hostprogs-m is used always, hostprogs-y, and hostprogs-m are deprecated. There is no user in upstream code, but I will keep them for external modules. I want to remove them entirely someday. Prompt downstream users for the migration. Signed-off-by: Masahiro Yamada --- scripts/Makefile.lib | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) (limited to 'scripts') diff --git a/scripts/Makefile.lib b/scripts/Makefile.lib index cd52a8c6428f..52299d5dba28 100644 --- a/scripts/Makefile.lib +++ b/scripts/Makefile.lib @@ -4,8 +4,18 @@ asflags-y += $(EXTRA_AFLAGS) ccflags-y += $(EXTRA_CFLAGS) cppflags-y += $(EXTRA_CPPFLAGS) ldflags-y += $(EXTRA_LDFLAGS) +ifneq ($(always),) +$(warning 'always' is deprecated. Please use 'always-y' instead) always-y += $(always) -hostprogs += $(hostprogs-y) $(hostprogs-m) +endif +ifneq ($(hostprogs-y),) +$(warning 'hostprogs-y' is deprecated. Please use 'hostprogs' instead) +hostprogs += $(hostprogs-y) +endif +ifneq ($(hostprogs-m),) +$(warning 'hostprogs-m' is deprecated. Please use 'hostprogs' instead) +hostprogs += $(hostprogs-m) +endif # flags that take effect in current and sub directories KBUILD_AFLAGS += $(subdir-asflags-y) -- cgit v1.2.3 From 7f3a59db274c3e3d884c785e363a054110f1c266 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Wed, 29 Apr 2020 12:45:14 +0900 Subject: kbuild: add infrastructure to build userspace programs Kbuild supports the infrastructure to build host programs, but there was no support to build userspace programs for the target architecture (i.e. the same architecture as the kernel). Sam Ravnborg worked on this in 2014 (https://lkml.org/lkml/2014/7/13/154), but it was not merged. One problem at that time was, there was no good way to know whether $(CC) can link standalone programs. In fact, pre-built kernel.org toolchains [1] are often used for building the kernel, but they do not provide libc. Now, we can handle this cleanly because the compiler capability is evaluated at the Kconfig time. If $(CC) cannot link standalone programs, the relevant options are hidden by 'depends on CC_CAN_LINK'. The implementation just mimics scripts/Makefile.host The userspace programs are compiled with the same flags as the host programs. In addition, it uses -m32 or -m64 if it is found in $(KBUILD_CFLAGS). This new syntax has two usecases. - Sample programs Several userspace programs under samples/ include UAPI headers installed in usr/include. Most of them were previously built for the host architecture just to use the 'hostprogs' syntax. However, 'make headers' always works for the target architecture. This caused the arch mismatch in cross-compiling. To fix this distortion, sample code should be built for the target architecture. - Bpfilter net/bpfilter/Makefile compiles bpfilter_umh as the user mode helper, and embeds it into the kernel. Currently, it overrides HOSTCC with CC to use the 'hostprogs' syntax. This hack should go away. [1]: https://mirrors.edge.kernel.org/pub/tools/crosstool/ Signed-off-by: Masahiro Yamada Acked-by: Sam Ravnborg --- Makefile | 13 ++++++++++--- scripts/Makefile.build | 6 ++++++ scripts/Makefile.clean | 2 +- scripts/Makefile.userprogs | 45 +++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 62 insertions(+), 4 deletions(-) create mode 100644 scripts/Makefile.userprogs (limited to 'scripts') diff --git a/Makefile b/Makefile index 9671fa09c83a..faec37f23c48 100644 --- a/Makefile +++ b/Makefile @@ -406,9 +406,12 @@ else HOSTCC = gcc HOSTCXX = g++ endif -KBUILD_HOSTCFLAGS := -Wall -Wmissing-prototypes -Wstrict-prototypes -O2 \ - -fomit-frame-pointer -std=gnu89 $(HOST_LFS_CFLAGS) \ - $(HOSTCFLAGS) + +export KBUILD_USERCFLAGS := -Wall -Wmissing-prototypes -Wstrict-prototypes \ + -O2 -fomit-frame-pointer -std=gnu89 +export KBUILD_USERLDFLAGS := + +KBUILD_HOSTCFLAGS := $(KBUILD_USERCFLAGS) $(HOST_LFS_CFLAGS) $(HOSTCFLAGS) KBUILD_HOSTCXXFLAGS := -Wall -O2 $(HOST_LFS_CFLAGS) $(HOSTCXXFLAGS) KBUILD_HOSTLDFLAGS := $(HOST_LFS_LDFLAGS) $(HOSTLDFLAGS) KBUILD_HOSTLDLIBS := $(HOST_LFS_LIBS) $(HOSTLDLIBS) @@ -944,6 +947,10 @@ ifeq ($(CONFIG_RELR),y) LDFLAGS_vmlinux += --pack-dyn-relocs=relr endif +# Align the bit size of userspace programs with the kernel +KBUILD_USERCFLAGS += $(filter -m32 -m64, $(KBUILD_CFLAGS)) +KBUILD_USERLDFLAGS += $(filter -m32 -m64, $(KBUILD_CFLAGS)) + # make the checker run with the right architecture CHECKFLAGS += --arch=$(ARCH) diff --git a/scripts/Makefile.build b/scripts/Makefile.build index 9fcbfac15d1d..3665b1a0bc8e 100644 --- a/scripts/Makefile.build +++ b/scripts/Makefile.build @@ -50,6 +50,12 @@ ifneq ($(hostprogs)$(hostcxxlibs-y)$(hostcxxlibs-m),) include scripts/Makefile.host endif +# Do not include userprogs rules unless needed. +userprogs := $(sort $(userprogs)) +ifneq ($(userprogs),) +include scripts/Makefile.userprogs +endif + ifndef obj $(warning kbuild: Makefile.build is included improperly) endif diff --git a/scripts/Makefile.clean b/scripts/Makefile.clean index 075f0cc2d8d7..e2c76122319d 100644 --- a/scripts/Makefile.clean +++ b/scripts/Makefile.clean @@ -29,7 +29,7 @@ subdir-ymn := $(addprefix $(obj)/,$(subdir-ymn)) __clean-files := $(extra-y) $(extra-m) $(extra-) \ $(always) $(always-y) $(always-m) $(always-) $(targets) $(clean-files) \ - $(hostprogs) $(hostprogs-y) $(hostprogs-m) $(hostprogs-) \ + $(hostprogs) $(hostprogs-y) $(hostprogs-m) $(hostprogs-) $(userprogs) \ $(hostcxxlibs-y) $(hostcxxlibs-m) __clean-files := $(filter-out $(no-clean-files), $(__clean-files)) diff --git a/scripts/Makefile.userprogs b/scripts/Makefile.userprogs new file mode 100644 index 000000000000..fb415297337a --- /dev/null +++ b/scripts/Makefile.userprogs @@ -0,0 +1,45 @@ +# SPDX-License-Identifier: GPL-2.0-only +# +# Build userspace programs for the target system +# + +# Executables compiled from a single .c file +user-csingle := $(foreach m, $(userprogs), $(if $($(m)-objs),,$(m))) + +# Executables linked based on several .o files +user-cmulti := $(foreach m, $(userprogs), $(if $($(m)-objs),$(m))) + +# Objects compiled from .c files +user-cobjs := $(sort $(foreach m, $(userprogs), $($(m)-objs))) + +user-csingle := $(addprefix $(obj)/, $(user-csingle)) +user-cmulti := $(addprefix $(obj)/, $(user-cmulti)) +user-cobjs := $(addprefix $(obj)/, $(user-cobjs)) + +user_ccflags = -Wp,-MMD,$(depfile) $(KBUILD_USERCFLAGS) $(userccflags) \ + $($(target-stem)-userccflags) +user_ldflags = $(KBUILD_USERLDFLAGS) $(userldflags) $($(target-stem)-userldflags) + +# Create an executable from a single .c file +quiet_cmd_user_cc_c = CC [U] $@ + cmd_user_cc_c = $(CC) $(user_ccflags) $(user_ldflags) -o $@ $< \ + $($(target-stem)-userldlibs) +$(user-csingle): $(obj)/%: $(src)/%.c FORCE + $(call if_changed_dep,user_cc_c) + +# Link an executable based on list of .o files +quiet_cmd_user_ld = LD [U] $@ + cmd_user_ld = $(CC) $(user_ldflags) -o $@ \ + $(addprefix $(obj)/, $($(target-stem)-objs)) \ + $($(target-stem)-userldlibs) +$(user-cmulti): FORCE + $(call if_changed,user_ld) +$(call multi_depend, $(user-cmulti), , -objs) + +# Create .o file from a .c file +quiet_cmd_user_cc_o_c = CC [U] $@ + cmd_user_cc_o_c = $(CC) $(user_ccflags) -c -o $@ $< +$(user-cobjs): $(obj)/%.o: $(src)/%.c FORCE + $(call if_changed_dep,user_cc_o_c) + +targets += $(user-csingle) $(user-cmulti) $(user-cobjs) -- cgit v1.2.3 From 5967577231f9b19acd5a59485e9075964065bbe3 Mon Sep 17 00:00:00 2001 From: Siddharth Gupta Date: Tue, 5 May 2020 18:52:37 -0700 Subject: scripts: headers_install: Exit with error on config leak Misuse of CONFIG_* in UAPI headers should result in an error. These config options can be set in userspace by the user application which includes these headers to control the APIs and structures being used in a kernel which supports multiple targets. Signed-off-by: Siddharth Gupta Signed-off-by: Masahiro Yamada --- scripts/headers_install.sh | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) (limited to 'scripts') diff --git a/scripts/headers_install.sh b/scripts/headers_install.sh index a07668a5c36b..94a833597a88 100755 --- a/scripts/headers_install.sh +++ b/scripts/headers_install.sh @@ -64,7 +64,7 @@ configs=$(sed -e ' d ' $OUTFILE) -# The entries in the following list are not warned. +# The entries in the following list do not result in an error. # Please do not add a new entry. This list is only for existing ones. # The list will be reduced gradually, and deleted eventually. (hopefully) # @@ -98,18 +98,19 @@ include/uapi/linux/raw.h:CONFIG_MAX_RAW_DEVS for c in $configs do - warn=1 + leak_error=1 for ignore in $config_leak_ignores do if echo "$INFILE:$c" | grep -q "$ignore$"; then - warn= + leak_error= break fi done - if [ "$warn" = 1 ]; then - echo "warning: $INFILE: leak $c to user-space" >&2 + if [ "$leak_error" = 1 ]; then + echo "error: $INFILE: leak $c to user-space" >&2 + exit 1 fi done -- cgit v1.2.3 From 859c81750130844590a83eff847c6c55e2340ab1 Mon Sep 17 00:00:00 2001 From: "Gustavo A. R. Silva" Date: Thu, 7 May 2020 13:56:01 -0500 Subject: modpost,fixdep: Replace zero-length array with flexible-array The current codebase makes use of the zero-length array language extension to the C90 standard, but the preferred mechanism to declare variable-length types such as these ones is a flexible array member[1][2], introduced in C99: struct foo { int stuff; struct boo array[]; }; By making use of the mechanism above, we will get a compiler warning in case the flexible array does not occur last in the structure, which will help us prevent some kind of undefined behavior bugs from being inadvertently introduced[3] to the codebase from now on. Also, notice that, dynamic memory allocations won't be affected by this change: "Flexible array members have incomplete type, and so the sizeof operator may not be applied. As a quirk of the original implementation of zero-length arrays, sizeof evaluates to zero."[1] sizeof(flexible-array-member) triggers a warning because flexible array members have incomplete type[1]. There are some instances of code in which the sizeof operator is being incorrectly/erroneously applied to zero-length arrays and the result is zero. Such instances may be hiding some bugs. So, this work (flexible-array member conversions) will also help to get completely rid of those sorts of issues. This issue was found with the help of Coccinelle. [1] https://gcc.gnu.org/onlinedocs/gcc/Zero-Length.html [2] https://github.com/KSPP/linux/issues/21 [3] commit 76497732932f ("cxgb3/l2t: Fix undefined behaviour") Signed-off-by: Gustavo A. R. Silva Signed-off-by: Masahiro Yamada --- scripts/basic/fixdep.c | 2 +- scripts/mod/modpost.c | 2 +- scripts/mod/modpost.h | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) (limited to 'scripts') diff --git a/scripts/basic/fixdep.c b/scripts/basic/fixdep.c index 877ca2c88246..d98540552941 100644 --- a/scripts/basic/fixdep.c +++ b/scripts/basic/fixdep.c @@ -160,7 +160,7 @@ struct item { struct item *next; unsigned int len; unsigned int hash; - char name[0]; + char name[]; }; #define HASHSZ 256 diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c index 5c3c50c5ec52..4d4b979d76be 100644 --- a/scripts/mod/modpost.c +++ b/scripts/mod/modpost.c @@ -166,7 +166,7 @@ struct symbol { * (only for external modules) **/ unsigned int is_static:1; /* 1 if symbol is not global */ enum export export; /* Type of export */ - char name[0]; + char name[]; }; static struct symbol *symbolhash[SYMBOL_HASH_SIZE]; diff --git a/scripts/mod/modpost.h b/scripts/mod/modpost.h index 60dca9b7106b..39f6c29fb568 100644 --- a/scripts/mod/modpost.h +++ b/scripts/mod/modpost.h @@ -111,7 +111,7 @@ buf_write(struct buffer *buf, const char *s, int len); struct namespace_list { struct namespace_list *next; - char namespace[0]; + char namespace[]; }; struct module { -- cgit v1.2.3 From 677f1410e05813fde62d724d9210fce04c505fc7 Mon Sep 17 00:00:00 2001 From: Maninder Singh Date: Fri, 8 May 2020 16:33:14 +0530 Subject: scripts/checkstack.pl: don't display $dre as different entity currently script prints stack usage for functions in two ways:($re and $dre) dre breaks sorting mechanism. 0xffffa00011f26f88 sunxi_mux_clk_setup.isra.0 [vmlinux]:Dynamic (0x140) .. 0xffffa00011f27210 sunxi_divs_clk_setup [vmlinux]: Dynamic (0x1d0) so we can print it in decimal only. Also address before function name is changed to function start address rather than stack consumption address. Because in next patch, arm has two ways to use stack which can be clubbed and printed in one function only. All symbols whose stack by adding(re and dre) is greater than 100, will be printed. 0xffffa00011f2720c0 sunxi_divs_clk_setup [vmlinux]: 464 ... 0xffffa00011f26f840 sunxi_mux_clk_setup.isra.0 [vmlinux]:320 Co-developed-by: Vaneet Narang Signed-off-by: Vaneet Narang Signed-off-by: Maninder Singh Signed-off-by: Masahiro Yamada --- scripts/checkstack.pl | 54 +++++++++++++++++++++++++-------------------------- 1 file changed, 27 insertions(+), 27 deletions(-) (limited to 'scripts') diff --git a/scripts/checkstack.pl b/scripts/checkstack.pl index 371bd17a4983..695710895560 100755 --- a/scripts/checkstack.pl +++ b/scripts/checkstack.pl @@ -109,11 +109,30 @@ my (@stack, $re, $dre, $x, $xs, $funcre); # # main() # -my ($func, $file, $lastslash); +my ($func, $file, $lastslash, $total_size, $addr, $intro); + +$total_size = 0; while (my $line = ) { if ($line =~ m/$funcre/) { $func = $1; + next if $line !~ m/^($xs*)/; + if ($total_size > 100) { + push @stack, "$intro$total_size\n"; + } + + $addr = $1; + $addr =~ s/ /0/g; + $addr = "0x$addr"; + + $intro = "$addr $func [$file]:"; + my $padlen = 56 - length($intro); + while ($padlen > 0) { + $intro .= ' '; + $padlen -= 8; + } + + $total_size = 0; } elsif ($line =~ m/(.*):\s*file format/) { $file = $1; @@ -134,37 +153,18 @@ while (my $line = ) { } next if ($size > 0x10000000); - next if $line !~ m/^($xs*)/; - my $addr = $1; - $addr =~ s/ /0/g; - $addr = "0x$addr"; - - my $intro = "$addr $func [$file]:"; - my $padlen = 56 - length($intro); - while ($padlen > 0) { - $intro .= ' '; - $padlen -= 8; - } - next if ($size < 100); - push @stack, "$intro$size\n"; + $total_size += $size; } elsif (defined $dre && $line =~ m/$dre/) { - my $size = "Dynamic ($1)"; - - next if $line !~ m/^($xs*)/; - my $addr = $1; - $addr =~ s/ /0/g; - $addr = "0x$addr"; + my $size = $1; - my $intro = "$addr $func [$file]:"; - my $padlen = 56 - length($intro); - while ($padlen > 0) { - $intro .= ' '; - $padlen -= 8; - } - push @stack, "$intro$size\n"; + $size = hex($size) if ($size =~ /^0x/); + $total_size += $size; } } +if ($total_size > 100) { + push @stack, "$intro$total_size\n"; +} # Sort output by size (last field) print sort { ($b =~ /:\t*(\d+)$/)[0] <=> ($a =~ /:\t*(\d+)$/)[0] } @stack; -- cgit v1.2.3 From 572220aad525bd3650f796d7e29cc06d41df4235 Mon Sep 17 00:00:00 2001 From: Maninder Singh Date: Fri, 8 May 2020 16:33:15 +0530 Subject: scripts/checkstack.pl: Add argument to print stacks greather than value. Add arguments support to print stacks which are greater than argument value only. Co-developed-by: Vaneet Narang Signed-off-by: Vaneet Narang Signed-off-by: Maninder Singh Signed-off-by: Masahiro Yamada --- scripts/checkstack.pl | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) (limited to 'scripts') diff --git a/scripts/checkstack.pl b/scripts/checkstack.pl index 695710895560..bc23cc7edcaa 100755 --- a/scripts/checkstack.pl +++ b/scripts/checkstack.pl @@ -35,7 +35,7 @@ use strict; # $1 (first bracket) matches the dynamic amount of the stack growth # # use anything else and feel the pain ;) -my (@stack, $re, $dre, $x, $xs, $funcre); +my (@stack, $re, $dre, $x, $xs, $funcre, $min_stack); { my $arch = shift; if ($arch eq "") { @@ -43,6 +43,11 @@ my (@stack, $re, $dre, $x, $xs, $funcre); chomp($arch); } + $min_stack = shift; + if ($min_stack eq "" || $min_stack !~ /^\d+$/) { + $min_stack = 100; + } + $x = "[0-9a-f]"; # hex character $xs = "[0-9a-f ]"; # hex character or space $funcre = qr/^$x* <(.*)>:$/; @@ -117,7 +122,7 @@ while (my $line = ) { if ($line =~ m/$funcre/) { $func = $1; next if $line !~ m/^($xs*)/; - if ($total_size > 100) { + if ($total_size > $min_stack) { push @stack, "$intro$total_size\n"; } @@ -162,7 +167,7 @@ while (my $line = ) { $total_size += $size; } } -if ($total_size > 100) { +if ($total_size > $min_stack) { push @stack, "$intro$total_size\n"; } -- cgit v1.2.3 From 3311eeebae94b37a21b37af4410bb5e2fe3dc0c0 Mon Sep 17 00:00:00 2001 From: Maninder Singh Date: Fri, 8 May 2020 16:33:16 +0530 Subject: scripts/checkstack.pl: add arm push handling for stack usage To count stack usage of push {*, fp, ip, lr, pc} instruction in ARM, if FRAME POINTER is enabled. e.g. c01f0d48: e92ddff0 push {r4, r5, r6, r7, r8, r9, sl, fp, ip, lr, pc} c01f0d50 : c01f0d44: e1a0c00d mov ip, sp c01f0d48: e92ddff0 push {r4, r5, r6, r7, r8, r9, sl, fp, ip, lr, pc} c01f0d4c: e24cb004 sub fp, ip, #4 c01f0d50: e24dd094 sub sp, sp, #448 ; 0x1C0 $ cat dump | scripts/checkstack.pl arm 0xc01f0d50 Y []: 448 added subroutine frame work for this. After change: 0xc01f0d500 Y []: 492 Co-developed-by: Vaneet Narang Signed-off-by: Vaneet Narang Signed-off-by: Maninder Singh Signed-off-by: Masahiro Yamada --- scripts/checkstack.pl | 28 +++++++++++++++++++++++++++- 1 file changed, 27 insertions(+), 1 deletion(-) (limited to 'scripts') diff --git a/scripts/checkstack.pl b/scripts/checkstack.pl index bc23cc7edcaa..bc07e19f2786 100755 --- a/scripts/checkstack.pl +++ b/scripts/checkstack.pl @@ -34,8 +34,10 @@ use strict; # $& (whole re) matches the complete objdump line with the stack growth # $1 (first bracket) matches the dynamic amount of the stack growth # +# $sub: subroutine for special handling to check stack usage. +# # use anything else and feel the pain ;) -my (@stack, $re, $dre, $x, $xs, $funcre, $min_stack); +my (@stack, $re, $dre, $sub, $x, $xs, $funcre, $min_stack); { my $arch = shift; if ($arch eq "") { @@ -59,6 +61,7 @@ my (@stack, $re, $dre, $x, $xs, $funcre, $min_stack); } elsif ($arch eq 'arm') { #c0008ffc: e24dd064 sub sp, sp, #100 ; 0x64 $re = qr/.*sub.*sp, sp, #(([0-9]{2}|[3-9])[0-9]{2})/o; + $sub = \&arm_push_handling; } elsif ($arch =~ /^x86(_64)?$/ || $arch =~ /^i[3456]86$/) { #c0105234: 81 ec ac 05 00 00 sub $0x5ac,%esp # or @@ -111,6 +114,24 @@ my (@stack, $re, $dre, $x, $xs, $funcre, $min_stack); } } +# +# To count stack usage of push {*, fp, ip, lr, pc} instruction in ARM, +# if FRAME POINTER is enabled. +# e.g. c01f0d48: e92ddff0 push {r4, r5, r6, r7, r8, r9, sl, fp, ip, lr, pc} +# +sub arm_push_handling { + my $regex = qr/.*push.*fp, ip, lr, pc}/o; + my $size = 0; + my $line_arg = shift; + + if ($line_arg =~ m/$regex/) { + $size = $line_arg =~ tr/,//; + $size = ($size + 1) * 4; + } + + return $size; +} + # # main() # @@ -166,6 +187,11 @@ while (my $line = ) { $size = hex($size) if ($size =~ /^0x/); $total_size += $size; } + elsif (defined $sub) { + my $size = &$sub($line); + + $total_size += $size; + } } if ($total_size > $min_stack) { push @stack, "$intro$total_size\n"; -- cgit v1.2.3 From 6ce16f2bc879fb8943d2165f81862c6f89ec1b77 Mon Sep 17 00:00:00 2001 From: Maninder Singh Date: Fri, 8 May 2020 16:33:17 +0530 Subject: scripts/checkstack.pl: fix arm sp regex if objdump has below entries; c01ed608 : c01ed614: e24ddff7 sub sp, sp, #120 ; 0x78 c01f0d50 : c01f0d50: e24dd094 sub sp, sp, #140 ; 0x8c scripts fails to read stack usage. so making regex $re for ARM similar to aarch64 Co-developed-by: Vaneet Narang Signed-off-by: Vaneet Narang Signed-off-by: Maninder Singh Signed-off-by: Masahiro Yamada --- scripts/checkstack.pl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'scripts') diff --git a/scripts/checkstack.pl b/scripts/checkstack.pl index bc07e19f2786..d2c38584ece6 100755 --- a/scripts/checkstack.pl +++ b/scripts/checkstack.pl @@ -60,7 +60,7 @@ my (@stack, $re, $dre, $sub, $x, $xs, $funcre, $min_stack); $dre = qr/^.*sub.*sp, sp, #(0x$x{1,8})/o; } elsif ($arch eq 'arm') { #c0008ffc: e24dd064 sub sp, sp, #100 ; 0x64 - $re = qr/.*sub.*sp, sp, #(([0-9]{2}|[3-9])[0-9]{2})/o; + $re = qr/.*sub.*sp, sp, #([0-9]{1,4})/o; $sub = \&arm_push_handling; } elsif ($arch =~ /^x86(_64)?$/ || $arch =~ /^i[3456]86$/) { #c0105234: 81 ec ac 05 00 00 sub $0x5ac,%esp -- cgit v1.2.3 From 827365ffdaa9aa9c0b423800c4d0e72b1fbb938e Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Sun, 10 May 2020 11:00:44 +0900 Subject: gcc-plugins: remove always-false $(if ...) in Makefile This is the remnant of commit c17d6179ad5a ("gcc-plugins: remove unused GCC_PLUGIN_SUBDIR"). The conditional $(if $(findstring /,$(p)),...) is always false because none of plugins contains '/' in the file name. Clean up the code. Signed-off-by: Masahiro Yamada Reviewed-by: Kees Cook --- scripts/gcc-plugins/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'scripts') diff --git a/scripts/gcc-plugins/Makefile b/scripts/gcc-plugins/Makefile index 80f354289eeb..4014ba7e2fbd 100644 --- a/scripts/gcc-plugins/Makefile +++ b/scripts/gcc-plugins/Makefile @@ -14,7 +14,7 @@ $(objtree)/$(obj)/randomize_layout_seed.h: FORCE $(call if_changed,create_randomize_layout_seed) targets = randomize_layout_seed.h randomize_layout_hash.h -hostcxxlibs-y := $(foreach p,$(GCC_PLUGIN),$(if $(findstring /,$(p)),,$(p))) +hostcxxlibs-y := $(GCC_PLUGIN) always-y := $(hostcxxlibs-y) $(foreach p,$(hostcxxlibs-y:%.so=%),$(eval $(p)-objs := $(p).o)) -- cgit v1.2.3 From 8451791d1ff0fd229e3f5ef267a32423f5b5540f Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Mon, 11 May 2020 13:21:49 +0900 Subject: kbuild: make module name conflict fatal error I think all the warnings have been fixed by now. Make it a fatal error. Check it before modpost because we need to stop building *.ko files. Also, pass modules.order via a script parameter. Signed-off-by: Masahiro Yamada --- Makefile | 7 +++++-- scripts/modules-check.sh | 16 +++++++++++++--- 2 files changed, 18 insertions(+), 5 deletions(-) (limited to 'scripts') diff --git a/Makefile b/Makefile index 1915630cc24b..1f5bbfb31103 100644 --- a/Makefile +++ b/Makefile @@ -1335,9 +1335,12 @@ all: modules # using awk while concatenating to the final file. PHONY += modules -modules: $(if $(KBUILD_BUILTIN),vmlinux) modules.order +modules: $(if $(KBUILD_BUILTIN),vmlinux) modules_check $(Q)$(MAKE) -f $(srctree)/scripts/Makefile.modpost - $(Q)$(CONFIG_SHELL) $(srctree)/scripts/modules-check.sh + +PHONY += modules_check +modules_check: modules.order + $(Q)$(CONFIG_SHELL) $(srctree)/scripts/modules-check.sh $< modules.order: descend $(Q)$(AWK) '!x[$$0]++' $(addsuffix /$@, $(build-dirs)) > $@ diff --git a/scripts/modules-check.sh b/scripts/modules-check.sh index f51f446707b8..43de226071ae 100755 --- a/scripts/modules-check.sh +++ b/scripts/modules-check.sh @@ -3,14 +3,24 @@ set -e +if [ $# != 1 ]; then + echo "Usage: $0 " >& 2 + exit 1 +fi + +exit_code=0 + # Check uniqueness of module names check_same_name_modules() { - for m in $(sed 's:.*/::' modules.order | sort | uniq -d) + for m in $(sed 's:.*/::' $1 | sort | uniq -d) do - echo "warning: same module names found:" >&2 + echo "error: the following would cause module name conflict:" >&2 sed -n "/\/$m/s:^: :p" modules.order >&2 + exit_code=1 done } -check_same_name_modules +check_same_name_modules "$1" + +exit $exit_code -- cgit v1.2.3 From e578edc72276280b8fae57f6bf79cb443ceee7a2 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Fri, 22 May 2020 10:59:58 +0900 Subject: kbuild: remove ifdef builtin-target / lib-target I do not see a good reason to add ifdef here. Signed-off-by: Masahiro Yamada --- scripts/Makefile.build | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) (limited to 'scripts') diff --git a/scripts/Makefile.build b/scripts/Makefile.build index 3665b1a0bc8e..9af88f4cacb8 100644 --- a/scripts/Makefile.build +++ b/scripts/Makefile.build @@ -384,16 +384,14 @@ $(obj)/%/built-in.a: $(obj)/% ; # # Rule to compile a set of .o files into one .a file (without symbol table) # -ifdef builtin-target quiet_cmd_ar_builtin = AR $@ cmd_ar_builtin = rm -f $@; $(AR) cDPrST $@ $(real-prereqs) -$(builtin-target): $(real-obj-y) FORCE +$(obj)/built-in.a: $(real-obj-y) FORCE $(call if_changed,ar_builtin) targets += $(builtin-target) -endif # builtin-target # # Rule to create modules.order file @@ -408,15 +406,11 @@ $(modorder-target): $(subdir-ym) FORCE # # Rule to compile a set of .o files into one .a file (with symbol table) # -ifdef lib-target - -$(lib-target): $(lib-y) FORCE +$(obj)/lib.a: $(lib-y) FORCE $(call if_changed,ar) targets += $(lib-target) -endif - # NOTE: # Do not replace $(filter %.o,^) with $(real-prereqs). When a single object # module is turned into a multi object module, $^ will contain header file -- cgit v1.2.3 From b480fec988b051df792633e99bf622fc63a305f6 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Fri, 22 May 2020 10:59:59 +0900 Subject: kbuild: clear KBUILD_MODULES in top Makefile if CONFIG_MODULES=n Do not try to build any module-related artifacts when CONFIG_MODULES is disabled. Signed-off-by: Masahiro Yamada --- Makefile | 4 ++++ scripts/Makefile.build | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) (limited to 'scripts') diff --git a/Makefile b/Makefile index 1f5bbfb31103..72eb55a36545 100644 --- a/Makefile +++ b/Makefile @@ -1724,6 +1724,10 @@ build-dirs := $(foreach d, $(build-dirs), \ endif +ifndef CONFIG_MODULES +KBUILD_MODULES := +endif + # Handle descending into subdirectories listed in $(build-dirs) # Preset locale variables to speed up the build process. Limit locale # tweaks to this spot to avoid wrong language settings when running diff --git a/scripts/Makefile.build b/scripts/Makefile.build index 9af88f4cacb8..f46d25441804 100644 --- a/scripts/Makefile.build +++ b/scripts/Makefile.build @@ -77,7 +77,7 @@ ifdef need-builtin builtin-target := $(obj)/built-in.a endif -ifeq ($(CONFIG_MODULES)$(need-modorder),y1) +ifdef need-modorder modorder-target := $(obj)/modules.order endif -- cgit v1.2.3 From 6ba3bcb01393777d38c8b466249e4a3e6ffc8adb Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Fri, 22 May 2020 11:00:00 +0900 Subject: kbuild: move subdir-obj-y to scripts/Makefile.build Save $(addprefix ...) for subdir-obj-y. Signed-off-by: Masahiro Yamada --- scripts/Makefile.build | 2 ++ scripts/Makefile.lib | 5 ----- 2 files changed, 2 insertions(+), 5 deletions(-) (limited to 'scripts') diff --git a/scripts/Makefile.build b/scripts/Makefile.build index f46d25441804..ee283efc1b45 100644 --- a/scripts/Makefile.build +++ b/scripts/Makefile.build @@ -69,6 +69,8 @@ endif # =========================================================================== +subdir-obj-y := $(filter %/built-in.a, $(real-obj-y)) + ifneq ($(strip $(lib-y) $(lib-m) $(lib-)),) lib-target := $(obj)/lib.a endif diff --git a/scripts/Makefile.lib b/scripts/Makefile.lib index 52299d5dba28..a41a4bbd20e2 100644 --- a/scripts/Makefile.lib +++ b/scripts/Makefile.lib @@ -62,10 +62,6 @@ multi-used-y := $(sort $(foreach m,$(obj-y), $(if $(strip $($(m:.o=-objs)) $($(m multi-used-m := $(sort $(foreach m,$(obj-m), $(if $(strip $($(m:.o=-objs)) $($(m:.o=-y)) $($(m:.o=-m)) $($(m:.o=-))), $(m)))) multi-used := $(multi-used-y) $(multi-used-m) -# $(subdir-obj-y) is the list of objects in $(obj-y) which uses dir/ to -# tell kbuild to descend -subdir-obj-y := $(filter %/built-in.a, $(obj-y)) - # Replace multi-part objects by their individual parts, # including built-in.a from subdirectories real-obj-y := $(foreach m, $(obj-y), $(if $(strip $($(m:.o=-objs)) $($(m:.o=-y)) $($(m:.o=-))),$($(m:.o=-objs)) $($(m:.o=-y)),$(m))) @@ -91,7 +87,6 @@ targets := $(addprefix $(obj)/,$(targets)) modorder := $(addprefix $(obj)/,$(modorder)) obj-m := $(addprefix $(obj)/,$(obj-m)) lib-y := $(addprefix $(obj)/,$(lib-y)) -subdir-obj-y := $(addprefix $(obj)/,$(subdir-obj-y)) real-obj-y := $(addprefix $(obj)/,$(real-obj-y)) real-obj-m := $(addprefix $(obj)/,$(real-obj-m)) multi-used-m := $(addprefix $(obj)/,$(multi-used-m)) -- cgit v1.2.3 From aaa385ba9afe7aca25a1545a609963ee59b6c76b Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Fri, 22 May 2020 11:00:01 +0900 Subject: kbuild: rename subdir-obj-y to subdir-builtin I think subdir-builtin is clearer. While I was here, I made its build rule explicit. Signed-off-by: Masahiro Yamada --- scripts/Makefile.build | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) (limited to 'scripts') diff --git a/scripts/Makefile.build b/scripts/Makefile.build index ee283efc1b45..323264607b9f 100644 --- a/scripts/Makefile.build +++ b/scripts/Makefile.build @@ -69,7 +69,8 @@ endif # =========================================================================== -subdir-obj-y := $(filter %/built-in.a, $(real-obj-y)) +# subdir-builtin may contain duplications. Use $(sort ...) +subdir-builtin := $(sort $(filter %/built-in.a, $(real-obj-y))) ifneq ($(strip $(lib-y) $(lib-m) $(lib-)),) lib-target := $(obj)/lib.a @@ -356,7 +357,7 @@ endif $(obj)/%.o: $(src)/%.S $(objtool_dep) FORCE $(call if_changed_rule,as_o_S) -targets += $(filter-out $(subdir-obj-y), $(real-obj-y)) $(real-obj-m) $(lib-y) +targets += $(filter-out $(subdir-builtin), $(real-obj-y)) $(real-obj-m) $(lib-y) targets += $(extra-y) $(always-y) $(MAKECMDGOALS) # Linker scripts preprocessor (.lds.S -> .lds) @@ -381,7 +382,7 @@ $(obj)/%.asn1.c $(obj)/%.asn1.h: $(src)/%.asn1 $(objtree)/scripts/asn1_compiler # --------------------------------------------------------------------------- # To build objects in subdirs, we need to descend into the directories -$(obj)/%/built-in.a: $(obj)/% ; +$(subdir-builtin): $(obj)/%/built-in.a: $(obj)/% ; # # Rule to compile a set of .o files into one .a file (without symbol table) @@ -489,7 +490,7 @@ PHONY += $(subdir-ym) $(subdir-ym): $(Q)$(MAKE) $(build)=$@ \ $(if $(filter $@/, $(KBUILD_SINGLE_TARGETS)),single-build=) \ - need-builtin=$(if $(filter $@/built-in.a, $(subdir-obj-y)),1) \ + need-builtin=$(if $(filter $@/built-in.a, $(subdir-builtin)),1) \ need-modorder=$(if $(need-modorder),$(if $(filter $@/modules.order, $(modorder)),1)) # Add FORCE to the prequisites of a target to force it to be always rebuilt. -- cgit v1.2.3 From 454753d9f67ae40b6a2142ddb6b4dbdcc9654aa9 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Fri, 22 May 2020 11:00:02 +0900 Subject: kbuild: make modules.order rule consistent with built-in.a built-in.a contains the built-in object paths from the current and sub directories. module.order collects the module paths from the current and sub directories. Make their build rules look more symmetrical. Signed-off-by: Masahiro Yamada --- scripts/Makefile.build | 10 ++++++---- scripts/Makefile.lib | 2 ++ 2 files changed, 8 insertions(+), 4 deletions(-) (limited to 'scripts') diff --git a/scripts/Makefile.build b/scripts/Makefile.build index 323264607b9f..ee9a817e19a3 100644 --- a/scripts/Makefile.build +++ b/scripts/Makefile.build @@ -69,8 +69,9 @@ endif # =========================================================================== -# subdir-builtin may contain duplications. Use $(sort ...) +# subdir-builtin and subdir-modorder may contain duplications. Use $(sort ...) subdir-builtin := $(sort $(filter %/built-in.a, $(real-obj-y))) +subdir-modorder := $(sort $(filter %/modules.order, $(modorder))) ifneq ($(strip $(lib-y) $(lib-m) $(lib-)),) lib-target := $(obj)/lib.a @@ -383,6 +384,7 @@ $(obj)/%.asn1.c $(obj)/%.asn1.h: $(src)/%.asn1 $(objtree)/scripts/asn1_compiler # To build objects in subdirs, we need to descend into the directories $(subdir-builtin): $(obj)/%/built-in.a: $(obj)/% ; +$(subdir-modorder): $(obj)/%/modules.order: $(obj)/% ; # # Rule to compile a set of .o files into one .a file (without symbol table) @@ -401,9 +403,9 @@ targets += $(builtin-target) # # Create commands to either record .ko file or cat modules.order from # a subdirectory -$(modorder-target): $(subdir-ym) FORCE +$(obj)/modules.order: $(subdir-modorder) FORCE $(Q){ $(foreach m, $(modorder), \ - $(if $(filter %/modules.order, $m), cat $m, echo $m);) :; } \ + $(if $(filter $^, $m), cat $m, echo $m);) :; } \ | $(AWK) '!x[$$0]++' - > $@ # @@ -491,7 +493,7 @@ $(subdir-ym): $(Q)$(MAKE) $(build)=$@ \ $(if $(filter $@/, $(KBUILD_SINGLE_TARGETS)),single-build=) \ need-builtin=$(if $(filter $@/built-in.a, $(subdir-builtin)),1) \ - need-modorder=$(if $(need-modorder),$(if $(filter $@/modules.order, $(modorder)),1)) + need-modorder=$(if $(filter $@/modules.order, $(subdir-modorder)),1) # Add FORCE to the prequisites of a target to force it to be always rebuilt. # --------------------------------------------------------------------------- diff --git a/scripts/Makefile.lib b/scripts/Makefile.lib index a41a4bbd20e2..0d931cc0df94 100644 --- a/scripts/Makefile.lib +++ b/scripts/Makefile.lib @@ -35,7 +35,9 @@ lib-y := $(filter-out $(obj-y), $(sort $(lib-y) $(lib-m))) # Determine modorder. # Unfortunately, we don't have information about ordering between -y # and -m subdirs. Just put -y's first. +ifdef need-modorder modorder := $(patsubst %/,%/modules.order, $(filter %/, $(obj-y)) $(obj-m:.o=.ko)) +endif # Handle objects in subdirs # --------------------------------------------------------------------------- -- cgit v1.2.3 From e9e81b634303b215e83beced03f04f02f7893442 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Mon, 25 May 2020 00:42:15 +0900 Subject: kbuild: disallow multi-word in M= or KBUILD_EXTMOD $(firstword ...) in scripts/Makefile.modpost was added by commit 3f3fd3c05585 ("[PATCH] kbuild: allow multi-word $M in Makefile.modpost") to build multiple external module directories. It was a solution to resolve symbol dependencies when an external module depends on another external module. Commit 0d96fb20b7ed ("kbuild: Add new Kbuild variable KBUILD_EXTRA_SYMBOLS") introduced another solution by passing symbol info via KBUILD_EXTRA_SYMBOLS, then broke the multi-word M= support. include $(if $(wildcard $(KBUILD_EXTMOD)/Kbuild), \ $(KBUILD_EXTMOD)/Kbuild, $(KBUILD_EXTMOD)/Makefile) ... does not work if KBUILD_EXTMOD contains multiple words. This feature has been broken for more than a decade. Remove the bitrotten code, and stop parsing if M or KBUILD_EXTMOD contains multiple words. As Documentation/kbuild/modules.rst explains, if your module depends on another one, there are two solutions: - add a common top-level Kbuild file - use KBUILD_EXTRA_SYMBOLS Signed-off-by: Masahiro Yamada --- Makefile | 3 +++ scripts/Makefile.modpost | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) (limited to 'scripts') diff --git a/Makefile b/Makefile index 72eb55a36545..48a2dfaf3bf3 100644 --- a/Makefile +++ b/Makefile @@ -218,6 +218,9 @@ ifeq ("$(origin M)", "command line") KBUILD_EXTMOD := $(M) endif +$(if $(word 2, $(KBUILD_EXTMOD)), \ + $(error building multiple external modules is not supported)) + export KBUILD_CHECKSRC KBUILD_EXTMOD extmod-prefix = $(if $(KBUILD_EXTMOD),$(KBUILD_EXTMOD)/) diff --git a/scripts/Makefile.modpost b/scripts/Makefile.modpost index 957eed6a17a5..b79bf0e30d32 100644 --- a/scripts/Makefile.modpost +++ b/scripts/Makefile.modpost @@ -44,7 +44,7 @@ include include/config/auto.conf include scripts/Kbuild.include kernelsymfile := $(objtree)/Module.symvers -modulesymfile := $(firstword $(KBUILD_EXTMOD))/Module.symvers +modulesymfile := $(KBUILD_EXTMOD)/Module.symvers MODPOST = scripts/mod/modpost \ $(if $(CONFIG_MODVERSIONS),-m) \ -- cgit v1.2.3 From d2e4d05cf1a1f8bfe168ea29b217355be7a4e9ec Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Mon, 25 May 2020 14:47:04 +0900 Subject: modpost: fix potential segmentation fault for addend_i386_rel() This may not be a practical problem, but the second pass of ARCH=i386 modpost causes segmentation fault if the -s option is not passed. MODPOST 12 modules Segmentation fault (core dumped) make[2]: *** [scripts/Makefile.modpost:94: __modpost] Error 139 make[1]: *** [Makefile:1339: modules] Error 2 make[1]: *** Waiting for unfinished jobs.... The segmentation fault occurs when section_rel() is called for vmlinux, which is untested in regular builds. The cause of the problem is reloc_location() returning a wrong pointer for ET_EXEC object type. In this case, you need to subtract sechdr->sh_addr, otherwise it would get access beyond the mmap'ed memory. Add sym_get_data_by_offset() helper to avoid code duplication. Signed-off-by: Masahiro Yamada --- scripts/mod/modpost.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) (limited to 'scripts') diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c index 4d4b979d76be..8c5f1bd75481 100644 --- a/scripts/mod/modpost.c +++ b/scripts/mod/modpost.c @@ -300,19 +300,23 @@ static const char *sec_name(struct elf_info *elf, int secindex) return sech_name(elf, &elf->sechdrs[secindex]); } -static void *sym_get_data(const struct elf_info *info, const Elf_Sym *sym) +static void *sym_get_data_by_offset(const struct elf_info *info, + unsigned int secindex, unsigned long offset) { - unsigned int secindex = get_secindex(info, sym); Elf_Shdr *sechdr = &info->sechdrs[secindex]; - unsigned long offset; - offset = sym->st_value; if (info->hdr->e_type != ET_REL) offset -= sechdr->sh_addr; return (void *)info->hdr + sechdr->sh_offset + offset; } +static void *sym_get_data(const struct elf_info *info, const Elf_Sym *sym) +{ + return sym_get_data_by_offset(info, get_secindex(info, sym), + sym->st_value); +} + #define strstarts(str, prefix) (strncmp(str, prefix, strlen(prefix)) == 0) static enum export export_from_secname(struct elf_info *elf, unsigned int sec) @@ -1752,11 +1756,7 @@ static void check_section_mismatch(const char *modname, struct elf_info *elf, static unsigned int *reloc_location(struct elf_info *elf, Elf_Shdr *sechdr, Elf_Rela *r) { - Elf_Shdr *sechdrs = elf->sechdrs; - int section = sechdr->sh_info; - - return (void *)elf->hdr + sechdrs[section].sh_offset + - r->r_offset; + return sym_get_data_by_offset(elf, sechdr->sh_info, r->r_offset); } static int addend_386_rel(struct elf_info *elf, Elf_Shdr *sechdr, Elf_Rela *r) -- cgit v1.2.3 From 565587d8d5b518234652063820561587fc269c11 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Mon, 25 May 2020 14:47:05 +0900 Subject: modpost: refactor sech_name() Use sym_get_data_by_offset() helper to get access to the .shstrtab section data. No functional change is intended because elf->sechdrs[elf->secindex_strings].sh_addr is 0 for both ET_REL and ET_EXEC object types. Signed-off-by: Masahiro Yamada --- scripts/mod/modpost.c | 23 +++++++++++------------ 1 file changed, 11 insertions(+), 12 deletions(-) (limited to 'scripts') diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c index 8c5f1bd75481..160139508821 100644 --- a/scripts/mod/modpost.c +++ b/scripts/mod/modpost.c @@ -288,18 +288,6 @@ static enum export export_no(const char *s) return export_unknown; } -static const char *sech_name(struct elf_info *elf, Elf_Shdr *sechdr) -{ - return (void *)elf->hdr + - elf->sechdrs[elf->secindex_strings].sh_offset + - sechdr->sh_name; -} - -static const char *sec_name(struct elf_info *elf, int secindex) -{ - return sech_name(elf, &elf->sechdrs[secindex]); -} - static void *sym_get_data_by_offset(const struct elf_info *info, unsigned int secindex, unsigned long offset) { @@ -317,6 +305,17 @@ static void *sym_get_data(const struct elf_info *info, const Elf_Sym *sym) sym->st_value); } +static const char *sech_name(const struct elf_info *info, Elf_Shdr *sechdr) +{ + return sym_get_data_by_offset(info, info->secindex_strings, + sechdr->sh_name); +} + +static const char *sec_name(const struct elf_info *info, int secindex) +{ + return sech_name(info, &info->sechdrs[secindex]); +} + #define strstarts(str, prefix) (strncmp(str, prefix, strlen(prefix)) == 0) static enum export export_from_secname(struct elf_info *elf, unsigned int sec) -- cgit v1.2.3 From 0a8820e7f807158670d3400974b20691cd8774d9 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Mon, 1 Jun 2020 14:56:55 +0900 Subject: kbuild: refactor subdir-ym calculation Remove the unneeded variables, __subdir-y and __subdir-m. Signed-off-by: Masahiro Yamada --- scripts/Makefile.lib | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) (limited to 'scripts') diff --git a/scripts/Makefile.lib b/scripts/Makefile.lib index 0d931cc0df94..748e44d5a1e3 100644 --- a/scripts/Makefile.lib +++ b/scripts/Makefile.lib @@ -39,16 +39,14 @@ ifdef need-modorder modorder := $(patsubst %/,%/modules.order, $(filter %/, $(obj-y)) $(obj-m:.o=.ko)) endif +# Subdirectories we need to descend into +subdir-ym := $(sort $(subdir-y) $(subdir-m) \ + $(patsubst %/,%, $(filter %/, $(obj-y) $(obj-m)))) + # Handle objects in subdirs # --------------------------------------------------------------------------- # o if we encounter foo/ in $(obj-y), replace it by foo/built-in.a -# and add the directory to the list of dirs to descend into: $(subdir-y) # o if we encounter foo/ in $(obj-m), remove it from $(obj-m) -# and add the directory to the list of dirs to descend into: $(subdir-m) -__subdir-y := $(patsubst %/,%,$(filter %/, $(obj-y))) -subdir-y += $(__subdir-y) -__subdir-m := $(patsubst %/,%,$(filter %/, $(obj-m))) -subdir-m += $(__subdir-m) ifdef need-builtin obj-y := $(patsubst %/, %/built-in.a, $(obj-y)) else @@ -56,9 +54,6 @@ obj-y := $(filter-out %/, $(obj-y)) endif obj-m := $(filter-out %/, $(obj-m)) -# Subdirectories we need to descend into -subdir-ym := $(sort $(subdir-y) $(subdir-m)) - # If $(foo-objs), $(foo-y), $(foo-m), or $(foo-) exists, foo.o is a composite object multi-used-y := $(sort $(foreach m,$(obj-y), $(if $(strip $($(m:.o=-objs)) $($(m:.o=-y)) $($(m:.o=-))), $(m)))) multi-used-m := $(sort $(foreach m,$(obj-m), $(if $(strip $($(m:.o=-objs)) $($(m:.o=-y)) $($(m:.o=-m)) $($(m:.o=-))), $(m)))) -- cgit v1.2.3 From f3908ab3ffd92c77af1bad7f699b8a1c14f462bf Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Mon, 1 Jun 2020 14:56:56 +0900 Subject: kbuild: refactor tagets caluculation for KBUILD_{BUILTIN,KBUILD_MODULES} Remove lib-target, builtin-target, modorder-target, and modtargets. Instead, add targets-for-builtin and targets-for-modules. Signed-off-by: Masahiro Yamada --- scripts/Makefile.build | 25 ++++++++++++------------- 1 file changed, 12 insertions(+), 13 deletions(-) (limited to 'scripts') diff --git a/scripts/Makefile.build b/scripts/Makefile.build index ee9a817e19a3..a1f09bec8c70 100644 --- a/scripts/Makefile.build +++ b/scripts/Makefile.build @@ -73,19 +73,24 @@ endif subdir-builtin := $(sort $(filter %/built-in.a, $(real-obj-y))) subdir-modorder := $(sort $(filter %/modules.order, $(modorder))) +targets-for-builtin := $(extra-y) + ifneq ($(strip $(lib-y) $(lib-m) $(lib-)),) -lib-target := $(obj)/lib.a +targets-for-builtin += $(obj)/lib.a endif ifdef need-builtin -builtin-target := $(obj)/built-in.a +targets-for-builtin += $(obj)/built-in.a endif +targets-for-modules := $(obj-m) +targets-for-modules += $(patsubst %.o, %.mod, $(obj-m)) + ifdef need-modorder -modorder-target := $(obj)/modules.order +targets-for-modules += $(obj)/modules.order endif -mod-targets := $(patsubst %.o, %.mod, $(obj-m)) +targets += $(targets-for-builtin) $(targets-for-modules) # Linus' kernel sanity checking tool ifeq ($(KBUILD_CHECKSRC),1) @@ -284,8 +289,6 @@ cmd_mod = { \ $(obj)/%.mod: $(obj)/%.o FORCE $(call if_changed,mod) -targets += $(mod-targets) - quiet_cmd_cc_lst_c = MKLST $@ cmd_cc_lst_c = $(CC) $(c_flags) -g -c -o $*.o $< && \ $(CONFIG_SHELL) $(srctree)/scripts/makelst $*.o \ @@ -359,7 +362,7 @@ $(obj)/%.o: $(src)/%.S $(objtool_dep) FORCE $(call if_changed_rule,as_o_S) targets += $(filter-out $(subdir-builtin), $(real-obj-y)) $(real-obj-m) $(lib-y) -targets += $(extra-y) $(always-y) $(MAKECMDGOALS) +targets += $(always-y) $(MAKECMDGOALS) # Linker scripts preprocessor (.lds.S -> .lds) # --------------------------------------------------------------------------- @@ -396,8 +399,6 @@ quiet_cmd_ar_builtin = AR $@ $(obj)/built-in.a: $(real-obj-y) FORCE $(call if_changed,ar_builtin) -targets += $(builtin-target) - # # Rule to create modules.order file # @@ -414,8 +415,6 @@ $(obj)/modules.order: $(subdir-modorder) FORCE $(obj)/lib.a: $(lib-y) FORCE $(call if_changed,ar) -targets += $(lib-target) - # NOTE: # Do not replace $(filter %.o,^) with $(real-prereqs). When a single object # module is turned into a multi object module, $^ will contain header file @@ -478,8 +477,8 @@ endif else -__build: $(if $(KBUILD_BUILTIN),$(builtin-target) $(lib-target) $(extra-y)) \ - $(if $(KBUILD_MODULES),$(obj-m) $(mod-targets) $(modorder-target)) \ +__build: $(if $(KBUILD_BUILTIN), $(targets-for-builtin)) \ + $(if $(KBUILD_MODULES), $(targets-for-modules)) \ $(subdir-ym) $(always-y) @: -- cgit v1.2.3 From b2c88554912267483baf8b4f5ae0a1bff529f6a3 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Mon, 1 Jun 2020 14:57:00 +0900 Subject: kbuild: update modules.order only when contained modules are updated Make modules.order depend on $(obj-m), and use if_changed to build it. This will avoid unneeded update of modules.order, which will be useful to optimize the modpost stage. Currently, the second pass of modpost is always invoked. By checking the timestamp of modules.order, we can avoid the unneeded modpost. Signed-off-by: Masahiro Yamada --- Makefile | 14 +++++++++++--- scripts/Makefile.build | 21 +++++++++++++-------- scripts/Makefile.lib | 27 ++++++++++++++------------- 3 files changed, 38 insertions(+), 24 deletions(-) (limited to 'scripts') diff --git a/Makefile b/Makefile index 24cf37c21cba..b0bbf8453b66 100644 --- a/Makefile +++ b/Makefile @@ -1066,6 +1066,10 @@ vmlinux-alldirs := $(sort $(vmlinux-dirs) Documentation \ $(patsubst %/,%,$(filter %/, $(core-) \ $(drivers-) $(libs-)))) +subdir-modorder := $(addsuffix modules.order,$(filter %/, \ + $(core-y) $(core-m) $(libs-y) $(libs-m) \ + $(drivers-y) $(drivers-m))) + build-dirs := $(vmlinux-dirs) clean-dirs := $(vmlinux-alldirs) @@ -1124,7 +1128,7 @@ targets := vmlinux # The actual objects are generated when descending, # make sure no implicit rule kicks in -$(sort $(vmlinux-deps)): descend ; +$(sort $(vmlinux-deps) $(subdir-modorder)): descend ; filechk_kernel.release = \ echo "$(KERNELVERSION)$$($(CONFIG_SHELL) $(srctree)/scripts/setlocalversion $(srctree))" @@ -1345,8 +1349,12 @@ PHONY += modules_check modules_check: modules.order $(Q)$(CONFIG_SHELL) $(srctree)/scripts/modules-check.sh $< -modules.order: descend - $(Q)$(AWK) '!x[$$0]++' $(addsuffix /$@, $(build-dirs)) > $@ +cmd_modules_order = $(AWK) '!x[$$0]++' $(real-prereqs) > $@ + +modules.order: $(subdir-modorder) FORCE + $(call if_changed,modules_order) + +targets += modules.order # Target to prepare building external modules PHONY += modules_prepare diff --git a/scripts/Makefile.build b/scripts/Makefile.build index a1f09bec8c70..2e8810b7e5ed 100644 --- a/scripts/Makefile.build +++ b/scripts/Makefile.build @@ -71,7 +71,7 @@ endif # subdir-builtin and subdir-modorder may contain duplications. Use $(sort ...) subdir-builtin := $(sort $(filter %/built-in.a, $(real-obj-y))) -subdir-modorder := $(sort $(filter %/modules.order, $(modorder))) +subdir-modorder := $(sort $(filter %/modules.order, $(obj-m))) targets-for-builtin := $(extra-y) @@ -83,8 +83,7 @@ ifdef need-builtin targets-for-builtin += $(obj)/built-in.a endif -targets-for-modules := $(obj-m) -targets-for-modules += $(patsubst %.o, %.mod, $(obj-m)) +targets-for-modules := $(patsubst %.o, %.mod, $(filter %.o, $(obj-m))) ifdef need-modorder targets-for-modules += $(obj)/modules.order @@ -361,8 +360,9 @@ endif $(obj)/%.o: $(src)/%.S $(objtool_dep) FORCE $(call if_changed_rule,as_o_S) -targets += $(filter-out $(subdir-builtin), $(real-obj-y)) $(real-obj-m) $(lib-y) -targets += $(always-y) $(MAKECMDGOALS) +targets += $(filter-out $(subdir-builtin), $(real-obj-y)) +targets += $(filter-out $(subdir-modorder), $(real-obj-m)) +targets += $(lib-y) $(always-y) $(MAKECMDGOALS) # Linker scripts preprocessor (.lds.S -> .lds) # --------------------------------------------------------------------------- @@ -404,11 +404,16 @@ $(obj)/built-in.a: $(real-obj-y) FORCE # # Create commands to either record .ko file or cat modules.order from # a subdirectory -$(obj)/modules.order: $(subdir-modorder) FORCE - $(Q){ $(foreach m, $(modorder), \ - $(if $(filter $^, $m), cat $m, echo $m);) :; } \ +# Add $(obj-m) as the prerequisite to avoid updating the timestamp of +# modules.order unless contained modules are updated. + +cmd_modules_order = { $(foreach m, $(real-prereqs), \ + $(if $(filter %/modules.order, $m), cat $m, echo $(patsubst %.o,%.ko,$m));) :; } \ | $(AWK) '!x[$$0]++' - > $@ +$(obj)/modules.order: $(obj-m) FORCE + $(call if_changed,modules_order) + # # Rule to compile a set of .o files into one .a file (with symbol table) # diff --git a/scripts/Makefile.lib b/scripts/Makefile.lib index 748e44d5a1e3..e598b07e6de4 100644 --- a/scripts/Makefile.lib +++ b/scripts/Makefile.lib @@ -32,27 +32,29 @@ obj-m := $(filter-out $(obj-y),$(obj-m)) # Filter out objects already built-in lib-y := $(filter-out $(obj-y), $(sort $(lib-y) $(lib-m))) -# Determine modorder. -# Unfortunately, we don't have information about ordering between -y -# and -m subdirs. Just put -y's first. -ifdef need-modorder -modorder := $(patsubst %/,%/modules.order, $(filter %/, $(obj-y)) $(obj-m:.o=.ko)) -endif - # Subdirectories we need to descend into subdir-ym := $(sort $(subdir-y) $(subdir-m) \ $(patsubst %/,%, $(filter %/, $(obj-y) $(obj-m)))) -# Handle objects in subdirs -# --------------------------------------------------------------------------- -# o if we encounter foo/ in $(obj-y), replace it by foo/built-in.a -# o if we encounter foo/ in $(obj-m), remove it from $(obj-m) +# Handle objects in subdirs: +# - If we encounter foo/ in $(obj-y), replace it by foo/built-in.a and +# foo/modules.order +# - If we encounter foo/ in $(obj-m), replace it by foo/modules.order +# +# Generate modules.order to determine modorder. Unfortunately, we don't have +# information about ordering between -y and -m subdirs. Just put -y's first. + +ifdef need-modorder +obj-m := $(patsubst %/,%/modules.order, $(filter %/, $(obj-y)) $(obj-m)) +else +obj-m := $(filter-out %/, $(obj-m)) +endif + ifdef need-builtin obj-y := $(patsubst %/, %/built-in.a, $(obj-y)) else obj-y := $(filter-out %/, $(obj-y)) endif -obj-m := $(filter-out %/, $(obj-m)) # If $(foo-objs), $(foo-y), $(foo-m), or $(foo-) exists, foo.o is a composite object multi-used-y := $(sort $(foreach m,$(obj-y), $(if $(strip $($(m:.o=-objs)) $($(m:.o=-y)) $($(m:.o=-))), $(m)))) @@ -81,7 +83,6 @@ endif extra-y := $(addprefix $(obj)/,$(extra-y)) always-y := $(addprefix $(obj)/,$(always-y)) targets := $(addprefix $(obj)/,$(targets)) -modorder := $(addprefix $(obj)/,$(modorder)) obj-m := $(addprefix $(obj)/,$(obj-m)) lib-y := $(addprefix $(obj)/,$(lib-y)) real-obj-y := $(addprefix $(obj)/,$(real-obj-y)) -- cgit v1.2.3 From 91e6ee581270b8ae970f028b898314d73f16870b Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Mon, 1 Jun 2020 14:57:01 +0900 Subject: modpost: fix -i (--ignore-errors) MAKEFLAGS detection $(filter -i,$(MAKEFLAGS)) works only in limited use-cases. The representation of $(MAKEFLAGS) depends on various factors: - GNU Make version (version 3.8x or version 4.x) - The presence of other flags like -j In my experiments, $(MAKEFLAGS) is expanded as follows: * GNU Make 3.8x: * without -j option: --no-print-directory -Rri * with -j option: --no-print-directory -Rr --jobserver-fds=3,4 -j -i * GNU Make 4.x: * without -j option: irR --no-print-directory * with -j option: irR -j --jobserver-fds=3,4 --no-print-directory For GNU Make 4.x, the flags are grouped as 'irR', which does not work. For the single thread build with GNU Make 3.8x, the flags are grouped as '-Rri', which does not work either. To make it work for all cases, do likewise as commit 6f0fa58e4596 ("kbuild: simplify silent build (-s) detection"). BTW, since commit ff9b45c55b26 ("kbuild: modpost: read modules.order instead of $(MODVERDIR)/*.mod"), you also need to pass -k option to build final *.ko files. 'make -i -k' ignores compile errors in modules, and build as many remaining *.ko as possible. Please note this feature is kind of dangerous if other modules depend on the broken module because the generated modules will lack the correct module dependency or CRC. Honestly, I am not a big fan of it, but I am keeping this feature. Fixes: eed380f3f593 ("modpost: Optionally ignore secondary errors seen if a single module build fails") Cc: Guenter Roeck Signed-off-by: Masahiro Yamada --- scripts/Makefile.modpost | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'scripts') diff --git a/scripts/Makefile.modpost b/scripts/Makefile.modpost index b79bf0e30d32..cadc74c6b5a4 100644 --- a/scripts/Makefile.modpost +++ b/scripts/Makefile.modpost @@ -66,7 +66,7 @@ __modpost: else -MODPOST += $(subst -i,-n,$(filter -i,$(MAKEFLAGS))) -s -T - \ +MODPOST += -s -T - \ $(if $(KBUILD_NSDEPS),-d $(MODULES_NSDEPS)) ifeq ($(KBUILD_EXTMOD),) @@ -82,6 +82,11 @@ include $(if $(wildcard $(KBUILD_EXTMOD)/Kbuild), \ $(KBUILD_EXTMOD)/Kbuild, $(KBUILD_EXTMOD)/Makefile) endif +# 'make -i -k' ignores compile errors, and builds as many modules as possible. +ifneq ($(findstring i,$(filter-out --%,$(MAKEFLAGS))),) +MODPOST += -n +endif + # find all modules listed in modules.order modules := $(sort $(shell cat $(MODORDER))) -- cgit v1.2.3 From 89d6117680bd8ac6a86f58576de0bd6905421707 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Mon, 1 Jun 2020 14:57:02 +0900 Subject: modpost: move -T option close to the modpost command The '-T -' option reads the file list from stdin. It is clearer to put it close to the piped command. Signed-off-by: Masahiro Yamada --- scripts/Makefile.modpost | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'scripts') diff --git a/scripts/Makefile.modpost b/scripts/Makefile.modpost index cadc74c6b5a4..ac143c085182 100644 --- a/scripts/Makefile.modpost +++ b/scripts/Makefile.modpost @@ -66,7 +66,7 @@ __modpost: else -MODPOST += -s -T - \ +MODPOST += -s \ $(if $(KBUILD_NSDEPS),-d $(MODULES_NSDEPS)) ifeq ($(KBUILD_EXTMOD),) @@ -93,7 +93,7 @@ modules := $(sort $(shell cat $(MODORDER))) # Read out modules.order instead of expanding $(modules) to pass in modpost. # Otherwise, allmodconfig would fail with "Argument list too long". quiet_cmd_modpost = MODPOST $(words $(modules)) modules - cmd_modpost = sed 's/ko$$/o/' $(MODORDER) | $(MODPOST) + cmd_modpost = sed 's/ko$$/o/' $(MODORDER) | $(MODPOST) -T - __modpost: $(call cmd,modpost) -- cgit v1.2.3 From 4e5ab74c3cbbe7ca2b907a86ce5140e442b340bf Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Mon, 1 Jun 2020 14:57:03 +0900 Subject: modpost: pass -N option only for modules modpost The built-in only code is not required to have MODULE_IMPORT_NS() to use symbols. So, the namespace is not checked for vmlinux(.o). Do not pass the meaningless -N option to the first pass of modpost. Signed-off-by: Masahiro Yamada --- scripts/Makefile.modpost | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'scripts') diff --git a/scripts/Makefile.modpost b/scripts/Makefile.modpost index ac143c085182..3334f100a490 100644 --- a/scripts/Makefile.modpost +++ b/scripts/Makefile.modpost @@ -53,7 +53,6 @@ MODPOST = scripts/mod/modpost \ $(if $(KBUILD_EXTMOD),$(addprefix -e ,$(KBUILD_EXTRA_SYMBOLS))) \ $(if $(KBUILD_EXTMOD),-o $(modulesymfile)) \ $(if $(CONFIG_SECTION_MISMATCH_WARN_ONLY),,-E) \ - $(if $(CONFIG_MODULE_ALLOW_MISSING_NAMESPACE_IMPORTS)$(KBUILD_NSDEPS),-N) \ $(if $(KBUILD_MODPOST_WARN),-w) ifdef MODPOST_VMLINUX @@ -82,6 +81,10 @@ include $(if $(wildcard $(KBUILD_EXTMOD)/Kbuild), \ $(KBUILD_EXTMOD)/Kbuild, $(KBUILD_EXTMOD)/Makefile) endif +# modpost options for modules (both in-kernel and external) +MODPOST += \ + $(if $(CONFIG_MODULE_ALLOW_MISSING_NAMESPACE_IMPORTS)$(KBUILD_NSDEPS),-N) + # 'make -i -k' ignores compile errors, and builds as many modules as possible. ifneq ($(findstring i,$(filter-out --%,$(MAKEFLAGS))),) MODPOST += -n -- cgit v1.2.3 From 2beee868997485a5718a349c7868260d5ee7378f Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Mon, 1 Jun 2020 14:57:04 +0900 Subject: modpost: load KBUILD_EXTRA_SYMBOLS files in order Currently, modpost reads extra symbol dump files in the reverse order. If '-e foo -e bar' is given, modpost reads bar, foo, in this order. This is probably not a big deal, but there is no good reason to reverse the order. Read files in the given order. Signed-off-by: Masahiro Yamada --- scripts/mod/modpost.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) (limited to 'scripts') diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c index 160139508821..5224a02edbf2 100644 --- a/scripts/mod/modpost.c +++ b/scripts/mod/modpost.c @@ -2555,8 +2555,8 @@ int main(int argc, char **argv) int opt; int err; int n; - struct ext_sym_list *extsym_iter; struct ext_sym_list *extsym_start = NULL; + struct ext_sym_list **extsym_iter = &extsym_start; while ((opt = getopt(argc, argv, "i:e:mnsT:o:awENd:")) != -1) { switch (opt) { @@ -2566,11 +2566,9 @@ int main(int argc, char **argv) break; case 'e': external_module = 1; - extsym_iter = - NOFAIL(malloc(sizeof(*extsym_iter))); - extsym_iter->next = extsym_start; - extsym_iter->file = optarg; - extsym_start = extsym_iter; + *extsym_iter = NOFAIL(calloc(1, sizeof(**extsym_iter))); + (*extsym_iter)->file = optarg; + extsym_iter = &(*extsym_iter)->next; break; case 'm': modversions = 1; @@ -2610,10 +2608,12 @@ int main(int argc, char **argv) if (kernel_read) read_dump(kernel_read, 1); while (extsym_start) { + struct ext_sym_list *tmp; + read_dump(extsym_start->file, 0); - extsym_iter = extsym_start->next; + tmp = extsym_start->next; free(extsym_start); - extsym_start = extsym_iter; + extsym_start = tmp; } while (optind < argc) -- cgit v1.2.3 From 52c3416db00d970c91a6992ab6e5ff48e077ad29 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Mon, 1 Jun 2020 14:57:05 +0900 Subject: modpost: track if the symbol origin is a dump file or ELF object The meaning of sym->kernel is obscure; it is set for in-kernel symbols loaded from Modules.symvers. This happens only when we are building external modules, and it is used to determine whether to dump symbols to $(KBUILD_EXTMOD)/Modules.symvers It is clearer to remember whether the symbol or module came from a dump file or ELF object. This changes the KBUILD_EXTRA_SYMBOLS behavior. Previously, symbols loaded from KBUILD_EXTRA_SYMBOLS are accumulated into the current $(KBUILD_EXTMOD)/Modules.symvers Going forward, they will be only used to check symbol references, but not dumped into the current $(KBUILD_EXTMOD)/Modules.symvers. I believe this makes more sense. sym->vmlinux will have no user. Remove it too. Signed-off-by: Masahiro Yamada --- scripts/mod/modpost.c | 15 +++++---------- scripts/mod/modpost.h | 1 + 2 files changed, 6 insertions(+), 10 deletions(-) (limited to 'scripts') diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c index 5224a02edbf2..60f35b89cea2 100644 --- a/scripts/mod/modpost.c +++ b/scripts/mod/modpost.c @@ -161,9 +161,6 @@ struct symbol { int crc_valid; char *namespace; unsigned int weak:1; - unsigned int vmlinux:1; /* 1 if symbol is defined in vmlinux */ - unsigned int kernel:1; /* 1 if symbol is from kernel - * (only for external modules) **/ unsigned int is_static:1; /* 1 if symbol is not global */ enum export export; /* Type of export */ char name[]; @@ -398,8 +395,6 @@ static struct symbol *sym_add_exported(const char *name, struct module *mod, } s->module = mod; - s->vmlinux = is_vmlinux(mod->name); - s->kernel = 0; s->export = export; return s; } @@ -2427,7 +2422,7 @@ static void write_if_changed(struct buffer *b, const char *fname) /* parse Module.symvers file. line format: * 0x12345678symbolmoduleexportnamespace **/ -static void read_dump(const char *fname, unsigned int kernel) +static void read_dump(const char *fname) { unsigned long size, pos = 0; void *file = grab_file(fname, &size); @@ -2465,9 +2460,9 @@ static void read_dump(const char *fname, unsigned int kernel) have_vmlinux = 1; mod = new_module(modname); mod->skip = 1; + mod->from_dump = 1; } s = sym_add_exported(symname, mod, export_no(export)); - s->kernel = kernel; s->is_static = 0; sym_set_crc(symname, crc); sym_update_namespace(symname, namespace); @@ -2487,7 +2482,7 @@ static int dump_sym(struct symbol *sym) { if (!external_module) return 1; - if (sym->vmlinux || sym->kernel) + if (sym->module->from_dump) return 0; return 1; } @@ -2606,11 +2601,11 @@ int main(int argc, char **argv) } if (kernel_read) - read_dump(kernel_read, 1); + read_dump(kernel_read); while (extsym_start) { struct ext_sym_list *tmp; - read_dump(extsym_start->file, 0); + read_dump(extsym_start->file); tmp = extsym_start->next; free(extsym_start); extsym_start = tmp; diff --git a/scripts/mod/modpost.h b/scripts/mod/modpost.h index 39f6c29fb568..933a88c733bc 100644 --- a/scripts/mod/modpost.h +++ b/scripts/mod/modpost.h @@ -119,6 +119,7 @@ struct module { const char *name; int gpl_compatible; struct symbol *unres; + int from_dump; /* 1 if module was loaded from *.symvers */ int seen; int skip; int has_init; -- cgit v1.2.3 From ce2ddd6d6ab3b343837d5c8e17538a5f67fa400e Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Mon, 1 Jun 2020 14:57:06 +0900 Subject: modpost: allow to pass -i option multiple times to remove -e option Now that there is no difference between -i and -e, they can be unified. Make modpost accept the -i option multiple times, then remove -e. I will reuse -e for a different purpose. Signed-off-by: Masahiro Yamada --- scripts/Makefile.modpost | 2 +- scripts/mod/modpost.c | 9 +-------- 2 files changed, 2 insertions(+), 9 deletions(-) (limited to 'scripts') diff --git a/scripts/Makefile.modpost b/scripts/Makefile.modpost index 3334f100a490..7e07adab929c 100644 --- a/scripts/Makefile.modpost +++ b/scripts/Makefile.modpost @@ -50,7 +50,7 @@ MODPOST = scripts/mod/modpost \ $(if $(CONFIG_MODVERSIONS),-m) \ $(if $(CONFIG_MODULE_SRCVERSION_ALL),-a) \ $(if $(KBUILD_EXTMOD),-i,-o) $(kernelsymfile) \ - $(if $(KBUILD_EXTMOD),$(addprefix -e ,$(KBUILD_EXTRA_SYMBOLS))) \ + $(if $(KBUILD_EXTMOD),$(addprefix -i ,$(KBUILD_EXTRA_SYMBOLS))) \ $(if $(KBUILD_EXTMOD),-o $(modulesymfile)) \ $(if $(CONFIG_SECTION_MISMATCH_WARN_ONLY),,-E) \ $(if $(KBUILD_MODPOST_WARN),-w) diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c index 60f35b89cea2..28d8f5377c62 100644 --- a/scripts/mod/modpost.c +++ b/scripts/mod/modpost.c @@ -2544,7 +2544,6 @@ int main(int argc, char **argv) { struct module *mod; struct buffer buf = { }; - char *kernel_read = NULL; char *missing_namespace_deps = NULL; char *dump_write = NULL, *files_source = NULL; int opt; @@ -2553,13 +2552,9 @@ int main(int argc, char **argv) struct ext_sym_list *extsym_start = NULL; struct ext_sym_list **extsym_iter = &extsym_start; - while ((opt = getopt(argc, argv, "i:e:mnsT:o:awENd:")) != -1) { + while ((opt = getopt(argc, argv, "i:mnsT:o:awENd:")) != -1) { switch (opt) { case 'i': - kernel_read = optarg; - external_module = 1; - break; - case 'e': external_module = 1; *extsym_iter = NOFAIL(calloc(1, sizeof(**extsym_iter))); (*extsym_iter)->file = optarg; @@ -2600,8 +2595,6 @@ int main(int argc, char **argv) } } - if (kernel_read) - read_dump(kernel_read); while (extsym_start) { struct ext_sym_list *tmp; -- cgit v1.2.3 From 7924799ed2ddaa393c2ef0c4cd13a81d122bffde Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Mon, 1 Jun 2020 14:57:07 +0900 Subject: modpost: rename ext_sym_list to dump_list The -i option is used to include Modules.symver as well as files from $(KBUILD_EXTRA_SYMBOLS). Make the struct and variable names more generic. Signed-off-by: Masahiro Yamada --- scripts/mod/modpost.c | 27 ++++++++++++++------------- 1 file changed, 14 insertions(+), 13 deletions(-) (limited to 'scripts') diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c index 28d8f5377c62..b8e521f50b2d 100644 --- a/scripts/mod/modpost.c +++ b/scripts/mod/modpost.c @@ -2535,8 +2535,8 @@ static void write_namespace_deps_files(const char *fname) free(ns_deps_buf.p); } -struct ext_sym_list { - struct ext_sym_list *next; +struct dump_list { + struct dump_list *next; const char *file; }; @@ -2549,16 +2549,17 @@ int main(int argc, char **argv) int opt; int err; int n; - struct ext_sym_list *extsym_start = NULL; - struct ext_sym_list **extsym_iter = &extsym_start; + struct dump_list *dump_read_start = NULL; + struct dump_list **dump_read_iter = &dump_read_start; while ((opt = getopt(argc, argv, "i:mnsT:o:awENd:")) != -1) { switch (opt) { case 'i': external_module = 1; - *extsym_iter = NOFAIL(calloc(1, sizeof(**extsym_iter))); - (*extsym_iter)->file = optarg; - extsym_iter = &(*extsym_iter)->next; + *dump_read_iter = + NOFAIL(calloc(1, sizeof(**dump_read_iter))); + (*dump_read_iter)->file = optarg; + dump_read_iter = &(*dump_read_iter)->next; break; case 'm': modversions = 1; @@ -2595,13 +2596,13 @@ int main(int argc, char **argv) } } - while (extsym_start) { - struct ext_sym_list *tmp; + while (dump_read_start) { + struct dump_list *tmp; - read_dump(extsym_start->file); - tmp = extsym_start->next; - free(extsym_start); - extsym_start = tmp; + read_dump(dump_read_start->file); + tmp = dump_read_start->next; + free(dump_read_start); + dump_read_start = tmp; } while (optind < argc) -- cgit v1.2.3 From e3fb4df7fe4e8636de32a1e4ff5ebc75257f5570 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Mon, 1 Jun 2020 14:57:08 +0900 Subject: modpost: re-add -e to set external_module flag Previously, the -i option had two functions; load a symbol dump file, and set the external_module flag. I want to assign a dedicate option for each of them. Going forward, the -i is used to load a symbol dump file, and the -e to set the external_module flag. With this, we will be able to use -i for loading in-kernel symbols. Signed-off-by: Masahiro Yamada --- scripts/Makefile.modpost | 4 ++++ scripts/mod/modpost.c | 6 ++++-- 2 files changed, 8 insertions(+), 2 deletions(-) (limited to 'scripts') diff --git a/scripts/Makefile.modpost b/scripts/Makefile.modpost index 7e07adab929c..4d79afe997ad 100644 --- a/scripts/Makefile.modpost +++ b/scripts/Makefile.modpost @@ -79,6 +79,10 @@ src := $(obj) # Include the module's Makefile to find KBUILD_EXTRA_SYMBOLS include $(if $(wildcard $(KBUILD_EXTMOD)/Kbuild), \ $(KBUILD_EXTMOD)/Kbuild, $(KBUILD_EXTMOD)/Makefile) + +# modpost option for external modules +MODPOST += -e + endif # modpost options for modules (both in-kernel and external) diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c index b8e521f50b2d..4a2f27d97bf1 100644 --- a/scripts/mod/modpost.c +++ b/scripts/mod/modpost.c @@ -2552,10 +2552,12 @@ int main(int argc, char **argv) struct dump_list *dump_read_start = NULL; struct dump_list **dump_read_iter = &dump_read_start; - while ((opt = getopt(argc, argv, "i:mnsT:o:awENd:")) != -1) { + while ((opt = getopt(argc, argv, "ei:mnsT:o:awENd:")) != -1) { switch (opt) { - case 'i': + case 'e': external_module = 1; + break; + case 'i': *dump_read_iter = NOFAIL(calloc(1, sizeof(**dump_read_iter))); (*dump_read_iter)->file = optarg; -- cgit v1.2.3 From bcfedae7d92886597e581ec32dfbf698cbccb4a1 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Mon, 1 Jun 2020 14:57:09 +0900 Subject: modpost: print symbol dump file as the build target in short log The symbol dump *.symvers is the output of modpost. Print it in the short log. Signed-off-by: Masahiro Yamada --- scripts/Makefile.modpost | 33 ++++++++++++++++++++------------- 1 file changed, 20 insertions(+), 13 deletions(-) (limited to 'scripts') diff --git a/scripts/Makefile.modpost b/scripts/Makefile.modpost index 4d79afe997ad..e766e134b0f3 100644 --- a/scripts/Makefile.modpost +++ b/scripts/Makefile.modpost @@ -44,25 +44,26 @@ include include/config/auto.conf include scripts/Kbuild.include kernelsymfile := $(objtree)/Module.symvers -modulesymfile := $(KBUILD_EXTMOD)/Module.symvers MODPOST = scripts/mod/modpost \ $(if $(CONFIG_MODVERSIONS),-m) \ $(if $(CONFIG_MODULE_SRCVERSION_ALL),-a) \ - $(if $(KBUILD_EXTMOD),-i,-o) $(kernelsymfile) \ + $(if $(KBUILD_EXTMOD),-i $(kernelsymfile)) \ $(if $(KBUILD_EXTMOD),$(addprefix -i ,$(KBUILD_EXTRA_SYMBOLS))) \ - $(if $(KBUILD_EXTMOD),-o $(modulesymfile)) \ $(if $(CONFIG_SECTION_MISMATCH_WARN_ONLY),,-E) \ - $(if $(KBUILD_MODPOST_WARN),-w) + $(if $(KBUILD_MODPOST_WARN),-w) \ + -o $@ ifdef MODPOST_VMLINUX -quiet_cmd_modpost = MODPOST vmlinux.o - cmd_modpost = $(MODPOST) vmlinux.o +quiet_cmd_modpost = MODPOST $@ + cmd_modpost = $(MODPOST) $< -__modpost: +Module.symvers: vmlinux.o $(call cmd,modpost) +__modpost: Module.symvers + else MODPOST += -s \ @@ -70,6 +71,8 @@ MODPOST += -s \ ifeq ($(KBUILD_EXTMOD),) MODPOST += $(wildcard vmlinux) +output-symdump := Module.symvers + else # set src + obj - they may be used in the modules's Makefile @@ -83,6 +86,8 @@ include $(if $(wildcard $(KBUILD_EXTMOD)/Kbuild), \ # modpost option for external modules MODPOST += -e +output-symdump := $(KBUILD_EXTMOD)/Module.symvers + endif # modpost options for modules (both in-kernel and external) @@ -94,20 +99,22 @@ ifneq ($(findstring i,$(filter-out --%,$(MAKEFLAGS))),) MODPOST += -n endif -# find all modules listed in modules.order -modules := $(sort $(shell cat $(MODORDER))) - -# Read out modules.order instead of expanding $(modules) to pass in modpost. +# Read out modules.order to pass in modpost. # Otherwise, allmodconfig would fail with "Argument list too long". -quiet_cmd_modpost = MODPOST $(words $(modules)) modules +quiet_cmd_modpost = MODPOST $@ cmd_modpost = sed 's/ko$$/o/' $(MODORDER) | $(MODPOST) -T - -__modpost: +$(output-symdump): FORCE $(call cmd,modpost) + +__modpost: $(output-symdump) ifneq ($(KBUILD_MODPOST_NOFINAL),1) $(Q)$(MAKE) -f $(srctree)/scripts/Makefile.modfinal endif +PHONY += FORCE +FORCE: + endif .PHONY: $(PHONY) -- cgit v1.2.3 From f1005b30ade716eb9286613aeb1d33b5c7852a91 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Mon, 1 Jun 2020 14:57:10 +0900 Subject: modpost: refactor -i option calculation Prepare to use -i for in-tree modpost as well. Signed-off-by: Masahiro Yamada --- scripts/Makefile.modpost | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) (limited to 'scripts') diff --git a/scripts/Makefile.modpost b/scripts/Makefile.modpost index e766e134b0f3..79e850c8ce01 100644 --- a/scripts/Makefile.modpost +++ b/scripts/Makefile.modpost @@ -43,13 +43,9 @@ __modpost: include include/config/auto.conf include scripts/Kbuild.include -kernelsymfile := $(objtree)/Module.symvers - MODPOST = scripts/mod/modpost \ $(if $(CONFIG_MODVERSIONS),-m) \ $(if $(CONFIG_MODULE_SRCVERSION_ALL),-a) \ - $(if $(KBUILD_EXTMOD),-i $(kernelsymfile)) \ - $(if $(KBUILD_EXTMOD),$(addprefix -i ,$(KBUILD_EXTRA_SYMBOLS))) \ $(if $(CONFIG_SECTION_MISMATCH_WARN_ONLY),,-E) \ $(if $(KBUILD_MODPOST_WARN),-w) \ -o $@ @@ -86,12 +82,14 @@ include $(if $(wildcard $(KBUILD_EXTMOD)/Kbuild), \ # modpost option for external modules MODPOST += -e +input-symdump := Module.symvers $(KBUILD_EXTRA_SYMBOLS) output-symdump := $(KBUILD_EXTMOD)/Module.symvers endif # modpost options for modules (both in-kernel and external) MODPOST += \ + $(addprefix -i ,$(input-symdump)) \ $(if $(CONFIG_MODULE_ALLOW_MISSING_NAMESPACE_IMPORTS)$(KBUILD_NSDEPS),-N) # 'make -i -k' ignores compile errors, and builds as many modules as possible. -- cgit v1.2.3 From 269a535ca931b754a40dda3ab60514e68773c759 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Mon, 1 Jun 2020 14:57:11 +0900 Subject: modpost: generate vmlinux.symvers and reuse it for the second modpost The full build runs modpost twice, first for vmlinux.o and second for modules. The first pass dumps all the vmlinux symbols into Module.symvers, but the second pass parses vmlinux again instead of reusing the dump file, presumably because it needs to avoid accumulating stale symbols. Loading symbol info from a dump file is faster than parsing an ELF object. Besides, modpost deals with various issues to parse vmlinux in the second pass. A solution is to make the first pass dumps symbols into a separate file, vmlinux.symvers. The second pass reads it, and parses module .o files. The merged symbol information is dumped into Module.symvers in the same way as before. This makes further modpost cleanups possible. Also, it fixes the problem of 'make vmlinux', which previously overwrote Module.symvers, throwing away module symbols. I slightly touched scripts/link-vmlinux.sh so that vmlinux is re-linked when you cross this commit. Otherwise, vmlinux.symvers would not be generated. Signed-off-by: Masahiro Yamada --- .gitignore | 1 + Documentation/dontdiff | 1 + Makefile | 2 +- scripts/Makefile.modpost | 7 ++++--- scripts/link-vmlinux.sh | 2 -- 5 files changed, 7 insertions(+), 6 deletions(-) (limited to 'scripts') diff --git a/.gitignore b/.gitignore index 2258e906f01c..87b9dd8a163b 100644 --- a/.gitignore +++ b/.gitignore @@ -56,6 +56,7 @@ modules.order /linux /vmlinux /vmlinux.32 +/vmlinux.symvers /vmlinux-gdb.py /vmlinuz /System.map diff --git a/Documentation/dontdiff b/Documentation/dontdiff index 72fc2e9e2b63..ef9519c32c55 100644 --- a/Documentation/dontdiff +++ b/Documentation/dontdiff @@ -251,6 +251,7 @@ vmlinux-* vmlinux.aout vmlinux.bin.all vmlinux.lds +vmlinux.symvers vmlinuz voffset.h vsyscall.lds diff --git a/Makefile b/Makefile index b0bbf8453b66..9768140f8d5a 100644 --- a/Makefile +++ b/Makefile @@ -1416,7 +1416,7 @@ endif # CONFIG_MODULES # make distclean Remove editor backup files, patch leftover files and the like # Directories & files removed with 'make clean' -CLEAN_FILES += include/ksym \ +CLEAN_FILES += include/ksym vmlinux.symvers \ modules.builtin modules.builtin.modinfo modules.nsdeps # Directories & files removed with 'make mrproper' diff --git a/scripts/Makefile.modpost b/scripts/Makefile.modpost index 79e850c8ce01..896c799911c5 100644 --- a/scripts/Makefile.modpost +++ b/scripts/Makefile.modpost @@ -55,10 +55,10 @@ ifdef MODPOST_VMLINUX quiet_cmd_modpost = MODPOST $@ cmd_modpost = $(MODPOST) $< -Module.symvers: vmlinux.o +vmlinux.symvers: vmlinux.o $(call cmd,modpost) -__modpost: Module.symvers +__modpost: vmlinux.symvers else @@ -66,7 +66,8 @@ MODPOST += -s \ $(if $(KBUILD_NSDEPS),-d $(MODULES_NSDEPS)) ifeq ($(KBUILD_EXTMOD),) -MODPOST += $(wildcard vmlinux) + +input-symdump := vmlinux.symvers output-symdump := Module.symvers else diff --git a/scripts/link-vmlinux.sh b/scripts/link-vmlinux.sh index d09ab4afbda4..d5af6be50b50 100755 --- a/scripts/link-vmlinux.sh +++ b/scripts/link-vmlinux.sh @@ -218,8 +218,6 @@ on_signals() } trap on_signals HUP INT QUIT TERM -# -# # Use "make V=1" to debug this script case "${KBUILD_VERBOSE}" in *1*) -- cgit v1.2.3 From 436b2ac603d58504f38041a0cd8adb5aeace992b Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Mon, 1 Jun 2020 14:57:12 +0900 Subject: modpost: invoke modpost only when input files are updated Currently, the second pass of modpost is always invoked when you run 'make' or 'make modules' even if none of modules is changed. Use if_changed to invoke it only when it is necessary. Signed-off-by: Masahiro Yamada --- scripts/Makefile.modpost | 20 ++++++++++++++++---- scripts/mod/modpost.c | 32 +++++++++++++++++++++----------- 2 files changed, 37 insertions(+), 15 deletions(-) (limited to 'scripts') diff --git a/scripts/Makefile.modpost b/scripts/Makefile.modpost index 896c799911c5..f29a02196b72 100644 --- a/scripts/Makefile.modpost +++ b/scripts/Makefile.modpost @@ -90,7 +90,7 @@ endif # modpost options for modules (both in-kernel and external) MODPOST += \ - $(addprefix -i ,$(input-symdump)) \ + $(addprefix -i ,$(wildcard $(input-symdump))) \ $(if $(CONFIG_MODULE_ALLOW_MISSING_NAMESPACE_IMPORTS)$(KBUILD_NSDEPS),-N) # 'make -i -k' ignores compile errors, and builds as many modules as possible. @@ -98,13 +98,18 @@ ifneq ($(findstring i,$(filter-out --%,$(MAKEFLAGS))),) MODPOST += -n endif +$(input-symdump): + @: + # Read out modules.order to pass in modpost. # Otherwise, allmodconfig would fail with "Argument list too long". quiet_cmd_modpost = MODPOST $@ - cmd_modpost = sed 's/ko$$/o/' $(MODORDER) | $(MODPOST) -T - + cmd_modpost = sed 's/ko$$/o/' $< | $(MODPOST) -T - -$(output-symdump): FORCE - $(call cmd,modpost) +$(output-symdump): $(MODORDER) $(input-symdump) FORCE + $(call if_changed,modpost) + +targets += $(output-symdump) __modpost: $(output-symdump) ifneq ($(KBUILD_MODPOST_NOFINAL),1) @@ -114,6 +119,13 @@ endif PHONY += FORCE FORCE: +existing-targets := $(wildcard $(sort $(targets))) + +-include $(foreach f,$(existing-targets),$(dir $(f)).$(notdir $(f)).cmd) + +PHONY += FORCE +FORCE: + endif .PHONY: $(PHONY) diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c index 4a2f27d97bf1..b839c48689df 100644 --- a/scripts/mod/modpost.c +++ b/scripts/mod/modpost.c @@ -2375,6 +2375,25 @@ static void add_srcversion(struct buffer *b, struct module *mod) } } +static void write_buf(struct buffer *b, const char *fname) +{ + FILE *file; + + file = fopen(fname, "w"); + if (!file) { + perror(fname); + exit(1); + } + if (fwrite(b->p, 1, b->pos, file) != b->pos) { + perror(fname); + exit(1); + } + if (fclose(file) != 0) { + perror(fname); + exit(1); + } +} + static void write_if_changed(struct buffer *b, const char *fname) { char *tmp; @@ -2407,16 +2426,7 @@ static void write_if_changed(struct buffer *b, const char *fname) close_write: fclose(file); write: - file = fopen(fname, "w"); - if (!file) { - perror(fname); - exit(1); - } - if (fwrite(b->p, 1, b->pos, file) != b->pos) { - perror(fname); - exit(1); - } - fclose(file); + write_buf(b, fname); } /* parse Module.symvers file. line format: @@ -2508,7 +2518,7 @@ static void write_dump(const char *fname) symbol = symbol->next; } } - write_if_changed(&buf, fname); + write_buf(&buf, fname); free(buf.p); } -- cgit v1.2.3 From 7e8a3235823bcb779acf92de630edd5ddffaf886 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Mon, 1 Jun 2020 14:57:13 +0900 Subject: modpost: show warning if vmlinux is not found when processing modules check_exports() does not print warnings about unresolved symbols if vmlinux is missing because there would be too many. This situation happens when you do 'make modules' from the clean tree, or compile external modules against a kernel tree that has not been completely built. It is dangerous to not check unresolved symbols because you might be building useless modules. At least it should be warned. Signed-off-by: Masahiro Yamada --- scripts/mod/modpost.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) (limited to 'scripts') diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c index b839c48689df..3df26789c2e6 100644 --- a/scripts/mod/modpost.c +++ b/scripts/mod/modpost.c @@ -2001,8 +2001,6 @@ static void read_symbols(const char *modname) mod = new_module(modname); - /* When there's no vmlinux, don't print warnings about - * unresolved symbols (since there'll be too many ;) */ if (is_vmlinux(modname)) { have_vmlinux = 1; mod->skip = 1; @@ -2623,6 +2621,13 @@ 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"); + err = 0; for (mod = modules; mod; mod = mod->next) { -- cgit v1.2.3 From 48a0f72797bdc6b428f951aff265f5aecc2bda49 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Mon, 1 Jun 2020 14:57:14 +0900 Subject: modpost: show warning if any of symbol dump files is missing If modpost fails to load a symbol dump file, it cannot check unresolved symbols, hence module dependency will not be added. Nor CRCs can be added. Currently, external module builds check only $(objtree)/Module.symvers, but it should check files specified by KBUILD_EXTRA_SYMBOLS as well. Move the warning message from the top Makefile to scripts/Makefile.modpost and print the warning if any dump file is missing. Signed-off-by: Masahiro Yamada --- Makefile | 10 +--------- scripts/Makefile.modpost | 5 ++++- 2 files changed, 5 insertions(+), 10 deletions(-) (limited to 'scripts') diff --git a/Makefile b/Makefile index 9768140f8d5a..ee3ed9dfca2c 100644 --- a/Makefile +++ b/Makefile @@ -1649,17 +1649,9 @@ else # KBUILD_EXTMOD # We are always building modules KBUILD_MODULES := 1 -PHONY += $(objtree)/Module.symvers -$(objtree)/Module.symvers: - @test -e $(objtree)/Module.symvers || ( \ - echo; \ - echo " WARNING: Symbol version dump $(objtree)/Module.symvers"; \ - echo " is missing; modules will have no dependencies and modversions."; \ - echo ) - build-dirs := $(KBUILD_EXTMOD) PHONY += modules -modules: descend $(objtree)/Module.symvers +modules: descend $(Q)$(MAKE) -f $(srctree)/scripts/Makefile.modpost PHONY += modules_install diff --git a/scripts/Makefile.modpost b/scripts/Makefile.modpost index f29a02196b72..e47f87557f09 100644 --- a/scripts/Makefile.modpost +++ b/scripts/Makefile.modpost @@ -98,8 +98,11 @@ ifneq ($(findstring i,$(filter-out --%,$(MAKEFLAGS))),) MODPOST += -n endif +# Clear VPATH to not search for *.symvers in $(srctree). Check only $(objtree). +VPATH := $(input-symdump): - @: + @echo >&2 'WARNING: Symbol version dump "$@" is missing.' + @echo >&2 ' Modules may not have dependencies or modversions.' # Read out modules.order to pass in modpost. # Otherwise, allmodconfig would fail with "Argument list too long". -- cgit v1.2.3 From f693153519607449d3e270d9e6af20b032543c05 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Mon, 1 Jun 2020 14:57:15 +0900 Subject: modpost: drop RCS/CVS $Revision handling in MODULE_VERSION() As far as I understood, this code gets rid of '$Revision$' or '$Revision:' of CVS, RCS or whatever in MODULE_VERSION() tags. Remove the primeval code. Signed-off-by: Masahiro Yamada --- scripts/mod/modpost.c | 3 --- scripts/mod/modpost.h | 4 --- scripts/mod/sumversion.c | 66 ------------------------------------------------ 3 files changed, 73 deletions(-) (limited to 'scripts') diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c index 3df26789c2e6..fbb3d3391e52 100644 --- a/scripts/mod/modpost.c +++ b/scripts/mod/modpost.c @@ -2066,9 +2066,6 @@ static void read_symbols(const char *modname) check_sec_ref(mod, modname, &info); version = get_modinfo(&info, "version"); - if (version) - maybe_frob_rcs_version(modname, version, info.modinfo, - version - (char *)info.hdr); if (version || (all_versions && !is_vmlinux(modname))) get_src_version(modname, mod->srcversion, sizeof(mod->srcversion)-1); diff --git a/scripts/mod/modpost.h b/scripts/mod/modpost.h index 933a88c733bc..e5eace03a2b3 100644 --- a/scripts/mod/modpost.h +++ b/scripts/mod/modpost.h @@ -188,10 +188,6 @@ void handle_moddevtable(struct module *mod, struct elf_info *info, void add_moddevtable(struct buffer *buf, struct module *mod); /* sumversion.c */ -void maybe_frob_rcs_version(const char *modfilename, - char *version, - void *modinfo, - unsigned long modinfo_offset); void get_src_version(const char *modname, char sum[], unsigned sumlen); /* from modpost.c */ diff --git a/scripts/mod/sumversion.c b/scripts/mod/sumversion.c index 63062024ce0e..f27f22420cbc 100644 --- a/scripts/mod/sumversion.c +++ b/scripts/mod/sumversion.c @@ -429,69 +429,3 @@ void get_src_version(const char *modname, char sum[], unsigned sumlen) release: release_file(file, len); } - -static void write_version(const char *filename, const char *sum, - unsigned long offset) -{ - int fd; - - fd = open(filename, O_RDWR); - if (fd < 0) { - warn("changing sum in %s failed: %s\n", - filename, strerror(errno)); - return; - } - - if (lseek(fd, offset, SEEK_SET) == (off_t)-1) { - warn("changing sum in %s:%lu failed: %s\n", - filename, offset, strerror(errno)); - goto out; - } - - if (write(fd, sum, strlen(sum)+1) != strlen(sum)+1) { - warn("writing sum in %s failed: %s\n", - filename, strerror(errno)); - goto out; - } -out: - close(fd); -} - -static int strip_rcs_crap(char *version) -{ - unsigned int len, full_len; - - if (strncmp(version, "$Revision", strlen("$Revision")) != 0) - return 0; - - /* Space for version string follows. */ - full_len = strlen(version) + strlen(version + strlen(version) + 1) + 2; - - /* Move string to start with version number: prefix will be - * $Revision$ or $Revision: */ - len = strlen("$Revision"); - if (version[len] == ':' || version[len] == '$') - len++; - while (isspace(version[len])) - len++; - memmove(version, version+len, full_len-len); - full_len -= len; - - /* Preserve up to next whitespace. */ - len = 0; - while (version[len] && !isspace(version[len])) - len++; - memmove(version + len, version + strlen(version), - full_len - strlen(version)); - return 1; -} - -/* Clean up RCS-style version numbers. */ -void maybe_frob_rcs_version(const char *modfilename, - char *version, - void *modinfo, - unsigned long version_offset) -{ - if (strip_rcs_crap(version)) - write_version(modfilename, version, version_offset); -} -- cgit v1.2.3 From 4ddea2f8e825a86e94011ebc32eb1dce220b2316 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Mon, 1 Jun 2020 14:57:16 +0900 Subject: modpost: do not call get_modinfo() for vmlinux(.o) The three calls of get_modinfo() ("license", "import_ns", "version") always return NULL for vmlinux(.o) because the built-in module info is prefixed with __MODULE_INFO_PREFIX. It is harmless to call get_modinfo(), but there is no point to search for what apparently does not exist. Signed-off-by: Masahiro Yamada --- scripts/mod/modpost.c | 45 ++++++++++++++++++++++++--------------------- 1 file changed, 24 insertions(+), 21 deletions(-) (limited to 'scripts') diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c index fbb3d3391e52..a5da633af700 100644 --- a/scripts/mod/modpost.c +++ b/scripts/mod/modpost.c @@ -2006,25 +2006,26 @@ static void read_symbols(const char *modname) mod->skip = 1; } - license = get_modinfo(&info, "license"); - if (!license && !is_vmlinux(modname)) - warn("missing MODULE_LICENSE() in %s\n" - "see include/linux/module.h for " - "more information\n", modname); - while (license) { - if (license_is_gpl_compatible(license)) - mod->gpl_compatible = 1; - else { - mod->gpl_compatible = 0; - break; + if (!is_vmlinux(modname)) { + license = get_modinfo(&info, "license"); + if (!license) + warn("missing MODULE_LICENSE() in %s\n", modname); + while (license) { + if (license_is_gpl_compatible(license)) + mod->gpl_compatible = 1; + else { + mod->gpl_compatible = 0; + break; + } + license = get_next_modinfo(&info, "license", license); } - license = get_next_modinfo(&info, "license", license); - } - namespace = get_modinfo(&info, "import_ns"); - while (namespace) { - add_namespace(&mod->imported_namespaces, namespace); - namespace = get_next_modinfo(&info, "import_ns", namespace); + namespace = get_modinfo(&info, "import_ns"); + while (namespace) { + add_namespace(&mod->imported_namespaces, namespace); + namespace = get_next_modinfo(&info, "import_ns", + namespace); + } } for (sym = info.symtab_start; sym < info.symtab_stop; sym++) { @@ -2065,10 +2066,12 @@ static void read_symbols(const char *modname) if (!is_vmlinux(modname) || vmlinux_section_warnings) check_sec_ref(mod, modname, &info); - version = get_modinfo(&info, "version"); - if (version || (all_versions && !is_vmlinux(modname))) - get_src_version(modname, mod->srcversion, - sizeof(mod->srcversion)-1); + if (!is_vmlinux(modname)) { + version = get_modinfo(&info, "version"); + if (version || all_versions) + get_src_version(modname, mod->srcversion, + sizeof(mod->srcversion) - 1); + } parse_elf_finish(&info); -- cgit v1.2.3 From ac5100f54329676469688d1b5415cd8d6428c909 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Mon, 1 Jun 2020 14:57:17 +0900 Subject: modpost: add read_text_file() and get_line() helpers modpost uses grab_file() to open a file, but it is not suitable for a text file because the mmap'ed file is not terminated by null byte. Actually, I see some issues for the use of grab_file(). The new helper, read_text_file() loads the whole file content into a malloc'ed buffer, and appends a null byte. Then, get_line() reads each line. To handle text files, I intend to replace as follows: grab_file() -> read_text_file() get_new_line() -> get_line() Signed-off-by: Masahiro Yamada --- scripts/mod/modpost.c | 49 +++++++++++++++++++++++++++++++++++++++++++++++++ scripts/mod/modpost.h | 2 ++ 2 files changed, 51 insertions(+) (limited to 'scripts') diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c index a5da633af700..0a844902998e 100644 --- a/scripts/mod/modpost.c +++ b/scripts/mod/modpost.c @@ -112,6 +112,55 @@ void *do_nofail(void *ptr, const char *expr) return ptr; } +char *read_text_file(const char *filename) +{ + struct stat st; + size_t nbytes; + int fd; + char *buf; + + fd = open(filename, O_RDONLY); + if (fd < 0) { + perror(filename); + exit(1); + } + + if (fstat(fd, &st) < 0) { + perror(filename); + exit(1); + } + + buf = NOFAIL(malloc(st.st_size + 1)); + + nbytes = st.st_size; + + while (nbytes) { + ssize_t bytes_read; + + bytes_read = read(fd, buf, nbytes); + if (bytes_read < 0) { + perror(filename); + exit(1); + } + + nbytes -= bytes_read; + } + buf[st.st_size] = '\0'; + + close(fd); + + return buf; +} + +char *get_line(char **stringp) +{ + /* do not return the unwanted extra line at EOF */ + if (*stringp && **stringp == '\0') + return NULL; + + return strsep(stringp, "\n"); +} + /* A list of all modules we processed */ static struct module *modules; diff --git a/scripts/mod/modpost.h b/scripts/mod/modpost.h index e5eace03a2b3..f4412febcd13 100644 --- a/scripts/mod/modpost.h +++ b/scripts/mod/modpost.h @@ -191,6 +191,8 @@ void add_moddevtable(struct buffer *buf, struct module *mod); void get_src_version(const char *modname, char sum[], unsigned sumlen); /* from modpost.c */ +char *read_text_file(const char *filename); +char *get_line(char **stringp); void *grab_file(const char *filename, unsigned long *size); char* get_next_line(unsigned long *pos, void *file, unsigned long size); void release_file(void *file, unsigned long size); -- cgit v1.2.3 From f531c1b5de65bc687bdcca69e7649fe2db5b6d87 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Mon, 1 Jun 2020 14:57:18 +0900 Subject: modpost: fix potential mmap'ed file overrun in get_src_version() I do not know how reliably this function works, but it looks dangerous to me. strchr(sources, '\n'); ... continues searching until it finds '\n' or it reaches the '\0' terminator. In other words, 'sources' should be a null-terminated string. However, grab_file() just mmaps a file, so 'sources' is not terminated with null byte. If the file does not contain '\n' at all, strchr() will go beyond the mmap'ed memory. Use read_text_file(), which loads the file content into a malloc'ed buffer, appending null byte. Here we are interested only in the first line of *.mod files. Use get_line() helper to get the first line. This also makes missing *.mod file a fatal error. Commit 4be40e22233c ("kbuild: do not emit src version warning for non-modules") ignored missing *.mod files. I do not fully understand what that commit addressed, but commit 91341d4b2c19 ("kbuild: introduce new option to enhance section mismatch analysis") introduced partial section checks by using modpost. built-in.o was parsed by modpost. Even modules had a problem because *.mod files were created after the modpost check. Commit b7dca6dd1e59 ("kbuild: create *.mod with full directory path and remove MODVERDIR") stopped doing that. Now that modpost is only invoked after the directory descend, *.mod files should always exist at the modpost stage. Signed-off-by: Masahiro Yamada --- scripts/mod/sumversion.c | 28 +++++++++++----------------- 1 file changed, 11 insertions(+), 17 deletions(-) (limited to 'scripts') diff --git a/scripts/mod/sumversion.c b/scripts/mod/sumversion.c index f27f22420cbc..5fb142db6195 100644 --- a/scripts/mod/sumversion.c +++ b/scripts/mod/sumversion.c @@ -392,40 +392,34 @@ out: /* Calc and record src checksum. */ void get_src_version(const char *modname, char sum[], unsigned sumlen) { - void *file; - unsigned long len; + char *buf, *pos, *firstline; struct md4_ctx md; - char *sources, *end, *fname; + char *fname; char filelist[PATH_MAX + 1]; /* objects for a module are listed in the first line of *.mod file. */ snprintf(filelist, sizeof(filelist), "%.*smod", (int)strlen(modname) - 1, modname); - file = grab_file(filelist, &len); - if (!file) - /* not a module or .mod file missing - ignore */ - return; + buf = read_text_file(filelist); - sources = file; - - end = strchr(sources, '\n'); - if (!end) { + pos = buf; + firstline = get_line(&pos); + if (!firstline) { warn("bad ending versions file for %s\n", modname); - goto release; + goto free; } - *end = '\0'; md4_init(&md); - while ((fname = strsep(&sources, " ")) != NULL) { + while ((fname = strsep(&firstline, " "))) { if (!*fname) continue; if (!(is_static_library(fname)) && !parse_source_files(fname, &md)) - goto release; + goto free; } md4_final_ascii(&md, sum, sumlen); -release: - release_file(file, len); +free: + free(buf); } -- cgit v1.2.3 From 7c8f5662c502b7b967399fef8a64532ec43b063d Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Mon, 1 Jun 2020 14:57:19 +0900 Subject: modpost: avoid false-positive file open error One problem of grab_file() is that it cannot distinguish the following two cases: - It cannot read the file (the file does not exist, or read permission is not set) - It can read the file, but the file size is zero This is because grab_file() calls mmap(), which requires the mapped length is greater than 0. Hence, grab_file() fails for both cases. If an empty header file were included for checksum calculation, the following warning would be printed: WARNING: modpost: could not open ...: Invalid argument An empty file is a valid source file, so it should not fail. Use read_text_file() instead. It can read a zero-length file. Then, parse_file() will succeed with doing nothing. Going forward, the first case (it cannot read the file) is a fatal error. If the source file from which an object was compiled is missing, something went wrong. Signed-off-by: Masahiro Yamada --- scripts/mod/sumversion.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) (limited to 'scripts') diff --git a/scripts/mod/sumversion.c b/scripts/mod/sumversion.c index 5fb142db6195..9f77c9dfce20 100644 --- a/scripts/mod/sumversion.c +++ b/scripts/mod/sumversion.c @@ -258,9 +258,8 @@ static int parse_file(const char *fname, struct md4_ctx *md) char *file; unsigned long i, len; - file = grab_file(fname, &len); - if (!file) - return 0; + file = read_text_file(fname); + len = strlen(file); for (i = 0; i < len; i++) { /* Collapse and ignore \ and CR. */ @@ -287,7 +286,7 @@ static int parse_file(const char *fname, struct md4_ctx *md) add_char(file[i], md); } - release_file(file, len); + free(file); return 1; } /* Check whether the file is a static library or not */ -- cgit v1.2.3 From 70f30cfe5b892fcb7f98e7df72ed6ccfe3225628 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Mon, 1 Jun 2020 14:57:20 +0900 Subject: modpost: use read_text_file() and get_line() for reading text files grab_file() mmaps a file, but it is not so efficient here because get_next_line() copies every line to the temporary buffer anyway. read_text_file() and get_line() are simpler. get_line() exploits the library function strchr(). Going forward, the missing *.symvers or *.cmd is a fatal error. This should not happen because scripts/Makefile.modpost guards the -i option files with $(wildcard $(input-symdump)). Signed-off-by: Masahiro Yamada --- scripts/mod/modpost.c | 15 ++++++++------- scripts/mod/sumversion.c | 16 ++++++---------- 2 files changed, 14 insertions(+), 17 deletions(-) (limited to 'scripts') diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c index 0a844902998e..4fdf992e9729 100644 --- a/scripts/mod/modpost.c +++ b/scripts/mod/modpost.c @@ -2481,15 +2481,16 @@ static void write_if_changed(struct buffer *b, const char *fname) **/ static void read_dump(const char *fname) { - unsigned long size, pos = 0; - void *file = grab_file(fname, &size); - char *line; + char *buf, *pos, *line; - if (!file) + buf = read_text_file(fname); + if (!buf) /* No symbol versions, silently ignore */ return; - while ((line = get_next_line(&pos, file, size))) { + pos = buf; + + while ((line = get_line(&pos))) { char *symname, *namespace, *modname, *d, *export; unsigned int crc; struct module *mod; @@ -2524,10 +2525,10 @@ static void read_dump(const char *fname) sym_set_crc(symname, crc); sym_update_namespace(symname, namespace); } - release_file(file, size); + free(buf); return; fail: - release_file(file, size); + free(buf); fatal("parse error in symbol dump file\n"); } diff --git a/scripts/mod/sumversion.c b/scripts/mod/sumversion.c index 9f77c9dfce20..d587f40f1117 100644 --- a/scripts/mod/sumversion.c +++ b/scripts/mod/sumversion.c @@ -303,9 +303,8 @@ static int is_static_library(const char *objfile) * to figure out source files. */ static int parse_source_files(const char *objfile, struct md4_ctx *md) { - char *cmd, *file, *line, *dir; + char *cmd, *file, *line, *dir, *pos; const char *base; - unsigned long flen, pos = 0; int dirlen, ret = 0, check_files = 0; cmd = NOFAIL(malloc(strlen(objfile) + sizeof("..cmd"))); @@ -323,14 +322,12 @@ static int parse_source_files(const char *objfile, struct md4_ctx *md) strncpy(dir, objfile, dirlen); dir[dirlen] = '\0'; - file = grab_file(cmd, &flen); - if (!file) { - warn("could not find %s for %s\n", cmd, objfile); - goto out; - } + file = read_text_file(cmd); + + pos = file; /* Sum all files in the same dir or subdirs. */ - while ((line = get_next_line(&pos, file, flen)) != NULL) { + while ((line = get_line(&pos))) { char* p = line; if (strncmp(line, "source_", sizeof("source_")-1) == 0) { @@ -381,8 +378,7 @@ static int parse_source_files(const char *objfile, struct md4_ctx *md) /* Everyone parsed OK */ ret = 1; out_file: - release_file(file, flen); -out: + free(file); free(dir); free(cmd); return ret; -- cgit v1.2.3 From 75893572d45399cefbb88443d0878adae9cb0b41 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Mon, 1 Jun 2020 14:57:21 +0900 Subject: modpost: remove get_next_text() and make {grab,release_}file static get_next_line() is no longer used. Remove. grab_file() and release_file() are only used in modpost.c. Make them static. Signed-off-by: Masahiro Yamada --- scripts/mod/modpost.c | 38 ++------------------------------------ scripts/mod/modpost.h | 3 --- 2 files changed, 2 insertions(+), 39 deletions(-) (limited to 'scripts') diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c index 4fdf992e9729..93019349f022 100644 --- a/scripts/mod/modpost.c +++ b/scripts/mod/modpost.c @@ -463,7 +463,7 @@ static void sym_set_crc(const char *name, unsigned int crc) s->crc_valid = 1; } -void *grab_file(const char *filename, unsigned long *size) +static void *grab_file(const char *filename, unsigned long *size) { struct stat st; void *map = MAP_FAILED; @@ -485,41 +485,7 @@ failed: return map; } -/** - * Return a copy of the next line in a mmap'ed file. - * spaces in the beginning of the line is trimmed away. - * Return a pointer to a static buffer. - **/ -char *get_next_line(unsigned long *pos, void *file, unsigned long size) -{ - static char line[4096]; - int skip = 1; - size_t len = 0; - signed char *p = (signed char *)file + *pos; - char *s = line; - - for (; *pos < size ; (*pos)++) { - if (skip && isspace(*p)) { - p++; - continue; - } - skip = 0; - if (*p != '\n' && (*pos < size)) { - len++; - *s++ = *p++; - if (len > 4095) - break; /* Too long, stop */ - } else { - /* End of string */ - *s = '\0'; - return line; - } - } - /* End of buffer */ - return NULL; -} - -void release_file(void *file, unsigned long size) +static void release_file(void *file, unsigned long size) { munmap(file, size); } diff --git a/scripts/mod/modpost.h b/scripts/mod/modpost.h index f4412febcd13..bc524506d2f9 100644 --- a/scripts/mod/modpost.h +++ b/scripts/mod/modpost.h @@ -193,9 +193,6 @@ void get_src_version(const char *modname, char sum[], unsigned sumlen); /* from modpost.c */ char *read_text_file(const char *filename); char *get_line(char **stringp); -void *grab_file(const char *filename, unsigned long *size); -char* get_next_line(unsigned long *pos, void *file, unsigned long size); -void release_file(void *file, unsigned long size); enum loglevel { LOG_WARN, -- cgit v1.2.3 From 467b82d7cee4373aa7bc47fd3043e2fa0a3440f5 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Mon, 1 Jun 2020 14:57:22 +0900 Subject: modpost: remove -s option The -s option was added by commit 8d8d8289df65 ("kbuild: do not do section mismatch checks on vmlinux in 2nd pass"). Now that the second pass does not parse vmlinux, this option is unneeded. Signed-off-by: Masahiro Yamada --- scripts/Makefile.modpost | 2 +- scripts/mod/modpost.c | 10 ++-------- 2 files changed, 3 insertions(+), 9 deletions(-) (limited to 'scripts') diff --git a/scripts/Makefile.modpost b/scripts/Makefile.modpost index e47f87557f09..4938a6f368c0 100644 --- a/scripts/Makefile.modpost +++ b/scripts/Makefile.modpost @@ -62,7 +62,7 @@ __modpost: vmlinux.symvers else -MODPOST += -s \ +MODPOST += \ $(if $(KBUILD_NSDEPS),-d $(MODULES_NSDEPS)) ifeq ($(KBUILD_EXTMOD),) diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c index 93019349f022..b667f531a645 100644 --- a/scripts/mod/modpost.c +++ b/scripts/mod/modpost.c @@ -30,8 +30,6 @@ static int have_vmlinux = 0; static int all_versions = 0; /* If we are modposting external module set to 1 */ static int external_module = 0; -/* Warn about section mismatch in vmlinux if set to 1 */ -static int vmlinux_section_warnings = 1; /* Only warn about unresolved symbols */ static int warn_unresolved = 0; /* How a symbol is exported */ @@ -2078,8 +2076,7 @@ static void read_symbols(const char *modname) } } - if (!is_vmlinux(modname) || vmlinux_section_warnings) - check_sec_ref(mod, modname, &info); + check_sec_ref(mod, modname, &info); if (!is_vmlinux(modname)) { version = get_modinfo(&info, "version"); @@ -2576,7 +2573,7 @@ int main(int argc, char **argv) struct dump_list *dump_read_start = NULL; struct dump_list **dump_read_iter = &dump_read_start; - while ((opt = getopt(argc, argv, "ei:mnsT:o:awENd:")) != -1) { + while ((opt = getopt(argc, argv, "ei:mnT:o:awENd:")) != -1) { switch (opt) { case 'e': external_module = 1; @@ -2599,9 +2596,6 @@ int main(int argc, char **argv) case 'a': all_versions = 1; break; - case 's': - vmlinux_section_warnings = 0; - break; case 'T': files_source = optarg; break; -- cgit v1.2.3 From 859c926aea29353bced3a456c2f73753040b437e Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Mon, 1 Jun 2020 14:57:23 +0900 Subject: modpost: move -d option in scripts/Makefile.modpost Collect options for modules into a single place. Signed-off-by: Masahiro Yamada --- scripts/Makefile.modpost | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'scripts') diff --git a/scripts/Makefile.modpost b/scripts/Makefile.modpost index 4938a6f368c0..3651cbf6ad49 100644 --- a/scripts/Makefile.modpost +++ b/scripts/Makefile.modpost @@ -62,9 +62,6 @@ __modpost: vmlinux.symvers else -MODPOST += \ - $(if $(KBUILD_NSDEPS),-d $(MODULES_NSDEPS)) - ifeq ($(KBUILD_EXTMOD),) input-symdump := vmlinux.symvers @@ -91,6 +88,7 @@ endif # modpost options for modules (both in-kernel and external) MODPOST += \ $(addprefix -i ,$(wildcard $(input-symdump))) \ + $(if $(KBUILD_NSDEPS),-d $(MODULES_NSDEPS)) \ $(if $(CONFIG_MODULE_ALLOW_MISSING_NAMESPACE_IMPORTS)$(KBUILD_NSDEPS),-N) # 'make -i -k' ignores compile errors, and builds as many modules as possible. -- cgit v1.2.3 From 3379576dd6e708f66498d49b4cec5f9b198791a0 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Mon, 1 Jun 2020 14:57:24 +0900 Subject: modpost: remove mod->is_dot_o struct member Previously, there were two cases where mod->is_dot_o is unset: [1] the executable 'vmlinux' in the second pass of modpost [2] modules loaded by read_dump() I think [1] was intended usage to distinguish 'vmlinux.o' and 'vmlinux'. Now that modpost does not parse the executable 'vmlinux', this case does not happen. [2] is obscure, maybe a bug. Module.symver stores module paths without extension. So, none of modules loaded by read_dump() has the .o suffix, and new_module() unsets ->is_dot_o. Anyway, it is not a big deal because handle_symbol() is not called for the case. To sum up, all the parsed ELF files are .o files. mod->is_dot_o is unneeded. Signed-off-by: Masahiro Yamada --- scripts/mod/modpost.c | 14 ++------------ scripts/mod/modpost.h | 1 - 2 files changed, 2 insertions(+), 13 deletions(-) (limited to 'scripts') diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c index b667f531a645..bc00bbac50bb 100644 --- a/scripts/mod/modpost.c +++ b/scripts/mod/modpost.c @@ -182,10 +182,8 @@ static struct module *new_module(const char *modname) p = NOFAIL(strdup(modname)); /* strip trailing .o */ - if (strends(p, ".o")) { + if (strends(p, ".o")) p[strlen(p) - 2] = '\0'; - mod->is_dot_o = 1; - } /* add to list */ mod->name = p; @@ -716,8 +714,7 @@ static void handle_symbol(struct module *mod, struct elf_info *info, enum export export; const char *name; - if ((!is_vmlinux(mod->name) || mod->is_dot_o) && - strstarts(symname, "__ksymtab")) + if (strstarts(symname, "__ksymtab")) export = export_from_secname(info, get_secindex(info, sym)); else export = export_from_sec(info, get_secindex(info, sym)); @@ -2676,13 +2673,6 @@ int main(int argc, char **argv) struct symbol *s; for (s = symbolhash[n]; s; s = s->next) { - /* - * Do not check "vmlinux". This avoids the same warnings - * shown twice, and false-positives for ARCH=um. - */ - if (is_vmlinux(s->module->name) && !s->module->is_dot_o) - continue; - if (s->is_static) warn("\"%s\" [%s] is a static %s\n", s->name, s->module->name, diff --git a/scripts/mod/modpost.h b/scripts/mod/modpost.h index bc524506d2f9..68d813abf33d 100644 --- a/scripts/mod/modpost.h +++ b/scripts/mod/modpost.h @@ -126,7 +126,6 @@ struct module { int has_cleanup; struct buffer dev_table_buf; char srcversion[25]; - int is_dot_o; // Missing namespace dependencies struct namespace_list *missing_namespaces; // Actual imported namespaces -- cgit v1.2.3 From 1be5fa6c948533bb95ac783010ef686261be5384 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Mon, 1 Jun 2020 14:57:25 +0900 Subject: modpost: remove is_vmlinux() call in check_for_{gpl_usage,unused}() check_exports() is never called for vmlinux because mod->skip is set for vmlinux. Hence, check_for_gpl_usage() and check_for_unused() are not called for vmlinux, either. is_vmlinux() is always false here. Remove the is_vmlinux() calls, and hard-code the ".ko" suffix. Signed-off-by: Masahiro Yamada --- scripts/mod/modpost.c | 20 ++++++++------------ 1 file changed, 8 insertions(+), 12 deletions(-) (limited to 'scripts') diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c index bc00bbac50bb..84a642c14775 100644 --- a/scripts/mod/modpost.c +++ b/scripts/mod/modpost.c @@ -2144,20 +2144,18 @@ void buf_write(struct buffer *buf, const char *s, int len) static void check_for_gpl_usage(enum export exp, const char *m, const char *s) { - const char *e = is_vmlinux(m) ?"":".ko"; - switch (exp) { case export_gpl: - fatal("GPL-incompatible module %s%s " - "uses GPL-only symbol '%s'\n", m, e, s); + fatal("GPL-incompatible module %s.ko uses GPL-only symbol '%s'\n", + m, s); break; case export_unused_gpl: - fatal("GPL-incompatible module %s%s " - "uses GPL-only symbol marked UNUSED '%s'\n", m, e, s); + fatal("GPL-incompatible module %s.ko uses GPL-only symbol marked UNUSED '%s'\n", + m, s); break; case export_gpl_future: - warn("GPL-incompatible module %s%s " - "uses future GPL-only symbol '%s'\n", m, e, s); + warn("GPL-incompatible module %s.ko uses future GPL-only symbol '%s'\n", + m, s); break; case export_plain: case export_unused: @@ -2169,13 +2167,11 @@ static void check_for_gpl_usage(enum export exp, const char *m, const char *s) static void check_for_unused(enum export exp, const char *m, const char *s) { - const char *e = is_vmlinux(m) ?"":".ko"; - switch (exp) { case export_unused: case export_unused_gpl: - warn("module %s%s " - "uses symbol '%s' marked UNUSED\n", m, e, s); + warn("module %s.ko uses symbol '%s' marked UNUSED\n", + m, s); break; default: /* ignore */ -- cgit v1.2.3 From 5a438af9db2c4a0b80d51d8c1c9c623b0c0de967 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Mon, 1 Jun 2020 14:57:26 +0900 Subject: modpost: add mod->is_vmlinux struct member is_vmlinux() is called in several places to check whether the current module is vmlinux or not. It is faster and clearer to check mod->is_vmlinux flag. Signed-off-by: Masahiro Yamada --- scripts/mod/modpost.c | 19 ++++++++++--------- scripts/mod/modpost.h | 1 + 2 files changed, 11 insertions(+), 9 deletions(-) (limited to 'scripts') diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c index 84a642c14775..167700a7b80f 100644 --- a/scripts/mod/modpost.c +++ b/scripts/mod/modpost.c @@ -187,6 +187,7 @@ static struct module *new_module(const char *modname) /* add to list */ mod->name = p; + mod->is_vmlinux = is_vmlinux(modname); mod->gpl_compatible = -1; mod->next = modules; modules = mod; @@ -431,11 +432,11 @@ static struct symbol *sym_add_exported(const char *name, struct module *mod, if (!s) { s = new_symbol(name, mod, export); - } else if (!external_module || is_vmlinux(s->module->name) || + } else if (!external_module || s->module->is_vmlinux || s->module == mod) { warn("%s: '%s' exported twice. Previous export was in %s%s\n", mod->name, name, s->module->name, - is_vmlinux(s->module->name) ? "" : ".ko"); + s->module->is_vmlinux ? "" : ".ko"); return s; } @@ -692,7 +693,7 @@ static void handle_modversion(const struct module *mod, if (sym->st_shndx == SHN_UNDEF) { warn("EXPORT symbol \"%s\" [%s%s] version generation failed, symbol will not be versioned.\n", - symname, mod->name, is_vmlinux(mod->name) ? "":".ko"); + symname, mod->name, mod->is_vmlinux ? "" : ".ko"); return; } @@ -2011,12 +2012,12 @@ static void read_symbols(const char *modname) mod = new_module(modname); - if (is_vmlinux(modname)) { + if (mod->is_vmlinux) { have_vmlinux = 1; mod->skip = 1; } - if (!is_vmlinux(modname)) { + if (!mod->is_vmlinux) { license = get_modinfo(&info, "license"); if (!license) warn("missing MODULE_LICENSE() in %s\n", modname); @@ -2075,7 +2076,7 @@ static void read_symbols(const char *modname) check_sec_ref(mod, modname, &info); - if (!is_vmlinux(modname)) { + if (!mod->is_vmlinux) { version = get_modinfo(&info, "version"); if (version || all_versions) get_src_version(modname, mod->srcversion, @@ -2345,7 +2346,7 @@ static void add_depends(struct buffer *b, struct module *mod) /* Clear ->seen flag of modules that own symbols needed by this. */ for (s = mod->unres; s; s = s->next) if (s->module) - s->module->seen = is_vmlinux(s->module->name); + s->module->seen = s->module->is_vmlinux; buf_printf(b, "\n"); buf_printf(b, "MODULE_INFO(depends, \""); @@ -2470,9 +2471,9 @@ static void read_dump(const char *fname) goto fail; mod = find_module(modname); if (!mod) { - if (is_vmlinux(modname)) - have_vmlinux = 1; mod = new_module(modname); + if (mod->is_vmlinux) + have_vmlinux = 1; mod->skip = 1; mod->from_dump = 1; } diff --git a/scripts/mod/modpost.h b/scripts/mod/modpost.h index 68d813abf33d..87251729539e 100644 --- a/scripts/mod/modpost.h +++ b/scripts/mod/modpost.h @@ -120,6 +120,7 @@ struct module { int gpl_compatible; struct symbol *unres; int from_dump; /* 1 if module was loaded from *.symvers */ + int is_vmlinux; int seen; int skip; int has_init; -- cgit v1.2.3 From 0b19d54cae11bd5b9e208f52e42d88ad33a3b1d9 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Mon, 1 Jun 2020 14:57:27 +0900 Subject: modpost: remove mod->skip struct member The meaning of 'skip' is obscure since it does not explain "what to skip". mod->skip is set when it is vmlinux or the module info came from a dump file. So, mod->skip is equivalent to (mod->is_vmlinux || mod->from_dump). For the check in write_namespace_deps_files(), mod->is_vmlinux is unneeded because the -d option is not passed in the first pass of modpost. Signed-off-by: Masahiro Yamada --- scripts/mod/modpost.c | 9 +++------ scripts/mod/modpost.h | 1 - 2 files changed, 3 insertions(+), 7 deletions(-) (limited to 'scripts') diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c index 167700a7b80f..925c1a1856aa 100644 --- a/scripts/mod/modpost.c +++ b/scripts/mod/modpost.c @@ -2012,10 +2012,8 @@ static void read_symbols(const char *modname) mod = new_module(modname); - if (mod->is_vmlinux) { + if (mod->is_vmlinux) have_vmlinux = 1; - mod->skip = 1; - } if (!mod->is_vmlinux) { license = get_modinfo(&info, "license"); @@ -2474,7 +2472,6 @@ static void read_dump(const char *fname) mod = new_module(modname); if (mod->is_vmlinux) have_vmlinux = 1; - mod->skip = 1; mod->from_dump = 1; } s = sym_add_exported(symname, mod, export_no(export)); @@ -2535,7 +2532,7 @@ static void write_namespace_deps_files(const char *fname) for (mod = modules; mod; mod = mod->next) { - if (mod->skip || !mod->missing_namespaces) + if (mod->from_dump || !mod->missing_namespaces) continue; buf_printf(&ns_deps_buf, "%s.ko:", mod->name); @@ -2637,7 +2634,7 @@ int main(int argc, char **argv) for (mod = modules; mod; mod = mod->next) { char fname[PATH_MAX]; - if (mod->skip) + if (mod->is_vmlinux || mod->from_dump) continue; buf.pos = 0; diff --git a/scripts/mod/modpost.h b/scripts/mod/modpost.h index 87251729539e..3dc9e8fa5d1f 100644 --- a/scripts/mod/modpost.h +++ b/scripts/mod/modpost.h @@ -122,7 +122,6 @@ struct module { int from_dump; /* 1 if module was loaded from *.symvers */ int is_vmlinux; int seen; - int skip; int has_init; int has_cleanup; struct buffer dev_table_buf; -- cgit v1.2.3 From 858b937d289bbf7551d496100c1fa9efcad5796e Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Mon, 1 Jun 2020 14:57:28 +0900 Subject: modpost: set have_vmlinux in new_module() Set have_vmlinux flag in a single place. Signed-off-by: Masahiro Yamada --- scripts/mod/modpost.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) (limited to 'scripts') diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c index 925c1a1856aa..b317328ae21b 100644 --- a/scripts/mod/modpost.c +++ b/scripts/mod/modpost.c @@ -192,6 +192,9 @@ static struct module *new_module(const char *modname) mod->next = modules; modules = mod; + if (mod->is_vmlinux) + have_vmlinux = 1; + return mod; } @@ -2012,9 +2015,6 @@ static void read_symbols(const char *modname) mod = new_module(modname); - if (mod->is_vmlinux) - have_vmlinux = 1; - if (!mod->is_vmlinux) { license = get_modinfo(&info, "license"); if (!license) @@ -2470,8 +2470,6 @@ static void read_dump(const char *fname) mod = find_module(modname); if (!mod) { mod = new_module(modname); - if (mod->is_vmlinux) - have_vmlinux = 1; mod->from_dump = 1; } s = sym_add_exported(symname, mod, export_no(export)); -- cgit v1.2.3 From a82f794c41ab51f088af325f5d9acba30a6facdb Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Mon, 1 Jun 2020 14:57:29 +0900 Subject: modpost: strip .o from modname before calling new_module() new_module() conditionally strips the .o because the modname has .o suffix when it is called from read_symbols(), but no .o when it is called from read_dump(). It is clearer to strip .o in read_symbols(). I also used flexible-array for mod->name. Signed-off-by: Masahiro Yamada --- scripts/mod/modpost.c | 20 +++++++++++--------- scripts/mod/modpost.h | 2 +- 2 files changed, 12 insertions(+), 10 deletions(-) (limited to 'scripts') diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c index b317328ae21b..ebfa9b76ba92 100644 --- a/scripts/mod/modpost.c +++ b/scripts/mod/modpost.c @@ -175,18 +175,12 @@ static struct module *find_module(const char *modname) static struct module *new_module(const char *modname) { struct module *mod; - char *p; - mod = NOFAIL(malloc(sizeof(*mod))); + mod = NOFAIL(malloc(sizeof(*mod) + strlen(modname) + 1)); memset(mod, 0, sizeof(*mod)); - p = NOFAIL(strdup(modname)); - - /* strip trailing .o */ - if (strends(p, ".o")) - p[strlen(p) - 2] = '\0'; /* add to list */ - mod->name = p; + strcpy(mod->name, modname); mod->is_vmlinux = is_vmlinux(modname); mod->gpl_compatible = -1; mod->next = modules; @@ -2013,7 +2007,15 @@ static void read_symbols(const char *modname) if (!parse_elf(&info, modname)) return; - mod = new_module(modname); + { + char *tmp; + + /* strip trailing .o */ + tmp = NOFAIL(strdup(modname)); + tmp[strlen(tmp) - 2] = '\0'; + mod = new_module(tmp); + free(tmp); + } if (!mod->is_vmlinux) { license = get_modinfo(&info, "license"); diff --git a/scripts/mod/modpost.h b/scripts/mod/modpost.h index 3dc9e8fa5d1f..254c75378583 100644 --- a/scripts/mod/modpost.h +++ b/scripts/mod/modpost.h @@ -116,7 +116,6 @@ struct namespace_list { struct module { struct module *next; - const char *name; int gpl_compatible; struct symbol *unres; int from_dump; /* 1 if module was loaded from *.symvers */ @@ -130,6 +129,7 @@ struct module { struct namespace_list *missing_namespaces; // Actual imported namespaces struct namespace_list *imported_namespaces; + char name[]; }; struct elf_info { -- cgit v1.2.3 From 4de7b62936122570408357417f21072e78292926 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Mon, 1 Jun 2020 14:57:30 +0900 Subject: modpost: remove is_vmlinux() helper Now that is_vmlinux() is called only in new_module(), we can inline the function call. modname is the basename with '.o' is stripped. No need to compare it with 'vmlinux.o'. vmlinux is always located at the current working directory. No need to strip the directory path. Signed-off-by: Masahiro Yamada --- scripts/mod/modpost.c | 16 +--------------- 1 file changed, 1 insertion(+), 15 deletions(-) (limited to 'scripts') diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c index ebfa9b76ba92..a3ffabf4eca5 100644 --- a/scripts/mod/modpost.c +++ b/scripts/mod/modpost.c @@ -88,20 +88,6 @@ static inline bool strends(const char *str, const char *postfix) return strcmp(str + strlen(str) - strlen(postfix), postfix) == 0; } -static int is_vmlinux(const char *modname) -{ - const char *myname; - - myname = strrchr(modname, '/'); - if (myname) - myname++; - else - myname = modname; - - return (strcmp(myname, "vmlinux") == 0) || - (strcmp(myname, "vmlinux.o") == 0); -} - void *do_nofail(void *ptr, const char *expr) { if (!ptr) @@ -181,7 +167,7 @@ static struct module *new_module(const char *modname) /* add to list */ strcpy(mod->name, modname); - mod->is_vmlinux = is_vmlinux(modname); + mod->is_vmlinux = (strcmp(modname, "vmlinux") == 0); mod->gpl_compatible = -1; mod->next = modules; modules = mod; -- cgit v1.2.3 From 3b09efc4f0c94669a928c0453d2dcb54c59543f2 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Mon, 1 Jun 2020 14:57:31 +0900 Subject: modpost: change elf_info->size to size_t Align with the mmap / munmap APIs. Signed-off-by: Masahiro Yamada --- scripts/mod/modpost.c | 9 ++++----- scripts/mod/modpost.h | 2 +- 2 files changed, 5 insertions(+), 6 deletions(-) (limited to 'scripts') diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c index a3ffabf4eca5..e5cee2367d5e 100644 --- a/scripts/mod/modpost.c +++ b/scripts/mod/modpost.c @@ -443,7 +443,7 @@ static void sym_set_crc(const char *name, unsigned int crc) s->crc_valid = 1; } -static void *grab_file(const char *filename, unsigned long *size) +static void *grab_file(const char *filename, size_t *size) { struct stat st; void *map = MAP_FAILED; @@ -465,7 +465,7 @@ failed: return map; } -static void release_file(void *file, unsigned long size) +static void release_file(void *file, size_t size) { munmap(file, size); } @@ -521,9 +521,8 @@ static int parse_elf(struct elf_info *info, const char *filename) /* Check if file offset is correct */ if (hdr->e_shoff > info->size) { - fatal("section header offset=%lu in file '%s' is bigger than " - "filesize=%lu\n", (unsigned long)hdr->e_shoff, - filename, info->size); + fatal("section header offset=%lu in file '%s' is bigger than filesize=%zu\n", + (unsigned long)hdr->e_shoff, filename, info->size); return 0; } diff --git a/scripts/mod/modpost.h b/scripts/mod/modpost.h index 254c75378583..3aa052722233 100644 --- a/scripts/mod/modpost.h +++ b/scripts/mod/modpost.h @@ -133,7 +133,7 @@ struct module { }; struct elf_info { - unsigned long size; + size_t size; Elf_Ehdr *hdr; Elf_Shdr *sechdrs; Elf_Sym *symtab_start; -- cgit v1.2.3 From 72d24accf02add25e08733f0ecc93cf10fcbd88c Mon Sep 17 00:00:00 2001 From: ashimida Date: Tue, 2 Jun 2020 15:45:17 +0800 Subject: mksysmap: Fix the mismatch of '.L' symbols in System.map When System.map was generated, the kernel used mksysmap to filter the kernel symbols, but all the symbols with the second letter 'L' in the kernel were filtered out, not just the symbols starting with 'dot + L'. For example: ashimida@ubuntu:~/linux$ cat System.map |grep ' .L' ashimida@ubuntu:~/linux$ nm -n vmlinux |grep ' .L' ffff0000088028e0 t bLength_show ...... ffff0000092e0408 b PLLP_OUTC_lock ffff0000092e0410 b PLLP_OUTA_lock The original intent should be to filter out all local symbols starting with '.L', so the dot should be escaped. Fixes: 00902e984732 ("mksysmap: Add h8300 local symbol pattern") Signed-off-by: ashimida Signed-off-by: Masahiro Yamada --- scripts/mksysmap | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'scripts') diff --git a/scripts/mksysmap b/scripts/mksysmap index a35acc0d0b82..9aa23d15862a 100755 --- a/scripts/mksysmap +++ b/scripts/mksysmap @@ -41,4 +41,4 @@ # so we just ignore them to let readprofile continue to work. # (At least sparc64 has __crc_ in the middle). -$NM -n $1 | grep -v '\( [aNUw] \)\|\(__crc_\)\|\( \$[adt]\)\|\( .L\)' > $2 +$NM -n $1 | grep -v '\( [aNUw] \)\|\(__crc_\)\|\( \$[adt]\)\|\( \.L\)' > $2 -- cgit v1.2.3 From 8dfb61dcbaceb19a5ded5e9c9dcf8d05acc32294 Mon Sep 17 00:00:00 2001 From: Denis Efremov Date: Fri, 5 Jun 2020 10:39:55 +0300 Subject: kbuild: add variables for compression tools Allow user to use alternative implementations of compression tools, such as pigz, pbzip2, pxz. For example, multi-threaded tools to speed up the build: $ make GZIP=pigz BZIP2=pbzip2 Variables _GZIP, _BZIP2, _LZOP are used internally because original env vars are reserved by the tools. The use of GZIP in gzip tool is obsolete since 2015. However, alternative implementations (e.g., pigz) still rely on it. BZIP2, BZIP, LZOP vars are not obsolescent. The credit goes to @grsecurity. As a sidenote, for multi-threaded lzma, xz compression one can use: $ export XZ_OPT="--threads=0" Signed-off-by: Denis Efremov Signed-off-by: Masahiro Yamada --- Makefile | 25 +++++++++++++++++++++++-- arch/arm/boot/deflate_xip_data.sh | 2 +- arch/ia64/Makefile | 2 +- arch/m68k/Makefile | 8 ++++---- arch/parisc/Makefile | 2 +- kernel/gen_kheaders.sh | 2 +- scripts/Makefile.lib | 12 ++++++------ scripts/Makefile.package | 8 ++++---- scripts/package/buildtar | 6 +++--- scripts/xz_wrap.sh | 2 +- 10 files changed, 45 insertions(+), 24 deletions(-) (limited to 'scripts') diff --git a/Makefile b/Makefile index 7b750dc0b2da..64ebbc1dfbef 100644 --- a/Makefile +++ b/Makefile @@ -458,6 +458,26 @@ PYTHON = python PYTHON3 = python3 CHECK = sparse BASH = bash +GZIP = gzip +BZIP2 = bzip2 +LZOP = lzop +LZMA = lzma +LZ4 = lz4c +XZ = xz + +# GZIP, BZIP2, LZOP env vars are used by the tools. Support them as the command +# line interface, but use _GZIP, _BZIP2, _LZOP internally. +_GZIP := $(GZIP) +_BZIP2 := $(BZIP2) +_LZOP := $(LZOP) + +# Reset GZIP, BZIP2, LZOP in this Makefile +override GZIP= +override BZIP2= +override LZOP= + +# Reset GZIP, BZIP2, LZOP in recursive invocations +MAKEOVERRIDES += GZIP= BZIP2= LZOP= CHECKFLAGS := -D__linux__ -Dlinux -D__STDC__ -Dunix -D__unix__ \ -Wbitwise -Wno-return-void -Wno-unknown-attribute $(CF) @@ -506,6 +526,7 @@ CLANG_FLAGS := export ARCH SRCARCH CONFIG_SHELL BASH HOSTCC KBUILD_HOSTCFLAGS CROSS_COMPILE LD CC export CPP AR NM STRIP OBJCOPY OBJDUMP OBJSIZE READELF PAHOLE LEX YACC AWK INSTALLKERNEL export PERL PYTHON PYTHON3 CHECK CHECKFLAGS MAKE UTS_MACHINE HOSTCXX +export _GZIP _BZIP2 _LZOP LZMA LZ4 XZ export KBUILD_HOSTCXXFLAGS KBUILD_HOSTLDFLAGS KBUILD_HOSTLDLIBS LDFLAGS_MODULE export KBUILD_CPPFLAGS NOSTDINC_FLAGS LINUXINCLUDE OBJCOPYFLAGS KBUILD_LDFLAGS @@ -1020,10 +1041,10 @@ export mod_strip_cmd mod_compress_cmd = true ifdef CONFIG_MODULE_COMPRESS ifdef CONFIG_MODULE_COMPRESS_GZIP - mod_compress_cmd = gzip -n -f + mod_compress_cmd = $(_GZIP) -n -f endif # CONFIG_MODULE_COMPRESS_GZIP ifdef CONFIG_MODULE_COMPRESS_XZ - mod_compress_cmd = xz -f + mod_compress_cmd = $(XZ) -f endif # CONFIG_MODULE_COMPRESS_XZ endif # CONFIG_MODULE_COMPRESS export mod_compress_cmd diff --git a/arch/arm/boot/deflate_xip_data.sh b/arch/arm/boot/deflate_xip_data.sh index 40937248cebe..739f0464321e 100755 --- a/arch/arm/boot/deflate_xip_data.sh +++ b/arch/arm/boot/deflate_xip_data.sh @@ -56,7 +56,7 @@ trap 'rm -f "$XIPIMAGE.tmp"; exit 1' 1 2 3 # substitute the data section by a compressed version $DD if="$XIPIMAGE" count=$data_start iflag=count_bytes of="$XIPIMAGE.tmp" $DD if="$XIPIMAGE" skip=$data_start iflag=skip_bytes | -gzip -9 >> "$XIPIMAGE.tmp" +$_GZIP -9 >> "$XIPIMAGE.tmp" # replace kernel binary mv -f "$XIPIMAGE.tmp" "$XIPIMAGE" diff --git a/arch/ia64/Makefile b/arch/ia64/Makefile index 32240000dc0c..f817f3d5e758 100644 --- a/arch/ia64/Makefile +++ b/arch/ia64/Makefile @@ -40,7 +40,7 @@ $(error Sorry, you need a newer version of the assember, one that is built from endif quiet_cmd_gzip = GZIP $@ -cmd_gzip = cat $(real-prereqs) | gzip -n -f -9 > $@ +cmd_gzip = cat $(real-prereqs) | $(_GZIP) -n -f -9 > $@ quiet_cmd_objcopy = OBJCOPY $@ cmd_objcopy = $(OBJCOPY) $(OBJCOPYFLAGS) $(OBJCOPYFLAGS_$(@F)) $< $@ diff --git a/arch/m68k/Makefile b/arch/m68k/Makefile index 5d9288384096..ce6db5e5a5a3 100644 --- a/arch/m68k/Makefile +++ b/arch/m68k/Makefile @@ -135,10 +135,10 @@ vmlinux.gz: vmlinux ifndef CONFIG_KGDB cp vmlinux vmlinux.tmp $(STRIP) vmlinux.tmp - gzip -9c vmlinux.tmp >vmlinux.gz + $(_GZIP) -9c vmlinux.tmp >vmlinux.gz rm vmlinux.tmp else - gzip -9c vmlinux >vmlinux.gz + $(_GZIP) -9c vmlinux >vmlinux.gz endif bzImage: vmlinux.bz2 @@ -148,10 +148,10 @@ vmlinux.bz2: vmlinux ifndef CONFIG_KGDB cp vmlinux vmlinux.tmp $(STRIP) vmlinux.tmp - bzip2 -1c vmlinux.tmp >vmlinux.bz2 + $(_BZIP2) -1c vmlinux.tmp >vmlinux.bz2 rm vmlinux.tmp else - bzip2 -1c vmlinux >vmlinux.bz2 + $(_BZIP2) -1c vmlinux >vmlinux.bz2 endif archclean: diff --git a/arch/parisc/Makefile b/arch/parisc/Makefile index 628cd8bb7ad8..e1aa514aeb36 100644 --- a/arch/parisc/Makefile +++ b/arch/parisc/Makefile @@ -162,7 +162,7 @@ vmlinuz: bzImage $(OBJCOPY) $(boot)/bzImage $@ else vmlinuz: vmlinux - @gzip -cf -9 $< > $@ + @$(_GZIP) -cf -9 $< > $@ endif install: diff --git a/kernel/gen_kheaders.sh b/kernel/gen_kheaders.sh index e13ca842eb7e..c1510f0ab3ea 100755 --- a/kernel/gen_kheaders.sh +++ b/kernel/gen_kheaders.sh @@ -88,7 +88,7 @@ find $cpio_dir -type f -print0 | find $cpio_dir -printf "./%P\n" | LC_ALL=C sort | \ tar "${KBUILD_BUILD_TIMESTAMP:+--mtime=$KBUILD_BUILD_TIMESTAMP}" \ --owner=0 --group=0 --numeric-owner --no-recursion \ - -Jcf $tarfile -C $cpio_dir/ -T - > /dev/null + -I $XZ -cf $tarfile -C $cpio_dir/ -T - > /dev/null echo $headers_md5 > kernel/kheaders.md5 echo "$this_file_md5" >> kernel/kheaders.md5 diff --git a/scripts/Makefile.lib b/scripts/Makefile.lib index e598b07e6de4..127f2a7e3ced 100644 --- a/scripts/Makefile.lib +++ b/scripts/Makefile.lib @@ -244,7 +244,7 @@ cmd_objcopy = $(OBJCOPY) $(OBJCOPYFLAGS) $(OBJCOPYFLAGS_$(@F)) $< $@ # --------------------------------------------------------------------------- quiet_cmd_gzip = GZIP $@ - cmd_gzip = cat $(real-prereqs) | gzip -n -f -9 > $@ + cmd_gzip = cat $(real-prereqs) | $(_GZIP) -n -f -9 > $@ # DTC # --------------------------------------------------------------------------- @@ -337,19 +337,19 @@ printf "%08x\n" $$dec_size | \ ) quiet_cmd_bzip2 = BZIP2 $@ - cmd_bzip2 = { cat $(real-prereqs) | bzip2 -9; $(size_append); } > $@ + cmd_bzip2 = { cat $(real-prereqs) | $(_BZIP2) -9; $(size_append); } > $@ # Lzma # --------------------------------------------------------------------------- quiet_cmd_lzma = LZMA $@ - cmd_lzma = { cat $(real-prereqs) | lzma -9; $(size_append); } > $@ + cmd_lzma = { cat $(real-prereqs) | $(LZMA) -9; $(size_append); } > $@ quiet_cmd_lzo = LZO $@ - cmd_lzo = { cat $(real-prereqs) | lzop -9; $(size_append); } > $@ + cmd_lzo = { cat $(real-prereqs) | $(_LZOP) -9; $(size_append); } > $@ quiet_cmd_lz4 = LZ4 $@ - cmd_lz4 = { cat $(real-prereqs) | lz4c -l -c1 stdin stdout; \ + cmd_lz4 = { cat $(real-prereqs) | $(LZ4) -l -c1 stdin stdout; \ $(size_append); } > $@ # U-Boot mkimage @@ -396,7 +396,7 @@ quiet_cmd_xzkern = XZKERN $@ $(size_append); } > $@ quiet_cmd_xzmisc = XZMISC $@ - cmd_xzmisc = cat $(real-prereqs) | xz --check=crc32 --lzma2=dict=1MiB > $@ + cmd_xzmisc = cat $(real-prereqs) | $(XZ) --check=crc32 --lzma2=dict=1MiB > $@ # ASM offsets # --------------------------------------------------------------------------- diff --git a/scripts/Makefile.package b/scripts/Makefile.package index 02135d2671a6..b2b6153af63a 100644 --- a/scripts/Makefile.package +++ b/scripts/Makefile.package @@ -45,7 +45,7 @@ if test "$(objtree)" != "$(srctree)"; then \ false; \ fi ; \ $(srctree)/scripts/setlocalversion --save-scmversion; \ -tar -cz $(RCS_TAR_IGNORE) -f $(2).tar.gz \ +tar -I $(_GZIP) -c $(RCS_TAR_IGNORE) -f $(2).tar.gz \ --transform 's:^:$(2)/:S' $(TAR_CONTENT) $(3); \ rm -f $(objtree)/.scmversion @@ -127,9 +127,9 @@ util/PERF-VERSION-GEN $(CURDIR)/$(perf-tar)/); \ tar rf $(perf-tar).tar $(perf-tar)/HEAD $(perf-tar)/PERF-VERSION-FILE; \ rm -r $(perf-tar); \ $(if $(findstring tar-src,$@),, \ -$(if $(findstring bz2,$@),bzip2, \ -$(if $(findstring gz,$@),gzip, \ -$(if $(findstring xz,$@),xz, \ +$(if $(findstring bz2,$@),$(_BZIP2), \ +$(if $(findstring gz,$@),$(_GZIP), \ +$(if $(findstring xz,$@),$(XZ), \ $(error unknown target $@)))) \ -f -9 $(perf-tar).tar) diff --git a/scripts/package/buildtar b/scripts/package/buildtar index 77c7caefede1..ad62c6879622 100755 --- a/scripts/package/buildtar +++ b/scripts/package/buildtar @@ -28,15 +28,15 @@ case "${1}" in opts= ;; targz-pkg) - opts=--gzip + opts="-I ${_GZIP}" tarball=${tarball}.gz ;; tarbz2-pkg) - opts=--bzip2 + opts="-I ${_BZIP2}" tarball=${tarball}.bz2 ;; tarxz-pkg) - opts=--xz + opts="-I ${XZ}" tarball=${tarball}.xz ;; *) diff --git a/scripts/xz_wrap.sh b/scripts/xz_wrap.sh index 7a2d372f4885..76e9cbcfbeab 100755 --- a/scripts/xz_wrap.sh +++ b/scripts/xz_wrap.sh @@ -20,4 +20,4 @@ case $SRCARCH in sparc) BCJ=--sparc ;; esac -exec xz --check=crc32 $BCJ --lzma2=$LZMA2OPTS,dict=32MiB +exec $XZ --check=crc32 $BCJ --lzma2=$LZMA2OPTS,dict=32MiB -- cgit v1.2.3