diff options
Diffstat (limited to 'scripts')
-rw-r--r-- | scripts/Makefile | 1 | ||||
-rw-r--r-- | scripts/Makefile.kasan | 20 | ||||
-rw-r--r-- | scripts/Makefile.modfinal | 2 | ||||
-rwxr-xr-x | scripts/checkpatch.pl | 133 | ||||
-rwxr-xr-x | scripts/gcc-x86_32-has-stack-protector.sh | 6 | ||||
-rwxr-xr-x | scripts/get_abi.pl | 74 | ||||
-rwxr-xr-x | scripts/kernel-doc | 60 | ||||
-rw-r--r-- | scripts/module.lds.S | 19 | ||||
-rwxr-xr-x | scripts/spdxcheck.py | 2 | ||||
-rwxr-xr-x | scripts/sphinx-pre-install | 2 |
10 files changed, 258 insertions, 61 deletions
diff --git a/scripts/Makefile b/scripts/Makefile index c36106bce80e..9adb6d247818 100644 --- a/scripts/Makefile +++ b/scripts/Makefile @@ -14,6 +14,7 @@ hostprogs-always-$(CONFIG_ASN1) += asn1_compiler hostprogs-always-$(CONFIG_MODULE_SIG_FORMAT) += sign-file hostprogs-always-$(CONFIG_SYSTEM_TRUSTED_KEYRING) += extract-cert hostprogs-always-$(CONFIG_SYSTEM_EXTRA_CERTIFICATE) += insert-sys-cert +hostprogs-always-$(CONFIG_SYSTEM_REVOCATION_LIST) += extract-cert HOSTCFLAGS_sorttable.o = -I$(srctree)/tools/include HOSTCFLAGS_asn1_compiler.o = -I$(srctree)/include diff --git a/scripts/Makefile.kasan b/scripts/Makefile.kasan index 1e000cc2e7b4..3d791908ed36 100644 --- a/scripts/Makefile.kasan +++ b/scripts/Makefile.kasan @@ -2,6 +2,14 @@ CFLAGS_KASAN_NOSANITIZE := -fno-builtin KASAN_SHADOW_OFFSET ?= $(CONFIG_KASAN_SHADOW_OFFSET) +cc-param = $(call cc-option, -mllvm -$(1), $(call cc-option, --param $(1))) + +ifdef CONFIG_KASAN_STACK + stack_enable := 1 +else + stack_enable := 0 +endif + ifdef CONFIG_KASAN_GENERIC ifdef CONFIG_KASAN_INLINE @@ -12,8 +20,6 @@ endif CFLAGS_KASAN_MINIMAL := -fsanitize=kernel-address -cc-param = $(call cc-option, -mllvm -$(1), $(call cc-option, --param $(1))) - # -fasan-shadow-offset fails without -fsanitize CFLAGS_KASAN_SHADOW := $(call cc-option, -fsanitize=kernel-address \ -fasan-shadow-offset=$(KASAN_SHADOW_OFFSET), \ @@ -27,7 +33,7 @@ else CFLAGS_KASAN := $(CFLAGS_KASAN_SHADOW) \ $(call cc-param,asan-globals=1) \ $(call cc-param,asan-instrumentation-with-call-threshold=$(call_threshold)) \ - $(call cc-param,asan-stack=$(CONFIG_KASAN_STACK)) \ + $(call cc-param,asan-stack=$(stack_enable)) \ $(call cc-param,asan-instrument-allocas=1) endif @@ -36,14 +42,14 @@ endif # CONFIG_KASAN_GENERIC ifdef CONFIG_KASAN_SW_TAGS ifdef CONFIG_KASAN_INLINE - instrumentation_flags := -mllvm -hwasan-mapping-offset=$(KASAN_SHADOW_OFFSET) + instrumentation_flags := $(call cc-param,hwasan-mapping-offset=$(KASAN_SHADOW_OFFSET)) else - instrumentation_flags := -mllvm -hwasan-instrument-with-calls=1 + instrumentation_flags := $(call cc-param,hwasan-instrument-with-calls=1) endif CFLAGS_KASAN := -fsanitize=kernel-hwaddress \ - -mllvm -hwasan-instrument-stack=$(CONFIG_KASAN_STACK) \ - -mllvm -hwasan-use-short-granules=0 \ + $(call cc-param,hwasan-instrument-stack=$(stack_enable)) \ + $(call cc-param,hwasan-use-short-granules=0) \ $(instrumentation_flags) endif # CONFIG_KASAN_SW_TAGS diff --git a/scripts/Makefile.modfinal b/scripts/Makefile.modfinal index 735e11e9041b..dd87cea9fba7 100644 --- a/scripts/Makefile.modfinal +++ b/scripts/Makefile.modfinal @@ -23,7 +23,7 @@ modname = $(notdir $(@:.mod.o=)) part-of-module = y quiet_cmd_cc_o_c = CC [M] $@ - cmd_cc_o_c = $(CC) $(c_flags) -c -o $@ $< + cmd_cc_o_c = $(CC) $(filter-out $(CC_FLAGS_CFI), $(c_flags)) -c -o $@ $< %.mod.o: %.mod.c FORCE $(call if_changed_dep,cc_o_c) diff --git a/scripts/checkpatch.pl b/scripts/checkpatch.pl index 73f22fe2d60c..d67146d0b33c 100755 --- a/scripts/checkpatch.pl +++ b/scripts/checkpatch.pl @@ -23,6 +23,9 @@ my $V = '0.32'; use Getopt::Long qw(:config no_auto_abbrev); my $quiet = 0; +my $verbose = 0; +my %verbose_messages = (); +my %verbose_emitted = (); my $tree = 1; my $chk_signoff = 1; my $chk_patch = 1; @@ -61,6 +64,7 @@ my $spelling_file = "$D/spelling.txt"; my $codespell = 0; my $codespellfile = "/usr/share/codespell/dictionary.txt"; my $conststructsfile = "$D/const_structs.checkpatch"; +my $docsfile = "$D/../Documentation/dev-tools/checkpatch.rst"; my $typedefsfile; my $color = "auto"; my $allow_c99_comments = 1; # Can be overridden by --ignore C99_COMMENT_TOLERANCE @@ -78,6 +82,7 @@ Version: $V Options: -q, --quiet quiet + -v, --verbose verbose mode --no-tree run without a kernel tree --no-signoff do not check for 'Signed-off-by' line --patch treat FILE as patchfile (default) @@ -158,15 +163,51 @@ sub list_types { my $text = <$script>; close($script); - my @types = (); + my %types = (); # Also catch when type or level is passed through a variable - for ($text =~ /(?:(?:\bCHK|\bWARN|\bERROR|&\{\$msg_level})\s*\(|\$msg_type\s*=)\s*"([^"]+)"/g) { - push (@types, $_); + while ($text =~ /(?:(\bCHK|\bWARN|\bERROR|&\{\$msg_level})\s*\(|\$msg_type\s*=)\s*"([^"]+)"/g) { + if (defined($1)) { + if (exists($types{$2})) { + $types{$2} .= ",$1" if ($types{$2} ne $1); + } else { + $types{$2} = $1; + } + } else { + $types{$2} = "UNDETERMINED"; + } } - @types = sort(uniq(@types)); + print("#\tMessage type\n\n"); - foreach my $type (@types) { + if ($color) { + print(" ( Color coding: "); + print(RED . "ERROR" . RESET); + print(" | "); + print(YELLOW . "WARNING" . RESET); + print(" | "); + print(GREEN . "CHECK" . RESET); + print(" | "); + print("Multiple levels / Undetermined"); + print(" )\n\n"); + } + + foreach my $type (sort keys %types) { + my $orig_type = $type; + if ($color) { + my $level = $types{$type}; + if ($level eq "ERROR") { + $type = RED . $type . RESET; + } elsif ($level eq "WARN") { + $type = YELLOW . $type . RESET; + } elsif ($level eq "CHK") { + $type = GREEN . $type . RESET; + } + } print(++$count . "\t" . $type . "\n"); + if ($verbose && exists($verbose_messages{$orig_type})) { + my $message = $verbose_messages{$orig_type}; + $message =~ s/\n/\n\t/g; + print("\t" . $message . "\n\n"); + } } exit($exitcode); @@ -198,6 +239,46 @@ if (-f $conf) { unshift(@ARGV, @conf_args) if @conf_args; } +sub load_docs { + open(my $docs, '<', "$docsfile") + or warn "$P: Can't read the documentation file $docsfile $!\n"; + + my $type = ''; + my $desc = ''; + my $in_desc = 0; + + while (<$docs>) { + chomp; + my $line = $_; + $line =~ s/\s+$//; + + if ($line =~ /^\s*\*\*(.+)\*\*$/) { + if ($desc ne '') { + $verbose_messages{$type} = trim($desc); + } + $type = $1; + $desc = ''; + $in_desc = 1; + } elsif ($in_desc) { + if ($line =~ /^(?:\s{4,}|$)/) { + $line =~ s/^\s{4}//; + $desc .= $line; + $desc .= "\n"; + } else { + $verbose_messages{$type} = trim($desc); + $type = ''; + $desc = ''; + $in_desc = 0; + } + } + } + + if ($desc ne '') { + $verbose_messages{$type} = trim($desc); + } + close($docs); +} + # Perl's Getopt::Long allows options to take optional arguments after a space. # Prevent --color by itself from consuming other arguments foreach (@ARGV) { @@ -208,6 +289,7 @@ foreach (@ARGV) { GetOptions( 'q|quiet+' => \$quiet, + 'v|verbose!' => \$verbose, 'tree!' => \$tree, 'signoff!' => \$chk_signoff, 'patch!' => \$chk_patch, @@ -247,13 +329,27 @@ GetOptions( help(0) if ($help); +die "$P: --git cannot be used with --file or --fix\n" if ($git && ($file || $fix)); +die "$P: --verbose cannot be used with --terse\n" if ($verbose && $terse); + +if ($color =~ /^[01]$/) { + $color = !$color; +} elsif ($color =~ /^always$/i) { + $color = 1; +} elsif ($color =~ /^never$/i) { + $color = 0; +} elsif ($color =~ /^auto$/i) { + $color = (-t STDOUT); +} else { + die "$P: Invalid color mode: $color\n"; +} + +load_docs() if ($verbose); list_types(0) if ($list_types); $fix = 1 if ($fix_inplace); $check_orig = $check; -die "$P: --git cannot be used with --file or --fix\n" if ($git && ($file || $fix)); - my $exit = 0; my $perl_version_ok = 1; @@ -268,18 +364,6 @@ if ($#ARGV < 0) { push(@ARGV, '-'); } -if ($color =~ /^[01]$/) { - $color = !$color; -} elsif ($color =~ /^always$/i) { - $color = 1; -} elsif ($color =~ /^never$/i) { - $color = 0; -} elsif ($color =~ /^auto$/i) { - $color = (-t STDOUT); -} else { - die "$P: Invalid color mode: $color\n"; -} - # skip TAB size 1 to avoid additional checks on $tabsize - 1 die "$P: Invalid TAB size: $tabsize\n" if ($tabsize < 2); @@ -2209,7 +2293,16 @@ sub report { splice(@lines, 1, 1); $output = join("\n", @lines); } - $output = (split('\n', $output))[0] . "\n" if ($terse); + + if ($terse) { + $output = (split('\n', $output))[0] . "\n"; + } + + if ($verbose && exists($verbose_messages{$type}) && + !exists($verbose_emitted{$type})) { + $output .= $verbose_messages{$type} . "\n\n"; + $verbose_emitted{$type} = 1; + } push(our @report, $output); diff --git a/scripts/gcc-x86_32-has-stack-protector.sh b/scripts/gcc-x86_32-has-stack-protector.sh index f5c119495254..825c75c5b715 100755 --- a/scripts/gcc-x86_32-has-stack-protector.sh +++ b/scripts/gcc-x86_32-has-stack-protector.sh @@ -1,4 +1,8 @@ #!/bin/sh # SPDX-License-Identifier: GPL-2.0 -echo "int foo(void) { char X[200]; return 3; }" | $* -S -x c -c -m32 -O0 -fstack-protector - -o - 2> /dev/null | grep -q "%gs" +# This requires GCC 8.1 or better. Specifically, we require +# -mstack-protector-guard-reg, added by +# https://gcc.gnu.org/bugzilla/show_bug.cgi?id=81708 + +echo "int foo(void) { char X[200]; return 3; }" | $* -S -x c -c -m32 -O0 -fstack-protector -mstack-protector-guard-reg=fs -mstack-protector-guard-symbol=__stack_chk_guard - -o - 2> /dev/null | grep -q "%fs" diff --git a/scripts/get_abi.pl b/scripts/get_abi.pl index 92d9aa6cc4f5..d7aa82094296 100755 --- a/scripts/get_abi.pl +++ b/scripts/get_abi.pl @@ -281,8 +281,12 @@ sub create_labels { # Outputs the book on ReST format # -# \b doesn't work well with paths. So, we need to define something else -my $bondary = qr { (?<![\w\/\`\{])(?=[\w\/\`\{])|(?<=[\w\/\`\{])(?![\w\/\`\{]) }x; +# \b doesn't work well with paths. So, we need to define something else: +# Boundaries are punct characters, spaces and end-of-line +my $start = qr {(^|\s|\() }x; +my $bondary = qr { ([,.:;\)\s]|\z) }x; +my $xref_match = qr { $start(\/(sys|config|proc|dev|kvd)\/[^,.:;\)\s]+)$bondary }x; +my $symbols = qr { ([\x01-\x08\x0e-\x1f\x21-\x2f\x3a-\x40\x7b-\xff]) }x; sub output_rest { create_labels(); @@ -305,7 +309,6 @@ sub output_rest { } my $w = $what; - $w =~ s/([\(\)\_\-\*\=\^\~\\])/\\$1/g; if ($type ne "File") { my $cur_part = $what; @@ -329,6 +332,7 @@ sub output_rest { my $len = 0; foreach my $name (@names) { + $name =~ s/$symbols/\\$1/g; $name = "**$name**"; $len = length($name) if (length($name) > $len); } @@ -377,32 +381,60 @@ sub output_rest { # Enrich text by creating cross-references - $desc =~ s,Documentation/(?!devicetree)(\S+)\.rst,:doc:`/$1`,g; + my $new_desc = ""; + my $init_indent = -1; + my $literal_indent = -1; + + open(my $fh, "+<", \$desc); + while (my $d = <$fh>) { + my $indent = $d =~ m/^(\s+)/; + my $spaces = length($indent); + $init_indent = $indent if ($init_indent < 0); + if ($literal_indent >= 0) { + if ($spaces > $literal_indent) { + $new_desc .= $d; + next; + } else { + $literal_indent = -1; + } + } else { + if ($d =~ /()::$/ && !($d =~ /^\s*\.\./)) { + $literal_indent = $spaces; + } + } - my @matches = $desc =~ m,Documentation/ABI/([\w\/\-]+),; - foreach my $f (@matches) { - my $xref = $f; - my $path = $f; - $path =~ s,.*/(.*/.*),$1,;; - $path =~ s,[/\-],_,g;; - $xref .= " <abi_file_" . $path . ">"; - $desc =~ s,\bDocumentation/ABI/$f\b,:ref:`$xref`,g; - } + $d =~ s,Documentation/(?!devicetree)(\S+)\.rst,:doc:`/$1`,g; - @matches = $desc =~ m,$bondary(/sys/[^\s\.\,\;\:\*\s\`\'\(\)]+)$bondary,; + my @matches = $d =~ m,Documentation/ABI/([\w\/\-]+),g; + foreach my $f (@matches) { + my $xref = $f; + my $path = $f; + $path =~ s,.*/(.*/.*),$1,;; + $path =~ s,[/\-],_,g;; + $xref .= " <abi_file_" . $path . ">"; + $d =~ s,\bDocumentation/ABI/$f\b,:ref:`$xref`,g; + } + + # Seek for cross reference symbols like /sys/... + @matches = $d =~ m/$xref_match/g; - foreach my $s (@matches) { - if (defined($data{$s}) && defined($data{$s}->{label})) { - my $xref = $s; + foreach my $s (@matches) { + next if (!($s =~ m,/,)); + if (defined($data{$s}) && defined($data{$s}->{label})) { + my $xref = $s; - $xref =~ s/([\x00-\x1f\x21-\x2f\x3a-\x40\x7b-\xff])/\\$1/g; - $xref = ":ref:`$xref <" . $data{$s}->{label} . ">`"; + $xref =~ s/$symbols/\\$1/g; + $xref = ":ref:`$xref <" . $data{$s}->{label} . ">`"; - $desc =~ s,$bondary$s$bondary,$xref,g; + $d =~ s,$start$s$bondary,$1$xref$2,g; + } } + $new_desc .= $d; } + close $fh; + - print "$desc\n\n"; + print "$new_desc\n\n"; } else { $desc =~ s/^\s+//; diff --git a/scripts/kernel-doc b/scripts/kernel-doc index 8b5bc7bf4bb8..2a85d34fdcd0 100755 --- a/scripts/kernel-doc +++ b/scripts/kernel-doc @@ -391,8 +391,14 @@ my $doc_com = '\s*\*\s*'; my $doc_com_body = '\s*\* ?'; my $doc_decl = $doc_com . '(\w+)'; # @params and a strictly limited set of supported section names +# Specifically: +# Match @word: +# @...: +# @{section-name}: +# while trying to not match literal block starts like "example::" +# my $doc_sect = $doc_com . - '\s*(\@[.\w]+|\@\.\.\.|description|context|returns?|notes?|examples?)\s*:(.*)'; + '\s*(\@[.\w]+|\@\.\.\.|description|context|returns?|notes?|examples?)\s*:([^:].*)?$'; my $doc_content = $doc_com_body . '(.*)'; my $doc_block = $doc_com . 'DOC:\s*(.*)?'; my $doc_inline_start = '^\s*/\*\*\s*$'; @@ -1201,12 +1207,23 @@ sub dump_union($$) { sub dump_struct($$) { my $x = shift; my $file = shift; + my $decl_type; + my $members; + my $type = qr{struct|union}; + # For capturing struct/union definition body, i.e. "{members*}qualifiers*" + my $definition_body = qr{\{(.*)\}(?:\s*(?:__packed|__aligned|____cacheline_aligned_in_smp|____cacheline_aligned|__attribute__\s*\(\([a-z0-9,_\s\(\)]*\)\)))*}; - if ($x =~ /(struct|union)\s+(\w+)\s*\{(.*)\}(\s*(__packed|__aligned|____cacheline_aligned_in_smp|____cacheline_aligned|__attribute__\s*\(\([a-z0-9,_\s\(\)]*\)\)))*/) { - my $decl_type = $1; + if ($x =~ /($type)\s+(\w+)\s*$definition_body/) { + $decl_type = $1; $declaration_name = $2; - my $members = $3; + $members = $3; + } elsif ($x =~ /typedef\s+($type)\s*$definition_body\s*(\w+)\s*;/) { + $decl_type = $1; + $declaration_name = $3; + $members = $2; + } + if ($members) { if ($identifier ne $declaration_name) { print STDERR "${file}:$.: warning: expecting prototype for $decl_type $identifier. Prototype was for $decl_type $declaration_name instead\n"; return; @@ -1401,9 +1418,14 @@ sub dump_enum($$) { if ($members) { if ($identifier ne $declaration_name) { - print STDERR "${file}:$.: warning: expecting prototype for enum $identifier. Prototype was for enum $declaration_name instead\n"; + if ($identifier eq "") { + print STDERR "${file}:$.: warning: wrong kernel-doc identifier on line:\n"; + } else { + print STDERR "${file}:$.: warning: expecting prototype for enum $identifier. Prototype was for enum $declaration_name instead\n"; + } return; } + $declaration_name = "(anonymous)" if ($declaration_name eq ""); my %_members; @@ -1755,12 +1777,14 @@ sub dump_function($$) { $prototype =~ s/^noinline +//; $prototype =~ s/__init +//; $prototype =~ s/__init_or_module +//; + $prototype =~ s/__flatten +//; $prototype =~ s/__meminit +//; $prototype =~ s/__must_check +//; $prototype =~ s/__weak +//; $prototype =~ s/__sched +//; $prototype =~ s/__printf\s*\(\s*\d*\s*,\s*\d*\s*\) +//; my $define = $prototype =~ s/^#\s*define\s+//; #ak added + $prototype =~ s/__attribute_const__ +//; $prototype =~ s/__attribute__\s*\(\( (?: [\w\s]++ # attribute name @@ -2085,15 +2109,28 @@ sub process_name($$) { } } elsif (/$doc_decl/o) { $identifier = $1; - if (/\s*([\w\s]+?)(\(\))?\s*([-:].*)?$/) { + my $is_kernel_comment = 0; + my $decl_start = qr{\s*\*}; + # test for pointer declaration type, foo * bar() - desc + my $fn_type = qr{\w+\s*\*\s*}; + my $parenthesis = qr{\(\w*\)}; + my $decl_end = qr{[-:].*}; + if (/^$decl_start\s*([\w\s]+?)$parenthesis?\s*$decl_end?$/) { $identifier = $1; } if ($identifier =~ m/^(struct|union|enum|typedef)\b\s*(\S*)/) { $decl_type = $1; $identifier = $2; - } else { + $is_kernel_comment = 1; + } + # Look for foo() or static void foo() - description; or misspelt + # identifier + elsif (/^$decl_start\s*$fn_type?(\w+)\s*$parenthesis?\s*$decl_end?$/ || + /^$decl_start\s*$fn_type?(\w+.*)$parenthesis?\s*$decl_end$/) { + $identifier = $1; $decl_type = 'function'; $identifier =~ s/^define\s+//; + $is_kernel_comment = 1; } $identifier =~ s/\s+$//; @@ -2115,13 +2152,20 @@ sub process_name($$) { $declaration_purpose = ""; } + if (!$is_kernel_comment) { + print STDERR "${file}:$.: warning: This comment starts with '/**', but isn't a kernel-doc comment. Refer Documentation/doc-guide/kernel-doc.rst\n"; + print STDERR $_; + ++$warnings; + $state = STATE_NORMAL; + } + if (($declaration_purpose eq "") && $verbose) { print STDERR "${file}:$.: warning: missing initial short description on line:\n"; print STDERR $_; ++$warnings; } - if ($identifier eq "") { + if ($identifier eq "" && $decl_type ne "enum") { print STDERR "${file}:$.: warning: wrong kernel-doc identifier on line:\n"; print STDERR $_; ++$warnings; diff --git a/scripts/module.lds.S b/scripts/module.lds.S index 2c52535f9b56..04c5685c25cf 100644 --- a/scripts/module.lds.S +++ b/scripts/module.lds.S @@ -3,10 +3,20 @@ * Archs are free to supply their own linker scripts. ld will * combine them automatically. */ +#ifdef CONFIG_CFI_CLANG +# include <asm/page.h> +# define ALIGN_CFI ALIGN(PAGE_SIZE) +# define SANITIZER_DISCARDS *(.eh_frame) +#else +# define ALIGN_CFI +# define SANITIZER_DISCARDS +#endif + SECTIONS { /DISCARD/ : { *(.discard) *(.discard.*) + SANITIZER_DISCARDS } __ksymtab 0 : { *(SORT(___ksymtab+*)) } @@ -41,7 +51,14 @@ SECTIONS { *(.rodata..L*) } - .text : { *(.text .text.[0-9a-zA-Z_]*) } + /* + * With CONFIG_CFI_CLANG, we assume __cfi_check is at the beginning + * of the .text section, and is aligned to PAGE_SIZE. + */ + .text : ALIGN_CFI { + *(.text.__cfi_check) + *(.text .text.[0-9a-zA-Z_]* .text..L.cfi*) + } #endif } diff --git a/scripts/spdxcheck.py b/scripts/spdxcheck.py index cbdb5c83c08f..3e784cf9f401 100755 --- a/scripts/spdxcheck.py +++ b/scripts/spdxcheck.py @@ -243,7 +243,7 @@ if __name__ == '__main__': # Initialize SPDX data spdx = read_spdxdata(repo) - # Initilize the parser + # Initialize the parser parser = id_parser(spdx) except SPDXException as se: diff --git a/scripts/sphinx-pre-install b/scripts/sphinx-pre-install index b5f9fd5b2880..fe92020d67e3 100755 --- a/scripts/sphinx-pre-install +++ b/scripts/sphinx-pre-install @@ -259,7 +259,7 @@ sub get_sphinx_version($) open IN, "$cmd --version 2>&1 |"; while (<IN>) { - if (m/^\s*sphinx-build\s+([\d\.]+)(\+\/[\da-f]+)?$/) { + if (m/^\s*sphinx-build\s+([\d\.]+)((\+\/[\da-f]+)|(b\d+))?$/) { $ver=$1; last; } |