summaryrefslogtreecommitdiff
path: root/scripts
diff options
context:
space:
mode:
Diffstat (limited to 'scripts')
-rw-r--r--scripts/Makefile.asm-generic17
-rw-r--r--scripts/Makefile.build5
-rw-r--r--scripts/Makefile.dtbo24
-rw-r--r--scripts/Makefile.headersinst103
-rw-r--r--scripts/Makefile.lib26
-rw-r--r--scripts/Makefile.ubsan17
-rwxr-xr-xscripts/build-all.py427
-rw-r--r--scripts/check-config-debug-exemptions58
-rw-r--r--scripts/check-config-perf-exemptions61
-rwxr-xr-xscripts/check-config.py147
-rwxr-xr-xscripts/checkpatch.pl292
-rwxr-xr-xscripts/clang-android.sh4
-rw-r--r--scripts/dtc/Makefile2
-rw-r--r--scripts/dtc/libfdt/fdt.c14
-rw-r--r--scripts/dtc/libfdt/fdt_rw.c2
-rwxr-xr-xscripts/gen_compile_commands.py151
-rwxr-xr-xscripts/mkcompile_h2
-rwxr-xr-xscripts/setlocalversion23
-rw-r--r--scripts/sortextable.c1
-rwxr-xr-xscripts/tags.sh222
20 files changed, 1417 insertions, 181 deletions
diff --git a/scripts/Makefile.asm-generic b/scripts/Makefile.asm-generic
index 045e0098e962..95f7d8090152 100644
--- a/scripts/Makefile.asm-generic
+++ b/scripts/Makefile.asm-generic
@@ -13,11 +13,26 @@ include scripts/Kbuild.include
# Create output directory if not already present
_dummy := $(shell [ -d $(obj) ] || mkdir -p $(obj))
+# Stale wrappers when the corresponding files are removed from generic-y
+# need removing.
+generated-y := $(generic-y) $(generated-y)
+all-files := $(patsubst %, $(obj)/%, $(generated-y))
+old-headers := $(wildcard $(obj)/*.h)
+unwanted := $(filter-out $(all-files),$(old-headers))
+
quiet_cmd_wrap = WRAP $@
cmd_wrap = echo "\#include <asm-generic/$*.h>" >$@
-all: $(patsubst %, $(obj)/%, $(generic-y))
+quiet_cmd_remove = REMOVE $(unwanted)
+cmd_remove = rm -f $(unwanted)
+
+all: $(patsubst %, $(obj)/%, $(generic-y)) FORCE
+ $(if $(unwanted),$(call cmd,remove),)
@:
$(obj)/%.h:
$(call cmd,wrap)
+
+PHONY += FORCE
+.PHONY: $(PHONY)
+FORCE: ;
diff --git a/scripts/Makefile.build b/scripts/Makefile.build
index 42aef001dfdd..e6441514be23 100644
--- a/scripts/Makefile.build
+++ b/scripts/Makefile.build
@@ -64,6 +64,11 @@ ifneq ($(hostprogs-y)$(hostprogs-m),)
include scripts/Makefile.host
endif
+# Do not include host rules unless needed
+ifneq ($(dtbo-y),)
+include scripts/Makefile.dtbo
+endif
+
ifneq ($(KBUILD_SRC),)
# Create output directory if not already present
_dummy := $(shell [ -d $(obj) ] || mkdir -p $(obj))
diff --git a/scripts/Makefile.dtbo b/scripts/Makefile.dtbo
new file mode 100644
index 000000000000..db4a0f4b9a56
--- /dev/null
+++ b/scripts/Makefile.dtbo
@@ -0,0 +1,24 @@
+__dtbo := $(sort $(dtbo-y))
+
+dtbo-base := $(sort $(foreach m,$(__dtbo),$($(m)-base)))
+dtbo := $(foreach m,$(__dtbo),$(if $($(m)-base),$(m)))
+
+__dtbo := $(addprefix $(obj)/,$(__dtbo))
+dtbo-base := $(addprefix $(obj)/,$(dtbo-base))
+dtbo := $(addprefix $(obj)/,$(dtbo))
+
+ifneq ($(DTC_OVERLAY_TEST_EXT),)
+DTC_OVERLAY_TEST = $(DTC_OVERLAY_TEST_EXT)
+quiet_cmd_dtbo_verify = VERIFY $@
+cmd_dtbo_verify = $(DTC_OVERLAY_TEST) $(addprefix $(obj)/,$($(@F)-base)) $@ $(dot-target).dtb
+else
+cmd_dtbo_verify = true
+endif
+
+$(obj)/%.dtbo: $(src)/%.dts FORCE
+ $(call if_changed_dep,dtc)
+ $(call if_changed,dtbo_verify)
+
+$(call multi_depend, $(dtbo), , -base)
+
+always += $(dtbo)
diff --git a/scripts/Makefile.headersinst b/scripts/Makefile.headersinst
index 1106d6ca3a38..82abf5a09e5d 100644
--- a/scripts/Makefile.headersinst
+++ b/scripts/Makefile.headersinst
@@ -1,33 +1,56 @@
# ==========================================================================
# Installing headers
#
-# header-y - list files to be installed. They are preprocessed
-# to remove __KERNEL__ section of the file
-# genhdr-y - Same as header-y but in a generated/ directory
+# All headers under include/uapi, include/generated/uapi,
+# arch/<arch>/include/uapi and arch/<arch>/include/generated/uapi are
+# exported.
+# They are preprocessed to remove __KERNEL__ section of the file.
#
# ==========================================================================
+PHONY := __headers
+__headers:
+
+include scripts/Kbuild.include
+
+srcdir := $(srctree)/$(obj)
+subdirs := $(patsubst $(srcdir)/%/.,%,$(wildcard $(srcdir)/*/.))
+# caller may set destination dir (when installing to asm/)
+_dst := $(if $(dst),$(dst),$(obj))
+
+# Recursion
+__headers: $(subdirs)
+
+.PHONY: $(subdirs)
+$(subdirs):
+ $(Q)$(MAKE) $(hdr-inst)=$(obj)/$@ dst=$(_dst)/$@
+
+# Skip header install/check for include/uapi and arch/$(hdr-arch)/include/uapi.
+# We have only sub-directories there.
+skip-inst := $(if $(filter %/uapi,$(obj)),1)
+
+ifeq ($(skip-inst),)
+
# generated header directory
gen := $(if $(gen),$(gen),$(subst include/,include/generated/,$(obj)))
+# Kbuild file is optional
kbuild-file := $(srctree)/$(obj)/Kbuild
-include $(kbuild-file)
-
-# called may set destination dir (when installing to asm/)
-_dst := $(if $(destination-y),$(destination-y),$(if $(dst),$(dst),$(obj)))
+-include $(kbuild-file)
old-kbuild-file := $(srctree)/$(subst uapi/,,$(obj))/Kbuild
ifneq ($(wildcard $(old-kbuild-file)),)
include $(old-kbuild-file)
endif
-include scripts/Kbuild.include
-
installdir := $(INSTALL_HDR_PATH)/$(subst uapi/,,$(_dst))
-header-y := $(sort $(header-y))
-subdirs := $(patsubst %/,%,$(filter %/, $(header-y)))
-header-y := $(filter-out %/, $(header-y))
+gendir := $(objtree)/$(gen)
+header-files := $(notdir $(wildcard $(srcdir)/*.h))
+header-files += $(notdir $(wildcard $(srcdir)/*.agh))
+header-files := $(filter-out $(no-export-headers), $(header-files))
+genhdr-files := $(notdir $(wildcard $(gendir)/*.h))
+genhdr-files := $(filter-out $(header-files), $(genhdr-files))
# files used to track state of install/check
install-file := $(installdir)/.install
@@ -35,36 +58,22 @@ check-file := $(installdir)/.check
# generic-y list all files an architecture uses from asm-generic
# Use this to build a list of headers which require a wrapper
-wrapper-files := $(filter $(header-y), $(generic-y))
-
-srcdir := $(srctree)/$(obj)
-gendir := $(objtree)/$(gen)
+generic-files := $(notdir $(wildcard $(srctree)/include/uapi/asm-generic/*.h))
+wrapper-files := $(filter $(generic-files), $(generic-y))
+wrapper-files := $(filter-out $(header-files), $(wrapper-files))
oldsrcdir := $(srctree)/$(subst /uapi,,$(obj))
# all headers files for this dir
-header-y := $(filter-out $(generic-y), $(header-y))
-all-files := $(header-y) $(genhdr-y) $(wrapper-files)
+all-files := $(header-files) $(genhdr-files) $(wrapper-files)
output-files := $(addprefix $(installdir)/, $(all-files))
-input-files1 := $(foreach hdr, $(header-y), \
- $(if $(wildcard $(srcdir)/$(hdr)), \
- $(wildcard $(srcdir)/$(hdr))) \
- )
-input-files1-name := $(notdir $(input-files1))
-input-files2 := $(foreach hdr, $(header-y), \
- $(if $(wildcard $(srcdir)/$(hdr)),, \
- $(if $(wildcard $(oldsrcdir)/$(hdr)), \
- $(wildcard $(oldsrcdir)/$(hdr)), \
- $(error Missing UAPI file $(srcdir)/$(hdr))) \
- ))
-input-files2-name := $(notdir $(input-files2))
-input-files3 := $(foreach hdr, $(genhdr-y), \
- $(if $(wildcard $(gendir)/$(hdr)), \
- $(wildcard $(gendir)/$(hdr)), \
- $(error Missing generated UAPI file $(gendir)/$(hdr)) \
- ))
-input-files3-name := $(notdir $(input-files3))
+ifneq ($(mandatory-y),)
+missing := $(filter-out $(all-files),$(mandatory-y))
+ifneq ($(missing),)
+$(error Some mandatory headers ($(missing)) are missing in $(obj))
+endif
+endif
# Work out what needs to be removed
oldheaders := $(patsubst $(installdir)/%,%,$(wildcard $(installdir)/*.h))
@@ -78,9 +87,8 @@ printdir = $(patsubst $(INSTALL_HDR_PATH)/%/,%,$(dir $@))
quiet_cmd_install = INSTALL $(printdir) ($(words $(all-files))\
file$(if $(word 2, $(all-files)),s))
cmd_install = \
- $(CONFIG_SHELL) $< $(installdir) $(srcdir) $(input-files1-name); \
- $(CONFIG_SHELL) $< $(installdir) $(oldsrcdir) $(input-files2-name); \
- $(CONFIG_SHELL) $< $(installdir) $(gendir) $(input-files3-name); \
+ $(CONFIG_SHELL) $< $(installdir) $(srcdir) $(header-files); \
+ $(CONFIG_SHELL) $< $(installdir) $(gendir) $(genhdr-files); \
for F in $(wrapper-files); do \
echo "\#include <asm-generic/$$F>" > $(installdir)/$$F; \
done; \
@@ -98,21 +106,21 @@ quiet_cmd_check = CHECK $(printdir) ($(words $(all-files)) files)
$(PERL) $< $(INSTALL_HDR_PATH)/include $(SRCARCH); \
touch $@
-PHONY += __headersinst __headerscheck
-
ifndef HDRCHECK
# Rules for installing headers
-__headersinst: $(subdirs) $(install-file)
+__headers: $(install-file)
@:
targets += $(install-file)
-$(install-file): scripts/headers_install.sh $(input-files1) $(input-files2) $(input-files3) FORCE
+$(install-file): scripts/headers_install.sh \
+ $(addprefix $(srcdir)/,$(header-files)) \
+ $(addprefix $(gendir)/,$(genhdr-files)) FORCE
$(if $(unwanted),$(call cmd,remove),)
$(if $(wildcard $(dir $@)),,$(shell mkdir -p $(dir $@)))
$(call if_changed,install)
else
-__headerscheck: $(subdirs) $(check-file)
+__headers: $(check-file)
@:
targets += $(check-file)
@@ -121,11 +129,6 @@ $(check-file): scripts/headers_check.pl $(output-files) FORCE
endif
-# Recursion
-.PHONY: $(subdirs)
-$(subdirs):
- $(Q)$(MAKE) $(hdr-inst)=$(obj)/$@ dst=$(_dst)/$@
-
targets := $(wildcard $(sort $(targets)))
cmd_files := $(wildcard \
$(foreach f,$(targets),$(dir $(f)).$(notdir $(f)).cmd))
@@ -134,6 +137,8 @@ ifneq ($(cmd_files),)
include $(cmd_files)
endif
+endif # skip-inst
+
.PHONY: $(PHONY)
PHONY += FORCE
FORCE: ;
diff --git a/scripts/Makefile.lib b/scripts/Makefile.lib
index 434a0b8e3c97..5a93712ea570 100644
--- a/scripts/Makefile.lib
+++ b/scripts/Makefile.lib
@@ -129,6 +129,12 @@ _c_flags += $(if $(patsubst n%,, \
$(CFLAGS_KASAN), $(CFLAGS_KASAN_NOSANITIZE))
endif
+ifeq ($(CONFIG_UBSAN),y)
+_c_flags += $(if $(patsubst n%,, \
+ $(UBSAN_SANITIZE_$(basetarget).o)$(UBSAN_SANITIZE)$(CONFIG_UBSAN_SANITIZE_ALL)), \
+ $(CFLAGS_UBSAN))
+endif
+
ifeq ($(CONFIG_KCOV),y)
_c_flags += $(if $(patsubst n%,, \
$(KCOV_INSTRUMENT_$(basetarget).o)$(KCOV_INSTRUMENT)y), \
@@ -292,10 +298,16 @@ cmd_dt_S_dtb= \
$(obj)/%.dtb.S: $(obj)/%.dtb
$(call cmd,dt_S_dtb)
+ifneq ($(DTC_EXT),)
+DTC = $(DTC_EXT)
+else
+DTC = $(objtree)/scripts/dtc/dtc
+endif
+
quiet_cmd_dtc = DTC $@
cmd_dtc = mkdir -p $(dir ${dtc-tmp}) ; \
$(CPP) $(dtc_cpp_flags) -x assembler-with-cpp -o $(dtc-tmp) $< ; \
- $(objtree)/scripts/dtc/dtc -O dtb -o $@ -b 0 \
+ $(DTC) -O dtb -o $@ -b 0 \
-i $(dir $<) $(DTC_FLAGS) \
-d $(depfile).dtc.tmp $(dtc-tmp) ; \
cat $(depfile).pre.tmp $(depfile).dtc.tmp > $(depfile)
@@ -305,6 +317,18 @@ $(obj)/%.dtb: $(src)/%.dts FORCE
dtc-tmp = $(subst $(comma),_,$(dot-target).dts.tmp)
+# Helper targets for Installing DTBs into the boot directory
+quiet_cmd_dtb_install = INSTALL $<
+ cmd_dtb_install = cp $< $(2)
+
+_dtbinst_pre_:
+ $(Q)if [ -d $(INSTALL_DTBS_PATH).old ]; then rm -rf $(INSTALL_DTBS_PATH).old; fi
+ $(Q)if [ -d $(INSTALL_DTBS_PATH) ]; then mv $(INSTALL_DTBS_PATH) $(INSTALL_DTBS_PATH).old; fi
+ $(Q)mkdir -p $(INSTALL_DTBS_PATH)
+
+%.dtb_dtbinst_: $(obj)/%.dtb _dtbinst_pre_
+ $(call cmd,dtb_install,$(INSTALL_DTBS_PATH))
+
# cat
# ---------------------------------------------------------------------------
# Concatentate multiple files together
diff --git a/scripts/Makefile.ubsan b/scripts/Makefile.ubsan
new file mode 100644
index 000000000000..8ab68679cfb5
--- /dev/null
+++ b/scripts/Makefile.ubsan
@@ -0,0 +1,17 @@
+ifdef CONFIG_UBSAN
+ CFLAGS_UBSAN += $(call cc-option, -fsanitize=shift)
+ CFLAGS_UBSAN += $(call cc-option, -fsanitize=integer-divide-by-zero)
+ CFLAGS_UBSAN += $(call cc-option, -fsanitize=unreachable)
+ CFLAGS_UBSAN += $(call cc-option, -fsanitize=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)
+ CFLAGS_UBSAN += $(call cc-option, -fsanitize=returns-nonnull-attribute)
+ CFLAGS_UBSAN += $(call cc-option, -fsanitize=bool)
+ CFLAGS_UBSAN += $(call cc-option, -fsanitize=enum)
+
+ifdef CONFIG_UBSAN_ALIGNMENT
+ CFLAGS_UBSAN += $(call cc-option, -fsanitize=alignment)
+endif
+endif
diff --git a/scripts/build-all.py b/scripts/build-all.py
new file mode 100755
index 000000000000..4f02c33d4248
--- /dev/null
+++ b/scripts/build-all.py
@@ -0,0 +1,427 @@
+#! /usr/bin/env python2
+
+# Copyright (c) 2009-2015, The Linux Foundation. All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are met:
+# * Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# * Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+# * Neither the name of The Linux Foundation nor
+# the names of its contributors may be used to endorse or promote
+# products derived from this software without specific prior written
+# permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+# NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+# Build the kernel for all targets using the Android build environment.
+
+from collections import namedtuple
+import glob
+from optparse import OptionParser
+import os
+import re
+import shutil
+import subprocess
+import sys
+import threading
+import Queue
+
+version = 'build-all.py, version 1.99'
+
+build_dir = '../all-kernels'
+make_command = ["vmlinux", "modules", "dtbs"]
+all_options = {}
+compile64 = os.environ.get('CROSS_COMPILE64')
+
+def error(msg):
+ sys.stderr.write("error: %s\n" % msg)
+
+def fail(msg):
+ """Fail with a user-printed message"""
+ error(msg)
+ sys.exit(1)
+
+if not os.environ.get('CROSS_COMPILE'):
+ fail("CROSS_COMPILE must be set in the environment")
+
+def check_kernel():
+ """Ensure that PWD is a kernel directory"""
+ if (not os.path.isfile('MAINTAINERS') or
+ not os.path.isfile('arch/arm64/configs/msm_defconfig')):
+ fail("This doesn't seem to be an MSM kernel dir")
+
+def check_build():
+ """Ensure that the build directory is present."""
+ if not os.path.isdir(build_dir):
+ try:
+ os.makedirs(build_dir)
+ except OSError as exc:
+ if exc.errno == errno.EEXIST:
+ pass
+ else:
+ raise
+
+failed_targets = []
+
+BuildResult = namedtuple('BuildResult', ['status', 'messages'])
+
+class BuildSequence(namedtuple('BuildSequence', ['log_name', 'short_name', 'steps'])):
+
+ def set_width(self, width):
+ self.width = width
+
+ def __enter__(self):
+ self.log = open(self.log_name, 'w')
+ def __exit__(self, type, value, traceback):
+ self.log.close()
+
+ def run(self):
+ self.status = None
+ messages = ["Building: " + self.short_name]
+ def printer(line):
+ text = "[%-*s] %s" % (self.width, self.short_name, line)
+ messages.append(text)
+ self.log.write(text)
+ self.log.write('\n')
+ for step in self.steps:
+ st = step.run(printer)
+ if st:
+ self.status = BuildResult(self.short_name, messages)
+ break
+ if not self.status:
+ self.status = BuildResult(None, messages)
+
+class BuildTracker:
+ """Manages all of the steps necessary to perform a build. The
+ build consists of one or more sequences of steps. The different
+ sequences can be processed independently, while the steps within a
+ sequence must be done in order."""
+
+ def __init__(self, parallel_builds):
+ self.sequence = []
+ self.lock = threading.Lock()
+ self.parallel_builds = parallel_builds
+
+ def add_sequence(self, log_name, short_name, steps):
+ self.sequence.append(BuildSequence(log_name, short_name, steps))
+
+ def longest_name(self):
+ longest = 0
+ for seq in self.sequence:
+ longest = max(longest, len(seq.short_name))
+ return longest
+
+ def __repr__(self):
+ return "BuildTracker(%s)" % self.sequence
+
+ def run_child(self, seq):
+ seq.set_width(self.longest)
+ tok = self.build_tokens.get()
+ with self.lock:
+ print "Building:", seq.short_name
+ with seq:
+ seq.run()
+ self.results.put(seq.status)
+ self.build_tokens.put(tok)
+
+ def run(self):
+ self.longest = self.longest_name()
+ self.results = Queue.Queue()
+ children = []
+ errors = []
+ self.build_tokens = Queue.Queue()
+ nthreads = self.parallel_builds
+ print "Building with", nthreads, "threads"
+ for i in range(nthreads):
+ self.build_tokens.put(True)
+ for seq in self.sequence:
+ child = threading.Thread(target=self.run_child, args=[seq])
+ children.append(child)
+ child.start()
+ for child in children:
+ stats = self.results.get()
+ if all_options.verbose:
+ with self.lock:
+ for line in stats.messages:
+ print line
+ sys.stdout.flush()
+ if stats.status:
+ errors.append(stats.status)
+ for child in children:
+ child.join()
+ if errors:
+ fail("\n ".join(["Failed targets:"] + errors))
+
+class PrintStep:
+ """A step that just prints a message"""
+ def __init__(self, message):
+ self.message = message
+
+ def run(self, outp):
+ outp(self.message)
+
+class MkdirStep:
+ """A step that makes a directory"""
+ def __init__(self, direc):
+ self.direc = direc
+
+ def run(self, outp):
+ outp("mkdir %s" % self.direc)
+ os.mkdir(self.direc)
+
+class RmtreeStep:
+ def __init__(self, direc):
+ self.direc = direc
+
+ def run(self, outp):
+ outp("rmtree %s" % self.direc)
+ shutil.rmtree(self.direc, ignore_errors=True)
+
+class CopyfileStep:
+ def __init__(self, src, dest):
+ self.src = src
+ self.dest = dest
+
+ def run(self, outp):
+ outp("cp %s %s" % (self.src, self.dest))
+ shutil.copyfile(self.src, self.dest)
+
+class ExecStep:
+ def __init__(self, cmd, **kwargs):
+ self.cmd = cmd
+ self.kwargs = kwargs
+
+ def run(self, outp):
+ outp("exec: %s" % (" ".join(self.cmd),))
+ with open('/dev/null', 'r') as devnull:
+ proc = subprocess.Popen(self.cmd, stdin=devnull,
+ stdout=subprocess.PIPE,
+ stderr=subprocess.STDOUT,
+ **self.kwargs)
+ stdout = proc.stdout
+ while True:
+ line = stdout.readline()
+ if not line:
+ break
+ line = line.rstrip('\n')
+ outp(line)
+ result = proc.wait()
+ if result != 0:
+ return ('error', result)
+ else:
+ return None
+
+class Builder():
+
+ def __init__(self, name, defconfig):
+ self.name = name
+ self.defconfig = defconfig
+
+ self.confname = self.defconfig.split('/')[-1]
+
+ # Determine if this is a 64-bit target based on the location
+ # of the defconfig.
+ self.make_env = os.environ.copy()
+ if "/arm64/" in defconfig:
+ if compile64:
+ self.make_env['CROSS_COMPILE'] = compile64
+ else:
+ fail("Attempting to build 64-bit, without setting CROSS_COMPILE64")
+ self.make_env['ARCH'] = 'arm64'
+ else:
+ self.make_env['ARCH'] = 'arm'
+ self.make_env['KCONFIG_NOTIMESTAMP'] = 'true'
+ self.log_name = "%s/log-%s.log" % (build_dir, self.name)
+
+ def build(self):
+ steps = []
+ dest_dir = os.path.join(build_dir, self.name)
+ log_name = "%s/log-%s.log" % (build_dir, self.name)
+ steps.append(PrintStep('Building %s in %s log %s' %
+ (self.name, dest_dir, log_name)))
+ if not os.path.isdir(dest_dir):
+ steps.append(MkdirStep(dest_dir))
+ defconfig = self.defconfig
+ dotconfig = '%s/.config' % dest_dir
+ savedefconfig = '%s/defconfig' % dest_dir
+
+ staging_dir = 'install_staging'
+ modi_dir = '%s' % staging_dir
+ hdri_dir = '%s/usr' % staging_dir
+ steps.append(RmtreeStep(os.path.join(dest_dir, staging_dir)))
+
+ steps.append(ExecStep(['make', 'O=%s' % dest_dir,
+ self.confname], env=self.make_env))
+
+ if not all_options.updateconfigs:
+ # Build targets can be dependent upon the completion of
+ # previous build targets, so build them one at a time.
+ cmd_line = ['make',
+ 'INSTALL_HDR_PATH=%s' % hdri_dir,
+ 'INSTALL_MOD_PATH=%s' % modi_dir,
+ 'O=%s' % dest_dir]
+ build_targets = []
+ for c in make_command:
+ if re.match(r'^-{1,2}\w', c):
+ cmd_line.append(c)
+ else:
+ build_targets.append(c)
+ for t in build_targets:
+ steps.append(ExecStep(cmd_line + [t], env=self.make_env))
+
+ # Copy the defconfig back.
+ if all_options.configs or all_options.updateconfigs:
+ steps.append(ExecStep(['make', 'O=%s' % dest_dir,
+ 'savedefconfig'], env=self.make_env))
+ steps.append(CopyfileStep(savedefconfig, defconfig))
+
+ return steps
+
+def update_config(file, str):
+ print 'Updating %s with \'%s\'\n' % (file, str)
+ with open(file, 'a') as defconfig:
+ defconfig.write(str + '\n')
+
+def scan_configs():
+ """Get the full list of defconfigs appropriate for this tree."""
+ names = []
+ arch_pats = (
+ r'[fm]sm[0-9]*_defconfig',
+ r'apq*_defconfig',
+ r'qsd*_defconfig',
+ r'mpq*_defconfig',
+ r'sdm[0-9]*_defconfig',
+ )
+ arch64_pats = (
+ r'msm*_defconfig',
+ r'sdm[0-9]*_defconfig',
+ )
+ for p in arch_pats:
+ for n in glob.glob('arch/arm/configs/' + p):
+ name = os.path.basename(n)[:-10]
+ names.append(Builder(name, n))
+ if 'CROSS_COMPILE64' in os.environ:
+ for p in arch64_pats:
+ for n in glob.glob('arch/arm64/configs/' + p):
+ name = os.path.basename(n)[:-10] + "-64"
+ names.append(Builder(name, n))
+ return names
+
+def build_many(targets):
+ print "Building %d target(s)" % len(targets)
+
+ # To try and make up for the link phase being serial, try to do
+ # two full builds in parallel. Don't do too many because lots of
+ # parallel builds tends to use up available memory rather quickly.
+ parallel = 2
+ if all_options.jobs and all_options.jobs > 1:
+ j = max(all_options.jobs / parallel, 2)
+ make_command.append("-j" + str(j))
+
+ tracker = BuildTracker(parallel)
+ for target in targets:
+ if all_options.updateconfigs:
+ update_config(target.defconfig, all_options.updateconfigs)
+ steps = target.build()
+ tracker.add_sequence(target.log_name, target.name, steps)
+ tracker.run()
+
+def main():
+ global make_command
+
+ check_kernel()
+ check_build()
+
+ configs = scan_configs()
+
+ usage = ("""
+ %prog [options] all -- Build all targets
+ %prog [options] target target ... -- List specific targets
+ %prog [options] perf -- Build all perf targets
+ %prog [options] noperf -- Build all non-perf targets""")
+ parser = OptionParser(usage=usage, version=version)
+ parser.add_option('--configs', action='store_true',
+ dest='configs',
+ help="Copy configs back into tree")
+ parser.add_option('--list', action='store_true',
+ dest='list',
+ help='List available targets')
+ parser.add_option('-v', '--verbose', action='store_true',
+ dest='verbose',
+ help='Output to stdout in addition to log file')
+ parser.add_option('--oldconfig', action='store_true',
+ dest='oldconfig',
+ help='Only process "make oldconfig"')
+ parser.add_option('--updateconfigs',
+ dest='updateconfigs',
+ help="Update defconfigs with provided option setting, "
+ "e.g. --updateconfigs=\'CONFIG_USE_THING=y\'")
+ parser.add_option('-j', '--jobs', type='int', dest="jobs",
+ help="Number of simultaneous jobs")
+ parser.add_option('-l', '--load-average', type='int',
+ dest='load_average',
+ help="Don't start multiple jobs unless load is below LOAD_AVERAGE")
+ parser.add_option('-k', '--keep-going', action='store_true',
+ dest='keep_going', default=False,
+ help="Keep building other targets if a target fails")
+ parser.add_option('-m', '--make-target', action='append',
+ help='Build the indicated make target (default: %s)' %
+ ' '.join(make_command))
+
+ (options, args) = parser.parse_args()
+ global all_options
+ all_options = options
+
+ if options.list:
+ print "Available targets:"
+ for target in configs:
+ print " %s" % target.name
+ sys.exit(0)
+
+ if options.oldconfig:
+ make_command = ["oldconfig"]
+ elif options.make_target:
+ make_command = options.make_target
+
+ if args == ['all']:
+ build_many(configs)
+ elif args == ['perf']:
+ targets = []
+ for t in configs:
+ if "perf" in t.name:
+ targets.append(t)
+ build_many(targets)
+ elif args == ['noperf']:
+ targets = []
+ for t in configs:
+ if "perf" not in t.name:
+ targets.append(t)
+ build_many(targets)
+ elif len(args) > 0:
+ all_configs = {}
+ for t in configs:
+ all_configs[t.name] = t
+ targets = []
+ for t in args:
+ if t not in all_configs:
+ parser.error("Target '%s' not one of %s" % (t, all_configs.keys()))
+ targets.append(all_configs[t])
+ build_many(targets)
+ else:
+ parser.error("Must specify a target to build, or 'all'")
+
+if __name__ == "__main__":
+ main()
diff --git a/scripts/check-config-debug-exemptions b/scripts/check-config-debug-exemptions
new file mode 100644
index 000000000000..331a924e3612
--- /dev/null
+++ b/scripts/check-config-debug-exemptions
@@ -0,0 +1,58 @@
+CP15_BARRIER_EMULATION
+DEVKMEM
+DEVMEM
+HID_A4TECH
+HID_ACRUX
+HID_BELKIN
+HID_CHERRY
+HID_CHICONY
+HID_CYPRESS
+HID_DRAGONRISE
+HID_EMS_FF
+HID_EZKEY
+HID_GREENASIA
+HID_GYRATION
+HID_HOLTEK
+HID_KENSINGTON
+HID_KEYTOUCH
+HID_KYE
+HID_LCPOWER
+HID_LOGITECH
+HID_MONTEREY
+HID_NTRIG
+HID_ORTEK
+HID_PANTHERLORD
+HID_PETALYNX
+HID_PICOLCD
+HID_PRIMAX
+HID_PRODIKEYS
+HID_ROCCAT
+HID_SAITEK
+HID_SAMSUNG
+HID_SMARTJOYPLUS
+HID_SONY
+HID_SPEEDLINK
+HID_SUNPLUS
+HID_THRUSTMASTER
+HID_TIVO
+HID_TOPSEED
+HID_TWINHAN
+HID_UCLOGIC
+HID_WACOM
+HID_WALTOP
+HID_WIIMOTE
+HID_ZEROPLUS
+HID_ZYDACRON
+JOYSTICK_XPAD_FF
+JOYSTICK_XPAD_LEDS
+KSM
+MODULES
+PSTORE
+SETEND_EMULATION
+TABLET_USB_ACECAD
+TABLET_USB_AIPTEK
+TABLET_USB_GTCO
+TABLET_USB_HANWANG
+TABLET_USB_KBTAB
+USB_CONFIGFS
+USB_OTG_WAKELOCK
diff --git a/scripts/check-config-perf-exemptions b/scripts/check-config-perf-exemptions
new file mode 100644
index 000000000000..d499f5abeb1e
--- /dev/null
+++ b/scripts/check-config-perf-exemptions
@@ -0,0 +1,61 @@
+CGROUP_DEBUG
+CP15_BARRIER_EMULATION
+DEVKMEM
+DEVMEM
+HID_A4TECH
+HID_ACRUX
+HID_BELKIN
+HID_CHERRY
+HID_CHICONY
+HID_CYPRESS
+HID_DRAGONRISE
+HID_EMS_FF
+HID_EZKEY
+HID_GREENASIA
+HID_GYRATION
+HID_HOLTEK
+HID_KENSINGTON
+HID_KEYTOUCH
+HID_KYE
+HID_LCPOWER
+HID_LOGITECH
+HID_MONTEREY
+HID_NTRIG
+HID_ORTEK
+HID_PANTHERLORD
+HID_PETALYNX
+HID_PICOLCD
+HID_PRIMAX
+HID_PRODIKEYS
+HID_ROCCAT
+HID_SAITEK
+HID_SAMSUNG
+HID_SMARTJOYPLUS
+HID_SONY
+HID_SPEEDLINK
+HID_SUNPLUS
+HID_THRUSTMASTER
+HID_TIVO
+HID_TOPSEED
+HID_TWINHAN
+HID_UCLOGIC
+HID_WACOM
+HID_WALTOP
+HID_WIIMOTE
+HID_ZEROPLUS
+HID_ZYDACRON
+JOYSTICK_XPAD_FF
+JOYSTICK_XPAD_LEDS
+KSM
+MODULES
+PM_DEBUG
+PSTORE
+SETEND_EMULATION
+SUSPEND_TIME
+TABLET_USB_ACECAD
+TABLET_USB_AIPTEK
+TABLET_USB_GTCO
+TABLET_USB_HANWANG
+TABLET_USB_KBTAB
+USB_CONFIGFS
+USB_OTG_WAKELOCK
diff --git a/scripts/check-config.py b/scripts/check-config.py
new file mode 100755
index 000000000000..79c2bdf59759
--- /dev/null
+++ b/scripts/check-config.py
@@ -0,0 +1,147 @@
+#! /usr/bin/env python
+
+# Copyright (c) 2015, The Linux Foundation. All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are met:
+# * Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# * Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+# * Neither the name of The Linux Foundation nor
+# the names of its contributors may be used to endorse or promote
+# products derived from this software without specific prior written
+# permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+# NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+"""
+Android kernel configuration validator.
+
+The Android kernel reference trees contain some config stubs of
+configuration options that are required for Android to function
+correctly, and additional ones that are recommended.
+
+This script can help compare these base configs with the ".config"
+output of the compiler to determine if the proper configs are defined.
+"""
+
+from collections import namedtuple
+from optparse import OptionParser
+import re
+import sys
+
+version = "check-config.py, version 0.0.1"
+
+req_re = re.compile(r'''^CONFIG_(.*)=(.*)$''')
+forb_re = re.compile(r'''^# CONFIG_(.*) is not set$''')
+comment_re = re.compile(r'''^(#.*|)$''')
+
+Enabled = namedtuple('Enabled', ['name', 'value'])
+Disabled = namedtuple('Disabled', ['name'])
+
+def walk_config(name):
+ with open(name, 'r') as fd:
+ for line in fd:
+ line = line.rstrip()
+ m = req_re.match(line)
+ if m:
+ yield Enabled(m.group(1), m.group(2))
+ continue
+
+ m = forb_re.match(line)
+ if m:
+ yield Disabled(m.group(1))
+ continue
+
+ m = comment_re.match(line)
+ if m:
+ continue
+
+ print "WARNING: Unknown .config line: ", line
+
+class Checker():
+ def __init__(self):
+ self.required = {}
+ self.exempted = set()
+ self.forbidden = set()
+
+ def add_required(self, fname):
+ for ent in walk_config(fname):
+ if type(ent) is Enabled:
+ self.required[ent.name] = ent.value
+ elif type(ent) is Disabled:
+ if ent.name in self.required:
+ del self.required[ent.name]
+ self.forbidden.add(ent.name)
+
+ def add_exempted(self, fname):
+ with open(fname, 'r') as fd:
+ for line in fd:
+ line = line.rstrip()
+ self.exempted.add(line)
+
+ def check(self, path):
+ failure = False
+
+ # Don't run this for mdm targets
+ if re.search('mdm', path):
+ print "Not applicable to mdm targets... bypassing"
+ else:
+ for ent in walk_config(path):
+ # Go to the next iteration if this config is exempt
+ if ent.name in self.exempted:
+ continue
+
+ if type(ent) is Enabled:
+ if ent.name in self.forbidden:
+ print "error: Config should not be present: %s" %ent.name
+ failure = True
+
+ if ent.name in self.required and ent.value != self.required[ent.name]:
+ print "error: Config has wrong value: %s %s expecting: %s" \
+ %(ent.name, ent.value, self.required[ent.name])
+ failure = True
+
+ elif type(ent) is Disabled:
+ if ent.name in self.required:
+ print "error: Config should be present, but is disabled: %s" %ent.name
+ failure = True
+
+ if failure:
+ sys.exit(1)
+
+def main():
+ usage = """%prog [options] path/to/.config"""
+ parser = OptionParser(usage=usage, version=version)
+ parser.add_option('-r', '--required', dest="required",
+ action="append")
+ parser.add_option('-e', '--exempted', dest="exempted",
+ action="append")
+ (options, args) = parser.parse_args()
+ if len(args) != 1:
+ parser.error("Expecting a single path argument to .config")
+ elif options.required is None or options.exempted is None:
+ parser.error("Expecting a file containing required configurations")
+
+ ch = Checker()
+ for r in options.required:
+ ch.add_required(r)
+ for e in options.exempted:
+ ch.add_exempted(e)
+
+ ch.check(args[0])
+
+if __name__ == '__main__':
+ main()
diff --git a/scripts/checkpatch.pl b/scripts/checkpatch.pl
index fabdf0e5c28c..02996be239bc 100755
--- a/scripts/checkpatch.pl
+++ b/scripts/checkpatch.pl
@@ -11,6 +11,13 @@ use File::Basename;
use Cwd 'abs_path';
use Term::ANSIColor qw(:constants);
+use constant BEFORE_SHORTTEXT => 0;
+use constant IN_SHORTTEXT_BLANKLINE => 1;
+use constant IN_SHORTTEXT => 2;
+use constant AFTER_SHORTTEXT => 3;
+use constant CHECK_NEXT_SHORTTEXT => 4;
+use constant SHORTTEXT_LIMIT => 75;
+
my $P = $0;
my $D = dirname(abs_path($P));
@@ -22,6 +29,7 @@ my $quiet = 0;
my $tree = 1;
my $chk_signoff = 1;
my $chk_patch = 1;
+my $chk_author = 1;
my $tst_only;
my $emacs = 0;
my $terse = 0;
@@ -52,6 +60,8 @@ my $spelling_file = "$D/spelling.txt";
my $codespell = 0;
my $codespellfile = "/usr/share/codespell/dictionary.txt";
my $color = 1;
+my $qca_sign_off = 0;
+my $codeaurora_sign_off = 0;
sub help {
my ($exitcode) = @_;
@@ -64,6 +74,7 @@ Options:
-q, --quiet quiet
--no-tree run without a kernel tree
--no-signoff do not check for 'Signed-off-by' line
+ --no-author do not check for unexpected authors
--patch treat FILE as patchfile (default)
--emacs emacs compile window format
--terse one line per report
@@ -137,6 +148,7 @@ GetOptions(
'tree!' => \$tree,
'signoff!' => \$chk_signoff,
'patch!' => \$chk_patch,
+ 'author!' => \$chk_author,
'emacs!' => \$emacs,
'terse!' => \$terse,
'showfile!' => \$showfile,
@@ -1909,6 +1921,33 @@ sub tabify {
return "$leading";
}
+sub cleanup_continuation_headers {
+ # Collapse any header-continuation lines into a single line so they
+ # can be parsed meaningfully, as the parser only has one line
+ # of context to work with.
+ my $again;
+ do {
+ $again = 0;
+ foreach my $n (0 .. scalar(@rawlines) - 2) {
+ if ($rawlines[$n]=~/^\s*$/) {
+ # A blank line means there's no more chance
+ # of finding headers. Shortcut to done.
+ return;
+ }
+ if ($rawlines[$n]=~/^[\x21-\x39\x3b-\x7e]+:/ &&
+ $rawlines[$n+1]=~/^\s+/) {
+ # Continuation header. Collapse it.
+ my $line = splice @rawlines, $n+1, 1;
+ $line=~s/^\s+/ /;
+ $rawlines[$n] .= $line;
+ # We've 'destabilized' the list, so restart.
+ $again = 1;
+ last;
+ }
+ }
+ } while ($again);
+}
+
sub pos_last_openparen {
my ($line) = @_;
@@ -1947,6 +1986,8 @@ sub process {
my $prevrawline="";
my $stashline="";
my $stashrawline="";
+ my $subjectline="";
+ my $sublinenr="";
my $length;
my $indent;
@@ -2000,9 +2041,14 @@ sub process {
my $setup_docs = 0;
my $camelcase_file_seeded = 0;
+ my $shorttext = BEFORE_SHORTTEXT;
+ my $shorttext_exspc = 0;
+ my $commit_text_present = 0;
sanitise_line_reset();
+ cleanup_continuation_headers();
my $line;
+
foreach my $rawline (@rawlines) {
$linenr++;
$line = $rawline;
@@ -2184,13 +2230,115 @@ sub process {
}
next;
}
-
$here .= "FILE: $realfile:$realline:" if ($realcnt != 0);
my $hereline = "$here\n$rawline\n";
my $herecurr = "$here\n$rawline\n";
my $hereprev = "$here\n$prevrawline\n$rawline\n";
+ if ($shorttext != AFTER_SHORTTEXT) {
+ if ($shorttext == IN_SHORTTEXT_BLANKLINE && $line=~/\S/) {
+ # the subject line was just processed,
+ # a blank line must be next
+ WARN("NONBLANK_AFTER_SUMMARY",
+ "non-blank line after summary line\n" . $herecurr);
+ $shorttext = IN_SHORTTEXT;
+ # this non-blank line may or may not be commit text -
+ # a warning has been generated so assume it is commit
+ # text and move on
+ $commit_text_present = 1;
+ # fall through and treat this line as IN_SHORTTEXT
+ }
+ if ($shorttext == IN_SHORTTEXT) {
+ if ($line=~/^---/ || $line=~/^diff.*/) {
+ if ($commit_text_present == 0) {
+ WARN("NO_COMMIT_TEXT",
+ "please add commit text explaining " .
+ "*why* the change is needed\n" .
+ $herecurr);
+ }
+ $shorttext = AFTER_SHORTTEXT;
+ } elsif (length($line) > (SHORTTEXT_LIMIT +
+ $shorttext_exspc)
+ && $line !~ /^:([0-7]{6}\s){2}
+ ([[:xdigit:]]+\.*
+ \s){2}\w+\s\w+/xms) {
+ WARN("LONG_COMMIT_TEXT",
+ "commit text line over " .
+ SHORTTEXT_LIMIT .
+ " characters\n" . $herecurr);
+ } elsif ($line=~/^\s*change-id:/i ||
+ $line=~/^\s*signed-off-by:/i ||
+ $line=~/^\s*crs-fixed:/i ||
+ $line=~/^\s*acked-by:/i) {
+ # this is a tag, there must be commit
+ # text by now
+ if ($commit_text_present == 0) {
+ WARN("NO_COMMIT_TEXT",
+ "please add commit text explaining " .
+ "*why* the change is needed\n" .
+ $herecurr);
+ # prevent duplicate warnings
+ $commit_text_present = 1;
+ }
+ } elsif ($line=~/\S/) {
+ $commit_text_present = 1;
+ }
+ } elsif ($shorttext == IN_SHORTTEXT_BLANKLINE) {
+ # case of non-blank line in this state handled above
+ $shorttext = IN_SHORTTEXT;
+ } elsif ($shorttext == CHECK_NEXT_SHORTTEXT) {
+# The Subject line doesn't have to be the last header in the patch.
+# Avoid moving to the IN_SHORTTEXT state until clear of all headers.
+# Per RFC5322, continuation lines must be folded, so any left-justified
+# text which looks like a header is definitely a header.
+ if ($line!~/^[\x21-\x39\x3b-\x7e]+:/) {
+ $shorttext = IN_SHORTTEXT;
+ # Check for Subject line followed by a blank line.
+ if (length($line) != 0) {
+ WARN("NONBLANK_AFTER_SUMMARY",
+ "non-blank line after " .
+ "summary line\n" .
+ $sublinenr . $here .
+ "\n" . $subjectline .
+ "\n" . $line . "\n");
+ # this non-blank line may or may not
+ # be commit text - a warning has been
+ # generated so assume it is commit
+ # text and move on
+ $commit_text_present = 1;
+ }
+ }
+ # The next two cases are BEFORE_SHORTTEXT.
+ } elsif ($line=~/^Subject: \[[^\]]*\] (.*)/) {
+ # This is the subject line. Go to
+ # CHECK_NEXT_SHORTTEXT to wait for the commit
+ # text to show up.
+ $shorttext = CHECK_NEXT_SHORTTEXT;
+ $subjectline = $line;
+ $sublinenr = "#$linenr & ";
+# Check for Subject line less than line limit
+ if (length($1) > SHORTTEXT_LIMIT && !($1 =~ m/Revert\ \"/)) {
+ WARN("LONG_SUMMARY_LINE",
+ "summary line over " .
+ SHORTTEXT_LIMIT .
+ " characters\n" . $herecurr);
+ }
+ } elsif ($line=~/^ (.*)/) {
+ # Indented format, this must be the summary
+ # line (i.e. git show). There will be no more
+ # headers so we are now in the shorttext.
+ $shorttext = IN_SHORTTEXT_BLANKLINE;
+ $shorttext_exspc = 4;
+ if (length($1) > SHORTTEXT_LIMIT && !($1 =~ m/Revert\ \"/)) {
+ WARN("LONG_SUMMARY_LINE",
+ "summary line over " .
+ SHORTTEXT_LIMIT .
+ " characters\n" . $herecurr);
+ }
+ }
+ }
+
$cnt_lines++ if ($realcnt != 0);
# Check if the commit log has what seems like a diff which can confuse patch
@@ -2283,6 +2431,16 @@ sub process {
"email address '$email' might be better as '$suggested_email$comment'\n" . $herecurr);
}
}
+ if ($chk_author) {
+ if ($line =~ /^\s*signed-off-by:.*qca\.qualcomm\.com/i) {
+ $qca_sign_off = 1;
+ } elsif ($line =~ /^\s*signed-off-by:.*codeaurora\.org/i) {
+ $codeaurora_sign_off = 1;
+ } elsif ($line =~ /^\s*signed-off-by:.*(quicinc|qualcomm)\.com/i) {
+ WARN("BAD_SIGN_OFF",
+ "invalid Signed-off-by identity\n" . $line );
+ }
+ }
# Check for duplicate signatures
my $sig_nospace = $line;
@@ -2309,12 +2467,6 @@ sub process {
"The 'stable' address should be 'stable\@vger.kernel.org'\n" . $herecurr);
}
-# Check for unwanted Gerrit info
- if ($in_commit_log && $line =~ /^\s*change-id:/i) {
- ERROR("GERRIT_CHANGE_ID",
- "Remove Gerrit Change-Id's before submitting upstream.\n" . $herecurr);
- }
-
# Check if the commit log is in a possible stack dump
if ($in_commit_log && !$commit_log_possible_stack_dump &&
($line =~ /^\s*(?:WARNING:|BUG:)/ ||
@@ -2414,6 +2566,12 @@ sub process {
"added, moved or deleted file(s), does MAINTAINERS need updating?\n" . $herecurr);
}
+#check the patch for invalid author credentials
+ if ($chk_author && !($line =~ /^From:.*qca\.qualcomm\.com/) &&
+ $line =~ /^From:.*(quicinc|qualcomm)\.com/) {
+ WARN("BAD_AUTHOR", "invalid author identity\n" . $line );
+ }
+
# Check for wrappage within a valid hunk of the file
if ($realcnt != 0 && $line !~ m{^(?:\+|-| |\\ No newline|$)}) {
ERROR("CORRUPTED_PATCH",
@@ -2640,8 +2798,7 @@ sub process {
#
# if LONG_LINE is ignored, the other 2 types are also ignored
#
-
- if ($line =~ /^\+/ && $length > $max_line_length) {
+ if ($line =~ /^\+/ && $length > $max_line_length && $realfile ne "scripts/checkpatch.pl") {
my $msg_type = "LONG_LINE";
# Check the allowed long line types first
@@ -4135,7 +4292,7 @@ sub process {
# check spacing on parentheses
if ($line =~ /\(\s/ && $line !~ /\(\s*(?:\\)?$/ &&
- $line !~ /for\s*\(\s+;/) {
+ $line !~ /for\s*\(\s+;/ && $line !~ /^\+\s*[A-Z_][A-Z\d_]*\(\s*\d+(\,.*)?\)\,?$/) {
if (ERROR("SPACING",
"space prohibited after that open parenthesis '('\n" . $herecurr) &&
$fix) {
@@ -4506,7 +4663,7 @@ sub process {
if ($realfile !~ m@/vmlinux.lds.h$@ &&
$line =~ /^.\s*\#\s*define\s*$Ident(\()?/) {
my $ln = $linenr;
- my $cnt = $realcnt;
+ my $cnt = $realcnt - 1;
my ($off, $dstat, $dcond, $rest);
my $ctx = '';
my $has_flow_statement = 0;
@@ -4533,6 +4690,12 @@ sub process {
{
}
+ # Extremely long macros may fall off the end of the
+ # available context without closing. Give a dangling
+ # backslash the benefit of the doubt and allow it
+ # to gobble any hanging open-parens.
+ $dstat =~ s/\(.+\\$/1/;
+
# Flatten any obvious string concatentation.
while ($dstat =~ s/($String)\s*$Ident/$1/ ||
$dstat =~ s/$Ident\s*($String)/$1/)
@@ -4545,6 +4708,7 @@ sub process {
MODULE_PARM_DESC|
DECLARE_PER_CPU|
DEFINE_PER_CPU|
+ CLK_[A-Z\d_]+|
__typeof__\(|
union|
struct|
@@ -4895,11 +5059,94 @@ sub process {
"Avoid line continuations in quoted strings\n" . $herecurr);
}
+# sys_open/read/write/close are not allowed in the kernel
+ if ($line =~ /\b(sys_(?:open|read|write|close))\b/) {
+ ERROR("FILE_OPS",
+ "$1 is inappropriate in kernel code.\n" .
+ $herecurr);
+ }
+
+# filp_open is a backdoor for sys_open
+ if ($line =~ /\b(filp_open)\b/) {
+ ERROR("FILE_OPS",
+ "$1 is inappropriate in kernel code.\n" .
+ $herecurr);
+ }
+
+# read[bwl] & write[bwl] use too many barriers, use the _relaxed variants
+ if ($line =~ /\b((?:read|write)[bwl])\b/) {
+ ERROR("NON_RELAXED_IO",
+ "Use of $1 is deprecated: use $1_relaxed\n\t" .
+ "with appropriate memory barriers instead.\n" .
+ $herecurr);
+ }
+
+# likewise, in/out[bwl] should be __raw_read/write[bwl]...
+ if ($line =~ /\b((in|out)([bwl]))\b/) {
+ my ($all, $pref, $suf) = ($1, $2, $3);
+ $pref =~ s/in/read/;
+ $pref =~ s/out/write/;
+ ERROR("NON_RELAXED_IO",
+ "Use of $all is deprecated: use " .
+ "__raw_$pref$suf\n\t" .
+ "with appropriate memory barriers instead.\n" .
+ $herecurr);
+ }
+
+# dsb is too ARMish, and should usually be mb.
+ if ($line =~ /[^-_>*\.]\bdsb\b[^-_\.;]/) {
+ WARN("ARM_BARRIER",
+ "Use of dsb is discouranged: prefer mb.\n" .
+ $herecurr);
+ }
+
+# MSM - check if a non board-gpiomux file has any gpiomux declarations
+ if ($realfile =~ /\/mach-msm\/board-[0-9]+/ &&
+ $realfile !~ /camera/ && $realfile !~ /gpiomux/ &&
+ $line =~ /\s*struct msm_gpiomux_config\s*/ ) {
+ WARN("GPIOMUX_IN_BOARD",
+ "Non gpiomux board file cannot have a gpiomux config declarations. Please declare gpiomux configs in board-*-gpiomux.c file.\n" . $herecurr);
+ }
+
+# MSM - check if vreg_xxx function are used
+ if ($line =~ /\b(vreg_(get|put|set_level|enable|disable))\b/) {
+ WARN("DEPRECATED_VREG_APIS",
+ "Use of $1 API is deprecated: " .
+ "use regulator APIs\n" . $herecurr);
+ }
+
+# unbounded string functions are overflow risks
+ my %str_fns = (
+ "sprintf" => "snprintf",
+ "strcpy" => "strlcpy",
+ "strncpy" => "strlcpy",
+ "strcat" => "strlcat",
+ "strncat" => "strlcat",
+ "vsprintf" => "vsnprintf",
+ "strchr" => "strnchr",
+ "strstr" => "strnstr",
+ );
+ foreach my $k (keys %str_fns) {
+ if ($line =~ /\b$k\b/) {
+ ERROR("UNBOUNDED_STRING_FNS",
+ "Use of $k is deprecated: " .
+ "use $str_fns{$k} instead.\n" .
+ $herecurr);
+ }
+ }
+
# warn about #if 0
if ($line =~ /^.\s*\#\s*if\s+0\b/) {
- CHK("REDUNDANT_CODE",
- "if this code is redundant consider removing it\n" .
- $herecurr);
+ WARN("IF_0",
+ "if this code is redundant consider removing it\n"
+ . $herecurr);
+ }
+
+# warn about #if 1
+ if ($line =~ /^.\s*\#\s*if\s+1\b/) {
+ WARN("IF_1",
+ "if this code is required consider removing"
+ . " #if 1\n" . $herecurr);
}
# check for needless "if (<foo>) fn(<foo>)" uses
@@ -5089,6 +5336,12 @@ sub process {
"Comparing get_jiffies_64() is almost always wrong; prefer time_after64, time_before64 and friends\n" . $herecurr);
}
+# check the patch for use of mdelay
+ if ($line =~ /\bmdelay\s*\(/) {
+ WARN("MDELAY",
+ "use of mdelay() found: msleep() is the preferred API.\n" . $herecurr );
+ }
+
# warn about #ifdefs in C files
# if ($line =~ /^.\s*\#\s*if(|n)def/ && ($realfile =~ /\.c$/)) {
# print "#ifdef in C files should be avoided\n";
@@ -5575,6 +5828,12 @@ sub process {
"switch default: should use break\n" . $herectx);
}
+# check for return codes on error paths
+ if ($line =~ /\breturn\s+-\d+/) {
+ ERROR("NO_ERROR_CODE",
+ "illegal return value, please use an error code\n" . $herecurr);
+ }
+
# check for gcc specific __FUNCTION__
if ($line =~ /\b__FUNCTION__\b/) {
if (WARN("USE_FUNC",
@@ -5793,6 +6052,11 @@ sub process {
}
}
+ if ($chk_author && $qca_sign_off && !$codeaurora_sign_off) {
+ WARN("BAD_SIGN_OFF",
+ "QCA Signed-off-by requires CODEAURORA Signed-off-by\n" . $line );
+ }
+
# If we have no input at all, then there is nothing to report on
# so just keep quiet.
if ($#rawlines == -1) {
diff --git a/scripts/clang-android.sh b/scripts/clang-android.sh
new file mode 100755
index 000000000000..9186c4f48576
--- /dev/null
+++ b/scripts/clang-android.sh
@@ -0,0 +1,4 @@
+#!/bin/sh
+# SPDX-License-Identifier: GPL-2.0
+
+$* -dM -E - </dev/null 2>&1 | grep -q __ANDROID__ && echo "y"
diff --git a/scripts/dtc/Makefile b/scripts/dtc/Makefile
index 2a48022c41e7..2eb4aec040f4 100644
--- a/scripts/dtc/Makefile
+++ b/scripts/dtc/Makefile
@@ -1,7 +1,9 @@
# scripts/dtc makefile
hostprogs-y := dtc
+ifeq ($(DTC_EXT),)
always := $(hostprogs-y)
+endif
dtc-objs := dtc.o flattree.o fstree.o data.o livetree.o treesource.o \
srcpos.o checks.o util.o
diff --git a/scripts/dtc/libfdt/fdt.c b/scripts/dtc/libfdt/fdt.c
index 22286a1aaeaf..14fb793ed05d 100644
--- a/scripts/dtc/libfdt/fdt.c
+++ b/scripts/dtc/libfdt/fdt.c
@@ -71,6 +71,20 @@ int fdt_check_header(const void *fdt)
return -FDT_ERR_BADMAGIC;
}
+ if (fdt_off_dt_struct(fdt) > (UINT_MAX - fdt_size_dt_struct(fdt)))
+ return FDT_ERR_BADOFFSET;
+
+ if (fdt_off_dt_strings(fdt) > (UINT_MAX - fdt_size_dt_strings(fdt)))
+ return FDT_ERR_BADOFFSET;
+
+ if ((fdt_off_dt_struct(fdt) + fdt_size_dt_struct(fdt))
+ > fdt_totalsize(fdt))
+ return FDT_ERR_BADOFFSET;
+
+ if ((fdt_off_dt_strings(fdt) + fdt_size_dt_strings(fdt))
+ > fdt_totalsize(fdt))
+ return FDT_ERR_BADOFFSET;
+
return 0;
}
diff --git a/scripts/dtc/libfdt/fdt_rw.c b/scripts/dtc/libfdt/fdt_rw.c
index 2eed4f58387c..55fc93245961 100644
--- a/scripts/dtc/libfdt/fdt_rw.c
+++ b/scripts/dtc/libfdt/fdt_rw.c
@@ -392,7 +392,7 @@ int fdt_del_node(void *fdt, int nodeoffset)
static void _fdt_packblocks(const char *old, char *new,
int mem_rsv_size, int struct_size)
{
- int mem_rsv_off, struct_off, strings_off;
+ uint32_t mem_rsv_off, struct_off, strings_off;
mem_rsv_off = FDT_ALIGN(sizeof(struct fdt_header), 8);
struct_off = mem_rsv_off + mem_rsv_size;
diff --git a/scripts/gen_compile_commands.py b/scripts/gen_compile_commands.py
new file mode 100755
index 000000000000..c458696ef3a7
--- /dev/null
+++ b/scripts/gen_compile_commands.py
@@ -0,0 +1,151 @@
+#!/usr/bin/env python
+# SPDX-License-Identifier: GPL-2.0
+#
+# Copyright (C) Google LLC, 2018
+#
+# Author: Tom Roeder <tmroeder@google.com>
+#
+"""A tool for generating compile_commands.json in the Linux kernel."""
+
+import argparse
+import json
+import logging
+import os
+import re
+
+_DEFAULT_OUTPUT = 'compile_commands.json'
+_DEFAULT_LOG_LEVEL = 'WARNING'
+
+_FILENAME_PATTERN = r'^\..*\.cmd$'
+_LINE_PATTERN = r'^cmd_[^ ]*\.o := (.* )([^ ]*\.c)$'
+_VALID_LOG_LEVELS = ['DEBUG', 'INFO', 'WARNING', 'ERROR', 'CRITICAL']
+
+# A kernel build generally has over 2000 entries in its compile_commands.json
+# database. If this code finds 300 or fewer, then warn the user that they might
+# not have all the .cmd files, and they might need to compile the kernel.
+_LOW_COUNT_THRESHOLD = 300
+
+
+def parse_arguments():
+ """Sets up and parses command-line arguments.
+
+ Returns:
+ log_level: A logging level to filter log output.
+ directory: The directory to search for .cmd files.
+ output: Where to write the compile-commands JSON file.
+ """
+ usage = 'Creates a compile_commands.json database from kernel .cmd files'
+ parser = argparse.ArgumentParser(description=usage)
+
+ directory_help = ('Path to the kernel source directory to search '
+ '(defaults to the working directory)')
+ parser.add_argument('-d', '--directory', type=str, help=directory_help)
+
+ output_help = ('The location to write compile_commands.json (defaults to '
+ 'compile_commands.json in the search directory)')
+ parser.add_argument('-o', '--output', type=str, help=output_help)
+
+ log_level_help = ('The level of log messages to produce (one of ' +
+ ', '.join(_VALID_LOG_LEVELS) + '; defaults to ' +
+ _DEFAULT_LOG_LEVEL + ')')
+ parser.add_argument(
+ '--log_level', type=str, default=_DEFAULT_LOG_LEVEL,
+ help=log_level_help)
+
+ args = parser.parse_args()
+
+ log_level = args.log_level
+ if log_level not in _VALID_LOG_LEVELS:
+ raise ValueError('%s is not a valid log level' % log_level)
+
+ directory = args.directory or os.getcwd()
+ output = args.output or os.path.join(directory, _DEFAULT_OUTPUT)
+ directory = os.path.abspath(directory)
+
+ return log_level, directory, output
+
+
+def process_line(root_directory, file_directory, command_prefix, relative_path):
+ """Extracts information from a .cmd line and creates an entry from it.
+
+ Args:
+ root_directory: The directory that was searched for .cmd files. Usually
+ used directly in the "directory" entry in compile_commands.json.
+ file_directory: The path to the directory the .cmd file was found in.
+ command_prefix: The extracted command line, up to the last element.
+ relative_path: The .c file from the end of the extracted command.
+ Usually relative to root_directory, but sometimes relative to
+ file_directory and sometimes neither.
+
+ Returns:
+ An entry to append to compile_commands.
+
+ Raises:
+ ValueError: Could not find the extracted file based on relative_path and
+ root_directory or file_directory.
+ """
+ # The .cmd files are intended to be included directly by Make, so they
+ # escape the pound sign '#', either as '\#' or '$(pound)' (depending on the
+ # kernel version). The compile_commands.json file is not interepreted
+ # by Make, so this code replaces the escaped version with '#'.
+ prefix = command_prefix.replace('\#', '#').replace('$(pound)', '#')
+
+ cur_dir = root_directory
+ expected_path = os.path.join(cur_dir, relative_path)
+ if not os.path.exists(expected_path):
+ # Try using file_directory instead. Some of the tools have a different
+ # style of .cmd file than the kernel.
+ cur_dir = file_directory
+ expected_path = os.path.join(cur_dir, relative_path)
+ if not os.path.exists(expected_path):
+ raise ValueError('File %s not in %s or %s' %
+ (relative_path, root_directory, file_directory))
+ return {
+ 'directory': cur_dir,
+ 'file': relative_path,
+ 'command': prefix + relative_path,
+ }
+
+
+def main():
+ """Walks through the directory and finds and parses .cmd files."""
+ log_level, directory, output = parse_arguments()
+
+ level = getattr(logging, log_level)
+ logging.basicConfig(format='%(levelname)s: %(message)s', level=level)
+
+ filename_matcher = re.compile(_FILENAME_PATTERN)
+ line_matcher = re.compile(_LINE_PATTERN)
+
+ compile_commands = []
+ for dirpath, _, filenames in os.walk(directory):
+ for filename in filenames:
+ if not filename_matcher.match(filename):
+ continue
+ filepath = os.path.join(dirpath, filename)
+
+ with open(filepath, 'rt') as f:
+ for line in f:
+ result = line_matcher.match(line)
+ if not result:
+ continue
+
+ try:
+ entry = process_line(directory, dirpath,
+ result.group(1), result.group(2))
+ compile_commands.append(entry)
+ except ValueError as err:
+ logging.info('Could not add line from %s: %s',
+ filepath, err)
+
+ with open(output, 'wt') as f:
+ json.dump(compile_commands, f, indent=2, sort_keys=True)
+
+ count = len(compile_commands)
+ if count < _LOW_COUNT_THRESHOLD:
+ logging.warning(
+ 'Found %s entries. Have you compiled the kernel?', count)
+
+
+if __name__ == '__main__':
+ main()
diff --git a/scripts/mkcompile_h b/scripts/mkcompile_h
index 6fdc97ef6023..fd8fdb91581d 100755
--- a/scripts/mkcompile_h
+++ b/scripts/mkcompile_h
@@ -76,7 +76,7 @@ UTS_TRUNCATE="cut -b -$UTS_LEN"
echo \#define LINUX_COMPILE_BY \"`echo $LINUX_COMPILE_BY | $UTS_TRUNCATE`\"
echo \#define LINUX_COMPILE_HOST \"`echo $LINUX_COMPILE_HOST | $UTS_TRUNCATE`\"
- echo \#define LINUX_COMPILER \"`$CC -v 2>&1 | grep ' version '`\"
+ echo \#define LINUX_COMPILER \"`$CC -v 2>&1 | grep ' version ' | sed 's/[[:space:]]*$//'`\"
) > .tmpcompile
# Only replace the real compile.h if the new one is different,
diff --git a/scripts/setlocalversion b/scripts/setlocalversion
index aa28c3f29809..1bbde3a91099 100755
--- a/scripts/setlocalversion
+++ b/scripts/setlocalversion
@@ -48,7 +48,20 @@ scm_version()
# If we are at a tagged commit (like "v2.6.30-rc6"), we ignore
# it, because this version is defined in the top level Makefile.
- if [ -z "`git describe --exact-match 2>/dev/null`" ]; then
+ if atag="`git describe --exact-match --abbrev=0 2>/dev/null`"; then
+ # Make sure we're at the tag that matches the Makefile.
+ # If not place the hash of the tag as well for
+ # v2.6.30-rc5-g314aef
+ if [ "x$atag" != "x$VERSION" ]; then
+ # If only the short version is requested,
+ # don't bother running further git commands
+ if $short; then
+ echo "+"
+ return
+ fi
+ printf '%s%s' -g "`git show-ref -s --abbrev --tags $atag 2>/dev/null`"
+ fi
+ else
# If only the short version is requested, don't bother
# running further git commands
@@ -57,10 +70,12 @@ scm_version()
return
fi
# If we are past a tagged commit (like
- # "v2.6.30-rc5-302-g72357d5"), we pretty print it.
+ # "v2.6.30-rc5-302-g72357d5"), we pretty print it and
+ # include the hash of any new tag on top.
if atag="`git describe 2>/dev/null`"; then
- echo "$atag" | awk -F- '{printf("-%05d-%s", $(NF-1),$(NF))}'
-
+ tag="`git describe --abbrev=0 2>/dev/null`"
+ commit="`echo "$atag" | awk -F- '{printf("-%05d-%s", $(NF-1),$(NF))}'`"
+ printf '%s%s%s' -g "`git show-ref -s --abbrev --tags $tag 2>/dev/null`" $commit
# If we don't have a tag at all we print -g{commitish}.
else
printf '%s%s' -g $head
diff --git a/scripts/sortextable.c b/scripts/sortextable.c
index 19d83647846c..a2c0d620ca80 100644
--- a/scripts/sortextable.c
+++ b/scripts/sortextable.c
@@ -283,6 +283,7 @@ do_file(char const *const fname)
case EM_X86_64:
case EM_S390:
case EM_AARCH64:
+ case EM_PARISC:
custom_sort = sort_relative_table;
break;
case EM_ARCOMPACT:
diff --git a/scripts/tags.sh b/scripts/tags.sh
index 45e246595d10..2a61db329adf 100755
--- a/scripts/tags.sh
+++ b/scripts/tags.sh
@@ -1,4 +1,4 @@
-#!/bin/sh
+#!/bin/bash
# Generate tags or cscope files
# Usage tags.sh <mode>
#
@@ -135,11 +135,6 @@ all_kconfigs()
find_other_sources 'Kconfig*'
}
-all_defconfigs()
-{
- find_sources $ALLSOURCE_ARCHS "defconfig"
-}
-
docscope()
{
(echo \-k; echo \-q; all_target_sources) > cscope.files
@@ -151,8 +146,111 @@ dogtags()
all_target_sources | gtags -i -f -
}
+# Basic regular expressions with an optional /kind-spec/ for ctags and
+# the following limitations:
+# - No regex modifiers
+# - Use \{0,1\} instead of \?, because etags expects an unescaped ?
+# - \s is not working with etags, use a space or [ \t]
+# - \w works, but does not match underscores in etags
+# - etags regular expressions have to match at the start of a line;
+# a ^[^#] is prepended by setup_regex unless an anchor is already present
+regex_asm=(
+ '/^\(ENTRY\|_GLOBAL\)(\([[:alnum:]_\\]*\)).*/\2/'
+)
+regex_c=(
+ '/^SYSCALL_DEFINE[0-9](\([[:alnum:]_]*\).*/sys_\1/'
+ '/^COMPAT_SYSCALL_DEFINE[0-9](\([[:alnum:]_]*\).*/compat_sys_\1/'
+ '/^TRACE_EVENT(\([[:alnum:]_]*\).*/trace_\1/'
+ '/^TRACE_EVENT(\([[:alnum:]_]*\).*/trace_\1_rcuidle/'
+ '/^DEFINE_EVENT([^,)]*, *\([[:alnum:]_]*\).*/trace_\1/'
+ '/^DEFINE_EVENT([^,)]*, *\([[:alnum:]_]*\).*/trace_\1_rcuidle/'
+ '/^DEFINE_INSN_CACHE_OPS(\([[:alnum:]_]*\).*/get_\1_slot/'
+ '/^DEFINE_INSN_CACHE_OPS(\([[:alnum:]_]*\).*/free_\1_slot/'
+ '/^PAGEFLAG(\([[:alnum:]_]*\).*/Page\1/'
+ '/^PAGEFLAG(\([[:alnum:]_]*\).*/SetPage\1/'
+ '/^PAGEFLAG(\([[:alnum:]_]*\).*/ClearPage\1/'
+ '/^TESTSETFLAG(\([[:alnum:]_]*\).*/TestSetPage\1/'
+ '/^TESTPAGEFLAG(\([[:alnum:]_]*\).*/Page\1/'
+ '/^SETPAGEFLAG(\([[:alnum:]_]*\).*/SetPage\1/'
+ '/\<__SETPAGEFLAG(\([[:alnum:]_]*\).*/__SetPage\1/'
+ '/\<TESTCLEARFLAG(\([[:alnum:]_]*\).*/TestClearPage\1/'
+ '/\<__TESTCLEARFLAG(\([[:alnum:]_]*\).*/TestClearPage\1/'
+ '/\<CLEARPAGEFLAG(\([[:alnum:]_]*\).*/ClearPage\1/'
+ '/\<__CLEARPAGEFLAG(\([[:alnum:]_]*\).*/__ClearPage\1/'
+ '/^__PAGEFLAG(\([[:alnum:]_]*\).*/__SetPage\1/'
+ '/^__PAGEFLAG(\([[:alnum:]_]*\).*/__ClearPage\1/'
+ '/^PAGEFLAG_FALSE(\([[:alnum:]_]*\).*/Page\1/'
+ '/\<TESTSCFLAG(\([[:alnum:]_]*\).*/TestSetPage\1/'
+ '/\<TESTSCFLAG(\([[:alnum:]_]*\).*/TestClearPage\1/'
+ '/\<SETPAGEFLAG_NOOP(\([[:alnum:]_]*\).*/SetPage\1/'
+ '/\<CLEARPAGEFLAG_NOOP(\([[:alnum:]_]*\).*/ClearPage\1/'
+ '/\<__CLEARPAGEFLAG_NOOP(\([[:alnum:]_]*\).*/__ClearPage\1/'
+ '/\<TESTCLEARFLAG_FALSE(\([[:alnum:]_]*\).*/TestClearPage\1/'
+ '/^PAGE_MAPCOUNT_OPS(\([[:alnum:]_]*\).*/Page\1/'
+ '/^PAGE_MAPCOUNT_OPS(\([[:alnum:]_]*\).*/__SetPage\1/'
+ '/^PAGE_MAPCOUNT_OPS(\([[:alnum:]_]*\).*/__ClearPage\1/'
+ '/^TASK_PFA_TEST([^,]*, *\([[:alnum:]_]*\))/task_\1/'
+ '/^TASK_PFA_SET([^,]*, *\([[:alnum:]_]*\))/task_set_\1/'
+ '/^TASK_PFA_CLEAR([^,]*, *\([[:alnum:]_]*\))/task_clear_\1/'
+ '/^DEF_MMIO_\(IN\|OUT\)_[XD](\([[:alnum:]_]*\),[^)]*)/\2/'
+ '/^DEBUGGER_BOILERPLATE(\([[:alnum:]_]*\))/\1/'
+ '/^DEF_PCI_AC_\(\|NO\)RET(\([[:alnum:]_]*\).*/\2/'
+ '/^PCI_OP_READ(\(\w*\).*[1-4])/pci_bus_read_config_\1/'
+ '/^PCI_OP_WRITE(\(\w*\).*[1-4])/pci_bus_write_config_\1/'
+ '/\<DEFINE_\(MUTEX\|SEMAPHORE\|SPINLOCK\)(\([[:alnum:]_]*\)/\2/v/'
+ '/\<DEFINE_\(RAW_SPINLOCK\|RWLOCK\|SEQLOCK\)(\([[:alnum:]_]*\)/\2/v/'
+ '/\<DECLARE_\(RWSEM\|COMPLETION\)(\([[:alnum:]_]\+\)/\2/v/'
+ '/\<DECLARE_BITMAP(\([[:alnum:]_]*\)/\1/v/'
+ '/\(^\|\s\)\(\|L\|H\)LIST_HEAD(\([[:alnum:]_]*\)/\3/v/'
+ '/\(^\|\s\)RADIX_TREE(\([[:alnum:]_]*\)/\2/v/'
+ '/\<DEFINE_PER_CPU([^,]*, *\([[:alnum:]_]*\)/\1/v/'
+ '/\<DEFINE_PER_CPU_SHARED_ALIGNED([^,]*, *\([[:alnum:]_]*\)/\1/v/'
+ '/\<DECLARE_WAIT_QUEUE_HEAD(\([[:alnum:]_]*\)/\1/v/'
+ '/\<DECLARE_\(TASKLET\|WORK\|DELAYED_WORK\)(\([[:alnum:]_]*\)/\2/v/'
+ '/\(^\s\)OFFSET(\([[:alnum:]_]*\)/\2/v/'
+ '/\(^\s\)DEFINE(\([[:alnum:]_]*\)/\2/v/'
+ '/\<DEFINE_HASHTABLE(\([[:alnum:]_]*\)/\1/v/'
+)
+regex_kconfig=(
+ '/^[[:blank:]]*\(menu\|\)config[[:blank:]]\+\([[:alnum:]_]\+\)/\2/'
+ '/^[[:blank:]]*\(menu\|\)config[[:blank:]]\+\([[:alnum:]_]\+\)/CONFIG_\2/'
+)
+setup_regex()
+{
+ local mode=$1 lang tmp=() r
+ shift
+
+ regex=()
+ for lang; do
+ case "$lang" in
+ asm) tmp=("${regex_asm[@]}") ;;
+ c) tmp=("${regex_c[@]}") ;;
+ kconfig) tmp=("${regex_kconfig[@]}") ;;
+ esac
+ for r in "${tmp[@]}"; do
+ if test "$mode" = "exuberant"; then
+ regex[${#regex[@]}]="--regex-$lang=${r}b"
+ else
+ # Remove ctags /kind-spec/
+ case "$r" in
+ /*/*/?/)
+ r=${r%?/}
+ esac
+ # Prepend ^[^#] unless already anchored
+ case "$r" in
+ /^*) ;;
+ *)
+ r="/^[^#]*${r#/}"
+ esac
+ regex[${#regex[@]}]="--regex=$r"
+ fi
+ done
+ done
+}
+
exuberant()
{
+ setup_regex exuberant asm c
all_target_sources | xargs $1 -a \
-I __initdata,__exitdata,__initconst, \
-I __initdata_memblock \
@@ -166,118 +264,22 @@ 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 \
- --regex-asm='/^(ENTRY|_GLOBAL)\(([^)]*)\).*/\2/' \
- --regex-c='/^SYSCALL_DEFINE[[:digit:]]?\(([^,)]*).*/sys_\1/' \
- --regex-c='/^COMPAT_SYSCALL_DEFINE[[:digit:]]?\(([^,)]*).*/compat_sys_\1/' \
- --regex-c++='/^TRACE_EVENT\(([^,)]*).*/trace_\1/' \
- --regex-c++='/^TRACE_EVENT\(([^,)]*).*/trace_\1_rcuidle/' \
- --regex-c++='/^DEFINE_EVENT\([^,)]*, *([^,)]*).*/trace_\1/' \
- --regex-c++='/^DEFINE_EVENT\([^,)]*, *([^,)]*).*/trace_\1_rcuidle/' \
- --regex-c++='/PAGEFLAG\(([^,)]*).*/Page\1/' \
- --regex-c++='/PAGEFLAG\(([^,)]*).*/SetPage\1/' \
- --regex-c++='/PAGEFLAG\(([^,)]*).*/ClearPage\1/' \
- --regex-c++='/TESTSETFLAG\(([^,)]*).*/TestSetPage\1/' \
- --regex-c++='/TESTPAGEFLAG\(([^,)]*).*/Page\1/' \
- --regex-c++='/SETPAGEFLAG\(([^,)]*).*/SetPage\1/' \
- --regex-c++='/__SETPAGEFLAG\(([^,)]*).*/__SetPage\1/' \
- --regex-c++='/TESTCLEARFLAG\(([^,)]*).*/TestClearPage\1/' \
- --regex-c++='/__TESTCLEARFLAG\(([^,)]*).*/TestClearPage\1/' \
- --regex-c++='/CLEARPAGEFLAG\(([^,)]*).*/ClearPage\1/' \
- --regex-c++='/__CLEARPAGEFLAG\(([^,)]*).*/__ClearPage\1/' \
- --regex-c++='/__PAGEFLAG\(([^,)]*).*/__SetPage\1/' \
- --regex-c++='/__PAGEFLAG\(([^,)]*).*/__ClearPage\1/' \
- --regex-c++='/PAGEFLAG_FALSE\(([^,)]*).*/Page\1/' \
- --regex-c++='/TESTSCFLAG\(([^,)]*).*/TestSetPage\1/' \
- --regex-c++='/TESTSCFLAG\(([^,)]*).*/TestClearPage\1/' \
- --regex-c++='/SETPAGEFLAG_NOOP\(([^,)]*).*/SetPage\1/' \
- --regex-c++='/CLEARPAGEFLAG_NOOP\(([^,)]*).*/ClearPage\1/' \
- --regex-c++='/__CLEARPAGEFLAG_NOOP\(([^,)]*).*/__ClearPage\1/' \
- --regex-c++='/TESTCLEARFLAG_FALSE\(([^,)]*).*/TestClearPage\1/' \
- --regex-c++='/__TESTCLEARFLAG_FALSE\(([^,)]*).*/__TestClearPage\1/' \
- --regex-c++='/_PE\(([^,)]*).*/PEVENT_ERRNO__\1/' \
- --regex-c++='/TASK_PFA_TEST\([^,]*,\s*([^)]*)\)/task_\1/' \
- --regex-c++='/TASK_PFA_SET\([^,]*,\s*([^)]*)\)/task_set_\1/' \
- --regex-c++='/TASK_PFA_CLEAR\([^,]*,\s*([^)]*)\)/task_clear_\1/'\
- --regex-c++='/DEF_MMIO_(IN|OUT)_(X|D)\(([^,]*),\s*[^)]*\)/\3/' \
- --regex-c++='/DEBUGGER_BOILERPLATE\(([^,]*)\)/\1/' \
- --regex-c='/PCI_OP_READ\((\w*).*[1-4]\)/pci_bus_read_config_\1/' \
- --regex-c='/PCI_OP_WRITE\((\w*).*[1-4]\)/pci_bus_write_config_\1/' \
- --regex-c='/DEFINE_(MUTEX|SEMAPHORE|SPINLOCK)\((\w*)/\2/v/' \
- --regex-c='/DEFINE_(RAW_SPINLOCK|RWLOCK|SEQLOCK)\((\w*)/\2/v/' \
- --regex-c='/DECLARE_(RWSEM|COMPLETION)\((\w*)/\2/v/' \
- --regex-c='/DECLARE_BITMAP\((\w*)/\1/v/' \
- --regex-c='/(^|\s)(|L|H)LIST_HEAD\((\w*)/\3/v/' \
- --regex-c='/(^|\s)RADIX_TREE\((\w*)/\2/v/' \
- --regex-c='/DEFINE_PER_CPU\(([^,]*,\s*)(\w*).*\)/\2/v/' \
- --regex-c='/DEFINE_PER_CPU_SHARED_ALIGNED\(([^,]*,\s*)(\w*).*\)/\2/v/' \
- --regex-c='/DECLARE_WAIT_QUEUE_HEAD\((\w*)/\1/v/' \
- --regex-c='/DECLARE_(TASKLET|WORK|DELAYED_WORK)\((\w*)/\2/v/' \
- --regex-c='/DEFINE_PCI_DEVICE_TABLE\((\w*)/\1/v/' \
- --regex-c='/(^\s)OFFSET\((\w*)/\2/v/' \
- --regex-c='/(^\s)DEFINE\((\w*)/\2/v/' \
- --regex-c='/DEFINE_HASHTABLE\((\w*)/\1/v/'
+ --extra=+fq --c-kinds=+px --fields=+iaS --langmap=c:+.h \
+ "${regex[@]}"
+ setup_regex exuberant kconfig
all_kconfigs | xargs $1 -a \
- --langdef=kconfig --language-force=kconfig \
- --regex-kconfig='/^[[:blank:]]*(menu|)config[[:blank:]]+([[:alnum:]_]+)/\2/'
+ --langdef=kconfig --language-force=kconfig "${regex[@]}"
- all_kconfigs | xargs $1 -a \
- --langdef=kconfig --language-force=kconfig \
- --regex-kconfig='/^[[:blank:]]*(menu|)config[[:blank:]]+([[:alnum:]_]+)/CONFIG_\2/'
-
- all_defconfigs | xargs -r $1 -a \
- --langdef=dotconfig --language-force=dotconfig \
- --regex-dotconfig='/^#?[[:blank:]]*(CONFIG_[[:alnum:]_]+)/\1/'
}
emacs()
{
- all_target_sources | xargs $1 -a \
- --regex='/^\(ENTRY\|_GLOBAL\)(\([^)]*\)).*/\2/' \
- --regex='/^SYSCALL_DEFINE[0-9]?(\([^,)]*\).*/sys_\1/' \
- --regex='/^COMPAT_SYSCALL_DEFINE[0-9]?(\([^,)]*\).*/compat_sys_\1/' \
- --regex='/^TRACE_EVENT(\([^,)]*\).*/trace_\1/' \
- --regex='/^TRACE_EVENT(\([^,)]*\).*/trace_\1_rcuidle/' \
- --regex='/^DEFINE_EVENT([^,)]*, *\([^,)]*\).*/trace_\1/' \
- --regex='/^DEFINE_EVENT([^,)]*, *\([^,)]*\).*/trace_\1_rcuidle/' \
- --regex='/PAGEFLAG(\([^,)]*\).*/Page\1/' \
- --regex='/PAGEFLAG(\([^,)]*\).*/SetPage\1/' \
- --regex='/PAGEFLAG(\([^,)]*\).*/ClearPage\1/' \
- --regex='/TESTSETFLAG(\([^,)]*\).*/TestSetPage\1/' \
- --regex='/TESTPAGEFLAG(\([^,)]*\).*/Page\1/' \
- --regex='/SETPAGEFLAG(\([^,)]*\).*/SetPage\1/' \
- --regex='/__SETPAGEFLAG(\([^,)]*\).*/__SetPage\1/' \
- --regex='/TESTCLEARFLAG(\([^,)]*\).*/TestClearPage\1/' \
- --regex='/__TESTCLEARFLAG(\([^,)]*\).*/TestClearPage\1/' \
- --regex='/CLEARPAGEFLAG(\([^,)]*\).*/ClearPage\1/' \
- --regex='/__CLEARPAGEFLAG(\([^,)]*\).*/__ClearPage\1/' \
- --regex='/__PAGEFLAG(\([^,)]*\).*/__SetPage\1/' \
- --regex='/__PAGEFLAG(\([^,)]*\).*/__ClearPage\1/' \
- --regex='/PAGEFLAG_FALSE(\([^,)]*\).*/Page\1/' \
- --regex='/TESTSCFLAG(\([^,)]*\).*/TestSetPage\1/' \
- --regex='/TESTSCFLAG(\([^,)]*\).*/TestClearPage\1/' \
- --regex='/SETPAGEFLAG_NOOP(\([^,)]*\).*/SetPage\1/' \
- --regex='/CLEARPAGEFLAG_NOOP(\([^,)]*\).*/ClearPage\1/' \
- --regex='/__CLEARPAGEFLAG_NOOP(\([^,)]*\).*/__ClearPage\1/' \
- --regex='/TESTCLEARFLAG_FALSE(\([^,)]*\).*/TestClearPage\1/' \
- --regex='/__TESTCLEARFLAG_FALSE(\([^,)]*\).*/__TestClearPage\1/' \
- --regex='/TASK_PFA_TEST\([^,]*,\s*([^)]*)\)/task_\1/' \
- --regex='/TASK_PFA_SET\([^,]*,\s*([^)]*)\)/task_set_\1/' \
- --regex='/TASK_PFA_CLEAR\([^,]*,\s*([^)]*)\)/task_clear_\1/' \
- --regex='/_PE(\([^,)]*\).*/PEVENT_ERRNO__\1/' \
- --regex='/PCI_OP_READ(\([a-z]*[a-z]\).*[1-4])/pci_bus_read_config_\1/' \
- --regex='/PCI_OP_WRITE(\([a-z]*[a-z]\).*[1-4])/pci_bus_write_config_\1/'\
- --regex='/[^#]*DEFINE_HASHTABLE(\([^,)]*\)/\1/'
-
- all_kconfigs | xargs $1 -a \
- --regex='/^[ \t]*\(\(menu\)*config\)[ \t]+\([a-zA-Z0-9_]+\)/\3/'
-
- all_kconfigs | xargs $1 -a \
- --regex='/^[ \t]*\(\(menu\)*config\)[ \t]+\([a-zA-Z0-9_]+\)/CONFIG_\3/'
+ setup_regex emacs asm c
+ all_target_sources | xargs $1 -a "${regex[@]}"
- all_defconfigs | xargs -r $1 -a \
- --regex='/^#?[ \t]?\(CONFIG_[a-zA-Z0-9_]+\)/\1/'
+ setup_regex emacs kconfig
+ all_kconfigs | xargs $1 -a "${regex[@]}"
}
xtags()