diff options
Diffstat (limited to 'scripts')
-rw-r--r-- | scripts/Makefile.asm-generic | 17 | ||||
-rw-r--r-- | scripts/Makefile.build | 5 | ||||
-rw-r--r-- | scripts/Makefile.dtbo | 24 | ||||
-rw-r--r-- | scripts/Makefile.headersinst | 103 | ||||
-rw-r--r-- | scripts/Makefile.lib | 26 | ||||
-rw-r--r-- | scripts/Makefile.ubsan | 17 | ||||
-rwxr-xr-x | scripts/build-all.py | 427 | ||||
-rw-r--r-- | scripts/check-config-debug-exemptions | 58 | ||||
-rw-r--r-- | scripts/check-config-perf-exemptions | 61 | ||||
-rwxr-xr-x | scripts/check-config.py | 147 | ||||
-rwxr-xr-x | scripts/checkpatch.pl | 292 | ||||
-rwxr-xr-x | scripts/clang-android.sh | 4 | ||||
-rw-r--r-- | scripts/dtc/Makefile | 2 | ||||
-rw-r--r-- | scripts/dtc/libfdt/fdt.c | 14 | ||||
-rw-r--r-- | scripts/dtc/libfdt/fdt_rw.c | 2 | ||||
-rwxr-xr-x | scripts/gen_compile_commands.py | 151 | ||||
-rwxr-xr-x | scripts/mkcompile_h | 2 | ||||
-rwxr-xr-x | scripts/setlocalversion | 23 | ||||
-rw-r--r-- | scripts/sortextable.c | 1 | ||||
-rwxr-xr-x | scripts/tags.sh | 222 |
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() |