From ac5f313624d876b41d4a1292181d17e80d44159c Mon Sep 17 00:00:00 2001 From: Wen Yang Date: Fri, 10 Jan 2020 21:15:26 +0800 Subject: coccinelle: semantic patch to check for inappropriate do_div() calls do_div() does a 64-by-32 division. When the divisor is unsigned long, u64, or s64, do_div() truncates it to 32 bits, this means it can test non-zero and be truncated to zero for division. This semantic patch is inspired by Mateusz Guzik's patch: commit b0ab99e7736a ("sched: Fix possible divide by zero in avg_atom() calculation") Signed-off-by: Wen Yang Signed-off-by: Julia Lawall Cc: Gilles Muller Cc: Nicolas Palix Cc: Michal Marek Cc: Matthias Maennich Cc: Greg Kroah-Hartman Cc: Masahiro Yamada Cc: Thomas Gleixner Cc: cocci@systeme.lip6.fr Cc: linux-kernel@vger.kernel.org --- scripts/coccinelle/misc/do_div.cocci | 155 +++++++++++++++++++++++++++++++++++ 1 file changed, 155 insertions(+) create mode 100644 scripts/coccinelle/misc/do_div.cocci (limited to 'scripts') diff --git a/scripts/coccinelle/misc/do_div.cocci b/scripts/coccinelle/misc/do_div.cocci new file mode 100644 index 000000000000..79db083c5208 --- /dev/null +++ b/scripts/coccinelle/misc/do_div.cocci @@ -0,0 +1,155 @@ +// SPDX-License-Identifier: GPL-2.0-only +/// do_div() does a 64-by-32 division. +/// When the divisor is long, unsigned long, u64, or s64, +/// do_div() truncates it to 32 bits, this means it can test +/// non-zero and be truncated to 0 for division on 64bit platforms. +/// +//# This makes an effort to find those inappropriate do_div() calls. +// +// Confidence: Moderate +// Copyright: (C) 2020 Wen Yang, Alibaba. +// Comments: +// Options: --no-includes --include-headers + +virtual context +virtual org +virtual report + +@initialize:python@ +@@ + +def get_digit_type_and_value(str): + is_digit = False + value = 0 + + try: + if (str.isdigit()): + is_digit = True + value = int(str, 0) + elif (str.upper().endswith('ULL')): + is_digit = True + value = int(str[:-3], 0) + elif (str.upper().endswith('LL')): + is_digit = True + value = int(str[:-2], 0) + elif (str.upper().endswith('UL')): + is_digit = True + value = int(str[:-2], 0) + elif (str.upper().endswith('L')): + is_digit = True + value = int(str[:-1], 0) + elif (str.upper().endswith('U')): + is_digit = True + value = int(str[:-1], 0) + except Exception as e: + print('Error:',e) + is_digit = False + value = 0 + finally: + return is_digit, value + +def filter_out_safe_constants(str): + is_digit, value = get_digit_type_and_value(str) + if (is_digit): + if (value >= 0x100000000): + return True + else: + return False + else: + return True + +def construct_warnings(suggested_fun): + msg="WARNING: do_div() does a 64-by-32 division, please consider using %s instead." + return msg % suggested_fun + +@depends on context@ +expression f; +long l: script:python() { filter_out_safe_constants(l) }; +unsigned long ul : script:python() { filter_out_safe_constants(ul) }; +u64 ul64 : script:python() { filter_out_safe_constants(ul64) }; +s64 sl64 : script:python() { filter_out_safe_constants(sl64) }; + +@@ +( +* do_div(f, l); +| +* do_div(f, ul); +| +* do_div(f, ul64); +| +* do_div(f, sl64); +) + +@r depends on (org || report)@ +expression f; +position p; +long l: script:python() { filter_out_safe_constants(l) }; +unsigned long ul : script:python() { filter_out_safe_constants(ul) }; +u64 ul64 : script:python() { filter_out_safe_constants(ul64) }; +s64 sl64 : script:python() { filter_out_safe_constants(sl64) }; +@@ +( +do_div@p(f, l); +| +do_div@p(f, ul); +| +do_div@p(f, ul64); +| +do_div@p(f, sl64); +) + +@script:python depends on org@ +p << r.p; +ul << r.ul; +@@ + +coccilib.org.print_todo(p[0], construct_warnings("div64_ul")) + +@script:python depends on org@ +p << r.p; +l << r.l; +@@ + +coccilib.org.print_todo(p[0], construct_warnings("div64_long")) + +@script:python depends on org@ +p << r.p; +ul64 << r.ul64; +@@ + +coccilib.org.print_todo(p[0], construct_warnings("div64_u64")) + +@script:python depends on org@ +p << r.p; +sl64 << r.sl64; +@@ + +coccilib.org.print_todo(p[0], construct_warnings("div64_s64")) + +@script:python depends on report@ +p << r.p; +ul << r.ul; +@@ + +coccilib.report.print_report(p[0], construct_warnings("div64_ul")) + +@script:python depends on report@ +p << r.p; +l << r.l; +@@ + +coccilib.report.print_report(p[0], construct_warnings("div64_long")) + +@script:python depends on report@ +p << r.p; +sl64 << r.sl64; +@@ + +coccilib.report.print_report(p[0], construct_warnings("div64_s64")) + +@script:python depends on report@ +p << r.p; +ul64 << r.ul64; +@@ + +coccilib.report.print_report(p[0], construct_warnings("div64_u64")) -- cgit v1.2.3 From 46d28947d9876fc0f8f93d3c69813ef6e9852595 Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Wed, 8 Sep 2021 15:29:18 +0200 Subject: x86/extable: Rework the exception table mechanics The exception table entries contain the instruction address, the fixup address and the handler address. All addresses are relative. Storing the handler address has a few downsides: 1) Most handlers need to be exported 2) Handlers can be defined everywhere and there is no overview about the handler types 3) MCE needs to check the handler type to decide whether an in kernel #MC can be recovered. The functionality of the handler itself is not in any way special, but for these checks there need to be separate functions which in the worst case have to be exported. Some of these 'recoverable' exception fixups are pretty obscure and just reuse some other handler to spare code. That obfuscates e.g. the #MC safe copy functions. Cleaning that up would require more handlers and exports Rework the exception fixup mechanics by storing a fixup type number instead of the handler address and invoke the proper handler for each fixup type. Also teach the extable sort to leave the type field alone. This makes most handlers static except for special cases like the MCE MSR fixup and the BPF fixup. This allows to add more types for cleaning up the obscure places without adding more handler code and exports. There is a marginal code size reduction for a production config and it removes _eight_ exported symbols. Signed-off-by: Thomas Gleixner Signed-off-by: Borislav Petkov Acked-by: Alexei Starovoitov Link: https://lkml.kernel.org/r/20210908132525.211958725@linutronix.de --- scripts/sorttable.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'scripts') diff --git a/scripts/sorttable.c b/scripts/sorttable.c index f355869c65cd..a9b3324cacf9 100644 --- a/scripts/sorttable.c +++ b/scripts/sorttable.c @@ -236,7 +236,7 @@ static void x86_sort_relative_table(char *extab_image, int image_size) w(r(loc) + i, loc); w(r(loc + 1) + i + 4, loc + 1); - w(r(loc + 2) + i + 8, loc + 2); + /* Don't touch the fixup type */ i += sizeof(uint32_t) * 3; } @@ -249,7 +249,7 @@ static void x86_sort_relative_table(char *extab_image, int image_size) w(r(loc) - i, loc); w(r(loc + 1) - (i + 4), loc + 1); - w(r(loc + 2) - (i + 8), loc + 2); + /* Don't touch the fixup type */ i += sizeof(uint32_t) * 3; } -- cgit v1.2.3 From d06246ebd7738bbfc581b887bc24a102450a323f Mon Sep 17 00:00:00 2001 From: "Philip K. Gisslow" Date: Sun, 5 Sep 2021 09:31:32 +0200 Subject: scripts/tags.sh: Fix obsolete parameter for ctags Distros such as Fedora and Arch are using the maintained universal-ctags implementation. This version has replaced the obsolete --extra flag with --extras. Signed-off-by: Philip K. Gisslow Link: https://lore.kernel.org/r/20210905073133.21910-1-ripxorip@gmail.com Signed-off-by: Greg Kroah-Hartman --- scripts/tags.sh | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'scripts') diff --git a/scripts/tags.sh b/scripts/tags.sh index db8ba411860a..b24bfaec6290 100755 --- a/scripts/tags.sh +++ b/scripts/tags.sh @@ -247,6 +247,10 @@ setup_regex() exuberant() { + CTAGS_EXTRA="extra" + if $1 --version 2>&1 | grep -iq universal; then + CTAGS_EXTRA="extras" + fi setup_regex exuberant asm c all_target_sources | xargs $1 -a \ -I __initdata,__exitdata,__initconst,__ro_after_init \ @@ -261,7 +265,7 @@ exuberant() -I EXPORT_SYMBOL,EXPORT_SYMBOL_GPL,ACPI_EXPORT_SYMBOL \ -I DEFINE_TRACE,EXPORT_TRACEPOINT_SYMBOL,EXPORT_TRACEPOINT_SYMBOL_GPL \ -I static,const \ - --extra=+fq --c-kinds=+px --fields=+iaS --langmap=c:+.h \ + --$CTAGS_EXTRA=+fq --c-kinds=+px --fields=+iaS --langmap=c:+.h \ "${regex[@]}" setup_regex exuberant kconfig -- cgit v1.2.3 From ab9c14805b379b7890f2e162149b6978b2a75986 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Sat, 18 Sep 2021 11:52:11 +0200 Subject: scripts: get_abi.pl: Better handle multiple What parameters Using a comma here is problematic, as some What: expressions may already contain a comma. So, use \xac character instead. Signed-off-by: Mauro Carvalho Chehab Link: https://lore.kernel.org/r/e83e7ffaf3429f8dfca00d1d01653ecfa36f6119.1631957565.git.mchehab+huawei@kernel.org Signed-off-by: Greg Kroah-Hartman --- scripts/get_abi.pl | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'scripts') diff --git a/scripts/get_abi.pl b/scripts/get_abi.pl index d7aa82094296..cfc107df59f4 100755 --- a/scripts/get_abi.pl +++ b/scripts/get_abi.pl @@ -129,12 +129,12 @@ sub parse_abi { push @{$symbols{$content}->{file}}, " $file:" . ($ln - 1); if ($tag =~ m/what/) { - $what .= ", " . $content; + $what .= "\xac" . $content; } else { if ($what) { parse_error($file, $ln, "What '$what' doesn't have a description", "") if (!$data{$what}->{description}); - foreach my $w(split /, /, $what) { + foreach my $w(split /\xac/, $what) { $symbols{$w}->{xref} = $what; }; } @@ -239,7 +239,7 @@ sub parse_abi { if ($what) { parse_error($file, $ln, "What '$what' doesn't have a description", "") if (!$data{$what}->{description}); - foreach my $w(split /, /,$what) { + foreach my $w(split /\xac/,$what) { $symbols{$w}->{xref} = $what; }; } @@ -328,7 +328,7 @@ sub output_rest { printf ".. _%s:\n\n", $data{$what}->{label}; - my @names = split /, /,$w; + my @names = split /\xac/,$w; my $len = 0; foreach my $name (@names) { -- cgit v1.2.3 From f090db43958a0a0b6a920d25f56a79cce2ec8d1b Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Sat, 18 Sep 2021 11:52:12 +0200 Subject: scripts: get_abi.pl: Check for missing symbols at the ABI specs Check for the symbols that exists under /sys but aren't defined at Documentation/ABI. Signed-off-by: Mauro Carvalho Chehab Link: https://lore.kernel.org/r/958e4f3a319148af6d847c0df95e35426f9c4c5f.1631957565.git.mchehab+huawei@kernel.org Signed-off-by: Greg Kroah-Hartman --- scripts/get_abi.pl | 90 ++++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 88 insertions(+), 2 deletions(-) (limited to 'scripts') diff --git a/scripts/get_abi.pl b/scripts/get_abi.pl index cfc107df59f4..78364c4c4967 100755 --- a/scripts/get_abi.pl +++ b/scripts/get_abi.pl @@ -13,7 +13,9 @@ my $help = 0; my $man = 0; my $debug = 0; my $enable_lineno = 0; +my $show_warnings = 1; my $prefix="Documentation/ABI"; +my $sysfs_prefix="/sys"; # # If true, assumes that the description is formatted with ReST @@ -36,7 +38,7 @@ pod2usage(2) if (scalar @ARGV < 1 || @ARGV > 2); my ($cmd, $arg) = @ARGV; -pod2usage(2) if ($cmd ne "search" && $cmd ne "rest" && $cmd ne "validate"); +pod2usage(2) if ($cmd ne "search" && $cmd ne "rest" && $cmd ne "validate" && $cmd ne "undefined"); pod2usage(2) if ($cmd eq "search" && !$arg); require Data::Dumper if ($debug); @@ -50,6 +52,8 @@ my %symbols; sub parse_error($$$$) { my ($file, $ln, $msg, $data) = @_; + return if (!$show_warnings); + $data =~ s/\s+$/\n/; print STDERR "Warning: file $file#$ln:\n\t$msg"; @@ -521,11 +525,88 @@ sub search_symbols { } } +# Exclude /sys/kernel/debug and /sys/kernel/tracing from the search path +sub skip_debugfs { + if (($File::Find::dir =~ m,^/sys/kernel,)) { + return grep {!/(debug|tracing)/ } @_; + } + + if (($File::Find::dir =~ m,^/sys/fs,)) { + return grep {!/(pstore|bpf|fuse)/ } @_; + } + + return @_ +} + +my %leaf; + +my $escape_symbols = qr { ([\x01-\x08\x0e-\x1f\x21-\x29\x2b-\x2d\x3a-\x40\x7b-\xff]) }x; +sub parse_existing_sysfs { + my $file = $File::Find::name; + + my $mode = (stat($file))[2]; + return if ($mode & S_IFDIR); + + my $leave = $file; + $leave =~ s,.*/,,; + + if (defined($leaf{$leave})) { + # FIXME: need to check if the path makes sense + my $what = $leaf{$leave}; + + $what =~ s/,/ /g; + + $what =~ s/\<[^\>]+\>/.*/g; + $what =~ s/\{[^\}]+\}/.*/g; + $what =~ s/\[[^\]]+\]/.*/g; + $what =~ s,/\.\.\./,/.*/,g; + $what =~ s,/\*/,/.*/,g; + + $what =~ s/\s+/ /g; + + # Escape all other symbols + $what =~ s/$escape_symbols/\\$1/g; + + foreach my $i (split / /,$what) { + if ($file =~ m#^$i$#) { +# print "$file: $i: OK!\n"; + return; + } + } + + print "$file: $leave is defined at $what\n"; + + return; + } + + print "$file not found.\n"; +} + +sub undefined_symbols { + foreach my $w (sort keys %data) { + foreach my $what (split /\xac /,$w) { + my $leave = $what; + $leave =~ s,.*/,,; + + if (defined($leaf{$leave})) { + $leaf{$leave} .= " " . $what; + } else { + $leaf{$leave} = $what; + } + } + } + + find({wanted =>\&parse_existing_sysfs, preprocess =>\&skip_debugfs, no_chdir => 1}, $sysfs_prefix); +} + # Ensure that the prefix will always end with a slash # While this is not needed for find, it makes the patch nicer # with --enable-lineno $prefix =~ s,/?$,/,; +if ($cmd eq "undefined" || $cmd eq "search") { + $show_warnings = 0; +} # # Parses all ABI files located at $prefix dir # @@ -536,7 +617,9 @@ print STDERR Data::Dumper->Dump([\%data], [qw(*data)]) if ($debug); # # Handles the command # -if ($cmd eq "search") { +if ($cmd eq "undefined") { + undefined_symbols; +} elsif ($cmd eq "search") { search_symbols; } else { if ($cmd eq "rest") { @@ -575,6 +658,9 @@ B - output the ABI in ReST markup language B - validate the ABI contents +B - existing symbols at the system that aren't + defined at Documentation/ABI + =back =head1 OPTIONS -- cgit v1.2.3 From ab02c5150b3164bad777d882fe324cbca3cc9d1d Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Sat, 18 Sep 2021 11:52:13 +0200 Subject: scripts: get_abi.pl: detect softlinks The way sysfs works is that the same leave may be present under /sys/devices, /sys/bus and /sys/class, etc, linked via soft symlinks. To make it harder to parse, the ABI definition usually refers only to one of those locations. So, improve the logic in order to retrieve the symlinks. Signed-off-by: Mauro Carvalho Chehab Link: https://lore.kernel.org/r/77c49f7d158d88e17f18d40652b75cdde9e179eb.1631957565.git.mchehab+huawei@kernel.org Signed-off-by: Greg Kroah-Hartman --- scripts/get_abi.pl | 189 +++++++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 156 insertions(+), 33 deletions(-) (limited to 'scripts') diff --git a/scripts/get_abi.pl b/scripts/get_abi.pl index 78364c4c4967..b0ca4f4e56f2 100755 --- a/scripts/get_abi.pl +++ b/scripts/get_abi.pl @@ -8,8 +8,10 @@ use Pod::Usage; use Getopt::Long; use File::Find; use Fcntl ':mode'; +use Cwd 'abs_path'; my $help = 0; +my $hint = 0; my $man = 0; my $debug = 0; my $enable_lineno = 0; @@ -28,6 +30,7 @@ GetOptions( "rst-source!" => \$description_is_rst, "dir=s" => \$prefix, 'help|?' => \$help, + "show-hints" => \$hint, man => \$man ) or pod2usage(2); @@ -526,7 +529,7 @@ sub search_symbols { } # Exclude /sys/kernel/debug and /sys/kernel/tracing from the search path -sub skip_debugfs { +sub dont_parse_special_attributes { if (($File::Find::dir =~ m,^/sys/kernel,)) { return grep {!/(debug|tracing)/ } @_; } @@ -539,64 +542,178 @@ sub skip_debugfs { } my %leaf; +my %aliases; +my @files; -my $escape_symbols = qr { ([\x01-\x08\x0e-\x1f\x21-\x29\x2b-\x2d\x3a-\x40\x7b-\xff]) }x; +my $escape_symbols = qr { ([\x01-\x08\x0e-\x1f\x21-\x29\x2b-\x2d\x3a-\x40\x7b-\xfe]) }x; sub parse_existing_sysfs { my $file = $File::Find::name; + my $mode = (lstat($file))[2]; + my $abs_file = abs_path($file); - my $mode = (stat($file))[2]; - return if ($mode & S_IFDIR); + if (S_ISLNK($mode)) { + $aliases{$file} = $abs_file; + return; + } + + return if (S_ISDIR($mode)); - my $leave = $file; - $leave =~ s,.*/,,; + # Trivial: file is defined exactly the same way at ABI What: + return if (defined($data{$file})); + return if (defined($data{$abs_file})); - if (defined($leaf{$leave})) { - # FIXME: need to check if the path makes sense - my $what = $leaf{$leave}; + push @files, $abs_file; +} - $what =~ s/,/ /g; +sub check_undefined_symbols { + foreach my $file (sort @files) { - $what =~ s/\<[^\>]+\>/.*/g; - $what =~ s/\{[^\}]+\}/.*/g; - $what =~ s/\[[^\]]+\]/.*/g; - $what =~ s,/\.\.\./,/.*/,g; - $what =~ s,/\*/,/.*/,g; + # sysfs-module is special, as its definitions are inside + # a text. For now, just ignore them. + next if ($file =~ m#^/sys/module/#); - $what =~ s/\s+/ /g; + # Ignore cgroup and firmware + next if ($file =~ m#^/sys/(fs/cgroup|firmware)/#); - # Escape all other symbols - $what =~ s/$escape_symbols/\\$1/g; + my $defined = 0; + my $exact = 0; + my $whats = ""; - foreach my $i (split / /,$what) { - if ($file =~ m#^$i$#) { -# print "$file: $i: OK!\n"; - return; + my $leave = $file; + $leave =~ s,.*/,,; + + my $path = $file; + $path =~ s,(.*/).*,$1,; + + if (defined($leaf{$leave})) { + my $what = $leaf{$leave}; + $whats .= " $what" if (!($whats =~ m/$what/)); + + foreach my $w (split / /, $what) { + if ($file =~ m#^$w$#) { + $exact = 1; + last; + } + } + # Check for aliases + # + # TODO: this algorithm is O(w * n²). It can be + # improved in the future in order to handle it + # faster, by changing parse_existing_sysfs to + # store the sysfs inside a tree, at the expense + # on making the code less readable and/or using some + # additional perl library. + foreach my $a (keys %aliases) { + my $new = $aliases{$a}; + my $len = length($new); + + if (substr($file, 0, $len) eq $new) { + my $newf = $a . substr($file, $len); + + foreach my $w (split / /, $what) { + if ($newf =~ m#^$w$#) { + $exact = 1; + last; + } + } + } } + + $defined++; } + next if ($exact); - print "$file: $leave is defined at $what\n"; + # Ignore some sysfs nodes + next if ($file =~ m#/(sections|notes)/#); - return; - } + # Would need to check at + # Documentation/admin-guide/kernel-parameters.txt, but this + # is not easily parseable. + next if ($file =~ m#/parameters/#); - print "$file not found.\n"; + if ($hint && $defined) { + print "$leave at $path might be one of:$whats\n"; + next; + } + print "$file not found.\n"; + } } sub undefined_symbols { + find({ + wanted =>\&parse_existing_sysfs, + preprocess =>\&dont_parse_special_attributes, + no_chdir => 1 + }, $sysfs_prefix); + foreach my $w (sort keys %data) { foreach my $what (split /\xac /,$w) { + next if (!($what =~ m/^$sysfs_prefix/)); + + # Convert what into regular expressions + + $what =~ s,/\.\.\./,/*/,g; + $what =~ s,\*,.*,g; + + # Temporarily change [0-9]+ type of patterns + $what =~ s/\[0\-9\]\+/\xff/g; + + # Temporarily change [\d+-\d+] type of patterns + $what =~ s/\[0\-\d+\]/\xff/g; + $what =~ s/\[(\d+)\]/\xf4$1\xf5/g; + + # Temporarily change [0-9] type of patterns + $what =~ s/\[(\d)\-(\d)\]/\xf4$1-$2\xf5/g; + + # Handle multiple option patterns + $what =~ s/[\{\<\[]([\w_]+)(?:[,|]+([\w_]+)){1,}[\}\>\]]/($1|$2)/g; + + # Handle wildcards + $what =~ s/\<[^\>]+\>/.*/g; + $what =~ s/\{[^\}]+\}/.*/g; + $what =~ s/\[[^\]]+\]/.*/g; + + $what =~ s/[XYZ]/.*/g; + + # Recover [0-9] type of patterns + $what =~ s/\xf4/[/g; + $what =~ s/\xf5/]/g; + + # Remove duplicated spaces + $what =~ s/\s+/ /g; + + # Special case: this ABI has a parenthesis on it + $what =~ s/sqrt\(x^2\+y^2\+z^2\)/sqrt\(x^2\+y^2\+z^2\)/; + + # Special case: drop comparition as in: + # What: foo = + # (this happens on a few IIO definitions) + $what =~ s,\s*\=.*$,,; + my $leave = $what; $leave =~ s,.*/,,; - if (defined($leaf{$leave})) { - $leaf{$leave} .= " " . $what; - } else { - $leaf{$leave} = $what; + next if ($leave =~ m/^\.\*/ || $leave eq ""); + + # Escape all other symbols + $what =~ s/$escape_symbols/\\$1/g; + $what =~ s/\\\\/\\/g; + $what =~ s/\\([\[\]\(\)\|])/$1/g; + $what =~ s/(\d+)\\(-\d+)/$1$2/g; + + $leave =~ s/[\(\)]//g; + + foreach my $l (split /\|/, $leave) { + if (defined($leaf{$l})) { + next if ($leaf{$l} =~ m/$what/); + $leaf{$l} .= " " . $what; + } else { + $leaf{$l} = $what; + } } } } - - find({wanted =>\&parse_existing_sysfs, preprocess =>\&skip_debugfs, no_chdir => 1}, $sysfs_prefix); + check_undefined_symbols; } # Ensure that the prefix will always end with a slash @@ -646,7 +763,8 @@ abi_book.pl - parse the Linux ABI files and produce a ReST book. =head1 SYNOPSIS B [--debug] [--enable-lineno] [--man] [--help] - [--(no-)rst-source] [--dir=] [] + [--(no-)rst-source] [--dir=] [--show-hints] + [] Where can be: @@ -688,6 +806,11 @@ Enable output of #define LINENO lines. Put the script in verbose mode, useful for debugging. Can be called multiple times, to increase verbosity. +=item B<--show-hints> + +Show hints about possible definitions for the missing ABI symbols. +Used only when B. + =item B<--help> Prints a brief help message and exits. -- cgit v1.2.3 From 14c942578e19f5760319da3371193c1bc6242f7f Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Sat, 18 Sep 2021 11:52:14 +0200 Subject: scripts: get_abi.pl: add an option to filter undefined results The output of this script can be too big. Add an option to filter out results, in order to help finding issues at the ABI files. Signed-off-by: Mauro Carvalho Chehab Link: https://lore.kernel.org/r/7b56c10195bb5e5dfd8b5838a3db8d361231d884.1631957565.git.mchehab+huawei@kernel.org Signed-off-by: Greg Kroah-Hartman --- scripts/get_abi.pl | 37 +++++++++++++++++++++++++++++++------ 1 file changed, 31 insertions(+), 6 deletions(-) (limited to 'scripts') diff --git a/scripts/get_abi.pl b/scripts/get_abi.pl index b0ca4f4e56f2..f5f2f664e336 100755 --- a/scripts/get_abi.pl +++ b/scripts/get_abi.pl @@ -18,6 +18,7 @@ my $enable_lineno = 0; my $show_warnings = 1; my $prefix="Documentation/ABI"; my $sysfs_prefix="/sys"; +my $search_string; # # If true, assumes that the description is formatted with ReST @@ -31,6 +32,7 @@ GetOptions( "dir=s" => \$prefix, 'help|?' => \$help, "show-hints" => \$hint, + "search-string=s" => \$search_string, man => \$man ) or pod2usage(2); @@ -568,16 +570,13 @@ sub parse_existing_sysfs { sub check_undefined_symbols { foreach my $file (sort @files) { - # sysfs-module is special, as its definitions are inside - # a text. For now, just ignore them. - next if ($file =~ m#^/sys/module/#); - # Ignore cgroup and firmware next if ($file =~ m#^/sys/(fs/cgroup|firmware)/#); my $defined = 0; my $exact = 0; my $whats = ""; + my $found_string; my $leave = $file; $leave =~ s,.*/,,; @@ -585,6 +584,12 @@ sub check_undefined_symbols { my $path = $file; $path =~ s,(.*/).*,$1,; + if ($search_string) { + next if (!($file =~ m#$search_string#)); + $found_string = 1; + } + + print "--> $file\n" if ($found_string && $hint); if (defined($leaf{$leave})) { my $what = $leaf{$leave}; $whats .= " $what" if (!($whats =~ m/$what/)); @@ -610,6 +615,7 @@ sub check_undefined_symbols { if (substr($file, 0, $len) eq $new) { my $newf = $a . substr($file, $len); + print " $newf\n" if ($found_string && $hint); foreach my $w (split / /, $what) { if ($newf =~ m#^$w$#) { $exact = 1; @@ -632,10 +638,10 @@ sub check_undefined_symbols { next if ($file =~ m#/parameters/#); if ($hint && $defined) { - print "$leave at $path might be one of:$whats\n"; + print "$leave at $path might be one of:$whats\n" if (!$search_string || $found_string); next; } - print "$file not found.\n"; + print "$file not found.\n" if (!$search_string || $found_string); } } @@ -701,16 +707,29 @@ sub undefined_symbols { $what =~ s/\\([\[\]\(\)\|])/$1/g; $what =~ s/(\d+)\\(-\d+)/$1$2/g; + $what =~ s/\xff/\\d+/g; + + + # Special case: IIO ABI which a parenthesis. + $what =~ s/sqrt(.*)/sqrt\(.*\)/; + $leave =~ s/[\(\)]//g; + my $added = 0; foreach my $l (split /\|/, $leave) { if (defined($leaf{$l})) { next if ($leaf{$l} =~ m/$what/); $leaf{$l} .= " " . $what; + $added = 1; } else { $leaf{$l} = $what; + $added = 1; } } + if ($search_string && $added) { + print "What: $what\n" if ($what =~ m#$search_string#); + } + } } check_undefined_symbols; @@ -764,6 +783,7 @@ abi_book.pl - parse the Linux ABI files and produce a ReST book. B [--debug] [--enable-lineno] [--man] [--help] [--(no-)rst-source] [--dir=] [--show-hints] + [--search-string ] [] Where can be: @@ -811,6 +831,11 @@ times, to increase verbosity. Show hints about possible definitions for the missing ABI symbols. Used only when B. +=item B<--search-string> [regex string] + +Show only occurences that match a search string. +Used only when B. + =item B<--help> Prints a brief help message and exits. -- cgit v1.2.3 From 50116aec11debf6dec6295856f3b9368a6a04edf Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Sat, 18 Sep 2021 11:52:15 +0200 Subject: scripts: get_abi.pl: don't skip what that ends with wildcards The search algorithm used inside check_undefined_symbols has an optimization: it seeks only whats that have the same leave name. This helps not only to speedup the search, but it also allows providing a hint about a partial match. There's a drawback, however: when "what:" finishes with a wildcard, the logic will skip the what, reporting it as "not found". Fix it by grouping the remaining cases altogether, and disabing any hints for such cases. Signed-off-by: Mauro Carvalho Chehab Link: https://lore.kernel.org/r/79ba5139643355230e3bba136b20991cfc92020f.1631957565.git.mchehab+huawei@kernel.org Signed-off-by: Greg Kroah-Hartman --- scripts/get_abi.pl | 80 +++++++++++++++++++++++++++++++----------------------- 1 file changed, 46 insertions(+), 34 deletions(-) (limited to 'scripts') diff --git a/scripts/get_abi.pl b/scripts/get_abi.pl index f5f2f664e336..fe83f295600c 100755 --- a/scripts/get_abi.pl +++ b/scripts/get_abi.pl @@ -589,44 +589,47 @@ sub check_undefined_symbols { $found_string = 1; } + if ($leave =~ /^\d+$/ || !defined($leaf{$leave})) { + $leave = "others"; + } + print "--> $file\n" if ($found_string && $hint); - if (defined($leaf{$leave})) { - my $what = $leaf{$leave}; - $whats .= " $what" if (!($whats =~ m/$what/)); - - foreach my $w (split / /, $what) { - if ($file =~ m#^$w$#) { - $exact = 1; - last; - } + my $what = $leaf{$leave}; + $whats .= " $what" if (!($whats =~ m/$what/)); + + foreach my $w (split / /, $what) { + if ($file =~ m#^$w$#) { + $exact = 1; + last; } - # Check for aliases - # - # TODO: this algorithm is O(w * n²). It can be - # improved in the future in order to handle it - # faster, by changing parse_existing_sysfs to - # store the sysfs inside a tree, at the expense - # on making the code less readable and/or using some - # additional perl library. - foreach my $a (keys %aliases) { - my $new = $aliases{$a}; - my $len = length($new); - - if (substr($file, 0, $len) eq $new) { - my $newf = $a . substr($file, $len); - - print " $newf\n" if ($found_string && $hint); - foreach my $w (split / /, $what) { - if ($newf =~ m#^$w$#) { - $exact = 1; - last; - } + } + # Check for aliases + # + # TODO: this algorithm is O(w * n²). It can be + # improved in the future in order to handle it + # faster, by changing parse_existing_sysfs to + # store the sysfs inside a tree, at the expense + # on making the code less readable and/or using some + # additional perl library. + foreach my $a (keys %aliases) { + my $new = $aliases{$a}; + my $len = length($new); + + if (substr($file, 0, $len) eq $new) { + my $newf = $a . substr($file, $len); + + print " $newf\n" if ($found_string && $hint); + foreach my $w (split / /, $what) { + if ($newf =~ m#^$w$#) { + $exact = 1; + last; } } } - - $defined++; } + + $defined++; + next if ($exact); # Ignore some sysfs nodes @@ -637,7 +640,7 @@ sub check_undefined_symbols { # is not easily parseable. next if ($file =~ m#/parameters/#); - if ($hint && $defined) { + if ($hint && $defined && $leave ne "others") { print "$leave at $path might be one of:$whats\n" if (!$search_string || $found_string); next; } @@ -699,7 +702,16 @@ sub undefined_symbols { my $leave = $what; $leave =~ s,.*/,,; - next if ($leave =~ m/^\.\*/ || $leave eq ""); + # $leave is used to improve search performance at + # check_undefined_symbols, as the algorithm there can seek + # for a small number of "what". It also allows giving a + # hint about a leave with the same name somewhere else. + # However, there are a few occurences where the leave is + # either a wildcard or a number. Just group such cases + # altogether. + if ($leave =~ m/^\.\*/ || $leave eq "" || $leave =~ /^\d+$/) { + $leave = "others" ; + } # Escape all other symbols $what =~ s/$escape_symbols/\\$1/g; -- cgit v1.2.3 From 0b87a1b81ba9b9e2d1d2bc65b3b4318bb645a6e7 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Sat, 18 Sep 2021 11:52:16 +0200 Subject: scripts: get_abi.pl: Ignore fs/cgroup sysfs nodes earlier In order to speedup the parser and store less data, handle fs/cgroup exceptions a lot earlier. Signed-off-by: Mauro Carvalho Chehab Link: https://lore.kernel.org/r/caa37831c9e02ae58677d1515ed7cee94f52ea9d.1631957565.git.mchehab+huawei@kernel.org Signed-off-by: Greg Kroah-Hartman --- scripts/get_abi.pl | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'scripts') diff --git a/scripts/get_abi.pl b/scripts/get_abi.pl index fe83f295600c..aa0a751563ba 100755 --- a/scripts/get_abi.pl +++ b/scripts/get_abi.pl @@ -550,6 +550,10 @@ my @files; my $escape_symbols = qr { ([\x01-\x08\x0e-\x1f\x21-\x29\x2b-\x2d\x3a-\x40\x7b-\xfe]) }x; sub parse_existing_sysfs { my $file = $File::Find::name; + + # Ignore cgroup and firmware + return if ($file =~ m#^/sys/(fs/cgroup|firmware)/#); + my $mode = (lstat($file))[2]; my $abs_file = abs_path($file); @@ -570,9 +574,6 @@ sub parse_existing_sysfs { sub check_undefined_symbols { foreach my $file (sort @files) { - # Ignore cgroup and firmware - next if ($file =~ m#^/sys/(fs/cgroup|firmware)/#); - my $defined = 0; my $exact = 0; my $whats = ""; -- cgit v1.2.3 From ca8e055c22155b262e14409a555bab41a52edfea Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Sat, 18 Sep 2021 11:52:17 +0200 Subject: scripts: get_abi.pl: add a graph to speedup the undefined algorithm Searching for symlinks is an expensive operation with the current logic, as it is at the order of O(n^3). In practice, running the check spends 2-3 minutes to check all symbols. Fix it by storing the directory tree into a graph, and using a Breadth First Search (BFS) to find the links for each sysfs node. With such improvement, it can now report issues with ~11 seconds on my machine. It comes with a price, though: there are more symbols reported as undefined after this change. I suspect it is due to some sysfs circular loops that are dropped by BFS. Despite such increase, it seems that the reports are now more coherent. Signed-off-by: Mauro Carvalho Chehab Link: https://lore.kernel.org/r/f5c1e7b14a27132821c08f0459ba9aea3ed69028.1631957565.git.mchehab+huawei@kernel.org Signed-off-by: Greg Kroah-Hartman --- scripts/get_abi.pl | 188 ++++++++++++++++++++++++++++++++++++----------------- 1 file changed, 127 insertions(+), 61 deletions(-) (limited to 'scripts') diff --git a/scripts/get_abi.pl b/scripts/get_abi.pl index aa0a751563ba..c52a1cf0f49d 100755 --- a/scripts/get_abi.pl +++ b/scripts/get_abi.pl @@ -546,6 +546,73 @@ sub dont_parse_special_attributes { my %leaf; my %aliases; my @files; +my %root; + +sub graph_add_file { + my $file = shift; + my $type = shift; + + my $dir = $file; + $dir =~ s,^(.*/).*,$1,; + $file =~ s,.*/,,; + + my $name; + my $file_ref = \%root; + foreach my $edge(split "/", $dir) { + $name .= "$edge/"; + if (!defined ${$file_ref}{$edge}) { + ${$file_ref}{$edge} = { }; + } + $file_ref = \%{$$file_ref{$edge}}; + ${$file_ref}{"__name"} = [ $name ]; + } + $name .= "$file"; + ${$file_ref}{$file} = { + "__name" => [ $name ] + }; + + return \%{$$file_ref{$file}}; +} + +sub graph_add_link { + my $file = shift; + my $link = shift; + + # Traverse graph to find the reference + my $file_ref = \%root; + foreach my $edge(split "/", $file) { + $file_ref = \%{$$file_ref{$edge}} || die "Missing node!"; + } + + # do a BFS + + my @queue; + my %seen; + my $base_name; + my $st; + + push @queue, $file_ref; + $seen{$start}++; + + while (@queue) { + my $v = shift @queue; + my @child = keys(%{$v}); + + foreach my $c(@child) { + next if $seen{$$v{$c}}; + next if ($c eq "__name"); + + # Add new name + my $name = @{$$v{$c}{"__name"}}[0]; + if ($name =~ s#^$file/#$link/#) { + push @{$$v{$c}{"__name"}}, $name; + } + # Add child to the queue and mark as seen + push @queue, $$v{$c}; + $seen{$c}++; + } + } +} my $escape_symbols = qr { ([\x01-\x08\x0e-\x1f\x21-\x29\x2b-\x2d\x3a-\x40\x7b-\xfe]) }x; sub parse_existing_sysfs { @@ -568,19 +635,50 @@ sub parse_existing_sysfs { return if (defined($data{$file})); return if (defined($data{$abs_file})); - push @files, $abs_file; + push @files, graph_add_file($abs_file, "file"); +} + +sub get_leave($) +{ + my $what = shift; + my $leave; + + my $l = $what; + my $stop = 1; + + $leave = $l; + $leave =~ s,/$,,; + $leave =~ s,.*/,,; + $leave =~ s/[\(\)]//g; + + # $leave is used to improve search performance at + # check_undefined_symbols, as the algorithm there can seek + # for a small number of "what". It also allows giving a + # hint about a leave with the same name somewhere else. + # However, there are a few occurences where the leave is + # either a wildcard or a number. Just group such cases + # altogether. + if ($leave =~ m/^\.\*/ || $leave eq "" || $leave =~ /^\d+$/) { + $leave = "others"; + } + + return $leave; } sub check_undefined_symbols { - foreach my $file (sort @files) { + foreach my $file_ref (sort @files) { + my @names = @{$$file_ref{"__name"}}; + my $file = $names[0]; my $defined = 0; my $exact = 0; - my $whats = ""; my $found_string; - my $leave = $file; - $leave =~ s,.*/,,; + my $leave = get_leave($file); + if (!defined($leaf{$leave})) { + $leave = "others"; + } + my $what = $leaf{$leave}; my $path = $file; $path =~ s,(.*/).*,$1,; @@ -590,41 +688,12 @@ sub check_undefined_symbols { $found_string = 1; } - if ($leave =~ /^\d+$/ || !defined($leaf{$leave})) { - $leave = "others"; - } - - print "--> $file\n" if ($found_string && $hint); - my $what = $leaf{$leave}; - $whats .= " $what" if (!($whats =~ m/$what/)); - - foreach my $w (split / /, $what) { - if ($file =~ m#^$w$#) { - $exact = 1; - last; - } - } - # Check for aliases - # - # TODO: this algorithm is O(w * n²). It can be - # improved in the future in order to handle it - # faster, by changing parse_existing_sysfs to - # store the sysfs inside a tree, at the expense - # on making the code less readable and/or using some - # additional perl library. - foreach my $a (keys %aliases) { - my $new = $aliases{$a}; - my $len = length($new); - - if (substr($file, 0, $len) eq $new) { - my $newf = $a . substr($file, $len); - - print " $newf\n" if ($found_string && $hint); - foreach my $w (split / /, $what) { - if ($newf =~ m#^$w$#) { - $exact = 1; - last; - } + foreach my $a (@names) { + print "--> $a\n" if ($found_string && $hint); + foreach my $w (split /\xac/, $what) { + if ($a =~ m#^$w$#) { + $exact = 1; + last; } } } @@ -641,8 +710,13 @@ sub check_undefined_symbols { # is not easily parseable. next if ($file =~ m#/parameters/#); - if ($hint && $defined && $leave ne "others") { - print "$leave at $path might be one of:$whats\n" if (!$search_string || $found_string); + if ($hint && $defined && (!$search_string || $found_string)) { + $what =~ s/\xac/\n\t/g; + if ($leave ne "others") { + print " more likely regexes:\n\t$what\n"; + } else { + print " tested regexes:\n\t$what\n"; + } next; } print "$file not found.\n" if (!$search_string || $found_string); @@ -656,8 +730,10 @@ sub undefined_symbols { no_chdir => 1 }, $sysfs_prefix); + $leaf{"others"} = ""; + foreach my $w (sort keys %data) { - foreach my $what (split /\xac /,$w) { + foreach my $what (split /\xac/,$w) { next if (!($what =~ m/^$sysfs_prefix/)); # Convert what into regular expressions @@ -700,19 +776,7 @@ sub undefined_symbols { # (this happens on a few IIO definitions) $what =~ s,\s*\=.*$,,; - my $leave = $what; - $leave =~ s,.*/,,; - - # $leave is used to improve search performance at - # check_undefined_symbols, as the algorithm there can seek - # for a small number of "what". It also allows giving a - # hint about a leave with the same name somewhere else. - # However, there are a few occurences where the leave is - # either a wildcard or a number. Just group such cases - # altogether. - if ($leave =~ m/^\.\*/ || $leave eq "" || $leave =~ /^\d+$/) { - $leave = "others" ; - } + my $leave = get_leave($what); # Escape all other symbols $what =~ s/$escape_symbols/\\$1/g; @@ -722,17 +786,14 @@ sub undefined_symbols { $what =~ s/\xff/\\d+/g; - # Special case: IIO ABI which a parenthesis. $what =~ s/sqrt(.*)/sqrt\(.*\)/; - $leave =~ s/[\(\)]//g; - my $added = 0; foreach my $l (split /\|/, $leave) { if (defined($leaf{$l})) { - next if ($leaf{$l} =~ m/$what/); - $leaf{$l} .= " " . $what; + next if ($leaf{$l} =~ m/\b$what\b/); + $leaf{$l} .= "\xac" . $what; $added = 1; } else { $leaf{$l} = $what; @@ -745,6 +806,11 @@ sub undefined_symbols { } } + # Take links into account + foreach my $link (keys %aliases) { + my $abs_file = $aliases{$link}; + graph_add_link($abs_file, $link); + } check_undefined_symbols; } -- cgit v1.2.3 From 9ae54ce551e9661e7dfd7b8b3d32913162208f40 Mon Sep 17 00:00:00 2001 From: Rob Herring Date: Mon, 13 Sep 2021 14:28:16 -0500 Subject: kbuild: Enable dtc 'unit_address_format' warning by default With all the 'unit_address_format' warnings fixed, enable the warning by default. Cc: Michal Marek Cc: Nick Desaulniers Cc: linux-kbuild@vger.kernel.org Acked-by: Masahiro Yamada Signed-off-by: Rob Herring Acked-by: Nick Desaulniers Link: https://lore.kernel.org/r/20210913192816.1225025-9-robh@kernel.org --- scripts/Makefile.lib | 1 - 1 file changed, 1 deletion(-) (limited to 'scripts') diff --git a/scripts/Makefile.lib b/scripts/Makefile.lib index 54582673fc1a..56d50eb0cd80 100644 --- a/scripts/Makefile.lib +++ b/scripts/Makefile.lib @@ -310,7 +310,6 @@ DTC_FLAGS += -Wno-interrupt_provider # Disable noisy checks by default ifeq ($(findstring 1,$(KBUILD_EXTRA_WARN)),) DTC_FLAGS += -Wno-unit_address_vs_reg \ - -Wno-unit_address_format \ -Wno-avoid_unnecessary_addr_size \ -Wno-alias_paths \ -Wno-graph_child_address \ -- cgit v1.2.3 From 8f0c32c788fffa8e88f995372415864039347c8a Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Tue, 31 Aug 2021 16:39:52 +0900 Subject: kbuild: move objtool_args back to scripts/Makefile.build Commit b1a1a1a09b46 ("kbuild: lto: postpone objtool") moved objtool_args to Makefile.lib, so the arguments can be used in Makefile.modfinal as well as Makefile.build. With commit 850ded46c642 ("kbuild: Fix TRIM_UNUSED_KSYMS with LTO_CLANG"), module LTO linking came back to scripts/Makefile.build again. So, there is no more reason to keep objtool_args in a separate file. Get it back to the original place, close to the objtool command. Remove the stale comment too. Signed-off-by: Masahiro Yamada Reviewed-by: Kees Cook Acked-by: Josh Poimboeuf --- scripts/Makefile.build | 10 ++++++++++ scripts/Makefile.lib | 11 ----------- 2 files changed, 10 insertions(+), 11 deletions(-) (limited to 'scripts') diff --git a/scripts/Makefile.build b/scripts/Makefile.build index 3efc984d4c69..17508c0e4358 100644 --- a/scripts/Makefile.build +++ b/scripts/Makefile.build @@ -224,6 +224,16 @@ cmd_record_mcount = $(if $(findstring $(strip $(CC_FLAGS_FTRACE)),$(_c_flags)), endif # CONFIG_FTRACE_MCOUNT_USE_RECORDMCOUNT ifdef CONFIG_STACK_VALIDATION + +objtool_args = \ + $(if $(CONFIG_UNWINDER_ORC),orc generate,check) \ + $(if $(part-of-module), --module) \ + $(if $(CONFIG_FRAME_POINTER),, --no-fp) \ + $(if $(CONFIG_GCOV_KERNEL)$(CONFIG_LTO_CLANG), --no-unreachable)\ + $(if $(CONFIG_RETPOLINE), --retpoline) \ + $(if $(CONFIG_X86_SMAP), --uaccess) \ + $(if $(CONFIG_FTRACE_MCOUNT_USE_OBJTOOL), --mcount) + ifndef CONFIG_LTO_CLANG __objtool_obj := $(objtree)/tools/objtool/objtool diff --git a/scripts/Makefile.lib b/scripts/Makefile.lib index 54582673fc1a..0a8a4689c3eb 100644 --- a/scripts/Makefile.lib +++ b/scripts/Makefile.lib @@ -232,17 +232,6 @@ ifeq ($(CONFIG_LTO_CLANG),y) mod-prelink-ext := .lto endif -# Objtool arguments are also needed for modfinal with LTO, so we define -# then here to avoid duplication. -objtool_args = \ - $(if $(CONFIG_UNWINDER_ORC),orc generate,check) \ - $(if $(part-of-module), --module) \ - $(if $(CONFIG_FRAME_POINTER),, --no-fp) \ - $(if $(CONFIG_GCOV_KERNEL)$(CONFIG_LTO_CLANG), --no-unreachable)\ - $(if $(CONFIG_RETPOLINE), --retpoline) \ - $(if $(CONFIG_X86_SMAP), --uaccess) \ - $(if $(CONFIG_FTRACE_MCOUNT_USE_OBJTOOL), --mcount) - # Useful for describing the dependency of composite objects # Usage: # $(call multi_depend, multi_used_targets, suffix_to_remove, suffix_to_add) -- cgit v1.2.3 From 5c4859e77aa11f9a8d9533962389893d199df70e Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Tue, 31 Aug 2021 16:39:53 +0900 Subject: kbuild: rename __objtool_obj and reuse it for cmd_cc_lto_link_modules Rename __objtool_obj to objtool, and move it out of the 'ifndef CONFIG_LTO_CLANG' conditional, so it can be used for cmd_cc_lto_link_modules as well. Signed-off-by: Masahiro Yamada Reviewed-by: Nick Desaulniers Reviewed-by: Kees Cook Acked-by: Josh Poimboeuf --- scripts/Makefile.build | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) (limited to 'scripts') diff --git a/scripts/Makefile.build b/scripts/Makefile.build index 17508c0e4358..e78096cd396b 100644 --- a/scripts/Makefile.build +++ b/scripts/Makefile.build @@ -225,6 +225,8 @@ endif # CONFIG_FTRACE_MCOUNT_USE_RECORDMCOUNT ifdef CONFIG_STACK_VALIDATION +objtool := $(objtree)/tools/objtool/objtool + objtool_args = \ $(if $(CONFIG_UNWINDER_ORC),orc generate,check) \ $(if $(part-of-module), --module) \ @@ -236,17 +238,15 @@ objtool_args = \ ifndef CONFIG_LTO_CLANG -__objtool_obj := $(objtree)/tools/objtool/objtool - # 'OBJECT_FILES_NON_STANDARD := y': skip objtool checking for a directory # 'OBJECT_FILES_NON_STANDARD_foo.o := 'y': skip objtool checking for a file # 'OBJECT_FILES_NON_STANDARD_foo.o := 'n': override directory skip for a file cmd_objtool = $(if $(patsubst y%,, \ $(OBJECT_FILES_NON_STANDARD_$(basetarget).o)$(OBJECT_FILES_NON_STANDARD)n), \ - $(__objtool_obj) $(objtool_args) $@) + $(objtool) $(objtool_args) $@) objtool_obj = $(if $(patsubst y%,, \ $(OBJECT_FILES_NON_STANDARD_$(basetarget).o)$(OBJECT_FILES_NON_STANDARD)n), \ - $(__objtool_obj)) + $(objtool)) endif # CONFIG_LTO_CLANG endif # CONFIG_STACK_VALIDATION @@ -300,8 +300,7 @@ cmd_cc_lto_link_modules = \ ifdef CONFIG_STACK_VALIDATION # objtool was skipped for LLVM bitcode, run it now that we have compiled # modules into native code -cmd_cc_lto_link_modules += ; \ - $(objtree)/tools/objtool/objtool $(objtool_args) --module $@ +cmd_cc_lto_link_modules += ; $(objtool) $(objtool_args) --module $@ endif $(obj)/%.lto.o: $(obj)/%.o FORCE -- cgit v1.2.3 From 92594d569b6d377168fa74c6bb27c5696af02a9d Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Tue, 31 Aug 2021 16:39:54 +0900 Subject: kbuild: store the objtool command in *.cmd files objtool_dep includes include/config/{ORC_UNWINDER,STACK_VALIDATION} so that all the objects are rebuilt when CONFIG_ORC_UNWINDER or CONFIG_STACK_VALIDATION is toggled. BTW, the correct option name is not CONFIG_ORC_UNWINDER, but CONFIG_UNWINDER_ORC. Commit 11af847446ed ("x86/unwind: Rename unwinder config options to 'CONFIG_UNWINDER_*'") missed to adjust this part. So, this dependency has been broken for a long time. As you can see in 'objtool_args', there are more CONFIG options that affect the objtool command line. Adding more and more include/config/* is ugly and unmaintainable. Another issue is that non-standard objects are needlessly rebuilt. Objects specified as OBJECT_FILES_NON_STANDARD is not processed by objtool, but they are rebuilt anyway when CONFIG_STACK_VALIDATION is toggled. This is not a big deal, but better to fix. A cleaner and more precise fix is to include the objtool command in *.cmd files so any command change is naturally detected by if_change. Signed-off-by: Masahiro Yamada Reviewed-by: Nick Desaulniers Reviewed-by: Kees Cook Acked-by: Josh Poimboeuf --- scripts/Makefile.build | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) (limited to 'scripts') diff --git a/scripts/Makefile.build b/scripts/Makefile.build index e78096cd396b..021ae0146913 100644 --- a/scripts/Makefile.build +++ b/scripts/Makefile.build @@ -155,7 +155,7 @@ $(obj)/%.ll: $(src)/%.c FORCE # (See cmd_cc_o_c + relevant part of rule_cc_o_c) quiet_cmd_cc_o_c = CC $(quiet_modtag) $@ - cmd_cc_o_c = $(CC) $(c_flags) -c -o $@ $< + cmd_cc_o_c = $(CC) $(c_flags) -c -o $@ $< $(cmd_objtool) ifdef CONFIG_MODVERSIONS # When module versioning is enabled the following steps are executed: @@ -243,7 +243,7 @@ ifndef CONFIG_LTO_CLANG # 'OBJECT_FILES_NON_STANDARD_foo.o := 'n': override directory skip for a file cmd_objtool = $(if $(patsubst y%,, \ $(OBJECT_FILES_NON_STANDARD_$(basetarget).o)$(OBJECT_FILES_NON_STANDARD)n), \ - $(objtool) $(objtool_args) $@) + ; $(objtool) $(objtool_args) $@) objtool_obj = $(if $(patsubst y%,, \ $(OBJECT_FILES_NON_STANDARD_$(basetarget).o)$(OBJECT_FILES_NON_STANDARD)n), \ $(objtool)) @@ -251,10 +251,8 @@ objtool_obj = $(if $(patsubst y%,, \ endif # CONFIG_LTO_CLANG endif # CONFIG_STACK_VALIDATION -# Rebuild all objects when objtool changes, or is enabled/disabled. -objtool_dep = $(objtool_obj) \ - $(wildcard include/config/ORC_UNWINDER \ - include/config/STACK_VALIDATION) +# Rebuild all objects when objtool changes +objtool_dep = $(objtool_obj) ifdef CONFIG_TRIM_UNUSED_KSYMS cmd_gen_ksymdeps = \ @@ -269,7 +267,6 @@ define rule_cc_o_c $(call cmd,gen_ksymdeps) $(call cmd,checksrc) $(call cmd,checkdoc) - $(call cmd,objtool) $(call cmd,modversions_c) $(call cmd,record_mcount) endef @@ -277,7 +274,6 @@ endef define rule_as_o_S $(call cmd_and_fixdep,as_o_S) $(call cmd,gen_ksymdeps) - $(call cmd,objtool) $(call cmd,modversions_S) endef @@ -365,7 +361,7 @@ $(obj)/%.s: $(src)/%.S FORCE $(call if_changed_dep,cpp_s_S) quiet_cmd_as_o_S = AS $(quiet_modtag) $@ - cmd_as_o_S = $(CC) $(a_flags) -c -o $@ $< + cmd_as_o_S = $(CC) $(a_flags) -c -o $@ $< $(cmd_objtool) ifdef CONFIG_ASM_MODVERSIONS -- cgit v1.2.3 From 918a6b7f68468ab80ec5e7ab7f3d2ef88905c20b Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Tue, 31 Aug 2021 16:39:55 +0900 Subject: kbuild: factor out OBJECT_FILES_NON_STANDARD check into a macro The OBJECT_FILES_NON_STANDARD check is quite long. Factor it out into a new macro, objtool-enabled, to not repeat it. Signed-off-by: Masahiro Yamada Reviewed-by: Nick Desaulniers Reviewed-by: Kees Cook Acked-by: Josh Poimboeuf --- scripts/Makefile.build | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'scripts') diff --git a/scripts/Makefile.build b/scripts/Makefile.build index 021ae0146913..720a86642f48 100644 --- a/scripts/Makefile.build +++ b/scripts/Makefile.build @@ -241,12 +241,12 @@ ifndef CONFIG_LTO_CLANG # 'OBJECT_FILES_NON_STANDARD := y': skip objtool checking for a directory # 'OBJECT_FILES_NON_STANDARD_foo.o := 'y': skip objtool checking for a file # 'OBJECT_FILES_NON_STANDARD_foo.o := 'n': override directory skip for a file -cmd_objtool = $(if $(patsubst y%,, \ - $(OBJECT_FILES_NON_STANDARD_$(basetarget).o)$(OBJECT_FILES_NON_STANDARD)n), \ - ; $(objtool) $(objtool_args) $@) -objtool_obj = $(if $(patsubst y%,, \ - $(OBJECT_FILES_NON_STANDARD_$(basetarget).o)$(OBJECT_FILES_NON_STANDARD)n), \ - $(objtool)) + +objtool-enabled = $(if $(filter-out y%, \ + $(OBJECT_FILES_NON_STANDARD_$(basetarget).o)$(OBJECT_FILES_NON_STANDARD)n),y) + +cmd_objtool = $(if $(objtool-enabled), ; $(objtool) $(objtool_args) $@) +objtool_obj = $(if $(objtool-enabled), $(objtool)) endif # CONFIG_LTO_CLANG endif # CONFIG_STACK_VALIDATION -- cgit v1.2.3 From ef62588c2c8611c196b780561610921b7b864bb2 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Tue, 31 Aug 2021 16:39:56 +0900 Subject: kbuild: detect objtool update without using .SECONDEXPANSION Redo commit 8852c5524029 ("kbuild: Fix objtool dependency for 'OBJECT_FILES_NON_STANDARD_ := n'") to add the objtool dependency in a cleaner way. Using .SECONDEXPANSION ends up with unreadable code due to escaped dollars. Also, it is not efficient because the second half of Makefile.build is parsed twice every time. Append the objtool dependency to the *.cmd files at the build time. This is what fixdep and gen_ksymdeps.sh already do. So, following the same pattern seems a natural solution. This allows us to drop $$(objtool_dep) entirely. Signed-off-by: Masahiro Yamada Reviewed-by: Kees Cook Reviewed-by: Nick Desaulniers Acked-by: Josh Poimboeuf --- scripts/Makefile.build | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) (limited to 'scripts') diff --git a/scripts/Makefile.build b/scripts/Makefile.build index 720a86642f48..21b55f37a23f 100644 --- a/scripts/Makefile.build +++ b/scripts/Makefile.build @@ -246,14 +246,11 @@ objtool-enabled = $(if $(filter-out y%, \ $(OBJECT_FILES_NON_STANDARD_$(basetarget).o)$(OBJECT_FILES_NON_STANDARD)n),y) cmd_objtool = $(if $(objtool-enabled), ; $(objtool) $(objtool_args) $@) -objtool_obj = $(if $(objtool-enabled), $(objtool)) +cmd_gen_objtooldep = $(if $(objtool-enabled), { echo ; echo '$@: $$(wildcard $(objtool))' ; } >> $(dot-target).cmd) endif # CONFIG_LTO_CLANG endif # CONFIG_STACK_VALIDATION -# Rebuild all objects when objtool changes -objtool_dep = $(objtool_obj) - ifdef CONFIG_TRIM_UNUSED_KSYMS cmd_gen_ksymdeps = \ $(CONFIG_SHELL) $(srctree)/scripts/gen_ksymdeps.sh $@ >> $(dot-target).cmd @@ -267,6 +264,7 @@ define rule_cc_o_c $(call cmd,gen_ksymdeps) $(call cmd,checksrc) $(call cmd,checkdoc) + $(call cmd,gen_objtooldep) $(call cmd,modversions_c) $(call cmd,record_mcount) endef @@ -274,12 +272,12 @@ endef define rule_as_o_S $(call cmd_and_fixdep,as_o_S) $(call cmd,gen_ksymdeps) + $(call cmd,gen_objtooldep) $(call cmd,modversions_S) endef # Built-in and composite module parts -.SECONDEXPANSION: -$(obj)/%.o: $(src)/%.c $(recordmcount_source) $$(objtool_dep) FORCE +$(obj)/%.o: $(src)/%.c $(recordmcount_source) FORCE $(call if_changed_rule,cc_o_c) $(call cmd,force_checksrc) @@ -380,7 +378,7 @@ cmd_modversions_S = \ fi endif -$(obj)/%.o: $(src)/%.S $$(objtool_dep) FORCE +$(obj)/%.o: $(src)/%.S FORCE $(call if_changed_rule,as_o_S) targets += $(filter-out $(subdir-builtin), $(real-obj-y)) -- cgit v1.2.3 From 90a353491e9f95516fcfd33ae7331d638557416c Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Tue, 31 Aug 2021 16:39:57 +0900 Subject: kbuild: reuse $(cmd_objtool) for cmd_cc_lto_link_modules For CONFIG_LTO_CLANG=y, the objtool processing is not possible at the compilation, hence postponed by the link time. Reuse $(cmd_objtool) for CONFIG_LTO_CLANG=y by defining objtool-enabled properly. For CONFIG_LTO_CLANG=y: objtool-enabled is off for %.o compilation objtool-enabled is on for %.lto link For CONFIG_LTO_CLANG=n: objtool-enabled is on for %.o compilation (but, it depends on OBJECT_FILE_NON_STANDARD) Set part-of-module := y for %.lto.o to avoid repeating --module. Signed-off-by: Masahiro Yamada Reviewed-by: Kees Cook Acked-by: Josh Poimboeuf --- scripts/Makefile.build | 28 +++++++++++++++++----------- 1 file changed, 17 insertions(+), 11 deletions(-) (limited to 'scripts') diff --git a/scripts/Makefile.build b/scripts/Makefile.build index 21b55f37a23f..78656b527fe5 100644 --- a/scripts/Makefile.build +++ b/scripts/Makefile.build @@ -236,20 +236,26 @@ objtool_args = \ $(if $(CONFIG_X86_SMAP), --uaccess) \ $(if $(CONFIG_FTRACE_MCOUNT_USE_OBJTOOL), --mcount) -ifndef CONFIG_LTO_CLANG +cmd_objtool = $(if $(objtool-enabled), ; $(objtool) $(objtool_args) $@) +cmd_gen_objtooldep = $(if $(objtool-enabled), { echo ; echo '$@: $$(wildcard $(objtool))' ; } >> $(dot-target).cmd) + +endif # CONFIG_STACK_VALIDATION + +ifdef CONFIG_LTO_CLANG + +# Skip objtool for LLVM bitcode +$(obj)/%.o: objtool-enabled := + +else # 'OBJECT_FILES_NON_STANDARD := y': skip objtool checking for a directory # 'OBJECT_FILES_NON_STANDARD_foo.o := 'y': skip objtool checking for a file # 'OBJECT_FILES_NON_STANDARD_foo.o := 'n': override directory skip for a file -objtool-enabled = $(if $(filter-out y%, \ +$(obj)/%.o: objtool-enabled = $(if $(filter-out y%, \ $(OBJECT_FILES_NON_STANDARD_$(basetarget).o)$(OBJECT_FILES_NON_STANDARD)n),y) -cmd_objtool = $(if $(objtool-enabled), ; $(objtool) $(objtool_args) $@) -cmd_gen_objtooldep = $(if $(objtool-enabled), { echo ; echo '$@: $$(wildcard $(objtool))' ; } >> $(dot-target).cmd) - -endif # CONFIG_LTO_CLANG -endif # CONFIG_STACK_VALIDATION +endif ifdef CONFIG_TRIM_UNUSED_KSYMS cmd_gen_ksymdeps = \ @@ -289,13 +295,13 @@ cmd_cc_lto_link_modules = \ $(LD) $(ld_flags) -r -o $@ \ $(shell [ -s $(@:.lto.o=.o.symversions) ] && \ echo -T $(@:.lto.o=.o.symversions)) \ - --whole-archive $(filter-out FORCE,$^) + --whole-archive $(filter-out FORCE,$^) \ + $(cmd_objtool) -ifdef CONFIG_STACK_VALIDATION # objtool was skipped for LLVM bitcode, run it now that we have compiled # modules into native code -cmd_cc_lto_link_modules += ; $(objtool) $(objtool_args) --module $@ -endif +$(obj)/%.lto.o: objtool-enabled = y +$(obj)/%.lto.o: part-of-module := y $(obj)/%.lto.o: $(obj)/%.o FORCE $(call if_changed,cc_lto_link_modules) -- cgit v1.2.3 From e27c42a52e374b8bad02797ddb32a35348c7e00b Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Thu, 23 Sep 2021 17:41:12 +0200 Subject: scripts: get_abi.pl: Fix get_abi.pl search output Currently, the get_abi.pl will print an invalid symbol (\xac character). Fix it. Fixes: ab9c14805b37 ("scripts: get_abi.pl: Better handle multiple What parameters") Signed-off-by: Mauro Carvalho Chehab Link: https://lore.kernel.org/r/fb27ac372e38f5ae9d088f9f4e9710c659e0b9e8.1632411447.git.mchehab+huawei@kernel.org Signed-off-by: Greg Kroah-Hartman --- scripts/get_abi.pl | 1 + 1 file changed, 1 insertion(+) (limited to 'scripts') diff --git a/scripts/get_abi.pl b/scripts/get_abi.pl index c52a1cf0f49d..65261f464e25 100755 --- a/scripts/get_abi.pl +++ b/scripts/get_abi.pl @@ -501,6 +501,7 @@ sub search_symbols { my $file = $data{$what}->{filepath}; + $what =~ s/\xac/, /g; my $bar = $what; $bar =~ s/./-/g; -- cgit v1.2.3 From 45495db9790fd9247f31a79c433e1723a1bdf039 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Thu, 23 Sep 2021 17:41:13 +0200 Subject: scripts: get_abi.pl: call get_leave() a little late The $what conversions need to replace some characters to avoid breaking regex expressions found on some What:. only after replacing them back, the script should get the $leave devnode. Fixes: ca8e055c2215 ("scripts: get_abi.pl: add a graph to speedup the undefined algorithm") Signed-off-by: Mauro Carvalho Chehab Link: https://lore.kernel.org/r/a21631f8a884f50a962beafdd800f27891348d95.1632411447.git.mchehab+huawei@kernel.org Signed-off-by: Greg Kroah-Hartman --- scripts/get_abi.pl | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'scripts') diff --git a/scripts/get_abi.pl b/scripts/get_abi.pl index 65261f464e25..9eb8a033d363 100755 --- a/scripts/get_abi.pl +++ b/scripts/get_abi.pl @@ -777,8 +777,6 @@ sub undefined_symbols { # (this happens on a few IIO definitions) $what =~ s,\s*\=.*$,,; - my $leave = get_leave($what); - # Escape all other symbols $what =~ s/$escape_symbols/\\$1/g; $what =~ s/\\\\/\\/g; @@ -790,6 +788,7 @@ sub undefined_symbols { # Special case: IIO ABI which a parenthesis. $what =~ s/sqrt(.*)/sqrt\(.*\)/; + my $leave = get_leave($what); my $added = 0; foreach my $l (split /\|/, $leave) { if (defined($leaf{$l})) { -- cgit v1.2.3 From 46f661fd0faf7f518b6760ac15f02fa36896c126 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Thu, 23 Sep 2021 17:41:14 +0200 Subject: scripts: get_abi.pl: improve debug logic Add a level for debug, in order to allow it to be extended to debug other parts of the script. Signed-off-by: Mauro Carvalho Chehab Link: https://lore.kernel.org/r/0203416c6c418abb4fc20577a5f48d0d2a41bae7.1632411447.git.mchehab+huawei@kernel.org Signed-off-by: Greg Kroah-Hartman --- scripts/get_abi.pl | 28 +++++++++++++++++++--------- 1 file changed, 19 insertions(+), 9 deletions(-) (limited to 'scripts') diff --git a/scripts/get_abi.pl b/scripts/get_abi.pl index 9eb8a033d363..bb80303fea22 100755 --- a/scripts/get_abi.pl +++ b/scripts/get_abi.pl @@ -9,6 +9,7 @@ use Getopt::Long; use File::Find; use Fcntl ':mode'; use Cwd 'abs_path'; +use Data::Dumper; my $help = 0; my $hint = 0; @@ -20,13 +21,18 @@ my $prefix="Documentation/ABI"; my $sysfs_prefix="/sys"; my $search_string; +# Debug options +my $dbg_what_parsing = 1; +my $dbg_what_open = 2; +my $dbg_dump_abi_structs = 4; + # # If true, assumes that the description is formatted with ReST # my $description_is_rst = 1; GetOptions( - "debug|d+" => \$debug, + "debug=i" => \$debug, "enable-lineno" => \$enable_lineno, "rst-source!" => \$description_is_rst, "dir=s" => \$prefix, @@ -46,7 +52,7 @@ my ($cmd, $arg) = @ARGV; pod2usage(2) if ($cmd ne "search" && $cmd ne "rest" && $cmd ne "validate" && $cmd ne "undefined"); pod2usage(2) if ($cmd eq "search" && !$arg); -require Data::Dumper if ($debug); +require Data::Dumper if ($debug & $dbg_dump_abi_structs); my %data; my %symbols; @@ -106,7 +112,7 @@ sub parse_abi { my @labels; my $label = ""; - print STDERR "Opening $file\n" if ($debug > 1); + print STDERR "Opening $file\n" if ($debug & $dbg_what_open); open IN, $file; while() { $ln++; @@ -178,7 +184,7 @@ sub parse_abi { $data{$what}->{filepath} .= " " . $file; } } - print STDERR "\twhat: $what\n" if ($debug > 1); + print STDERR "\twhat: $what\n" if ($debug & $dbg_what_parsing); $data{$what}->{line_no} = $ln; } else { $data{$what}->{line_no} = $ln if (!defined($data{$what}->{line_no})); @@ -827,7 +833,7 @@ if ($cmd eq "undefined" || $cmd eq "search") { # find({wanted =>\&parse_abi, no_chdir => 1}, $prefix); -print STDERR Data::Dumper->Dump([\%data], [qw(*data)]) if ($debug); +print STDERR Data::Dumper->Dump([\%data], [qw(*data)]) if ($debug & $dbg_dump_abi_structs); # # Handles the command @@ -860,7 +866,7 @@ abi_book.pl - parse the Linux ABI files and produce a ReST book. =head1 SYNOPSIS -B [--debug] [--enable-lineno] [--man] [--help] +B [--debug ] [--enable-lineno] [--man] [--help] [--(no-)rst-source] [--dir=] [--show-hints] [--search-string ] [] @@ -900,10 +906,14 @@ logic (--no-rst-source). Enable output of #define LINENO lines. -=item B<--debug> +=item B<--debug> I + +Print debug information according with the level, which is given by the +following bitmask: -Put the script in verbose mode, useful for debugging. Can be called multiple -times, to increase verbosity. + - 1: Debug parsing What entries from ABI files; + - 2: Shows what files are opened from ABI files; + - 4: Dump the structs used to store the contents of the ABI files. =item B<--show-hints> -- cgit v1.2.3 From 9263589422fe176d377b912145e64ee02bf5c813 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Thu, 23 Sep 2021 17:41:15 +0200 Subject: scripts: get_abi.pl: Better handle leaves with wildcards When the the leaf of a regex ends with a wildcard, the speedup algorithm to reduce the number of regexes to seek won't work. So, when those are found, place at the "others" exception. That slows down the search from 0.14s to 1 minute on my machine, but the results are a lot more consistent. Signed-off-by: Mauro Carvalho Chehab Link: https://lore.kernel.org/r/60bb97cf337333783f9f52e114b896439e9cc215.1632411447.git.mchehab+huawei@kernel.org Signed-off-by: Greg Kroah-Hartman --- scripts/get_abi.pl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'scripts') diff --git a/scripts/get_abi.pl b/scripts/get_abi.pl index bb80303fea22..3c0063d0e05e 100755 --- a/scripts/get_abi.pl +++ b/scrip