From 29f006fdefe6f88abde973a0b0f20d2704e93fd4 Mon Sep 17 00:00:00 2001 From: Peter Zijlstra Date: Sat, 29 Aug 2020 22:03:35 +0900 Subject: asm-generic/atomic: Add try_cmpxchg() fallbacks Only x86 provides try_cmpxchg() outside of the atomic_t interfaces, provide generic fallbacks to create this interface from the widely available cmpxchg() function. Signed-off-by: Peter Zijlstra (Intel) Signed-off-by: Masami Hiramatsu Signed-off-by: Ingo Molnar Acked-by: Will Deacon Link: https://lore.kernel.org/r/159870621515.1229682.15506193091065001742.stgit@devnote2 --- scripts/atomic/gen-atomic-fallback.sh | 63 +++++++++++++++++++++++++++---- scripts/atomic/gen-atomic-instrumented.sh | 29 +++++++++++--- 2 files changed, 79 insertions(+), 13 deletions(-) (limited to 'scripts') diff --git a/scripts/atomic/gen-atomic-fallback.sh b/scripts/atomic/gen-atomic-fallback.sh index 693dfa1de430..317a6cec76e1 100755 --- a/scripts/atomic/gen-atomic-fallback.sh +++ b/scripts/atomic/gen-atomic-fallback.sh @@ -144,15 +144,11 @@ gen_proto_order_variants() printf "#endif /* ${basename}_relaxed */\n\n" } -gen_xchg_fallbacks() +gen_order_fallbacks() { local xchg="$1"; shift + cat < Date: Tue, 27 Oct 2020 11:20:36 +0100 Subject: scripts: kernel-doc: fix typedef parsing The include/linux/genalloc.h file defined this typedef: typedef unsigned long (*genpool_algo_t)(unsigned long *map,unsigned long size,unsigned long start,unsigned int nr,void *data, struct gen_pool *pool, unsigned long start_addr); Because it has a type composite of two words (unsigned long), the parser gets the typedef name wrong: .. c:macro:: long **Typedef**: Allocation callback function type definition Fix the regex in order to accept composite types when defining a typedef for a function pointer. Signed-off-by: Mauro Carvalho Chehab Link: https://lore.kernel.org/r/328e8018041cc44f7a1684e57f8d111230761c4f.1603792384.git.mchehab+huawei@kernel.org Signed-off-by: Jonathan Corbet --- scripts/kernel-doc | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'scripts') diff --git a/scripts/kernel-doc b/scripts/kernel-doc index c8f6b11d5da1..c7c9f1e8428d 100755 --- a/scripts/kernel-doc +++ b/scripts/kernel-doc @@ -1434,13 +1434,14 @@ sub dump_typedef($$) { $x =~ s@/\*.*?\*/@@gos; # strip comments. # Parse function prototypes - if ($x =~ /typedef\s+(\w+)\s*\(\*\s*(\w\S+)\s*\)\s*\((.*)\);/ || - $x =~ /typedef\s+(\w+)\s*(\w\S+)\s*\s*\((.*)\);/) { + if ($x =~ /typedef((?:\s+[\w\*]+){1,8})\s*\(\*?\s*(\w\S+)\s*\)\s*\((.*)\);/ || + $x =~ /typedef((?:\s+[\w\*]+\s+){1,8})\s*\*?(\w\S+)\s*\s*\((.*)\);/) { # Function typedefs $return_type = $1; $declaration_name = $2; my $args = $3; + $return_type =~ s/^\s+//; create_parameterlist($args, ',', $file, $declaration_name); -- cgit From 7efc6c4295f5489e25eaef6d6fb6ceb6a6e238d0 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Tue, 27 Oct 2020 11:20:37 +0100 Subject: scripts: kernel-doc: split typedef complex regex The typedef regex for function prototypes are very complex. Split them into 3 separate regex and then join them using qr. Signed-off-by: Mauro Carvalho Chehab Link: https://lore.kernel.org/r/3a4af999a0d62d4ab9dfae1cdefdfcad93383356.1603792384.git.mchehab+huawei@kernel.org Signed-off-by: Jonathan Corbet --- scripts/kernel-doc | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) (limited to 'scripts') diff --git a/scripts/kernel-doc b/scripts/kernel-doc index c7c9f1e8428d..cf71897df36d 100755 --- a/scripts/kernel-doc +++ b/scripts/kernel-doc @@ -1427,17 +1427,21 @@ sub dump_enum($$) { } } +my $typedef_type = qr { ((?:\s+[\w\*]+){1,8})\s* }x; +my $typedef_ident = qr { \*?\s*(\w\S+)\s* }x; +my $typedef_args = qr { \s*\((.*)\); }x; + +my $typedef1 = qr { typedef$typedef_type\($typedef_ident\)$typedef_args }x; +my $typedef2 = qr { typedef$typedef_type$typedef_ident$typedef_args }x; + sub dump_typedef($$) { my $x = shift; my $file = shift; $x =~ s@/\*.*?\*/@@gos; # strip comments. - # Parse function prototypes - if ($x =~ /typedef((?:\s+[\w\*]+){1,8})\s*\(\*?\s*(\w\S+)\s*\)\s*\((.*)\);/ || - $x =~ /typedef((?:\s+[\w\*]+\s+){1,8})\s*\*?(\w\S+)\s*\s*\((.*)\);/) { - - # Function typedefs + # Parse function typedef prototypes + if ($x =~ $typedef1 || $x =~ $typedef2) { $return_type = $1; $declaration_name = $2; my $args = $3; -- cgit From 72b97d0b911872ba36a5742b7d790b6b165e11d8 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Tue, 27 Oct 2020 10:51:05 +0100 Subject: scripts: kernel-doc: use :c:union when needed Sphinx C domain code after 3.2.1 will start complaning if :c:struct would be used for an union type: .../Documentation/gpu/drm-kms-helpers:352: ../drivers/video/hdmi.c:851: WARNING: C 'identifier' cross-reference uses wrong tag: reference name is 'union hdmi_infoframe' but found name is 'struct hdmi_infoframe'. Full reference name is 'union hdmi_infoframe'. Full found name is 'struct hdmi_infoframe'. So, let's address this issue too in advance, in order to avoid future issues. Signed-off-by: Mauro Carvalho Chehab Link: https://lore.kernel.org/r/6e4ec3eec914df62389a299797a3880ae4490f35.1603791716.git.mchehab+huawei@kernel.org Signed-off-by: Jonathan Corbet --- scripts/kernel-doc | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'scripts') diff --git a/scripts/kernel-doc b/scripts/kernel-doc index cf71897df36d..f699cf05d409 100755 --- a/scripts/kernel-doc +++ b/scripts/kernel-doc @@ -1092,7 +1092,11 @@ sub output_struct_rst(%) { print "\n\n.. c:type:: " . $name . "\n\n"; } else { my $name = $args{'struct'}; - print "\n\n.. c:struct:: " . $name . "\n\n"; + if ($args{'type'} eq 'union') { + print "\n\n.. c:union:: " . $name . "\n\n"; + } else { + print "\n\n.. c:struct:: " . $name . "\n\n"; + } } print_lineno($declaration_start_line); $lineprefix = " "; -- cgit From 821f5c90130d15f8f725412d714d05df3b9e0fac Mon Sep 17 00:00:00 2001 From: Andrii Nakryiko Date: Wed, 28 Oct 2020 11:12:04 -0700 Subject: bpf: Add struct bpf_redir_neigh forward declaration to BPF helper defs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Forward-declare struct bpf_redir_neigh in bpf_helper_defs.h to avoid compiler warning about unknown structs. Fixes: ba452c9e996d ("bpf: Fix bpf_redirect_neigh helper api to support supplying nexthop") Signed-off-by: Andrii Nakryiko Signed-off-by: Daniel Borkmann Acked-by: Toke Høiland-Jørgensen Link: https://lore.kernel.org/bpf/20201028181204.111241-1-andrii@kernel.org --- scripts/bpf_helpers_doc.py | 1 + 1 file changed, 1 insertion(+) (limited to 'scripts') diff --git a/scripts/bpf_helpers_doc.py b/scripts/bpf_helpers_doc.py index 6769caae142f..31484377b8b1 100755 --- a/scripts/bpf_helpers_doc.py +++ b/scripts/bpf_helpers_doc.py @@ -408,6 +408,7 @@ class PrinterHelpers(Printer): 'struct bpf_perf_event_data', 'struct bpf_perf_event_value', 'struct bpf_pidns_info', + 'struct bpf_redir_neigh', 'struct bpf_sock', 'struct bpf_sock_addr', 'struct bpf_sock_ops', -- cgit From d1889589a4f54b2d1d7075d608b596d6fcfd3d96 Mon Sep 17 00:00:00 2001 From: Sven Joachim Date: Mon, 26 Oct 2020 20:32:16 +0100 Subject: builddeb: Fix rootless build in setuid/setgid directory Building 5.10-rc1 in a setgid directory failed with the following error: dpkg-deb: error: control directory has bad permissions 2755 (must be >=0755 and <=0775) When building with fakeroot, the earlier chown call would have removed the setgid bits, but in a rootless build they remain. Fixes: 3e8541803624 ("builddeb: Enable rootless builds") Cc: Guillem Jover Signed-off-by: Sven Joachim Signed-off-by: Masahiro Yamada --- scripts/package/builddeb | 2 ++ 1 file changed, 2 insertions(+) (limited to 'scripts') diff --git a/scripts/package/builddeb b/scripts/package/builddeb index 1b11f8993629..91a502bb97e8 100755 --- a/scripts/package/builddeb +++ b/scripts/package/builddeb @@ -45,6 +45,8 @@ create_package() { chmod -R go-w "$pdir" # in case we are in a restrictive umask environment like 0077 chmod -R a+rX "$pdir" + # in case we build in a setuid/setgid directory + chmod -R ug-s "$pdir" # Create the package dpkg-gencontrol -p$pname -P"$pdir" -- cgit From daaaf58a2b7fd59951bd090eddee131f26422e20 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Mon, 2 Nov 2020 11:32:15 +0100 Subject: scripts: get_abi.pl: Don't let ABI files to create subtitles The ReST output should only contain documentation titles automatically created by the script. There are two reasons for that: 1) Consistency. just a handful ABI docs define titles 2) To avoid critical errors. Docutils (which is the basis for Sphinx) allows a free assign of documentation title markups. So, one document could be doing things like: Level 1 ======= Level 2 ------- While another one could do the reverse: Level 1 ------- Level 2 ======= But the same document can't mix. As the output of get_abi.pl will join contents from multiple files, if they don't define the levels on a consistent errors, errors like this can happen: Sphinx parallel build error: docutils.utils.SystemMessage: /home/rdunlap/lnx/lnx-510-rc2/Documentation/ABI/testing/sysfs-bus-rapidio:2: (SEVERE/4) Title level inconsistent: Attributes Common for All RapidIO Devices ----------------------------------------- Which cause some versions of Sphinx to go into an endless loop. It should be noticed that an alternative to that would be to replace all title occurrences by a single markup, but that will make the parser more complex, and, due to (1) it would generate an inconsistent output. So, better to just remove the titles defined at the ABI files from the output. Reported-by: Randy Dunlap Signed-off-by: Mauro Carvalho Chehab Link: https://lore.kernel.org/r/6c62ef5c01d39dee8d891f8390c816d2a889670a.1604312590.git.mchehab+huawei@kernel.org Signed-off-by: Greg Kroah-Hartman --- scripts/get_abi.pl | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'scripts') diff --git a/scripts/get_abi.pl b/scripts/get_abi.pl index 2cb592f8eba4..459f169f834c 100755 --- a/scripts/get_abi.pl +++ b/scripts/get_abi.pl @@ -352,6 +352,12 @@ sub output_rest { if (!($desc =~ /^\s*$/)) { if ($description_is_rst) { + # Remove title markups from the description + # Having titles inside ABI files will only work if extra + # care would be taken in order to strictly follow the same + # level order for each markup. + $desc =~ s/\n[\-\*\=\^\~]+\n/\n\n/g; + # Enrich text by creating cross-references $desc =~ s,Documentation/(?!devicetree)(\S+)\.rst,:doc:`/$1`,g; -- cgit From 9d4fdda3344611ec53ededccc0c13cb149ba4375 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Mon, 2 Nov 2020 11:32:16 +0100 Subject: scripts: get_api.pl: Add sub-titles to ABI output Instead of adding titles just for the files, add titles for each part of the ABI output, in order to make easier to search for a symbol there. Signed-off-by: Mauro Carvalho Chehab Link: https://lore.kernel.org/r/64752a5de06ab8263c296e3ed01414b25861e1eb.1604312590.git.mchehab+huawei@kernel.org Signed-off-by: Greg Kroah-Hartman --- scripts/get_abi.pl | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) (limited to 'scripts') diff --git a/scripts/get_abi.pl b/scripts/get_abi.pl index 459f169f834c..68dab828a722 100755 --- a/scripts/get_abi.pl +++ b/scripts/get_abi.pl @@ -287,6 +287,8 @@ my $bondary = qr { (?{type} eq "File") cmp ($data{$b}->{type} eq "File") || $a cmp $b @@ -306,6 +308,21 @@ sub output_rest { $w =~ s/([\(\)\_\-\*\=\^\~\\])/\\$1/g; if ($type ne "File") { + my $cur_part = $what; + if ($what =~ '/') { + if ($what =~ m#^(\/?(?:[\w\-]+\/?){1,2})#) { + $cur_part = "Symbols under $1"; + $cur_part =~ s,/$,,; + } + } + + if ($cur_part ne "" && $part ne $cur_part) { + $part = $cur_part; + my $bar = $part; + $bar =~ s/./-/g; + print "$part\n$bar\n\n"; + } + printf ".. _%s:\n\n", $data{$what}->{label}; my @names = split /, /,$w; -- cgit From a70a04b3844f59c29573a8581d5c263225060dd6 Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Sat, 7 Nov 2020 12:54:49 +0100 Subject: locking/atomics: Regenerate the atomics-check SHA1's The include/asm-generic/atomic-instrumented.h checksum got out of sync, so regenerate it. (No change to actual code.) Also make scripts/atomic/gen-atomics.sh executable, to make it easier to use. The auto-generated atomic header signatures are now fine: thule:~/tip> scripts/atomic/check-atomics.sh thule:~/tip> Signed-off-by: Ingo Molnar Cc: linux-kernel@vger.kernel.org Cc: Peter Zijlstra Cc: Linus Torvalds Cc: Andrew Morton Cc: Thomas Gleixner Cc: Paul E. McKenney Cc: Will Deacon Signed-off-by: Ingo Molnar --- scripts/atomic/gen-atomics.sh | 0 1 file changed, 0 insertions(+), 0 deletions(-) mode change 100644 => 100755 scripts/atomic/gen-atomics.sh (limited to 'scripts') diff --git a/scripts/atomic/gen-atomics.sh b/scripts/atomic/gen-atomics.sh old mode 100644 new mode 100755 -- cgit From 2b076054e524a92e3a303de487dfb7cf85d8e149 Mon Sep 17 00:00:00 2001 From: Peter Zijlstra Date: Mon, 9 Nov 2020 12:39:12 +0100 Subject: remove boolinit.cocci 0/1 for booleans is perfectly valid C. Signed-off-by: Peter Zijlstra (Intel) Signed-off-by: Julia Lawall --- scripts/coccinelle/misc/boolinit.cocci | 195 --------------------------------- 1 file changed, 195 deletions(-) delete mode 100644 scripts/coccinelle/misc/boolinit.cocci (limited to 'scripts') diff --git a/scripts/coccinelle/misc/boolinit.cocci b/scripts/coccinelle/misc/boolinit.cocci deleted file mode 100644 index fed6126e2b9d..000000000000 --- a/scripts/coccinelle/misc/boolinit.cocci +++ /dev/null @@ -1,195 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -/// Bool initializations should use true and false. Bool tests don't need -/// comparisons. Based on contributions from Joe Perches, Rusty Russell -/// and Bruce W Allan. -/// -// Confidence: High -// Copyright: (C) 2012 Julia Lawall, INRIA/LIP6. -// Copyright: (C) 2012 Gilles Muller, INRIA/LiP6. -// URL: http://coccinelle.lip6.fr/ -// Options: --include-headers - -virtual patch -virtual context -virtual org -virtual report - -@boolok@ -symbol true,false; -@@ -( -true -| -false -) - -@depends on patch@ -bool t; -@@ - -( -- t == true -+ t -| -- true == t -+ t -| -- t != true -+ !t -| -- true != t -+ !t -| -- t == false -+ !t -| -- false == t -+ !t -| -- t != false -+ t -| -- false != t -+ t -) - -@depends on patch disable is_zero, isnt_zero@ -bool t; -@@ - -( -- t == 1 -+ t -| -- t != 1 -+ !t -| -- t == 0 -+ !t -| -- t != 0 -+ t -) - -@depends on patch && boolok@ -bool b; -@@ -( - b = -- 0 -+ false -| - b = -- 1 -+ true -) - -// --------------------------------------------------------------------- - -@r1 depends on !patch@ -bool t; -position p; -@@ - -( -* t@p == true -| -* true == t@p -| -* t@p != true -| -* true != t@p -| -* t@p == false -| -* false == t@p -| -* t@p != false -| -* false != t@p -) - -@r2 depends on !patch disable is_zero, isnt_zero@ -bool t; -position p; -@@ - -( -* t@p == 1 -| -* t@p != 1 -| -* t@p == 0 -| -* t@p != 0 -) - -@r3 depends on !patch && boolok@ -bool b; -position p1; -@@ -( -*b@p1 = 0 -| -*b@p1 = 1 -) - -@r4 depends on !patch@ -bool b; -position p2; -identifier i; -constant c != {0,1}; -@@ -( - b = i -| -*b@p2 = c -) - -@script:python depends on org@ -p << r1.p; -@@ - -cocci.print_main("WARNING: Comparison to bool",p) - -@script:python depends on org@ -p << r2.p; -@@ - -cocci.print_main("WARNING: Comparison of 0/1 to bool variable",p) - -@script:python depends on org@ -p1 << r3.p1; -@@ - -cocci.print_main("WARNING: Assignment of 0/1 to bool variable",p1) - -@script:python depends on org@ -p2 << r4.p2; -@@ - -cocci.print_main("ERROR: Assignment of non-0/1 constant to bool variable",p2) - -@script:python depends on report@ -p << r1.p; -@@ - -coccilib.report.print_report(p[0],"WARNING: Comparison to bool") - -@script:python depends on report@ -p << r2.p; -@@ - -coccilib.report.print_report(p[0],"WARNING: Comparison of 0/1 to bool variable") - -@script:python depends on report@ -p1 << r3.p1; -@@ - -coccilib.report.print_report(p1[0],"WARNING: Assignment of 0/1 to bool variable") - -@script:python depends on report@ -p2 << r4.p2; -@@ - -coccilib.report.print_report(p2[0],"ERROR: Assignment of non-0/1 constant to bool variable") -- cgit From 5f9ae91f7c0dbbc4195e2a6c8eedcaeb5b9e4cbb Mon Sep 17 00:00:00 2001 From: Andrii Nakryiko Date: Mon, 9 Nov 2020 17:19:30 -0800 Subject: kbuild: Build kernel module BTFs if BTF is enabled and pahole supports it Detect if pahole supports split BTF generation, and generate BTF for each selected kernel module, if it does. This is exposed to Makefiles and C code as CONFIG_DEBUG_INFO_BTF_MODULES flag. Kernel module BTF has to be re-generated if either vmlinux's BTF changes or module's .ko changes. To achieve that, I needed a helper similar to if_changed, but that would allow to filter out vmlinux from the list of updated dependencies for .ko building. I've put it next to the only place that uses and needs it, but it might be a better idea to just add it along the other if_changed variants into scripts/Kbuild.include. Each kernel module's BTF deduplication is pretty fast, as it does only incremental BTF deduplication on top of already deduplicated vmlinux BTF. To show the added build time, I've first ran make only just built kernel (to establish the baseline) and then forced only BTF re-generation, without regenerating .ko files. The build was performed with -j60 parallelization on 56-core machine. The final time also includes bzImage building, so it's not a pure BTF overhead. $ time make -j60 ... make -j60 27.65s user 10.96s system 782% cpu 4.933 total $ touch ~/linux-build/default/vmlinux && time make -j60 ... make -j60 123.69s user 27.85s system 1566% cpu 9.675 total So 4.6 seconds real time, with noticeable part spent in compressed vmlinux and bzImage building. To show size savings, I've built my kernel configuration with about 700 kernel modules with full BTF per each kernel module (without deduplicating against vmlinux) and with split BTF against deduplicated vmlinux (approach in this patch). Below are top 10 modules with biggest BTF sizes. And total size of BTF data across all kernel modules. It shows that split BTF "compresses" 115MB down to 5MB total. And the biggest kernel modules get a downsize from 500-570KB down to 200-300KB. FULL BTF ======== $ for f in $(find . -name '*.ko'); do size -A -d $f | grep BTF | awk '{print $2}'; done | awk '{ s += $1 } END { print s }' 115710691 $ for f in $(find . -name '*.ko'); do printf "%s %d\n" $f $(size -A -d $f | grep BTF | awk '{print $2}'); done | sort -nr -k2 | head -n10 ./drivers/gpu/drm/i915/i915.ko 570570 ./drivers/net/ethernet/mellanox/mlx5/core/mlx5_core.ko 520240 ./drivers/gpu/drm/radeon/radeon.ko 503849 ./drivers/infiniband/hw/mlx5/mlx5_ib.ko 491777 ./fs/xfs/xfs.ko 411544 ./drivers/net/ethernet/intel/i40e/i40e.ko 403904 ./drivers/net/ethernet/broadcom/bnx2x/bnx2x.ko 398754 ./drivers/infiniband/core/ib_core.ko 397224 ./fs/cifs/cifs.ko 386249 ./fs/nfsd/nfsd.ko 379738 SPLIT BTF ========= $ for f in $(find . -name '*.ko'); do size -A -d $f | grep BTF | awk '{print $2}'; done | awk '{ s += $1 } END { print s }' 5194047 $ for f in $(find . -name '*.ko'); do printf "%s %d\n" $f $(size -A -d $f | grep BTF | awk '{print $2}'); done | sort -nr -k2 | head -n10 ./drivers/gpu/drm/i915/i915.ko 293206 ./drivers/gpu/drm/radeon/radeon.ko 282103 ./fs/xfs/xfs.ko 222150 ./drivers/net/ethernet/mellanox/mlx5/core/mlx5_core.ko 198503 ./drivers/infiniband/hw/mlx5/mlx5_ib.ko 198356 ./drivers/net/ethernet/broadcom/bnx2x/bnx2x.ko 113444 ./fs/cifs/cifs.ko 109379 ./arch/x86/kvm/kvm.ko 100225 ./drivers/gpu/drm/drm.ko 94827 ./drivers/infiniband/core/ib_core.ko 91188 Signed-off-by: Andrii Nakryiko Signed-off-by: Alexei Starovoitov Link: https://lore.kernel.org/bpf/20201110011932.3201430-4-andrii@kernel.org --- scripts/Makefile.modfinal | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) (limited to 'scripts') diff --git a/scripts/Makefile.modfinal b/scripts/Makefile.modfinal index ae01baf96f4e..02b892421f7a 100644 --- a/scripts/Makefile.modfinal +++ b/scripts/Makefile.modfinal @@ -6,6 +6,7 @@ PHONY := __modfinal __modfinal: +include include/config/auto.conf include $(srctree)/scripts/Kbuild.include # for c_flags @@ -36,8 +37,23 @@ quiet_cmd_ld_ko_o = LD [M] $@ -T scripts/module.lds -o $@ $(filter %.o, $^); \ $(if $(ARCH_POSTLINK), $(MAKE) -f $(ARCH_POSTLINK) $@, true) -$(modules): %.ko: %.o %.mod.o scripts/module.lds FORCE - +$(call if_changed,ld_ko_o) +quiet_cmd_btf_ko = BTF [M] $@ + cmd_btf_ko = LLVM_OBJCOPY=$(OBJCOPY) $(PAHOLE) -J --btf_base vmlinux $@ + +# Same as newer-prereqs, but allows to exclude specified extra dependencies +newer_prereqs_except = $(filter-out $(PHONY) $(1),$?) + +# Same as if_changed, but allows to exclude specified extra dependencies +if_changed_except = $(if $(call newer_prereqs_except,$(2))$(cmd-check), \ + $(cmd); \ + printf '%s\n' 'cmd_$@ := $(make-cmd)' > $(dot-target).cmd, @:) + +# Re-generate module BTFs if either module's .ko or vmlinux changed +$(modules): %.ko: %.o %.mod.o scripts/module.lds vmlinux FORCE + +$(call if_changed_except,ld_ko_o,vmlinux) +ifdef CONFIG_DEBUG_INFO_BTF_MODULES + +$(if $(newer-prereqs),$(call cmd,btf_ko)) +endif targets += $(modules) $(modules:.ko=.mod.o) -- cgit From ae5b17e464146ddb8fee744fa2150922d6072916 Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Mon, 2 Nov 2020 19:06:37 +0200 Subject: scripts: kernel-doc: Restore anonymous enum parsing The commit d38c8cfb0571 ("scripts: kernel-doc: add support for typedef enum") broke anonymous enum parsing. Restore it by relying on members rather than its name. Fixes: d38c8cfb0571 ("scripts: kernel-doc: add support for typedef enum") Reported-by: kernel test robot Signed-off-by: Andy Shevchenko Reviewed-by: Mauro Carvalho Chehab Cc: Mauro Carvalho Chehab Link: https://lore.kernel.org/r/20201102170637.36138-1-andriy.shevchenko@linux.intel.com Signed-off-by: Jonathan Corbet --- scripts/kernel-doc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'scripts') diff --git a/scripts/kernel-doc b/scripts/kernel-doc index f699cf05d409..9b6ddeb097e9 100755 --- a/scripts/kernel-doc +++ b/scripts/kernel-doc @@ -1390,7 +1390,7 @@ sub dump_enum($$) { $members = $2; } - if ($declaration_name) { + if ($members) { my %_members; $members =~ s/\s+$//; -- cgit From 3f6719c7b62f0327c9091e26d0da10e65668229e Mon Sep 17 00:00:00 2001 From: KP Singh Date: Tue, 17 Nov 2020 23:29:28 +0000 Subject: bpf: Add bpf_bprm_opts_set helper The helper allows modification of certain bits on the linux_binprm struct starting with the secureexec bit which can be updated using the BPF_F_BPRM_SECUREEXEC flag. secureexec can be set by the LSM for privilege gaining executions to set the AT_SECURE auxv for glibc. When set, the dynamic linker disables the use of certain environment variables (like LD_PRELOAD). Signed-off-by: KP Singh Signed-off-by: Daniel Borkmann Acked-by: Martin KaFai Lau Link: https://lore.kernel.org/bpf/20201117232929.2156341-1-kpsingh@chromium.org --- scripts/bpf_helpers_doc.py | 2 ++ 1 file changed, 2 insertions(+) (limited to 'scripts') diff --git a/scripts/bpf_helpers_doc.py b/scripts/bpf_helpers_doc.py index 31484377b8b1..c5bc947a70ad 100755 --- a/scripts/bpf_helpers_doc.py +++ b/scripts/bpf_helpers_doc.py @@ -418,6 +418,7 @@ class PrinterHelpers(Printer): 'struct bpf_tcp_sock', 'struct bpf_tunnel_key', 'struct bpf_xfrm_state', + 'struct linux_binprm', 'struct pt_regs', 'struct sk_reuseport_md', 'struct sockaddr', @@ -465,6 +466,7 @@ class PrinterHelpers(Printer): 'struct bpf_tcp_sock', 'struct bpf_tunnel_key', 'struct bpf_xfrm_state', + 'struct linux_binprm', 'struct pt_regs', 'struct sk_reuseport_md', 'struct sockaddr', -- cgit From c9343637d6b265127dfe37cd7e09eb6feac03032 Mon Sep 17 00:00:00 2001 From: Vasily Gorbik Date: Thu, 12 Nov 2020 15:54:47 +0100 Subject: s390/ftrace: assume -mhotpatch or -mrecord-mcount always available Currently the kernel minimal compiler requirement is gcc 4.9 or clang 10.0.1. * gcc -mhotpatch option is supported since 4.8. * A combination of -pg -mrecord-mcount -mnop-mcount -mfentry flags is supported since gcc 9 and since clang 10. Drop support for old -pg function prologues. Which leaves binary compatible -mhotpatch / -mnop-mcount -mfentry prologues in a form: brcl 0,0 Which are also do not require initial nop optimization / conversion and presence of _mcount symbol. Signed-off-by: Vasily Gorbik Reviewed-by: Heiko Carstens Signed-off-by: Heiko Carstens --- scripts/recordmcount.pl | 3 --- 1 file changed, 3 deletions(-) (limited to 'scripts') diff --git a/scripts/recordmcount.pl b/scripts/recordmcount.pl index 3f77a5d695c1..56c801502b9a 100755 --- a/scripts/recordmcount.pl +++ b/scripts/recordmcount.pl @@ -254,9 +254,6 @@ if ($arch eq "x86_64") { if ($cc =~ /-DCC_USING_HOTPATCH/) { $mcount_regex = "^\\s*([0-9a-fA-F]+):\\s*c0 04 00 00 00 00\\s*brcl\\s*0,[0-9a-f]+ <([^\+]*)>\$"; $mcount_adjust = 0; - } else { - $mcount_regex = "^\\s*([0-9a-fA-F]+):\\s*R_390_(PC|PLT)32DBL\\s+_mcount\\+0x2\$"; - $mcount_adjust = -14; } $alignment = 8; $type = ".quad"; -- cgit From 095fbca0a94930b58f977284ef1b759b98700f8b Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Mon, 26 Oct 2020 23:03:13 +0100 Subject: Makefile.extrawarn: move -Wcast-align to W=3 This warning behaves differently depending on the architecture and compiler. Using x86 gcc, we get no output at all because gcc knows the architecture can handle unaligned accesses. Using x86 clang, or gcc on an architecture that needs to manually deal with unaligned accesses, the build log is completely flooded with these warnings, as they are commonly invoked by inline functions of networking headers, e.g. include/linux/skbuff.h:1426:26: warning: cast increases required alignment of target type [-Wcast-align] The compiler is correct to point this out, as we are dealing with undefined behavior that does cause problems in practice, but there is also no good way to rewrite the code in commonly included headers to a safer method. Signed-off-by: Arnd Bergmann Reviewed-by: Nathan Chancellor Signed-off-by: Masahiro Yamada --- scripts/Makefile.extrawarn | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'scripts') diff --git a/scripts/Makefile.extrawarn b/scripts/Makefile.extrawarn index 95e4cdb94fe9..6baee1200615 100644 --- a/scripts/Makefile.extrawarn +++ b/scripts/Makefile.extrawarn @@ -60,7 +60,6 @@ endif # ifneq ($(findstring 2, $(KBUILD_EXTRA_WARN)),) -KBUILD_CFLAGS += -Wcast-align KBUILD_CFLAGS += -Wdisabled-optimization KBUILD_CFLAGS += -Wnested-externs KBUILD_CFLAGS += -Wshadow @@ -80,6 +79,7 @@ endif ifneq ($(findstring 3, $(KBUILD_EXTRA_WARN)),) KBUILD_CFLAGS += -Wbad-function-cast +KBUILD_CFLAGS += -Wcast-align KBUILD_CFLAGS += -Wcast-qual KBUILD_CFLAGS += -Wconversion KBUILD_CFLAGS += -Wpacked -- cgit From e732b538f4557cd0a856bbce3cde55d2dfef3b03 Mon Sep 17 00:00:00 2001 From: Andrii Nakryiko Date: Fri, 20 Nov 2020 23:08:28 -0800 Subject: kbuild: Skip module BTF generation for out-of-tree external modules In some modes of operation, Kbuild allows to build modules without having vmlinux image around. In such case, generation of module BTF is impossible. This patch changes the behavior to emit a warning about impossibility of generating kernel module BTF, instead of breaking the build. This is especially important for out-of-tree external module builds. In vmlinux-less mode: $ make clean $ make modules_prepare $ touch drivers/acpi/button.c $ make M=drivers/acpi ... CC [M] drivers/acpi/button.o MODPOST drivers/acpi/Module.symvers LD [M] drivers/acpi/button.ko BTF [M] drivers/acpi/button.ko Skipping BTF generation for drivers/acpi/button.ko due to unavailability of vmlinux ... $ readelf -S ~/linux-build/default/drivers/acpi/button.ko | grep BTF -A1 ... empty ... Now with normal build: $ make all ... LD [M] drivers/acpi/button.ko BTF [M] drivers/acpi/button.ko ... $ readelf -S ~/linux-build/default/drivers/acpi/button.ko | grep BTF -A1 [60] .BTF PROGBITS 0000000000000000 00029310 000000000000ab3f 0000000000000000 0 0 1 Fixes: 5f9ae91f7c0d ("kbuild: Build kernel module BTFs if BTF is enabled and pahole supports it") Reported-by: Bruce Allan Signed-off-by: Andrii Nakryiko Signed-off-by: Daniel Borkmann Cc: Jessica Yu Cc: Greg Kroah-Hartman Cc: Masahiro Yamada Link: https://lore.kernel.org/bpf/20201121070829.2612884-1-andrii@kernel.org --- scripts/Makefile.modfinal | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) (limited to 'scripts') diff --git a/scripts/Makefile.modfinal b/scripts/Makefile.modfinal index 02b892421f7a..d49ec001825d 100644 --- a/scripts/Makefile.modfinal +++ b/scripts/Makefile.modfinal @@ -38,7 +38,12 @@ quiet_cmd_ld_ko_o = LD [M] $@ $(if $(ARCH_POSTLINK), $(MAKE) -f $(ARCH_POSTLINK) $@, true) quiet_cmd_btf_ko = BTF [M] $@ - cmd_btf_ko = LLVM_OBJCOPY=$(OBJCOPY) $(PAHOLE) -J --btf_base vmlinux $@ + cmd_btf_ko = \ + if [ -f vmlinux ]; then \ + LLVM_OBJCOPY=$(OBJCOPY) $(PAHOLE) -J --btf_base vmlinux $@; \ + else \ + printf "Skipping BTF generation for %s due to unavailability of vmlinux\n" $@ 1>&2; \ + fi; # Same as newer-prereqs, but allows to exclude specified extra dependencies newer_prereqs_except = $(filter-out $(PHONY) $(1),$?) @@ -49,7 +54,7 @@ if_changed_except = $(if $(call newer_prereqs_except,$(2))$(cmd-check), \ printf '%s\n' 'cmd_$@ := $(make-cmd)' > $(dot-target).cmd, @:) # Re-generate module BTFs if either module's .ko or vmlinux changed -$(modules): %.ko: %.o %.mod.o scripts/module.lds vmlinux FORCE +$(modules): %.ko: %.o %.mod.o scripts/module.lds $(if $(KBUILD_BUILTIN),vmlinux) FORCE +$(call if_changed_except,ld_ko_o,vmlinux) ifdef CONFIG_DEBUG_INFO_BTF_MODULES +$(if $(newer-prereqs),$(call cmd,btf_ko)) -- cgit From 27672f0d280a3f286a410a8db2004f46ace72a17 Mon Sep 17 00:00:00 2001 From: KP Singh Date: Tue, 24 Nov 2020 15:12:09 +0000 Subject: bpf: Add a BPF helper for getting the IMA hash of an inode Provide a wrapper function to get the IMA hash of an inode. This helper is useful in fingerprinting files (e.g executables on execution) and using these fingerprints in detections like an executable unlinking itself. Since the ima_inode_hash can sleep, it's only allowed for sleepable LSM hooks. Signed-off-by: KP Singh Signed-off-by: Daniel Borkmann Acked-by: Yonghong Song Link: https://lore.kernel.org/bpf/20201124151210.1081188-3-kpsingh@chromium.org --- scripts/bpf_helpers_doc.py | 2 ++ 1 file changed, 2 insertions(+) (limited to 'scripts') diff --git a/scripts/bpf_helpers_doc.py b/scripts/bpf_helpers_doc.py index c5bc947a70ad..8b829748d488 100755 --- a/scripts/bpf_helpers_doc.py +++ b/scripts/bpf_helpers_doc.py @@ -436,6 +436,7 @@ class PrinterHelpers(Printer): 'struct xdp_md', 'struct path', 'struct btf_ptr', + 'struct inode', ] known_types = { '...', @@ -480,6 +481,7 @@ class PrinterHelpers(Printer): 'struct task_struct', 'struct path', 'struct btf_ptr', + 'struct inode', } mapped_types = { 'u8': '__u8', -- cgit From d5750cd3c5486e9c0fa11100df01de8ca0c13fa7 Mon Sep 17 00:00:00 2001 From: Nathan Chancellor Date: Thu, 19 Nov 2020 13:46:58 -0700 Subject: kbuild: Disable CONFIG_LD_ORPHAN_WARN for ld.lld 10.0.1 ld.lld 10.0.1 spews a bunch of various warnings about .rela sections, along with a few others. Newer versions of ld.lld do not have these warnings. As a result, do not add '--orphan-handling=warn' to LDFLAGS_vmlinux if ld.lld's version is not new enough. Link: https://github.com/ClangBuiltLinux/linux/issues/1187 Link: https://github.com/ClangBuiltLinux/linux/issues/1193 Reported-by: Arvind Sankar Reported-by: kernelci.org bot Reported-by: Mark Brown Reviewed-by: Kees Cook Signed-off-by: Nathan Chancellor Reviewed-by: Nick Desaulniers Signed-off-by: Masahiro Yamada --- scripts/lld-version.sh | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) create mode 100755 scripts/lld-version.sh (limited to 'scripts') diff --git a/scripts/lld-version.sh b/scripts/lld-version.sh new file mode 100755 index 000000000000..d70edb4d8a4f --- /dev/null +++ b/scripts/lld-version.sh @@ -0,0 +1,20 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0 +# +# Usage: $ ./scripts/lld-version.sh ld.lld +# +# Print the linker version of `ld.lld' in a 5 or 6-digit form +# such as `100001' for ld.lld 10.0.1 etc. + +linker_string="$($* --version)" + +if ! ( echo $linker_string | grep -q LLD ); then + echo 0 + exit 1 +fi + +VERSION=$(echo $linker_string | cut -d ' ' -f 2) +MAJOR=$(echo $VERSION | cut -d . -f 1) +MINOR=$(echo $VERSION | cut -d . -f 2) +PATCHLEVEL=$(echo $VERSION | cut -d . -f 3) +printf "%d%02d%02d\\n" $MAJOR $MINOR $PATCHLEVEL -- cgit From 52a4be3ffc0fe2cc6af779c35525846cda7dea28 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Mon, 30 Nov 2020 16:36:30 +0100 Subject: scripts: get_feat.pl: add a script to handle Documentation/features The Documentation/features contains a set of parseable files. It is not worth converting them to ReST format, as they're useful the way it is. It is, however, interesting to parse them and produce output on different formats: 1) Output the contents of a feature in ReST format; 2) Output what features a given architecture supports; 3) Output a matrix with features x architectures. Signed-off-by: Mauro Carvalho Chehab Link: https://lore.kernel.org/r/8b0c1ad06d689283a6d78c4ccd188a02c3acc0de.1606748711.git.mchehab+huawei@kernel.org Signed-off-by: Jonathan Corbet --- scripts/get_feat.pl | 474 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 474 insertions(+) create mode 100755 scripts/get_feat.pl (limited to 'scripts') diff --git a/scripts/get_feat.pl b/scripts/get_feat.pl new file mode 100755 index 000000000000..79d83595addd --- /dev/null +++ b/scripts/get_feat.pl @@ -0,0 +1,474 @@ +#!/usr/bin/perl +# SPDX-License-Identifier: GPL-2.0 + +use strict; +use Pod::Usage; +use Getopt::Long; +use File::Find; +use Fcntl ':mode'; + +my $help; +my $man; +my $debug; +my $arch; +my $feat; +my $prefix="Documentation/features"; + +GetOptions( + "debug|d+" => \$debug, + "dir=s" => \$prefix, + 'help|?' => \$help, + 'arch=s' => \$arch, + 'feat=s' => \$feat, + man => \$man +) or pod2usage(2); + +pod2usage(1) if $help; +pod2usage(-exitstatus => 0, -verbose => 2) if $man; + +pod2usage(2) if (scalar @ARGV < 1 || @ARGV > 2); + +my ($cmd, $arg) = @ARGV; + +pod2usage(2) if ($cmd ne "current" && $cmd ne "rest" && $cmd ne "validate"); + +require Data::Dumper if ($debug); + +my %data; +my %archs; + +# +# Displays an error message, printing file name and line +# +sub parse_error($$$$) { + my ($file, $ln, $msg, $data) = @_; + + $data =~ s/\s+$/\n/; + + print STDERR "Warning: file $file#$ln:\n\t$msg"; + + if ($data ne "") { + print STDERR ". Line\n\t\t$data"; + } else { + print STDERR "\n"; + } +} + +# +# Parse a features file, storing its contents at %data +# + +my $h_name = "Feature"; +my $h_kconfig = "Kconfig"; +my $h_description = "Description"; +my $h_subsys = "Subsystem"; +my $h_status = "Status"; +my $h_arch = "Architecture"; + +my $max_size_name = length($h_name); +my $max_size_kconfig = length($h_kconfig); +my $max_size_description = length($h_description); +my $max_size_subsys = length($h_subsys); +my $max_size_status = length($h_status); +my $max_size_arch = length($h_arch); + +sub parse_feat { + my $file = $File::Find::name; + + my $mode = (stat($file))[2]; + return if ($mode & S_IFDIR); + return if ($file =~ m,($prefix)/arch-support.txt,); + return if (!($file =~ m,arch-support.txt$,)); + + my $subsys = ""; + $subsys = $2 if ( m,.*($prefix)/([^/]+).*,); + + if (length($subsys) > $max_size_subsys) { + $max_size_subsys = length($subsys); + } + + my $name; + my $kconfig; + my $description; + my $comments = ""; + my $last_status; + my $ln; + my %arch_table; + + print STDERR "Opening $file\n" if ($debug > 1); + open IN, $file; + + while() { + $ln++; + + if (m/^\#\s+Feature\s+name:\s*(.*\S)/) { + $name = $1; + if (length($name) > $max_size_name) { + $max_size_name = length($name); + } + next; + } + if (m/^\#\s+Kconfig:\s*(.*\S)/) { + $kconfig = $1; + if (length($kconfig) > $max_size_kconfig) { + $max_size_kconfig = length($kconfig); + } + next; + } + if (m/^\#\s+description:\s*(.*\S)/) { + $description = $1; + if (length($description) > $max_size_description) { + $max_size_description = length($description); + } + next; + } + next if (m/^\\s*$/); + next if (m/^\s*\-+\s*$/); + next if (m/^\s*\|\s*arch\s*\|\s*status\s*\|\s*$/); + + if (m/^\#\s*(.*)/) { + $comments .= "$1\n"; + next; + } + if (m/^\s*\|\s*(\S+):\s*\|\s*(\S+)\s*\|\s*$/) { + my $a = $1; + my $status = $2; + + if (length($status) > $max_size_status) { + $max_size_status = length($status); + } + if (length($a) > $max_size_arch) { + $max_size_arch = length($a); + } + + $status = "---" if ($status =~ m/^\.\.$/); + + $archs{$a} = 1; + $arch_table{$a} = $status; + next; + } + + #Everything else is an error + parse_error($file, $ln, "line is invalid", $_); + } + close IN; + + if (!$name) { + parse_error($file, $ln, "Feature name not found", ""); + return; + } + + parse_error($file, $ln, "Subsystem not found", "") if (!$subsys); + parse_error($file, $ln, "Kconfig not found", "") if (!$kconfig); + parse_error($file, $ln, "Description not found", "") if (!$description); + + if (!%arch_table) { + parse_error($file, $ln, "Architecture table not found", ""); + return; + } + + $data{$name}->{where} = $file; + $data{$name}->{subsys} = $subsys; + $data{$name}->{kconfig} = $kconfig; + $data{$name}->{description} = $description; + $data{$name}->{comments} = $comments; + $data{$name}->{table} = \%arch_table; +} + +# +# Output feature(s) for a given architecture +# +sub output_arch_table { + my $title = "Feature status on $arch architecture"; + + print "=" x length($title) . "\n"; + print "$title\n"; + print "=" x length($title) . "\n\n"; + + print "=" x $max_size_subsys; + print " "; + print "=" x $max_size_name; + print " "; + print "=" x $max_size_kconfig; + print " "; + print "=" x $max_size_status; + print " "; + print "=" x $max_size_description; + print "\n"; + printf "%-${max_size_subsys}s ", $h_subsys; + printf "%-${max_size_name}s ", $h_name; + printf "%-${max_size_kconfig}s ", $h_kconfig; + printf "%-${max_size_status}s ", $h_status; + printf "%-${max_size_description}s\n", $h_description; + print "=" x $max_size_subsys; + print " "; + print "=" x $max_size_name; + print " "; + print "=" x $max_size_kconfig; + print " "; + print "=" x $max_size_status; + print " "; + print "=" x $max_size_description; + print "\n"; + + foreach my $name (sort { + ($data{$a}->{subsys} cmp $data{$b}->{subsys}) || + ($data{$a}->{name} cmp $data{$b}->{name}) + } keys %data) { + next if ($feat && $name ne $feat); + + my %arch_table = %{$data{$name}->{table}}; + printf "%-${max_size_subsys}s ", $data{$name}->{subsys}; + printf "%-${max_size_name}s ", $name; + printf "%-${max_size_kconfig}s ", $data{$name}->{kconfig}; + printf "%-${max_size_status}s ", $arch_table{$arch}; + printf "%-${max_size_description}s\n", $data{$name}->{description}; + } + + print "=" x $max_size_subsys; + print " "; + print "=" x $max_size_name; + print " "; + print "=" x $max_size_kconfig; + print " "; + print "=" x $max_size_status; + print " "; + print "=" x $max_size_description; + print "\n"; +} + +# +# Output a feature on all architectures +# +sub output_feature { + my $title = "Feature $feat"; + + print "=" x length($title) . "\n"; + print "$title\n"; + print "=" x length($title) . "\n\n"; + + print ":Subsystem: $data{$feat}->{subsys} \n" if ($data{$feat}->{subsys}); + print ":Kconfig: $data{$feat}->{kconfig} \n" if ($data{$feat}->{kconfig}); + + my $desc = $data{$feat}->{description}; + $desc =~ s/^([a-z])/\U$1/; + $desc =~ s/\.?\s*//; + print "\n$desc.\n\n"; + + my $com = $data{$feat}->{comments}; + $com =~ s/^\s+//; + $com =~ s/\s+$//; + if ($com) { + print "Comments\n"; + print "--------\n\n"; + print "$com\n\n"; + } + + print "=" x $max_size_arch; + print " "; + print "=" x $max_size_status; + print "\n"; + + printf "%-${max_size_arch}s ", $h_arch; + printf "%-${max_size_status}s", $h_status . "\n"; + + print "=" x $max_size_arch; + print " "; + print "=" x $max_size_status; + print "\n"; + + my %arch_table = %{$data{$feat}->{table}}; + foreach my $arch (sort keys %arch_table) { + printf "%-${max_size_arch}s ", $arch; + printf "%-${max_size_status}s\n", $arch_table{$arch}; + } + + print "=" x $max_size_arch; + print " "; + print "=" x $max_size_status; + print "\n"; +} + +# +# Output all features for all architectures +# + +sub matrix_lines { + print "=" x $max_size_subsys; + print " "; + print "=" x $max_size_name; + print " "; + + foreach my $arch (sort keys %archs) { + my $len = $max_size_status; + + $len = length($arch) if ($len < length($arch)); + + print "=" x $len; + print " "; + } + print "=" x $max_size_kconfig; + print " "; + print "=" x $max_size_description; + print "\n"; +} + +sub output_matrix { + + my $title = "Feature List (feature x architecture)"; + + print "=" x length($title) . "\n"; + print "$title\n"; + print "=" x length($title) . "\n\n"; + + matrix_lines; + + printf "%-${max_size_subsys}s ", $h_subsys; + printf "%-${max_size_name}s ", $h_name; + + foreach my $arch (sort keys %archs) { + printf "%-${max_size_status}s ", $arch; + } + printf "%-${max_size_kconfig}s ", $h_kconfig; + printf "%-${max_size_description}s\n", $h_description; + + matrix_lines; + + foreach my $name (sort { + ($data{$a}->{subsys} cmp $data{$b}->{subsys}) || + ($data{$a}->{name} cmp $data{$b}->{name}) + } keys %data) { + printf "%-${max_size_subsys}s ", $data{$name}->{subsys}; + printf "%-${max_size_name}s ", $name; + + my %arch_table = %{$data{$name}->{table}}; + + foreach my $arch (sort keys %arch_table) { + my $len = $max_size_status; + + $len = length($arch) if ($len < length($arch)); + + printf "%-${len}s ", $arch_table{$arch}; + } + printf "%-${max_size_kconfig}s ", $data{$name}->{kconfig}; + printf "%-${max_size_description}s\n", $data{$name}->{description}; + } + + matrix_lines; +} + + +# +# Parses all feature files located at $prefix dir +# +find({wanted =>\&parse_feat, no_chdir => 1}, $prefix); + +print STDERR Data::Dumper->Dump([\%data], [qw(*data)]) if ($debug); + +# +# Handles the command +# +if ($cmd eq "current") { + $arch = qx(uname -m | sed 's/x86_64/x86/' | sed 's/i386/x86/'); + $arch =~s/\s+$//; +} + +if ($cmd ne "validate") { + if ($arch) { + output_arch_table; + } elsif ($feat) { + output_feature; + } else { + output_matrix; + } +} + +__END__ + +=head1 NAME + +get_feat.pl - parse the Linux Feature files and produce a ReST book. + +=head1 SYNOPSIS + +B [--debug] [--man] [--help] [--dir=] + [--arch=] [--feat=] [] + +Where can be: + +=over 8 + +B - output features for this machine's architecture + +B - output features in ReST markup language + +B - validate the feature contents + +=back + +=head1 OPTIONS + +=over 8 + +=item B<--arch> + +Output features for an specific architecture, optionally filtering for +a single specific feature. + +=item B<--feat> + +Output features for a single specific architecture. + +=item B<--dir> + +Changes the location of the Feature files. By default, it uses +the Documentation/features directory. + +=item B<--debug> + +Put the script in verbose mode, useful for debugging. Can be called multiple +times, to increase verbosity. + +=item B<--help> + +Prints a brief help message and exits. + +=item B<--man> + +Prints the manual page and exits. + +=back + +=head1 DESCRIPTION + +Parse the Linux feature files from Documentation/features (by default), +optionally producing results at ReST format. + +It supports output data per architecture, per feature or a +feature x arch matrix. + +When used with B command, it will use either one of the tree formats: + +If neither B<--arch> or B<--feature> arguments are used, it will output a +matrix with features per architecture. + +If B<--arch> argument is used, it will output the features availability for +a given architecture. + +If B<--feat> argument is used, it will output the content of the feature +file using ReStructured Text markup. + +=head1 BUGS + +Report bugs to Mauro Carvalho Chehab + +=head1 COPYRIGHT + +Copyright (c) 2019 by Mauro Carvalho Chehab . + +License GPLv2: GNU GPL version 2 . + +This is free software: you are free to change and redistribute it. +There is NO WARRANTY, to the extent permitted by law. + +=cut -- cgit From ba813f7c2dc894eebcb3f8a66c0e9e26e53a4923 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Mon, 30 Nov 2020 16:36:31 +0100 Subject: scripts: get_feat.pl: improve matrix output Instead of producing a too wide table, let's split it per subsystem, and use a better notation in order to make easier for the reader to identify how a feature is supported on multiple architectures. Signed-off-by: Mauro Carvalho Chehab Link: https://lore.kernel.org/r/9c3e8c813e8146c5c30e10fa75974f8fbfe6016a.1606748711.git.mchehab+huawei@kernel.org Signed-off-by: Jonathan Corbet --- scripts/get_feat.pl | 113 ++++++++++++++++++++++++++++++++-------------------- 1 file changed, 70 insertions(+), 43 deletions(-) (limited to 'scripts') diff --git a/scripts/get_feat.pl b/scripts/get_feat.pl index 79d83595addd..7b92ebab7ddd 100755 --- a/scripts/get_feat.pl +++ b/scripts/get_feat.pl @@ -293,68 +293,95 @@ sub output_feature { # Output all features for all architectures # -sub matrix_lines { - print "=" x $max_size_subsys; - print " "; - print "=" x $max_size_name; - print " "; - - foreach my $arch (sort keys %archs) { - my $len = $max_size_status; - - $len = length($arch) if ($len < length($arch)); +sub matrix_lines($$) { + my $partial = shift; + my $header = shift; + my $split; + my $fill; + my $ln_marker; + + if ($header) { + $ln_marker = "="; + } else { + $ln_marker = "-"; + } - print "=" x $len; - print " "; + if ($partial) { + $split = "|"; + $fill = " "; + } else { + $split = "+"; + $fill = $ln_marker; } - print "=" x $max_size_kconfig; - print " "; - print "=" x $max_size_description; - print "\n"; + + print $split; + print $fill x $max_size_name; + print $split; + print $fill x $max_size_kconfig; + print $split; + print $fill x $max_size_description; + print "+"; + print $ln_marker x $max_size_arch; + print "+"; + print $ln_marker x $max_size_status; + print "+\n"; } sub output_matrix { - - my $title = "Feature List (feature x architecture)"; + my $title = "Feature status on all architectures"; print "=" x length($title) . "\n"; print "$title\n"; print "=" x length($title) . "\n\n"; - matrix_lines; - - printf "%-${max_size_subsys}s ", $h_subsys; - printf "%-${max_size_name}s ", $h_name; + my $cur_subsys = ""; + foreach my $name (sort { + ($data{$a}->{subsys} cmp $data{$b}->{subsys}) or + ($a cmp $b) + } keys %data) { - foreach my $arch (sort keys %archs) { - printf "%-${max_size_status}s ", $arch; - } - printf "%-${max_size_kconfig}s ", $h_kconfig; - printf "%-${max_size_description}s\n", $h_description; + if ($cur_subsys ne $data{$name}->{subsys}) { + if ($cur_subsys ne "") { + printf "\n"; + } - matrix_lines; + $cur_subsys = $data{$name}->{subsys}; - foreach my $name (sort { - ($data{$a}->{subsys} cmp $data{$b}->{subsys}) || - ($data{$a}->{name} cmp $data{$b}->{name}) - } keys %data) { - printf "%-${max_size_subsys}s ", $data{$name}->{subsys}; - printf "%-${max_size_name}s ", $name; + my $title = "Subsystem: $cur_subsys"; + print "$title\n"; + print "=" x length($title) . "\n\n"; - my %arch_table = %{$data{$name}->{table}}; + matrix_lines(0, 0); + printf "|%-${max_size_name}s", $h_name; + printf "|%-${max_size_kconfig}s", $h_kconfig; + printf "|%-${max_size_description}s", $h_description; - foreach my $arch (sort keys %arch_table) { - my $len = $max_size_status; + printf "|%-${max_size_arch}s", $h_arch; + printf "|%-${max_size_status}s|\n", $h_status; - $len = length($arch) if ($len < length($arch)); + matrix_lines(0, 1); + } - printf "%-${len}s ", $arch_table{$arch}; + my %arch_table = %{$data{$name}->{table}}; + my $first = 1; + foreach my $arch (sort keys %arch_table) { + if ($first) { + printf "|%-${max_size_name}s", $name; + printf "|%-${max_size_kconfig}s", $data{$name}->{kconfig}; + printf "|%-${max_size_description}s", $data{$name}->{description}; + $first = 0; + } else { + matrix_lines(1, 0); + + printf "|%-${max_size_name}s", ""; + printf "|%-${max_size_kconfig}s", ""; + printf "|%-${max_size_description}s", ""; + } + printf "|%-${max_size_arch}s", $arch; + printf "|%-${max_size_status}s|\n", $arch_table{$arch}; } - printf "%-${max_size_kconfig}s ", $data{$name}->{kconfig}; - printf "%-${max_size_description}s\n", $data{$name}->{description}; + matrix_lines(0, 0); } - - matrix_lines; } -- cgit From ca908577790fd0dc3070813b752d7eb7f74e609f Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Mon, 30 Nov 2020 16:36:32 +0100 Subject: scripts: get_feat.pl: use its implementation for list-arch.sh Add support for the same output format as the bash script, and use its implementation instead of the previous one. I opted to do such patch in order to have a single script responsible for parsing Documentation/features and produce different outputs. As someone may rely on the past format, which is easy to parse it, get_feat.pl now gains a new command with the same output format as the previous script. As a side effect, the perl script is a lot faster, as it reads each file only once, instead of parsing files several times via a for command and grep commands inside it. This patch also changes the features list order to be case-insensitive, in order to better match the output of the existing script. Signed-off-by: Mauro Carvalho Chehab Link: https://lore.kernel.org/r/a97f49677805ad4e6b982d02c0db8c9dfbbd20a6.1606748711.git.mchehab+huawei@kernel.org Signed-off-by: Jonathan Corbet --- scripts/get_feat.pl | 77 ++++++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 64 insertions(+), 13 deletions(-) (limited to 'scripts') diff --git a/scripts/get_feat.pl b/scripts/get_feat.pl index 7b92ebab7ddd..81d1b78d65c9 100755 --- a/scripts/get_feat.pl +++ b/scripts/get_feat.pl @@ -6,13 +6,18 @@ use Pod::Usage; use Getopt::Long; use File::Find; use Fcntl ':mode'; +use Cwd 'abs_path'; my $help; my $man; my $debug; my $arch; my $feat; -my $prefix="Documentation/features"; + +my $basename = abs_path($0); +$basename =~ s,/[^/]+$,/,; + +my $prefix=$basename . "../Documentation/features"; GetOptions( "debug|d+" => \$debug, @@ -20,17 +25,19 @@ GetOptions( 'help|?' => \$help, 'arch=s' => \$arch, 'feat=s' => \$feat, + 'feature=s' => \$feat, man => \$man ) or pod2usage(2); pod2usage(1) if $help; pod2usage(-exitstatus => 0, -verbose => 2) if $man; -pod2usage(2) if (scalar @ARGV < 1 || @ARGV > 2); +pod2usage(1) if (scalar @ARGV < 1 || @ARGV > 2); my ($cmd, $arg) = @ARGV; -pod2usage(2) if ($cmd ne "current" && $cmd ne "rest" && $cmd ne "validate"); +pod2usage(2) if ($cmd ne "current" && $cmd ne "rest" && $cmd ne "validate" + && $cmd ne "ls" && $cmd ne "list"); require Data::Dumper if ($debug); @@ -213,7 +220,7 @@ sub output_arch_table { foreach my $name (sort { ($data{$a}->{subsys} cmp $data{$b}->{subsys}) || - ($data{$a}->{name} cmp $data{$b}->{name}) + ("\L$a" cmp "\L$b") } keys %data) { next if ($feat && $name ne $feat); @@ -222,7 +229,7 @@ sub output_arch_table { printf "%-${max_size_name}s ", $name; printf "%-${max_size_kconfig}s ", $data{$name}->{kconfig}; printf "%-${max_size_status}s ", $arch_table{$arch}; - printf "%-${max_size_description}s\n", $data{$name}->{description}; + printf "%-s\n", $data{$name}->{description}; } print "=" x $max_size_subsys; @@ -237,6 +244,31 @@ sub output_arch_table { print "\n"; } +# +# list feature(s) for a given architecture +# +sub list_arch_features { + print "#\n# Kernel feature support matrix of the '$arch' architecture:\n#\n"; + + foreach my $name (sort { + ($data{$a}->{subsys} cmp $data{$b}->{subsys}) || + ("\L$a" cmp "\L$b") + } keys %data) { + next if ($feat && $name ne $feat); + + my %arch_table = %{$data{$name}->{table}}; + + my $status = $arch_table{$arch}; + $status = " " x ((4 - length($status)) / 2) . $status; + + printf " %${max_size_subsys}s/ ", $data{$name}->{subsys}; + printf "%-${max_size_name}s: ", $name; + printf "%-5s| ", $status; + printf "%${max_size_kconfig}s # ", $data{$name}->{kconfig}; + printf " %s\n", $data{$name}->{description}; + } +} + # # Output a feature on all architectures # @@ -337,7 +369,7 @@ sub output_matrix { my $cur_subsys = ""; foreach my $name (sort { ($data{$a}->{subsys} cmp $data{$b}->{subsys}) or - ($a cmp $b) + ("\L$a" cmp "\L$b") } keys %data) { if ($cur_subsys ne $data{$name}->{subsys}) { @@ -400,6 +432,17 @@ if ($cmd eq "current") { $arch =~s/\s+$//; } +if ($cmd eq "ls" or $cmd eq "list") { + if (!$arch) { + $arch = qx(uname -m | sed 's/x86_64/x86/' | sed 's/i386/x86/'); + $arch =~s/\s+$//; + } + + list_arch_features; + + exit; +} + if ($cmd ne "validate") { if ($arch) { output_arch_table; @@ -418,18 +461,26 @@ get_feat.pl - parse the Linux Feature files and produce a ReST book. =head1 SYNOPSIS -B [--debug] [--man] [--help] [--dir=] - [--arch=] [--feat=] [] +B [--debug] [--man] [--help] [--dir=] [--arch=] + [--feature=|--feat=] [] Where can be: =over 8 -B - output features for this machine's architecture +B - output table in ReST compatible ASCII format + with features for this machine's architecture + +B - output table(s) in ReST compatible ASCII format + with features in ReST markup language. The output + is affected by --arch or --feat/--feature flags. -B - output features in ReST markup language +B - validate the contents of the files under + Documentation/features. -B - validate the feature contents +B or B - list features for this machine's architecture, + using an easier to parse format. + The output is affected by --arch flag. =back @@ -442,9 +493,9 @@ B - validate the feature contents Output features for an specific architecture, optionally filtering for a single specific feature. -=item B<--feat> +=item B<--feat> or B<--feature> -Output features for a single specific architecture. +Output features for a single specific feature. =item B<--dir> -- cgit From 7d2c6b1edf790d96e9017a0b27be2425e1af1532 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Wed, 2 Dec 2020 09:17:32 +0100 Subject: scripts: kernel-doc: fix parsing function-like typedefs Changeset 6b80975c6308 ("scripts: kernel-doc: fix typedef parsing") added support for things like: typedef unsigned long foo(); However, it caused a regression on this prototype: typedef bool v4l2_check_dv_timings_fnc(const struct v4l2_dv_timings *t, void *handle); This is only noticed after adding a patch that checks if the kernel-doc identifier matches the typedef: ./scripts/kernel-doc -none $(git grep '^.. kernel-doc::' Documentation/ |cut -d ' ' -f 3|sort|uniq) 2>&1|grep expecting include/media/v4l2-dv-timings.h:38: warning: expecting prototype for typedef v4l2_check_dv_timings_fnc. Prototype was for typedef nc instead The problem is that, with the new parsing logic, it is not checking for complete words at the type part. Fix it by adding a \b at the end of each type word at the regex. fixes: 6b80975c6308 ("scripts: kernel-doc: fix typedef parsing") Signed-off-by: Mauro Carvalho Chehab Link: https://lore.kernel.org/r/218ff56dcb8e73755005d3fb64586eb1841a276b.1606896997.git.mchehab+huawei@kernel.org Signed-off-by: Jonathan Corbet --- scripts/kernel-doc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'scripts') diff --git a/scripts/kernel-doc b/scripts/kernel-doc index 9b6ddeb097e9..6325bec3f66f 100755 --- a/scripts/kernel-doc +++ b/scripts/kernel-doc @@ -1431,7 +1431,7 @@ sub dump_enum($$) { } } -my $typedef_type = qr { ((?:\s+[\w\*]+){1,8})\s* }x; +my $typedef_type = qr { ((?:\s+[\w\*]+\b){1,8})\s* }x; my $typedef_ident = qr { \*?\s*(\w\S+)\s* }x; my $typedef_args = qr { \s*\((.*)\); }x; -- cgit From 7de3697e9cbd4bd3d62bafa249d57990e1b8f294 Mon Sep 17 00:00:00 2001 From: Dave Ertman Date: Wed, 2 Dec 2020 16:54:24 -0800 Subject: Add auxiliary bus support Add support for the Auxiliary Bus, auxiliary_device and auxiliary_driver. It enables drivers to create an auxiliary_device and bind an auxiliary_driver to it. The bus supports probe/remove shutdown and suspend/resume callbacks. Each auxiliary_device has a unique string based id; driver binds to an auxiliary_device based on this id through the bus. Co-developed-by: Kiran Patil Co-developed-by: Ranjani Sridharan Co-developed-by: Fred Oh Co-developed-by: Leon Romanovsky Signed-off-by: Kiran Patil Signed-off-by: Ranjani Sridharan Signed-off-by: Fred Oh Signed-off-by: Leon Romanovsky Signed-off-by: Dave Ertman Reviewed-by: Pierre-Louis Bossart Reviewed-by: Shiraz Saleem Reviewed-by: Parav Pandit Reviewed-by: Dan Williams Reviewed-by: Martin Habets Link: https://lore.kernel.org/r/20201113161859.1775473-2-david.m.ertman@intel.com Signed-off-by: Dan Williams Link: https://lore.kernel.org/r/160695681289.505290.8978295443574440604.stgit@dwillia2-desk3.amr.corp.intel.com Signed-off-by: Greg Kroah-Hartman --- scripts/mod/devicetable-offsets.c | 3 +++ scripts/mod/file2alias.c | 8 ++++++++ 2 files changed, 11 insertions(+) (limited to 'scripts') diff --git a/scripts/mod/devicetable-offsets.c b/scripts/mod/devicetable-offsets.c index 27007c18e754..e377f52dbfa3 100644 --- a/scripts/mod/devicetable-offsets.c +++ b/scripts/mod/devicetable-offsets.c @@ -243,5 +243,8 @@ int main(void) DEVID(mhi_device_id); DEVID_FIELD(mhi_device_id, chan); + DEVID(auxiliary_device_id); + DEVID_FIELD(auxiliary_device_id, name); + return 0; } diff --git a/scripts/mod/file2alias.c b/scripts/mod/file2alias.c index 2417dd1dee33..fb4827027536 100644 --- a/scripts/mod/file2alias.c +++ b/scripts/mod/file2alias.c @@ -1364,6 +1364,13 @@ static int do_mhi_entry(const char *filename, void *symval, char *alias) { DEF_FIELD_ADDR(symval, mhi_device_id, chan); sprintf(alias, MHI_DEVICE_MODALIAS_FMT, *chan); + return 1; +} + +static int do_auxiliary_entry(const char *filename, void *symval, char *alias) +{ + DEF_FIELD_ADDR(symval, auxiliary_device_id, name); + sprintf(alias, AUXILIARY_MODULE_PREFIX "%s", *name); return 1; } @@ -1442,6 +1449,7 @@ static const struct devtable devtable[] = { {"tee", SIZE_tee_client_device_id, do_tee_entry}, {"wmi", SIZE_wmi_device_id, do_wmi_entry}, {"mhi", SIZE_mhi_device_id, do_mhi_entry}, + {"auxiliary", SIZE_auxiliary_device_id, do_auxiliary_entry}, }; /* Create MODULE_ALIAS() statements. -- cgit From 4f19cab76136e800a3f04d8c9aa4d8e770e3d3d8 Mon Sep 17 00:00:00 2001 From: Florent Revest Date: Fri, 4 Dec 2020 12:36:05 +0100 Subject: bpf: Add a bpf_sock_from_file helper While eBPF programs can check whether a file is a socket by file->f_op == &socket_file_ops, they cannot convert the void private_data pointer to a struct socket BTF pointer. In order to do this a new helper wrapping sock_from_file is added. This is useful to tracing programs but also other program types inheriting this set of helpers such as iterators or LSM programs. Signed-off-by: Florent Revest Signed-off-by: Daniel Borkmann Acked-by: KP Singh Acked-by: Martin KaFai Lau Link: https://lore.kernel.org/bpf/20201204113609.1850150-2-revest@google.com --- scripts/bpf_helpers_doc.py | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'scripts') diff --git a/scripts/bpf_helpers_doc.py b/scripts/bpf_helpers_doc.py index 8b829748d488..867ada23281c 100755 --- a/scripts/bpf_helpers_doc.py +++ b/scripts/bpf_helpers_doc.py @@ -437,6 +437,8 @@ class PrinterHelpers(Printer): 'struct path', 'struct btf_ptr', 'struct inode', + 'struct socket', + 'struct file', ] known_types = { '...', @@ -482,6 +484,8 @@ class PrinterHelpers(Printer): 'struct path', 'struct btf_ptr', 'struct inode', + 'struct socket', + 'struct file', } mapped_types = { 'u8': '__u8', -- cgit From dbb9090232936c08510b7d028b8a6e03b4716154 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Fri, 4 Dec 2020 16:32:28 +0100 Subject: scripts: get_feat.pl: make complete table more coincise Currently, there are too many white spaces at the tables, and the information is very sparsed on it. Make the format a lot more compact. Suggested-by: Jonathan Corbet Signed-off-by: Mauro Carvalho Chehab Link: https://lore.kernel.org/r/8165ff379313e63a69898db19d790e4436224ffd.1607095090.git.mchehab+huawei@kernel.org Signed-off-by: Jonathan Corbet --- scripts/get_feat.pl | 105 ++++++++++++++++++++++++++++++++++------------------ 1 file changed, 68 insertions(+), 37 deletions(-) (limited to 'scripts') diff --git a/scripts/get_feat.pl b/scripts/get_feat.pl index 81d1b78d65c9..10bf23fbc9c5 100755 --- a/scripts/get_feat.pl +++ b/scripts/get_feat.pl @@ -325,10 +325,10 @@ sub output_feature { # Output all features for all architectures # -sub matrix_lines($$) { - my $partial = shift; +sub matrix_lines($$$) { + my $desc_size = shift; + my $status_size = shift; my $header = shift; - my $split; my $fill; my $ln_marker; @@ -338,24 +338,14 @@ sub matrix_lines($$) { $ln_marker = "-"; } - if ($partial) { - $split = "|"; - $fill = " "; - } else { - $split = "+"; - $fill = $ln_marker; - } + $fill = $ln_marker; - print $split; + print "+"; print $fill x $max_size_name; - print $split; - print $fill x $max_size_kconfig; - print $split; - print $fill x $max_size_description; print "+"; - print $ln_marker x $max_size_arch; + print $fill x $desc_size; print "+"; - print $ln_marker x $max_size_status; + print $ln_marker x $status_size; print "+\n"; } @@ -366,6 +356,14 @@ sub output_matrix { print "$title\n"; print "=" x length($title) . "\n\n"; + my $desc_title = "$h_kconfig / $h_description"; + + my $desc_size = $max_size_kconfig + 4; + $desc_size = $max_size_description if ($max_size_description > $desc_size); + $desc_size = length($desc_title) if (length($desc_title) > $desc_size); + + my $status_size = 60; + my $cur_subsys = ""; foreach my $name (sort { ($data{$a}->{subsys} cmp $data{$b}->{subsys}) or @@ -383,36 +381,69 @@ sub output_matrix { print "$title\n"; print "=" x length($title) . "\n\n"; - matrix_lines(0, 0); - printf "|%-${max_size_name}s", $h_name; - printf "|%-${max_size_kconfig}s", $h_kconfig; - printf "|%-${max_size_description}s", $h_description; - printf "|%-${max_size_arch}s", $h_arch; - printf "|%-${max_size_status}s|\n", $h_status; + matrix_lines($desc_size, $status_size, 0); + + printf "|%-${max_size_name}s", $h_name; + printf "|%-${desc_size}s", $desc_title; - matrix_lines(0, 1); + printf "|%-${status_size}s|\n", "Status per architecture"; + matrix_lines($desc_size, $status_size, 1); } my %arch_table = %{$data{$name}->{table}}; - my $first = 1; - foreach my $arch (sort keys %arch_table) { - if ($first) { - printf "|%-${max_size_name}s", $name; - printf "|%-${max_size_kconfig}s", $data{$name}->{kconfig}; - printf "|%-${max_size_description}s", $data{$name}->{description}; - $first = 0; + my $cur_status = ""; + + my @lines; + my $line = ""; + foreach my $arch (sort { + ($arch_table{$a} cmp $arch_table{$b}) or + ("\L$a" cmp "\L$b") + } keys %arch_table) { + + my $status = $arch_table{$arch}; + + if ($status eq "---") { + $status = "Not compatible"; + } + + if ($status ne $cur_status) { + if ($line ne "") { + push @lines, $line; + $line = ""; + } + $line = "- **" . $status . "**: " . $arch; + } elsif (length($line) + length ($arch) + 2 < $status_size) { + $line .= ", " . $arch; } else { - matrix_lines(1, 0); + push @lines, $line; + $line = " " . $arch; + } + $cur_status = $status; + } + push @lines, $line if ($line ne ""); + + # Ensure that description will be printed + push @lines, "" while (scalar(@lines) < 2); + my $ln = 0; + for my $line(@lines) { + if (!$ln) { + printf "|%-${max_size_name}s", $name; + printf "|%-${desc_size}s", "``" . $data{$name}->{kconfig} . "``"; + } elsif ($ln == 2) { + printf "|%-${max_size_name}s", ""; + printf "|%-${desc_size}s", $data{$name}->{description}; + } else { printf "|%-${max_size_name}s", ""; - printf "|%-${max_size_kconfig}s", ""; - printf "|%-${max_size_description}s", ""; + printf "|%-${desc_size}s", ""; } - printf "|%-${max_size_arch}s", $arch; - printf "|%-${max_size_status}s|\n", $arch_table{$arch}; + + printf "|%-${status_size}s|\n", $line; + + $ln++; } - matrix_lines(0, 0); + matrix_lines($desc_size, $status_size, 0); } } -- cgit From 4fa32f8702891713fcd8ae807da4bab862812c94 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Fri, 4 Dec 2020 16:32:29 +0100 Subject: scripts: get_feat.pl: change the group by order Right now, arch compatibility is grouped by status at the alphabetical order from A to Z, and then from a to z, e. g:. --- TODO ok Revert the order, in order to print first the OK results, then TODO, and, finally, the not compatible ones. Signed-off-by: Mauro Carvalho Chehab Link: https://lore.kernel.org/r/46d53d138eab8e4a55124323ceb5b212c6eedd08.1607095090.git.mchehab+huawei@kernel.org Signed-off-by: Jonathan Corbet --- scripts/get_feat.pl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'scripts') diff --git a/scripts/get_feat.pl b/scripts/get_feat.pl index 10bf23fbc9c5..3f73c8534059 100755 --- a/scripts/get_feat.pl +++ b/scripts/get_feat.pl @@ -397,7 +397,7 @@ sub output_matrix { my @lines; my $line = ""; foreach my $arch (sort { - ($arch_table{$a} cmp $arch_table{$b}) or + ($arch_table{$b} cmp $arch_table{$a}) or ("\L$a" cmp "\L$b") } keys %arch_table) { -- cgit From f5889e70b9ccd25f1f140c372eaa7ded9819c102 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Fri, 4 Dec 2020 16:32:30 +0100 Subject: scripts: get_feat.pl: reduce table width for all features output Auto-adjust the table columns width to better fit under terminals, by breaking the description on multiple lines and auto-estimating the minimal size for the per-architecture status. Signed-off-by: Mauro Carvalho Chehab Link: https://lore.kernel.org/r/9d39ac3fd51f1360aecc328c01558be88a1d6930.1607095090.git.mchehab+huawei@kernel.org Signed-off-by: Jonathan Corbet --- scripts/get_feat.pl | 71 ++++++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 59 insertions(+), 12 deletions(-) (limited to 'scripts') diff --git a/scripts/get_feat.pl b/scripts/get_feat.pl index 3f73c8534059..457712355676 100755 --- a/scripts/get_feat.pl +++ b/scripts/get_feat.pl @@ -19,6 +19,11 @@ $basename =~ s,/[^/]+$,/,; my $prefix=$basename . "../Documentation/features"; +# Used only at for full features output. The script will auto-adjust +# such values for the minimal possible values +my $status_size = 1; +my $description_size = 1; + GetOptions( "debug|d+" => \$debug, "dir=s" => \$prefix, @@ -77,7 +82,10 @@ my $max_size_kconfig = length($h_kconfig); my $max_size_description = length($h_description); my $max_size_subsys = length($h_subsys); my $max_size_status = length($h_status); -my $max_size_arch = length($h_arch); + +my $max_size_arch = 0; +my $max_size_arch_with_header; +my $max_description_word = 0; sub parse_feat { my $file = $File::Find::name; @@ -127,6 +135,13 @@ sub parse_feat { if (length($description) > $max_size_description) { $max_size_description = length($description); } + + foreach my $word (split /\s+/, $description) { + if (length($word) > $max_description_word) { + $max_description_word = length($word); + } + } + next; } next if (m/^\\s*$/); @@ -180,6 +195,8 @@ sub parse_feat { $data{$name}->{description} = $description; $data{$name}->{comments} = $comments; $data{$name}->{table} = \%arch_table; + + $max_size_arch_with_header = $max_size_arch + length($h_arch); } # @@ -296,7 +313,7 @@ sub output_feature { print "$com\n\n"; } - print "=" x $max_size_arch; + print "=" x $max_size_arch_with_header; print " "; print "=" x $max_size_status; print "\n"; @@ -304,7 +321,7 @@ sub output_feature { printf "%-${max_size_arch}s ", $h_arch; printf "%-${max_size_status}s", $h_status . "\n"; - print "=" x $max_size_arch; + print "=" x $max_size_arch_with_header; print " "; print "=" x $max_size_status; print "\n"; @@ -315,7 +332,7 @@ sub output_feature { printf "%-${max_size_status}s\n", $arch_table{$arch}; } - print "=" x $max_size_arch; + print "=" x $max_size_arch_with_header; print " "; print "=" x $max_size_status; print "\n"; @@ -351,6 +368,7 @@ sub matrix_lines($$$) { sub output_matrix { my $title = "Feature status on all architectures"; + my $notcompat = "Not compatible"; print "=" x length($title) . "\n"; print "$title\n"; @@ -359,10 +377,21 @@ sub output_matrix { my $desc_title = "$h_kconfig / $h_description"; my $desc_size = $max_size_kconfig + 4; - $desc_size = $max_size_description if ($max_size_description > $desc_size); + if (!$description_size) { + $desc_size = $max_size_description if ($max_size_description > $desc_size); + } else { + $desc_size = $description_size if ($description_size > $desc_size); + } + $desc_size = $max_description_word if ($max_description_word > $desc_size); + $desc_size = length($desc_title) if (length($desc_title) > $desc_size); - my $status_size = 60; + $max_size_status = length($notcompat) if (length($notcompat) > $max_size_status); + + # Ensure that the status will fit + my $min_status_size = $max_size_status + $max_size_arch + 6; + $status_size = $min_status_size if ($status_size < $min_status_size); + my $cur_subsys = ""; foreach my $name (sort { @@ -394,7 +423,7 @@ sub output_matrix { my %arch_table = %{$data{$name}->{table}}; my $cur_status = ""; - my @lines; + my (@lines, @descs); my $line = ""; foreach my $arch (sort { ($arch_table{$b} cmp $arch_table{$a}) or @@ -404,7 +433,7 @@ sub output_matrix { my $status = $arch_table{$arch}; if ($status eq "---") { - $status = "Not compatible"; + $status = $notcompat; } if ($status ne $cur_status) { @@ -423,17 +452,35 @@ sub output_matrix { } push @lines, $line if ($line ne ""); - # Ensure that description will be printed - push @lines, "" while (scalar(@lines) < 2); + my $description = $data{$name}->{description}; + while (length($description) > $desc_size) { + my $d = substr $description, 0, $desc_size; + + # Ensure that it will end on a space + # if it can't, it means that the size is too small + # Instead of aborting it, let's print what we have + if (!($d =~ s/^(.*)\s+.*/$1/)) { + $d = substr $d, 0, -1; + push @descs, "$d\\"; + $description =~ s/^\Q$d\E//; + } else { + push @descs, $d; + $description =~ s/^\Q$d\E\s+//; + } + } + push @descs, $description; + + # Ensure that the full description will be printed + push @lines, "" while (scalar(@lines) < 2 + scalar(@descs)); my $ln = 0; for my $line(@lines) { if (!$ln) { printf "|%-${max_size_name}s", $name; printf "|%-${desc_size}s", "``" . $data{$name}->{kconfig} . "``"; - } elsif ($ln == 2) { + } elsif ($ln >= 2 && scalar(@descs)) { printf "|%-${max_size_name}s", ""; - printf "|%-${desc_size}s", $data{$name}->{description}; + printf "|%-${desc_size}s", shift @descs; } else { printf "|%-${max_size_name}s", ""; printf "|%-${desc_size}s", ""; -- cgit From af2d22254e8ee4558d3803372735c0b4f6046cd2 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Wed, 2 Dec 2020 22:49:29 +0900 Subject: gcc-plugins: remove code for GCC versions older than 4.9 Documentation/process/changes.rst says the minimal GCC version is 4.9. Hence, BUILDING_GCC_VERSION is greater than or equal to 4009. Signed-off-by: Masahiro Yamada Signed-off-by: Kees Cook Link: https://lore.kernel.org/r/20201202134929.99883-1-masahiroy@kernel.org --- scripts/gcc-plugins/gcc-common.h | 407 --------------------- scripts/gcc-plugins/gcc-generate-gimple-pass.h | 12 - scripts/gcc-plugins/gcc-generate-ipa-pass.h | 23 -- scripts/gcc-plugins/gcc-generate-rtl-pass.h | 17 - scripts/gcc-plugins/gcc-generate-simple_ipa-pass.h | 17 - scripts/gcc-plugins/latent_entropy_plugin.c | 12 - scripts/gcc-plugins/randomize_layout_plugin.c | 4 - scripts/gcc-plugins/sancov_plugin.c | 6 - scripts/gcc-plugins/stackleak_plugin.c | 4 +- scripts/gcc-plugins/structleak_plugin.c | 4 - 10 files changed, 1 insertion(+), 505 deletions(-) (limited to 'scripts') diff --git a/scripts/gcc-plugins/gcc-common.h b/scripts/gcc-plugins/gcc-common.h index 9ad76b7f3f10..0c087614fc3e 100644 --- a/scripts/gcc-plugins/gcc-common.h +++ b/scripts/gcc-plugins/gcc-common.h @@ -55,47 +55,17 @@ #include "cfgloop.h" #include "cgraph.h" #include "opts.h" - -#if BUILDING_GCC_VERSION == 4005 -#include -#endif - -#if BUILDING_GCC_VERSION >= 4007 #include "tree-pretty-print.h" #include "gimple-pretty-print.h" -#endif - -#if BUILDING_GCC_VERSION >= 4006 -/* - * The c-family headers were moved into a subdirectory in GCC version - * 4.7, but most plugin-building users of GCC 4.6 are using the Debian - * or Ubuntu package, which has an out-of-tree patch to move this to the - * same location as found in 4.7 and later: - * https://sources.debian.net/src/gcc-4.6/4.6.3-14/debian/patches/pr45078.diff/ - */ #include "c-family/c-common.h" -#else -#include "c-common.h" -#endif - -#if BUILDING_GCC_VERSION <= 4008 -#include "tree-flow.h" -#else #include "tree-cfgcleanup.h" #include "tree-ssa-operands.h" #include "tree-into-ssa.h" -#endif - -#if BUILDING_GCC_VERSION >= 4008 #include "is-a.h" -#endif - #include "diagnostic.h" #include "tree-dump.h" #include "tree-pass.h" -#if BUILDING_GCC_VERSION >= 4009 #include "pass_manager.h" -#endif #include "predict.h" #include "ipa-utils.h" @@ -103,7 +73,6 @@ #include "stringpool.h" #endif -#if BUILDING_GCC_VERSION >= 4009 #include "attribs.h" #include "varasm.h" #include "stor-layout.h" @@ -122,18 +91,13 @@ #include "tree-eh.h" #include "stmt.h" #include "gimplify.h" -#endif - #include "gimple.h" - -#if BUILDING_GCC_VERSION >= 4009 #include "tree-ssa-operands.h" #include "tree-phinodes.h" #include "tree-cfg.h" #include "gimple-iterator.h" #include "gimple-ssa.h" #include "ssa-iterators.h" -#endif #if BUILDING_GCC_VERSION >= 5000 #include "builtins.h" @@ -143,15 +107,6 @@ void debug_dominance_info(enum cdi_direction dir); void debug_dominance_tree(enum cdi_direction dir, basic_block root); -#if BUILDING_GCC_VERSION == 4006 -void debug_gimple_stmt(gimple); -void debug_gimple_seq(gimple_seq); -void print_gimple_seq(FILE *, gimple_seq, int, int); -void print_gimple_stmt(FILE *, gimple, int, int); -void print_gimple_expr(FILE *, gimple, int, int); -void dump_gimple_stmt(pretty_printer *, gimple, int, int); -#endif - #ifndef __unused #define __unused __attribute__((__unused__)) #endif @@ -190,372 +145,12 @@ struct register_pass_info NAME##_pass_info = { \ .pos_op = POS, \ } -#if BUILDING_GCC_VERSION == 4005 -#define FOR_EACH_LOCAL_DECL(FUN, I, D) \ - for (tree vars = (FUN)->local_decls, (I) = 0; \ - vars && ((D) = TREE_VALUE(vars)); \ - vars = TREE_CHAIN(vars), (I)++) -#define DECL_CHAIN(NODE) (TREE_CHAIN(DECL_MINIMAL_CHECK(NODE))) -#define FOR_EACH_VEC_ELT(T, V, I, P) \ - for (I = 0; VEC_iterate(T, (V), (I), (P)); ++(I)) -#define TODO_rebuild_cgraph_edges 0 -#define SCOPE_FILE_SCOPE_P(EXP) (!(EXP)) - -#ifndef O_BINARY -#define O_BINARY 0 -#endif - -typedef struct varpool_node *varpool_node_ptr; - -static inline bool gimple_call_builtin_p(gimple stmt, enum built_in_function code) -{ - tree fndecl; - - if (!is_gimple_call(stmt)) - return false; - fndecl = gimple_call_fndecl(stmt); - if (!fndecl || DECL_BUILT_IN_CLASS(fndecl) != BUILT_IN_NORMAL) - return false; - return DECL_FUNCTION_CODE(fndecl) == code; -} - -static inline bool is_simple_builtin(tree decl) -{ - if (decl && DECL_BUILT_IN_CLASS(decl) != BUILT_IN_NORMAL) - return false; - - switch (DECL_FUNCTION_CODE(decl)) { - /* Builtins that expand to constants. */ - case BUILT_IN_CONSTANT_P: - case BUILT_IN_EXPECT: - case BUILT_IN_OBJECT_SIZE: - case BUILT_IN_UNREACHABLE: - /* Simple register moves or loads from stack. */ - case BUILT_IN_RETURN_ADDRESS: - case BUILT_IN_EXTRACT_RETURN_ADDR: - case BUILT_IN_FROB_RETURN_ADDR: - case BUILT_IN_RETURN: - case BUILT_IN_AGGREGATE_INCOMING_ADDRESS: - case BUILT_IN_FRAME_ADDRESS: - case BUILT_IN_VA_END: - case BUILT_IN_STACK_SAVE: - case BUILT_IN_STACK_RESTORE: - /* Exception state returns or moves registers around. */ - case BUILT_IN_EH_FILTER: - case BUILT_IN_EH_POINTER: - case BUILT_IN_EH_COPY_VALUES: - return true; - - default: - return false; - } -} - -static inline void add_local_decl(struct function *fun, tree d) -{ - gcc_assert(TREE_CODE(d) == VAR_DECL); - fun->local_decls = tree_cons(NULL_TREE, d, fun->local_decls); -} -#endif - -#if BUILDING_GCC_VERSION <= 4006 -#define ANY_RETURN_P(rtx) (GET_CODE(rtx) == RETURN) -#define C_DECL_REGISTER(EXP) DECL_LANG_FLAG_4(EXP) -#define EDGE_PRESERVE 0ULL -#define HOST_WIDE_INT_PRINT_HEX_PURE "%" HOST_WIDE_INT_PRINT "x" -#define flag_fat_lto_objects true - -#define get_random_seed(noinit) ({ \ - unsigned HOST_WIDE_INT seed; \ - sscanf(get_random_seed(noinit), "%" HOST_WIDE_INT_PRINT "x", &seed); \ - seed * seed; }) - -#define int_const_binop(code, arg1, arg2) \ - int_const_binop((code), (arg1), (arg2), 0) - -static inline bool gimple_clobber_p(gimple s __unused) -{ - return false; -} - -static inline bool gimple_asm_clobbers_memory_p(const_gimple stmt) -{ - unsigned i; - - for (i = 0; i < gimple_asm_nclobbers(stmt); i++) { - tree op = gimple_asm_clobber_op(stmt, i); - - if (!strcmp(TREE_STRING_POINTER(TREE_VALUE(op)), "memory")) - return true; - } - - return false; -} - -static inline tree builtin_decl_implicit(enum built_in_function fncode) -{ - return implicit_built_in_decls[fncode]; -} - -static inline int ipa_reverse_postorder(struct cgraph_node **order) -{ - return cgraph_postorder(order); -} - -static inline struct cgraph_node *cgraph_create_node(tree decl) -{ - return cgraph_node(decl); -} - -static inline struct cgraph_node *cgraph_get_create_node(tree decl) -{ - struct cgraph_node *node = cgraph_get_node(decl); - - return node ? node : cgraph_node(decl); -} - -static inline bool cgraph_function_with_gimple_body_p(struct cgraph_node *node) -{ - return node->analyzed && !node->thunk.thunk_p && !node->alias; -} - -static inline struct cgraph_node *cgraph_first_function_with_gimple_body(void) -{ - struct cgraph_node *node; - - for (node = cgraph_nodes; node; node = node->next) - if (cgraph_function_with_gimple_body_p(node)) - return node; - return NULL; -} - -static inline struct cgraph_node *cgraph_next_function_with_gimple_body(struct cgraph_node *node) -{ - for (node = node->next; node; node = node->next) - if (cgraph_function_with_gimple_body_p(node)) - return node; - return NULL; -} - -static inline bool cgraph_for_node_and_aliases(cgraph_node_ptr node, bool (*callback)(cgraph_node_ptr, void *), void *data, bool include_overwritable) -{ - cgraph_node_ptr alias; - - if (callback(node, data)) - return true; - - for (alias = node->same_body; alias; alias = alias->next) { - if (include_overwritable || cgraph_function_body_availability(alias) > AVAIL_OVERWRITABLE) - if (cgraph_for_node_and_aliases(alias, callback, data, include_overwritable)) - return true; - } - - return false; -} - -#define FOR_EACH_FUNCTION_WITH_GIMPLE_BODY(node) \ - for ((node) = cgraph_first_function_with_gimple_body(); (node); \ - (node) = cgraph_next_function_with_gimple_body(node)) - -static inline void varpool_add_new_variable(tree decl) -{ - varpool_finalize_decl(decl); -} -#endif - -#if BUILDING_GCC_VERSION <= 4007 -#define FOR_EACH_FUNCTION(node) \ - for (node = cgraph_nodes; node; node = node->next) -#define FOR_EACH_VARIABLE(node) \ - for (node = varpool_nodes; node; node = node->next) -#define PROP_loops 0 -#define NODE_SYMBOL(node) (node) -#define NODE_DECL(node) (node)->decl -#define INSN_LOCATION(INSN) RTL_LOCATION(INSN) -#define vNULL NULL - -static inline int bb_loop_depth(const_basic_block bb) -{ - return bb->loop_father ? loop_depth(bb->loop_father) : 0; -} - -static inline bool gimple_store_p(gimple gs) -{ - tree lhs = gimple_get_lhs(gs); - - return lhs && !is_gimple_reg(lhs); -} - -static inline void gimple_init_singleton(gimple g __unused) -{ -} -#endif - -#if BUILDING_GCC_VERSION == 4007 || BUILDING_GCC_VERSION == 4008 -static inline struct cgraph_node *cgraph_alias_target(struct cgraph_node *n) -{ - return cgraph_alias_aliased_node(n); -} -#endif - -#if BUILDING_GCC_VERSION <= 4008 -#define ENTRY_BLOCK_PTR_FOR_FN(FN) ENTRY_BLOCK_PTR_FOR_FUNCTION(FN) -#define EXIT_BLOCK_PTR_FOR_FN(FN) EXIT_BLOCK_PTR_FOR_FUNCTION(FN) -#define basic_block_info_for_fn(FN) ((FN)->cfg->x_basic_block_info) -#define n_basic_blocks_for_fn(FN) ((FN)->cfg->x_n_basic_blocks) -#define n_edges_for_fn(FN) ((FN)->cfg->x_n_edges) -#define last_basic_block_for_fn(FN) ((FN)->cfg->x_last_basic_block) -#define label_to_block_map_for_fn(FN) ((FN)->cfg->x_label_to_block_map) -#define profile_status_for_fn(FN) ((FN)->cfg->x_profile_status) -#define BASIC_BLOCK_FOR_FN(FN, N) BASIC_BLOCK_FOR_FUNCTION((FN), (N)) -#define NODE_IMPLICIT_ALIAS(node) (node)->same_body_alias -#define VAR_P(NODE) (TREE_CODE(NODE) == VAR_DECL) - -static inline bool tree_fits_shwi_p(const_tree t) -{ - if (t == NULL_TREE || TREE_CODE(t) != INTEGER_CST) - return false; - - if (TREE_INT_CST_HIGH(t) == 0 && (HOST_WIDE_INT)TREE_INT_CST_LOW(t) >= 0) - return true; - - if (TREE_INT_CST_HIGH(t) == -1 && (HOST_WIDE_INT)TREE_INT_CST_LOW(t) < 0 && !TYPE_UNSIGNED(TREE_TYPE(t))) - return true; - - return false; -} - -static inline bool tree_fits_uhwi_p(const_tree t) -{ - if (t == NULL_TREE || TREE_CODE(t) != INTEGER_CST) - return false; - - return TREE_INT_CST_HIGH(t) == 0; -} - -static inline HOST_WIDE_INT tree_to_shwi(const_tree t) -{ - gcc_assert(tree_fits_shwi_p(t)); - return TREE_INT_CST_LOW(t); -} - -static inline unsigned HOST_WIDE_INT tree_to_uhwi(const_tree t) -{ - gcc_assert(tree_fits_uhwi_p(t)); - return TREE_INT_CST_LOW(t); -} - -static inline const char *get_tree_code_name(enum tree_code code) -{ - gcc_assert(code < MAX_TREE_CODES); - return tree_code_name[code]; -} - -#define ipa_remove_stmt_references(cnode, stmt) - -typedef union gimple_statement_d gasm; -typedef union gimple_statement_d gassign; -typedef union gimple_statement_d gcall; -typedef union gimple_statement_d gcond; -typedef union gimple_statement_d gdebug; -typedef union gimple_statement_d ggoto; -typedef union gimple_statement_d gphi; -typedef union gimple_statement_d greturn; - -static inline gasm *as_a_gasm(gimple stmt) -{ - return stmt; -} - -static inline const gasm *as_a_const_gasm(const_gimple stmt) -{ - return stmt; -} - -static inline gassign *as_a_gassign(gimple stmt) -{ - return stmt; -} - -static inline const gassign *as_a_const_gassign(const_gimple stmt) -{ - return stmt; -} - -static inline gcall *as_a_gcall(gimple stmt) -{ - return stmt; -} - -static inline const gcall *as_a_const_gcall(const_gimple stmt) -{ - return stmt; -} - -static inline gcond *as_a_gcond(gimple stmt) -{ - return stmt; -} - -static inline const gcond *as_a_const_gcond(const_gimple stmt) -{ - return stmt; -} - -static inline gdebug *as_a_gdebug(gimple stmt) -{ - return stmt; -} - -static inline const gdebug *as_a_const_gdebug(const_gimple stmt) -{ - return stmt; -} - -static inline ggoto *as_a_ggoto(gimple stmt) -{ - return stmt; -} - -static inline const ggoto *as_a_const_ggoto(const_gimple stmt) -{ - return stmt; -} - -static inline gphi *as_a_gphi(gimple stmt) -{ - return stmt; -} - -static inline const gphi *as_a_const_gphi(const_gimple stmt) -{ - return stmt; -} - -static inline greturn *as_a_greturn(gimple stmt) -{ - return stmt; -} - -static inline const greturn *as_a_const_greturn(const_gimple stmt) -{ - return stmt; -} -#endif - -#if BUILDING_GCC_VERSION == 4008 -#define NODE_SYMBOL(node) (&(node)->symbol) -#define NODE_DECL(node) (node)->symbol.decl -#endif - -#if BUILDING_GCC_VERSION >= 4008 #define add_referenced_var(var) #define mark_sym_for_renaming(var) #define varpool_mark_needed_node(node) #define create_var_ann(var) #define TODO_dump_func 0 #define TODO_dump_cgraph 0 -#endif #if BUILDING_GCC_VERSION <= 4009 #define TODO_verify_il 0 @@ -676,7 +271,6 @@ static inline const greturn *as_a_const_greturn(const_gimple stmt) } #endif -#if BUILDING_GCC_VERSION >= 4009 #define TODO_ggc_collect 0 #define NODE_SYMBOL(node) (node) #define NODE_DECL(node) (node)->decl @@ -687,7 +281,6 @@ static inline opt_pass *get_pass_for_id(int id) { return g->get_passes()->get_pass_for_id(id); } -#endif #if BUILDING_GCC_VERSION >= 5000 && BUILDING_GCC_VERSION < 6000 /* gimple related */ diff --git a/scripts/gcc-plugins/gcc-generate-gimple-pass.h b/scripts/gcc-plugins/gcc-generate-gimple-pass.h index f20797e80b6d..51780828734e 100644 --- a/scripts/gcc-plugins/gcc-generate-gimple-pass.h +++ b/scripts/gcc-plugins/gcc-generate-gimple-pass.h @@ -73,18 +73,11 @@ #define TODO_FLAGS_FINISH 0 #endif -#if BUILDING_GCC_VERSION >= 4009 namespace { static const pass_data _PASS_NAME_PASS_DATA = { -#else -static struct gimple_opt_pass _PASS_NAME_PASS = { - .pass = { -#endif .type = GIMPLE_PASS, .name = _PASS_NAME_NAME, -#if BUILDING_GCC_VERSION >= 4008 .optinfo_flags = OPTGROUP_NONE, -#endif #if BUILDING_GCC_VERSION >= 5000 #elif BUILDING_GCC_VERSION == 4009 .has_gate = _HAS_GATE, @@ -102,12 +95,8 @@ static struct gimple_opt_pass _PASS_NAME_PASS = { .properties_destroyed = PROPERTIES_DESTROYED, .todo_flags_start = TODO_FLAGS_START, .todo_flags_finish = TODO_FLAGS_FINISH, -#if BUILDING_GCC_VERSION < 4009 - } -#endif }; -#if BUILDING_GCC_VERSION >= 4009 class _PASS_NAME_PASS : public gimple_opt_pass { public: _PASS_NAME_PASS() : gimple_opt_pass(_PASS_NAME_PASS_DATA, g) {} @@ -128,7 +117,6 @@ public: #else virtual unsigned int execute(void) { return _EXECUTE(); } #endif -#endif }; } diff --git a/scripts/gcc-plugins/gcc-generate-ipa-pass.h b/scripts/gcc-plugins/gcc-generate-ipa-pass.h index 92bb4f3a87a4..c34ffec035bf 100644 --- a/scripts/gcc-plugins/gcc-generate-ipa-pass.h +++ b/scripts/gcc-plugins/gcc-generate-ipa-pass.h @@ -141,18 +141,11 @@ #define FUNCTION_TRANSFORM_TODO_FLAGS_START 0 #endif -#if BUILDING_GCC_VERSION >= 4009 namespace { static const pass_data _PASS_NAME_PASS_DATA = { -#else -static struct ipa_opt_pass_d _PASS_NAME_PASS = { - .pass = { -#endif .type = IPA_PASS, .name = _PASS_NAME_NAME, -#if BUILDING_GCC_VERSION >= 4008 .optinfo_flags = OPTGROUP_NONE, -#endif #if BUILDING_GCC_VERSION >= 5000 #elif BUILDING_GCC_VERSION == 4009 .has_gate = _HAS_GATE, @@ -170,23 +163,8 @@ static struct ipa_opt_pass_d _PASS_NAME_PASS = { .properties_destroyed = PROPERTIES_DESTROYED, .todo_flags_start = TODO_FLAGS_START, .todo_flags_finish = TODO_FLAGS_FINISH, -#if BUILDING_GCC_VERSION < 4009 - }, - .generate_summary = _GENERATE_SUMMARY, - .write_summary = _WRITE_SUMMARY, - .read_summary = _READ_SUMMARY, -#if BUILDING_GCC_VERSION >= 4006 - .write_optimization_summary = _WRITE_OPTIMIZATION_SUMMARY, - .read_optimization_summary = _READ_OPTIMIZATION_SUMMARY, -#endif - .stmt_fixup = _STMT_FIXUP, - .function_transform_todo_flags_start = FUNCTION_TRANSFORM_TODO_FLAGS_START, - .function_transform = _FUNCTION_TRANSFORM, - .variable_transform = _VARIABLE_TRANSFORM, -#endif }; -#if BUILDING_GCC_VERSION >= 4009 class _PASS_NAME_PASS : public ipa_opt_pass_d { public: _PASS_NAME_PASS() : ipa_opt_pass_d(_PASS_NAME_PASS_DATA, @@ -206,7 +184,6 @@ public: virtual bool gate(function *) { return _GATE(); } #else virtual bool gate(void) { return _GATE(); } -#endif #endif virtual opt_pass *clone() { return new _PASS_NAME_PASS(); } diff --git a/scripts/gcc-plugins/gcc-generate-rtl-pass.h b/scripts/gcc-plugins/gcc-generate-rtl-pass.h index d69cd80b6c10..d14614f4b139 100644 --- a/scripts/gcc-plugins/gcc-generate-rtl-pass.h +++ b/scripts/gcc-plugins/gcc-generate-rtl-pass.h @@ -73,18 +73,11 @@ #define TODO_FLAGS_FINISH 0 #endif -#if BUILDING_GCC_VERSION >= 4009 namespace { static const pass_data _PASS_NAME_PASS_DATA = { -#else -static struct rtl_opt_pass _PASS_NAME_PASS = { - .pass = { -#endif .type = RTL_PASS, .name = _PASS_NAME_NAME, -#if BUILDING_GCC_VERSION >= 4008 .optinfo_flags = OPTGROUP_NONE, -#endif #if BUILDING_GCC_VERSION >= 5000 #elif BUILDING_GCC_VERSION == 4009 .has_gate = _HAS_GATE, @@ -102,12 +95,8 @@ static struct rtl_opt_pass _PASS_NAME_PASS = { .properties_destroyed = PROPERTIES_DESTROYED, .todo_flags_start = TODO_FLAGS_START, .todo_flags_finish = TODO_FLAGS_FINISH, -#if BUILDING_GCC_VERSION < 4009 - } -#endif }; -#if BUILDING_GCC_VERSION >= 4009 class _PASS_NAME_PASS : public rtl_opt_pass { public: _PASS_NAME_PASS() : rtl_opt_pass(_PASS_NAME_PASS_DATA, g) {} @@ -136,12 +125,6 @@ opt_pass *_MAKE_PASS_NAME_PASS(void) { return new _PASS_NAME_PASS(); } -#else -struct opt_pass *_MAKE_PASS_NAME_PASS(void) -{ - return &_PASS_NAME_PASS.pass; -} -#endif /* clean up user provided defines */ #undef PASS_NAME diff --git a/scripts/gcc-plugins/gcc-generate-simple_ipa-pass.h b/scripts/gcc-plugins/gcc-generate-simple_ipa-pass.h index 06800bc477e0..ef6f4c2cb6fa 100644 --- a/scripts/gcc-plugins/gcc-generate-simple_ipa-pass.h +++ b/scripts/gcc-plugins/gcc-generate-simple_ipa-pass.h @@ -73,18 +73,11 @@ #define TODO_FLAGS_FINISH 0 #endif -#if BUILDING_GCC_VERSION >= 4009 namespace { static const pass_data _PASS_NAME_PASS_DATA = { -#else -static struct simple_ipa_opt_pass _PASS_NAME_PASS = { - .pass = { -#endif .type = SIMPLE_IPA_PASS, .name = _PASS_NAME_NAME, -#if BUILDING_GCC_VERSION >= 4008 .optinfo_flags = OPTGROUP_NONE, -#endif #if BUILDING_GCC_VERSION >= 5000 #elif BUILDING_GCC_VERSION == 4009 .has_gate = _HAS_GATE, @@ -102,12 +95,8 @@ static struct simple_ipa_opt_pass _PASS_NAME_PASS = { .properties_destroyed = PROPERTIES_DESTROYED, .todo_flags_start = TODO_FLAGS_START, .todo_flags_finish = TODO_FLAGS_FINISH, -#if BUILDING_GCC_VERSION < 4009 - } -#endif }; -#if BUILDING_GCC_VERSION >= 4009 class _PASS_NAME_PASS : public simple_ipa_opt_pass { public: _PASS_NAME_PASS() : simple_ipa_opt_pass(_PASS_NAME_PASS_DATA, g) {} @@ -136,12 +125,6 @@ opt_pass *_MAKE_PASS_NAME_PASS(void) { return new _PASS_NAME_PASS(); } -#else -struct opt_pass *_MAKE_PASS_NAME_PASS(void) -{ - return &_PASS_NAME_PASS.pass; -} -#endif /* clean up user provided defines */ #undef PASS_NAME diff --git a/scripts/gcc-plugins/latent_entropy_plugin.c b/scripts/gcc-plugins/latent_entropy_plugin.c index cbe1d6c4b1a5..9dced66d158e 100644 --- a/scripts/gcc-plugins/latent_entropy_plugin.c +++ b/scripts/gcc-plugins/latent_entropy_plugin.c @@ -125,11 +125,7 @@ static tree handle_latent_entropy_attribute(tree *node, tree name, bool *no_add_attrs) { tree type; -#if BUILDING_GCC_VERSION <= 4007 - VEC(constructor_elt, gc) *vals; -#else vec *vals; -#endif switch (TREE_CODE(*node)) { default: @@ -181,11 +177,7 @@ static tree handle_latent_entropy_attribute(tree *node, tree name, if (fld) break; -#if BUILDING_GCC_VERSION <= 4007 - vals = VEC_alloc(constructor_elt, gc, nelt); -#else vec_alloc(vals, nelt); -#endif for (fld = lst; fld; fld = TREE_CHAIN(fld)) { tree random_const, fld_t = TREE_TYPE(fld); @@ -225,11 +217,7 @@ static tree handle_latent_entropy_attribute(tree *node, tree name, elt_size_int = TREE_INT_CST_LOW(elt_size); nelt = array_size_int / elt_size_int; -#if BUILDING_GCC_VERSION <= 4007 - vals = VEC_alloc(constructor_elt, gc, nelt); -#else vec_alloc(vals, nelt); -#endif for (i = 0; i < nelt; i++) { tree cst = size_int(i); diff --git a/scripts/gcc-plugins/randomize_layout_plugin.c b/scripts/gcc-plugins/randomize_layout_plugin.c index bd29e4e7a524..334741a31d0a 100644 --- a/scripts/gcc-plugins/randomize_layout_plugin.c +++ b/scripts/gcc-plugins/randomize_layout_plugin.c @@ -590,16 +590,12 @@ static void register_attributes(void *event_data, void *data) randomize_layout_attr.name = "randomize_layout"; randomize_layout_attr.type_required = true; randomize_layout_attr.handler = handle_randomize_layout_attr; -#if BUILDING_GCC_VERSION >= 4007 randomize_layout_attr.affects_type_identity = true; -#endif no_randomize_layout_attr.name = "no_randomize_layout"; no_randomize_layout_attr.type_required = true; no_randomize_layout_attr.handler = handle_randomize_layout_attr; -#if BUILDING_GCC_VERSION >= 4007 no_randomize_layout_attr.affects_type_identity = true; -#endif randomize_considered_attr.name = "randomize_considered"; randomize_considered_attr.type_required = true; diff --git a/scripts/gcc-plugins/sancov_plugin.c b/scripts/gcc-plugins/sancov_plugin.c index caff4a6c7e9a..23bd023a283b 100644 --- a/scripts/gcc-plugins/sancov_plugin.c +++ b/scripts/gcc-plugins/sancov_plugin.c @@ -80,10 +80,8 @@ static void sancov_start_unit(void __unused *gcc_data, void __unused *user_data) nothrow_attr = tree_cons(get_identifier("nothrow"), NULL, NULL); decl_attributes(&sancov_fndecl, nothrow_attr, 0); gcc_assert(TREE_NOTHROW(sancov_fndecl)); -#if BUILDING_GCC_VERSION > 4005 leaf_attr = tree_cons(get_identifier("leaf"), NULL, NULL); decl_attributes(&sancov_fndecl, leaf_attr, 0); -#endif } __visible int plugin_init(struct plugin_name_args *plugin_info, struct plugin_gcc_version *version) @@ -106,11 +104,7 @@ __visible int plugin_init(struct plugin_name_args *plugin_info, struct plugin_gc }; /* BBs can be split afterwards?? */ -#if BUILDING_GCC_VERSION >= 4009 PASS_INFO(sancov, "asan", 0, PASS_POS_INSERT_BEFORE); -#else - PASS_INFO(sancov, "nrv", 1, PASS_POS_INSERT_BEFORE); -#endif if (!plugin_default_version_check(version, &gcc_version)) { error(G_("incompatible gcc/plugin versions")); diff --git a/scripts/gcc-plugins/stackleak_plugin.c b/scripts/gcc-plugins/stackleak_plugin.c index 48e141e07956..e9db7dcb3e5f 100644 --- a/scripts/gcc-plugins/stackleak_plugin.c +++ b/scripts/gcc-plugins/stackleak_plugin.c @@ -80,10 +80,8 @@ static bool is_alloca(gimple stmt) if (gimple_call_builtin_p(stmt, BUILT_IN_ALLOCA)) return true; -#if BUILDING_GCC_VERSION >= 4007 if (gimple_call_builtin_p(stmt, BUILT_IN_ALLOCA_WITH_ALIGN)) return true; -#endif return false; } @@ -322,7 +320,7 @@ static void remove_stack_tracking_gcall(void) /* Delete the stackleak_track_stack() call */ delete_insn_and_edges(insn); -#if BUILDING_GCC_VERSION >= 4007 && BUILDING_GCC_VERSION < 8000 +#if BUILDING_GCC_VERSION < 8000 if (GET_CODE(next) == NOTE && NOTE_KIND(next) == NOTE_INSN_CALL_ARG_LOCATION) { insn = next; diff --git a/scripts/gcc-plugins/structleak_plugin.c b/scripts/gcc-plugins/structleak_plugin.c index b9ef2e162107..29b480c33a8d 100644 --- a/scripts/gcc-plugins/structleak_plugin.c +++ b/scripts/gcc-plugins/structleak_plugin.c @@ -68,9 +68,7 @@ static void register_attributes(void *event_data, void *data) { user_attr.name = "user"; user_attr.handler = handle_user_attribute; -#if BUILDING_GCC_VERSION >= 4007 user_attr.affects_type_identity = true; -#endif register_attribute(&user_attr); } @@ -137,11 +135,9 @@ static void initialize(tree var) if (!gimple_assign_single_p(stmt)) continue; rhs1 = gimple_assign_rhs1(stmt); -#if BUILDING_GCC_VERSION >= 4007 /* ... of a non-clobbering expression... */ if (TREE_CLOBBER_P(rhs1)) continue; -#endif /* ... to our variable... */ if (gimple_get_lhs(stmt) != var) continue; -- cgit From 1e860048c53ee77ee9870dcce94847a28544b753 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Thu, 3 Dec 2020 21:57:00 +0900 Subject: gcc-plugins: simplify GCC plugin-dev capability test Linus pointed out a third of the time in the Kconfig parse stage comes from the single invocation of cc1plus in scripts/gcc-plugin.sh [1], and directly testing plugin-version.h for existence cuts down the overhead a lot. [2] This commit takes one step further to kill the build test entirely. The small piece of code was probably intended to test the C++ designated initializer, which was not supported until C++20. In fact, with -pedantic option given, both GCC and Clang emit a warning. $ echo 'class test { public: int test; } test = { .test = 1 };' | g++ -x c++ -pedantic - -fsyntax-only :1:43: warning: C++ designated initializers only available with '-std=c++2a' or '-std=gnu++2a' [-Wpedantic] $ echo 'class test { public: int test; } test = { .test = 1 };' | clang++ -x c++ -pedantic - -fsyntax-only :1:43: warning: designated initializers are a C++20 extension [-Wc++20-designator] class test { public: int test; } test = { .test = 1 }; ^ 1 warning generated. Otherwise, modern C++ compilers should be able to build the code, and hopefully skipping this test should not make any practical problem. Checking the existence of plugin-version.h is still needed to ensure the plugin-dev package is installed. The test code is now small enough to be embedded in scripts/gcc-plugins/Kconfig. [1] https://lore.kernel.org/lkml/CAHk-=wjU4DCuwQ4pXshRbwDCUQB31ScaeuDo1tjoZ0_PjhLHzQ@mail.gmail.com/ [2] https://lore.kernel.org/lkml/CAHk-=whK0aQxs6Q5ijJmYF1n2ch8cVFSUzU5yUM_HOjig=+vnw@mail.gmail.com/ Reported-by: Linus Torvalds Signed-off-by: Masahiro Yamada Signed-off-by: Kees Cook Link: https://lore.kernel.org/r/20201203125700.161354-1-masahiroy@kernel.org --- scripts/gcc-plugin.sh | 19 ------------------- scripts/gcc-plugins/Kconfig | 2 +- 2 files changed, 1 insertion(+), 20 deletions(-) delete mode 100755 scripts/gcc-plugin.sh (limited to 'scripts') diff --git a/scripts/gcc-plugin.sh b/scripts/gcc-plugin.sh deleted file mode 100755 index b79fd0bea838..000000000000 --- a/scripts/gcc-plugin.sh +++ /dev/null @@ -1,19 +0,0 @@ -#!/bin/sh -# SPDX-License-Identifier: GPL-2.0 - -set -e - -srctree=$(dirname "$0") - -gccplugins_dir=$($* -print-file-name=plugin) - -# we need a c++ compiler that supports the designated initializer GNU extension -$HOSTCC -c -x c++ -std=gnu++98 - -fsyntax-only -I $srctree/gcc-plugins -I $gccplugins_dir/include 2>/dev/null < Date: Fri, 4 Dec 2020 02:55:51 +0900 Subject: kbuild: avoid split lines in .mod files "xargs echo" is not a safe way to remove line breaks because the input may exceed the command line limit and xargs may break it up into multiple invocations of echo. This should never happen because scripts/gen_autoksyms.sh expects all undefined symbols are placed in the second line of .mod files. One possible way is to replace "xargs echo" with "sed ':x;N;$!bx;s/\n/ /g'" or something, but I rewrote the code by using awk because it is more readable. This issue was reported by Sami Tolvanen; in his Clang LTO patch set, $(multi-used-m) is no longer an ELF object, but a thin archive that contains LLVM bitcode files. llvm-nm prints out symbols for each archive member separately, which results a lot of dupications, in some places, beyond the system-defined limit. This problem must be fixed irrespective of LTO, and we must ensure zero possibility of having this issue. Link: https://lkml.org/lkml/2020/12/1/1658 Reported-by: Sami Tolvanen Signed-off-by: Masahiro Yamada Reviewed-by: Sami Tolvanen --- scripts/Makefile.build | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) (limited to 'scripts') diff --git a/scripts/Makefile.build b/scripts/Makefile.build index ae647379b579..4c058f12dd73 100644 --- a/scripts/Makefile.build +++ b/scripts/Makefile.build @@ -252,6 +252,9 @@ objtool_dep = $(objtool_obj) \ ifdef CONFIG_TRIM_UNUSED_KSYMS cmd_gen_ksymdeps = \ $(CONFIG_SHELL) $(srctree)/scripts/gen_ksymdeps.sh $@ >> $(dot-target).cmd + +# List module undefined symbols +undefined_syms = $(NM) $< | $(AWK) '$$1 == "U" { printf("%s%s", x++ ? " " : "", $$2) }'; endif define rule_cc_o_c @@ -271,13 +274,6 @@ define rule_as_o_S $(call cmd,modversions_S) endef -# List module undefined symbols (or empty line if not enabled) -ifdef CONFIG_TRIM_UNUSED_KSYMS -cmd_undef_syms = $(NM) $< | sed -n 's/^ *U //p' | xargs echo -else -cmd_undef_syms = echo -endif - # Built-in and composite module parts $(obj)/%.o: $(src)/%.c $(recordmcount_source) $(objtool_dep) FORCE $(call if_changed_rule,cc_o_c) @@ -285,7 +281,7 @@ $(obj)/%.o: $(src)/%.c $(recordmcount_source) $(objtool_dep) FORCE cmd_mod = { \ echo $(if $($*-objs)$($*-y)$($*-m), $(addprefix $(obj)/, $($*-objs) $($*-y) $($*-m)), $(@:.mod=.o)); \ - $(cmd_undef_syms); \ + $(undefined_syms) echo; \ } > $@ $(obj)/%.mod: $(obj)/%.o FORCE -- cgit From c25ce589dca10d64dde139ae093abc258a32869c Mon Sep 17 00:00:00 2001 From: Finn Behrens Date: Mon, 23 Nov 2020 15:15:33 +0100 Subject: tweewide: Fix most Shebang lines Change every shebang which does not need an argument to use /usr/bin/env. This is needed as not every distro has everything under /usr/bin, sometimes not even bash. Signed-off-by: Finn Behrens Signed-off-by: Masahiro Yamada --- scripts/bloat-o-meter | 2 +- scripts/config | 2 +- scripts/diffconfig | 2 +- scripts/get_abi.pl | 2 +- scripts/show_delta | 2 +- scripts/sphinx-pre-install | 2 +- scripts/split-man.pl | 2 +- scripts/tracing/draw_functrace.py | 2 +- 8 files changed, 8 insertions(+), 8 deletions(-) (limited to 'scripts') diff --git a/scripts/bloat-o-meter b/scripts/bloat-o-meter index d7ca46c612b3..652e9542043f 100755 --- a/scripts/bloat-o-meter +++ b/scripts/bloat-o-meter @@ -1,4 +1,4 @@ -#!/usr/bin/python +#!/usr/bin/env python # # Copyright 2004 Matt Mackall # diff --git a/scripts/config b/scripts/config index eee5b7f3a092..8c8d7c3d7acc 100755 --- a/scripts/config +++ b/scripts/config @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash # SPDX-License-Identifier: GPL-2.0 # Manipulate options in a .config file from the command line diff --git a/scripts/diffconfig b/scripts/diffconfig index 89abf777f197..627eba5849b5 100755 --- a/scripts/diffconfig +++ b/scripts/diffconfig @@ -1,4 +1,4 @@ -#!/usr/bin/python +#!/usr/bin/env python # SPDX-License-Identifier: GPL-2.0 # # diffconfig - a tool to compare .config files. diff --git a/scripts/get_abi.pl b/scripts/get_abi.pl index 68dab828a722..92d9aa6cc4f5 100755 --- a/scripts/get_abi.pl +++ b/scripts/get_abi.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl # SPDX-License-Identifier: GPL-2.0 use strict; diff --git a/scripts/show_delta b/scripts/show_delta index 264399307c4f..28e67e178194 100755 --- a/scripts/show_delta +++ b/scripts/show_delta @@ -1,4 +1,4 @@ -#!/usr/bin/python +#!/usr/bin/env python # SPDX-License-Identifier: GPL-2.0-only # # show_deltas: Read list of printk messages instrumented with diff --git a/scripts/sphinx-pre-install b/scripts/sphinx-pre-install index 40fa6923e80a..828a8615a918 100755 --- a/scripts/sphinx-pre-install +++ b/scripts/sphinx-pre-install @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl # SPDX-License-Identifier: GPL-2.0-or-later use strict; diff --git a/scripts/split-man.pl b/scripts/split-man.pl index c3db607ee9ec..96bd99dc977a 100755 --- a/scripts/split-man.pl +++ b/scripts/split-man.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl # SPDX-License-Identifier: GPL-2.0 # # Author: Mauro Carvalho Chehab diff --git a/scripts/tracing/draw_functrace.py b/scripts/tracing/draw_functrace.py index b65735758520..74f8aadfd4cb 100755 --- a/scripts/tracing/draw_functrace.py +++ b/scripts/tracing/draw_functrace.py @@ -1,4 +1,4 @@ -#!/usr/bin/python +#!/usr/bin/env python # SPDX-License-Identifier: GPL-2.0-only """ -- cgit From c93e4aeed1be5b99715a9127f5b38d6b4ab9e5d7 Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Tue, 24 Nov 2020 16:43:17 +0100 Subject: Makefile.extrawarn: remove -Wnested-externs warning The -Wnested-externs warning has become useless with gcc, since this warns every time that BUILD_BUG_ON() or similar macros are used. With clang, the warning option does nothing to start with, so just remove it entirely. Suggested-by: Nathan Chancellor Signed-off-by: Arnd Bergmann Reviewed-by: Nathan Chancellor Signed-off-by: Masahiro Yamada --- scripts/Makefile.extrawarn | 1 - 1 file changed, 1 deletion(-) (limited to 'scripts') diff --git a/scripts/Makefile.extrawarn b/scripts/Makefile.extrawarn index 6baee1200615..d53825503874 100644 --- a/scripts/Makefile.extrawarn +++ b/scripts/Makefile.extrawarn @@ -61,7 +61,6 @@ endif ifneq ($(findstring 2, $(KBUILD_EXTRA_WARN)),) KBUILD_CFLAGS += -Wdisabled-optimization -KBUILD_CFLAGS += -Wnested-externs KBUILD_CFLAGS += -Wshadow KBUILD_CFLAGS += $(call cc-option, -Wlogical-op) KBUILD_CFLAGS += -Wmissing-field-initializers -- cgit From 7b675649be2217786847dee13597a0ab8502cc40 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Sat, 24 Oct 2020 21:38:39 +0900 Subject: kconfig: qconf: drop Qt4 support It is possible to keep this compatible with both Qt4 and Qt5, but it is questionable if it is worth the efforts; it would require us to test this on both of them, and prevent us from using new features in Qt5. Qt5 was released in 2012, and now widely available. Drop the Qt4 support. Signed-off-by: Masahiro Yamada --- scripts/kconfig/qconf-cfg.sh | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) (limited to 'scripts') diff --git a/scripts/kconfig/qconf-cfg.sh b/scripts/kconfig/qconf-cfg.sh index 02ccc0ae1031..d1eb2407c35d 100755 --- a/scripts/kconfig/qconf-cfg.sh +++ b/scripts/kconfig/qconf-cfg.sh @@ -2,7 +2,6 @@ # SPDX-License-Identifier: GPL-2.0 PKG="Qt5Core Qt5Gui Qt5Widgets" -PKG2="QtCore QtGui" if [ -z "$(command -v pkg-config)" ]; then echo >&2 "*" @@ -18,15 +17,8 @@ if pkg-config --exists $PKG; then exit 0 fi -if pkg-config --exists $PKG2; then - echo cflags=\"$(pkg-config --cflags $PKG2)\" - echo libs=\"$(pkg-config --libs $PKG2)\" - echo moc=\"$(pkg-config --variable=moc_location QtCore)\" - exit 0 -fi - echo >&2 "*" -echo >&2 "* Could not find Qt via pkg-config." -echo >&2 "* Please install either Qt 4.8 or 5.x. and make sure it's in PKG_CONFIG_PATH" +echo >&2 "* Could not find Qt5 via pkg-config." +echo >&2 "* Please install Qt5 and make sure it's in PKG_CONFIG_PATH" echo >&2 "*" exit 1 -- cgit From 7cd0158703a4828252f10a4c4519778fa069ffdf Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Sat, 24 Oct 2020 21:38:40 +0900 Subject: kconfig: qconf: use a variable to pass packages to pkg-config The variable, PKG, is defined at the beginning of this script. Signed-off-by: Masahiro Yamada --- scripts/kconfig/qconf-cfg.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'scripts') diff --git a/scripts/kconfig/qconf-cfg.sh b/scripts/kconfig/qconf-cfg.sh index d1eb2407c35d..fa564cd795b7 100755 --- a/scripts/kconfig/qconf-cfg.sh +++ b/scripts/kconfig/qconf-cfg.sh @@ -11,7 +11,7 @@ if [ -z "$(command -v pkg-config)" ]; then fi if pkg-config --exists $PKG; then - echo cflags=\"-std=c++11 -fPIC $(pkg-config --cflags Qt5Core Qt5Gui Qt5Widgets)\" + echo cflags=\"-std=c++11 -fPIC $(pkg-config --cflags $PKG)\" echo libs=\"$(pkg-config --libs $PKG)\" echo moc=\"$(pkg-config --variable=host_bins Qt5Core)/moc\" exit 0 -- cgit From a2574c12df0d77eef293d2f388d7e05df33b6155 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Sat, 24 Oct 2020 21:38:41 +0900 Subject: kconfig: qconf: convert to Qt5 new signal/slot connection syntax Now that the Qt4 support was dropped, we can use the new connection syntax supported by Qt5. It provides compile-time checking of the validity of the connection. Previously, the connection between signals and slots were checked only run-time. Commit d85de3399f97 ("kconfig: qconf: fix signal connection to invalid slots") fixed wrong slots. This change makes it possible to catch such mistakes easily. Signed-off-by: Masahiro Yamada Tested-by: Boris Kolpackov --- scripts/kconfig/qconf.cc | 136 +++++++++++++++++++++++++++-------------------- 1 file changed, 78 insertions(+), 58 deletions(-) (limited to 'scripts') diff --git a/scripts/kconfig/qconf.cc b/scripts/kconfig/qconf.cc index f7eb093614f2..cbe749b44b1a 100644 --- a/scripts/kconfig/qconf.cc +++ b/scripts/kconfig/qconf.cc @@ -310,15 +310,16 @@ ConfigList::ConfigList(QWidget *parent, const char *name) setHeaderLabels(QStringList() << "Option" << "Name" << "Value"); - connect(this, SIGNAL(itemSelectionChanged(void)), - SLOT(updateSelection(void))); + connect(this, &ConfigList::itemSelectionChanged, + this, &ConfigList::updateSelection); if (name) { configSettings->beginGroup(name); showName = configSettings->value("/showName", false).toBool(); optMode = (enum optionMode)configSettings->value("/optionMode", 0).toInt(); configSettings->endGroup(); - connect(configApp, SIGNAL(aboutToQuit()), SLOT(saveSettings())); + connect(configApp, &QApplication::aboutToQuit, + this, &ConfigList::saveSettings); } showColumn(promptColIdx); @@ -888,10 +889,10 @@ void ConfigList::contextMenuEvent(QContextMenuEvent *e) headerPopup = new QMenu(this); action = new QAction("Show Name", this); action->setCheckable(true); - connect(action, SIGNAL(toggled(bool)), - SLOT(setShowName(bool))); - connect(this, SIGNAL(showNameChanged(bool)), - action, SLOT(setChecked(bool))); + connect(action, &QAction::toggled, + this, &ConfigList::setShowName); + connect(this, &ConfigList::showNameChanged, + action, &QAction::setChecked); action->setChecked(showName); headerPopup->addAction(action); } @@ -936,15 +937,18 @@ ConfigInfoView::ConfigInfoView(QWidget* parent, const char *name) configSettings->beginGroup(objectName()); setShowDebug(configSettings->value("/showDebug", false).toBool()); configSettings->endGroup(); - connect(configApp, SIGNAL(aboutToQuit()), SLOT(saveSettings())); + connect(configApp, &QApplication::aboutToQuit, + this, &ConfigInfoView::saveSettings); } contextMenu = createStandardContextMenu(); QAction *action = new QAction("Show Debug Info", contextMenu); action->setCheckable(true); - connect(action, SIGNAL(toggled(bool)), SLOT(setShowDebug(bool))); - connect(this, SIGNAL(showDebugChanged(bool)), action, SLOT(setChecked(bool))); + connect(action, &QAction::toggled, + this, &ConfigInfoView::setShowDebug); + connect(this, &ConfigInfoView::showDebugChanged, + action, &QAction::setChecked); action->setChecked(showDebug()); contextMenu->addSeparator(); contextMenu->addAction(action); @@ -1231,11 +1235,13 @@ ConfigSearchWindow::ConfigSearchWindow(ConfigMainWindow *parent) layout2->setSpacing(6); layout2->addWidget(new QLabel("Find:", this)); editField = new QLineEdit(this); - connect(editField, SIGNAL(returnPressed()), SLOT(search())); + connect(editField, &QLineEdit::returnPressed, + this, &ConfigSearchWindow::search); layout2->addWidget(editField); searchButton = new QPushButton("Search", this); searchButton->setAutoDefault(false); - connect(searchButton, SIGNAL(clicked()), SLOT(search())); + connect(searchButton, &QPushButton::clicked, + this, &ConfigSearchWindow::search); layout2->addWidget(searchButton); layout1->addLayout(layout2); @@ -1244,10 +1250,10 @@ ConfigSearchWindow::ConfigSearchWindow(ConfigMainWindow *parent) list = new ConfigList(split, "search"); list->mode = listMode; info = new ConfigInfoView(split, "search"); - connect(list, SIGNAL(menuChanged(struct menu *)), - info, SLOT(setInfo(struct menu *))); - connect(list, SIGNAL(menuChanged(struct menu *)), - parent, SLOT(setMenuLink(struct menu *))); + connect(list, &ConfigList::menuChanged, + info, &ConfigInfoView::setInfo); + connect(list, &ConfigList::menuChanged, + parent, &ConfigMainWindow::setMenuLink); layout1->addWidget(split); @@ -1267,7 +1273,8 @@ ConfigSearchWindow::ConfigSearchWindow(ConfigMainWindow *parent) if (ok) split->setSizes(sizes); configSettings->endGroup(); - connect(configApp, SIGNAL(aboutToQuit()), SLOT(saveSettings())); + connect(configApp, &QApplication::aboutToQuit, + this, &ConfigSearchWindow::saveSettings); } void ConfigSearchWindow::saveSettings(void) @@ -1367,19 +1374,23 @@ ConfigMainWindow::ConfigMainWindow(void) configList->setFocus(); backAction = new QAction(QPixmap(xpm_back), "Back", this); - connect(backAction, SIGNAL(triggered(bool)), SLOT(goBack())); + connect(backAction, &QAction::triggered, + this, &ConfigMainWindow::goBack); QAction *quitAction = new QAction("&Quit", this); quitAction->setShortcut(Qt::CTRL + Qt::Key_Q); - connect(quitAction, SIGNAL(triggered(bool)), SLOT(close())); + connect(quitAction, &QAction::triggered, + this, &ConfigMainWindow::close); QAction *loadAction = new QAction(QPixmap(xpm_load), "&Load", this); loadAction->setShortcut(Qt::CTRL + Qt::Key_L); - connect(loadAction, SIGNAL(triggered(bool)), SLOT(loadConfig())); + connect(loadAction, &QAction::triggered, + this, &ConfigMainWindow::loadConfig); saveAction = new QAction(QPixmap(xpm_save), "&Save", this); saveAction->setShortcut(Qt::CTRL + Qt::Key_S); - connect(saveAction, SIGNAL(triggered(bool)), SLOT(saveConfig())); + connect(saveAction, &QAction::triggered, + this, &ConfigMainWindow::saveConfig); conf_set_changed_callback(conf_changed); @@ -1388,31 +1399,37 @@ ConfigMainWindow::ConfigMainWindow(void) configname = xstrdup(conf_get_configname()); QAction *saveAsAction = new QAction("Save &As...", this); - connect(saveAsAction, SIGNAL(triggered(bool)), SLOT(saveConfigAs())); + connect(saveAsAction, &QAction::triggered, + this, &ConfigMainWindow::saveConfigAs); QAction *searchAction = new QAction("&Find", this); searchAction->setShortcut(Qt::CTRL + Qt::Key_F); - connect(searchAction, SIGNAL(triggered(bool)), SLOT(searchConfig())); + connect(searchAction, &QAction::triggered, + this, &ConfigMainWindow::searchConfig); singleViewAction = new QAction(QPixmap(xpm_single_view), "Single View", this); singleViewAction->setCheckable(true); - connect(singleViewAction, SIGNAL(triggered(bool)), SLOT(showSingleView())); + connect(singleViewAction, &QAction::triggered, + this, &ConfigMainWindow::showSingleView); splitViewAction = new QAction(QPixmap(xpm_split_view), "Split View", this); splitViewAction->setCheckable(true); - connect(splitViewAction, SIGNAL(triggered(bool)), SLOT(showSplitView())); + connect(splitViewAction, &QAction::triggered, + this, &ConfigMainWindow::showSplitView); fullViewAction = new QAction(QPixmap(xpm_tree_view), "Full View", this); fullViewAction->setCheckable(true); - connect(fullViewAction, SIGNAL(triggered(bool)), SLOT(showFullView())); + connect(fullViewAction, &QAction::triggered, + this, &ConfigMainWindow::showFullView); QAction *showNameAction = new QAction("Show Name", this); showNameAction->setCheckable(true); - connect(showNameAction, SIGNAL(toggled(bool)), configList, SLOT(setShowName(bool))); + connect(showNameAction, &QAction::toggled, + configList, &ConfigList::setShowName); showNameAction->setChecked(configList->showName); QActionGroup *optGroup = new QActionGroup(this); optGroup->setExclusive(true); - connect(optGroup, SIGNAL(triggered(QAction*)), configList, - SLOT(setOptionMode(QAction *))); - connect(optGroup, SIGNAL(triggered(QAction *)), menuList, - SLOT(setOptionMode(QAction *))); + connect(optGroup, &QActionGroup::triggered, + configList, &ConfigList::setOptionMode); + connect(optGroup, &QActionGroup::triggered, + menuList, &ConfigList::setOptionMode); ConfigList::showNormalAction = new QAction("Show Normal Options", optGroup); ConfigList::showNormalAction->setCheckable(true); @@ -1423,13 +1440,16 @@ ConfigMainWindow::ConfigMainWindow(void) QAction *showDebugAction = new QAction("Show Debug Info", this); showDebugAction->setCheckable(true); - connect(showDebugAction, SIGNAL(toggled(bool)), helpText, SLOT(setShowDebug(bool))); + connect(showDebugAction, &QAction::toggled, + helpText, &ConfigInfoView::setShowDebug); showDebugAction->setChecked(helpText->showDebug()); QAction *showIntroAction = new QAction("Introduction", this); - connect(showIntroAction, SIGNAL(triggered(bool)), SLOT(showIntro())); + connect(showIntroAction, &QAction::triggered, + this, &ConfigMainWindow::showIntro); QAction *showAboutAction = new QAction("About", this); - connect(showAboutAction, SIGNAL(triggered(bool)), SLOT(showAbout())); + connect(showAboutAction, &QAction::triggered, + this, &ConfigMainWindow::showAbout); // init tool bar QToolBar *toolBar = addToolBar("Tools"); @@ -1467,30 +1487,30 @@ ConfigMainWindow::ConfigMainWindow(void) menu->addAction(showIntroAction); menu->addAction(showAboutAction); - connect (helpText, SIGNAL (anchorClicked (const QUrl &)), - helpText, SLOT (clicked (const QUrl &)) ); - - connect(configList, SIGNAL(menuChanged(struct menu *)), - helpText, SLOT(setInfo(struct menu *))); - connect(configList, SIGNAL(menuSelected(struct menu *)), - SLOT(changeMenu(struct menu *))); - connect(configList, SIGNAL(itemSelected(struct menu *)), - SLOT(changeItens(struct menu *))); - connect(configList, SIGNAL(parentSelected()), - SLOT(goBack())); - connect(menuList, SIGNAL(menuChanged(struct menu *)), - helpText, SLOT(setInfo(struct menu *))); - connect(menuList, SIGNAL(menuSelected(struct menu *)), - SLOT(changeMenu(struct menu *))); - - connect(configList, SIGNAL(gotFocus(struct menu *)), - helpText, SLOT(setInfo(struct menu *))); - connect(menuList, SIGNAL(gotFocus(struct menu *)), - helpText, SLOT(setInfo(struct menu *))); - connect(menuList, SIGNAL(gotFocus(struct menu *)), - SLOT(listFocusChanged(void))); - connect(helpText, SIGNAL(menuSelected(struct menu *)), - SLOT(setMenuLink(struct menu *))); + connect(helpText, &ConfigInfoView::anchorClicked, + helpText, &ConfigInfoView::clicked); + + connect(configList, &ConfigList::menuChanged, + helpText, &ConfigInfoView::setInfo); + connect(configList, &ConfigList::menuSelected, + this, &ConfigMainWindow::changeMenu); + connect(configList, &ConfigList::itemSelected, + this, &ConfigMainWindow::changeItens); + connect(configList, &ConfigList::parentSelected, + this, &ConfigMainWindow::goBack); + connect(menuList, &ConfigList::menuChanged, + helpText, &ConfigInfoView::setInfo); + connect(menuList, &ConfigList::menuSelected, + this, &ConfigMainWindow::changeMenu); + + connect(configList, &ConfigList::gotFocus, + helpText, &ConfigInfoView::setInfo); + connect(menuList, &ConfigList::gotFocus, + helpText, &ConfigInfoView::setInfo); + connect(menuList, &ConfigList::gotFocus, + this, &ConfigMainWindow::listFocusChanged); + connect(helpText, &ConfigInfoView::menuSelected, + this, &ConfigMainWindow::setMenuLink); QString listMode = configSettings->value("/listMode", "symbol").toString(); if (listMode == "single") -- cgit From 98ebea7ba891569c3678c5cd2fd1960098e84f4e Mon Sep 17 00:00:00 2001 From: Boris Kolpackov Date: Thu, 29 Oct 2020 17:51:51 +0200 Subject: kconfig: make lkc.h self-sufficient #include-wise Signed-off-by: Boris Kolpackov Signed-off-by: Masahiro Yamada --- scripts/kconfig/lkc.h | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'scripts') diff --git a/scripts/kconfig/lkc.h b/scripts/kconfig/lkc.h index 8454649b17bd..bee2413bda63 100644 --- a/scripts/kconfig/lkc.h +++ b/scripts/kconfig/lkc.h @@ -6,6 +6,10 @@ #ifndef LKC_H #define LKC_H +#include +#include +#include + #include "expr.h" #ifdef __cplusplus -- cgit From f463269fb940d2a4259169b1e87aab8d259a9ec4 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Mon, 2 Nov 2020 11:59:57 +0900 Subject: kconfig: qconf: show Qt version in the About dialog You can get the Qt version by running "pkg-config --modversion Qt5Core" or something, but this might be useful to get the runtime Qt version more easily. Go to the menu "Help" -> "About", then you can see it. Signed-off-by: Masahiro Yamada --- scripts/kconfig/qconf.cc | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) (limited to 'scripts') diff --git a/scripts/kconfig/qconf.cc b/scripts/kconfig/qconf.cc index cbe749b44b1a..d000869b787c 100644 --- a/scripts/kconfig/qconf.cc +++ b/scripts/kconfig/qconf.cc @@ -1799,10 +1799,13 @@ void ConfigMainWindow::showIntro(void) void ConfigMainWindow::showAbout(void) { static const QString str = "qconf is Copyright (C) 2002 Roman Zippel .\n" - "Copyright (C) 2015 Boris Barbulovski .\n\n" - "Bug reports and feature request can also be entered at http://bugzilla.kernel.org/\n"; + "Copyright (C) 2015 Boris Barbulovski .\n" + "\n" + "Bug reports and feature request can also be entered at http://bugzilla.kernel.org/\n" + "\n" + "Qt Version: "; - QMessageBox::information(this, "qconf", str); + QMessageBox::information(this, "qconf", str + qVersion()); } void ConfigMainWindow::saveSettings(void) -- cgit From 78cb09078352d032b12e2af7feb9b5b7f0fa794c Mon Sep 17 00:00:00 2001 From: Boris Kolpackov Date: Mon, 23 Nov 2020 11:38:18 +0200 Subject: kconfig: clean up header inclusion - Add missing includes. - Remove no longer necessary includes. Signed-off-by: Boris Kolpackov Signed-off-by: Masahiro Yamada --- scripts/kconfig/conf.c | 1 - scripts/kconfig/confdata.c | 1 + scripts/kconfig/lexer.l | 1 - scripts/kconfig/symbol.c | 2 +- 4 files changed, 2 insertions(+), 3 deletions(-) (limited to 'scripts') diff --git a/scripts/kconfig/conf.c b/scripts/kconfig/conf.c index f6e548b8f795..db03e2f45de4 100644 --- a/scripts/kconfig/conf.c +++ b/scripts/kconfig/conf.c @@ -11,7 +11,6 @@ #include #include #include -#include #include #include diff --git a/scripts/kconfig/confdata.c b/scripts/kconfig/confdata.c index a39d93e3c6ae..2568dbe16ed6 100644 --- a/scripts/kconfig/confdata.c +++ b/scripts/kconfig/confdata.c @@ -5,6 +5,7 @@ #include #include +#include #include #include #include diff --git a/scripts/kconfig/lexer.l b/scripts/kconfig/lexer.l index 240109f965ae..9c22cb554673 100644 --- a/scripts/kconfig/lexer.l +++ b/scripts/kconfig/lexer.l @@ -12,7 +12,6 @@ #include #include #include -#include #include "lkc.h" #include "parser.tab.h" diff --git a/scripts/kconfig/symbol.c b/scripts/kconfig/symbol.c index ffa3ec65cc90..fe38e6fd2c2a 100644 --- a/scripts/kconfig/symbol.c +++ b/scripts/kconfig/symbol.c @@ -3,11 +3,11 @@ * Copyright (C) 2002 Roman Zippel */ +#include #include #include #include #include -#include #include "lkc.h" -- cgit From 33114c4359592d5c8a3d840eee9ff40039caf26f Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Sun, 13 Dec 2020 01:54:29 +0900 Subject: kbuild: do not use scripts/ld-version.sh for checking spatch version scripts/ld-version.sh was, as its file name implies, originally intended for the GNU ld version, but is (ab)used for the spatch version too. Use 'sort -CV' for the version comparison, then coccicheck does not need to use scripts/ld-version.sh. Fix nsdeps as well. Signed-off-by: Masahiro Yamada Signed-off-by: Julia Lawall --- scripts/coccicheck | 14 +++++--------- scripts/nsdeps | 4 +--- 2 files changed, 6 insertions(+), 12 deletions(-) (limited to 'scripts') diff --git a/scripts/coccicheck b/scripts/coccicheck index 209bb0427b43..d7f6b7ff130a 100755 --- a/scripts/coccicheck +++ b/scripts/coccicheck @@ -16,7 +16,6 @@ if [ ! -x "$SPATCH" ]; then fi SPATCH_VERSION=$($SPATCH --version | head -1 | awk '{print $3}') -SPATCH_VERSION_NUM=$(echo $SPATCH_VERSION | ${DIR}/scripts/ld-version.sh) USE_JOBS="no" $SPATCH --help | grep "\-\-jobs" > /dev/null && USE_JOBS="yes" @@ -186,14 +185,11 @@ coccinelle () { OPT=`grep "Options:" $COCCI | cut -d':' -f2` REQ=`grep "Requires:" $COCCI | cut -d':' -f2 | sed "s| ||"` - REQ_NUM=$(echo $REQ | ${DIR}/scripts/ld-version.sh) - if [ "$REQ_NUM" != "0" ] ; then - if [ "$SPATCH_VERSION_NUM" -lt "$REQ_NUM" ] ; then - echo "Skipping coccinelle SmPL patch: $COCCI" - echo "You have coccinelle: $SPATCH_VERSION" - echo "This SmPL patch requires: $REQ" - return - fi + if [ -n "$REQ" ] && ! { echo "$REQ"; echo "$SPATCH_VERSION"; } | sort -CV ; then + echo "Skipping coccinelle SmPL patch: $COCCI" + echo "You have coccinelle: $SPATCH_VERSION" + echo "This SmPL patch requires: $REQ" + return fi # The option '--parse-cocci' can be used to syntactically check the SmPL files. diff --git a/scripts/nsdeps b/scripts/nsdeps index dab4c1a0e27d..e8ce2a4d704a 100644 --- a/scripts/nsdeps +++ b/scripts/nsdeps @@ -12,11 +12,9 @@ if [ ! -x "$SPATCH" ]; then exit 1 fi -SPATCH_REQ_VERSION_NUM=$(echo $SPATCH_REQ_VERSION | ${DIR}/scripts/ld-version.sh) SPATCH_VERSION=$($SPATCH --version | head -1 | awk '{print $3}') -SPATCH_VERSION_NUM=$(echo $SPATCH_VERSION | ${DIR}/scripts/ld-version.sh) -if [ "$SPATCH_VERSION_NUM" -lt "$SPATCH_REQ_VERSION_NUM" ] ; then +if ! { echo "$SPATCH_REQ_VERSION"; echo "$SPATCH_VERSION"; } | sort -CV ; then echo "spatch needs to be version $SPATCH_REQ_VERSION or higher" exit 1 fi -- cgit From b784c77075023e1a71bc06e6b4f711acb99e9c73 Mon Sep 17 00:00:00 2001 From: Maxime Ripard Date: Tue, 15 Dec 2020 13:24:59 +0100 Subject: coccinnelle: Remove ptr_ret script The ptr_ret script script addresses a number of situations where we end up testing an error pointer, and if it's an error returning it, or return 0 otherwise to transform it into a PTR_ERR_OR_ZERO call. So it will convert a block like this: if (IS_ERR(err)) return PTR_ERR(err); return 0; into return PTR_ERR_OR_ZERO(err); While this is technically correct, it has a number of drawbacks. First, it merges the error and success path, which will make it harder for a reviewer or reader to grasp. It's also more difficult to extend if we were to add some code between the error check and the function return, making the author essentially revert that patch before adding new lines, while it would have been a trivial addition otherwise for the rewiever. Therefore, since that script is only about cosmetic in the first place, let's remove it since it's not worth it. Acked-by: Jani Nikula Acked-by: Thierry Reding Acked-by: Julia Lawall Reviewed-by: Wolfram Sang Reviewed-by: Mark Brown Signed-off-by: Maxime Ripard Signed-off-by: Julia Lawall --- scripts/coccinelle/api/ptr_ret.cocci | 97 ------------------------------------ 1 file changed, 97 deletions(-) delete mode 100644 scripts/coccinelle/api/ptr_ret.cocci (limited to 'scripts') diff --git a/scripts/coccinelle/api/ptr_ret.cocci b/scripts/coccinelle/api/ptr_ret.cocci deleted file mode 100644 index e76cd5d90a8a..000000000000 --- a/scripts/coccinelle/api/ptr_ret.cocci +++ /dev/null @@ -1,97 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -/// -/// Use PTR_ERR_OR_ZERO rather than if(IS_ERR(...)) + PTR_ERR -/// -// Confidence: High -// Copyright: (C) 2012 Julia Lawall, INRIA/LIP6. -// Copyright: (C) 2012 Gilles Muller, INRIA/LiP6. -// URL: http://coccinelle.lip6.fr/ -// Options: --no-includes --include-headers -// -// Keywords: ERR_PTR, PTR_ERR, PTR_ERR_OR_ZERO -// Version min: 2.6.39 -// - -virtual context -virtual patch -virtual org -virtual report - -@depends on patch@ -expression ptr; -@@ - -- if (IS_ERR(ptr)) return PTR_ERR(ptr); else return 0; -+ return PTR_ERR_OR_ZERO(ptr); - -@depends on patch@ -expression ptr; -@@ - -- if (IS_ERR(ptr)) return PTR_ERR(ptr); return 0; -+ return PTR_ERR_OR_ZERO(ptr); - -@depends on patch@ -expression ptr; -@@ - -- (IS_ERR(ptr) ? PTR_ERR(ptr) : 0) -+ PTR_ERR_OR_ZERO(ptr) - -@r1 depends on !patch@ -expression ptr; -position p1; -@@ - -* if@p1 (IS_ERR(ptr)) return PTR_ERR(ptr); else return 0; - -@r2 depends on !patch@ -expression ptr; -position p2; -@@ - -* if@p2 (IS_ERR(ptr)) return PTR_ERR(ptr); return 0; - -@r3 depends on !patch@ -expression ptr; -position p3; -@@ - -* IS_ERR@p3(ptr) ? PTR_ERR(ptr) : 0 - -@script:python depends on org@ -p << r1.p1; -@@ - -coccilib.org.print_todo(p[0], "WARNING: PTR_ERR_OR_ZERO can be used") - - -@script:python depends on org@ -p << r2.p2; -@@ - -coccilib.org.print_todo(p[0], "WARNING: PTR_ERR_OR_ZERO can be used") - -@script:python depends on org@ -p << r3.p3; -@@ - -coccilib.org.print_todo(p[0], "WARNING: PTR_ERR_OR_ZERO can be used") - -@script:python depends on report@ -p << r1.p1; -@@ - -coccilib.report.print_report(p[0], "WARNING: PTR_ERR_OR_ZERO can be used") - -@script:python depends on report@ -p << r2.p2; -@@ - -coccilib.report.print_report(p[0], "WARNING: PTR_ERR_OR_ZERO can be used") - -@script:python depends on report@ -p << r3.p3; -@@ - -coccilib.report.print_report(p[0], "WARNING: PTR_ERR_OR_ZERO can be used") -- cgit From 1db81a682a2f2a664489c4e94f3b945f70a43a13 Mon Sep 17 00:00:00 2001 From: Dwaipayan Ray Date: Tue, 15 Dec 2020 20:44:20 -0800 Subject: checkpatch: add new exception to repeated word check Recently, commit 4f6ad8aa1eac ("checkpatch: move repeated word test") moved the repeated word test to check for more file types. But after this, if checkpatch.pl is run on MAINTAINERS, it generates several new warnings of the type: WARNING: Possible repeated word: 'git' For example: WARNING: Possible repeated word: 'git' +T: git git://git.kernel.org/pub/scm/linux/kernel/git/rw/uml.git So, the pattern "git git://..." is a false positive in this case. There are several other combinations which may produce a wrong warning message, such as "@size size", ":Begin begin", etc. Extend repeated word check to compare the characters before and after the word matches. If there is a non whitespace character before the first word or a non whitespace character excluding punctuation characters after the second word, then the check is skipped and the warning is avoided. Also add case insensitive word matching to the repeated word check. Link: https://lore.kernel.org/linux-kernel-mentees/81b6a0bb2c7b9256361573f7a13201ebcd4876f1.camel@perches.com/ Link: https://lkml.kernel.org/r/20201017162732.152351-1-dwaipayanray1@gmail.com Signed-off-by: Dwaipayan Ray Suggested-by: Joe Perches Suggested-by: Lukas Bulwahn Acked-by: Joe Perches Cc: Aditya Srivastava Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- scripts/checkpatch.pl | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) (limited to 'scripts') diff --git a/scripts/checkpatch.pl b/scripts/checkpatch.pl index fab38b493cef..7e505688257a 100755 --- a/scripts/checkpatch.pl +++ b/scripts/checkpatch.pl @@ -3050,19 +3050,30 @@ sub process { # check for repeated words separated by a single space if ($rawline =~ /^\+/ || $in_commit_log) { + pos($rawline) = 1 if (!$in_commit_log); while ($rawline =~ /\b($word_pattern) (?=($word_pattern))/g) { my $first = $1; my $second = $2; - + my $start_pos = $-[1]; + my $end_pos = $+[2]; if ($first =~ /(?:struct|union|enum)/) { pos($rawline) += length($first) + length($second) + 1; next; } - next if ($first ne $second); + next if (lc($first) ne lc($second)); next if ($first eq 'long'); + # check for character before and after the word matches + my $start_char = ''; + my $end_char = ''; + $start_char = substr($rawline, $start_pos - 1, 1) if ($start_pos > ($in_commit_log ? 0 : 1)); + $end_char = substr($rawline, $end_pos, 1) if ($end_pos < length($rawline)); + + next if ($start_char =~ /^\S$/); + next if (index(" \t.,;?!", $end_char) == -1); + if (WARN("REPEATED_WORD", "Possible repeated word: '$first'\n" . $herecurr) && $fix) { -- cgit From 8d0325cc74a31d517b5b4307c8d895c6e81076b7 Mon Sep 17 00:00:00 2001 From: Aditya Srivastava Date: Tue, 15 Dec 2020 20:44:24 -0800 Subject: checkpatch: fix false positives in REPEATED_WORD warning Presence of hexadecimal address or symbol results in false warning message by checkpatch.pl. For example, running checkpatch on commit b8ad540dd4e4 ("mptcp: fix memory leak in mptcp_subflow_create_socket()") results in warning: WARNING:REPEATED_WORD: Possible repeated word: 'ff' 00 00 00 00 00 00 00 00 00 2f 30 0a 81 88 ff ff ........./0..... Similarly, the presence of list command output in commit results in an unnecessary warning. For example, running checkpatch on commit 899e5ffbf246 ("perf record: Introduce --switch-output-event") gives: WARNING:REPEATED_WORD: Possible repeated word: 'root' dr-xr-x---. 12 root root 4096 Apr 27 17:46 .. Here, it reports 'ff' and 'root' to be repeated, but it is in fact part of some address or code, where it has to be repeated. In these cases, the intent of the warning to find stylistic issues in commit messages is not met and the warning is just completely wrong in this case. To avoid these warnings, add an additional regex check for the directory permission pattern and avoid checking the line for this class of warning. Similarly, to avoid hex pattern, check if the word consists of hex symbols and skip this warning if it is not among the common english words formed using hex letters. A quick evaluation on v5.6..v5.8 showed that this fix reduces REPEATED_WORD warnings by the frequency of 1890. A quick manual check found all cases are related to hex output or list command outputs in commit messages. Link: https://lkml.kernel.org/r/20201024102253.13614-1-yashsri421@gmail.com Signed-off-by: Aditya Srivastava Acked-by: Joe Perches Cc: Dwaipayan Ray Cc: Lukas Bulwahn Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- scripts/checkpatch.pl | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) (limited to 'scripts') diff --git a/scripts/checkpatch.pl b/scripts/checkpatch.pl index 7e505688257a..519da711cb12 100755 --- a/scripts/checkpatch.pl +++ b/scripts/checkpatch.pl @@ -853,6 +853,13 @@ our $declaration_macros = qr{(?x: (?:SKCIPHER_REQUEST|SHASH_DESC|AHASH_REQUEST)_ON_STACK\s*\( )}; +our %allow_repeated_words = ( + add => '', + added => '', + bad => '', + be => '', +); + sub deparenthesize { my ($string) = @_; return "" if (!defined($string)); @@ -3049,7 +3056,9 @@ sub process { } # check for repeated words separated by a single space - if ($rawline =~ /^\+/ || $in_commit_log) { +# avoid false positive from list command eg, '-rw-r--r-- 1 root root' + if (($rawline =~ /^\+/ || $in_commit_log) && + $rawline !~ /[bcCdDlMnpPs\?-][rwxsStT-]{9}/) { pos($rawline) = 1 if (!$in_commit_log); while ($rawline =~ /\b($word_pattern) (?=($word_pattern))/g) { @@ -3074,6 +3083,11 @@ sub process { next if ($start_char =~ /^\S$/); next if (index(" \t.,;?!", $end_char) == -1); + # avoid repeating hex occurrences like 'ff ff fe 09 ...' + if ($first =~ /\b[0-9a-f]{2,}\b/i) { + next if (!exists($allow_repeated_words{lc($first)})); + } + if (WARN("REPEATED_WORD", "Possible repeated word: '$first'\n" . $herecurr) && $fix) { -- cgit From 4104a20646fe20ed5aa9be883eef7340b219f9a8 Mon Sep 17 00:00:00 2001 From: Łukasz Stelmach Date: Tue, 15 Dec 2020 20:44:27 -0800 Subject: checkpatch: ignore generated CamelCase defines and enum values MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Ignore autogenerated CamelCase-like defines and enum values like DRM_MODE_CONNECTOR_Unknown or ETHTOOL_LINK_MODE_Asym_Pause_BIT. Link: https://lkml.kernel.org/r/20201022184916.7904-1-l.stelmach@samsung.com Signed-off-by: Łukasz Stelmach Suggested-by: Joe Perches Acked-by: Joe Perches Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- scripts/checkpatch.pl | 2 ++ 1 file changed, 2 insertions(+) (limited to 'scripts') diff --git a/scripts/checkpatch.pl b/scripts/checkpatch.pl index 519da711cb12..6bbc24e66916 100755 --- a/scripts/checkpatch.pl +++ b/scripts/checkpatch.pl @@ -5320,6 +5320,8 @@ sub process { #CamelCase if ($var !~ /^$Constant$/ && $var =~ /[A-Z][a-z]|[a-z][A-Z]/ && +#Ignore some autogenerated defines and enum values + $var !~ /^(?:[A-Z]+_){1,5}[A-Z]{1,3}[a-z]/ && #Ignore Page variants $var !~ /^(?:Clear|Set|TestClear|TestSet|)Page[A-Z]/ && #Ignore SI style variants like nS, mV and dB -- cgit From 73169765e6e7ac54528778faa592b15df5c8a93c Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Tue, 15 Dec 2020 20:44:30 -0800 Subject: checkpatch: prefer static const declarations There are about 100,000 uses of 'static const ' but about 400 uses of 'static const' in the kernel where type is not a pointer. The kernel almost always uses "static const" over "const static" as there is a compiler warning for that declaration style. But there is no compiler warning for "static const". So add a checkpatch warning for the atypical declaration uses of. const static and static const For example: $ ./scripts/checkpatch.pl -f --emacs --quiet --nosummary -types=static_const arch/arm/crypto/aes-ce-glue.c arch/arm/crypto/aes-ce-glue.c:75: WARNING: Move const after static - use 'static const u8' #75: FILE: arch/arm/crypto/aes-ce-glue.c:75: + static u8 const rcon[] = { Link: https://lkml.kernel.org/r/4b863be68e679546b40d50b97a4a806c03056a1c.camel@perches.com Signed-off-by: Joe Perches Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- scripts/checkpatch.pl | 12 ++++++++++++ 1 file changed, 12 insertions(+) (limited to 'scripts') diff --git a/scripts/checkpatch.pl b/scripts/checkpatch.pl index 6bbc24e66916..4018bf89e63a 100755 --- a/scripts/checkpatch.pl +++ b/scripts/checkpatch.pl @@ -4232,6 +4232,18 @@ sub process { } } +# check for const static or static const declarations +# prefer 'static const ' over 'const static ' and 'static const' + if ($sline =~ /^\+\s*const\s+static\s+($Type)\b/ || + $sline =~ /^\+\s*static\s+($BasicType)\s+const\b/) { + if (WARN("STATIC_CONST", + "Move const after static - use 'static const $1'\n" . $herecurr) && + $fix) { + $fixed[$fixlinenr] =~ s/\bconst\s+static\b/static const/; + $fixed[$fixlinenr] =~ s/\bstatic\s+($BasicType)\s+const\b/static const $1/; + } + } + # check for non-global char *foo[] = {"bar", ...} declarations. if ($line =~ /^.\s+(?:static\s+|const\s+)?char\s+\*\s*\w+\s*\[\s*\]\s*=\s*\{/) { WARN("STATIC_CONST_CHAR_ARRAY", -- cgit From dc58bc553e7a8e1d6eeaffd92cb8b346e0d62f70 Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Tue, 15 Dec 2020 20:44:33 -0800 Subject: checkpatch: allow --fix removal of unnecessary break statements switch/case use of break after a return, goto or break is unnecessary. There is an existing warning for the return and goto uses, so add break and a --fix option too. Link: https://lkml.kernel.org/r/d9ea654104d55f590fb97d252d64a66b23c1a096.camel@perches.com Signed-off-by: Joe Perches Cc: Julia Lawall Cc: Tom Rix Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- scripts/checkpatch.pl | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) (limited to 'scripts') diff --git a/scripts/checkpatch.pl b/scripts/checkpatch.pl index 4018bf89e63a..c128875b6666 100755 --- a/scripts/checkpatch.pl +++ b/scripts/checkpatch.pl @@ -3699,12 +3699,16 @@ sub process { } # check indentation of a line with a break; -# if the previous line is a goto or return and is indented the same # of tabs +# if the previous line is a goto, return or break +# and is indented the same # of tabs if ($sline =~ /^\+([\t]+)break\s*;\s*$/) { my $tabs = $1; - if ($prevline =~ /^\+$tabs(?:goto|return)\b/) { - WARN("UNNECESSARY_BREAK", - "break is not useful after a goto or return\n" . $hereprev); + if ($prevline =~ /^\+$tabs(goto|return|break)\b/) { + if (WARN("UNNECESSARY_BREAK", + "break is not useful after a $1\n" . $hereprev) && + $fix) { + fix_delete_line($fixlinenr, $rawline); + } } } -- cgit From 7ebe1d173cae0778fa748ea3f2ae20dfa0f58e10 Mon Sep 17 00:00:00 2001 From: Dwaipayan Ray Date: Tue, 15 Dec 2020 20:44:36 -0800 Subject: checkpatch: extend attributes check to handle more patterns It is generally preferred that the macros from include/linux/compiler_attributes.h are used, unless there is a reason not to. checkpatch currently checks __attribute__ for each of packed, aligned, section, printf, scanf, and weak. Other declarations in compiler_attributes.h are not handled. Add a generic test to check the presence of such attributes. Some attributes require more specific handling and are kept separate. Also add fixes to the generic attributes check to substitute the correct conversions. New attributes which are now handled are: __always_inline__ __assume_aligned__(a, ## __VA_ARGS__) __cold__ __const__ __copy__(symbol) __designated_init__ __externally_visible__ __gnu_inline__ __malloc__ __mode__(x) __no_caller_saved_registers__ __noclone__ __noinline__ __nonstring__ __noreturn__ __pure__ __unused__ __used__ Declarations which contain multiple attributes like __attribute__((__packed__, __cold__)) are also handled except when proper conversions for one or more attributes of the list cannot be determined. Link: https://lore.kernel.org/linux-kernel-mentees/3ec15b41754b01666d94b76ce51b9832c2dd577a.camel@perches.com/ Link: https://lkml.kernel.org/r/20201025193103.23223-1-dwaipayanray1@gmail.com Signed-off-by: Dwaipayan Ray Suggested-by: Joe Perches Acked-by: Joe Perches Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- scripts/checkpatch.pl | 109 ++++++++++++++++++++++++++++++++------------------ 1 file changed, 71 insertions(+), 38 deletions(-) (limited to 'scripts') diff --git a/scripts/checkpatch.pl b/scripts/checkpatch.pl index c128875b6666..92949b8c5c76 100755 --- a/scripts/checkpatch.pl +++ b/scripts/checkpatch.pl @@ -6187,50 +6187,83 @@ sub process { } } -# Check for __attribute__ packed, prefer __packed +# Check for compiler attributes if ($realfile !~ m@\binclude/uapi/@ && - $line =~ /\b__attribute__\s*\(\s*\(.*\bpacked\b/) { - WARN("PREFER_PACKED", - "__packed is preferred over __attribute__((packed))\n" . $herecurr); - } - -# Check for __attribute__ aligned, prefer __aligned - if ($realfile !~ m@\binclude/uapi/@ && - $line =~ /\b__attribute__\s*\(\s*\(.*aligned/) { - WARN("PREFER_ALIGNED", - "__aligned(size) is preferred over __attribute__((aligned(size)))\n" . $herecurr); - } - -# Check for __attribute__ section, prefer __section - if ($realfile !~ m@\binclude/uapi/@ && - $line =~ /\b__attribute__\s*\(\s*\(.*_*section_*\s*\(\s*("[^"]*")/) { - my $old = substr($rawline, $-[1], $+[1] - $-[1]); - my $new = substr($old, 1, -1); - if (WARN("PREFER_SECTION", - "__section($new) is preferred over __attribute__((section($old)))\n" . $herecurr) && - $fix) { - $fixed[$fixlinenr] =~ s/\b__attribute__\s*\(\s*\(\s*_*section_*\s*\(\s*\Q$old\E\s*\)\s*\)\s*\)/__section($new)/; + $rawline =~ /\b__attribute__\s*\(\s*($balanced_parens)\s*\)/) { + my $attr = $1; + $attr =~ s/\s*\(\s*(.*)\)\s*/$1/; + + my %attr_list = ( + "aligned" => "__aligned", + "always_inline" => "__always_inline", + "assume_aligned" => "__assume_aligned", + "cold" => "__cold", + "const" => "__attribute_const__", + "copy" => "__copy", + "designated_init" => "__designated_init", + "externally_visible" => "__visible", + "format" => "printf|scanf", + "gnu_inline" => "__gnu_inline", + "malloc" => "__malloc", + "mode" => "__mode", + "no_caller_saved_registers" => "__no_caller_saved_registers", + "noclone" => "__noclone", + "noinline" => "noinline", + "nonstring" => "__nonstring", + "noreturn" => "__noreturn", + "packed" => "__packed", + "pure" => "__pure", + "used" => "__used" + ); + + my @conv_array = (); + my $conv_possible = 1; + + while ($attr =~ /\s*(\w+)\s*(${balanced_parens})?/g) { + my $curr_attr = $1; + my $params = ''; + $params = $2 if defined($2); + $curr_attr =~ s/^[\s_]+|[\s_]+$//g; + + if (exists($attr_list{$curr_attr})) { + if ($curr_attr eq "format" && $params) { + $params =~ /^\s*\(\s*(\w+)\s*,\s*(.*)/; + push(@conv_array, "__$1\($2"); + } else { + my $new = $attr_list{$curr_attr}; + push(@conv_array, "$new$params"); + } + } else { + $conv_possible = 0; + last; + } } - } -# Check for __attribute__ format(printf, prefer __printf - if ($realfile !~ m@\binclude/uapi/@ && - $line =~ /\b__attribute__\s*\(\s*\(\s*format\s*\(\s*printf/) { - if (WARN("PREFER_PRINTF", - "__printf(string-index, first-to-check) is preferred over __attribute__((format(printf, string-index, first-to-check)))\n" . $herecurr) && - $fix) { - $fixed[$fixlinenr] =~ s/\b__attribute__\s*\(\s*\(\s*format\s*\(\s*printf\s*,\s*(.*)\)\s*\)\s*\)/"__printf(" . trim($1) . ")"/ex; + if (scalar @conv_array > 0 && $conv_possible == 1) { + my $replace = join(' ', @conv_array); + if (WARN("PREFER_DEFINED_ATTRIBUTE_MACRO", + "$replace is preferred over __attribute__(($attr))\n" . $herecurr) && + $fix) { + $fixed[$fixlinenr] =~ s/\b__attribute__\s*\(\s*\(\s*\Q$attr\E\s*\)\s*\)/$replace/; + $fixed[$fixlinenr] =~ s/\}\Q$replace\E/} $replace/; + } + } + # Check for __attribute__ section, prefer __section + if ($attr =~ /^_*section_*\s*\(\s*("[^"]*")/) { + my $old = substr($attr, $-[1], $+[1] - $-[1]); + my $new = substr($old, 1, -1); + if (WARN("PREFER_DEFINED_ATTRIBUTE_MACRO", + "__section($new) is preferred over __attribute__((section($old)))\n" . $herecurr) && + $fix) { + $fixed[$fixlinenr] =~ s/\b__attribute__\s*\(\s*\(\s*_*section_*\s*\(\s*\Q$old\E\s*\)\s*\)\s*\)/__section($new)/; + } } - } -# Check for __attribute__ format(scanf, prefer __scanf - if ($realfile !~ m@\binclude/uapi/@ && - $line =~ /\b__attribute__\s*\(\s*\(\s*format\s*\(\s*scanf\b/) { - if (WARN("PREFER_SCANF", - "__scanf(string-index, first-to-check) is preferred over __attribute__((format(scanf, string-index, first-to-check)))\n" . $herecurr) && - $fix) { - $fixed[$fixlinenr] =~ s/\b__attribute__\s*\(\s*\(\s*format\s*\(\s*scanf\s*,\s*(.*)\)\s*\)\s*\)/"__scanf(" . trim($1) . ")"/ex; + # Check for __attribute__ unused, prefer __always_unused or __maybe_unused + if ($attr =~ /^_*unused/) { + WARN("PREFER_DEFINED_ATTRIBUTE_MACRO", + "__always_unused or __maybe_unused is preferred over __attribute__((__unused__))\n" . $herecurr); } } -- cgit From 47ca69b85821e150cfbbe86a18a038e9488c0090 Mon Sep 17 00:00:00 2001 From: Tom Rix Date: Tue, 15 Dec 2020 20:44:40 -0800 Subject: checkpatch: add a fixer for missing newline at eof Remove the trailing error message from the fixed lines. Link: https://lkml.kernel.org/r/20201017142546.28988-1-trix@redhat.com Signed-off-by: Tom Rix Acked-by: Joe Perches Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- scripts/checkpatch.pl | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'scripts') diff --git a/scripts/checkpatch.pl b/scripts/checkpatch.pl index 92949b8c5c76..7800a090e8fe 100755 --- a/scripts/checkpatch.pl +++ b/scripts/checkpatch.pl @@ -3418,8 +3418,11 @@ sub process { # check for adding lines without a newline. if ($line =~ /^\+/ && defined $lines[$linenr] && $lines[$linenr] =~ /^\\ No newline at end of file/) { - WARN("MISSING_EOF_NEWLINE", - "adding a line without newline at end of file\n" . $herecurr); + if (WARN("MISSING_EOF_NEWLINE", + "adding a line without newline at end of file\n" . $herecurr) && + $fix) { + fix_delete_line($fixlinenr+1, "No newline at end of file"); + } } # check we are in a valid source file C or perl if not then ignore this hunk -- cgit From 339f29d91acf3f49bcf919f0e11437438f58559a Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Tue, 15 Dec 2020 20:44:43 -0800 Subject: checkpatch: update __attribute__((section("name"))) quote removal commit 33def8498fdd ("treewide: Convert macro and uses of __section(foo) to __section("foo")") removed the stringification of the section name and now requires quotes around the named section. Update checkpatch to not remove any quotes when suggesting conversion of __attribute__((section("name"))) to __section("name") Miscellanea: o Add section to the hash with __section replacement o Remove separate test for __attribute__((section o Remove the limitation on converting attributes containing only known, possible conversions. Any unknown attribute types are now left as-is and known types are converted and moved before __attribute__ and removed from within the __attribute__((list...)). [joe@perches.com: eliminate the separate test below the possible conversions loop] Link: https://lkml.kernel.org/r/58e9d55e933dc8fdc6af489f2ad797fa8eb13e44.camel@perches.com Link: https://lkml.kernel.org/r/c04dd1c810e8d6a68e6a632e3191ae91651c8edf.camel@perches.com Signed-off-by: Joe Perches Cc: Dwaipayan Ray Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- scripts/checkpatch.pl | 47 +++++++++++++++-------------------------------- 1 file changed, 15 insertions(+), 32 deletions(-) (limited to 'scripts') diff --git a/scripts/checkpatch.pl b/scripts/checkpatch.pl index 7800a090e8fe..58095d9d8f34 100755 --- a/scripts/checkpatch.pl +++ b/scripts/checkpatch.pl @@ -6216,50 +6216,33 @@ sub process { "noreturn" => "__noreturn", "packed" => "__packed", "pure" => "__pure", + "section" => "__section", "used" => "__used" ); - my @conv_array = (); - my $conv_possible = 1; - while ($attr =~ /\s*(\w+)\s*(${balanced_parens})?/g) { - my $curr_attr = $1; + my $orig_attr = $1; my $params = ''; $params = $2 if defined($2); + my $curr_attr = $orig_attr; $curr_attr =~ s/^[\s_]+|[\s_]+$//g; - if (exists($attr_list{$curr_attr})) { + my $new = $attr_list{$curr_attr}; if ($curr_attr eq "format" && $params) { $params =~ /^\s*\(\s*(\w+)\s*,\s*(.*)/; - push(@conv_array, "__$1\($2"); + $new = "__$1\($2"; } else { - my $new = $attr_list{$curr_attr}; - push(@conv_array, "$new$params"); + $new = "$new$params"; + } + if (WARN("PREFER_DEFINED_ATTRIBUTE_MACRO", + "Prefer $new over __attribute__(($orig_attr$params))\n" . $herecurr) && + $fix) { + my $remove = "\Q$orig_attr\E" . '\s*' . "\Q$params\E" . '(?:\s*,\s*)?'; + $fixed[$fixlinenr] =~ s/$remove//; + $fixed[$fixlinenr] =~ s/\b__attribute__/$new __attribute__/; + $fixed[$fixlinenr] =~ s/\}\Q$new\E/} $new/; + $fixed[$fixlinenr] =~ s/ __attribute__\s*\(\s*\(\s*\)\s*\)//; } - } else { - $conv_possible = 0; - last; - } - } - - if (scalar @conv_array > 0 && $conv_possible == 1) { - my $replace = join(' ', @conv_array); - if (WARN("PREFER_DEFINED_ATTRIBUTE_MACRO", - "$replace is preferred over __attribute__(($attr))\n" . $herecurr) && - $fix) { - $fixed[$fixlinenr] =~ s/\b__attribute__\s*\(\s*\(\s*\Q$attr\E\s*\)\s*\)/$replace/; - $fixed[$fixlinenr] =~ s/\}\Q$replace\E/} $replace/; - } - } - - # Check for __attribute__ section, prefer __section - if ($attr =~ /^_*section_*\s*\(\s*("[^"]*")/) { - my $old = substr($attr, $-[1], $+[1] - $-[1]); - my $new = substr($old, 1, -1); - if (WARN("PREFER_DEFINED_ATTRIBUTE_MACRO", - "__section($new) is preferred over __attribute__((section($old)))\n" . $herecurr) && - $fix) { - $fixed[$fixlinenr] =~ s/\b__attribute__\s*\(\s*\(\s*_*section_*\s*\(\s*\Q$old\E\s*\)\s*\)\s*\)/__section($new)/; } } -- cgit From 7580c5b9b464f8936be850ef278927671338bbf2 Mon Sep 17 00:00:00 2001 From: Aditya Srivastava Date: Tue, 15 Dec 2020 20:44:47 -0800 Subject: checkpatch: add fix option for GERRIT_CHANGE_ID Currently, whenever a Gerrit Change-Id is present in a commit, checkpatch.pl warns to remove the Change-Id before submitting the patch. E.g., running checkpatch on commit adc311a5bbf6 ("iwlwifi: bump FW API to 53 for 22000 series") reports this error: ERROR: Remove Gerrit Change-Id's before submitting upstream Change-Id: I5725e46394f3f53c3069723fd513cc53c7df383d Provide a simple fix option by simply deleting the indicated line. Link: https://lkml.kernel.org/r/20201030114447.24199-1-yashsri421@gmail.com Signed-off-by: Aditya Srivastava Acked-by: Joe Perches Cc: Lukas Bulwahn Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- scripts/checkpatch.pl | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'scripts') diff --git a/scripts/checkpatch.pl b/scripts/checkpatch.pl index 58095d9d8f34..3480bcb9bbc6 100755 --- a/scripts/checkpatch.pl +++ b/scripts/checkpatch.pl @@ -2852,8 +2852,11 @@ sub process { # Check for Gerrit Change-Ids not in any patch context if ($realfile eq '' && !$has_patch_separator && $line =~ /^\s*change-id:/i) { - ERROR("GERRIT_CHANGE_ID", - "Remove Gerrit Change-Id's before submitting upstream\n" . $herecurr); + if (ERROR("GERRIT_CHANGE_ID", + "Remove Gerrit Change-Id's before submitting upstream\n" . $herecurr) && + $fix) { + fix_delete_line($fixlinenr, $rawline); + } } # Check if the commit log is in a possible stack dump -- cgit From 0830aab0e1d4d9bd391e5723c39f4b3b002fffb3 Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Tue, 15 Dec 2020 20:44:50 -0800 Subject: checkpatch: add __alias and __weak to suggested __attribute__ conversions Add __alias and __weak to the suggested __attribute__(()) conversions. Link: https://lkml.kernel.org/r/7b74137743c58ce0633ec4d575b94e2210e4dbe7.camel@perches.com Signed-off-by: Joe Perches Cc: Dwaipayan Ray Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- scripts/checkpatch.pl | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'scripts') diff --git a/scripts/checkpatch.pl b/scripts/checkpatch.pl index 3480bcb9bbc6..5a1096a4e220 100755 --- a/scripts/checkpatch.pl +++ b/scripts/checkpatch.pl @@ -6200,6 +6200,7 @@ sub process { $attr =~ s/\s*\(\s*(.*)\)\s*/$1/; my %attr_list = ( + "alias" => "__alias", "aligned" => "__aligned", "always_inline" => "__always_inline", "assume_aligned" => "__assume_aligned", @@ -6220,7 +6221,8 @@ sub process { "packed" => "__packed", "pure" => "__pure", "section" => "__section", - "used" => "__used" + "used" => "__used", + "weak" => "__weak" ); while ($attr =~ /\s*(\w+)\s*(${balanced_parens})?/g) { -- cgit From fccaebf00e603694b892b46722a52db3d4298561 Mon Sep 17 00:00:00 2001 From: Dwaipayan Ray Date: Tue, 15 Dec 2020 20:44:53 -0800 Subject: checkpatch: improve email parsing checkpatch doesn't report warnings for many common mistakes in emails. Some of which are trailing commas and incorrect use of email comments. At the same time several false positives are reported due to incorrect handling of mail comments. The most common of which is due to the pattern: # X.X Improve email parsing in checkpatch. Some general email rules are defined: - Multiple name comments should not be allowed. - Comments inside address should not be allowed. - In general comments should be enclosed within parentheses. Relaxation is given to comments beginning with #. - Stable addresses should not begin with a name. - Comments in stable addresses should begin only with a #. Improvements to parsing: - Detect and report unexpected content after email. - Quoted names are excluded from comment parsing. - Trailing dots, commas or quotes in email are removed during formatting. Correspondingly a BAD_SIGN_OFF warning is emitted. - Improperly quoted email like '"name
"' are now warned about. In addition, added fixes for all the possible rules. Link: https://lore.kernel.org/linux-kernel-mentees/6c275d95c3033422addfc256a30e6ae3dd37941d.camel@perches.com/ Link: https://lore.kernel.org/linux-kernel-mentees/20201105200857.GC1333458@kroah.com/ Link: https://lkml.kernel.org/r/20201108100632.75340-1-dwaipayanray1@gmail.com Signed-off-by: Dwaipayan Ray Suggested-by: Joe Perches Acked-by: Joe Perches Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- scripts/checkpatch.pl | 108 ++++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 91 insertions(+), 17 deletions(-) (limited to 'scripts') diff --git a/scripts/checkpatch.pl b/scripts/checkpatch.pl index 5a1096a4e220..2749f32dffe9 100755 --- a/scripts/checkpatch.pl +++ b/scripts/checkpatch.pl @@ -1159,6 +1159,7 @@ sub parse_email { my ($formatted_email) = @_; my $name = ""; + my $quoted = ""; my $name_comment = ""; my $address = ""; my $comment = ""; @@ -1190,14 +1191,20 @@ sub parse_email { } } - $comment = trim($comment); - $name = trim($name); - $name =~ s/^\"|\"$//g; - if ($name =~ s/(\s*\([^\)]+\))\s*//) { - $name_comment = trim($1); + # Extract comments from names excluding quoted parts + # "John D. (Doe)" - Do not extract + if ($name =~ s/\"(.+)\"//) { + $quoted = $1; + } + while ($name =~ s/\s*($balanced_parens)\s*/ /) { + $name_comment .= trim($1); } + $name =~ s/^[ \"]+|[ \"]+$//g; + $name = trim("$quoted $name"); + $address = trim($address); $address =~ s/^\<|\>$//g; + $comment = trim($comment); if ($name =~ /[^\w \-]/i) { ##has "must quote" chars $name =~ s/(? 1) { WARN("BAD_SIGN_OFF", - "email address '$email' might be better as '$suggested_email'\n" . $herecurr); + "Use a single name comment in email: '$email'\n" . $herecurr); + } + + + # stable@vger.kernel.org or stable@kernel.org shouldn't + # have an email name. In addition commments should strictly + # begin with a # + if ($email =~ /^.*stable\@(?:vger\.)?kernel\.org/i) { + if (($comment ne "" && $comment !~ /^#.+/) || + ($email_name ne "")) { + my $cur_name = $email_name; + my $new_comment = $comment; + $cur_name =~ s/[a-zA-Z\s\-\"]+//g; + + # Remove brackets enclosing comment text + # and # from start of comments to get comment text + $new_comment =~ s/^\((.*)\)$/$1/; + $new_comment =~ s/^\[(.*)\]$/$1/; + $new_comment =~ s/^[\s\#]+|\s+$//g; + + $new_comment = trim("$new_comment $cur_name") if ($cur_name ne $new_comment); + $new_comment = " # $new_comment" if ($new_comment ne ""); + my $new_email = "$email_address$new_comment"; + + if (WARN("BAD_STABLE_ADDRESS_STYLE", + "Invalid email format for stable: '$email', prefer '$new_email'\n" . $herecurr) && + $fix) { + $fixed[$fixlinenr] =~ s/\Q$email\E/$new_email/; + } + } + } elsif ($comment ne "" && $comment !~ /^(?:#.+|\(.+\))$/) { + my $new_comment = $comment; + + # Extract comment text from within brackets or + # c89 style /*...*/ comments + $new_comment =~ s/^\[(.*)\]$/$1/; + $new_comment =~ s/^\/\*(.*)\*\/$/$1/; + + $new_comment = trim($new_comment); + $new_comment =~ s/^[^\w]$//; # Single lettered comment with non word character is usually a typo + $new_comment = "($new_comment)" if ($new_comment ne ""); + my $new_email = format_email($email_name, $name_comment, $email_address, $new_comment); + + if (WARN("BAD_SIGN_OFF", + "Unexpected content after email: '$email', should be: '$new_email'\n" . $herecurr) && + $fix) { + $fixed[$fixlinenr] =~ s/\Q$email\E/$new_email/; + } } } -- cgit From e73d27159400f3ed7300387ce5d69707af8bf0fd Mon Sep 17 00:00:00 2001 From: Dwaipayan Ray Date: Tue, 15 Dec 2020 20:44:56 -0800 Subject: checkpatch: fix spelling errors and remove repeated word Delete repeated word in scripts/checkpatch.pl: "are are" -> "are" Fix typos: "commments" -> "comments" "falsly" -> "falsely" Link: https://lkml.kernel.org/r/20201113152316.62975-1-dwaipayanray1@gmail.com Signed-off-by: Dwaipayan Ray Acked-by: Joe Perches Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- scripts/checkpatch.pl | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'scripts') diff --git a/scripts/checkpatch.pl b/scripts/checkpatch.pl index 2749f32dffe9..041b82f6669e 100755 --- a/scripts/checkpatch.pl +++ b/scripts/checkpatch.pl @@ -2841,7 +2841,7 @@ sub process { # stable@vger.kernel.org or stable@kernel.org shouldn't - # have an email name. In addition commments should strictly + # have an email name. In addition comments should strictly # begin with a # if ($email =~ /^.*stable\@(?:vger\.)?kernel\.org/i) { if (($comment ne "" && $comment !~ /^#.+/) || @@ -5000,7 +5000,7 @@ sub process { ## $line !~ /^.\s*$Type\s+$Ident(?:\s*=[^,{]*)?\s*,\s*$Type\s*$Ident.*/) { ## ## # Remove any bracketed sections to ensure we do not -## # falsly report the parameters of functions. +## # falsely report the parameters of functions. ## my $ln = $line; ## while ($ln =~ s/\([^\(\)]*\)//g) { ## } @@ -7109,7 +7109,7 @@ sub process { exit(0); } - # This is not a patch, and we are are in 'no-patch' mode so + # This is not a patch, and we are in 'no-patch' mode so # just keep quiet. if (!$chk_patch && !$is_patch) { exit(0); -- cgit From 27b379af61025e32a9baf3a33e939941682693ba Mon Sep 17 00:00:00 2001 From: Aditya Srivastava Date: Tue, 15 Dec 2020 20:44:59 -0800 Subject: checkpatch: avoid COMMIT_LOG_LONG_LINE warning for signature tags Currently checkpatch warns us for long lines in commits even for signature tag lines. Generally these lines exceed the 75-character limit because of: 1) long names and long email address 2) some comments on scoped review and acknowledgement, i.e., for a dedicated pointer on what was reported by the identity in 'Reported-by' 3) some additional comments on CC: stable@vger.org tags Exclude signature tag lines from this class of warning. There were 1896 COMMIT_LOG_LONG_LINE warnings in v5.6..v5.8 before this patch application and 1879 afterwards. A quick manual check found all the dropped warnings related to signature tags. Link: https://lkml.kernel.org/r/20201116083754.10629-1-yashsri421@gmail.com Signed-off-by: Aditya Srivastava Acked-by: Joe Perches Cc: Lukas Bulwahn Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- scripts/checkpatch.pl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'scripts') diff --git a/scripts/checkpatch.pl b/scripts/checkpatch.pl index 041b82f6669e..176ea2c189b8 100755 --- a/scripts/checkpatch.pl +++ b/scripts/checkpatch.pl @@ -2952,8 +2952,8 @@ sub process { # file delta changes $line =~ /^\s*(?:[\w\.\-]+\/)++[\w\.\-]+:/ || # filename then : - $line =~ /^\s*(?:Fixes:|Link:)/i || - # A Fixes: or Link: line + $line =~ /^\s*(?:Fixes:|Link:|$signature_tags)/i || + # A Fixes: or Link: line or signature tag line $commit_log_possible_stack_dump)) { WARN("COMMIT_LOG_LONG_LINE", "Possible unwrapped commit description (prefer a maximum 75 chars per line)\n" . $herecurr); -- cgit From 03f4935135b9efeb780b970ba023c201f81cf4e6 Mon Sep 17 00:00:00 2001 From: Dwaipayan Ray Date: Tue, 15 Dec 2020 20:45:02 -0800 Subject: checkpatch: fix unescaped left brace There is an unescaped left brace in a regex in OPEN_BRACE check. This throws a runtime error when checkpatch is run with --fix flag and the OPEN_BRACE check is executed. Fix it by escaping the left brace. Link: https://lkml.kernel.org/r/20201115202928.81955-1-dwaipayanray1@gmail.com Fixes: 8d1824780f2f ("checkpatch: add --fix option for a couple OPEN_BRACE misuses") Signed-off-by: Dwaipayan Ray Acked-by: Joe Perches Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- scripts/checkpatch.pl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'scripts') diff --git a/scripts/checkpatch.pl b/scripts/checkpatch.pl index 176ea2c189b8..fdfd5ec09be6 100755 --- a/scripts/checkpatch.pl +++ b/scripts/checkpatch.pl @@ -4505,7 +4505,7 @@ sub process { $fix) { fix_delete_line($fixlinenr, $rawline); my $fixed_line = $rawline; - $fixed_line =~ /(^..*$Type\s*$Ident\(.*\)\s*){(.*)$/; + $fixed_line =~ /(^..*$Type\s*$Ident\(.*\)\s*)\{(.*)$/; my $line1 = $1; my $line2 = $2; fix_insert_line($fixlinenr, ltrim($line1)); -- cgit From da7355ab4e4a0021924e87acce2b9fb7e6f3264e Mon Sep 17 00:00:00 2001 From: Aditya Srivastava Date: Tue, 15 Dec 2020 20:45:06 -0800 Subject: checkpatch: add fix option for ASSIGNMENT_CONTINUATIONS Currently, checkpatch warns us if an assignment operator is placed at the start of a line and not at the end of previous line. E.g., running checkpatch on commit 8195b1396ec8 ("hv_netvsc: fix deadlock on hotplug") reports: CHECK: Assignment operator '=' should be on the previous line + struct netvsc_device *nvdev + = container_of(w, struct netvsc_device, subchan_work); Provide a simple fix by appending assignment operator to the previous line and removing from the current line, if both the lines are additions (ie start with '+') Link: https://lkml.kernel.org/r/20201121120407.22942-1-yashsri421@gmail.com Signed-off-by: Aditya Srivastava Acked-by: Joe Perches Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- scripts/checkpatch.pl | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) (limited to 'scripts') diff --git a/scripts/checkpatch.pl b/scripts/checkpatch.pl index fdfd5ec09be6..7dc094445d83 100755 --- a/scripts/checkpatch.pl +++ b/scripts/checkpatch.pl @@ -3533,8 +3533,14 @@ sub process { # check for assignments on the start of a line if ($sline =~ /^\+\s+($Assignment)[^=]/) { - CHK("ASSIGNMENT_CONTINUATIONS", - "Assignment operator '$1' should be on the previous line\n" . $hereprev); + my $operator = $1; + if (CHK("ASSIGNMENT_CONTINUATIONS", + "Assignment operator '$1' should be on the previous line\n" . $hereprev) && + $fix && $prevrawline =~ /^\+/) { + # add assignment operator to the previous line, remove from current line + $fixed[$fixlinenr - 1] .= " $operator"; + $fixed[$fixlinenr] =~ s/\Q$operator\E\s*//; + } } # check for && or || at the start of a line -- cgit From 8e08f0765f3744c65e2c8c570004079883b2f546 Mon Sep 17 00:00:00 2001 From: Aditya Srivastava Date: Tue, 15 Dec 2020 20:45:09 -0800 Subject: checkpatch: add fix option for LOGICAL_CONTINUATIONS Currently, checkpatch warns if logical continuations are placed at the start of a line and not at the end of previous line. E.g., running checkpatch on commit 3485507fc272 ("staging: bcm2835-camera: Reduce length of enum names") reports: CHECK:LOGICAL_CONTINUATIONS: Logical continuations should be on the previous line + if (!ret + && camera_port == Provide a simple fix by inserting logical operator at the last non-comment, non-whitespace char of the previous line and removing from current line, if both the lines are additions(ie start with '+') Link: https://lkml.kernel.org/r/20201123102818.24364-1-yashsri421@gmail.com Signed-off-by: Aditya Srivastava Acked-by: Joe Perches Cc: Lukas Bulwahn Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- scripts/checkpatch.pl | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) (limited to 'scripts') diff --git a/scripts/checkpatch.pl b/scripts/checkpatch.pl index 7dc094445d83..241c064f358b 100755 --- a/scripts/checkpatch.pl +++ b/scripts/checkpatch.pl @@ -3545,8 +3545,16 @@ sub process { # check for && or || at the start of a line if ($rawline =~ /^\+\s*(&&|\|\|)/) { - CHK("LOGICAL_CONTINUATIONS", - "Logical continuations should be on the previous line\n" . $hereprev); + my $operator = $1; + if (CHK("LOGICAL_CONTINUATIONS", + "Logical continuations should be on the previous line\n" . $hereprev) && + $fix && $prevrawline =~ /^\+/) { + # insert logical operator at last non-comment, non-whitepsace char on previous line + $prevline =~ /[\s$;]*$/; + my $line_end = substr($prevrawline, $-[0]); + $fixed[$fixlinenr - 1] =~ s/\Q$line_end\E$/ $operator$line_end/; + $fixed[$fixlinenr] =~ s/\Q$operator\E\s*//; + } } # check indentation starts on a tab stop -- cgit From 831242ab8dffab4cf2f89c597d5902ac86caeefe Mon Sep 17 00:00:00 2001 From: Aditya Srivastava Date: Tue, 15 Dec 2020 20:45:12 -0800 Subject: checkpatch: add fix and improve warning msg for non-standard signature Currently checkpatch warns for BAD_SIGN_OFF on non-standard signature styles. A large number of these warnings occur because of typo mistakes in signature tags. An evaluation over v4.13..v5.8 showed that out of 539 warnings due to non-standard signatures, 87 are due to typo mistakes. Following are the standard signature tags which are often incorrectly used, along with their individual counts of incorrect use (over v4.13..v5.8): Reviewed-by: 42 Signed-off-by: 25 Reported-by: 6 Acked-by: 4 Tested-by: 4 Suggested-by: 4 Provide a fix by calculating levenshtein distance for the signature tag with all the standard signatures and suggest a fix with a signature, whose edit distance is less than or equal to 2 with the misspelled signature. Out of the 86 mispelled signatures fixed with this approach, 85 were found to be good corrections and 1 was bad correction. Following was found to be a bad correction: Tweeted-by (count: 1) => Tested-by Link: https://lkml.kernel.org/r/20201128204333.7054-1-yashsri421@gmail.com Signed-off-by: Aditya Srivastava Acked-by: Joe Perches Cc: Lukas Bulwahn Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- scripts/checkpatch.pl | 71 +++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 69 insertions(+), 2 deletions(-) (limited to 'scripts') diff --git a/scripts/checkpatch.pl b/scripts/checkpatch.pl index 241c064f358b..d7616a6f1436 100755 --- a/scripts/checkpatch.pl +++ b/scripts/checkpatch.pl @@ -506,6 +506,64 @@ our $signature_tags = qr{(?xi: Cc: )}; +sub edit_distance_min { + my (@arr) = @_; + my $len = scalar @arr; + if ((scalar @arr) < 1) { + # if underflow, return + return; + } + my $min = $arr[0]; + for my $i (0 .. ($len-1)) { + if ($arr[$i] < $min) { + $min = $arr[$i]; + } + } + return $min; +} + +sub get_edit_distance { + my ($str1, $str2) = @_; + $str1 = lc($str1); + $str2 = lc($str2); + $str1 =~ s/-//g; + $str2 =~ s/-//g; + my $len1 = length($str1); + my $len2 = length($str2); + # two dimensional array storing minimum edit distance + my @distance; + for my $i (0 .. $len1) { + for my $j (0 .. $len2) { + if ($i == 0) { + $distance[$i][$j] = $j; + } elsif ($j == 0) { + $distance[$i][$j] = $i; + } elsif (substr($str1, $i-1, 1) eq substr($str2, $j-1, 1)) { + $distance[$i][$j] = $distance[$i - 1][$j - 1]; + } else { + my $dist1 = $distance[$i][$j - 1]; #insert distance + my $dist2 = $distance[$i - 1][$j]; # remove + my $dist3 = $distance[$i - 1][$j - 1]; #replace + $distance[$i][$j] = 1 + edit_distance_min($dist1, $dist2, $dist3); + } + } + } + return $distance[$len1][$len2]; +} + +sub find_standard_signature { + my ($sign_off) = @_; + my @standard_signature_tags = ( + 'Signed-off-by:', 'Co-developed-by:', 'Acked-by:', 'Tested-by:', + 'Reviewed-by:', 'Reported-by:', 'Suggested-by:' + ); + foreach my $signature (@standard_signature_tags) { + return $signature if (get_edit_distance($sign_off, $signature) <= 2); + } + + return ""; +} + our @typeListMisordered = ( qr{char\s+(?:un)?signed}, qr{int\s+(?:(?:un)?signed\s+)?short\s}, @@ -2773,8 +2831,17 @@ sub process { my $ucfirst_sign_off = ucfirst(lc($sign_off)); if ($sign_off !~ /$signature_tags/) { - WARN("BAD_SIGN_OFF", - "Non-standard signature: $sign_off\n" . $herecurr); + my $suggested_signature = find_standard_signature($sign_off); + if ($suggested_signature eq "") { + WARN("BAD_SIGN_OFF", + "Non-standard signature: $sign_off\n" . $herecurr); + } else { + if (WARN("BAD_SIGN_OFF", + "Non-standard signature: '$sign_off' - perhaps '$suggested_signature'?\n" . $herecurr) && + $fix) { + $fixed[$fixlinenr] =~ s/$sign_off/$suggested_signature/; + } + } } if (defined $space_before && $space_before ne "") { if (WARN("BAD_SIGN_OFF", -- cgit From 70eb2275ff8e0b4cafe67176674d580c987c071d Mon Sep 17 00:00:00 2001 From: Dwaipayan Ray Date: Tue, 15 Dec 2020 20:45:15 -0800 Subject: checkpatch: add warning for unnecessary use of %h[xudi] and %hh[xudi] Modifiers %h and %hh should never be used. Commit cbacb5ab0aa0 ("docs: printk-formats: Stop encouraging use of unnecessary %h[xudi] and %hh[xudi]") specifies that: "Standard integer promotion is already done and %hx and %hhx is useless so do not encourage the use of %hh[xudi] or %h[xudi]." "The "h" and "hh" things should never be used. The only reason for them being used if you have an "int", but you want to print it out as a "char" (and honestly, that is a really bad reason, you'd be better off just using a proper cast to make the code more obvious)." Add a new check to emit a warning on finding an unneeded use of %h or %hh modifier. Also add a fix option to the check. Link: https://lore.kernel.org/lkml/4910042649a4f3ab22fac93191b8c1fa0a2e17c3.camel@perches.com/ Link: https://lkml.kernel.org/r/20201128200046.78739-1-dwaipayanray1@gmail.com Signed-off-by: Dwaipayan Ray Suggested-by: Joe Perches Suggested-by: Lukas Bulwahn Acked-by: Joe Perches Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- scripts/checkpatch.pl | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) (limited to 'scripts') diff --git a/scripts/checkpatch.pl b/scripts/checkpatch.pl index d7616a6f1436..2716b9bfc0c2 100755 --- a/scripts/checkpatch.pl +++ b/scripts/checkpatch.pl @@ -6102,6 +6102,28 @@ sub process { "Avoid logging continuation uses where feasible\n" . $herecurr); } +# check for unnecessary use of %h[xudi] and %hh[xudi] in logging functions + if (defined $stat && + $line =~ /\b$logFunctions\s*\(/ && + index($stat, '"') >= 0) { + my $lc = $stat =~ tr@\n@@; + $lc = $lc + $linenr; + my $stat_real = get_stat_real($linenr, $lc); + pos($stat_real) = index($stat_real, '"'); + while ($stat_real =~ /[^\"%]*(%[\#\d\.\*\-]*(h+)[idux])/g) { + my $pspec = $1; + my $h = $2; + my $lineoff = substr($stat_real, 0, $-[1]) =~ tr@\n@@; + if (WARN("UNNECESSARY_MODIFIER", + "Integer promotion: Using '$h' in '$pspec' is unnecessary\n" . "$here\n$stat_real\n") && + $fix && $fixed[$fixlinenr + $lineoff] =~ /^\+/) { + my $nspec = $pspec; + $nspec =~ s/h//g; + $fixed[$fixlinenr + $lineoff] =~ s/\Q$pspec\E/$nspec/; + } + } + } + # check for mask then right shift without a parentheses if ($perl_version_ok && $line =~ /$LvalOrFunc\s*\&\s*($LvalOrFunc)\s*>>/ && -- cgit From 084a617acfa08118eafb51a6ef43e6fa4705853d Mon Sep 17 00:00:00 2001 From: Dwaipayan Ray Date: Tue, 15 Dec 2020 20:45:18 -0800 Subject: checkpatch: add warning for lines starting with a '#' in commit log Commit log lines starting with '#' are dropped by git as comments. Add a check to emit a warning for these lines. Also add a --fix option to insert a space before the leading '#' in such lines. Link: https://lkml.kernel.org/r/20201202205740.127986-1-dwaipayanray1@gmail.com Signed-off-by: Dwaipayan Ray Suggested-by: Joe Perches Suggested-by: Peilin Ye Tested-by: Peilin Ye Acked-by: Joe Perches Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- scripts/checkpatch.pl | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'scripts') diff --git a/scripts/checkpatch.pl b/scripts/checkpatch.pl index 2716b9bfc0c2..b7dde7260921 100755 --- a/scripts/checkpatch.pl +++ b/scripts/checkpatch.pl @@ -3033,6 +3033,15 @@ sub process { $commit_log_possible_stack_dump = 0; } +# Check for lines starting with a # + if ($in_commit_log && $line =~ /^#/) { + if (WARN("COMMIT_COMMENT_SYMBOL", + "Commit log lines starting with '#' are dropped by git as comments\n" . $herecurr) && + $fix) { + $fixed[$fixlinenr] =~ s/^/ /; + } + } + # Check for git id commit length and improperly formed commit descriptions if ($in_commit_log && !$commit_log_possible_stack_dump && $line !~ /^\s*(?:Link|Patchwork|http|https|BugLink|base-commit):/i && -- cgit From 7da07c31b1df1fa973d184378862443302fd1129 Mon Sep 17 00:00:00 2001 From: Dwaipayan Ray Date: Tue, 15 Dec 2020 20:45:21 -0800 Subject: checkpatch: fix TYPO_SPELLING check for words with apostrophe checkpatch reports a false TYPO_SPELLING warning for some words containing an apostrophe when run with --codespell option. A false positive is "doesn't". Occurrence of the word causes checkpatch to emit the following warning: "WARNING: 'doesn'' may be misspelled - perhaps 'doesn't'?" Modify the regex pattern to be more in line with the codespell default word matching regex. This fixes the word capture and avoids the false warning. In addition, highlight the misspelled word location by adding a caret below the word. [akpm@linux-foundation.org: make matched misspelling more obvious, per Joe] Link: https://lkml.kernel.org/r/09c24ef1aa2f1c4fe909d76f5426f08780b9d81c.camel@perches.com Link: https://lkml.kernel.org/r/20201201190729.169733-1-dwaipayanray1@gmail.com Signed-off-by: Dwaipayan Ray Suggested-by: Joe Perches Reported-by: Peilin Ye Acked-by: Joe Perches Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- scripts/checkpatch.pl | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'scripts') diff --git a/scripts/checkpatch.pl b/scripts/checkpatch.pl index b7dde7260921..7b086d1cd6c2 100755 --- a/scripts/checkpatch.pl +++ b/scripts/checkpatch.pl @@ -3182,15 +3182,18 @@ sub process { # Check for various typo / spelling mistakes if (defined($misspellings) && ($in_commit_log || $line =~ /^(?:\+|Subject:)/i)) { - while ($rawline =~ /(?:^|[^a-z@])($misspellings)(?:\b|$|[^a-z@])/gi) { + while ($rawline =~ /(?:^|[^\w\-'`])($misspellings)(?:[^\w\-'`]|$)/gi) { my $typo = $1; + my $blank = copy_spacing($rawline); + my $ptr = substr($blank, 0, $-[1]) . "^" x length($typo); + my $hereptr = "$hereline$ptr\n"; my $typo_fix = $spelling_fix{lc($typo)}; $typo_fix = ucfirst($typo_fix) if ($typo =~ /^[A-Z]/); $typo_fix = uc($typo_fix) if ($typo =~ /^[A-Z]+$/); my $msg_level = \&WARN; $msg_level = \&CHK if ($file); if (&{$msg_level}("TYPO_SPELLING", - "'$typo' may be misspelled - perhaps '$typo_fix'?\n" . $herecurr) && + "'$typo' may be misspelled - perhaps '$typo_fix'?\n" . $hereptr) && $fix) { $fixed[$fixlinenr] =~ s/(^|[^A-Za-z@])($typo)($|[^A-Za-z@])/$1$typo_fix$3/; } -- cgit From f5eea3b0442da801404859a780c02721d649f02f Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Tue, 15 Dec 2020 20:45:24 -0800 Subject: checkpatch: add printk_once and printk_ratelimit to prefer pr_ warning Add the _once and _ratelimited variants to the test for printk(KERN_ that should prefer pr_. Miscellanea: o Add comment description for the conversions [joe@perches.com: fixlet] Link: https://lkml.kernel.org/r/32260871d4718ba7f48a8e9e07452bb76de300db.camel@perches.comLink: https://lkml.kernel.org/r/993b72b2ef91a57c5e725b52971ce3fd31375061.camel@perches.com Signed-off-by: Joe Perches Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- scripts/checkpatch.pl | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) (limited to 'scripts') diff --git a/scripts/checkpatch.pl b/scripts/checkpatch.pl index 7b086d1cd6c2..00085308ed9d 100755 --- a/scripts/checkpatch.pl +++ b/scripts/checkpatch.pl @@ -4543,16 +4543,23 @@ sub process { "printk() should include KERN_ facility level\n" . $herecurr); } - if ($line =~ /\bprintk\s*\(\s*KERN_([A-Z]+)/) { - my $orig = $1; +# prefer variants of (subsystem|netdev|dev|pr)_ to printk(KERN_ + if ($line =~ /\b(printk(_once|_ratelimited)?)\s*\(\s*KERN_([A-Z]+)/) { + my $printk = $1; + my $modifier = $2; + my $orig = $3; + $modifier = "" if (!defined($modifier)); my $level = lc($orig); $level = "warn" if ($level eq "warning"); my $level2 = $level; $level2 = "dbg" if ($level eq "debug"); + $level .= $modifier; + $level2 .= $modifier; WARN("PREFER_PR_LEVEL", - "Prefer [subsystem eg: netdev]_$level2([subsystem]dev, ... then dev_$level2(dev, ... then pr_$level(... to printk(KERN_$orig ...\n" . $herecurr); + "Prefer [subsystem eg: netdev]_$level2([subsystem]dev, ... then dev_$level2(dev, ... then pr_$level(... to $printk(KERN_$orig ...\n" . $herecurr); } +# prefer dev_ to dev_printk(KERN_ if ($line =~ /\bdev_printk\s*\(\s*KERN_([A-Z]+)/) { my $orig = $1; my $level = lc($orig); -- cgit From d8a7f62b6eec198e85b8602e062c00e199f5c328 Mon Sep 17 00:00:00 2001 From: Kees Cook Date: Tue, 15 Dec 2020 20:46:20 -0800 Subject: ubsan: remove redundant -Wno-maybe-uninitialized Patch series "Clean up UBSAN Makefile", v2. This series attempts to address the issues seen with UBSAN's object-size sanitizer causing problems under GCC. In the process, the Kconfig and Makefile are refactored to do all the cc-option calls in the Kconfig. Additionally start to detangle -Wno-maybe-uninitialized, disable UBSAN_TRAP under COMPILE_TEST for wider build coverage, and expand the libusan tests. This patch (of 7): In commit 78a5255ffb6a ("Stop the ad-hoc games with -Wno-maybe-initialized") -Wmaybe-uninitialized was disabled globally, so keeping the disabling logic here too doesn't make sense. Link: https://lkml.kernel.org/r/20201203004437.389959-1-keescook@chromium.org Link: https://lkml.kernel.org/r/20201203004437.389959-2-keescook@chromium.org Signed-off-by: Kees Cook Cc: Linus Torvalds Cc: Ard Biesheuvel Cc: Arnd Bergmann Cc: Masahiro Yamada Cc: Michal Marek Cc: Nathan Chancellor Cc: Nick Desaulniers Cc: Marco Elver Cc: Randy Dunlap Cc: Dmitry Vyukov Cc: George Popescu Cc: Herbert Xu Cc: Peter Oberparleiter Cc: Andrey Ryabinin Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- scripts/Makefile.ubsan | 4 ---- 1 file changed, 4 deletions(-) (limited to 'scripts') diff --git a/scripts/Makefile.ubsan b/scripts/Makefile.ubsan index 9716dab06bc7..c18fecc53605 100644 --- a/scripts/Makefile.ubsan +++ b/scripts/Makefile.ubsan @@ -31,7 +31,3 @@ endif ifdef CONFIG_UBSAN_TRAP CFLAGS_UBSAN += $(call cc-option, -fsanitize-undefined-trap-on-error) endif - - # -fsanitize=* options makes GCC less smart than usual and - # increase number of 'maybe-uninitialized false-positives - CFLAGS_UBSAN += $(call cc-option, -Wno-maybe-uninitialized) -- cgit From cdf8a76fda4ae3b53c5a09e5a8c79e27b7b65d68 Mon Sep 17 00:00:00 2001 From: Kees Cook Date: Tue, 15 Dec 2020 20:46:24 -0800 Subject: ubsan: move cc-option tests into Kconfig Instead of doing if/endif blocks with cc-option calls in the UBSAN Makefile, move all the tests into Kconfig and use the Makefile to collect the results. Link: https://lkml.kernel.org/r/20201203004437.389959-3-keescook@chromium.org Link: https://lore.kernel.org/lkml/CAHk-=wjPasyJrDuwDnpHJS2TuQfExwe=px-SzLeN8GFMAQJPmQ@mail.gmail.com/ Signed-off-by: Kees Cook Suggested-by: Linus Torvalds Reviewed-by: Nathan Chancellor Tested-by: Nathan Chancellor Cc: Andrey Ryabinin Cc: Ard Biesheuvel Cc: Arnd Bergmann Cc: Dmitry Vyukov Cc: George Popescu Cc: Herbert Xu Cc: Marco Elver Cc: Masahiro Yamada Cc: Michal Marek Cc: Nick Desaulniers Cc: Peter Oberparleiter Cc: Randy Dunlap Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- scripts/Makefile.ubsan | 45 +++++++++++++++------------------------------ 1 file changed, 15 insertions(+), 30 deletions(-) (limited to 'scripts') diff --git a/scripts/Makefile.ubsan b/scripts/Makefile.ubsan index c18fecc53605..0e53a93e8f15 100644 --- a/scripts/Makefile.ubsan +++ b/scripts/Makefile.ubsan @@ -1,33 +1,18 @@ # SPDX-License-Identifier: GPL-2.0 -export CFLAGS_UBSAN := +# Enable available and selected UBSAN features. +ubsan-cflags-$(CONFIG_UBSAN_ALIGNMENT) += -fsanitize=alignment +ubsan-cflags-$(CONFIG_UBSAN_ONLY_BOUNDS) += -fsanitize=bounds +ubsan-cflags-$(CONFIG_UBSAN_ARRAY_BOUNDS) += -fsanitize=array-bounds +ubsan-cflags-$(CONFIG_UBSAN_LOCAL_BOUNDS) += -fsanitize=local-bounds +ubsan-cflags-$(CONFIG_UBSAN_SHIFT) += -fsanitize=shift +ubsan-cflags-$(CONFIG_UBSAN_DIV_ZERO) += -fsanitize=integer-divide-by-zero +ubsan-cflags-$(CONFIG_UBSAN_UNREACHABLE) += -fsanitize=unreachable +ubsan-cflags-$(CONFIG_UBSAN_SIGNED_OVERFLOW) += -fsanitize=signed-integer-overflow +ubsan-cflags-$(CONFIG_UBSAN_UNSIGNED_OVERFLOW) += -fsanitize=unsigned-integer-overflow +ubsan-cflags-$(CONFIG_UBSAN_OBJECT_SIZE) += -fsanitize=object-size +ubsan-cflags-$(CONFIG_UBSAN_BOOL) += -fsanitize=bool +ubsan-cflags-$(CONFIG_UBSAN_ENUM) += -fsanitize=enum +ubsan-cflags-$(CONFIG_UBSAN_TRAP) += -fsanitize-undefined-trap-on-error -ifdef CONFIG_UBSAN_ALIGNMENT - CFLAGS_UBSAN += $(call cc-option, -fsanitize=alignment) -endif - -ifdef CONFIG_UBSAN_BOUNDS - ifdef CONFIG_CC_IS_CLANG - CFLAGS_UBSAN += -fsanitize=array-bounds - else - CFLAGS_UBSAN += $(call cc-option, -fsanitize=bounds) - endif -endif - -ifdef CONFIG_UBSAN_LOCAL_BOUNDS - CFLAGS_UBSAN += -fsanitize=local-bounds -endif - -ifdef CONFIG_UBSAN_MISC - CFLAGS_UBSAN += $(call cc-option, -fsanitize=shift) - CFLAGS_UBSAN += $(call cc-option, -fsanitize=integer-divide-by-zero) - CFLAGS_UBSAN += $(call cc-option, -fsanitize=unreachable) - CFLAGS_UBSAN += $(call cc-option, -fsanitize=signed-integer-overflow) - CFLAGS_UBSAN += $(call cc-option, -fsanitize=object-size) - CFLAGS_UBSAN += $(call cc-option, -fsanitize=bool) - CFLAGS_UBSAN += $(call cc-option, -fsanitize=enum) -endif - -ifdef CONFIG_UBSAN_TRAP - CFLAGS_UBSAN += $(call cc-option, -fsanitize-undefined-trap-on-error) -endif +export CFLAGS_UBSAN := $(ubsan-cflags-y) -- cgit From bc72d723ec6b75c53e935e819682c3e67b83e9c1 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Tue, 1 Dec 2020 19:34:14 +0900 Subject: modpost: rename merror() to error() The log function names, warn(), merror(), fatal() are inconsistent. Commit 2a11665945d5 ("kbuild: distinguish between errors and warnings in modpost") intentionally chose merror() to avoid the conflict with the library function error(). See man page of error(3). But, we are already causing the conflict with warn() because it is also a library function. See man page of warn(3). err() would be a problem for the same reason. The common technique to work around name conflicts is to use macros. For example: /* in a header */ #define error(fmt, ...) __error(fmt, ##__VA_ARGS__) #define warn(fmt, ...) __warn(fmt, ##__VA_ARGS__) /* function definition */ void __error(const char *fmt, ...) { } void __warn(const char *fmt, ...) { } In this way, we can implement our own warn() and error(), still we can include and with no problem. And, commit 93c95e526a4e ("modpost: rework and consolidate logging interface") already did that. Since the log functions are all macros, we can use error() without causing "conflicting types" errors. Signed-off-by: Masahiro Yamada --- scripts/mod/modpost.c | 10 +++++----- scripts/mod/modpost.h | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) (limited to 'scripts') diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c index f882ce0d9327..337f6ca4bda3 100644 --- a/scripts/mod/modpost.c +++ b/scripts/mod/modpost.c @@ -403,8 +403,8 @@ static void sym_update_namespace(const char *symname, const char *namespace) * actually an assertion. */ if (!s) { - merror("Could not update namespace(%s) for symbol %s\n", - namespace, symname); + error("Could not update namespace(%s) for symbol %s\n", + namespace, symname); return; } @@ -2226,7 +2226,7 @@ static int check_modname_len(struct module *mod) else mod_name++; if (strlen(mod_name) >= MODULE_NAME_LEN) { - merror("module name is too long [%s.ko]\n", mod->name); + error("module name is too long [%s.ko]\n", mod->name); return 1; } @@ -2319,8 +2319,8 @@ static int add_versions(struct buffer *b, struct module *mod) continue; } if (strlen(s->name) >= MODULE_NAME_LEN) { - merror("too long symbol \"%s\" [%s.ko]\n", - s->name, mod->name); + error("too long symbol \"%s\" [%s.ko]\n", + s->name, mod->name); err = 1; break; } diff --git a/scripts/mod/modpost.h b/scripts/mod/modpost.h index 3aa052722233..f453504ad4df 100644 --- a/scripts/mod/modpost.h +++ b/scripts/mod/modpost.h @@ -202,5 +202,5 @@ enum loglevel { void modpost_log(enum loglevel loglevel, const char *fmt, ...); #define warn(fmt, args...) modpost_log(LOG_WARN, fmt, ##args) -#define merror(fmt, args...) modpost_log(LOG_ERROR, fmt, ##args) +#define error(fmt, args...) modpost_log(LOG_ERROR, fmt, ##args) #define fatal(fmt, args...) modpost_log(LOG_FATAL, fmt, ##args) -- cgit From 0fd3fbadd9a85e391828f3ef63ef1e96e2d2d752 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Tue, 1 Dec 2020 19:34:15 +0900 Subject: modpost: refactor error handling and clarify error/fatal difference We have 3 log functions. fatal() is special because it lets modpost bail out immediately. The difference between warn() and error() is the only prefix parts ("WARNING:" vs "ERROR:"). In my understanding, the expected handling of error() is to propagate the return code of the function to the exit code of modpost, as check_exports() etc. already does. This is a good manner in general because we should display as many error messages as possible in a single run of modpost. What is annoying about fatal() is that it kills modpost at the first error. People would need to run Kbuild again and again until they fix all errors. But, unfortunately, people tend to do: "This case should not be allowed. Let's replace warn() with fatal()." One of the reasons is probably it is tedious to manually hoist the error code to the main() function. This commit refactors error() so any single call for it automatically makes modpost return the error code. I also added comments in modpost.h for warn(), error(), and fatal(). Please use fatal() only when you have a strong reason to do so. For example: - Memory shortage (i.e. malloc() etc. has failed) - The ELF file is broken, and there is no point to continue parsing - Something really odd has happened For general coding errors, please use error(). Signed-off-by: Masahiro Yamada Tested-by: Quentin Perret --- scripts/mod/modpost.c | 43 ++++++++++++++----------------------------- scripts/mod/modpost.h | 13 +++++++++++++ 2 files changed, 27 insertions(+), 29 deletions(-) (limited to 'scripts') diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c index 337f6ca4bda3..43e00867623a 100644 --- a/scripts/mod/modpost.c +++ b/scripts/mod/modpost.c @@ -40,6 +40,8 @@ static int ignore_missing_files; /* If set to 1, only warn (instead of error) about missing ns imports */ static int allow_missing_ns_imports; +static bool error_occurred; + enum export { export_plain, export_unused, export_gpl, export_unused_gpl, export_gpl_future, export_unknown @@ -78,6 +80,8 @@ modpost_log(enum loglevel loglevel, const char *fmt, ...) if (loglevel == LOG_FATAL) exit(1); + if (loglevel == LOG_ERROR) + error_occurred = true; } static inline bool strends(const char *str, const char *postfix) @@ -2174,22 +2178,18 @@ static void check_for_unused(enum export exp, const char *m, const char *s) } } -static int check_exports(struct module *mod) +static void check_exports(struct module *mod) { struct symbol *s, *exp; - int err = 0; for (s = mod->unres; s; s = s->next) { const char *basename; exp = find_symbol(s->name); if (!exp || exp->module == mod) { - if (have_vmlinux && !s->weak) { + if (have_vmlinux && !s->weak) modpost_log(warn_unresolved ? LOG_WARN : LOG_ERROR, "\"%s\" [%s.ko] undefined!\n", s->name, mod->name); - if (!warn_unresolved) - err = 1; - } continue; } basename = strrchr(mod->name, '/'); @@ -2203,8 +2203,6 @@ static int check_exports(struct module *mod) modpost_log(allow_missing_ns_imports ? LOG_WARN : LOG_ERROR, "module %s uses symbol %s from namespace %s, but does not import it.\n", basename, exp->name, exp->namespace); - if (!allow_missing_ns_imports) - err = 1; add_namespace(&mod->missing_namespaces, exp->namespace); } @@ -2212,11 +2210,9 @@ static int check_exports(struct module *mod) check_for_gpl_usage(exp->export, basename, exp->name); check_for_unused(exp->export, basename, exp->name); } - - return err; } -static int check_modname_len(struct module *mod) +static void check_modname_len(struct module *mod) { const char *mod_name; @@ -2225,12 +2221,8 @@ static int check_modname_len(struct module *mod) mod_name = mod->name; else mod_name++; - if (strlen(mod_name) >= MODULE_NAME_LEN) { + if (strlen(mod_name) >= MODULE_NAME_LEN) error("module name is too long [%s.ko]\n", mod->name); - return 1; - } - - return 0; } /** @@ -2289,10 +2281,9 @@ static void add_staging_flag(struct buffer *b, const char *name) /** * Record CRCs for unresolved symbols **/ -static int add_versions(struct buffer *b, struct module *mod) +static void add_versions(struct buffer *b, struct module *mod) { struct symbol *s, *exp; - int err = 0; for (s = mod->unres; s; s = s->next) { exp = find_symbol(s->name); @@ -2304,7 +2295,7 @@ static int add_versions(struct buffer *b, struct module *mod) } if (!modversions) - return err; + return; buf_printf(b, "\n"); buf_printf(b, "static const struct modversion_info ____versions[]\n"); @@ -2321,7 +2312,6 @@ static int add_versions(struct buffer *b, struct module *mod) if (strlen(s->name) >= MODULE_NAME_LEN) { error("too long symbol \"%s\" [%s.ko]\n", s->name, mod->name); - err = 1; break; } buf_printf(b, "\t{ %#8x, \"%s\" },\n", @@ -2329,8 +2319,6 @@ static int add_versions(struct buffer *b, struct module *mod) } buf_printf(b, "};\n"); - - return err; } static void add_depends(struct buffer *b, struct module *mod) @@ -2554,7 +2542,6 @@ int main(int argc, char **argv) char *missing_namespace_deps = NULL; char *dump_write = NULL, *files_source = NULL; int opt; - int err; int n; struct dump_list *dump_read_start = NULL; struct dump_list **dump_read_iter = &dump_read_start; @@ -2624,8 +2611,6 @@ int main(int argc, char **argv) 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) { char fname[PATH_MAX]; @@ -2634,14 +2619,14 @@ int main(int argc, char **argv) buf.pos = 0; - err |= check_modname_len(mod); - err |= check_exports(mod); + check_modname_len(mod); + check_exports(mod); add_header(&buf, mod); add_intree_flag(&buf, !external_module); add_retpoline(&buf); add_staging_flag(&buf, mod->name); - err |= add_versions(&buf, mod); + add_versions(&buf, mod); add_depends(&buf, mod); add_moddevtable(&buf, mod); add_srcversion(&buf, mod); @@ -2671,5 +2656,5 @@ int main(int argc, char **argv) free(buf.p); - return err; + return error_occurred ? 1 : 0; } diff --git a/scripts/mod/modpost.h b/scripts/mod/modpost.h index f453504ad4df..e6f46eee0af0 100644 --- a/scripts/mod/modpost.h +++ b/scripts/mod/modpost.h @@ -201,6 +201,19 @@ enum loglevel { void modpost_log(enum loglevel loglevel, const char *fmt, ...); +/* + * warn - show the given message, then let modpost continue running, still + * allowing modpost to exit successfully. This should be used when + * we still allow to generate vmlinux and modules. + * + * error - show the given message, then let modpost continue running, but fail + * in the end. This should be used when we should stop building vmlinux + * or modules, but we can continue running modpost to catch as many + * issues as possible. + * + * fatal - show the given message, and bail out immediately. This should be + * used when there is no point to continue running modpost. + */ #define warn(fmt, args...) modpost_log(LOG_WARN, fmt, ##args) #define error(fmt, args...) modpost_log(LOG_ERROR, fmt, ##args) #define fatal(fmt, args...) modpost_log(LOG_FATAL, fmt, ##args) -- cgit From 1d6cd39293602e990b016994e51956eded35da7c Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Tue, 1 Dec 2020 19:34:16 +0900 Subject: modpost: turn missing MODULE_LICENSE() into error Do not create modules with no license tag. Signed-off-by: Masahiro Yamada --- scripts/mod/modpost.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'scripts') diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c index 43e00867623a..d55d7e5ef111 100644 --- a/scripts/mod/modpost.c +++ b/scripts/mod/modpost.c @@ -2018,7 +2018,7 @@ static void read_symbols(const char *modname) if (!mod->is_vmlinux) { license = get_modinfo(&info, "license"); if (!license) - warn("missing MODULE_LICENSE() in %s\n", modname); + error("missing MODULE_LICENSE() in %s\n", modname); while (license) { if (license_is_gpl_compatible(license)) mod->gpl_compatible = 1; -- cgit From d6d692fa21d3057edf457a764832077da8aa44d2 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Tue, 1 Dec 2020 19:34:17 +0900 Subject: modpost: change license incompatibility to error() from fatal() Change fatal() to error() to continue running to report more possible issues. There is no difference in the fact that modpost will fail anyway. Signed-off-by: Masahiro Yamada --- scripts/mod/modpost.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'scripts') diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c index d55d7e5ef111..d907c63b948f 100644 --- a/scripts/mod/modpost.c +++ b/scripts/mod/modpost.c @@ -2145,11 +2145,11 @@ static void check_for_gpl_usage(enum export exp, const char *m, const char *s) { switch (exp) { case export_gpl: - fatal("GPL-incompatible module %s.ko uses GPL-only symbol '%s'\n", + error("GPL-incompatible module %s.ko uses GPL-only symbol '%s'\n", m, s); break; case export_unused_gpl: - fatal("GPL-incompatible module %s.ko uses GPL-only symbol marked UNUSED '%s'\n", + error("GPL-incompatible module %s.ko uses GPL-only symbol marked UNUSED '%s'\n", m, s); break; case export_gpl_future: -- cgit From c7299d98c00afa81c65d9fa13a18ea923f3281ff Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Tue, 1 Dec 2020 19:34:18 +0900 Subject: modpost: turn section mismatches to error from fatal() There is code that reports static EXPORT_SYMBOL a few lines below. It is not a good idea to bail out here. I renamed sec_mismatch_fatal to sec_mismatch_warn_only (with logical inversion) to match to CONFIG_SECTION_MISMATCH_WARN_ONLY. Signed-off-by: Masahiro Yamada --- scripts/mod/modpost.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'scripts') diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c index d907c63b948f..a750596d5cc2 100644 --- a/scripts/mod/modpost.c +++ b/scripts/mod/modpost.c @@ -34,7 +34,7 @@ static int external_module = 0; static int warn_unresolved = 0; /* How a symbol is exported */ static int sec_mismatch_count = 0; -static int sec_mismatch_fatal = 0; +static int sec_mismatch_warn_only = true; /* ignore missing files */ static int ignore_missing_files; /* If set to 1, only warn (instead of error) about missing ns imports */ @@ -2576,7 +2576,7 @@ int main(int argc, char **argv) warn_unresolved = 1; break; case 'E': - sec_mismatch_fatal = 1; + sec_mismatch_warn_only = false; break; case 'N': allow_missing_ns_imports = 1; @@ -2640,8 +2640,8 @@ int main(int argc, char **argv) if (dump_write) write_dump(dump_write); - if (sec_mismatch_count && sec_mismatch_fatal) - fatal("Section mismatches detected.\n" + if (sec_mismatch_count && !sec_mismatch_warn_only) + error("Section mismatches detected.\n" "Set CONFIG_SECTION_MISMATCH_WARN_ONLY=y to allow them.\n"); for (n = 0; n < SYMBOL_HASH_SIZE; n++) { struct symbol *s; -- cgit From b9ed847b5ae69e0f2e685f9d53e2dd94c0db751e Mon Sep 17 00:00:00 2001 From: Quentin Perret Date: Tue, 1 Dec 2020 16:52:22 +0000 Subject: modpost: turn static exports into error Using EXPORT_SYMBOL*() on static functions is fundamentally wrong. Modpost currently reports that as a warning, but clearly this is not a pattern we should allow, and all in-tree occurences should have been fixed by now. So, promote the warn() message to error() to make sure this never happens again. Acked-by: Greg Kroah-Hartman Reviewed-by: Matthias Maennich Signed-off-by: Quentin Perret Signed-off-by: Masahiro Yamada --- scripts/mod/modpost.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'scripts') diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c index a750596d5cc2..d6c81657d695 100644 --- a/scripts/mod/modpost.c +++ b/scripts/mod/modpost.c @@ -2648,9 +2648,9 @@ int main(int argc, char **argv) for (s = symbolhash[n]; s; s = s->next) { if (s->is_static) - warn("\"%s\" [%s] is a static %s\n", - s->name, s->module->name, - export_str(s->export)); + error("\"%s\" [%s] is a static %s\n", + s->name, s->module->name, + export_str(s->export)); } } -- cgit From 9ab55d7f240fb05f84ec3b5e37f0c3ab2ce69053 Mon Sep 17 00:00:00 2001 From: Marco Elver Date: Tue, 1 Dec 2020 16:20:18 +0100 Subject: genksyms: Ignore module scoped _Static_assert() The C11 _Static_assert() keyword may be used at module scope, and we need to teach genksyms about it to not abort with an error. We currently have a growing number of static_assert() (but also direct usage of _Static_assert()) users at module scope: git grep -E '^_Static_assert\(|^static_assert\(' | grep -v '^tools' | wc -l 135 More recently, when enabling CONFIG_MODVERSIONS with CONFIG_KCSAN, we observe a number of warnings: WARNING: modpost: EXPORT symbol "<..all kcsan symbols..>" [vmlinux] [...] When running a preprocessed source through 'genksyms -w' a number of syntax errors point at usage of static_assert()s. In the case of kernel/kcsan/encoding.h, new static_assert()s had been introduced which used expressions that appear to cause genksyms to not even be able to recover from the syntax error gracefully (as it appears was the case previously). Therefore, make genksyms ignore all _Static_assert() and the contained expression. With the fix, usage of _Static_assert() no longer cause "syntax error" all over the kernel, and the above modpost warnings for KCSAN are gone, too. Signed-off-by: Marco Elver Acked-by: Nick Desaulniers Signed-off-by: Masahiro Yamada --- scripts/genksyms/keywords.c | 3 +++ scripts/genksyms/lex.l | 27 ++++++++++++++++++++++++++- scripts/genksyms/parse.y | 7 +++++++ 3 files changed, 36 insertions(+), 1 deletion(-) (limited to 'scripts') diff --git a/scripts/genksyms/keywords.c b/scripts/genksyms/keywords.c index 057c6cabad1d..b85e0979a00c 100644 --- a/scripts/genksyms/keywords.c +++ b/scripts/genksyms/keywords.c @@ -32,6 +32,9 @@ static struct resword { { "restrict", RESTRICT_KEYW }, { "asm", ASM_KEYW }, + // c11 keywords that can be used at module scope + { "_Static_assert", STATIC_ASSERT_KEYW }, + // attribute commented out in modutils 2.4.2. People are using 'attribute' as a // field name which breaks the genksyms parser. It is not a gcc keyword anyway. // KAO. }, diff --git a/scripts/genksyms/lex.l b/scripts/genksyms/lex.l index e265c5d96861..ae76472efc43 100644 --- a/scripts/genksyms/lex.l +++ b/scripts/genksyms/lex.l @@ -118,7 +118,7 @@ yylex(void) { static enum { ST_NOTSTARTED, ST_NORMAL, ST_ATTRIBUTE, ST_ASM, ST_TYPEOF, ST_TYPEOF_1, - ST_BRACKET, ST_BRACE, ST_EXPRESSION, + ST_BRACKET, ST_BRACE, ST_EXPRESSION, ST_STATIC_ASSERT, ST_TABLE_1, ST_TABLE_2, ST_TABLE_3, ST_TABLE_4, ST_TABLE_5, ST_TABLE_6 } lexstate = ST_NOTSTARTED; @@ -201,6 +201,11 @@ repeat: case EXPORT_SYMBOL_KEYW: goto fini; + + case STATIC_ASSERT_KEYW: + lexstate = ST_STATIC_ASSERT; + count = 0; + goto repeat; } } if (!suppress_type_lookup) @@ -401,6 +406,26 @@ repeat: } break; + case ST_STATIC_ASSERT: + APP; + switch (token) + { + case '(': + ++count; + goto repeat; + case ')': + if (--count == 0) + { + lexstate = ST_NORMAL; + token = STATIC_ASSERT_PHRASE; + break; + } + goto repeat; + default: + goto repeat; + } + break; + case ST_TABLE_1: goto repeat; diff --git a/scripts/genksyms/parse.y b/scripts/genksyms/parse.y index e22b42245bcc..8e9b5e69e8f0 100644 --- a/scripts/genksyms/parse.y +++ b/scripts/genksyms/parse.y @@ -80,6 +80,7 @@ static void record_compound(struct string_list **keyw, %token SHORT_KEYW %token SIGNED_KEYW %token STATIC_KEYW +%token STATIC_ASSERT_KEYW %token STRUCT_KEYW %token TYPEDEF_KEYW %token UNION_KEYW @@ -97,6 +98,7 @@ static void record_compound(struct string_list **keyw, %token BRACE_PHRASE %token BRACKET_PHRASE %token EXPRESSION_PHRASE +%token STATIC_ASSERT_PHRASE %token CHAR %token DOTS @@ -130,6 +132,7 @@ declaration1: | function_definition | asm_definition | export_definition + | static_assert | error ';' { $$ = $2; } | error '}' { $$ = $2; } ; @@ -493,6 +496,10 @@ export_definition: { export_symbol((*$3)->string); $$ = $5; } ; +/* Ignore any module scoped _Static_assert(...) */ +static_assert: + STATIC_ASSERT_PHRASE ';' { $$ = $2; } + ; %% -- cgit From 135b4957eac43af2aedf8e2a277b9540f33c2558 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Sun, 20 Dec 2020 03:18:42 +0900 Subject: kconfig: fix return value of do_error_if() $(error-if,...) is expanded to an empty string. Currently, it relies on eval_clause() returning xstrdup("") when all attempts for expansion fail, but the correct implementation is to make do_error_if() return xstrdup(""). Fixes: 1d6272e6fe43 ("kconfig: add 'info', 'warning-if', and 'error-if' built-in functions") Signed-off-by: Masahiro Yamada --- scripts/kconfig/preprocess.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'scripts') diff --git a/scripts/kconfig/preprocess.c b/scripts/kconfig/preprocess.c index 0243086fb168..0590f86df6e4 100644 --- a/scripts/kconfig/preprocess.c +++ b/scripts/kconfig/preprocess.c @@ -114,7 +114,7 @@ static char *do_error_if(int argc, char *argv[]) if (!strcmp(argv[0], "y")) pperror("%s", argv[1]); - return NULL; + return xstrdup(""); } static char *do_filename(int argc, char *argv[]) -- cgit From 0fea6e9af889f1a4e072f5de999e07fe6859fc88 Mon Sep 17 00:00:00 2001 From: Andrey Konovalov Date: Tue, 22 Dec 2020 12:02:06 -0800 Subject: kasan, arm64: expand CONFIG_KASAN checks Some #ifdef CONFIG_KASAN checks are only relevant for software KASAN modes (either related to shadow memory or compiler instrumentation). Expand those into CONFIG_KASAN_GENERIC || CONFIG_KASAN_SW_TAGS. Link: https://lkml.kernel.org/r/e6971e432dbd72bb897ff14134ebb7e169bdcf0c.1606161801.git.andreyknvl@google.com Signed-off-by: Andrey Konovalov Signed-off-by: Vincenzo Frascino Reviewed-by: Catalin Marinas Reviewed-by: Alexander Potapenko Tested-by: Vincenzo Frascino Cc: Andrey Ryabinin Cc: Branislav Rankov Cc: Dmitry Vyukov Cc: Evgenii Stepanov Cc: Kevin Brodsky Cc: Marco Elver Cc: Vasily Gorbik Cc: Will Deacon Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- scripts/Makefile.lib | 2 ++ 1 file changed, 2 insertions(+) (limited to 'scripts') diff --git a/scripts/Makefile.lib b/scripts/Makefile.lib index 94133708889d..213677a5ed33 100644 --- a/scripts/Makefile.lib +++ b/scripts/Makefile.lib @@ -148,10 +148,12 @@ endif # we don't want to check (depends on variables KASAN_SANITIZE_obj.o, KASAN_SANITIZE) # ifeq ($(CONFIG_KASAN),y) +ifneq ($(CONFIG_KASAN_HW_TAGS),y) _c_flags += $(if $(patsubst n%,, \ $(KASAN_SANITIZE_$(basetarget).o)$(KASAN_SANITIZE)y), \ $(CFLAGS_KASAN), $(CFLAGS_KASAN_NOSANITIZE)) endif +endif ifeq ($(CONFIG_UBSAN),y) _c_flags += $(if $(patsubst n%,, \ -- cgit From d8f6e5c6c83737cfdad46077e614885a3db9e809 Mon Sep 17 00:00:00 2001 From: Sumera Priyadarsini Date: Wed, 25 Nov 2020 02:02:12 +0530 Subject: scripts: coccicheck: Correct usage of make coccicheck The command "make coccicheck C=1 CHECK=scripts/coccicheck" results in the error: ./scripts/coccicheck: line 65: -1: shift count out of range This happens because every time the C variable is specified, the shell arguments need to be "shifted" in order to take only the last argument, which is the C file to test. These shell arguments mostly comprise flags that have been set in the Makefile. However, when coccicheck is specified in the make command as a rule, the number of shell arguments is zero, thus passing the invalid value -1 to the shift command, resulting in an error. Modify coccicheck to print correct usage of make coccicheck so as to avoid the error. Signed-off-by: Sumera Priyadarsini Signed-off-by: Julia Lawall --- scripts/coccicheck | 12 ++++++++++++ 1 file changed, 12 insertions(+) (limited to 'scripts') diff --git a/scripts/coccicheck b/scripts/coccicheck index d7f6b7ff130a..65fee63aeadb 100755 --- a/scripts/coccicheck +++ b/scripts/coccicheck @@ -60,6 +60,18 @@ COCCIINCLUDE=${COCCIINCLUDE// -include/ --include} if [ "$C" = "1" -o "$C" = "2" ]; then ONLINE=1 + if [[ $# -le 0 ]]; then + echo '' + echo 'Specifying both the variable "C" and rule "coccicheck" in the make +command results in a shift count error.' + echo '' + echo 'Try specifying "scripts/coccicheck" as a value for the CHECK variable instead.' + echo '' + echo 'Example: make C=2 CHECK=scripts/coccicheck drivers/net/ethernet/ethoc.o' + echo '' + exit 1 + fi + # Take only the last argument, which is the C file to test shift $(( $# - 1 )) OPTIONS="$COCCIINCLUDE $1" -- cgit