summaryrefslogtreecommitdiff
path: root/scripts
diff options
context:
space:
mode:
Diffstat (limited to 'scripts')
-rw-r--r--scripts/Makefile1
-rw-r--r--scripts/Makefile.kasan20
-rw-r--r--scripts/Makefile.lib34
-rw-r--r--scripts/Makefile.modfinal2
-rwxr-xr-xscripts/bpf_doc.py (renamed from scripts/bpf_helpers_doc.py)191
-rwxr-xr-xscripts/checkpatch.pl141
-rwxr-xr-xscripts/gcc-x86_32-has-stack-protector.sh6
-rwxr-xr-xscripts/get_abi.pl74
-rwxr-xr-xscripts/kernel-doc60
-rwxr-xr-xscripts/link-vmlinux.sh7
-rw-r--r--scripts/module.lds.S21
-rwxr-xr-xscripts/spdxcheck.py2
-rwxr-xr-xscripts/sphinx-pre-install2
13 files changed, 453 insertions, 108 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.lib b/scripts/Makefile.lib
index a4fbaf8880b9..64daf37e874b 100644
--- a/scripts/Makefile.lib
+++ b/scripts/Makefile.lib
@@ -73,14 +73,26 @@ always-y += $(userprogs-always-y) $(userprogs-always-m)
# DTB
# If CONFIG_OF_ALL_DTBS is enabled, all DT blobs are built
+dtb-$(CONFIG_OF_ALL_DTBS) += $(dtb-)
+
+# List all dtbs to be generated by fdtoverlay
+overlay-y := $(foreach m,$(dtb-y), $(if $(strip $($(m:.dtb=-dtbs))),$(m),))
+
+# Generate symbols for the base files so overlays can be applied to them.
+$(foreach m,$(overlay-y), $(eval DTC_FLAGS_$(basename $(firstword $($(m:.dtb=-dtbs)))) += -@))
+
+# Add base dtb and overlay dtbo
+dtb-y += $(foreach m,$(overlay-y), $($(m:.dtb=-dtbs)))
+
always-y += $(dtb-y)
-always-$(CONFIG_OF_ALL_DTBS) += $(dtb-)
ifneq ($(CHECK_DTBS),)
-always-y += $(patsubst %.dtb,%.dt.yaml, $(dtb-y))
-always-y += $(patsubst %.dtbo,%.dt.yaml, $(dtb-y))
-always-$(CONFIG_OF_ALL_DTBS) += $(patsubst %.dtb,%.dt.yaml, $(dtb-))
-always-$(CONFIG_OF_ALL_DTBS) += $(patsubst %.dtbo,%.dt.yaml, $(dtb-))
+# Don't run schema checks for dtbs created by fdtoverlay as they don't
+# have corresponding dts files.
+dt-yaml-y := $(filter-out $(overlay-y),$(dtb-y))
+
+always-y += $(patsubst %.dtb,%.dt.yaml, $(dt-yaml-y))
+always-y += $(patsubst %.dtbo,%.dt.yaml, $(dt-yaml-y))
endif
# Add subdir path
@@ -338,13 +350,23 @@ $(obj)/%.dtb: $(src)/%.dts $(DTC) FORCE
$(obj)/%.dtbo: $(src)/%.dts $(DTC) FORCE
$(call if_changed_dep,dtc)
+overlay-y := $(addprefix $(obj)/, $(overlay-y))
+
+quiet_cmd_fdtoverlay = DTOVL $@
+ cmd_fdtoverlay = $(objtree)/scripts/dtc/fdtoverlay -o $@ -i $(real-prereqs)
+
+$(overlay-y): FORCE
+ $(call if_changed,fdtoverlay)
+$(call multi_depend, $(overlay-y), .dtb, -dtbs)
+
DT_CHECKER ?= dt-validate
+DT_CHECKER_FLAGS ?= $(if $(DT_SCHEMA_FILES),,-m)
DT_BINDING_DIR := Documentation/devicetree/bindings
# DT_TMP_SCHEMA may be overridden from Documentation/devicetree/bindings/Makefile
DT_TMP_SCHEMA ?= $(objtree)/$(DT_BINDING_DIR)/processed-schema.json
quiet_cmd_dtb_check = CHECK $@
- cmd_dtb_check = $(DT_CHECKER) -u $(srctree)/$(DT_BINDING_DIR) -p $(DT_TMP_SCHEMA) $@
+ cmd_dtb_check = $(DT_CHECKER) $(DT_CHECKER_FLAGS) -u $(srctree)/$(DT_BINDING_DIR) -p $(DT_TMP_SCHEMA) $@
define rule_dtc
$(call cmd_and_fixdep,dtc)
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/bpf_helpers_doc.py b/scripts/bpf_doc.py
index 867ada23281c..2d94025b38e9 100755
--- a/scripts/bpf_helpers_doc.py
+++ b/scripts/bpf_doc.py
@@ -2,6 +2,7 @@
# SPDX-License-Identifier: GPL-2.0-only
#
# Copyright (C) 2018-2019 Netronome Systems, Inc.
+# Copyright (C) 2021 Isovalent, Inc.
# In case user attempts to run with Python 2.
from __future__ import print_function
@@ -13,6 +14,9 @@ import sys, os
class NoHelperFound(BaseException):
pass
+class NoSyscallCommandFound(BaseException):
+ pass
+
class ParsingError(BaseException):
def __init__(self, line='<line not provided>', reader=None):
if reader:
@@ -22,18 +26,27 @@ class ParsingError(BaseException):
else:
BaseException.__init__(self, 'Error parsing line: %s' % line)
-class Helper(object):
+
+class APIElement(object):
"""
- An object representing the description of an eBPF helper function.
- @proto: function prototype of the helper function
- @desc: textual description of the helper function
- @ret: description of the return value of the helper function
+ An object representing the description of an aspect of the eBPF API.
+ @proto: prototype of the API symbol
+ @desc: textual description of the symbol
+ @ret: (optional) description of any associated return value
"""
def __init__(self, proto='', desc='', ret=''):
self.proto = proto
self.desc = desc
self.ret = ret
+
+class Helper(APIElement):
+ """
+ An object representing the description of an eBPF helper function.
+ @proto: function prototype of the helper function
+ @desc: textual description of the helper function
+ @ret: description of the return value of the helper function
+ """
def proto_break_down(self):
"""
Break down helper function protocol into smaller chunks: return type,
@@ -60,6 +73,7 @@ class Helper(object):
return res
+
class HeaderParser(object):
"""
An object used to parse a file in order to extract the documentation of a
@@ -72,6 +86,13 @@ class HeaderParser(object):
self.reader = open(filename, 'r')
self.line = ''
self.helpers = []
+ self.commands = []
+
+ def parse_element(self):
+ proto = self.parse_symbol()
+ desc = self.parse_desc()
+ ret = self.parse_ret()
+ return APIElement(proto=proto, desc=desc, ret=ret)
def parse_helper(self):
proto = self.parse_proto()
@@ -79,6 +100,18 @@ class HeaderParser(object):
ret = self.parse_ret()
return Helper(proto=proto, desc=desc, ret=ret)
+ def parse_symbol(self):
+ p = re.compile(' \* ?(.+)$')
+ capture = p.match(self.line)
+ if not capture:
+ raise NoSyscallCommandFound
+ end_re = re.compile(' \* ?NOTES$')
+ end = end_re.match(self.line)
+ if end:
+ raise NoSyscallCommandFound
+ self.line = self.reader.readline()
+ return capture.group(1)
+
def parse_proto(self):
# Argument can be of shape:
# - "void"
@@ -140,16 +173,29 @@ class HeaderParser(object):
break
return ret
- def run(self):
- # Advance to start of helper function descriptions.
- offset = self.reader.read().find('* Start of BPF helper function descriptions:')
+ def seek_to(self, target, help_message):
+ self.reader.seek(0)
+ offset = self.reader.read().find(target)
if offset == -1:
- raise Exception('Could not find start of eBPF helper descriptions list')
+ raise Exception(help_message)
self.reader.seek(offset)
self.reader.readline()
self.reader.readline()
self.line = self.reader.readline()
+ def parse_syscall(self):
+ self.seek_to('* DOC: eBPF Syscall Commands',
+ 'Could not find start of eBPF syscall descriptions list')
+ while True:
+ try:
+ command = self.parse_element()
+ self.commands.append(command)
+ except NoSyscallCommandFound:
+ break
+
+ def parse_helpers(self):
+ self.seek_to('* Start of BPF helper function descriptions:',
+ 'Could not find start of eBPF helper descriptions list')
while True:
try:
helper = self.parse_helper()
@@ -157,6 +203,9 @@ class HeaderParser(object):
except NoHelperFound:
break
+ def run(self):
+ self.parse_syscall()
+ self.parse_helpers()
self.reader.close()
###############################################################################
@@ -165,10 +214,11 @@ class Printer(object):
"""
A generic class for printers. Printers should be created with an array of
Helper objects, and implement a way to print them in the desired fashion.
- @helpers: array of Helper objects to print to standard output
+ @parser: A HeaderParser with objects to print to standard output
"""
- def __init__(self, helpers):
- self.helpers = helpers
+ def __init__(self, parser):
+ self.parser = parser
+ self.elements = []
def print_header(self):
pass
@@ -181,19 +231,23 @@ class Printer(object):
def print_all(self):
self.print_header()
- for helper in self.helpers:
- self.print_one(helper)
+ for elem in self.elements:
+ self.print_one(elem)
self.print_footer()
+
class PrinterRST(Printer):
"""
- A printer for dumping collected information about helpers as a ReStructured
- Text page compatible with the rst2man program, which can be used to
- generate a manual page for the helpers.
- @helpers: array of Helper objects to print to standard output
+ A generic class for printers that print ReStructured Text. Printers should
+ be created with a HeaderParser object, and implement a way to print API
+ elements in the desired fashion.
+ @parser: A HeaderParser with objects to print to standard output
"""
- def print_header(self):
- header = '''\
+ def __init__(self, parser):
+ self.parser = parser
+
+ def print_license(self):
+ license = '''\
.. Copyright (C) All BPF authors and contributors from 2014 to present.
.. See git log include/uapi/linux/bpf.h in kernel tree for details.
..
@@ -221,9 +275,39 @@ class PrinterRST(Printer):
..
.. Please do not edit this file. It was generated from the documentation
.. located in file include/uapi/linux/bpf.h of the Linux kernel sources
-.. (helpers description), and from scripts/bpf_helpers_doc.py in the same
+.. (helpers description), and from scripts/bpf_doc.py in the same
.. repository (header and footer).
+'''
+ print(license)
+ def print_elem(self, elem):
+ if (elem.desc):
+ print('\tDescription')
+ # Do not strip all newline characters: formatted code at the end of
+ # a section must be followed by a blank line.
+ for line in re.sub('\n$', '', elem.desc, count=1).split('\n'):
+ print('{}{}'.format('\t\t' if line else '', line))
+
+ if (elem.ret):
+ print('\tReturn')
+ for line in elem.ret.rstrip().split('\n'):
+ print('{}{}'.format('\t\t' if line else '', line))
+
+ print('')
+
+
+class PrinterHelpersRST(PrinterRST):
+ """
+ A printer for dumping collected information about helpers as a ReStructured
+ Text page compatible with the rst2man program, which can be used to
+ generate a manual page for the helpers.
+ @parser: A HeaderParser with Helper objects to print to standard output
+ """
+ def __init__(self, parser):
+ self.elements = parser.helpers
+
+ def print_header(self):
+ header = '''\
===========
BPF-HELPERS
===========
@@ -264,6 +348,7 @@ kernel at the top).
HELPERS
=======
'''
+ PrinterRST.print_license(self)
print(header)
def print_footer(self):
@@ -380,27 +465,50 @@ SEE ALSO
def print_one(self, helper):
self.print_proto(helper)
+ self.print_elem(helper)
- if (helper.desc):
- print('\tDescription')
- # Do not strip all newline characters: formatted code at the end of
- # a section must be followed by a blank line.
- for line in re.sub('\n$', '', helper.desc, count=1).split('\n'):
- print('{}{}'.format('\t\t' if line else '', line))
- if (helper.ret):
- print('\tReturn')
- for line in helper.ret.rstrip().split('\n'):
- print('{}{}'.format('\t\t' if line else '', line))
+class PrinterSyscallRST(PrinterRST):
+ """
+ A printer for dumping collected information about the syscall API as a
+ ReStructured Text page compatible with the rst2man program, which can be
+ used to generate a manual page for the syscall.
+ @parser: A HeaderParser with APIElement objects to print to standard
+ output
+ """
+ def __init__(self, parser):
+ self.elements = parser.commands
+
+ def print_header(self):
+ header = '''\
+===
+bpf
+===
+-------------------------------------------------------------------------------
+Perform a command on an extended BPF object
+-------------------------------------------------------------------------------
+
+:Manual section: 2
+
+COMMANDS
+========
+'''
+ PrinterRST.print_license(self)
+ print(header)
+
+ def print_one(self, command):
+ print('**%s**' % (command.proto))
+ self.print_elem(command)
- print('')
class PrinterHelpers(Printer):
"""
A printer for dumping collected information about helpers as C header to
be included from BPF program.
- @helpers: array of Helper objects to print to standard output
+ @parser: A HeaderParser with Helper objects to print to standard output
"""
+ def __init__(self, parser):
+ self.elements = parser.helpers
type_fwds = [
'struct bpf_fib_lookup',
@@ -511,7 +619,7 @@ class PrinterHelpers(Printer):
def print_header(self):
header = '''\
-/* This is auto-generated file. See bpf_helpers_doc.py for details. */
+/* This is auto-generated file. See bpf_doc.py for details. */
/* Forward declarations of BPF structs */'''
@@ -589,8 +697,13 @@ script = os.path.abspath(sys.argv[0])
linuxRoot = os.path.dirname(os.path.dirname(script))
bpfh = os.path.join(linuxRoot, 'include/uapi/linux/bpf.h')
+printers = {
+ 'helpers': PrinterHelpersRST,
+ 'syscall': PrinterSyscallRST,
+}
+
argParser = argparse.ArgumentParser(description="""
-Parse eBPF header file and generate documentation for eBPF helper functions.
+Parse eBPF header file and generate documentation for the eBPF API.
The RST-formatted output produced can be turned into a manual page with the
rst2man utility.
""")
@@ -601,6 +714,8 @@ if (os.path.isfile(bpfh)):
default=bpfh)
else:
argParser.add_argument('--filename', help='path to include/uapi/linux/bpf.h')
+argParser.add_argument('target', nargs='?', default='helpers',
+ choices=printers.keys(), help='eBPF API target')
args = argParser.parse_args()
# Parse file.
@@ -609,7 +724,9 @@ headerParser.run()
# Print formatted output to standard output.
if args.header:
- printer = PrinterHelpers(headerParser.helpers)
+ if args.target != 'helpers':
+ raise NotImplementedError('Only helpers header generation is supported')
+ printer = PrinterHelpers(headerParser)
else:
- printer = PrinterRST(headerParser.helpers)
+ printer = printers[args.target](headerParser)
printer.print_all()
diff --git a/scripts/checkpatch.pl b/scripts/checkpatch.pl
index df8b23dc1eb0..ccb412a74725 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);
@@ -3152,7 +3245,7 @@ sub process {
($line =~ /^new file mode\s*\d+\s*$/) &&
($realfile =~ m@^Documentation/devicetree/bindings/.*\.txt$@)) {
WARN("DT_SCHEMA_BINDING_PATCH",
- "DT bindings should be in DT schema format. See: Documentation/devicetree/writing-schema.rst\n");
+ "DT bindings should be in DT schema format. See: Documentation/devicetree/bindings/writing-schema.rst\n");
}
# Check for wrappage within a valid hunk of the file
@@ -6606,9 +6699,11 @@ sub process {
$specifier = $1;
$extension = $2;
$qualifier = $3;
- if ($extension !~ /[SsBKRraEehMmIiUDdgVCbGNOxtf]/ ||
+ if ($extension !~ /[4SsBKRraEehMmIiUDdgVCbGNOxtf]/ ||
($extension eq "f" &&
- defined $qualifier && $qualifier !~ /^w/)) {
+ defined $qualifier && $qualifier !~ /^w/) ||
+ ($extension eq "4" &&
+ defined $qualifier && $qualifier !~ /^cc/)) {
$bad_specifier = $specifier;
last;
}
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/link-vmlinux.sh b/scripts/link-vmlinux.sh
index e9516bdfcc6f..7d112681f332 100755
--- a/scripts/link-vmlinux.sh
+++ b/scripts/link-vmlinux.sh
@@ -220,6 +220,7 @@ vmlinux_link()
gen_btf()
{
local pahole_ver
+ local extra_paholeopt=
if ! [ -x "$(command -v ${PAHOLE})" ]; then
echo >&2 "BTF: ${1}: pahole (${PAHOLE}) is not available"
@@ -234,8 +235,12 @@ gen_btf()
vmlinux_link ${1}
+ if [ "${pahole_ver}" -ge "121" ]; then
+ extra_paholeopt="${extra_paholeopt} --btf_gen_floats"
+ fi
+
info "BTF" ${2}
- LLVM_OBJCOPY=${OBJCOPY} ${PAHOLE} -J ${1}
+ LLVM_OBJCOPY=${OBJCOPY} ${PAHOLE} -J ${extra_paholeopt} ${1}
# Create ${2} which contains just .BTF section but no symbols. Add
# SHF_ALLOC because .BTF will be part of the vmlinux image. --strip-all
diff --git a/scripts/module.lds.S b/scripts/module.lds.S
index 168cd27e6122..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+*)) }
@@ -20,6 +30,7 @@ SECTIONS {
__patchable_function_entries : { *(__patchable_function_entries) }
+#ifdef CONFIG_LTO_CLANG
/*
* With CONFIG_LTO_CLANG, LLD always enables -fdata-sections and
* -ffunction-sections, which increases the size of the final module.
@@ -40,7 +51,15 @@ 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
}
/* bring in arch-specific sections */
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;
}