aboutsummaryrefslogtreecommitdiffstats
path: root/scripts
diff options
context:
space:
mode:
Diffstat (limited to 'scripts')
-rw-r--r--scripts/Kbuild.include10
-rw-r--r--scripts/Makefile.gcc-plugins39
-rw-r--r--scripts/Makefile.ubsan5
-rwxr-xr-xscripts/checkkconfigsymbols.py338
-rwxr-xr-xscripts/checkpatch.pl347
-rw-r--r--scripts/const_structs.checkpatch64
-rwxr-xr-xscripts/faddr2line177
-rwxr-xr-xscripts/gcc-plugin.sh14
-rw-r--r--scripts/gcc-plugins/Makefile12
-rwxr-xr-xscripts/get_maintainer.pl6
-rwxr-xr-xscripts/kernel-doc48
-rw-r--r--scripts/mod/modpost.c2
-rwxr-xr-xscripts/package/builddeb4
-rw-r--r--scripts/recordmcount.c2
-rwxr-xr-xscripts/recordmcount.pl2
-rw-r--r--scripts/spelling.txt1
-rwxr-xr-xscripts/tags.sh4
-rwxr-xr-xscripts/tracing/ftrace-bisect.sh115
-rwxr-xr-xscripts/ver_linux260
19 files changed, 959 insertions, 491 deletions
diff --git a/scripts/Kbuild.include b/scripts/Kbuild.include
index 15b196fc2f49..179219845dfc 100644
--- a/scripts/Kbuild.include
+++ b/scripts/Kbuild.include
@@ -108,16 +108,20 @@ as-option = $(call try-run,\
as-instr = $(call try-run,\
printf "%b\n" "$(1)" | $(CC) $(KBUILD_AFLAGS) -c -x assembler -o "$$TMP" -,$(2),$(3))
+# Do not attempt to build with gcc plugins during cc-option tests.
+# (And this uses delayed resolution so the flags will be up to date.)
+CC_OPTION_CFLAGS = $(filter-out $(GCC_PLUGINS_CFLAGS),$(KBUILD_CFLAGS))
+
# cc-option
# Usage: cflags-y += $(call cc-option,-march=winchip-c6,-march=i586)
cc-option = $(call try-run,\
- $(CC) $(KBUILD_CPPFLAGS) $(KBUILD_CFLAGS) $(1) -c -x c /dev/null -o "$$TMP",$(1),$(2))
+ $(CC) $(KBUILD_CPPFLAGS) $(CC_OPTION_CFLAGS) $(1) -c -x c /dev/null -o "$$TMP",$(1),$(2))
# cc-option-yn
# Usage: flag := $(call cc-option-yn,-march=winchip-c6)
cc-option-yn = $(call try-run,\
- $(CC) $(KBUILD_CPPFLAGS) $(KBUILD_CFLAGS) $(1) -c -x c /dev/null -o "$$TMP",y,n)
+ $(CC) $(KBUILD_CPPFLAGS) $(CC_OPTION_CFLAGS) $(1) -c -x c /dev/null -o "$$TMP",y,n)
# cc-option-align
# Prefix align with either -falign or -malign
@@ -127,7 +131,7 @@ cc-option-align = $(subst -functions=0,,\
# cc-disable-warning
# Usage: cflags-y += $(call cc-disable-warning,unused-but-set-variable)
cc-disable-warning = $(call try-run,\
- $(CC) $(KBUILD_CPPFLAGS) $(KBUILD_CFLAGS) -W$(strip $(1)) -c -x c /dev/null -o "$$TMP",-Wno-$(strip $(1)))
+ $(CC) $(KBUILD_CPPFLAGS) $(CC_OPTION_CFLAGS) -W$(strip $(1)) -c -x c /dev/null -o "$$TMP",-Wno-$(strip $(1)))
# cc-name
# Expands to either gcc or clang
diff --git a/scripts/Makefile.gcc-plugins b/scripts/Makefile.gcc-plugins
index 5e22b60589c1..61f0e6db909b 100644
--- a/scripts/Makefile.gcc-plugins
+++ b/scripts/Makefile.gcc-plugins
@@ -19,25 +19,42 @@ ifdef CONFIG_GCC_PLUGINS
endif
endif
- GCC_PLUGINS_CFLAGS := $(addprefix -fplugin=$(objtree)/scripts/gcc-plugins/, $(gcc-plugin-y))
+ GCC_PLUGINS_CFLAGS := $(strip $(addprefix -fplugin=$(objtree)/scripts/gcc-plugins/, $(gcc-plugin-y)) $(gcc-plugin-cflags-y))
- export PLUGINCC GCC_PLUGINS_CFLAGS GCC_PLUGIN SANCOV_PLUGIN
+ export PLUGINCC GCC_PLUGINS_CFLAGS GCC_PLUGIN GCC_PLUGIN_SUBDIR SANCOV_PLUGIN
+ ifneq ($(PLUGINCC),)
+ # SANCOV_PLUGIN can be only in CFLAGS_KCOV because avoid duplication.
+ GCC_PLUGINS_CFLAGS := $(filter-out $(SANCOV_PLUGIN), $(GCC_PLUGINS_CFLAGS))
+ endif
+
+ KBUILD_CFLAGS += $(GCC_PLUGINS_CFLAGS)
+ GCC_PLUGIN := $(gcc-plugin-y)
+ GCC_PLUGIN_SUBDIR := $(gcc-plugin-subdir-y)
+endif
+
+# If plugins aren't supported, abort the build before hard-to-read compiler
+# errors start getting spewed by the main build.
+PHONY += gcc-plugins-check
+gcc-plugins-check: FORCE
+ifdef CONFIG_GCC_PLUGINS
ifeq ($(PLUGINCC),)
ifneq ($(GCC_PLUGINS_CFLAGS),)
ifeq ($(call cc-ifversion, -ge, 0405, y), y)
- PLUGINCC := $(shell $(CONFIG_SHELL) -x $(srctree)/scripts/gcc-plugin.sh "$(__PLUGINCC)" "$(HOSTCXX)" "$(CC)")
- $(warning warning: your gcc installation does not support plugins, perhaps the necessary headers are missing?)
+ $(Q)$(srctree)/scripts/gcc-plugin.sh --show-error "$(__PLUGINCC)" "$(HOSTCXX)" "$(CC)" || true
+ @echo "Cannot use CONFIG_GCC_PLUGINS: your gcc installation does not support plugins, perhaps the necessary headers are missing?" >&2 && exit 1
else
- $(warning warning: your gcc version does not support plugins, you should upgrade it to gcc 4.5 at least)
+ @echo "Cannot use CONFIG_GCC_PLUGINS: your gcc version does not support plugins, you should upgrade it to at least gcc 4.5" >&2 && exit 1
endif
endif
- else
- # SANCOV_PLUGIN can be only in CFLAGS_KCOV because avoid duplication.
- GCC_PLUGINS_CFLAGS := $(filter-out $(SANCOV_PLUGIN), $(GCC_PLUGINS_CFLAGS))
endif
+endif
+ @:
- KBUILD_CFLAGS += $(GCC_PLUGINS_CFLAGS)
- GCC_PLUGIN := $(gcc-plugin-y)
-
+# Actually do the build, if requested.
+PHONY += gcc-plugins
+gcc-plugins: scripts_basic gcc-plugins-check
+ifdef CONFIG_GCC_PLUGINS
+ $(Q)$(MAKE) $(build)=scripts/gcc-plugins
endif
+ @:
diff --git a/scripts/Makefile.ubsan b/scripts/Makefile.ubsan
index 8ab68679cfb5..dd779c40c8e6 100644
--- a/scripts/Makefile.ubsan
+++ b/scripts/Makefile.ubsan
@@ -3,7 +3,6 @@ ifdef CONFIG_UBSAN
CFLAGS_UBSAN += $(call cc-option, -fsanitize=integer-divide-by-zero)
CFLAGS_UBSAN += $(call cc-option, -fsanitize=unreachable)
CFLAGS_UBSAN += $(call cc-option, -fsanitize=vla-bound)
- CFLAGS_UBSAN += $(call cc-option, -fsanitize=null)
CFLAGS_UBSAN += $(call cc-option, -fsanitize=signed-integer-overflow)
CFLAGS_UBSAN += $(call cc-option, -fsanitize=bounds)
CFLAGS_UBSAN += $(call cc-option, -fsanitize=object-size)
@@ -14,4 +13,8 @@ ifdef CONFIG_UBSAN
ifdef CONFIG_UBSAN_ALIGNMENT
CFLAGS_UBSAN += $(call cc-option, -fsanitize=alignment)
endif
+
+ifdef CONFIG_UBSAN_NULL
+ CFLAGS_UBSAN += $(call cc-option, -fsanitize=null)
+endif
endif
diff --git a/scripts/checkkconfigsymbols.py b/scripts/checkkconfigsymbols.py
index df643f60bb41..a32e4da4c117 100755
--- a/scripts/checkkconfigsymbols.py
+++ b/scripts/checkkconfigsymbols.py
@@ -1,98 +1,99 @@
-#!/usr/bin/env python2
+#!/usr/bin/env python3
"""Find Kconfig symbols that are referenced but not defined."""
-# (c) 2014-2015 Valentin Rothberg <valentinrothberg@gmail.com>
+# (c) 2014-2016 Valentin Rothberg <valentinrothberg@gmail.com>
# (c) 2014 Stefan Hengelein <stefan.hengelein@fau.de>
#
# Licensed under the terms of the GNU GPL License version 2
+import argparse
import difflib
import os
import re
import signal
+import subprocess
import sys
from multiprocessing import Pool, cpu_count
-from optparse import OptionParser
-from subprocess import Popen, PIPE, STDOUT
# regex expressions
OPERATORS = r"&|\(|\)|\||\!"
-FEATURE = r"(?:\w*[A-Z0-9]\w*){2,}"
-DEF = r"^\s*(?:menu){,1}config\s+(" + FEATURE + r")\s*"
-EXPR = r"(?:" + OPERATORS + r"|\s|" + FEATURE + r")+"
+SYMBOL = r"(?:\w*[A-Z0-9]\w*){2,}"
+DEF = r"^\s*(?:menu){,1}config\s+(" + SYMBOL + r")\s*"
+EXPR = r"(?:" + OPERATORS + r"|\s|" + SYMBOL + r")+"
DEFAULT = r"default\s+.*?(?:if\s.+){,1}"
STMT = r"^\s*(?:if|select|depends\s+on|(?:" + DEFAULT + r"))\s+" + EXPR
-SOURCE_FEATURE = r"(?:\W|\b)+[D]{,1}CONFIG_(" + FEATURE + r")"
+SOURCE_SYMBOL = r"(?:\W|\b)+[D]{,1}CONFIG_(" + SYMBOL + r")"
# regex objects
REGEX_FILE_KCONFIG = re.compile(r".*Kconfig[\.\w+\-]*$")
-REGEX_FEATURE = re.compile(r'(?!\B)' + FEATURE + r'(?!\B)')
-REGEX_SOURCE_FEATURE = re.compile(SOURCE_FEATURE)
+REGEX_SYMBOL = re.compile(r'(?!\B)' + SYMBOL + r'(?!\B)')
+REGEX_SOURCE_SYMBOL = re.compile(SOURCE_SYMBOL)
REGEX_KCONFIG_DEF = re.compile(DEF)
REGEX_KCONFIG_EXPR = re.compile(EXPR)
REGEX_KCONFIG_STMT = re.compile(STMT)
REGEX_KCONFIG_HELP = re.compile(r"^\s+(help|---help---)\s*$")
-REGEX_FILTER_FEATURES = re.compile(r"[A-Za-z0-9]$")
+REGEX_FILTER_SYMBOLS = re.compile(r"[A-Za-z0-9]$")
REGEX_NUMERIC = re.compile(r"0[xX][0-9a-fA-F]+|[0-9]+")
REGEX_QUOTES = re.compile("(\"(.*?)\")")
def parse_options():
"""The user interface of this module."""
- usage = "%prog [options]\n\n" \
- "Run this tool to detect Kconfig symbols that are referenced but " \
- "not defined in\nKconfig. The output of this tool has the " \
- "format \'Undefined symbol\\tFile list\'\n\n" \
- "If no option is specified, %prog will default to check your\n" \
- "current tree. Please note that specifying commits will " \
- "\'git reset --hard\'\nyour current tree! You may save " \
- "uncommitted changes to avoid losing data."
-
- parser = OptionParser(usage=usage)
-
- parser.add_option('-c', '--commit', dest='commit', action='store',
- default="",
- help="Check if the specified commit (hash) introduces "
- "undefined Kconfig symbols.")
-
- parser.add_option('-d', '--diff', dest='diff', action='store',
- default="",
- help="Diff undefined symbols between two commits. The "
- "input format bases on Git log's "
- "\'commmit1..commit2\'.")
-
- parser.add_option('-f', '--find', dest='find', action='store_true',
- default=False,
- help="Find and show commits that may cause symbols to be "
- "missing. Required to run with --diff.")
-
- parser.add_option('-i', '--ignore', dest='ignore', action='store',
- default="",
- help="Ignore files matching this pattern. Note that "
- "the pattern needs to be a Python regex. To "
- "ignore defconfigs, specify -i '.*defconfig'.")
-
- parser.add_option('-s', '--sim', dest='sim', action='store', default="",
- help="Print a list of maximum 10 string-similar symbols.")
-
- parser.add_option('', '--force', dest='force', action='store_true',
- default=False,
- help="Reset current Git tree even when it's dirty.")
-
- (opts, _) = parser.parse_args()
-
- if opts.commit and opts.diff:
+ usage = "Run this tool to detect Kconfig symbols that are referenced but " \
+ "not defined in Kconfig. If no option is specified, " \
+ "checkkconfigsymbols defaults to check your current tree. " \
+ "Please note that specifying commits will 'git reset --hard\' " \
+ "your current tree! You may save uncommitted changes to avoid " \
+ "losing data."
+
+ parser = argparse.ArgumentParser(description=usage)
+
+ parser.add_argument('-c', '--commit', dest='commit', action='store',
+ default="",
+ help="check if the specified commit (hash) introduces "
+ "undefined Kconfig symbols")
+
+ parser.add_argument('-d', '--diff', dest='diff', action='store',
+ default="",
+ help="diff undefined symbols between two commits "
+ "(e.g., -d commmit1..commit2)")
+
+ parser.add_argument('-f', '--find', dest='find', action='store_true',
+ default=False,
+ help="find and show commits that may cause symbols to be "
+ "missing (required to run with --diff)")
+
+ parser.add_argument('-i', '--ignore', dest='ignore', action='store',
+ default="",
+ help="ignore files matching this Python regex "
+ "(e.g., -i '.*defconfig')")
+
+ parser.add_argument('-s', '--sim', dest='sim', action='store', default="",
+ help="print a list of max. 10 string-similar symbols")
+
+ parser.add_argument('--force', dest='force', action='store_true',
+ default=False,
+ help="reset current Git tree even when it's dirty")
+
+ parser.add_argument('--no-color', dest='color', action='store_false',
+ default=True,
+ help="don't print colored output (default when not "
+ "outputting to a terminal)")
+
+ args = parser.parse_args()
+
+ if args.commit and args.diff:
sys.exit("Please specify only one option at once.")
- if opts.diff and not re.match(r"^[\w\-\.]+\.\.[\w\-\.]+$", opts.diff):
+ if args.diff and not re.match(r"^[\w\-\.]+\.\.[\w\-\.]+$", args.diff):
sys.exit("Please specify valid input in the following format: "
"\'commit1..commit2\'")
- if opts.commit or opts.diff:
- if not opts.force and tree_is_dirty():
+ if args.commit or args.diff:
+ if not args.force and tree_is_dirty():
sys.exit("The current Git tree is dirty (see 'git status'). "
"Running this script may\ndelete important data since it "
"calls 'git reset --hard' for some performance\nreasons. "
@@ -100,138 +101,148 @@ def parse_options():
"'--force' if you\nwant to ignore this warning and "
"continue.")
- if opts.commit:
- opts.find = False
+ if args.commit:
+ args.find = False
- if opts.ignore:
+ if args.ignore:
try:
- re.match(opts.ignore, "this/is/just/a/test.c")
+ re.match(args.ignore, "this/is/just/a/test.c")
except:
sys.exit("Please specify a valid Python regex.")
- return opts
+ return args
def main():
"""Main function of this module."""
- opts = parse_options()
+ args = parse_options()
- if opts.sim and not opts.commit and not opts.diff:
- sims = find_sims(opts.sim, opts.ignore)
+ global COLOR
+ COLOR = args.color and sys.stdout.isatty()
+
+ if args.sim and not args.commit and not args.diff:
+ sims = find_sims(args.sim, args.ignore)
if sims:
- print "%s: %s" % (yel("Similar symbols"), ', '.join(sims))
+ print("%s: %s" % (yel("Similar symbols"), ', '.join(sims)))
else:
- print "%s: no similar symbols found" % yel("Similar symbols")
+ print("%s: no similar symbols found" % yel("Similar symbols"))
sys.exit(0)
# dictionary of (un)defined symbols
defined = {}
undefined = {}
- if opts.commit or opts.diff:
+ if args.commit or args.diff:
head = get_head()
# get commit range
commit_a = None
commit_b = None
- if opts.commit:
- commit_a = opts.commit + "~"
- commit_b = opts.commit
- elif opts.diff:
- split = opts.diff.split("..")
+ if args.commit:
+ commit_a = args.commit + "~"
+ commit_b = args.commit
+ elif args.diff:
+ split = args.diff.split("..")
commit_a = split[0]
commit_b = split[1]
undefined_a = {}
undefined_b = {}
# get undefined items before the commit
- execute("git reset --hard %s" % commit_a)
- undefined_a, _ = check_symbols(opts.ignore)
+ reset(commit_a)
+ undefined_a, _ = check_symbols(args.ignore)
# get undefined items for the commit
- execute("git reset --hard %s" % commit_b)
- undefined_b, defined = check_symbols(opts.ignore)
+ reset(commit_b)
+ undefined_b, defined = check_symbols(args.ignore)
# report cases that are present for the commit but not before
- for feature in sorted(undefined_b):
- # feature has not been undefined before
- if not feature in undefined_a:
- files = sorted(undefined_b.get(feature))
- undefined[feature] = files
- # check if there are new files that reference the undefined feature
+ for symbol in sorted(undefined_b):
+ # symbol has not been undefined before
+ if symbol not in undefined_a:
+ files = sorted(undefined_b.get(symbol))
+ undefined[symbol] = files
+ # check if there are new files that reference the undefined symbol
else:
- files = sorted(undefined_b.get(feature) -
- undefined_a.get(feature))
+ files = sorted(undefined_b.get(symbol) -
+ undefined_a.get(symbol))
if files:
- undefined[feature] = files
+ undefined[symbol] = files
# reset to head
- execute("git reset --hard %s" % head)
+ reset(head)
# default to check the entire tree
else:
- undefined, defined = check_symbols(opts.ignore)
+ undefined, defined = check_symbols(args.ignore)
# now print the output
- for feature in sorted(undefined):
- print red(feature)
+ for symbol in sorted(undefined):
+ print(red(symbol))
- files = sorted(undefined.get(feature))
- print "%s: %s" % (yel("Referencing files"), ", ".join(files))
+ files = sorted(undefined.get(symbol))
+ print("%s: %s" % (yel("Referencing files"), ", ".join(files)))
- sims = find_sims(feature, opts.ignore, defined)
+ sims = find_sims(symbol, args.ignore, defined)
sims_out = yel("Similar symbols")
if sims:
- print "%s: %s" % (sims_out, ', '.join(sims))
+ print("%s: %s" % (sims_out, ', '.join(sims)))
else:
- print "%s: %s" % (sims_out, "no similar symbols found")
+ print("%s: %s" % (sims_out, "no similar symbols found"))
- if opts.find:
- print "%s:" % yel("Commits changing symbol")
- commits = find_commits(feature, opts.diff)
+ if args.find:
+ print("%s:" % yel("Commits changing symbol"))
+ commits = find_commits(symbol, args.diff)
if commits:
for commit in commits:
commit = commit.split(" ", 1)
- print "\t- %s (\"%s\")" % (yel(commit[0]), commit[1])
+ print("\t- %s (\"%s\")" % (yel(commit[0]), commit[1]))
else:
- print "\t- no commit found"
- print # new line
+ print("\t- no commit found")
+ print() # new line
+
+
+def reset(commit):
+ """Reset current git tree to %commit."""
+ execute(["git", "reset", "--hard", commit])
def yel(string):
"""
Color %string yellow.
"""
- return "\033[33m%s\033[0m" % string
+ return "\033[33m%s\033[0m" % string if COLOR else string
def red(string):
"""
Color %string red.
"""
- return "\033[31m%s\033[0m" % string
+ return "\033[31m%s\033[0m" % string if COLOR else string
def execute(cmd):
"""Execute %cmd and return stdout. Exit in case of error."""
- pop = Popen(cmd, stdout=PIPE, stderr=STDOUT, shell=True)
- (stdout, _) = pop.communicate() # wait until finished
- if pop.returncode != 0:
- sys.exit(stdout)
+ try:
+ stdout = subprocess.check_output(cmd, stderr=subprocess.STDOUT, shell=False)
+ stdout = stdout.decode(errors='replace')
+ except subprocess.CalledProcessError as fail:
+ exit(fail)
return stdout
def find_commits(symbol, diff):
"""Find commits changing %symbol in the given range of %diff."""
- commits = execute("git log --pretty=oneline --abbrev-commit -G %s %s"
- % (symbol, diff))
+ commits = execute(["git", "log", "--pretty=oneline",
+ "--abbrev-commit", "-G",
+ symbol, diff])
return [x for x in commits.split("\n") if x]
def tree_is_dirty():
"""Return true if the current working tree is dirty (i.e., if any file has
been added, deleted, modified, renamed or copied but not committed)."""
- stdout = execute("git status --porcelain")
+ stdout = execute(["git", "status", "--porcelain"])
for line in stdout:
if re.findall(r"[URMADC]{1}", line[:2]):
return True
@@ -240,13 +251,13 @@ def tree_is_dirty():
def get_head():
"""Return commit hash of current HEAD."""
- stdout = execute("git rev-parse HEAD")
+ stdout = execute(["git", "rev-parse", "HEAD"])
return stdout.strip('\n')
def partition(lst, size):
"""Partition list @lst into eveni-sized lists of size @size."""
- return [lst[i::size] for i in xrange(size)]
+ return [lst[i::size] for i in range(size)]
def init_worker():
@@ -254,7 +265,7 @@ def init_worker():
signal.signal(signal.SIGINT, signal.SIG_IGN)
-def find_sims(symbol, ignore, defined = []):
+def find_sims(symbol, ignore, defined=[]):
"""Return a list of max. ten Kconfig symbols that are string-similar to
@symbol."""
if defined:
@@ -279,7 +290,7 @@ def find_sims(symbol, ignore, defined = []):
def get_files():
"""Return a list of all files in the current git directory."""
# use 'git ls-files' to get the worklist
- stdout = execute("git ls-files")
+ stdout = execute(["git", "ls-files"])
if len(stdout) > 0 and stdout[-1] == "\n":
stdout = stdout[:-1]
@@ -311,8 +322,8 @@ def check_symbols_helper(pool, ignore):
check_symbols() in order to properly terminate running worker processes."""
source_files = []
kconfig_files = []
- defined_features = []
- referenced_features = dict() # {file: [features]}
+ defined_symbols = []
+ referenced_symbols = dict() # {file: [symbols]}
for gitfile in get_files():
if REGEX_FILE_KCONFIG.match(gitfile):
@@ -326,76 +337,75 @@ def check_symbols_helper(pool, ignore):
# parse source files
arglist = partition(source_files, cpu_count())
for res in pool.map(parse_source_files, arglist):
- referenced_features.update(res)
-
+ referenced_symbols.update(res)
# parse kconfig files
arglist = []
for part in partition(kconfig_files, cpu_count()):
arglist.append((part, ignore))
for res in pool.map(parse_kconfig_files, arglist):
- defined_features.extend(res[0])
- referenced_features.update(res[1])
- defined_features = set(defined_features)
+ defined_symbols.extend(res[0])
+ referenced_symbols.update(res[1])
+ defined_symbols = set(defined_symbols)
- # inverse mapping of referenced_features to dict(feature: [files])
+ # inverse mapping of referenced_symbols to dict(symbol: [files])
inv_map = dict()
- for _file, features in referenced_features.iteritems():
- for feature in features:
- inv_map[feature] = inv_map.get(feature, set())
- inv_map[feature].add(_file)
- referenced_features = inv_map
-
- undefined = {} # {feature: [files]}
- for feature in sorted(referenced_features):
+ for _file, symbols in referenced_symbols.items():
+ for symbol in symbols:
+ inv_map[symbol] = inv_map.get(symbol, set())
+ inv_map[symbol].add(_file)
+ referenced_symbols = inv_map
+
+ undefined = {} # {symbol: [files]}
+ for symbol in sorted(referenced_symbols):
# filter some false positives
- if feature == "FOO" or feature == "BAR" or \
- feature == "FOO_BAR" or feature == "XXX":
+ if symbol == "FOO" or symbol == "BAR" or \
+ symbol == "FOO_BAR" or symbol == "XXX":
continue
- if feature not in defined_features:
- if feature.endswith("_MODULE"):
+ if symbol not in defined_symbols:
+ if symbol.endswith("_MODULE"):
# avoid false positives for kernel modules
- if feature[:-len("_MODULE")] in defined_features:
+ if symbol[:-len("_MODULE")] in defined_symbols:
continue
- undefined[feature] = referenced_features.get(feature)
- return undefined, defined_features
+ undefined[symbol] = referenced_symbols.get(symbol)
+ return undefined, defined_symbols
def parse_source_files(source_files):
"""Parse each source file in @source_files and return dictionary with source
files as keys and lists of references Kconfig symbols as values."""
- referenced_features = dict()
+ referenced_symbols = dict()
for sfile in source_files:
- referenced_features[sfile] = parse_source_file(sfile)
- return referenced_features
+ referenced_symbols[sfile] = parse_source_file(sfile)
+ return referenced_symbols
def parse_source_file(sfile):
- """Parse @sfile and return a list of referenced Kconfig features."""
+ """Parse @sfile and return a list of referenced Kconfig symbols."""
lines = []
references = []
if not os.path.exists(sfile):
return references
- with open(sfile, "r") as stream:
+ with open(sfile, "r", encoding='utf-8', errors='replace') as stream:
lines = stream.readlines()
for line in lines:
- if not "CONFIG_" in line:
+ if "CONFIG_" not in line:
continue
- features = REGEX_SOURCE_FEATURE.findall(line)
- for feature in features:
- if not REGEX_FILTER_FEATURES.search(feature):
+ symbols = REGEX_SOURCE_SYMBOL.findall(line)
+ for symbol in symbols:
+ if not REGEX_FILTER_SYMBOLS.search(symbol):
continue
- references.append(feature)
+ references.append(symbol)
return references
-def get_features_in_line(line):
- """Return mentioned Kconfig features in @line."""
- return REGEX_FEATURE.findall(line)
+def get_symbols_in_line(line):
+ """Return mentioned Kconfig symbols in @line."""
+ return REGEX_SYMBOL.findall(line)
def parse_kconfig_files(args):
@@ -404,21 +414,21 @@ def parse_kconfig_files(args):
pattern."""
kconfig_files = args[0]
ignore = args[1]
- defined_features = []
- referenced_features = dict()
+ defined_symbols = []
+ referenced_symbols = dict()
for kfile in kconfig_files:
defined, references = parse_kconfig_file(kfile)
- defined_features.extend(defined)
+ defined_symbols.extend(defined)
if ignore and re.match(ignore, kfile):
# do not collect references for files that match the ignore pattern
continue
- referenced_features[kfile] = references
- return (defined_features, referenced_features)
+ referenced_symbols[kfile] = references
+ return (defined_symbols, referenced_symbols)
def parse_kconfig_file(kfile):
- """Parse @kfile and update feature definitions and references."""
+ """Parse @kfile and update symbol definitions and references."""
lines = []
defined = []
references = []
@@ -427,7 +437,7 @@ def parse_kconfig_file(kfile):
if not os.path.exists(kfile):
return defined, references
- with open(kfile, "r") as stream:
+ with open(kfile, "r", encoding='utf-8', errors='replace') as stream:
lines = stream.readlines()
for i in range(len(lines)):
@@ -436,8 +446,8 @@ def parse_kconfig_file(kfile):
line = line.split("#")[0] # ignore comments
if REGEX_KCONFIG_DEF.match(line):
- feature_def = REGEX_KCONFIG_DEF.findall(line)
- defined.append(feature_def[0])
+ symbol_def = REGEX_KCONFIG_DEF.findall(line)
+ defined.append(symbol_def[0])
skip = False
elif REGEX_KCONFIG_HELP.match(line):
skip = True
@@ -446,18 +456,18 @@ def parse_kconfig_file(kfile):
pass
elif REGEX_KCONFIG_STMT.match(line):
line = REGEX_QUOTES.sub("", line)
- features = get_features_in_line(line)
+ symbols = get_symbols_in_line(line)
# multi-line statements
while line.endswith("\\"):
i += 1
line = lines[i]
line = line.strip('\n')
- features.extend(get_features_in_line(line))
- for feature in set(features):
- if REGEX_NUMERIC.match(feature):
+ symbols.extend(get_symbols_in_line(line))
+ for symbol in set(symbols):
+ if REGEX_NUMERIC.match(symbol):
# ignore numeric values
continue
- references.append(feature)
+ references.append(symbol)
return defined, references
diff --git a/scripts/checkpatch.pl b/scripts/checkpatch.pl
index 4de3cc42fc50..a8368d1c4348 100755
--- a/scripts/checkpatch.pl
+++ b/scripts/checkpatch.pl
@@ -54,6 +54,7 @@ my $min_conf_desc_length = 4;
my $spelling_file = "$D/spelling.txt";
my $codespell = 0;
my $codespellfile = "/usr/share/codespell/dictionary.txt";
+my $conststructsfile = "$D/const_structs.checkpatch";
my $color = 1;
my $allow_c99_comments = 1;
@@ -523,7 +524,11 @@ our @mode_permission_funcs = (
["module_param_array_named", 5],
["debugfs_create_(?:file|u8|u16|u32|u64|x8|x16|x32|x64|size_t|atomic_t|bool|blob|regset32|u32_array)", 2],
["proc_create(?:_data|)", 2],
- ["(?:CLASS|DEVICE|SENSOR)_ATTR", 2],
+ ["(?:CLASS|DEVICE|SENSOR|SENSOR_DEVICE|IIO_DEVICE)_ATTR", 2],
+ ["IIO_DEV_ATTR_[A-Z_]+", 1],
+ ["SENSOR_(?:DEVICE_|)ATTR_2", 2],
+ ["SENSOR_TEMPLATE(?:_2|)", 3],
+ ["__ATTR", 2],
);
#Create a search pattern for all these functions to speed up a loop below
@@ -541,6 +546,32 @@ our $mode_perms_world_writable = qr{
0[0-7][0-7][2367]
}x;
+our %mode_permission_string_types = (
+ "S_IRWXU" => 0700,
+ "S_IRUSR" => 0400,
+ "S_IWUSR" => 0200,
+ "S_IXUSR" => 0100,
+ "S_IRWXG" => 0070,
+ "S_IRGRP" => 0040,
+ "S_IWGRP" => 0020,
+ "S_IXGRP" => 0010,
+ "S_IRWXO" => 0007,
+ "S_IROTH" => 0004,
+ "S_IWOTH" => 0002,
+ "S_IXOTH" => 0001,
+ "S_IRWXUGO" => 0777,
+ "S_IRUGO" => 0444,
+ "S_IWUGO" => 0222,
+ "S_IXUGO" => 0111,
+);
+
+#Create a search pattern for all these strings to speed up a loop below
+our $mode_perms_string_search = "";
+foreach my $entry (keys %mode_permission_string_types) {
+ $mode_perms_string_search .= '|' if ($mode_perms_string_search ne "");
+ $mode_perms_string_search .= $entry;
+}
+
our $allowed_asm_includes = qr{(?x:
irq|
memory|
@@ -598,6 +629,29 @@ if ($codespell) {
$misspellings = join("|", sort keys %spelling_fix) if keys %spelling_fix;
+my $const_structs = "";
+if (open(my $conststructs, '<', $conststructsfile)) {
+ while (<$conststructs>) {
+ my $line = $_;
+
+ $line =~ s/\s*\n?$//g;
+ $line =~ s/^\s*//g;
+
+ next if ($line =~ m/^\s*#/);
+ next if ($line =~ m/^\s*$/);
+ if ($line =~ /\s/) {
+ print("$conststructsfile: '$line' invalid - ignored\n");
+ next;
+ }
+
+ $const_structs .= '|' if ($const_structs ne "");
+ $const_structs .= $line;
+ }
+ close($conststructsfile);
+} else {
+ warn "No structs that should be const will be found - file '$conststructsfile': $!\n";
+}
+
sub build_types {
my $mods = "(?x: \n" . join("|\n ", (@modifierList, @modifierListFile)) . "\n)";
my $all = "(?x: \n" . join("|\n ", (@typeList, @typeListFile)) . "\n)";
@@ -704,6 +758,16 @@ sub seed_camelcase_file {
}
}
+sub is_maintained_obsolete {
+ my ($filename) = @_;
+
+ return 0 if (!(-e "$root/scripts/get_maintainer.pl"));
+
+ my $status = `perl $root/scripts/get_maintainer.pl --status --nom --nol --nogit --nogit-fallback -f $filename 2>&1`;
+
+ return $status =~ /obsolete/i;
+}
+
my $camelcase_seeded = 0;
sub seed_camelcase_includes {
return if ($camelcase_seeded);
@@ -2289,6 +2353,10 @@ sub process {
}
if ($found_file) {
+ if (is_maintained_obsolete($realfile)) {
+ WARN("OBSOLETE",
+ "$realfile is marked as 'obsolete' in the MAINTAINERS hierarchy. No unnecessary modifications please.\n");
+ }
if ($realfile =~ m@^(?:drivers/net/|net/|drivers/staging/)@) {
$check = 1;
} else {
@@ -2939,6 +3007,30 @@ sub process {
"Block comments use a trailing */ on a separate line\n" . $herecurr);
}
+# Block comment * alignment
+ if ($prevline =~ /$;[ \t]*$/ && #ends in comment
+ $line =~ /^\+[ \t]*$;/ && #leading comment
+ $rawline =~ /^\+[ \t]*\*/ && #leading *
+ (($prevrawline =~ /^\+.*?\/\*/ && #leading /*
+ $prevrawline !~ /\*\/[ \t]*$/) || #no trailing */
+ $prevrawline =~ /^\+[ \t]*\*/)) { #leading *
+ my $oldindent;
+ $prevrawline =~ m@^\+([ \t]*/?)\*@;
+ if (defined($1)) {
+ $oldindent = expand_tabs($1);
+ } else {
+ $prevrawline =~ m@^\+(.*/?)\*@;
+ $oldindent = expand_tabs($1);
+ }
+ $rawline =~ m@^\+([ \t]*)\*@;
+ my $newindent = $1;
+ $newindent = expand_tabs($newindent);
+ if (length($oldindent) ne length($newindent)) {
+ WARN("BLOCK_COMMENT_STYLE",
+ "Block comments should align the * on each line\n" . $hereprev);
+ }
+ }
+
# check for missing blank lines after struct/union declarations
# with exceptions for various attributes and macros
if ($prevline =~ /^[\+ ]};?\s*$/ &&
@@ -3570,15 +3662,6 @@ sub process {
}
}
-# check for uses of DEFINE_PCI_DEVICE_TABLE
- if ($line =~ /\bDEFINE_PCI_DEVICE_TABLE\s*\(\s*(\w+)\s*\)\s*=/) {
- if (WARN("DEFINE_PCI_DEVICE_TABLE",
- "Prefer struct pci_device_id over deprecated DEFINE_PCI_DEVICE_TABLE\n" . $herecurr) &&
- $fix) {
- $fixed[$fixlinenr] =~ s/\b(?:static\s+|)DEFINE_PCI_DEVICE_TABLE\s*\(\s*(\w+)\s*\)\s*=\s*/static const struct pci_device_id $1\[\] = /;
- }
- }
-
# check for new typedefs, only function parameters and sparse annotations
# make sense.
if ($line =~ /\btypedef\s/ &&
@@ -4674,7 +4757,17 @@ sub process {
$has_flow_statement = 1 if ($ctx =~ /\b(goto|return)\b/);
$has_arg_concat = 1 if ($ctx =~ /\#\#/ && $ctx !~ /\#\#\s*(?:__VA_ARGS__|args)\b/);
- $dstat =~ s/^.\s*\#\s*define\s+$Ident(?:\([^\)]*\))?\s*//;
+ $dstat =~ s/^.\s*\#\s*define\s+$Ident(\([^\)]*\))?\s*//;
+ my $define_args = $1;
+ my $define_stmt = $dstat;
+ my @def_args = ();
+
+ if (defined $define_args && $define_args ne "") {
+ $define_args = substr($define_args, 1, length($define_args) - 2);
+ $define_args =~ s/\s*//g;
+ @def_args = split(",", $define_args);
+ }
+
$dstat =~ s/$;//g;
$dstat =~ s/\\\n.//g;
$dstat =~ s/^\s*//s;
@@ -4710,6 +4803,15 @@ sub process {
^\[
}x;
#print "REST<$rest> dstat<$dstat> ctx<$ctx>\n";
+
+ $ctx =~ s/\n*$//;
+ my $herectx = $here . "\n";
+ my $stmt_cnt = statement_rawlines($ctx);
+
+ for (my $n = 0; $n < $stmt_cnt; $n++) {
+ $herectx .= raw_line($linenr, $n) . "\n";
+ }
+
if ($dstat ne '' &&
$dstat !~ /^(?:$Ident|-?$Constant),$/ && # 10, // foo(),
$dstat !~ /^(?:$Ident|-?$Constant);$/ && # foo();
@@ -4725,13 +4827,6 @@ sub process {
$dstat !~ /^\(\{/ && # ({...
$ctx !~ /^.\s*#\s*define\s+TRACE_(?:SYSTEM|INCLUDE_FILE|INCLUDE_PATH)\b/)
{
- $ctx =~ s/\n*$//;
- my $herectx = $here . "\n";
- my $cnt = statement_rawlines($ctx);
-
- for (my $n = 0; $n < $cnt; $n++) {
- $herectx .= raw_line($linenr, $n) . "\n";
- }
if ($dstat =~ /;/) {
ERROR("MULTISTATEMENT_MACRO_USE_DO_WHILE",
@@ -4740,6 +4835,46 @@ sub process {
ERROR("COMPLEX_MACRO",
"Macros with complex values should be enclosed in parentheses\n" . "$herectx");
}
+
+ }
+
+ # Make $define_stmt single line, comment-free, etc
+ my @stmt_array = split('\n', $define_stmt);
+ my $first = 1;
+ $define_stmt = "";
+ foreach my $l (@stmt_array) {
+ $l =~ s/\\$//;
+ if ($first) {
+ $define_stmt = $l;
+ $first = 0;
+ } elsif ($l =~ /^[\+ ]/) {
+ $define_stmt .= substr($l, 1);
+ }
+ }
+ $define_stmt =~ s/$;//g;
+ $define_stmt =~ s/\s+/ /g;
+ $define_stmt = trim($define_stmt);
+
+# check if any macro arguments are reused (ignore '...' and 'type')
+ foreach my $arg (@def_args) {
+ next if ($arg =~ /\.\.\./);
+ next if ($arg =~ /^type$/i);
+ my $tmp = $define_stmt;
+ $tmp =~ s/\b(typeof|__typeof__|__builtin\w+|typecheck\s*\(\s*$Type\s*,|\#+)\s*\(*\s*$arg\s*\)*\b//g;
+ $tmp =~ s/\#+\s*$arg\b//g;
+ $tmp =~ s/\b$arg\s*\#\#//g;
+ my $use_cnt = $tmp =~ s/\b$arg\b//g;
+ if ($use_cnt > 1) {
+ CHK("MACRO_ARG_REUSE",
+ "Macro argument reuse '$arg' - possible side-effects?\n" . "$herectx");
+ }
+# check if any macro arguments may have other precedence issues
+ if ($define_stmt =~ m/($Operators)?\s*\b$arg\b\s*($Operators)?/m &&
+ ((defined($1) && $1 ne ',') ||
+ (defined($2) && $2 ne ','))) {
+ CHK("MACRO_ARG_PRECEDENCE",
+ "Macro argument '$arg' may be better as '($arg)' to avoid precedence issues\n" . "$herectx");
+ }
}
# check for macros with flow control, but without ## concatenation
@@ -5504,46 +5639,46 @@ sub process {
}
# Check for memcpy(foo, bar, ETH_ALEN) that could be ether_addr_copy(foo, bar)
- if ($^V && $^V ge 5.10.0 &&
- defined $stat &&
- $stat =~ /^\+(?:.*?)\bmemcpy\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*\,\s*ETH_ALEN\s*\)/) {
- if (WARN("PREFER_ETHER_ADDR_COPY",
- "Prefer ether_addr_copy() over memcpy() if the Ethernet addresses are __aligned(2)\n" . "$here\n$stat\n") &&
- $fix) {
- $fixed[$fixlinenr] =~ s/\bmemcpy\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*\,\s*ETH_ALEN\s*\)/ether_addr_copy($2, $7)/;
- }
- }
+# if ($^V && $^V ge 5.10.0 &&
+# defined $stat &&
+# $stat =~ /^\+(?:.*?)\bmemcpy\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*\,\s*ETH_ALEN\s*\)/) {
+# if (WARN("PREFER_ETHER_ADDR_COPY",
+# "Prefer ether_addr_copy() over memcpy() if the Ethernet addresses are __aligned(2)\n" . "$here\n$stat\n") &&
+# $fix) {
+# $fixed[$fixlinenr] =~ s/\bmemcpy\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*\,\s*ETH_ALEN\s*\)/ether_addr_copy($2, $7)/;
+# }
+# }
# Check for memcmp(foo, bar, ETH_ALEN) that could be ether_addr_equal*(foo, bar)
- if ($^V && $^V ge 5.10.0 &&
- defined $stat &&
- $stat =~ /^\+(?:.*?)\bmemcmp\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*\,\s*ETH_ALEN\s*\)/) {
- WARN("PREFER_ETHER_ADDR_EQUAL",
- "Prefer ether_addr_equal() or ether_addr_equal_unaligned() over memcmp()\n" . "$here\n$stat\n")
- }
+# if ($^V && $^V ge 5.10.0 &&
+# defined $stat &&
+# $stat =~ /^\+(?:.*?)\bmemcmp\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*\,\s*ETH_ALEN\s*\)/) {
+# WARN("PREFER_ETHER_ADDR_EQUAL",
+# "Prefer ether_addr_equal() or ether_addr_equal_unaligned() over memcmp()\n" . "$here\n$stat\n")
+# }
# check for memset(foo, 0x0, ETH_ALEN) that could be eth_zero_addr
# check for memset(foo, 0xFF, ETH_ALEN) that could be eth_broadcast_addr
- if ($^V && $^V ge 5.10.0 &&
- defined $stat &&
- $stat =~ /^\+(?:.*?)\bmemset\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*\,\s*ETH_ALEN\s*\)/) {
-
- my $ms_val = $7;
-
- if ($ms_val =~ /^(?:0x|)0+$/i) {
- if (WARN("PREFER_ETH_ZERO_ADDR",
- "Prefer eth_zero_addr over memset()\n" . "$here\n$stat\n") &&
- $fix) {
- $fixed[$fixlinenr] =~ s/\bmemset\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*,\s*ETH_ALEN\s*\)/eth_zero_addr($2)/;
- }
- } elsif ($ms_val =~ /^(?:0xff|255)$/i) {
- if (WARN("PREFER_ETH_BROADCAST_ADDR",
- "Prefer eth_broadcast_addr() over memset()\n" . "$here\n$stat\n") &&
- $fix) {
- $fixed[$fixlinenr] =~ s/\bmemset\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*,\s*ETH_ALEN\s*\)/eth_broadcast_addr($2)/;
- }
- }
- }
+# if ($^V && $^V ge 5.10.0 &&
+# defined $stat &&
+# $stat =~ /^\+(?:.*?)\bmemset\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*\,\s*ETH_ALEN\s*\)/) {
+#
+# my $ms_val = $7;
+#
+# if ($ms_val =~ /^(?:0x|)0+$/i) {
+# if (WARN("PREFER_ETH_ZERO_ADDR",
+# "Prefer eth_zero_addr over memset()\n" . "$here\n$stat\n") &&
+# $fix) {
+# $fixed[$fixlinenr] =~ s/\bmemset\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*,\s*ETH_ALEN\s*\)/eth_zero_addr($2)/;
+# }
+# } elsif ($ms_val =~ /^(?:0xff|255)$/i) {
+# if (WARN("PREFER_ETH_BROADCAST_ADDR",
+# "Prefer eth_broadcast_addr() over memset()\n" . "$here\n$stat\n") &&
+# $fix) {
+# $fixed[$fixlinenr] =~ s/\bmemset\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*,\s*ETH_ALEN\s*\)/eth_broadcast_addr($2)/;
+# }
+# }
+# }
# typecasts on min/max could be min_t/max_t
if ($^V && $^V ge 5.10.0 &&
@@ -5663,6 +5798,19 @@ sub process {
"externs should be avoided in .c files\n" . $herecurr);
}
+ if ($realfile =~ /\.[ch]$/ && defined $stat &&
+ $stat =~ /^.\s*(?:extern\s+)?$Type\s*$Ident\s*\(\s*([^{]+)\s*\)\s*;/s &&
+ $1 ne "void") {
+ my $args = trim($1);
+ while ($args =~ m/\s*($Type\s*(?:$Ident|\(\s*\*\s*$Ident?\s*\)\s*$balanced_parens)?)/g) {
+ my $arg = trim($1);
+ if ($arg =~ /^$Type$/ && $arg !~ /enum\s+$Ident$/) {
+ WARN("FUNCTION_ARGUMENTS",
+ "function definition argument '$arg' should also have an identifier name\n" . $herecurr);
+ }
+ }
+ }
+
# checks for new __setup's
if ($rawline =~ /\b__setup\("([^"]*)"/) {
my $name = $1;
@@ -5862,46 +6010,6 @@ sub process {
}
# check for various structs that are normally const (ops, kgdb, device_tree)
- my $const_structs = qr{
- acpi_dock_ops|
- address_space_operations|
- backlight_ops|
- block_device_operations|
- dentry_operations|
- dev_pm_ops|
- dma_map_ops|
- extent_io_ops|
- file_lock_operations|
- file_operations|
- hv_ops|
- ide_dma_ops|
- intel_dvo_dev_ops|
- item_operations|
- iwl_ops|
- kgdb_arch|
- kgdb_io|
- kset_uevent_ops|
- lock_manager_operations|
- microcode_ops|
- mtrr_ops|
- neigh_ops|
- nlmsvc_binding|
- of_device_id|
- pci_raw_ops|
- pipe_buf_operations|
- platform_hibernation_ops|
- platform_suspend_ops|
- proto_ops|
- rpc_pipe_ops|
- seq_operations|
- snd_ac97_build_ops|
- soc_pcmcia_socket_ops|
- stacktrace_ops|
- sysfs_ops|
- tty_operations|
- uart_ops|
- usb_mon_operations|
- wd_ops}x;
if ($line !~ /\bconst\b/ &&
$line =~ /\bstruct\s+($const_structs)\b/) {
WARN("CONST_STRUCT",
@@ -5988,34 +6096,69 @@ sub process {
# Mode permission misuses where it seems decimal should be octal
# This uses a shortcut match to avoid unnecessary uses of a slow foreach loop
if ($^V && $^V ge 5.10.0 &&
+ defined $stat &&
$line =~ /$mode_perms_search/) {
foreach my $entry (@mode_permission_funcs) {
my $func = $entry->[0];
my $arg_pos = $entry->[1];
+ my $lc = $stat =~ tr@\n@@;
+ $lc = $lc + $linenr;
+ my $stat_real = raw_line($linenr, 0);
+ for (my $count = $linenr + 1; $count <= $lc; $count++) {
+ $stat_real = $stat_real . "\n" . raw_line($count, 0);
+ }
+
my $skip_args = "";
if ($arg_pos > 1) {
$arg_pos--;
$skip_args = "(?:\\s*$FuncArg\\s*,\\s*){$arg_pos,$arg_pos}";
}
- my $test = "\\b$func\\s*\\(${skip_args}([\\d]+)\\s*[,\\)]";
- if ($line =~ /$test/) {
+ my $test = "\\b$func\\s*\\(${skip_args}($FuncArg(?:\\|\\s*$FuncArg)*)\\s*[,\\)]";
+ if ($stat =~ /$test/) {
my $val = $1;
$val = $6 if ($skip_args ne "");
-
- if ($val !~ /^0$/ &&
- (($val =~ /^$Int$/ && $val !~ /^$Octal$/) ||
- length($val) ne 4)) {
+ if (($val =~ /^$Int$/ && $val !~ /^$Octal$/) ||
+ ($val =~ /^$Octal$/ && length($val) ne 4)) {
ERROR("NON_OCTAL_PERMISSIONS",
- "Use 4 digit octal (0777) not decimal permissions\n" . $herecurr);
- } elsif ($val =~ /^$Octal$/ && (oct($val) & 02)) {
+ "Use 4 digit octal (0777) not decimal permissions\n" . "$here\n" . $stat_real);
+ }
+ if ($val =~ /^$Octal$/ && (oct($val) & 02)) {
ERROR("EXPORTED_WORLD_WRITABLE",
- "Exporting writable files is usually an error. Consider more restrictive permissions.\n" . $herecurr);
+ "Exporting writable files is usually an error. Consider more restrictive permissions.\n" . "$here\n" . $stat_real);
}
}
}
}
+# check for uses of S_<PERMS> that could be octal for readability
+ if ($line =~ /\b$mode_perms_string_search\b/) {
+ my $val = "";
+ my $oval = "";
+ my $to = 0;
+ my $curpos = 0;
+ my $lastpos = 0;
+ while ($line =~ /\b(($mode_perms_string_search)\b(?:\s*\|\s*)?\s*)/g) {
+ $curpos = pos($line);
+ my $match = $2;
+ my $omatch = $1;
+ last if ($lastpos > 0 && ($curpos - length($omatch) != $lastpos));
+ $lastpos = $curpos;
+ $to |= $mode_permission_string_types{$match};
+ $val .= '\s*\|\s*' if ($val ne "");
+ $val .= $match;
+ $oval .= $omatch;
+ }
+ $oval =~ s/^\s*\|\s*//;
+ $oval =~ s/\s*\|\s*$//;
+ my $octal = sprintf("%04o", $to);
+ if (WARN("SYMBOLIC_PERMS",
+ "Symbolic permissions '$oval' are not preferred. Consider using octal permissions '$octal'.\n" . $herecurr) &&
+ $fix) {
+ $fixed[$fixlinenr] =~ s/$val/$octal/;
+ }
+ }
+
# validate content of MODULE_LICENSE against list from include/linux/module.h
if ($line =~ /\bMODULE_LICENSE\s*\(\s*($String)\s*\)/) {
my $extracted_string = get_quoted_string($line, $rawline);
diff --git a/scripts/const_structs.checkpatch b/scripts/const_structs.checkpatch
new file mode 100644
index 000000000000..ac5f1267151d
--- /dev/null
+++ b/scripts/const_structs.checkpatch
@@ -0,0 +1,64 @@
+acpi_dock_ops
+address_space_operations
+backlight_ops
+block_device_operations
+clk_ops
+comedi_lrange
+component_ops
+dentry_operations
+dev_pm_ops
+dma_map_ops
+driver_info
+drm_connector_funcs
+drm_encoder_funcs
+drm_encoder_helper_funcs
+ethtool_ops
+extent_io_ops
+file_lock_operations
+file_operations
+hv_ops
+ide_dma_ops
+ide_port_ops
+inode_operations
+intel_dvo_dev_ops
+irq_domain_ops
+item_operations
+iwl_cfg
+iwl_ops
+kgdb_arch
+kgdb_io
+kset_uevent_ops
+lock_manager_operations
+machine_desc
+microcode_ops
+mlxsw_reg_info
+mtrr_ops
+neigh_ops
+net_device_ops
+nlmsvc_binding
+nvkm_device_chip
+of_device_id
+pci_raw_ops
+pipe_buf_operations
+platform_hibernation_ops
+platform_suspend_ops
+proto_ops
+regmap_access_table
+rpc_pipe_ops
+rtc_class_ops
+sd_desc
+seq_operations
+sirfsoc_padmux
+snd_ac97_build_ops
+snd_soc_component_driver
+soc_pcmcia_socket_ops
+stacktrace_ops
+sysfs_ops
+tty_operations
+uart_ops
+usb_mon_operations
+v4l2_ctrl_ops
+v4l2_ioctl_ops
+vm_operations_struct
+wacom_features
+wd_ops
diff --git a/scripts/faddr2line b/scripts/faddr2line
new file mode 100755
index 000000000000..450b33257339
--- /dev/null
+++ b/scripts/faddr2line
@@ -0,0 +1,177 @@
+#!/bin/bash
+#
+# Translate stack dump function offsets.
+#
+# addr2line doesn't work with KASLR addresses. This works similarly to
+# addr2line, but instead takes the 'func+0x123' format as input:
+#
+# $ ./scripts/faddr2line ~/k/vmlinux meminfo_proc_show+0x5/0x568
+# meminfo_proc_show+0x5/0x568:
+# meminfo_proc_show at fs/proc/meminfo.c:27
+#
+# If the address is part of an inlined function, the full inline call chain is
+# printed:
+#
+# $ ./scripts/faddr2line ~/k/vmlinux native_write_msr+0x6/0x27
+# native_write_msr+0x6/0x27:
+# arch_static_branch at arch/x86/include/asm/msr.h:121
+# (inlined by) static_key_false at include/linux/jump_label.h:125
+# (inlined by) native_write_msr at arch/x86/include/asm/msr.h:125
+#
+# The function size after the '/' in the input is optional, but recommended.
+# It's used to help disambiguate any duplicate symbol names, which can occur
+# rarely. If the size is omitted for a duplicate symbol then it's possible for
+# multiple code sites to be printed:
+#
+# $ ./scripts/faddr2line ~/k/vmlinux raw_ioctl+0x5
+# raw_ioctl+0x5/0x20:
+# raw_ioctl at drivers/char/raw.c:122
+#
+# raw_ioctl+0x5/0xb1:
+# raw_ioctl at net/ipv4/raw.c:876
+#
+# Multiple addresses can be specified on a single command line:
+#
+# $ ./scripts/faddr2line ~/k/vmlinux type_show+0x10/45 free_reserved_area+0x90
+# type_show+0x10/0x2d:
+# type_show at drivers/video/backlight/backlight.c:213
+#
+# free_reserved_area+0x90/0x123:
+# free_reserved_area at mm/page_alloc.c:6429 (discriminator 2)
+
+
+set -o errexit
+set -o nounset
+
+command -v awk >/dev/null 2>&1 || die "awk isn't installed"
+command -v readelf >/dev/null 2>&1 || die "readelf isn't installed"
+command -v addr2line >/dev/null 2>&1 || die "addr2line isn't installed"
+
+usage() {
+ echo "usage: faddr2line <object file> <func+offset> <func+offset>..." >&2
+ exit 1
+}
+
+warn() {
+ echo "$1" >&2
+}
+
+die() {
+ echo "ERROR: $1" >&2
+ exit 1
+}
+
+# Try to figure out the source directory prefix so we can remove it from the
+# addr2line output. HACK ALERT: This assumes that start_kernel() is in
+# kernel/init.c! This only works for vmlinux. Otherwise it falls back to
+# printing the absolute path.
+find_dir_prefix() {
+ local objfile=$1
+
+ local start_kernel_addr=$(readelf -sW $objfile | awk '$8 == "start_kernel" {printf "0x%s", $2}')
+ [[ -z $start_kernel_addr ]] && return
+
+ local file_line=$(addr2line -e $objfile $start_kernel_addr)
+ [[ -z $file_line ]] && return
+
+ local prefix=${file_line%init/main.c:*}
+ if [[ -z $prefix ]] || [[ $prefix = $file_line ]]; then
+ return
+ fi
+
+ DIR_PREFIX=$prefix
+ return 0
+}
+
+__faddr2line() {
+ local objfile=$1
+ local func_addr=$2
+ local dir_prefix=$3
+ local print_warnings=$4
+
+ local func=${func_addr%+*}
+ local offset=${func_addr#*+}
+ offset=${offset%/*}
+ local size=
+ [[ $func_addr =~ "/" ]] && size=${func_addr#*/}
+
+ if [[ -z $func ]] || [[ -z $offset ]] || [[ $func = $func_addr ]]; then
+ warn "bad func+offset $func_addr"
+ DONE=1
+ return
+ fi
+
+ # Go through each of the object's symbols which match the func name.
+ # In rare cases there might be duplicates.
+ while read symbol; do
+ local fields=($symbol)
+ local sym_base=0x${fields[1]}
+ local sym_size=${fields[2]}
+ local sym_type=${fields[3]}
+
+ # calculate the address
+ local addr=$(($sym_base + $offset))
+ if [[ -z $addr ]] || [[ $addr = 0 ]]; then
+ warn "bad address: $sym_base + $offset"
+ DONE=1
+ return
+ fi
+ local hexaddr=0x$(printf %x $addr)
+
+ # weed out non-function symbols
+ if [[ $sym_type != "FUNC" ]]; then
+ [[ $print_warnings = 1 ]] &&
+ echo "skipping $func address at $hexaddr due to non-function symbol"
+ continue
+ fi
+
+ # if the user provided a size, make sure it matches the symbol's size
+ if [[ -n $size ]] && [[ $size -ne $sym_size ]]; then
+ [[ $print_warnings = 1 ]] &&
+ echo "skipping $func address at $hexaddr due to size mismatch ($size != $sym_size)"
+ continue;
+ fi
+
+ # make sure the provided offset is within the symbol's range
+ if [[ $offset -gt $sym_size ]]; then
+ [[ $print_warnings = 1 ]] &&
+ echo "skipping $func address at $hexaddr due to size mismatch ($offset > $sym_size)"
+ continue
+ fi
+
+ # separate multiple entries with a blank line
+ [[ $FIRST = 0 ]] && echo
+ FIRST=0
+
+ local hexsize=0x$(printf %x $sym_size)
+ echo "$func+$offset/$hexsize:"
+ addr2line -fpie $objfile $hexaddr | sed "s; $dir_prefix\(\./\)*; ;"
+ DONE=1
+
+ done < <(readelf -sW $objfile | awk -v f=$func '$8 == f {print}')
+}
+
+[[ $# -lt 2 ]] && usage
+
+objfile=$1
+[[ ! -f $objfile ]] && die "can't find objfile $objfile"
+shift
+
+DIR_PREFIX=supercalifragilisticexpialidocious
+find_dir_prefix $objfile
+
+FIRST=1
+while [[ $# -gt 0 ]]; do
+ func_addr=$1
+ shift
+
+ # print any matches found
+ DONE=0
+ __faddr2line $objfile $func_addr $DIR_PREFIX 0
+
+ # if no match was found, print warnings
+ if [[ $DONE = 0 ]]; then
+ __faddr2line $objfile $func_addr $DIR_PREFIX 1
+ warn "no match for $func_addr"
+ fi
+done
diff --git a/scripts/gcc-plugin.sh b/scripts/gcc-plugin.sh
index fb9207565471..b65224bfb847 100755
--- a/scripts/gcc-plugin.sh
+++ b/scripts/gcc-plugin.sh
@@ -1,5 +1,12 @@
#!/bin/sh
srctree=$(dirname "$0")
+
+SHOW_ERROR=
+if [ "$1" = "--show-error" ] ; then
+ SHOW_ERROR=1
+ shift || true
+fi
+
gccplugins_dir=$($3 -print-file-name=plugin)
plugincc=$($1 -E -x c++ - -o /dev/null -I"${srctree}"/gcc-plugins -I"${gccplugins_dir}"/include 2>&1 <<EOF
#include "gcc-common.h"
@@ -13,6 +20,9 @@ EOF
if [ $? -ne 0 ]
then
+ if [ -n "$SHOW_ERROR" ] ; then
+ echo "${plugincc}" >&2
+ fi
exit 1
fi
@@ -48,4 +58,8 @@ then
echo "$2"
exit 0
fi
+
+if [ -n "$SHOW_ERROR" ] ; then
+ echo "${plugincc}" >&2
+fi
exit 1
diff --git a/scripts/gcc-plugins/Makefile b/scripts/gcc-plugins/Makefile
index 88c8ec47232b..8b29dc17c73c 100644
--- a/scripts/gcc-plugins/Makefile
+++ b/scripts/gcc-plugins/Makefile
@@ -12,16 +12,18 @@ else
export HOST_EXTRACXXFLAGS
endif
-export GCCPLUGINS_DIR HOSTLIBS
-
ifneq ($(CFLAGS_KCOV), $(SANCOV_PLUGIN))
GCC_PLUGIN := $(filter-out $(SANCOV_PLUGIN), $(GCC_PLUGIN))
endif
-$(HOSTLIBS)-y := $(GCC_PLUGIN)
+export HOSTLIBS
+
+$(HOSTLIBS)-y := $(foreach p,$(GCC_PLUGIN),$(if $(findstring /,$(p)),,$(p)))
always := $($(HOSTLIBS)-y)
-cyc_complexity_plugin-objs := cyc_complexity_plugin.o
-sancov_plugin-objs := sancov_plugin.o
+$(foreach p,$($(HOSTLIBS)-y:%.so=%),$(eval $(p)-objs := $(p).o))
+
+subdir-y := $(GCC_PLUGIN_SUBDIR)
+subdir- += $(GCC_PLUGIN_SUBDIR)
clean-files += *.so
diff --git a/scripts/get_maintainer.pl b/scripts/get_maintainer.pl
index 122fcdaf42c8..aed4511f0304 100755
--- a/scripts/get_maintainer.pl
+++ b/scripts/get_maintainer.pl
@@ -432,7 +432,7 @@ foreach my $file (@ARGV) {
die "$P: file '${file}' not found\n";
}
}
- if ($from_filename || vcs_file_exists($file)) {
+ if ($from_filename || ($file ne "&STDIN" && vcs_file_exists($file))) {
$file =~ s/^\Q${cur_path}\E//; #strip any absolute path
$file =~ s/^\Q${lk_path}\E//; #or the path to the lk tree
push(@files, $file);
@@ -2136,9 +2136,11 @@ sub vcs_file_exists {
my $cmd = $VCS_cmds{"file_exists_cmd"};
$cmd =~ s/(\$\w+)/$1/eeg; # interpolate $cmd
-
+ $cmd .= " 2>&1";
$exists = &{$VCS_cmds{"execute_cmd"}}($cmd);
+ return 0 if ($? != 0);
+
return $exists;
}
diff --git a/scripts/kernel-doc b/scripts/kernel-doc
index 4f2e9049e8fa..93721f3c91bf 100755
--- a/scripts/kernel-doc
+++ b/scripts/kernel-doc
@@ -212,6 +212,7 @@ my $anon_struct_union = 0;
my $type_constant = '\%([-_\w]+)';
my $type_func = '(\w+)\(\)';
my $type_param = '\@(\w+)';
+my $type_fp_param = '\@(\w+)\(\)'; # Special RST handling for func ptr params
my $type_struct = '\&((struct\s*)*[_\w]+)';
my $type_struct_xml = '\\&amp;((struct\s*)*[_\w]+)';
my $type_env = '(\$\w+)';
@@ -292,6 +293,7 @@ my @highlights_rst = (
# Note: need to escape () to avoid func matching later
[$type_member_func, "\\:c\\:type\\:`\$1\$2\\\\(\\\\) <\$1>`"],
[$type_member, "\\:c\\:type\\:`\$1\$2 <\$1>`"],
+ [$type_fp_param, "**\$1\\\\(\\\\)**"],
[$type_func, "\\:c\\:func\\:`\$1()`"],
[$type_struct_full, "\\:c\\:type\\:`\$1 \$2 <\$2>`"],
[$type_enum_full, "\\:c\\:type\\:`\$1 \$2 <\$2>`"],
@@ -412,7 +414,7 @@ my $doc_com_body = '\s*\* ?';
my $doc_decl = $doc_com . '(\w+)';
# @params and a strictly limited set of supported section names
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*$';
@@ -1831,13 +1833,22 @@ sub output_function_rst(%) {
my %args = %{$_[0]};
my ($parameter, $section);
my $oldprefix = $lineprefix;
- my $start;
-
- print ".. c:function:: ";
+ my $start = "";
+
+ if ($args{'typedef'}) {
+ print ".. c:type:: ". $args{'function'} . "\n\n";
+ print_lineno($declaration_start_line);
+ print " **Typedef**: ";
+ $lineprefix = "";
+ output_highlight_rst($args{'purpose'});
+ $start = "\n\n**Syntax**\n\n ``";
+ } else {
+ print ".. c:function:: ";
+ }
if ($args{'functiontype'} ne "") {
- $start = $args{'functiontype'} . " " . $args{'function'} . " (";
+ $start .= $args{'functiontype'} . " " . $args{'function'} . " (";
} else {
- $start = $args{'function'} . " (";
+ $start .= $args{'function'} . " (";
}
print $start;
@@ -1849,9 +1860,6 @@ sub output_function_rst(%) {
$count++;
$type = $args{'parametertypes'}{$parameter};
- # RST doesn't like address_space tags at function prototypes
- $type =~ s/__(user|kernel|iomem|percpu|pmem|rcu)\s*//;
-
if ($type =~ m/([^\(]*\(\*)\s*\)\s*\(([^\)]*)\)/) {
# pointer-to-function
print $1 . $parameter . ") (" . $2;
@@ -1859,11 +1867,15 @@ sub output_function_rst(%) {
print $type . " " . $parameter;
}
}
- print ")\n\n";
- print_lineno($declaration_start_line);
- $lineprefix = " ";
- output_highlight_rst($args{'purpose'});
- print "\n";
+ if ($args{'typedef'}) {
+ print ");``\n\n";
+ } else {
+ print ")\n\n";
+ print_lineno($declaration_start_line);
+ $lineprefix = " ";
+ output_highlight_rst($args{'purpose'});
+ print "\n";
+ }
print "**Parameters**\n\n";
$lineprefix = " ";
@@ -2003,7 +2015,7 @@ sub output_struct_rst(%) {
($args{'parameterdescs'}{$parameter_name} ne $undescribed) || next;
$type = $args{'parametertypes'}{$parameter};
print_lineno($parameterdesc_start_lines{$parameter_name});
- print "``$type $parameter``\n";
+ print "``" . $parameter . "``\n";
output_highlight_rst($args{'parameterdescs'}{$parameter_name});
print "\n";
}
@@ -2193,7 +2205,9 @@ sub dump_typedef($$) {
$x =~ s@/\*.*?\*/@@gos; # strip comments.
# Parse function prototypes
- if ($x =~ /typedef\s+(\w+)\s*\(\*\s*(\w\S+)\s*\)\s*\((.*)\);/) {
+ if ($x =~ /typedef\s+(\w+)\s*\(\*\s*(\w\S+)\s*\)\s*\((.*)\);/ ||
+ $x =~ /typedef\s+(\w+)\s*(\w\S+)\s*\s*\((.*)\);/) {
+
# Function typedefs
$return_type = $1;
$declaration_name = $2;
@@ -2204,6 +2218,7 @@ sub dump_typedef($$) {
output_declaration($declaration_name,
'function',
{'function' => $declaration_name,
+ 'typedef' => 1,
'module' => $modulename,
'functiontype' => $return_type,
'parameterlist' => \@parameterlist,
@@ -2338,6 +2353,7 @@ sub push_parameter($$$) {
if ($type eq "" && $param =~ /\.\.\.$/)
{
+ $param = "...";
if (!defined $parameterdescs{$param} || $parameterdescs{$param} eq "") {
$parameterdescs{$param} = "variable arguments";
}
diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c
index 48958d3cec9e..bd8349759095 100644
--- a/scripts/mod/modpost.c
+++ b/scripts/mod/modpost.c
@@ -888,7 +888,7 @@ static void check_section(const char *modname, struct elf_info *elf,
#define DATA_SECTIONS ".data", ".data.rel"
#define TEXT_SECTIONS ".text", ".text.unlikely", ".sched.text", \
- ".kprobes.text"
+ ".kprobes.text", ".cpuidle.text"
#define OTHER_TEXT_SECTIONS ".ref.text", ".head.text", ".spinlock.text", \
".fixup", ".entry.text", ".exception.text", ".text.*", \
".coldtext"
diff --git a/scripts/package/builddeb b/scripts/package/builddeb
index e1c09e2f9be7..8ea9fd2b6573 100755
--- a/scripts/package/builddeb
+++ b/scripts/package/builddeb
@@ -332,7 +332,9 @@ if grep -q '^CONFIG_STACK_VALIDATION=y' $KCONFIG_CONFIG ; then
(cd $objtree; find tools/objtool -type f -executable) >> "$objtree/debian/hdrobjfiles"
fi
(cd $objtree; find arch/$SRCARCH/include Module.symvers include scripts -type f) >> "$objtree/debian/hdrobjfiles"
-(cd $objtree; find scripts/gcc-plugins -name \*.so -o -name gcc-common.h) >> "$objtree/debian/hdrobjfiles"
+if grep -q '^CONFIG_GCC_PLUGINS=y' $KCONFIG_CONFIG ; then
+ (cd $objtree; find scripts/gcc-plugins -name \*.so -o -name gcc-common.h) >> "$objtree/debian/hdrobjfiles"
+fi
destdir=$kernel_headers_dir/usr/src/linux-headers-$version
mkdir -p "$destdir"
(cd $srctree; tar -c -f - -T -) < "$objtree/debian/hdrsrcfiles" | (cd $destdir; tar -xf -)
diff --git a/scripts/recordmcount.c b/scripts/recordmcount.c
index 42396a74405d..5423a58d1b06 100644
--- a/scripts/recordmcount.c
+++ b/scripts/recordmcount.c
@@ -363,7 +363,9 @@ is_mcounted_section_name(char const *const txtname)
strcmp(".sched.text", txtname) == 0 ||
strcmp(".spinlock.text", txtname) == 0 ||
strcmp(".irqentry.text", txtname) == 0 ||
+ strcmp(".softirqentry.text", txtname) == 0 ||
strcmp(".kprobes.text", txtname) == 0 ||
+ strcmp(".cpuidle.text", txtname) == 0 ||
strcmp(".text.unlikely", txtname) == 0;
}
diff --git a/scripts/recordmcount.pl b/scripts/recordmcount.pl
index 96e2486a6fc4..faac4b10d8ea 100755
--- a/scripts/recordmcount.pl
+++ b/scripts/recordmcount.pl
@@ -134,7 +134,9 @@ my %text_sections = (
".sched.text" => 1,
".spinlock.text" => 1,
".irqentry.text" => 1,
+ ".softirqentry.text" => 1,
".kprobes.text" => 1,
+ ".cpuidle.text" => 1,
".text.unlikely" => 1,
);
diff --git a/scripts/spelling.txt b/scripts/spelling.txt
index fa79c6d2a5b8..163c720d3f2b 100644
--- a/scripts/spelling.txt
+++ b/scripts/spelling.txt
@@ -629,7 +629,6 @@ mispelt||misspelt
miximum||maximum
mmnemonic||mnemonic
mnay||many
-modeled||modelled
modulues||modules
monochorome||monochrome
monochromo||monochrome
diff --git a/scripts/tags.sh b/scripts/tags.sh
index ed7eef24ef89..a2ff3388e5ea 100755
--- a/scripts/tags.sh
+++ b/scripts/tags.sh
@@ -206,7 +206,6 @@ regex_c=(
'/\<DEFINE_PER_CPU_SHARED_ALIGNED([^,]*, *\([[:alnum:]_]*\)/\1/v/'
'/\<DECLARE_WAIT_QUEUE_HEAD(\([[:alnum:]_]*\)/\1/v/'
'/\<DECLARE_\(TASKLET\|WORK\|DELAYED_WORK\)(\([[:alnum:]_]*\)/\2/v/'
- '/\<DEFINE_PCI_DEVICE_TABLE(\([[:alnum:]_]*\)/\1/v/'
'/\(^\s\)OFFSET(\([[:alnum:]_]*\)/\2/v/'
'/\(^\s\)DEFINE(\([[:alnum:]_]*\)/\2/v/'
'/\<DEFINE_HASHTABLE(\([[:alnum:]_]*\)/\1/v/'
@@ -264,7 +263,8 @@ exuberant()
-I EXPORT_SYMBOL,EXPORT_SYMBOL_GPL,ACPI_EXPORT_SYMBOL \
-I DEFINE_TRACE,EXPORT_TRACEPOINT_SYMBOL,EXPORT_TRACEPOINT_SYMBOL_GPL \
-I static,const \
- --extra=+f --c-kinds=+px --langmap=c:+.h "${regex[@]}"
+ --extra=+fq --c-kinds=+px --fields=+iaS --langmap=c:+.h \
+ "${regex[@]}"
setup_regex exuberant kconfig
all_kconfigs | xargs $1 -a \
diff --git a/scripts/tracing/ftrace-bisect.sh b/scripts/tracing/ftrace-bisect.sh
new file mode 100755
index 000000000000..9ff8ac5fc53c
--- /dev/null
+++ b/scripts/tracing/ftrace-bisect.sh
@@ -0,0 +1,115 @@
+#!/bin/bash
+#
+# Here's how to use this:
+#
+# This script is used to help find functions that are being traced by function
+# tracer or function graph tracing that causes the machine to reboot, hang, or
+# crash. Here's the steps to take.
+#
+# First, determine if function tracing is working with a single function:
+#
+# (note, if this is a problem with function_graph tracing, then simply
+# replace "function" with "function_graph" in the following steps).
+#
+# # cd /sys/kernel/debug/tracing
+# # echo schedule > set_ftrace_filter
+# # echo function > current_tracer
+#
+# If this works, then we know that something is being traced that shouldn't be.
+#
+# # echo nop > current_tracer
+#
+# # cat available_filter_functions > ~/full-file
+# # ftrace-bisect ~/full-file ~/test-file ~/non-test-file
+# # cat ~/test-file > set_ftrace_filter
+#
+# *** Note *** this will take several minutes. Setting multiple functions is
+# an O(n^2) operation, and we are dealing with thousands of functions. So go
+# have coffee, talk with your coworkers, read facebook. And eventually, this
+# operation will end.
+#
+# # echo function > current_tracer
+#
+# If it crashes, we know that ~/test-file has a bad function.
+#
+# Reboot back to test kernel.
+#
+# # cd /sys/kernel/debug/tracing
+# # mv ~/test-file ~/full-file
+#
+# If it didn't crash.
+#
+# # echo nop > current_tracer
+# # mv ~/non-test-file ~/full-file
+#
+# Get rid of the other test file from previous run (or save them off somewhere).
+# # rm -f ~/test-file ~/non-test-file
+#
+# And start again:
+#
+# # ftrace-bisect ~/full-file ~/test-file ~/non-test-file
+#
+# The good thing is, because this cuts the number of functions in ~/test-file
+# by half, the cat of it into set_ftrace_filter takes half as long each
+# iteration, so don't talk so much at the water cooler the second time.
+#
+# Eventually, if you did this correctly, you will get down to the problem
+# function, and all we need to do is to notrace it.
+#
+# The way to figure out if the problem function is bad, just do:
+#
+# # echo <problem-function> > set_ftrace_notrace
+# # echo > set_ftrace_filter
+# # echo function > current_tracer
+#
+# And if it doesn't crash, we are done.
+#
+# If it does crash, do this again (there's more than one problem function)
+# but you need to echo the problem function(s) into set_ftrace_notrace before
+# enabling function tracing in the above steps. Or if you can compile the
+# kernel, annotate the problem functions with "notrace" and start again.
+#
+
+
+if [ $# -ne 3 ]; then
+ echo 'usage: ftrace-bisect full-file test-file non-test-file'
+ exit
+fi
+
+full=$1
+test=$2
+nontest=$3
+
+x=`cat $full | wc -l`
+if [ $x -eq 1 ]; then
+ echo "There's only one function left, must be the bad one"
+ cat $full
+ exit 0
+fi
+
+let x=$x/2
+let y=$x+1
+
+if [ ! -f $full ]; then
+ echo "$full does not exist"
+ exit 1
+fi
+
+if [ -f $test ]; then
+ echo -n "$test exists, delete it? [y/N]"
+ read a
+ if [ "$a" != "y" -a "$a" != "Y" ]; then
+ exit 1
+ fi
+fi
+
+if [ -f $nontest ]; then
+ echo -n "$nontest exists, delete it? [y/N]"
+ read a
+ if [ "$a" != "y" -a "$a" != "Y" ]; then
+ exit 1
+ fi
+fi
+
+sed -ne "1,${x}p" $full > $test
+sed -ne "$y,\$p" $full > $nontest
diff --git a/scripts/ver_linux b/scripts/ver_linux
index 0d8bd29b1bd6..430b201f3e25 100755
--- a/scripts/ver_linux
+++ b/scripts/ver_linux
@@ -1,193 +1,89 @@
-#!/bin/sh
+#!/bin/awk -f
# Before running this script please ensure that your PATH is
# typical as you use for compilation/installation. I use
# /bin /sbin /usr/bin /usr/sbin /usr/local/bin, but it may
# differ on your system.
-#
-echo 'If some fields are empty or look unusual you may have an old version.'
-echo 'Compare to the current minimal requirements in Documentation/Changes.'
-echo ' '
-uname -a
-echo ' '
-
-gcc -dumpversion 2>&1 |
-awk '/[0-9]+([.]?[0-9]+)+/ && !/not found$/{
- match($0, /[0-9]+([.]?[0-9]+)+/)
- printf("GNU C\t\t\t%s\n",
- substr($0,RSTART,RLENGTH))
-}'
-
-make --version 2>&1 |
-awk '/GNU Make/{
- match($0, /[0-9]+([.]?[0-9]+)+/)
- printf("GNU Make\t\t%s\n",
- substr($0,RSTART,RLENGTH))
-}'
-
-ld -v 2>&1 |
-awk '/[0-9]+([.]?[0-9]+)+/ && !/not found$/{
- match($0, /[0-9]+([.]?[0-9]+)+/)
- printf("Binutils\t\t%s\n",
- substr($0,RSTART,RLENGTH))
-}'
-
-mount --version 2>&1 |
-awk '/[0-9]+([.]?[0-9]+)+/ && !/not found$/{
- match($0, /[0-9]+([.]?[0-9]+)+/)
- $0 = substr($0,RSTART,RLENGTH)
- printf("Util-linux\t\t%s\nMount\t\t\t%s\n",$0,$0)
-}'
-
-depmod -V 2>&1 |
-awk '/[0-9]+([.]?[0-9]+)+/ && !/not found$/{
- match($0, /[0-9]+([.]?[0-9]+)+/)
- printf("Module-init-tools\t%s\n",
- substr($0,RSTART,RLENGTH))
-}'
-
-tune2fs 2>&1 |
-awk '/^tune2fs/{
- match($0, /[0-9]+([.]?[0-9]+)+/)
- printf("E2fsprogs\t\t%s\n",
- substr($0,RSTART,RLENGTH))
-}'
-
-fsck.jfs -V 2>&1 |
-awk '/version/{
- match($0, /[0-9]+([.]?[0-9]+)+/)
- printf("Jfsutils\t\t%s\n",
- substr($0,RSTART,RLENGTH))
-}'
-
-reiserfsck -V 2>&1 |
-awk '/^reiserfsck/{
- match($0, /[0-9]+([.]?[0-9]+)+/)
- printf("Reiserfsprogs\t\t%s\n",
- substr($0,RSTART,RLENGTH))
-}'
-
-fsck.reiser4 -V 2>&1 | grep ^fsck.reiser4 | awk \
-'NR==1{print "reiser4progs ", $2}'
-
-xfs_db -V 2>&1 |
-awk '/version/{
- match($0, /[0-9]+([.]?[0-9]+)+/)
- printf("Xfsprogs\t\t%s\n",
- substr($0,RSTART,RLENGTH))
-}'
-
-pccardctl -V 2>&1 |
-awk '/pcmciautils/{
- match($0, /[0-9]+([.]?[0-9]+)+/)
- printf("Pcmciautils\t\t%s\n",
- substr($0,RSTART,RLENGTH))
-}'
-
-cardmgr -V 2>&1| grep version | awk \
-'NR==1{print "pcmcia-cs ", $3}'
-
-quota -V 2>&1 |
-awk '/version/{
- match($0, /[0-9]+([.]?[0-9]+)+/)
- printf("Quota-tools\t\t%s\n",
- substr($0,RSTART,RLENGTH))
-}'
-
-pppd --version 2>&1 |
-awk '/version/{
- match($0, /[0-9]+([.]?[0-9]+)+/)
- printf("PPP\t\t\t%s\n",
- substr($0,RSTART,RLENGTH))
-}'
-
-isdnctrl 2>&1 | grep version | awk \
-'NR==1{print "isdn4k-utils ", $NF}'
-
-showmount --version 2>&1 | grep nfs-utils | awk \
-'NR==1{print "nfs-utils ", $NF}'
-
-test -r /proc/self/maps &&
-sed '
- /.*libc-\(.*\)\.so$/!d
- s//Linux C Library\t\t\1/
- q
-' /proc/self/maps
-
-ldd --version 2>&1 |
-awk '/^ldd/{
- match($0, /[0-9]+([.]?[0-9]+)+/)
- printf("Dynamic linker (ldd)\t%s\n",
- substr($0,RSTART,RLENGTH))
-}'
-
-libcpp=`ldconfig -p 2>/dev/null |
- awk '/(libg|stdc)[+]+\.so/ {
- print $NF
- exit
+BEGIN {
+ usage = "If some fields are empty or look unusual you may have an old version.\n"
+ usage = usage "Compare to the current minimal requirements in Documentation/Changes.\n"
+ print usage
+
+ system("uname -a")
+ printf("\n")
+
+ printversion("GNU C", version("gcc -dumpversion 2>&1"))
+ printversion("GNU Make", version("make --version 2>&1"))
+ printversion("Binutils", version("ld -v 2>&1"))
+ printversion("Util-linux", version("mount --version 2>&1"))
+ printversion("Mount", version("mount --version 2>&1"))
+ printversion("Module-init-tools", version("depmod -V 2>&1"))
+ printversion("E2fsprogs", version("tune2fs 2>&1"))
+ printversion("Jfsutils", version("fsck.jfs -V 2>&1"))
+ printversion("Reiserfsprogs", version("reiserfsck -V 2>&1"))
+ printversion("Reiser4fsprogs", version("fsck.reiser4 -V 2>&1"))
+ printversion("Xfsprogs", version("xfs_db -V 2>&1"))
+ printversion("Pcmciautils", version("pccardctl -V 2>&1"))
+ printversion("Pcmcia-cs", version("cardmgr -V 2>&1"))
+ printversion("Quota-tools", version("quota -V 2>&1"))
+ printversion("PPP", version("pppd --version 2>&1"))
+ printversion("Isdn4k-utils", version("isdnctrl 2>&1"))
+ printversion("Nfs-utils", version("showmount --version 2>&1"))
+
+ if (system("test -r /proc/self/maps") == 0) {
+ while (getline <"/proc/self/maps" > 0) {
+ n = split($0, procmaps, "/")
+ if (/libc.*so$/ && match(procmaps[n], /[0-9]+([.]?[0-9]+)+/)) {
+ ver = substr(procmaps[n], RSTART, RLENGTH)
+ printversion("Linux C Library", ver)
+ break
+ }
+ }
}
-'`
-test -r "$libcpp" &&
-ls -l $libcpp |
-sed '
- s!.*so\.!!
- s!^!Linux C++ Library\t!
-'
-ps --version 2>&1 |
-awk '/version/{
- match($0, /[0-9]+([.]?[0-9]+)+/)
- printf("Procps\t\t\t%s\n",
- substr($0,RSTART,RLENGTH))
-}'
-
-ifconfig --version 2>&1 |
-awk '/tools/{
- match($0, /[0-9]+([.]?[0-9]+)+/)
- printf("Net-tools\t\t%s\n",
- substr($0,RSTART,RLENGTH))
-}'
-
-loadkeys -V 2>&1 |
-awk '/[0-9]+([.]?[0-9]+)+/ && !/not found$/{
- match($0, /[0-9]+([.]?[0-9]+)+/)
- $0 = substr($0,RSTART,RLENGTH)
- printf("Kbd\t\t\t%s\nConsole-tools\t\t%s\n",$0,$0)
-}'
-oprofiled --version 2>&1 | awk \
-'(NR==1 && ($2 == "oprofile")) {print "oprofile ", $3}'
+ printversion("Dynamic linker (ldd)", version("ldd --version 2>&1"))
-expr --v 2>&1 |
-awk '/^expr/{
- match($0, /[0-9]+([.]?[0-9]+)+/)
- printf("Sh-utils\t\t%s\n",
- substr($0,RSTART,RLENGTH))
-}'
-
-udevadm --version 2>&1 |
-awk '/[0-9]+([.]?[0-9]+)+/ && !/not found$/{
- match($0, /[0-9]+([.]?[0-9]+)+/)
- printf("Udev\t\t\t%s\n",
- substr($0,RSTART,RLENGTH))
-}'
+ while ("ldconfig -p 2>/dev/null" | getline > 0) {
+ if (/(libg|stdc)[+]+\.so/) {
+ libcpp = $NF
+ break
+ }
+ }
+ if (system("test -r " libcpp) == 0)
+ printversion("Linux C++ Library", version("readlink " libcpp))
+
+ printversion("Procps", version("ps --version 2>&1"))
+ printversion("Net-tools", version("ifconfig --version 2>&1"))
+ printversion("Kbd", version("loadkeys -V 2>&1"))
+ printversion("Console-tools", version("loadkeys -V 2>&1"))
+ printversion("Oprofile", version("oprofiled --version 2>&1"))
+ printversion("Sh-utils", version("expr --v 2>&1"))
+ printversion("Udev", version("udevadm --version 2>&1"))
+ printversion("Wireless-tools", version("iwconfig --version 2>&1"))
+
+ if (system("test -r /proc/modules") == 0) {
+ while ("sort /proc/modules" | getline > 0) {
+ mods = mods sep $1
+ sep = " "
+ }
+ printversion("Modules Loaded", mods)
+ }
+}
-iwconfig --version 2>&1 |
-awk '/version/{
- match($0, /[0-9]+([.]?[0-9]+)+/)
- printf("Wireless-tools\t\t%s\n",
- substr($0,RSTART,RLENGTH))
-}'
+function version(cmd, ver) {
+ while (cmd | getline > 0) {
+ if (!/ver_linux/ && match($0, /[0-9]+([.]?[0-9]+)+/)) {
+ ver = substr($0, RSTART, RLENGTH)
+ break
+ }
+ }
+ close(cmd)
+ return ver
+}
-test -e /proc/modules &&
-sort /proc/modules |
-sed '
- s/ .*//
- H
-${
- g
- s/^\n/Modules Loaded\t\t/
- y/\n/ /
- q
+function printversion(name, value, ofmt) {
+ if (value != "") {
+ ofmt = "%-20s\t%s\n"
+ printf(ofmt, name, value)
+ }
}
- d
-'