Merge branch '2020-07-01-kconfig-etc-updates' into next
authorTom Rini <trini@konsulko.com>
Sun, 5 Jul 2020 22:03:32 +0000 (18:03 -0400)
committerTom Rini <trini@konsulko.com>
Sun, 5 Jul 2020 22:03:32 +0000 (18:03 -0400)
- Resync Kconfiglib with the v14.1.0 release.
- Re-sync our <linux/compiler*h> files with v5.7-rc5 from upstream.
- Fully resync checkpatch.pl with v5.7 release.

To safely to all of the above, we have a few bugfixes about functions
that need a 'static inline' but weren't.  We also stop setting
CROSS_COMPILE in arch/*/config.mk.  Finally, with the above changes
boards can now opt-in to optimizing inlining and we do this for the
socfpga stratix10 platform for space savings.

25 files changed:
Kconfig
Makefile
arch/arm/mach-socfpga/include/mach/misc.h
arch/arm/mach-tegra/ivc.c
arch/m68k/config.mk
arch/microblaze/config.mk
arch/nds32/config.mk
arch/nios2/config.mk
arch/powerpc/config.mk
arch/sh/config.mk
arch/x86/cpu/config.mk
arch/x86/include/asm/atomic.h
arch/xtensa/config.mk
configs/socfpga_stratix10_defconfig
drivers/pci/pcie_rockchip.h
include/linux/compiler-clang.h
include/linux/compiler-gcc.h
include/linux/compiler-intel.h
include/linux/compiler.h
include/linux/compiler_attributes.h [new file with mode: 0644]
include/linux/compiler_types.h [new file with mode: 0644]
lib/vsprintf.c
scripts/Kconfig.include [new file with mode: 0644]
scripts/checkpatch.pl
tools/buildman/kconfiglib.py

diff --git a/Kconfig b/Kconfig
index 6d45534..99bc5fa 100644 (file)
--- a/Kconfig
+++ b/Kconfig
@@ -5,6 +5,10 @@
 #
 mainmenu "U-Boot $(UBOOTVERSION) Configuration"
 
+comment "Compiler: $(CC_VERSION_TEXT)"
+
+source "scripts/Kconfig.include"
+
 # Allow defaults in arch-specific code to override any given here
 source "arch/Kconfig"
 
@@ -62,6 +66,35 @@ config CC_OPTIMIZE_FOR_SIZE
 
          This option is enabled by default for U-Boot.
 
+config OPTIMIZE_INLINING
+       bool "Allow compiler to uninline functions marked 'inline' in full U-Boot"
+       default n
+       help
+         This option determines if U-Boot forces gcc to inline the functions
+         developers have marked 'inline'. Doing so takes away freedom from gcc to
+         do what it thinks is best, which is desirable in some cases for size
+         reasons.
+
+config SPL_OPTIMIZE_INLINING
+       bool "Allow compiler to uninline functions marked 'inline' in SPL"
+       depends on SPL
+       default n
+       help
+         This option determines if U-Boot forces gcc to inline the functions
+         developers have marked 'inline'. Doing so takes away freedom from gcc to
+         do what it thinks is best, which is desirable in some cases for size
+         reasons.
+
+config TPL_OPTIMIZE_INLINING
+       bool "Allow compiler to uninline functions marked 'inline' in TPL"
+       depends on TPL
+       default n
+       help
+         This option determines if U-Boot forces gcc to inline the functions
+         developers have marked 'inline'. Doing so takes away freedom from gcc to
+         do what it thinks is best, which is desirable in some cases for size
+         reasons.
+
 config CC_COVERAGE
        bool "Enable code coverage analysis"
        depends on SANDBOX
@@ -69,6 +102,9 @@ config CC_COVERAGE
          Enabling this option will pass "--coverage" to gcc to compile
          and link code instrumented for coverage analysis.
 
+config CC_HAS_ASM_INLINE
+       def_bool $(success,echo 'void foo(void) { asm inline (""); }' | $(CC) -x c - -c -o /dev/null)
+
 config DISTRO_DEFAULTS
        bool "Select defaults suitable for booting general purpose Linux distributions"
        select AUTO_COMPLETE
index 0226930..9033509 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -683,6 +683,9 @@ KBUILD_CFLAGS += $(call cc-option,-fno-delete-null-pointer-checks)
 # disable stringop warnings in gcc 8+
 KBUILD_CFLAGS += $(call cc-disable-warning, stringop-truncation)
 
+# Enabled with W=2, disabled by default as noisy
+KBUILD_CFLAGS += $(call cc-disable-warning, maybe-uninitialized)
+
 # change __FILE__ to the relative path from the srctree
 KBUILD_CFLAGS  += $(call cc-option,-fmacro-prefix-map=$(srctree)/=)
 
index f6de1cc..a85c5ae 100644 (file)
@@ -20,7 +20,7 @@ extern struct bsel bsel_str[];
 #ifdef CONFIG_FPGA
 void socfpga_fpga_add(void *fpga_desc);
 #else
-inline void socfpga_fpga_add(void *fpga_desc) {}
+static inline void socfpga_fpga_add(void *fpga_desc) {}
 #endif
 
 #ifdef CONFIG_TARGET_SOCFPGA_GEN5
index e7c6d78..b69a458 100644 (file)
@@ -124,11 +124,11 @@ static inline int tegra_ivc_channel_empty(struct tegra_ivc *ivc,
 {
        /*
         * This function performs multiple checks on the same values with
-        * security implications, so create snapshots with ACCESS_ONCE() to
+        * security implications, so create snapshots with READ_ONCE() to
         * ensure that these checks use the same values.
         */
-       uint32_t w_count = ACCESS_ONCE(ch->w_count);
-       uint32_t r_count = ACCESS_ONCE(ch->r_count);
+       uint32_t w_count = READ_ONCE(ch->w_count);
+       uint32_t r_count = READ_ONCE(ch->r_count);
 
        /*
         * Perform an over-full check to prevent denial of service attacks where
@@ -153,14 +153,14 @@ static inline int tegra_ivc_channel_full(struct tegra_ivc *ivc,
         * Invalid cases where the counters indicate that the queue is over
         * capacity also appear full.
         */
-       return (ACCESS_ONCE(ch->w_count) - ACCESS_ONCE(ch->r_count)) >=
+       return (READ_ONCE(ch->w_count) - READ_ONCE(ch->r_count)) >=
               ivc->nframes;
 }
 
 static inline void tegra_ivc_advance_rx(struct tegra_ivc *ivc)
 {
-       ACCESS_ONCE(ivc->rx_channel->r_count) =
-                       ACCESS_ONCE(ivc->rx_channel->r_count) + 1;
+       WRITE_ONCE(ivc->rx_channel->r_count,
+                  READ_ONCE(ivc->rx_channel->r_count) + 1);
 
        if (ivc->r_pos == ivc->nframes - 1)
                ivc->r_pos = 0;
@@ -170,8 +170,8 @@ static inline void tegra_ivc_advance_rx(struct tegra_ivc *ivc)
 
 static inline void tegra_ivc_advance_tx(struct tegra_ivc *ivc)
 {
-       ACCESS_ONCE(ivc->tx_channel->w_count) =
-                       ACCESS_ONCE(ivc->tx_channel->w_count) + 1;
+       WRITE_ONCE(ivc->tx_channel->w_count,
+                  READ_ONCE(ivc->tx_channel->w_count) + 1);
 
        if (ivc->w_pos == ivc->nframes - 1)
                ivc->w_pos = 0;
@@ -232,7 +232,7 @@ static inline uint32_t tegra_ivc_channel_avail_count(struct tegra_ivc *ivc,
         * comment in tegra_ivc_channel_empty() for an explanation about
         * special over-full considerations.
         */
-       return ACCESS_ONCE(ch->w_count) - ACCESS_ONCE(ch->r_count);
+       return READ_ONCE(ch->w_count) - READ_ONCE(ch->r_count);
 }
 
 int tegra_ivc_read_get_next_frame(struct tegra_ivc *ivc, void **frame)
@@ -358,7 +358,7 @@ int tegra_ivc_channel_notified(struct tegra_ivc *ivc)
        /* Copy the receiver's state out of shared memory. */
        offset = offsetof(struct tegra_ivc_channel_header, w_count);
        tegra_ivc_invalidate_counter(ivc, ivc->rx_channel, offset);
-       peer_state = ACCESS_ONCE(ivc->rx_channel->state);
+       peer_state = READ_ONCE(ivc->rx_channel->state);
 
        if (peer_state == ivc_state_sync) {
                /*
index 88b1a40..ed59233 100644 (file)
@@ -3,10 +3,6 @@
 # (C) Copyright 2000-2002
 # Wolfgang Denk, DENX Software Engineering, wd@denx.de.
 
-ifeq ($(CROSS_COMPILE),)
-CROSS_COMPILE := m68k-elf-
-endif
-
 CONFIG_STANDALONE_LOAD_ADDR ?= 0x20000
 
 PLATFORM_CPPFLAGS += -D__M68K__
index 3c5866a..96c39b1 100644 (file)
@@ -6,10 +6,6 @@
 # (C) Copyright 2004 Atmark Techno, Inc.
 # Yasushi SHOJI <yashi@atmark-techno.com>
 
-ifeq ($(CROSS_COMPILE),)
-CROSS_COMPILE := mb-
-endif
-
 CONFIG_STANDALONE_LOAD_ADDR ?= 0x80F00000
 
 PLATFORM_CPPFLAGS += -ffixed-r31 -D__microblaze__
index a1c3371..c82dd69 100644 (file)
@@ -8,10 +8,6 @@
 # Macpaul Lin, Andes Technology Corporation <macpaul@andestech.com>
 #
 
-ifeq ($(CROSS_COMPILE),)
-CROSS_COMPILE := nds32le-linux-
-endif
-
 CONFIG_STANDALONE_LOAD_ADDR = 0x300000
 LDFLAGS_STANDALONE     += -T $(srctree)/examples/standalone/nds32.lds
 
index c63d170..44260b1 100644 (file)
@@ -4,10 +4,6 @@
 # Psyent Corporation <www.psyent.com>
 # Scott McNutt <smcnutt@psyent.com>
 
-ifeq ($(CROSS_COMPILE),)
-CROSS_COMPILE := nios2-elf-
-endif
-
 CONFIG_STANDALONE_LOAD_ADDR ?= 0x02000000
 
 PLATFORM_CPPFLAGS += -D__NIOS2__
index 88e2c58..307ca65 100644 (file)
@@ -3,10 +3,6 @@
 # (C) Copyright 2000-2010
 # Wolfgang Denk, DENX Software Engineering, wd@denx.de.
 
-ifeq ($(CROSS_COMPILE),)
-CROSS_COMPILE := ppc_8xx-
-endif
-
 CONFIG_STANDALONE_LOAD_ADDR ?= 0x40000
 LDFLAGS_FINAL += --gc-sections
 LDFLAGS_FINAL += --bss-plt
index 85dab38..78bb266 100644 (file)
@@ -3,10 +3,6 @@
 # (C) Copyright 2000-2002
 # Wolfgang Denk, DENX Software Engineering, wd@denx.de.
 
-ifeq ($(CROSS_COMPILE),)
-CROSS_COMPILE := sh4-linux-
-endif
-
 CONFIG_STANDALONE_LOAD_ADDR ?= 0x8C000000
 ifeq ($(CPU),sh2)
 LDFLAGS_STANDALONE += -EB
index 8f9814c..d3033b4 100644 (file)
@@ -3,8 +3,6 @@
 # (C) Copyright 2002
 # Daniel Engström, Omicron Ceti AB, daniel@omicron.se.
 
-CROSS_COMPILE ?= i386-linux-
-
 # DO NOT MODIFY THE FOLLOWING UNLESS YOU REALLY KNOW WHAT YOU ARE DOING!
 LDPPFLAGS += -DRESET_SEG_START=$(CONFIG_RESET_SEG_START)
 LDPPFLAGS += -DRESET_VEC_LOC=$(CONFIG_RESET_VEC_LOC)
index 4ca0f79..14f811f 100644 (file)
@@ -23,7 +23,7 @@ typedef struct { volatile int counter; } atomic_t;
  */
 static inline int atomic_read(const atomic_t *v)
 {
-       return ACCESS_ONCE((v)->counter);
+       return READ_ONCE((v)->counter);
 }
 
 /**
index ec37107..b080999 100644 (file)
@@ -3,7 +3,6 @@
 # (C) Copyright 2007 - 2013 Tensilica, Inc.
 # (C) Copyright 2014 - 2016 Cadence Design Systems Inc.
 
-CROSS_COMPILE ?= xtensa-linux-
 PLATFORM_CPPFLAGS += -D__XTENSA__ -mlongcalls -mforce-no-pic \
                     -ffunction-sections -fdata-sections
 
index 9611206..587745f 100644 (file)
@@ -12,6 +12,8 @@ CONFIG_TARGET_SOCFPGA_STRATIX10_SOCDK=y
 CONFIG_IDENT_STRING="socfpga_stratix10"
 CONFIG_SPL_FS_FAT=y
 CONFIG_SPL_TEXT_BASE=0xFFE00000
+CONFIG_OPTIMIZE_INLINING=y
+CONFIG_SPL_OPTIMIZE_INLINING=y
 CONFIG_BOOTDELAY=5
 CONFIG_USE_BOOTARGS=y
 CONFIG_BOOTARGS="earlycon"
index c3a0a28..845d505 100644 (file)
@@ -130,13 +130,12 @@ struct rockchip_pcie {
 
 int rockchip_pcie_phy_get(struct udevice *dev);
 
-inline struct rockchip_pcie_phy *pcie_get_phy(struct rockchip_pcie *pcie)
+static inline struct rockchip_pcie_phy *pcie_get_phy(struct rockchip_pcie *pcie)
 {
        return pcie->phy;
 }
 
-inline
-struct rockchip_pcie_phy_ops *phy_get_ops(struct rockchip_pcie_phy *phy)
+static inline struct rockchip_pcie_phy_ops *phy_get_ops(struct rockchip_pcie_phy *phy)
 {
        return (struct rockchip_pcie_phy_ops *)phy->ops;
 }
index d1e49d5..333a669 100644 (file)
@@ -1,12 +1,44 @@
-#ifndef __LINUX_COMPILER_H
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef __LINUX_COMPILER_TYPES_H
 #error "Please don't include <linux/compiler-clang.h> directly, include <linux/compiler.h> instead."
 #endif
 
-/* Some compiler specific definitions are overwritten here
- * for Clang compiler
- */
+/* Compiler specific definitions for Clang compiler */
 
-#ifdef uninitialized_var
-#undef uninitialized_var
 #define uninitialized_var(x) x = *(&(x))
+
+/* same as gcc, this was present in clang-2.6 so we can assume it works
+ * with any version that can compile the kernel
+ */
+#define __UNIQUE_ID(prefix) __PASTE(__PASTE(__UNIQUE_ID_, prefix), __COUNTER__)
+
+/* all clang versions usable with the kernel support KASAN ABI version 5 */
+#define KASAN_ABI_VERSION 5
+
+#if __has_feature(address_sanitizer) || __has_feature(hwaddress_sanitizer)
+/* emulate gcc's __SANITIZE_ADDRESS__ flag */
+#define __SANITIZE_ADDRESS__
+#define __no_sanitize_address \
+               __attribute__((no_sanitize("address", "hwaddress")))
+#else
+#define __no_sanitize_address
 #endif
+
+/*
+ * Not all versions of clang implement the the type-generic versions
+ * of the builtin overflow checkers. Fortunately, clang implements
+ * __has_builtin allowing us to avoid awkward version
+ * checks. Unfortunately, we don't know which version of gcc clang
+ * pretends to be, so the macro may or may not be defined.
+ */
+#if __has_builtin(__builtin_mul_overflow) && \
+    __has_builtin(__builtin_add_overflow) && \
+    __has_builtin(__builtin_sub_overflow)
+#define COMPILER_HAS_GENERIC_BUILTIN_OVERFLOW 1
+#endif
+
+/* The following are for compatibility with GCC, from compiler-gcc.h,
+ * and may be redefined here because they should not be shared with other
+ * compilers, like ICC.
+ */
+#define barrier() __asm__ __volatile__("" : : : "memory")
index 8d9e079..d7ee4c6 100644 (file)
@@ -1,4 +1,5 @@
-#ifndef __LINUX_COMPILER_H
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef __LINUX_COMPILER_TYPES_H
 #error "Please don't include <linux/compiler-gcc.h> directly, include <linux/compiler.h> instead."
 #endif
 
                     + __GNUC_MINOR__ * 100     \
                     + __GNUC_PATCHLEVEL__)
 
+#if GCC_VERSION < 40600
+# error Sorry, your compiler is too old - please upgrade it.
+#endif
+
 /* Optimization barrier */
 
 /* The "volatile" is due to gcc bugs */
-#define barrier() \
-       __asm__ __volatile__("": : :"memory")
+#define barrier() __asm__ __volatile__("": : :"memory")
 /*
  * This version is i.e. to prevent dead stores elimination on @ptr
  * where gcc and llvm may behave differently when otherwise using
  * clobbered. The issue is as follows: while the inline asm might
  * access any memory it wants, the compiler could have fit all of
  * @ptr into memory registers instead, and since @ptr never escaped
- * from that, it proofed that the inline asm wasn't touching any of
+ * from that, it proved that the inline asm wasn't touching any of
  * it. This version works well with both compilers, i.e. we're telling
  * the compiler that the inline asm absolutely may see the contents
  * of @ptr. See also: https://llvm.org/bugs/show_bug.cgi?id=15495
  */
-#define barrier_data(ptr) \
-       __asm__ __volatile__("": :"r"(ptr) :"memory")
+#define barrier_data(ptr) __asm__ __volatile__("": :"r"(ptr) :"memory")
 
 /*
  * This macro obfuscates arithmetic on a variable address so that gcc
        (typeof(ptr)) (__ptr + (off));                                  \
 })
 
-/* Make the optimizer believe the variable can be manipulated arbitrarily. */
-#define OPTIMIZER_HIDE_VAR(var)                                                \
-       __asm__ ("" : "=r" (var) : "0" (var))
-
-#ifdef __CHECKER__
-#define __must_be_array(a)     0
-#else
-/* &a[0] degrades to a pointer: a different type from an array */
-#define __must_be_array(a)     BUILD_BUG_ON_ZERO(__same_type((a), &(a)[0]))
-#endif
-
-/*
- * Force always-inline if the user requests it so via the .config,
- * or if gcc is too old:
- */
-#if !defined(CONFIG_ARCH_SUPPORTS_OPTIMIZED_INLINING) ||               \
-    !defined(CONFIG_OPTIMIZE_INLINING) || (__GNUC__ < 4)
-#define inline         inline          __attribute__((always_inline)) notrace
-#define __inline__     __inline__      __attribute__((always_inline)) notrace
-#define __inline       __inline        __attribute__((always_inline)) notrace
-#else
-/* A lot of inline functions can cause havoc with function tracing */
-#define inline         inline          notrace
-#define __inline__     __inline__      notrace
-#define __inline       __inline        notrace
-#endif
-
-#define __always_inline        inline __attribute__((always_inline))
-#define  noinline      __attribute__((noinline))
-
-#define __deprecated   __attribute__((deprecated))
-#define __packed       __attribute__((packed))
-#define __weak         __attribute__((weak))
-#define __alias(symbol)        __attribute__((alias(#symbol)))
-
 /*
- * it doesn't make sense on ARM (currently the only user of __naked)
- * to trace naked functions because then mcount is called without
- * stack and frame pointer being set up and there is no chance to
- * restore the lr register to the value before mcount was called.
- *
- * The asm() bodies of naked functions often depend on standard calling
- * conventions, therefore they must be noinline and noclone.
- *
- * GCC 4.[56] currently fail to enforce this, so we must do so ourselves.
- * See GCC PR44290.
- */
-#define __naked                __attribute__((naked)) noinline __noclone notrace
-
-#define __noreturn     __attribute__((noreturn))
-
-/*
- * From the GCC manual:
- *
- * Many functions have no effects except the return value and their
- * return value depends only on the parameters and/or global
- * variables.  Such a function can be subject to common subexpression
- * elimination and loop optimization just as an arithmetic operator
- * would be.
- * [...]
+ * A trick to suppress uninitialized variable warning without generating any
+ * code
  */
-#define __pure                 __attribute__((pure))
-#define __aligned(x)           __attribute__((aligned(x)))
-#define __printf(a, b)         __attribute__((format(printf, a, b)))
-#define __scanf(a, b)          __attribute__((format(scanf, a, b)))
-#define __attribute_const__    __attribute__((__const__))
-#define __maybe_unused         __attribute__((unused))
-#define __always_unused                __attribute__((unused))
-
-/* gcc version specific checks */
-
-#if GCC_VERSION < 30200
-# error Sorry, your compiler is too old - please upgrade it.
-#endif
-
-#if GCC_VERSION < 30300
-# define __used                        __attribute__((__unused__))
-#else
-# define __used                        __attribute__((__used__))
-#endif
-
-#ifdef CONFIG_GCOV_KERNEL
-# if GCC_VERSION < 30400
-#   error "GCOV profiling support for gcc versions below 3.4 not included"
-# endif /* __GNUC_MINOR__ */
-#endif /* CONFIG_GCOV_KERNEL */
+#define uninitialized_var(x) x = x
 
-#if GCC_VERSION >= 30400
-#define __must_check           __attribute__((warn_unused_result))
+#ifdef CONFIG_RETPOLINE
+#define __noretpoline __attribute__((__indirect_branch__("keep")))
 #endif
 
-#if GCC_VERSION >= 40000
+#define __UNIQUE_ID(prefix) __PASTE(__PASTE(__UNIQUE_ID_, prefix), __COUNTER__)
 
-/* GCC 4.1.[01] miscompiles __weak */
-#ifdef __KERNEL__
-# if GCC_VERSION >= 40100 &&  GCC_VERSION <= 40101
-#  error Your version of gcc miscompiles the __weak directive
-# endif
-#endif
+#define __compiletime_object_size(obj) __builtin_object_size(obj, 0)
 
-#define __used                 __attribute__((__used__))
-#define __compiler_offsetof(a, b)                                      \
-       __builtin_offsetof(a, b)
+#define __compiletime_warning(message) __attribute__((__warning__(message)))
+#define __compiletime_error(message) __attribute__((__error__(message)))
 
-#if GCC_VERSION >= 40100 && GCC_VERSION < 40600
-# define __compiletime_object_size(obj) __builtin_object_size(obj, 0)
+#if defined(LATENT_ENTROPY_PLUGIN) && !defined(__CHECKER__)
+#define __latent_entropy __attribute__((latent_entropy))
 #endif
 
-#if GCC_VERSION >= 40300
-/* Mark functions as cold. gcc will assume any path leading to a call
- * to them will be unlikely.  This means a lot of manual unlikely()s
- * are unnecessary now for any paths leading to the usual suspects
- * like BUG(), printk(), panic() etc. [but let's keep them for now for
- * older compilers]
- *
- * Early snapshots of gcc 4.3 don't support this and we can't detect this
- * in the preprocessor, but we can live with this because they're unreleased.
- * Maketime probing would be overkill here.
+/*
+ * calling noreturn functions, __builtin_unreachable() and __builtin_trap()
+ * confuse the stack allocation in gcc, leading to overly large stack
+ * frames, see https://gcc.gnu.org/bugzilla/show_bug.cgi?id=82365
  *
- * gcc also has a __attribute__((__hot__)) to move hot functions into
- * a special section, but I don't see any sense in this right now in
- * the kernel context
+ * Adding an empty inline assembly before it works around the problem
  */
-#define __cold                 __attribute__((__cold__))
-
-#define __UNIQUE_ID(prefix) __PASTE(__PASTE(__UNIQUE_ID_, prefix), __COUNTER__)
+#define barrier_before_unreachable() asm volatile("")
 
-#ifndef __CHECKER__
-# define __compiletime_warning(message) __attribute__((warning(message)))
-# define __compiletime_error(message) __attribute__((error(message)))
-#endif /* __CHECKER__ */
-#endif /* GCC_VERSION >= 40300 */
-
-#if GCC_VERSION >= 40500
 /*
  * Mark a position in code as unreachable.  This can be used to
  * suppress control flow warnings after asm blocks that transfer
  * control elsewhere.
- *
- * Early snapshots of gcc 4.5 don't support this and we can't detect
- * this in the preprocessor, but we can live with this because they're
- * unreleased.  Really, we need to have autoconf for the kernel.
- */
-#define unreachable() __builtin_unreachable()
-
-/* Mark a function definition as prohibited from being cloned. */
-#define __noclone      __attribute__((__noclone__))
-
-#endif /* GCC_VERSION >= 40500 */
-
-#if GCC_VERSION >= 40600
-/*
- * When used with Link Time Optimization, gcc can optimize away C functions or
- * variables which are referenced only from assembly code.  __visible tells the
- * optimizer that something else uses this function or variable, thus preventing
- * this.
  */
-#define __visible      __attribute__((externally_visible))
-#endif
-
+#define unreachable() \
+       do {                                    \
+               annotate_unreachable();         \
+               barrier_before_unreachable();   \
+               __builtin_unreachable();        \
+       } while (0)
 
-#if GCC_VERSION >= 40900 && !defined(__CHECKER__)
-/*
- * __assume_aligned(n, k): Tell the optimizer that the returned
- * pointer can be assumed to be k modulo n. The second argument is
- * optional (default 0), so we use a variadic macro to make the
- * shorthand.
- *
- * Beware: Do not apply this to functions which may return
- * ERR_PTRs. Also, it is probably unwise to apply it to functions
- * returning extra information in the low bits (but in that case the
- * compiler should see some alignment anyway, when the return value is
- * massaged by 'flags = ptr & 3; ptr &= ~3;').
- */
-#define __assume_aligned(a, ...) __attribute__((__assume_aligned__(a, ## __VA_ARGS__)))
+#if defined(RANDSTRUCT_PLUGIN) && !defined(__CHECKER__)
+#define __randomize_layout __attribute__((randomize_layout))
+#define __no_randomize_layout __attribute__((no_randomize_layout))
+/* This anon struct can add padding, so only enable it under randstruct. */
+#define randomized_struct_fields_start struct {
+#define randomized_struct_fields_end   } __randomize_layout;
 #endif
 
 /*
  */
 #define asm_volatile_goto(x...)        do { asm goto(x); asm (""); } while (0)
 
-#ifdef CONFIG_ARCH_USE_BUILTIN_BSWAP
-#if GCC_VERSION >= 40400
+/*
+ * sparse (__CHECKER__) pretends to be gcc, but can't do constant
+ * folding in __builtin_bswap*() (yet), so don't set these for it.
+ */
+#if defined(CONFIG_ARCH_USE_BUILTIN_BSWAP) && !defined(__CHECKER__)
 #define __HAVE_BUILTIN_BSWAP32__
 #define __HAVE_BUILTIN_BSWAP64__
-#endif
-#if GCC_VERSION >= 40800 || (defined(__powerpc__) && GCC_VERSION >= 40600)
+#if GCC_VERSION >= 40800
 #define __HAVE_BUILTIN_BSWAP16__
 #endif
-#endif /* CONFIG_ARCH_USE_BUILTIN_BSWAP */
+#endif /* CONFIG_ARCH_USE_BUILTIN_BSWAP && !__CHECKER__ */
 
-#if GCC_VERSION >= 50000
+#if GCC_VERSION >= 70000
+#define KASAN_ABI_VERSION 5
+#elif GCC_VERSION >= 50000
 #define KASAN_ABI_VERSION 4
 #elif GCC_VERSION >= 40902
 #define KASAN_ABI_VERSION 3
 #endif
 
-#if GCC_VERSION >= 40902
-/*
- * Tell the compiler that address safety instrumentation (KASAN)
- * should not be applied to that function.
- * Conflicts with inlining: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=67368
- */
+#if __has_attribute(__no_sanitize_address__)
 #define __no_sanitize_address __attribute__((no_sanitize_address))
+#else
+#define __no_sanitize_address
 #endif
 
-#endif /* gcc version >= 40000 specific checks */
-
-#if !defined(__noclone)
-#define __noclone      /* not needed */
-#endif
-
-#if !defined(__no_sanitize_address)
-#define __no_sanitize_address
+#if GCC_VERSION >= 50100
+#define COMPILER_HAS_GENERIC_BUILTIN_OVERFLOW 1
 #endif
 
 /*
- * A trick to suppress uninitialized variable warning without generating any
- * code
+ * Turn individual warnings and errors on and off locally, depending
+ * on version.
  */
-#define uninitialized_var(x) x = x
+#define __diag_GCC(version, severity, s) \
+       __diag_GCC_ ## version(__diag_GCC_ ## severity s)
+
+/* Severity used in pragma directives */
+#define __diag_GCC_ignore      ignored
+#define __diag_GCC_warn                warning
+#define __diag_GCC_error       error
+
+#define __diag_str1(s)         #s
+#define __diag_str(s)          __diag_str1(s)
+#define __diag(s)              _Pragma(__diag_str(GCC diagnostic s))
+
+#if GCC_VERSION >= 80000
+#define __diag_GCC_8(s)                __diag(s)
+#else
+#define __diag_GCC_8(s)
+#endif
+
+#define __no_fgcse __attribute__((optimize("-fno-gcse")))
index d4c7113..b17f3cd 100644 (file)
@@ -1,22 +1,17 @@
-#ifndef __LINUX_COMPILER_H
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef __LINUX_COMPILER_TYPES_H
 #error "Please don't include <linux/compiler-intel.h> directly, include <linux/compiler.h> instead."
 #endif
 
 #ifdef __ECC
 
-/* Some compiler specific definitions are overwritten here
- * for Intel ECC compiler
- */
+/* Compiler specific definitions for Intel ECC compiler */
 
 #include <asm/intrinsics.h>
 
 /* Intel ECC compiler doesn't support gcc specific asm stmts.
  * It uses intrinsics to do the equivalent things.
  */
-#undef barrier
-#undef barrier_data
-#undef RELOC_HIDE
-#undef OPTIMIZER_HIDE_VAR
 
 #define barrier() __memory_barrier()
 #define barrier_data(ptr) barrier()
  */
 #define OPTIMIZER_HIDE_VAR(var) barrier()
 
-/* Intel ECC compiler doesn't support __builtin_types_compatible_p() */
-#define __must_be_array(a) 0
-
 #endif
 
-#ifndef __HAVE_BUILTIN_BSWAP16__
 /* icc has this, but it's called _bswap16 */
 #define __HAVE_BUILTIN_BSWAP16__
 #define __builtin_bswap16 _bswap16
-#endif
-
index 0ea6c8f..5e3b3c0 100644 (file)
+/* SPDX-License-Identifier: GPL-2.0 */
 #ifndef __LINUX_COMPILER_H
 #define __LINUX_COMPILER_H
 
-#ifndef __ASSEMBLY__
+#include <linux/compiler_types.h>
 
-#ifdef __CHECKER__
-# define __user                __attribute__((noderef, address_space(1)))
-# define __kernel      __attribute__((address_space(0)))
-# define __safe                __attribute__((safe))
-# define __force       __attribute__((force))
-# define __nocast      __attribute__((nocast))
-# define __iomem       __attribute__((noderef, address_space(2)))
-# define __must_hold(x)        __attribute__((context(x,1,1)))
-# define __acquires(x) __attribute__((context(x,0,1)))
-# define __releases(x) __attribute__((context(x,1,0)))
-# define __acquire(x)  __context__(x,1)
-# define __release(x)  __context__(x,-1)
-# define __cond_lock(x,c)      ((c) ? ({ __acquire(x); 1; }) : 0)
-# define __percpu      __attribute__((noderef, address_space(3)))
-# define __pmem                __attribute__((noderef, address_space(5)))
-#ifdef CONFIG_SPARSE_RCU_POINTER
-# define __rcu         __attribute__((noderef, address_space(4)))
-#else
-# define __rcu
-#endif
-extern void __chk_user_ptr(const volatile void __user *);
-extern void __chk_io_ptr(const volatile void __iomem *);
-#else
-# define __user
-# define __kernel
-# define __safe
-# define __force
-# define __nocast
-# define __iomem
-# define __chk_user_ptr(x) (void)0
-# define __chk_io_ptr(x) (void)0
-# define __builtin_warning(x, y...) (1)
-# define __must_hold(x)
-# define __acquires(x)
-# define __releases(x)
-# define __acquire(x) (void)0
-# define __release(x) (void)0
-# define __cond_lock(x,c) (c)
-# define __percpu
-# define __rcu
-# define __pmem
-#endif
-
-/* Indirect macros required for expanded argument pasting, eg. __LINE__. */
-#define ___PASTE(a,b) a##b
-#define __PASTE(a,b) ___PASTE(a,b)
+#ifndef __ASSEMBLY__
 
 #ifdef __KERNEL__
 
-#ifdef __GNUC__
-#include <linux/compiler-gcc.h>
-#endif
-
-#if defined(CC_USING_HOTPATCH) && !defined(__CHECKER__)
-#define notrace __attribute__((hotpatch(0,0)))
-#else
-#define notrace __attribute__((no_instrument_function))
-#endif
-
-/* Intel compiler defines __GNUC__. So we will overwrite implementations
- * coming from above header files here
- */
-#ifdef __INTEL_COMPILER
-# include <linux/compiler-intel.h>
-#endif
-
-/* Clang compiler defines __GNUC__. So we will overwrite implementations
- * coming from above header files here
- */
-#ifdef __clang__
-#include <linux/compiler-clang.h>
-#endif
-
-/*
- * Generic compiler-dependent macros required for kernel
- * build go below this comment. Actual compiler/compiler version
- * specific implementations come from the above header files
- */
-
-struct ftrace_branch_data {
-       const char *func;
-       const char *file;
-       unsigned line;
-       union {
-               struct {
-                       unsigned long correct;
-                       unsigned long incorrect;
-               };
-               struct {
-                       unsigned long miss;
-                       unsigned long hit;
-               };
-               unsigned long miss_hit[2];
-       };
-};
-
 /*
  * Note: DISABLE_BRANCH_PROFILING can be used by special lowlevel code
  * to disable branch tracing on a per file basis.
  */
 #if defined(CONFIG_TRACE_BRANCH_PROFILING) \
     && !defined(DISABLE_BRANCH_PROFILING) && !defined(__CHECKER__)
-void ftrace_likely_update(struct ftrace_branch_data *f, int val, int expect);
+void ftrace_likely_update(struct ftrace_likely_data *f, int val,
+                         int expect, int is_constant);
 
 #define likely_notrace(x)      __builtin_expect(!!(x), 1)
 #define unlikely_notrace(x)    __builtin_expect(!!(x), 0)
 
-#define __branch_check__(x, expect) ({                                 \
-                       int ______r;                                    \
-                       static struct ftrace_branch_data                \
-                               __attribute__((__aligned__(4)))         \
-                               __attribute__((section("_ftrace_annotated_branch"))) \
+#define __branch_check__(x, expect, is_constant) ({                    \
+                       long ______r;                                   \
+                       static struct ftrace_likely_data                \
+                               __aligned(4)                            \
+                               __section(_ftrace_annotated_branch)     \
                                ______f = {                             \
-                               .func = __func__,                       \
-                               .file = __FILE__,                       \
-                               .line = __LINE__,                       \
+                               .data.func = __func__,                  \
+                               .data.file = __FILE__,                  \
+                               .data.line = __LINE__,                  \
                        };                                              \
-                       ______r = likely_notrace(x);                    \
-                       ftrace_likely_update(&______f, ______r, expect); \
+                       ______r = __builtin_expect(!!(x), expect);      \
+                       ftrace_likely_update(&______f, ______r,         \
+                                            expect, is_constant);      \
                        ______r;                                        \
                })
 
@@ -131,10 +42,10 @@ void ftrace_likely_update(struct ftrace_branch_data *f, int val, int expect);
  * written by Daniel Walker.
  */
 # ifndef likely
-#  define likely(x)    (__builtin_constant_p(x) ? !!(x) : __branch_check__(x, 1))
+#  define likely(x)    (__branch_check__(x, 1, __builtin_constant_p(x)))
 # endif
 # ifndef unlikely
-#  define unlikely(x)  (__builtin_constant_p(x) ? !!(x) : __branch_check__(x, 0))
+#  define unlikely(x)  (__branch_check__(x, 0, __builtin_constant_p(x)))
 # endif
 
 #ifdef CONFIG_PROFILE_ALL_BRANCHES
@@ -142,23 +53,24 @@ void ftrace_likely_update(struct ftrace_branch_data *f, int val, int expect);
  * "Define 'is'", Bill Clinton
  * "Define 'if'", Steven Rostedt
  */
-#define if(cond, ...) __trace_if( (cond , ## __VA_ARGS__) )
-#define __trace_if(cond) \
-       if (__builtin_constant_p(!!(cond)) ? !!(cond) :                 \
-       ({                                                              \
-               int ______r;                                            \
-               static struct ftrace_branch_data                        \
-                       __attribute__((__aligned__(4)))                 \
-                       __attribute__((section("_ftrace_branch")))      \
-                       ______f = {                                     \
-                               .func = __func__,                       \
-                               .file = __FILE__,                       \
-                               .line = __LINE__,                       \
-                       };                                              \
-               ______r = !!(cond);                                     \
-               ______f.miss_hit[______r]++;                                    \
-               ______r;                                                \
-       }))
+#define if(cond, ...) if ( __trace_if_var( !!(cond , ## __VA_ARGS__) ) )
+
+#define __trace_if_var(cond) (__builtin_constant_p(cond) ? (cond) : __trace_if_value(cond))
+
+#define __trace_if_value(cond) ({                      \
+       static struct ftrace_branch_data                \
+               __aligned(4)                            \
+               __section(_ftrace_branch)               \
+               __if_trace = {                          \
+                       .func = __func__,               \
+                       .file = __FILE__,               \
+                       .line = __LINE__,               \
+               };                                      \
+       (cond) ?                                        \
+               (__if_trace.miss_hit[1]++,1) :          \
+               (__if_trace.miss_hit[0]++,0);           \
+})
+
 #endif /* CONFIG_PROFILE_ALL_BRANCHES */
 
 #else
@@ -175,9 +87,76 @@ void ftrace_likely_update(struct ftrace_branch_data *f, int val, int expect);
 # define barrier_data(ptr) barrier()
 #endif
 
+/* workaround for GCC PR82365 if needed */
+#ifndef barrier_before_unreachable
+# define barrier_before_unreachable() do { } while (0)
+#endif
+
 /* Unreachable code */
+#ifdef CONFIG_STACK_VALIDATION
+/*
+ * These macros help objtool understand GCC code flow for unreachable code.
+ * The __COUNTER__ based labels are a hack to make each instance of the macros
+ * unique, to convince GCC not to merge duplicate inline asm statements.
+ */
+#define annotate_reachable() ({                                                \
+       asm volatile("%c0:\n\t"                                         \
+                    ".pushsection .discard.reachable\n\t"              \
+                    ".long %c0b - .\n\t"                               \
+                    ".popsection\n\t" : : "i" (__COUNTER__));          \
+})
+#define annotate_unreachable() ({                                      \
+       asm volatile("%c0:\n\t"                                         \
+                    ".pushsection .discard.unreachable\n\t"            \
+                    ".long %c0b - .\n\t"                               \
+                    ".popsection\n\t" : : "i" (__COUNTER__));          \
+})
+#define ASM_UNREACHABLE                                                        \
+       "999:\n\t"                                                      \
+       ".pushsection .discard.unreachable\n\t"                         \
+       ".long 999b - .\n\t"                                            \
+       ".popsection\n\t"
+
+/* Annotate a C jump table to allow objtool to follow the code flow */
+#define __annotate_jump_table __section(.rodata..c_jump_table)
+
+#else
+#define annotate_reachable()
+#define annotate_unreachable()
+#define __annotate_jump_table
+#endif
+
+#ifndef ASM_UNREACHABLE
+# define ASM_UNREACHABLE
+#endif
 #ifndef unreachable
-# define unreachable() do { } while (1)
+# define unreachable() do {            \
+       annotate_unreachable();         \
+       __builtin_unreachable();        \
+} while (0)
+#endif
+
+/*
+ * KENTRY - kernel entry point
+ * This can be used to annotate symbols (functions or data) that are used
+ * without their linker symbol being referenced explicitly. For example,
+ * interrupt vector handlers, or functions in the kernel image that are found
+ * programatically.
+ *
+ * Not required for symbols exported with EXPORT_SYMBOL, or initcalls. Those
+ * are handled in their own way (with KEEP() in linker scripts).
+ *
+ * KENTRY can be avoided if the symbols in question are marked as KEEP() in the
+ * linker script. For example an architecture could KEEP() its entire
+ * boot/exception vector code rather than annotate each function and data.
+ */
+#ifndef KENTRY
+# define KENTRY(sym)                                           \
+       extern typeof(sym) sym;                                 \
+       static const unsigned long __kentry_##sym               \
+       __used                                                  \
+       __section("___kentry" "+" #sym )                        \
+       = (unsigned long)&sym;
 #endif
 
 #ifndef RELOC_HIDE
@@ -188,7 +167,9 @@ void ftrace_likely_update(struct ftrace_branch_data *f, int val, int expect);
 #endif
 
 #ifndef OPTIMIZER_HIDE_VAR
-#define OPTIMIZER_HIDE_VAR(var) barrier()
+/* Make the optimizer believe the variable can be manipulated arbitrarily. */
+#define OPTIMIZER_HIDE_VAR(var)                                                \
+       __asm__ ("" : "=r" (var) : "0" (var))
 #endif
 
 /* Not-quite-unique ID. */
@@ -220,23 +201,21 @@ void __read_once_size(const volatile void *p, void *res, int size)
 
 #ifdef CONFIG_KASAN
 /*
- * This function is not 'inline' because __no_sanitize_address confilcts
+ * We can't declare function 'inline' because __no_sanitize_address confilcts
  * with inlining. Attempt to inline it may cause a build failure.
  *     https://gcc.gnu.org/bugzilla/show_bug.cgi?id=67368
  * '__maybe_unused' allows us to avoid defined-but-not-used warnings.
  */
-static __no_sanitize_address __maybe_unused
-void __read_once_size_nocheck(const volatile void *p, void *res, int size)
-{
-       __READ_ONCE_SIZE;
-}
+# define __no_kasan_or_inline __no_sanitize_address notrace __maybe_unused
 #else
-static __always_inline
+# define __no_kasan_or_inline __always_inline
+#endif
+
+static __no_kasan_or_inline
 void __read_once_size_nocheck(const volatile void *p, void *res, int size)
 {
        __READ_ONCE_SIZE;
 }
-#endif
 
 static __always_inline void __write_once_size(volatile void *p, void *res, int size)
 {
@@ -255,20 +234,21 @@ static __always_inline void __write_once_size(volatile void *p, void *res, int s
 /*
  * Prevent the compiler from merging or refetching reads or writes. The
  * compiler is also forbidden from reordering successive instances of
- * READ_ONCE, WRITE_ONCE and ACCESS_ONCE (see below), but only when the
- * compiler is aware of some particular ordering.  One way to make the
- * compiler aware of ordering is to put the two invocations of READ_ONCE,
- * WRITE_ONCE or ACCESS_ONCE() in different C statements.
+ * READ_ONCE and WRITE_ONCE, but only when the compiler is aware of some
+ * particular ordering. One way to make the compiler aware of ordering is to
+ * put the two invocations of READ_ONCE or WRITE_ONCE in different C
+ * statements.
  *
- * In contrast to ACCESS_ONCE these two macros will also work on aggregate
- * data types like structs or unions. If the size of the accessed data
- * type exceeds the word size of the machine (e.g., 32 bits or 64 bits)
- * READ_ONCE() and WRITE_ONCE()  will fall back to memcpy and print a
- * compile-time warning.
+ * These two macros will also work on aggregate data types like structs or
+ * unions. If the size of the accessed data type exceeds the word size of
+ * the machine (e.g., 32 bits or 64 bits) READ_ONCE() and WRITE_ONCE() will
+ * fall back to memcpy(). There's at least two memcpy()s: one for the
+ * __builtin_memcpy() and then one for the macro doing the copy of variable
+ * - '__u' allocated on the stack.
  *
  * Their two major use cases are: (1) Mediating communication between
  * process-level code and irq/NMI handlers, all running on the same CPU,
- * and (2) Ensuring that the compiler does not  fold, spindle, or otherwise
+ * and (2) Ensuring that the compiler does not fold, spindle, or otherwise
  * mutilate accesses that either do not require ordering or that interact
  * with an explicit memory barrier or atomic instruction that provides the
  * required ordering.
@@ -291,6 +271,12 @@ static __always_inline void __write_once_size(volatile void *p, void *res, int s
  */
 #define READ_ONCE_NOCHECK(x) __READ_ONCE(x, 0)
 
+static __no_kasan_or_inline
+unsigned long read_word_at_a_time(const void *addr)
+{
+       return *(unsigned long *)addr;
+}
+
 #define WRITE_ONCE(x, val) \
 ({                                                     \
        union { typeof(x) __val; char __c[1]; } __u =   \
@@ -299,158 +285,28 @@ static __always_inline void __write_once_size(volatile void *p, void *res, int s
        __u.__val;                                      \
 })
 
-/**
- * smp_cond_acquire() - Spin wait for cond with ACQUIRE ordering
- * @cond: boolean expression to wait for
- *
- * Equivalent to using smp_load_acquire() on the condition variable but employs
- * the control dependency of the wait to reduce the barrier on many platforms.
- *
- * The control dependency provides a LOAD->STORE order, the additional RMB
- * provides LOAD->LOAD order, together they provide LOAD->{LOAD,STORE} order,
- * aka. ACQUIRE.
- */
-#define smp_cond_acquire(cond) do {            \
-       while (!(cond))                         \
-               cpu_relax();                    \
-       smp_rmb(); /* ctrl + rmb := acquire */  \
-} while (0)
-
-#endif /* __KERNEL__ */
-
-#endif /* __ASSEMBLY__ */
-
-#ifdef __KERNEL__
-/*
- * Allow us to mark functions as 'deprecated' and have gcc emit a nice
- * warning for each use, in hopes of speeding the functions removal.
- * Usage is:
- *             int __deprecated foo(void)
- */
-#ifndef __deprecated
-# define __deprecated          /* unimplemented */
-#endif
-
-#ifdef MODULE
-#define __deprecated_for_modules __deprecated
-#else
-#define __deprecated_for_modules
-#endif
-
-#ifndef __must_check
-#define __must_check
-#endif
-
-#ifndef CONFIG_ENABLE_MUST_CHECK
-#undef __must_check
-#define __must_check
-#endif
-#ifndef CONFIG_ENABLE_WARN_DEPRECATED
-#undef __deprecated
-#undef __deprecated_for_modules
-#define __deprecated
-#define __deprecated_for_modules
-#endif
-
-/*
- * Allow us to avoid 'defined but not used' warnings on functions and data,
- * as well as force them to be emitted to the assembly file.
- *
- * As of gcc 3.4, static functions that are not marked with attribute((used))
- * may be elided from the assembly file.  As of gcc 3.4, static data not so
- * marked will not be elided, but this may change in a future gcc version.
- *
- * NOTE: Because distributions shipped with a backported unit-at-a-time
- * compiler in gcc 3.3, we must define __used to be __attribute__((used))
- * for gcc >=3.3 instead of 3.4.
- *
- * In prior versions of gcc, such functions and data would be emitted, but
- * would be warned about except with attribute((unused)).
- *
- * Mark functions that are referenced only in inline assembly as __used so
- * the code is emitted even though it appears to be unreferenced.
- */
-#ifndef __used
-# define __used                        /* unimplemented */
-#endif
-
-#ifndef __maybe_unused
-# define __maybe_unused                /* unimplemented */
-#endif
-
-#ifndef __always_unused
-# define __always_unused       /* unimplemented */
-#endif
-
-#ifndef noinline
-#define noinline
-#endif
-
-/*
- * Rather then using noinline to prevent stack consumption, use
- * noinline_for_stack instead.  For documentation reasons.
- */
-#define noinline_for_stack noinline
-
-#ifndef __always_inline
-#define __always_inline inline
-#endif
-
 #endif /* __KERNEL__ */
 
 /*
- * From the GCC manual:
- *
- * Many functions do not examine any values except their arguments,
- * and have no effects except the return value.  Basically this is
- * just slightly more strict class than the `pure' attribute above,
- * since function is not allowed to read global memory.
- *
- * Note that a function that has pointer arguments and examines the
- * data pointed to must _not_ be declared `const'.  Likewise, a
- * function that calls a non-`const' function usually must not be
- * `const'.  It does not make sense for a `const' function to return
- * `void'.
- */
-#ifndef __attribute_const__
-# define __attribute_const__   /* unimplemented */
-#endif
-
-/*
- * Tell gcc if a function is cold. The compiler will assume any path
- * directly leading to the call is unlikely.
+ * Force the compiler to emit 'sym' as a symbol, so that we can reference
+ * it from inline assembler. Necessary in case 'sym' could be inlined
+ * otherwise, or eliminated entirely due to lack of references that are
+ * visible to the compiler.
  */
+#define __ADDRESSABLE(sym) \
+       static void * __section(.discard.addressable) __used \
+               __PASTE(__addressable_##sym, __LINE__) = (void *)&sym;
 
-#ifndef __cold
-#define __cold
-#endif
-
-/* Simple shorthand for a section definition */
-#ifndef __section
-# define __section(S) __attribute__ ((__section__(#S)))
-#endif
-
-#ifndef __visible
-#define __visible
-#endif
-
-/*
- * Assume alignment of return value.
+/**
+ * offset_to_ptr - convert a relative memory offset to an absolute pointer
+ * @off:       the address of the 32-bit offset value
  */
-#ifndef __assume_aligned
-#define __assume_aligned(a, ...)
-#endif
-
-
-/* Are two types/vars the same type (ignoring qualifiers)? */
-#ifndef __same_type
-# define __same_type(a, b) __builtin_types_compatible_p(typeof(a), typeof(b))
-#endif
+static inline void *offset_to_ptr(const int *off)
+{
+       return (void *)((unsigned long)off + *off);
+}
 
-/* Is this type a native word size -- useful for atomic operations */
-#ifndef __native_word
-# define __native_word(t) (sizeof(t) == sizeof(char) || sizeof(t) == sizeof(short) || sizeof(t) == sizeof(int) || sizeof(t) == sizeof(long))
-#endif
+#endif /* __ASSEMBLY__ */
 
 /* Compile time object size, -1 for unknown */
 #ifndef __compiletime_object_size
@@ -461,29 +317,14 @@ static __always_inline void __write_once_size(volatile void *p, void *res, int s
 #endif
 #ifndef __compiletime_error
 # define __compiletime_error(message)
-/*
- * Sparse complains of variable sized arrays due to the temporary variable in
- * __compiletime_assert. Unfortunately we can't just expand it out to make
- * sparse see a constant array size without breaking compiletime_assert on old
- * versions of GCC (e.g. 4.2.4), so hide the array from sparse altogether.
- */
-# ifndef __CHECKER__
-#  define __compiletime_error_fallback(condition) \
-       do { ((void)sizeof(char[1 - 2 * condition])); } while (0)
-# endif
-#endif
-#ifndef __compiletime_error_fallback
-# define __compiletime_error_fallback(condition) do { } while (0)
 #endif
 
 #ifdef __OPTIMIZE__
 # define __compiletime_assert(condition, msg, prefix, suffix)          \
        do {                                                            \
-               bool __cond = !(condition);                             \
                extern void prefix ## suffix(void) __compiletime_error(msg); \
-               if (__cond)                                             \
+               if (!(condition))                                       \
                        prefix ## suffix();                             \
-               __compiletime_error_fallback(__cond);                   \
        } while (0)
 #else
 # define __compiletime_assert(condition, msg, prefix, suffix) do { } while (0)
@@ -502,58 +343,13 @@ static __always_inline void __write_once_size(volatile void *p, void *res, int s
  * compiler has support to do so.
  */
 #define compiletime_assert(condition, msg) \
-       _compiletime_assert(condition, msg, __compiletime_assert_, __LINE__)
+       _compiletime_assert(condition, msg, __compiletime_assert_, __COUNTER__)
 
 #define compiletime_assert_atomic_type(t)                              \
        compiletime_assert(__native_word(t),                            \
                "Need native word sized stores/loads for atomicity.")
 
-/*
- * Prevent the compiler from merging or refetching accesses.  The compiler
- * is also forbidden from reordering successive instances of ACCESS_ONCE(),
- * but only when the compiler is aware of some particular ordering.  One way
- * to make the compiler aware of ordering is to put the two invocations of
- * ACCESS_ONCE() in different C statements.
- *
- * ACCESS_ONCE will only work on scalar types. For union types, ACCESS_ONCE
- * on a union member will work as long as the size of the member matches the
- * size of the union and the size is smaller than word size.
- *
- * The major use cases of ACCESS_ONCE used to be (1) Mediating communication
- * between process-level code and irq/NMI handlers, all running on the same CPU,
- * and (2) Ensuring that the compiler does not  fold, spindle, or otherwise
- * mutilate accesses that either do not require ordering or that interact
- * with an explicit memory barrier or atomic instruction that provides the
- * required ordering.
- *
- * If possible use READ_ONCE()/WRITE_ONCE() instead.
- */
-#define __ACCESS_ONCE(x) ({ \
-        __maybe_unused typeof(x) __var = (__force typeof(x)) 0; \
-       (volatile typeof(x) *)&(x); })
-#define ACCESS_ONCE(x) (*__ACCESS_ONCE(x))
-
-/**
- * lockless_dereference() - safely load a pointer for later dereference
- * @p: The pointer to load
- *
- * Similar to rcu_dereference(), but for situations where the pointed-to
- * object's lifetime is managed by something other than RCU.  That
- * "something other" might be reference counting or simple immortality.
- */
-#define lockless_dereference(p) \
-({ \
-       typeof(p) _________p1 = READ_ONCE(p); \
-       smp_read_barrier_depends(); /* Dependency order vs. p above. */ \
-       (_________p1); \
-})
+/* &a[0] degrades to a pointer: a different type from an array */
+#define __must_be_array(a)     BUILD_BUG_ON_ZERO(__same_type((a), &(a)[0]))
 
-/* Ignore/forbid kprobes attach on very low level functions marked by this attribute: */
-#ifdef CONFIG_KPROBES
-# define __kprobes     __attribute__((__section__(".kprobes.text")))
-# define nokprobe_inline       __always_inline
-#else
-# define __kprobes
-# define nokprobe_inline       inline
-#endif
 #endif /* __LINUX_COMPILER_H */
diff --git a/include/linux/compiler_attributes.h b/include/linux/compiler_attributes.h
new file mode 100644 (file)
index 0000000..cdf0165
--- /dev/null
@@ -0,0 +1,273 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef __LINUX_COMPILER_ATTRIBUTES_H
+#define __LINUX_COMPILER_ATTRIBUTES_H
+
+/*
+ * The attributes in this file are unconditionally defined and they directly
+ * map to compiler attribute(s), unless one of the compilers does not support
+ * the attribute. In that case, __has_attribute is used to check for support
+ * and the reason is stated in its comment ("Optional: ...").
+ *
+ * Any other "attributes" (i.e. those that depend on a configuration option,
+ * on a compiler, on an architecture, on plugins, on other attributes...)
+ * should be defined elsewhere (e.g. compiler_types.h or compiler-*.h).
+ * The intention is to keep this file as simple as possible, as well as
+ * compiler- and version-agnostic (e.g. avoiding GCC_VERSION checks).
+ *
+ * This file is meant to be sorted (by actual attribute name,
+ * not by #define identifier). Use the __attribute__((__name__)) syntax
+ * (i.e. with underscores) to avoid future collisions with other macros.
+ * Provide links to the documentation of each supported compiler, if it exists.
+ */
+
+/*
+ * __has_attribute is supported on gcc >= 5, clang >= 2.9 and icc >= 17.
+ * In the meantime, to support 4.6 <= gcc < 5, we implement __has_attribute
+ * by hand.
+ *
+ * sparse does not support __has_attribute (yet) and defines __GNUC_MINOR__
+ * depending on the compiler used to build it; however, these attributes have
+ * no semantic effects for sparse, so it does not matter. Also note that,
+ * in order to avoid sparse's warnings, even the unsupported ones must be
+ * defined to 0.
+ */
+#ifndef __has_attribute
+# define __has_attribute(x) __GCC4_has_attribute_##x
+# define __GCC4_has_attribute___assume_aligned__      (__GNUC_MINOR__ >= 9)
+# define __GCC4_has_attribute___copy__                0
+# define __GCC4_has_attribute___designated_init__     0
+# define __GCC4_has_attribute___externally_visible__  1
+# define __GCC4_has_attribute___noclone__             1
+# define __GCC4_has_attribute___nonstring__           0
+# define __GCC4_has_attribute___no_sanitize_address__ (__GNUC_MINOR__ >= 8)
+# define __GCC4_has_attribute___fallthrough__         0
+#endif
+
+/*
+ *   gcc: https://gcc.gnu.org/onlinedocs/gcc/Common-Function-Attributes.html#index-alias-function-attribute
+ */
+#define __alias(symbol)                 __attribute__((__alias__(#symbol)))
+
+/*
+ *   gcc: https://gcc.gnu.org/onlinedocs/gcc/Common-Function-Attributes.html#index-aligned-function-attribute
+ *   gcc: https://gcc.gnu.org/onlinedocs/gcc/Common-Type-Attributes.html#index-aligned-type-attribute
+ *   gcc: https://gcc.gnu.org/onlinedocs/gcc/Common-Variable-Attributes.html#index-aligned-variable-attribute
+ */
+#define __aligned(x)                    __attribute__((__aligned__(x)))
+#define __aligned_largest               __attribute__((__aligned__))
+
+/*
+ * Note: users of __always_inline currently do not write "inline" themselves,
+ * which seems to be required by gcc to apply the attribute according
+ * to its docs (and also "warning: always_inline function might not be
+ * inlinable [-Wattributes]" is emitted).
+ *
+ *   gcc: https://gcc.gnu.org/onlinedocs/gcc/Common-Function-Attributes.html#index-always_005finline-function-attribute
+ * clang: mentioned
+ */
+#define __always_inline                 inline __attribute__((__always_inline__))
+
+/*
+ * The second argument is optional (default 0), so we use a variadic macro
+ * to make the shorthand.
+ *
+ * Beware: Do not apply this to functions which may return
+ * ERR_PTRs. Also, it is probably unwise to apply it to functions
+ * returning extra information in the low bits (but in that case the
+ * compiler should see some alignment anyway, when the return value is
+ * massaged by 'flags = ptr & 3; ptr &= ~3;').
+ *
+ * Optional: only supported since gcc >= 4.9
+ * Optional: not supported by icc
+ *
+ *   gcc: https://gcc.gnu.org/onlinedocs/gcc/Common-Function-Attributes.html#index-assume_005faligned-function-attribute
+ * clang: https://clang.llvm.org/docs/AttributeReference.html#assume-aligned
+ */
+#if __has_attribute(__assume_aligned__)
+# define __assume_aligned(a, ...)       __attribute__((__assume_aligned__(a, ## __VA_ARGS__)))
+#else
+# define __assume_aligned(a, ...)
+#endif
+
+/*
+ *   gcc: https://gcc.gnu.org/onlinedocs/gcc/Common-Function-Attributes.html#index-cold-function-attribute
+ *   gcc: https://gcc.gnu.org/onlinedocs/gcc/Label-Attributes.html#index-cold-label-attribute
+ */
+#define __cold                          __attribute__((__cold__))
+
+/*
+ * Note the long name.
+ *
+ *   gcc: https://gcc.gnu.org/onlinedocs/gcc/Common-Function-Attributes.html#index-const-function-attribute
+ */
+#define __attribute_const__             __attribute__((__const__))
+
+/*
+ * Optional: only supported since gcc >= 9
+ * Optional: not supported by clang
+ * Optional: not supported by icc
+ *
+ *   gcc: https://gcc.gnu.org/onlinedocs/gcc/Common-Function-Attributes.html#index-copy-function-attribute
+ */
+#if __has_attribute(__copy__)
+# define __copy(symbol)                 __attribute__((__copy__(symbol)))
+#else
+# define __copy(symbol)
+#endif
+
+/*
+ * Don't. Just don't. See commit 771c035372a0 ("deprecate the '__deprecated'
+ * attribute warnings entirely and for good") for more information.
+ *
+ *   gcc: https://gcc.gnu.org/onlinedocs/gcc/Common-Function-Attributes.html#index-deprecated-function-attribute
+ *   gcc: https://gcc.gnu.org/onlinedocs/gcc/Common-Type-Attributes.html#index-deprecated-type-attribute
+ *   gcc: https://gcc.gnu.org/onlinedocs/gcc/Common-Variable-Attributes.html#index-deprecated-variable-attribute
+ *   gcc: https://gcc.gnu.org/onlinedocs/gcc/Enumerator-Attributes.html#index-deprecated-enumerator-attribute
+ * clang: https://clang.llvm.org/docs/AttributeReference.html#deprecated
+ */
+#define __deprecated
+
+/*
+ * Optional: only supported since gcc >= 5.1
+ * Optional: not supported by clang
+ * Optional: not supported by icc
+ *
+ *   gcc: https://gcc.gnu.org/onlinedocs/gcc/Common-Type-Attributes.html#index-designated_005finit-type-attribute
+ */
+#if __has_attribute(__designated_init__)
+# define __designated_init              __attribute__((__designated_init__))
+#else
+# define __designated_init
+#endif
+
+/*
+ * Optional: not supported by clang
+ *
+ *   gcc: https://gcc.gnu.org/onlinedocs/gcc/Common-Function-Attributes.html#index-externally_005fvisible-function-attribute
+ */
+#if __has_attribute(__externally_visible__)
+# define __visible                      __attribute__((__externally_visible__))
+#else
+# define __visible
+#endif
+
+/*
+ *   gcc: https://gcc.gnu.org/onlinedocs/gcc/Common-Function-Attributes.html#index-format-function-attribute
+ * clang: https://clang.llvm.org/docs/AttributeReference.html#format
+ */
+#define __printf(a, b)                  __attribute__((__format__(printf, a, b)))
+#define __scanf(a, b)                   __attribute__((__format__(scanf, a, b)))
+
+/*
+ *   gcc: https://gcc.gnu.org/onlinedocs/gcc/Common-Function-Attributes.html#index-gnu_005finline-function-attribute
+ * clang: https://clang.llvm.org/docs/AttributeReference.html#gnu-inline
+ */
+#define __gnu_inline                    __attribute__((__gnu_inline__))
+
+/*
+ *   gcc: https://gcc.gnu.org/onlinedocs/gcc/Common-Function-Attributes.html#index-malloc-function-attribute
+ */
+#define __malloc                        __attribute__((__malloc__))
+
+/*
+ *   gcc: https://gcc.gnu.org/onlinedocs/gcc/Common-Type-Attributes.html#index-mode-type-attribute
+ *   gcc: https://gcc.gnu.org/onlinedocs/gcc/Common-Variable-Attributes.html#index-mode-variable-attribute
+ */
+#define __mode(x)                       __attribute__((__mode__(x)))
+
+/*
+ * Optional: not supported by clang
+ *
+ *  gcc: https://gcc.gnu.org/onlinedocs/gcc/Common-Function-Attributes.html#index-noclone-function-attribute
+ */
+#if __has_attribute(__noclone__)
+# define __noclone                      __attribute__((__noclone__))
+#else
+# define __noclone
+#endif
+
+/*
+ * Add the pseudo keyword 'fallthrough' so case statement blocks
+ * must end with any of these keywords:
+ *   break;
+ *   fallthrough;
+ *   goto <label>;
+ *   return [expression];
+ *
+ *  gcc: https://gcc.gnu.org/onlinedocs/gcc/Statement-Attributes.html#Statement-Attributes
+ */
+#if __has_attribute(__fallthrough__)
+# define fallthrough                    __attribute__((__fallthrough__))
+#else
+# define fallthrough                    do {} while (0)  /* fallthrough */
+#endif
+
+/*
+ * Note the missing underscores.
+ *
+ *   gcc: https://gcc.gnu.org/onlinedocs/gcc/Common-Function-Attributes.html#index-noinline-function-attribute
+ * clang: mentioned
+ */
+#define   noinline                      __attribute__((__noinline__))
+
+/*
+ * Optional: only supported since gcc >= 8
+ * Optional: not supported by clang
+ * Optional: not supported by icc
+ *
+ *   gcc: https://gcc.gnu.org/onlinedocs/gcc/Common-Variable-Attributes.html#index-nonstring-variable-attribute
+ */
+#if __has_attribute(__nonstring__)
+# define __nonstring                    __attribute__((__nonstring__))
+#else
+# define __nonstring
+#endif
+
+/*
+ *   gcc: https://gcc.gnu.org/onlinedocs/gcc/Common-Function-Attributes.html#index-noreturn-function-attribute
+ * clang: https://clang.llvm.org/docs/AttributeReference.html#noreturn
+ * clang: https://clang.llvm.org/docs/AttributeReference.html#id1
+ */
+#define __noreturn                      __attribute__((__noreturn__))
+
+/*
+ *   gcc: https://gcc.gnu.org/onlinedocs/gcc/Common-Type-Attributes.html#index-packed-type-attribute
+ * clang: https://gcc.gnu.org/onlinedocs/gcc/Common-Variable-Attributes.html#index-packed-variable-attribute
+ */
+#define __packed                        __attribute__((__packed__))
+
+/*
+ *   gcc: https://gcc.gnu.org/onlinedocs/gcc/Common-Function-Attributes.html#index-pure-function-attribute
+ */
+#define __pure                          __attribute__((__pure__))
+
+/*
+ *   gcc: https://gcc.gnu.org/onlinedocs/gcc/Common-Function-Attributes.html#index-section-function-attribute
+ *   gcc: https://gcc.gnu.org/onlinedocs/gcc/Common-Variable-Attributes.html#index-section-variable-attribute
+ * clang: https://clang.llvm.org/docs/AttributeReference.html#section-declspec-allocate
+ */
+#define __section(S)                    __attribute__((__section__(#S)))
+
+/*
+ *   gcc: https://gcc.gnu.org/onlinedocs/gcc/Common-Function-Attributes.html#index-unused-function-attribute
+ *   gcc: https://gcc.gnu.org/onlinedocs/gcc/Common-Type-Attributes.html#index-unused-type-attribute
+ *   gcc: https://gcc.gnu.org/onlinedocs/gcc/Common-Variable-Attributes.html#index-unused-variable-attribute
+ *   gcc: https://gcc.gnu.org/onlinedocs/gcc/Label-Attributes.html#index-unused-label-attribute
+ * clang: https://clang.llvm.org/docs/AttributeReference.html#maybe-unused-unused
+ */
+#define __always_unused                 __attribute__((__unused__))
+#define __maybe_unused                  __attribute__((__unused__))
+
+/*
+ *   gcc: https://gcc.gnu.org/onlinedocs/gcc/Common-Function-Attributes.html#index-used-function-attribute
+ *   gcc: https://gcc.gnu.org/onlinedocs/gcc/Common-Variable-Attributes.html#index-used-variable-attribute
+ */
+#define __used                          __attribute__((__used__))
+
+/*
+ *   gcc: https://gcc.gnu.org/onlinedocs/gcc/Common-Function-Attributes.html#index-weak-function-attribute
+ *   gcc: https://gcc.gnu.org/onlinedocs/gcc/Common-Variable-Attributes.html#index-weak-variable-attribute
+ */
+#define __weak                          __attribute__((__weak__))
+
+#endif /* __LINUX_COMPILER_ATTRIBUTES_H */
diff --git a/include/linux/compiler_types.h b/include/linux/compiler_types.h
new file mode 100644 (file)
index 0000000..1a30601
--- /dev/null
@@ -0,0 +1,246 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef __LINUX_COMPILER_TYPES_H
+#define __LINUX_COMPILER_TYPES_H
+
+#ifndef __ASSEMBLY__
+
+#ifdef __CHECKER__
+# define __user                __attribute__((noderef, address_space(1)))
+# define __kernel      __attribute__((address_space(0)))
+# define __safe                __attribute__((safe))
+# define __force       __attribute__((force))
+# define __nocast      __attribute__((nocast))
+# define __iomem       __attribute__((noderef, address_space(2)))
+# define __must_hold(x)        __attribute__((context(x,1,1)))
+# define __acquires(x) __attribute__((context(x,0,1)))
+# define __releases(x) __attribute__((context(x,1,0)))
+# define __acquire(x)  __context__(x,1)
+# define __release(x)  __context__(x,-1)
+# define __cond_lock(x,c)      ((c) ? ({ __acquire(x); 1; }) : 0)
+# define __percpu      __attribute__((noderef, address_space(3)))
+# define __rcu         __attribute__((noderef, address_space(4)))
+# define __private     __attribute__((noderef))
+extern void __chk_user_ptr(const volatile void __user *);
+extern void __chk_io_ptr(const volatile void __iomem *);
+# define ACCESS_PRIVATE(p, member) (*((typeof((p)->member) __force *) &(p)->member))
+#else /* __CHECKER__ */
+# ifdef STRUCTLEAK_PLUGIN
+#  define __user __attribute__((user))
+# else
+#  define __user
+# endif
+# define __kernel
+# define __safe
+# define __force
+# define __nocast
+# define __iomem
+# define __chk_user_ptr(x) (void)0
+# define __chk_io_ptr(x) (void)0
+# define __builtin_warning(x, y...) (1)
+# define __must_hold(x)
+# define __acquires(x)
+# define __releases(x)
+# define __acquire(x) (void)0
+# define __release(x) (void)0
+# define __cond_lock(x,c) (c)
+# define __percpu
+# define __rcu
+# define __private
+# define ACCESS_PRIVATE(p, member) ((p)->member)
+#endif /* __CHECKER__ */
+
+/* Indirect macros required for expanded argument pasting, eg. __LINE__. */
+#define ___PASTE(a,b) a##b
+#define __PASTE(a,b) ___PASTE(a,b)
+
+#ifdef __KERNEL__
+
+/* Attributes */
+#include <linux/compiler_attributes.h>
+
+/* Compiler specific macros. */
+#ifdef __clang__
+#include <linux/compiler-clang.h>
+#elif defined(__INTEL_COMPILER)
+#include <linux/compiler-intel.h>
+#elif defined(__GNUC__)
+/* The above compilers also define __GNUC__, so order is important here. */
+#include <linux/compiler-gcc.h>
+#else
+#error "Unknown compiler"
+#endif
+
+/*
+ * Some architectures need to provide custom definitions of macros provided
+ * by linux/compiler-*.h, and can do so using asm/compiler.h. We include that
+ * conditionally rather than using an asm-generic wrapper in order to avoid
+ * build failures if any C compilation, which will include this file via an
+ * -include argument in c_flags, occurs prior to the asm-generic wrappers being
+ * generated.
+ */
+#ifdef CONFIG_HAVE_ARCH_COMPILER_H
+#include <asm/compiler.h>
+#endif
+
+struct ftrace_branch_data {
+       const char *func;
+       const char *file;
+       unsigned line;
+       union {
+               struct {
+                       unsigned long correct;
+                       unsigned long incorrect;
+               };
+               struct {
+                       unsigned long miss;
+                       unsigned long hit;
+               };
+               unsigned long miss_hit[2];
+       };
+};
+
+struct ftrace_likely_data {
+       struct ftrace_branch_data       data;
+       unsigned long                   constant;
+};
+
+#ifdef CONFIG_ENABLE_MUST_CHECK
+#define __must_check           __attribute__((__warn_unused_result__))
+#else
+#define __must_check
+#endif
+
+#if defined(CC_USING_HOTPATCH)
+#define notrace                        __attribute__((hotpatch(0, 0)))
+#elif defined(CC_USING_PATCHABLE_FUNCTION_ENTRY)
+#define notrace                        __attribute__((patchable_function_entry(0, 0)))
+#else
+#define notrace                        __attribute__((__no_instrument_function__))
+#endif
+
+/*
+ * it doesn't make sense on ARM (currently the only user of __naked)
+ * to trace naked functions because then mcount is called without
+ * stack and frame pointer being set up and there is no chance to
+ * restore the lr register to the value before mcount was called.
+ */
+#define __naked                        __attribute__((__naked__)) notrace
+
+#define __compiler_offsetof(a, b)      __builtin_offsetof(a, b)
+
+/*
+ * Force always-inline if the user requests it so via the .config.
+ * Prefer gnu_inline, so that extern inline functions do not emit an
+ * externally visible function. This makes extern inline behave as per gnu89
+ * semantics rather than c99. This prevents multiple symbol definition errors
+ * of extern inline functions at link time.
+ * A lot of inline functions can cause havoc with function tracing.
+ * Do not use __always_inline here, since currently it expands to inline again
+ * (which would break users of __always_inline).
+ */
+#if !CONFIG_IS_ENABLED(OPTIMIZE_INLINING)
+#define inline inline __attribute__((__always_inline__)) __gnu_inline \
+       __inline_maybe_unused notrace
+#else
+#define inline inline                                    __gnu_inline \
+       __inline_maybe_unused notrace
+#endif
+
+/*
+ * gcc provides both __inline__ and __inline as alternate spellings of
+ * the inline keyword, though the latter is undocumented. New kernel
+ * code should only use the inline spelling, but some existing code
+ * uses __inline__. Since we #define inline above, to ensure
+ * __inline__ has the same semantics, we need this #define.
+ *
+ * However, the spelling __inline is strictly reserved for referring
+ * to the bare keyword.
+ */
+#define __inline__ inline
+
+/*
+ * GCC does not warn about unused static inline functions for -Wunused-function.
+ * Suppress the warning in clang as well by using __maybe_unused, but enable it
+ * for W=1 build. This will allow clang to find unused functions. Remove the
+ * __inline_maybe_unused entirely after fixing most of -Wunused-function warnings.
+ */
+#ifdef KBUILD_EXTRA_WARN1
+#define __inline_maybe_unused
+#else
+#define __inline_maybe_unused __maybe_unused
+#endif
+
+/*
+ * Rather then using noinline to prevent stack consumption, use
+ * noinline_for_stack instead.  For documentation reasons.
+ */
+#define noinline_for_stack noinline
+
+#endif /* __KERNEL__ */
+
+#endif /* __ASSEMBLY__ */
+
+/*
+ * The below symbols may be defined for one or more, but not ALL, of the above
+ * compilers. We don't consider that to be an error, so set them to nothing.
+ * For example, some of them are for compiler specific plugins.
+ */
+#ifndef __latent_entropy
+# define __latent_entropy
+#endif
+
+#ifndef __randomize_layout
+# define __randomize_layout __designated_init
+#endif
+
+#ifndef __no_randomize_layout
+# define __no_randomize_layout
+#endif
+
+#ifndef randomized_struct_fields_start
+# define randomized_struct_fields_start
+# define randomized_struct_fields_end
+#endif
+
+#ifndef asm_volatile_goto
+#define asm_volatile_goto(x...) asm goto(x)
+#endif
+
+#ifdef CONFIG_CC_HAS_ASM_INLINE
+#define asm_inline asm __inline
+#else
+#define asm_inline asm
+#endif
+
+#ifndef __no_fgcse
+# define __no_fgcse
+#endif
+
+/* Are two types/vars the same type (ignoring qualifiers)? */
+#define __same_type(a, b) __builtin_types_compatible_p(typeof(a), typeof(b))
+
+/* Is this type a native word size -- useful for atomic operations */
+#define __native_word(t) \
+       (sizeof(t) == sizeof(char) || sizeof(t) == sizeof(short) || \
+        sizeof(t) == sizeof(int) || sizeof(t) == sizeof(long))
+
+/* Helpers for emitting diagnostics in pragmas. */
+#ifndef __diag
+#define __diag(string)
+#endif
+
+#ifndef __diag_GCC
+#define __diag_GCC(version, severity, string)
+#endif
+
+#define __diag_push()  __diag(push)
+#define __diag_pop()   __diag(pop)
+
+#define __diag_ignore(compiler, version, option, comment) \
+       __diag_ ## compiler(version, ignore, option)
+#define __diag_warn(compiler, version, option, comment) \
+       __diag_ ## compiler(version, warn, option)
+#define __diag_error(compiler, version, option, comment) \
+       __diag_ ## compiler(version, error, option)
+
+#endif /* __LINUX_COMPILER_TYPES_H */
index de9ef90..9dc96c8 100644 (file)
@@ -26,8 +26,6 @@
 #include <linux/types.h>
 #include <linux/string.h>
 
-#define noinline __attribute__((noinline))
-
 /* we use this so that we can do without the ctype library */
 #define is_digit(c)    ((c) >= '0' && (c) <= '9')
 
diff --git a/scripts/Kconfig.include b/scripts/Kconfig.include
new file mode 100644 (file)
index 0000000..dad5583
--- /dev/null
@@ -0,0 +1,30 @@
+# Kconfig helper macros
+
+# Convenient variables
+comma       := ,
+quote       := "
+squote      := '
+empty       :=
+space       := $(empty) $(empty)
+dollar      := $
+right_paren := )
+left_paren  := (
+
+# $(if-success,<command>,<then>,<else>)
+# Return <then> if <command> exits with 0, <else> otherwise.
+if-success = $(shell,{ $(1); } >/dev/null 2>&1 && echo "$(2)" || echo "$(3)")
+
+# $(success,<command>)
+# Return y if <command> exits with 0, n otherwise
+success = $(if-success,$(1),y,n)
+
+# $(cc-option,<flag>)
+# Return y if the compiler supports <flag>, n otherwise
+cc-option = $(success,$(CC) -Werror $(1) -E -x c /dev/null -o /dev/null)
+
+# $(ld-option,<flag>)
+# Return y if the linker supports <flag>, n otherwise
+ld-option = $(success,$(LD) -v $(1))
+
+# gcc version including patch level
+gcc-version := $(shell,$(srctree)/scripts/gcc-version.sh -p $(CC) | sed 's/^0*//')
index edba365..9544e57 100755 (executable)
@@ -62,7 +62,10 @@ my $conststructsfile = "$D/const_structs.checkpatch";
 my $typedefsfile = "";
 my $u_boot = 0;
 my $color = "auto";
-my $allow_c99_comments = 1;
+my $allow_c99_comments = 1; # Can be overridden by --ignore C99_COMMENT_TOLERANCE
+# git output parsing needs US English output, so first set backtick child process LANGUAGE
+my $git_command ='export LANGUAGE=en_US.UTF-8; git';
+my $tabsize = 8;
 
 sub help {
        my ($exitcode) = @_;
@@ -99,6 +102,7 @@ Options:
                              if exceeded, warn on patches
                              requires --strict for use with --file
   --min-conf-desc-length=n   set the min description length, if shorter, warn
+  --tab-size=n               set the number of spaces for tab (default $tabsize)
   --root=PATH                PATH to the kernel tree root
   --no-summary               suppress the per-file summary
   --mailback                 only produce a report in case of warnings/errors
@@ -217,6 +221,7 @@ GetOptions(
        'list-types!'   => \$list_types,
        'max-line-length=i' => \$max_line_length,
        'min-conf-desc-length=i' => \$min_conf_desc_length,
+       'tab-size=i'    => \$tabsize,
        'root=s'        => \$root,
        'summary!'      => \$summary,
        'mailback!'     => \$mailback,
@@ -270,6 +275,9 @@ if ($color =~ /^[01]$/) {
        die "Invalid color mode: $color\n";
 }
 
+# skip TAB size 1 to avoid additional checks on $tabsize - 1
+die "Invalid TAB size: $tabsize\n" if ($tabsize < 2);
+
 sub hash_save_array_words {
        my ($hashRef, $arrayRef) = @_;
 
@@ -473,8 +481,19 @@ our $logFunctions = qr{(?x:
        seq_vprintf|seq_printf|seq_puts
 )};
 
+our $allocFunctions = qr{(?x:
+       (?:(?:devm_)?
+               (?:kv|k|v)[czm]alloc(?:_node|_array)? |
+               kstrdup(?:_const)? |
+               kmemdup(?:_nul)?) |
+       (?:\w+)?alloc_skb(?:_ip_align)? |
+                               # dev_alloc_skb/netdev_alloc_skb, et al
+       dma_alloc_coherent
+)};
+
 our $signature_tags = qr{(?xi:
        Signed-off-by:|
+       Co-developed-by:|
        Acked-by:|
        Tested-by:|
        Reviewed-by:|
@@ -580,6 +599,27 @@ foreach my $entry (@mode_permission_funcs) {
 }
 $mode_perms_search = "(?:${mode_perms_search})";
 
+our %deprecated_apis = (
+       "synchronize_rcu_bh"                    => "synchronize_rcu",
+       "synchronize_rcu_bh_expedited"          => "synchronize_rcu_expedited",
+       "call_rcu_bh"                           => "call_rcu",
+       "rcu_barrier_bh"                        => "rcu_barrier",
+       "synchronize_sched"                     => "synchronize_rcu",
+       "synchronize_sched_expedited"           => "synchronize_rcu_expedited",
+       "call_rcu_sched"                        => "call_rcu",
+       "rcu_barrier_sched"                     => "rcu_barrier",
+       "get_state_synchronize_sched"           => "get_state_synchronize_rcu",
+       "cond_synchronize_sched"                => "cond_synchronize_rcu",
+);
+
+#Create a search pattern for all these strings to speed up a loop below
+our $deprecated_apis_search = "";
+foreach my $entry (keys %deprecated_apis) {
+       $deprecated_apis_search .= '|' if ($deprecated_apis_search ne "");
+       $deprecated_apis_search .= $entry;
+}
+$deprecated_apis_search = "(?:${deprecated_apis_search})";
+
 our $mode_perms_world_writable = qr{
        S_IWUGO         |
        S_IWOTH         |
@@ -777,12 +817,12 @@ sub build_types {
                  }x;
        $Type   = qr{
                        $NonptrType
-                       (?:(?:\s|\*|\[\])+\s*const|(?:\s|\*\s*(?:const\s*)?|\[\])+|(?:\s*\[\s*\])+)?
+                       (?:(?:\s|\*|\[\])+\s*const|(?:\s|\*\s*(?:const\s*)?|\[\])+|(?:\s*\[\s*\])+){0,4}
                        (?:\s+$Inline|\s+$Modifier)*
                  }x;
        $TypeMisordered = qr{
                        $NonptrTypeMisordered
-                       (?:(?:\s|\*|\[\])+\s*const|(?:\s|\*\s*(?:const\s*)?|\[\])+|(?:\s*\[\s*\])+)?
+                       (?:(?:\s|\*|\[\])+\s*const|(?:\s|\*\s*(?:const\s*)?|\[\])+|(?:\s*\[\s*\])+){0,4}
                        (?:\s+$Inline|\s+$Modifier)*
                  }x;
        $Declare        = qr{(?:$Storage\s+(?:$Inline\s+)?)?$Type};
@@ -847,14 +887,18 @@ sub seed_camelcase_file {
        }
 }
 
+our %maintained_status = ();
+
 sub is_maintained_obsolete {
        my ($filename) = @_;
 
        return 0 if (!$tree || !(-e "$root/scripts/get_maintainer.pl"));
 
-       my $status = `perl $root/scripts/get_maintainer.pl --status --nom --nol --nogit --nogit-fallback -f $filename 2>&1`;
+       if (!exists($maintained_status{$filename})) {
+               $maintained_status{$filename} = `perl $root/scripts/get_maintainer.pl --status --nom --nol --nogit --nogit-fallback -f $filename 2>&1`;
+       }
 
-       return $status =~ /obsolete/i;
+       return $maintained_status{$filename} =~ /obsolete/i;
 }
 
 sub is_SPDX_License_valid {
@@ -879,7 +923,7 @@ sub seed_camelcase_includes {
        $camelcase_seeded = 1;
 
        if (-e ".git") {
-               my $git_last_include_commit = `git log --no-merges --pretty=format:"%h%n" -1 -- include`;
+               my $git_last_include_commit = `${git_command} log --no-merges --pretty=format:"%h%n" -1 -- include`;
                chomp $git_last_include_commit;
                $camelcase_cache = ".checkpatch-camelcase.git.$git_last_include_commit";
        } else {
@@ -907,7 +951,7 @@ sub seed_camelcase_includes {
        }
 
        if (-e ".git") {
-               $files = `git ls-files "include/*.h"`;
+               $files = `${git_command} ls-files "include/*.h"`;
                @include_files = split('\n', $files);
        }
 
@@ -931,13 +975,13 @@ sub git_commit_info {
 
        return ($id, $desc) if ((which("git") eq "") || !(-e ".git"));
 
-       my $output = `git log --no-color --format='%H %s' -1 $commit 2>&1`;
+       my $output = `${git_command} log --no-color --format='%H %s' -1 $commit 2>&1`;
        $output =~ s/^\s*//gm;
        my @lines = split("\n", $output);
 
        return ($id, $desc) if ($#lines < 0);
 
-       if ($lines[0] =~ /^error: short SHA1 $commit is ambiguous\./) {
+       if ($lines[0] =~ /^error: short SHA1 $commit is ambiguous/) {
 # Maybe one day convert this block of bash into something that returns
 # all matching commit ids, but it's very slow...
 #
@@ -981,7 +1025,7 @@ if ($git) {
                } else {
                        $git_range = "-1 $commit_expr";
                }
-               my $lines = `git log --no-color --no-merges --pretty=format:'%H %s' $git_range`;
+               my $lines = `${git_command} log --no-color --no-merges --pretty=format:'%H %s' $git_range`;
                foreach my $line (split(/\n/, $lines)) {
                        $line =~ /^([0-9a-fA-F]{40,40}) (.*)$/;
                        next if (!defined($1) || !defined($2));
@@ -996,6 +1040,7 @@ if ($git) {
 }
 
 my $vname;
+$allow_c99_comments = !defined $ignore_type{"C99_COMMENT_TOLERANCE"};
 for my $filename (@ARGV) {
        my $FILE;
        if ($git) {
@@ -1086,6 +1131,7 @@ sub parse_email {
        my ($formatted_email) = @_;
 
        my $name = "";
+       my $name_comment = "";
        my $address = "";
        my $comment = "";
 
@@ -1118,6 +1164,10 @@ sub parse_email {
 
        $name = trim($name);
        $name =~ s/^\"|\"$//g;
+       $name =~ s/(\s*\([^\)]+\))\s*//;
+       if (defined($1)) {
+               $name_comment = trim($1);
+       }
        $address = trim($address);
        $address =~ s/^\<|\>$//g;
 
@@ -1126,7 +1176,7 @@ sub parse_email {
                $name = "\"$name\"";
        }
 
-       return ($name, $address, $comment);
+       return ($name, $name_comment, $address, $comment);
 }
 
 sub format_email {
@@ -1152,6 +1202,23 @@ sub format_email {
        return $formatted_email;
 }
 
+sub reformat_email {
+       my ($email) = @_;
+
+       my ($email_name, $name_comment, $email_address, $comment) = parse_email($email);
+       return format_email($email_name, $email_address);
+}
+
+sub same_email_addresses {
+       my ($email1, $email2) = @_;
+
+       my ($email1_name, $name1_comment, $email1_address, $comment1) = parse_email($email1);
+       my ($email2_name, $name2_comment, $email2_address, $comment2) = parse_email($email2);
+
+       return $email1_name eq $email2_name &&
+              $email1_address eq $email2_address;
+}
+
 sub which {
        my ($bin) = @_;
 
@@ -1185,7 +1252,7 @@ sub expand_tabs {
                if ($c eq "\t") {
                        $res .= ' ';
                        $n++;
-                       for (; ($n % 8) != 0; $n++) {
+                       for (; ($n % $tabsize) != 0; $n++) {
                                $res .= ' ';
                        }
                        next;
@@ -2198,7 +2265,7 @@ sub string_find_replace {
 sub tabify {
        my ($leading) = @_;
 
-       my $source_indent = 8;
+       my $source_indent = $tabsize;
        my $max_spaces_before_tab = $source_indent - 1;
        my $spaces_to_tab = " " x $source_indent;
 
@@ -2240,6 +2307,19 @@ sub pos_last_openparen {
        return length(expand_tabs(substr($line, 0, $last_openparen))) + 1;
 }
 
+sub get_raw_comment {
+       my ($line, $rawline) = @_;
+       my $comment = '';
+
+       for my $i (0 .. (length($line) - 1)) {
+               if (substr($line, $i, 1) eq "$;") {
+                       $comment .= substr($rawline, $i, 1);
+               }
+       }
+
+       return $comment;
+}
+
 # Checks specific to U-Boot
 sub u_boot_line {
        my ($realfile, $line,  $herecurr) = @_;
@@ -2297,6 +2377,7 @@ sub process {
        my $is_binding_patch = -1;
        my $in_header_lines = $file ? 0 : 1;
        my $in_commit_log = 0;          #Scanning lines before patch
+       my $has_patch_separator = 0;    #Found a --- line
        my $has_commit_log = 0;         #Encountered lines before patch
        my $commit_log_lines = 0;       #Number of commit log lines
        my $commit_log_possible_stack_dump = 0;
@@ -2436,6 +2517,7 @@ sub process {
                $sline =~ s/$;/ /g;     #with comments as spaces
 
                my $rawline = $rawlines[$linenr - 1];
+               my $raw_comment = get_raw_comment($line, $rawline);
 
 # check if it's a mode change, rename or start of a patch
                if (!$in_commit_log &&
@@ -2607,21 +2689,26 @@ sub process {
                        $author = $1;
                        $author = encode("utf8", $author) if ($line =~ /=\?utf-8\?/i);
                        $author =~ s/"//g;
+                       $author = reformat_email($author);
                }
 
 # Check the patch for a signoff:
-               if ($line =~ /^\s*signed-off-by:/i) {
+               if ($line =~ /^\s*signed-off-by:\s*(.*)/i) {
                        $signoff++;
                        $in_commit_log = 0;
                        if ($author ne '') {
-                               my $l = $line;
-                               $l =~ s/"//g;
-                               if ($l =~ /^\s*signed-off-by:\s*\Q$author\E/i) {
-                                   $authorsignoff = 1;
+                               if (same_email_addresses($1, $author)) {
+                                       $authorsignoff = 1;
                                }
                        }
                }
 
+# Check for patch separator
+               if ($line =~ /^---$/) {
+                       $has_patch_separator = 1;
+                       $in_commit_log = 0;
+               }
+
 # Check if MAINTAINERS is being updated.  If so, there's probably no need to
 # emit the "does MAINTAINERS need updating?" message on file add/move/delete
                if ($line =~ /^\s*MAINTAINERS\s*\|/) {
@@ -2667,7 +2754,7 @@ sub process {
                                }
                        }
 
-                       my ($email_name, $email_address, $comment) = parse_email($email);
+                       my ($email_name, $name_comment, $email_address, $comment) = parse_email($email);
                        my $suggested_email = format_email(($email_name, $email_address));
                        if ($suggested_email eq "") {
                                ERROR("BAD_SIGN_OFF",
@@ -2678,9 +2765,7 @@ sub process {
                                $dequoted =~ s/" </ </;
                                # Don't force email to have quotes
                                # Allow just an angle bracketed address
-                               if ("$dequoted$comment" ne $email &&
-                                   "<$email_address>$comment" ne $email &&
-                                   "$suggested_email$comment" ne $email) {
+                               if (!same_email_addresses($email, $suggested_email)) {
                                        WARN("BAD_SIGN_OFF",
                                             "email address '$email' might be better as '$suggested_email$comment'\n" . $herecurr);
                                }
@@ -2696,6 +2781,24 @@ sub process {
                        } else {
                                $signatures{$sig_nospace} = 1;
                        }
+
+# Check Co-developed-by: immediately followed by Signed-off-by: with same name and email
+                       if ($sign_off =~ /^co-developed-by:$/i) {
+                               if ($email eq $author) {
+                                       WARN("BAD_SIGN_OFF",
+                                             "Co-developed-by: should not be used to attribute nominal patch author '$author'\n" . "$here\n" . $rawline);
+                               }
+                               if (!defined $lines[$linenr]) {
+                                       WARN("BAD_SIGN_OFF",
+                                             "Co-developed-by: must be immediately followed by Signed-off-by:\n" . "$here\n" . $rawline);
+                               } elsif ($rawlines[$linenr] !~ /^\s*signed-off-by:\s*(.*)/i) {
+                                       WARN("BAD_SIGN_OFF",
+                                            "Co-developed-by: must be immediately followed by Signed-off-by:\n" . "$here\n" . $rawline . "\n" .$rawlines[$linenr]);
+                               } elsif ($1 ne $email) {
+                                       WARN("BAD_SIGN_OFF",
+                                            "Co-developed-by and Signed-off-by: name/email do not match \n" . "$here\n" . $rawline . "\n" .$rawlines[$linenr]);
+                               }
+                       }
                }
 
 # Check email subject for common tools that don't need to be mentioned
@@ -2705,10 +2808,10 @@ sub process {
                             "A patch subject line should describe the change not the tool that found it\n" . $herecurr);
                }
 
-# Check for unwanted Gerrit info
-               if ($in_commit_log && $line =~ /^\s*change-id:/i) {
+# Check for Gerrit Change-Ids not in any patch context
+               if ($realfile eq '' && !$has_patch_separator && $line =~ /^\s*change-id:/i) {
                        ERROR("GERRIT_CHANGE_ID",
-                             "Remove Gerrit Change-Id's before submitting upstream.\n" . $herecurr);
+                             "Remove Gerrit Change-Id's before submitting upstream\n" . $herecurr);
                }
 
 # Check if the commit log is in a possible stack dump
@@ -2716,8 +2819,10 @@ sub process {
                    ($line =~ /^\s*(?:WARNING:|BUG:)/ ||
                     $line =~ /^\s*\[\s*\d+\.\d{6,6}\s*\]/ ||
                                        # timestamp
-                    $line =~ /^\s*\[\<[0-9a-fA-F]{8,}\>\]/)) {
-                                       # stack dump address
+                    $line =~ /^\s*\[\<[0-9a-fA-F]{8,}\>\]/) ||
+                    $line =~ /^(?:\s+\w+:\s+[0-9a-fA-F]+){3,3}/ ||
+                    $line =~ /^\s*\#\d+\s*\[[0-9a-fA-F]+\]\s*\w+ at [0-9a-fA-F]+/) {
+                                       # stack dump address styles
                        $commit_log_possible_stack_dump = 1;
                }
 
@@ -2744,7 +2849,7 @@ sub process {
 
 # Check for git id commit length and improperly formed commit descriptions
                if ($in_commit_log && !$commit_log_possible_stack_dump &&
-                   $line !~ /^\s*(?:Link|Patchwork|http|https|BugLink):/i &&
+                   $line !~ /^\s*(?:Link|Patchwork|http|https|BugLink|base-commit):/i &&
                    $line !~ /^This reverts commit [0-9a-f]{7,40}/ &&
                    ($line =~ /\bcommit\s+[0-9a-f]{5,}\b/i ||
                     ($line =~ /(?:\s|^)[0-9a-f]{12,40}(?:[\s"'\(\[]|$)/i &&
@@ -2813,6 +2918,14 @@ sub process {
                             "added, moved or deleted file(s), does MAINTAINERS need updating?\n" . $herecurr);
                }
 
+# Check for adding new DT bindings not in schema format
+               if (!$in_commit_log &&
+                   ($line =~ /^new file mode\s*\d+\s*$/) &&
+                   ($realfile =~ m@^Documentation/devicetree/bindings/.*\.txt$@)) {
+                       WARN("DT_SCHEMA_BINDING_PATCH",
+                            "DT bindings should be in DT schema format. See: Documentation/devicetree/writing-schema.rst\n");
+               }
+
 # Check for wrappage within a valid hunk of the file
                if ($realcnt != 0 && $line !~ m{^(?:\+|-| |\\ No newline|$)}) {
                        ERROR("CORRUPTED_PATCH",
@@ -2889,6 +3002,17 @@ sub process {
                        }
                }
 
+# check for invalid commit id
+               if ($in_commit_log && $line =~ /(^fixes:|\bcommit)\s+([0-9a-f]{6,40})\b/i) {
+                       my $id;
+                       my $description;
+                       ($id, $description) = git_commit_info($2, undef, undef);
+                       if (!defined($id)) {
+                               WARN("UNKNOWN_COMMIT_ID",
+                                    "Unknown commit id '$2', maybe rebased or not pulled?\n" . $herecurr);
+                       }
+               }
+
 # ignore non-hunk lines and lines being removed
                next if (!$hunk_line || $line =~ /^-/);
 
@@ -3018,7 +3142,7 @@ sub process {
                        my @compats = $rawline =~ /\"([a-zA-Z0-9\-\,\.\+_]+)\"/g;
 
                        my $dt_path = $root . "/Documentation/devicetree/bindings/";
-                       my $vp_file = $dt_path . "vendor-prefixes.txt";
+                       my $vp_file = $dt_path . "vendor-prefixes.yaml";
 
                        foreach my $compat (@compats) {
                                my $compat2 = $compat;
@@ -3033,7 +3157,7 @@ sub process {
 
                                next if $compat !~ /^([a-zA-Z0-9\-]+)\,/;
                                my $vendor = $1;
-                               `grep -Eq "^$vendor\\b" $vp_file`;
+                               `grep -Eq "\\"\\^\Q$vendor\E,\\.\\*\\":" $vp_file`;
                                if ( $? >> 8 ) {
                                        WARN("UNDOCUMENTED_DT_STRING",
                                             "DT compatible string vendor \"$vendor\" appears un-documented -- check $vp_file\n" . $herecurr);
@@ -3051,22 +3175,41 @@ sub process {
                                        $comment = '/*';
                                } elsif ($realfile =~ /\.(c|dts|dtsi)$/) {
                                        $comment = '//';
-                               } elsif (($checklicenseline == 2) || $realfile =~ /\.(sh|pl|py|awk|tc)$/) {
+                               } elsif (($checklicenseline == 2) || $realfile =~ /\.(sh|pl|py|awk|tc|yaml)$/) {
                                        $comment = '#';
                                } elsif ($realfile =~ /\.rst$/) {
                                        $comment = '..';
                                }
 
+# check SPDX comment style for .[chsS] files
+                               if ($realfile =~ /\.[chsS]$/ &&
+                                   $rawline =~ /SPDX-License-Identifier:/ &&
+                                   $rawline !~ m@^\+\s*\Q$comment\E\s*@) {
+                                       WARN("SPDX_LICENSE_TAG",
+                                            "Improper SPDX comment style for '$realfile', please use '$comment' instead\n" . $herecurr);
+                               }
+
                                if ($comment !~ /^$/ &&
-                                   $rawline !~ /^\+\Q$comment\E SPDX-License-Identifier: /) {
-                                        WARN("SPDX_LICENSE_TAG",
-                                             "Missing or malformed SPDX-License-Identifier tag in line $checklicenseline\n" . $herecurr);
+                                   $rawline !~ m@^\+\Q$comment\E SPDX-License-Identifier: @) {
+                                       WARN("SPDX_LICENSE_TAG",
+                                            "Missing or malformed SPDX-License-Identifier tag in line $checklicenseline\n" . $herecurr);
                                } elsif ($rawline =~ /(SPDX-License-Identifier: .*)/) {
-                                        my $spdx_license = $1;
-                                        if (!is_SPDX_License_valid($spdx_license)) {
-                                                 WARN("SPDX_LICENSE_TAG",
-                                                      "'$spdx_license' is not supported in LICENSES/...\n" . $herecurr);
-                                        }
+                                       my $spdx_license = $1;
+                                       if (!is_SPDX_License_valid($spdx_license)) {
+                                               WARN("SPDX_LICENSE_TAG",
+                                                    "'$spdx_license' is not supported in LICENSES/...\n" . $herecurr);
+                                       }
+                                       if ($realfile =~ m@^Documentation/devicetree/bindings/@ &&
+                                           not $spdx_license =~ /GPL-2\.0.*BSD-2-Clause/) {
+                                               my $msg_level = \&WARN;
+                                               $msg_level = \&CHK if ($file);
+                                               if (&{$msg_level}("SPDX_LICENSE_TAG",
+
+                                                                 "DT binding documents should be licensed (GPL-2.0-only OR BSD-2-Clause)\n" . $herecurr) &&
+                                                   $fix) {
+                                                       $fixed[$fixlinenr] =~ s/SPDX-License-Identifier: .*/SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)/;
+                                               }
+                                       }
                                }
                        }
                }
@@ -3074,6 +3217,14 @@ sub process {
 # check we are in a valid source file if not then ignore this hunk
                next if ($realfile !~ /\.(h|c|s|S|sh|dtsi|dts)$/);
 
+# check for using SPDX-License-Identifier on the wrong line number
+               if ($realline != $checklicenseline &&
+                   $rawline =~ /\bSPDX-License-Identifier:/ &&
+                   substr($line, @-, @+ - @-) eq "$;" x (@+ - @-)) {
+                       WARN("SPDX_LICENSE_TAG",
+                            "Misplaced SPDX-License-Identifier tag - use line $checklicenseline instead\n" . $herecurr);
+               }
+
 # line length limit (with some exclusions)
 #
 # There are a few types of lines that may extend beyond $max_line_length:
@@ -3152,7 +3303,7 @@ sub process {
                next if ($realfile !~ /\.(h|c|pl|dtsi|dts)$/);
 
 # at the beginning of a line any tabs must come first and anything
-# more than 8 must use tabs.
+# more than $tabsize must use tabs.
                if ($rawline =~ /^\+\s* \t\s*\S/ ||
                    $rawline =~ /^\+\s*        \s*/) {
                        my $herevet = "$here\n" . cat_vet($rawline) . "\n";
@@ -3171,7 +3322,7 @@ sub process {
                                "please, no space before tabs\n" . $herevet) &&
                            $fix) {
                                while ($fixed[$fixlinenr] =~
-                                          s/(^\+.*) {8,8}\t/$1\t\t/) {}
+                                          s/(^\+.*) {$tabsize,$tabsize}\t/$1\t\t/) {}
                                while ($fixed[$fixlinenr] =~
                                           s/(^\+.*) +\t/$1\t/) {}
                        }
@@ -3193,11 +3344,11 @@ sub process {
                if ($perl_version_ok &&
                    $sline =~ /^\+\t+( +)(?:$c90_Keywords\b|\{\s*$|\}\s*(?:else\b|while\b|\s*$)|$Declare\s*$Ident\s*[;=])/) {
                        my $indent = length($1);
-                       if ($indent % 8) {
+                       if ($indent % $tabsize) {
                                if (WARN("TABSTOP",
                                         "Statements should start on a tabstop\n" . $herecurr) &&
                                    $fix) {
-                                       $fixed[$fixlinenr] =~ s@(^\+\t+) +@$1 . "\t" x ($indent/8)@e;
+                                       $fixed[$fixlinenr] =~ s@(^\+\t+) +@$1 . "\t" x ($indent/$tabsize)@e;
                                }
                        }
                }
@@ -3215,8 +3366,8 @@ sub process {
                                my $newindent = $2;
 
                                my $goodtabindent = $oldindent .
-                                       "\t" x ($pos / 8) .
-                                       " "  x ($pos % 8);
+                                       "\t" x ($pos / $tabsize) .
+                                       " "  x ($pos % $tabsize);
                                my $goodspaceindent = $oldindent . " "  x $pos;
 
                                if ($newindent ne $goodtabindent &&
@@ -3687,11 +3838,11 @@ sub process {
                        #print "line<$line> prevline<$prevline> indent<$indent> sindent<$sindent> check<$check> continuation<$continuation> s<$s> cond_lines<$cond_lines> stat_real<$stat_real> stat<$stat>\n";
 
                        if ($check && $s ne '' &&
-                           (($sindent % 8) != 0 ||
+                           (($sindent % $tabsize) != 0 ||
                             ($sindent < $indent) ||
                             ($sindent == $indent &&
                              ($s !~ /^\s*(?:\}|\{|else\b)/)) ||
-                            ($sindent > $indent + 8))) {
+                            ($sindent > $indent + $tabsize))) {
                                WARN("SUSPECT_CODE_INDENT",
                                     "suspect code indent for conditional statements ($indent, $sindent)\n" . $herecurr . "$stat_real\n");
                        }
@@ -3917,14 +4068,23 @@ sub process {
                        WARN("STATIC_CONST_CHAR_ARRAY",
                             "static const char * array should probably be static const char * const\n" .
                                $herecurr);
-               }
+               }
+
+# check for initialized const char arrays that should be static const
+               if ($line =~ /^\+\s*const\s+(char|unsigned\s+char|_*u8|(?:[us]_)?int8_t)\s+\w+\s*\[\s*(?:\w+\s*)?\]\s*=\s*"/) {
+                       if (WARN("STATIC_CONST_CHAR_ARRAY",
+                                "const array should probably be static const\n" . $herecurr) &&
+                           $fix) {
+                               $fixed[$fixlinenr] =~ s/(^.\s*)const\b/${1}static const/;
+                       }
+               }
 
 # check for static char foo[] = "bar" declarations.
                if ($line =~ /\bstatic\s+char\s+(\w+)\s*\[\s*\]\s*=\s*"/) {
                        WARN("STATIC_CONST_CHAR_ARRAY",
                             "static char array declaration should probably be static const char\n" .
                                $herecurr);
-               }
+               }
 
 # check for const <foo> const where <foo> is not a pointer or array type
                if ($sline =~ /\bconst\s+($BasicType)\s+const\b/) {
@@ -3959,7 +4119,7 @@ sub process {
                }
 
 # check for function declarations without arguments like "int foo()"
-               if ($line =~ /(\b$Type\s+$Ident)\s*\(\s*\)/) {
+               if ($line =~ /(\b$Type\s*$Ident)\s*\(\s*\)/) {
                        if (ERROR("FUNCTION_WITHOUT_ARGS",
                                  "Bad function definition - $1() should probably be $1(void)\n" . $herecurr) &&
                            $fix) {
@@ -4070,15 +4230,6 @@ sub process {
                             "Prefer [subsystem eg: netdev]_$level2([subsystem]dev, ... then dev_$level2(dev, ... then pr_$level(...  to printk(KERN_$orig ...\n" . $herecurr);
                }
 
-               if ($line =~ /\bpr_warning\s*\(/) {
-                       if (WARN("PREFER_PR_LEVEL",
-                                "Prefer pr_warn(... to pr_warning(...\n" . $herecurr) &&
-                           $fix) {
-                               $fixed[$fixlinenr] =~
-                                   s/\bpr_warning\b/pr_warn/;
-                       }
-               }
-
                if ($line =~ /\bdev_printk\s*\(\s*KERN_([A-Z]+)/) {
                        my $orig = $1;
                        my $level = lc($orig);
@@ -4536,7 +4687,7 @@ sub process {
                                            ($op eq '>' &&
                                             $ca =~ /<\S+\@\S+$/))
                                        {
-                                               $ok = 1;
+                                               $ok = 1;
                                        }
 
                                        # for asm volatile statements
@@ -4632,7 +4783,7 @@ sub process {
 
 # closing brace should have a space following it when it has anything
 # on the line
-               if ($line =~ /}(?!(?:,|;|\)))\S/) {
+               if ($line =~ /}(?!(?:,|;|\)|\}))\S/) {
                        if (ERROR("SPACING",
                                  "space required after that close brace '}'\n" . $herecurr) &&
                            $fix) {
@@ -4871,7 +5022,7 @@ sub process {
                        # conditional.
                        substr($s, 0, length($c), '');
                        $s =~ s/\n.*//g;
-                       $s =~ s/$;//g;  # Remove any comments
+                       $s =~ s/$;//g;  # Remove any comments
                        if (length($c) && $s !~ /^\s*{?\s*\\*\s*$/ &&
                            $c !~ /}\s*while\s*/)
                        {
@@ -4910,7 +5061,7 @@ sub process {
 # if and else should not have general statements after it
                if ($line =~ /^.\s*(?:}\s*)?else\b(.*)/) {
                        my $s = $1;
-                       $s =~ s/$;//g;  # Remove any comments
+                       $s =~ s/$;//g;  # Remove any comments
                        if ($s !~ /^\s*(?:\sif|(?:{|)\s*\\?\s*$)/) {
                                ERROR("TRAILING_STATEMENTS",
                                      "trailing statements should be on next line\n" . $herecurr);
@@ -4982,24 +5133,14 @@ sub process {
                while ($line =~ m{($Constant|$Lval)}g) {
                        my $var = $1;
 
-#gcc binary extension
-                       if ($var =~ /^$Binary$/) {
-                               if (WARN("GCC_BINARY_CONSTANT",
-                                        "Avoid gcc v4.3+ binary constant extension: <$var>\n" . $herecurr) &&
-                                   $fix) {
-                                       my $hexval = sprintf("0x%x", oct($var));
-                                       $fixed[$fixlinenr] =~
-                                           s/\b$var\b/$hexval/;
-                               }
-                       }
-
 #CamelCase
                        if ($var !~ /^$Constant$/ &&
                            $var =~ /[A-Z][a-z]|[a-z][A-Z]/ &&
 #Ignore Page<foo> variants
                            $var !~ /^(?:Clear|Set|TestClear|TestSet|)Page[A-Z]/ &&
-#Ignore SI style variants like nS, mV and dB (ie: max_uV, regulator_min_uA_show)
-                           $var !~ /^(?:[a-z_]*?)_?[a-z][A-Z](?:_[a-z_]+)?$/ &&
+#Ignore SI style variants like nS, mV and dB
+#(ie: max_uV, regulator_min_uA_show, RANGE_mA_VALUE)
+                           $var !~ /^(?:[a-z0-9_]*|[A-Z0-9_]*)?_?[a-z][A-Z](?:_[a-z0-9_]+|_[A-Z0-9_]+)?$/ &&
 #Ignore some three character SI units explicitly, like MiB and KHz
                            $var !~ /^(?:[a-z_]*?)_?(?:[KMGT]iB|[KMGT]?Hz)(?:_[a-z_]+)?$/) {
                                while ($var =~ m{($Ident)}g) {
@@ -5096,7 +5237,7 @@ sub process {
                        {
                        }
 
-                       # Flatten any obvious string concatentation.
+                       # Flatten any obvious string concatenation.
                        while ($dstat =~ s/($String)\s*$Ident/$1/ ||
                               $dstat =~ s/$Ident\s*($String)/$1/)
                        {
@@ -5174,7 +5315,7 @@ sub process {
                                next if ($arg =~ /\.\.\./);
                                next if ($arg =~ /^type$/i);
                                my $tmp_stmt = $define_stmt;
-                               $tmp_stmt =~ s/\b(typeof|__typeof__|__builtin\w+|typecheck\s*\(\s*$Type\s*,|\#+)\s*\(*\s*$arg\s*\)*\b//g;
+                               $tmp_stmt =~ s/\b(sizeof|typeof|__typeof__|__builtin\w+|typecheck\s*\(\s*$Type\s*,|\#+)\s*\(*\s*$arg\s*\)*\b//g;
                                $tmp_stmt =~ s/\#+\s*$arg\b//g;
                                $tmp_stmt =~ s/\b$arg\s*\#\#//g;
                                my $use_cnt = () = $tmp_stmt =~ /\b$arg\b/g;
@@ -5573,7 +5714,8 @@ sub process {
                        my ($s, $c) = ctx_statement_block($linenr - 3, $realcnt, 0);
 #                      print("line: <$line>\nprevline: <$prevline>\ns: <$s>\nc: <$c>\n\n\n");
 
-                       if ($s =~ /(?:^|\n)[ \+]\s*(?:$Type\s*)?\Q$testval\E\s*=\s*(?:\([^\)]*\)\s*)?\s*(?:devm_)?(?:[kv][czm]alloc(?:_node|_array)?\b|kstrdup|kmemdup|(?:dev_)?alloc_skb)/) {
+                       if ($s =~ /(?:^|\n)[ \+]\s*(?:$Type\s*)?\Q$testval\E\s*=\s*(?:\([^\)]*\)\s*)?\s*$allocFunctions\s*\(/ &&
+                           $s !~ /\b__GFP_NOWARN\b/ ) {
                                WARN("OOM_MESSAGE",
                                     "Possible unnecessary 'out of memory' message\n" . $hereprev);
                        }
@@ -5694,7 +5836,7 @@ sub process {
                        # ignore udelay's < 10, however
                        if (! ($delay < 10) ) {
                                CHK("USLEEP_RANGE",
-                                   "usleep_range is preferred over udelay; see Documentation/timers/timers-howto.txt\n" . $herecurr);
+                                   "usleep_range is preferred over udelay; see Documentation/timers/timers-howto.rst\n" . $herecurr);
                        }
                        if ($delay > 2000) {
                                WARN("LONG_UDELAY",
@@ -5706,7 +5848,7 @@ sub process {
                if ($line =~ /\bmsleep\s*\((\d+)\);/) {
                        if ($1 < 20) {
                                WARN("MSLEEP",
-                                    "msleep < 20ms can sleep for up to 20ms; see Documentation/timers/timers-howto.txt\n" . $herecurr);
+                                    "msleep < 20ms can sleep for up to 20ms; see Documentation/timers/timers-howto.rst\n" . $herecurr);
                        }
                }
 
@@ -5855,6 +5997,18 @@ sub process {
                             "__aligned(size) is preferred over __attribute__((aligned(size)))\n" . $herecurr);
                }
 
+# Check for __attribute__ section, prefer __section
+               if ($realfile !~ m@\binclude/uapi/@ &&
+                   $line =~ /\b__attribute__\s*\(\s*\(.*_*section_*\s*\(\s*("[^"]*")/) {
+                       my $old = substr($rawline, $-[1], $+[1] - $-[1]);
+                       my $new = substr($old, 1, -1);
+                       if (WARN("PREFER_SECTION",
+                                "__section($new) is preferred over __attribute__((section($old)))\n" . $herecurr) &&
+                           $fix) {
+                               $fixed[$fixlinenr] =~ s/\b__attribute__\s*\(\s*\(\s*_*section_*\s*\(\s*\Q$old\E\s*\)\s*\)\s*\)/__section($new)/;
+                       }
+               }
+
 # Check for __attribute__ format(printf, prefer __printf
                if ($realfile !~ m@\binclude/uapi/@ &&
                    $line =~ /\b__attribute__\s*\(\s*\(\s*format\s*\(\s*printf/) {
@@ -5970,14 +6124,18 @@ sub process {
                        for (my $count = $linenr; $count <= $lc; $count++) {
                                my $specifier;
                                my $extension;
+                               my $qualifier;
                                my $bad_specifier = "";
                                my $fmt = get_quoted_string($lines[$count - 1], raw_line($count, 0));
                                $fmt =~ s/%%//g;
 
-                               while ($fmt =~ /(\%[\*\d\.]*p(\w))/g) {
+                               while ($fmt =~ /(\%[\*\d\.]*p(\w)(\w*))/g) {
                                        $specifier = $1;
                                        $extension = $2;
-                                       if ($extension !~ /[SsBKRraEhMmIiUDdgVCbGNOx]/) {
+                                       $qualifier = $3;
+                                       if ($extension !~ /[SsBKRraEehMmIiUDdgVCbGNOxtf]/ ||
+                                           ($extension eq "f" &&
+                                            defined $qualifier && $qualifier !~ /^w/)) {
                                                $bad_specifier = $specifier;
                                                last;
                                        }
@@ -5994,7 +6152,6 @@ sub process {
                                        my $ext_type = "Invalid";
                                        my $use = "";
                                        if ($bad_specifier =~ /p[Ff]/) {
-                                               $ext_type = "Deprecated";
                                                $use = " - use %pS instead";
                                                $use =~ s/pS/ps/ if ($bad_specifier =~ /pf/);
                                        }
@@ -6097,11 +6254,11 @@ sub process {
                        my $max = $7;
                        if ($min eq $max) {
                                WARN("USLEEP_RANGE",
-                                    "usleep_range should not use min == max args; see Documentation/timers/timers-howto.txt\n" . "$here\n$stat\n");
+                                    "usleep_range should not use min == max args; see Documentation/timers/timers-howto.rst\n" . "$here\n$stat\n");
                        } elsif ($min =~ /^\d+$/ && $max =~ /^\d+$/ &&
                                 $min > $max) {
                                WARN("USLEEP_RANGE",
-                                    "usleep_range args reversed, use min then max; see Documentation/timers/timers-howto.txt\n" . "$here\n$stat\n");
+                                    "usleep_range args reversed, use min then max; see Documentation/timers/timers-howto.rst\n" . "$here\n$stat\n");
                        }
                }
 
@@ -6178,13 +6335,17 @@ sub process {
                }
 
 # check for function declarations that have arguments without identifier names
+# while avoiding uninitialized_var(x)
                if (defined $stat &&
-                   $stat =~ /^.\s*(?:extern\s+)?$Type\s*(?:$Ident|\(\s*\*\s*$Ident\s*\))\s*\(\s*([^{]+)\s*\)\s*;/s &&
-                   $1 ne "void") {
-                       my $args = trim($1);
+                   $stat =~ /^.\s*(?:extern\s+)?$Type\s*(?:($Ident)|\(\s*\*\s*$Ident\s*\))\s*\(\s*([^{]+)\s*\)\s*;/s &&
+                   (!defined($1) ||
+                    (defined($1) && $1 ne "uninitialized_var")) &&
+                    $2 ne "void") {
+                       my $args = trim($2);
                        while ($args =~ m/\s*($Type\s*(?:$Ident|\(\s*\*\s*$Ident?\s*\)\s*$balanced_parens)?)/g) {
                                my $arg = trim($1);
-                               if ($arg =~ /^$Type$/ && $arg !~ /enum\s+$Ident$/) {
+                               if ($arg =~ /^$Type$/ &&
+                                       $arg !~ /enum\s+$Ident$/) {
                                        WARN("FUNCTION_ARGUMENTS",
                                             "function definition argument '$arg' should also have an identifier name\n" . $herecurr);
                                }
@@ -6224,8 +6385,8 @@ sub process {
                        }
                }
 
-# check for pointless casting of kmalloc return
-               if ($line =~ /\*\s*\)\s*[kv][czm]alloc(_node){0,1}\b/) {
+# check for pointless casting of alloc functions
+               if ($line =~ /\*\s*\)\s*$allocFunctions\b/) {
                        WARN("UNNECESSARY_CASTS",
                             "unnecessary cast may hide bugs, see http://c-faq.com/malloc/mallocnocast.html\n" . $herecurr);
                }
@@ -6233,7 +6394,7 @@ sub process {
 # alloc style
 # p = alloc(sizeof(struct foo), ...) should be p = alloc(sizeof(*p), ...)
                if ($perl_version_ok &&
-                   $line =~ /\b($Lval)\s*\=\s*(?:$balanced_parens)?\s*([kv][mz]alloc(?:_node)?)\s*\(\s*(sizeof\s*\(\s*struct\s+$Lval\s*\))/) {
+                   $line =~ /\b($Lval)\s*\=\s*(?:$balanced_parens)?\s*((?:kv|k|v)[mz]alloc(?:_node)?)\s*\(\s*(sizeof\s*\(\s*struct\s+$Lval\s*\))/) {
                        CHK("ALLOC_SIZEOF_STRUCT",
                            "Prefer $3(sizeof(*$1)...) over $3($4...)\n" . $herecurr);
                }
@@ -6337,6 +6498,28 @@ sub process {
                        }
                }
 
+# check for /* fallthrough */ like comment, prefer fallthrough;
+               my @fallthroughs = (
+                       'fallthrough',
+                       '@fallthrough@',
+                       'lint -fallthrough[ \t]*',
+                       'intentional(?:ly)?[ \t]*fall(?:(?:s | |-)[Tt]|t)hr(?:ough|u|ew)',
+                       '(?:else,?\s*)?FALL(?:S | |-)?THR(?:OUGH|U|EW)[ \t.!]*(?:-[^\n\r]*)?',
+                       'Fall(?:(?:s | |-)[Tt]|t)hr(?:ough|u|ew)[ \t.!]*(?:-[^\n\r]*)?',
+                       'fall(?:s | |-)?thr(?:ough|u|ew)[ \t.!]*(?:-[^\n\r]*)?',
+                   );
+               if ($raw_comment ne '') {
+                       foreach my $ft (@fallthroughs) {
+                               if ($raw_comment =~ /$ft/) {
+                                       my $msg_level = \&WARN;
+                                       $msg_level = \&CHK if ($file);
+                                       &{$msg_level}("PREFER_FALLTHROUGH",
+                                                     "Prefer 'fallthrough;' over fallthrough comment\n" . $herecurr);
+                                       last;
+                               }
+                       }
+               }
+
 # check for switch/default statements without a break;
                if ($perl_version_ok &&
                    defined $stat &&
@@ -6396,19 +6579,6 @@ sub process {
                        }
                }
 
-# check for bool bitfields
-               if ($sline =~ /^.\s+bool\s*$Ident\s*:\s*\d+\s*;/) {
-                       WARN("BOOL_BITFIELD",
-                            "Avoid using bool as bitfield.  Prefer bool bitfields as unsigned int or u<8|16|32>\n" . $herecurr);
-               }
-
-# check for bool use in .h files
-               if ($realfile =~ /\.h$/ &&
-                   $sline =~ /^.\s+bool\s*$Ident\s*(?::\s*d+\s*)?;/) {
-                       CHK("BOOL_MEMBER",
-                           "Avoid using bool structure members because of possible alignment issues - see: https://lkml.org/lkml/2017/11/21/384\n" . $herecurr);
-               }
-
 # check for semaphores initialized locked
                if ($line =~ /^.\s*sema_init.+,\W?0\W?\)/) {
                        WARN("CONSIDER_COMPLETION",
@@ -6427,6 +6597,20 @@ sub process {
                             "please use device_initcall() or more appropriate function instead of __initcall() (see include/linux/init.h)\n" . $herecurr);
                }
 
+# check for spin_is_locked(), suggest lockdep instead
+               if ($line =~ /\bspin_is_locked\(/) {
+                       WARN("USE_LOCKDEP",
+                            "Where possible, use lockdep_assert_held instead of assertions based on spin_is_locked\n" . $herecurr);
+               }
+
+# check for deprecated apis
+               if ($line =~ /\b($deprecated_apis_search)\b\s*\(/) {
+                       my $deprecated_api = $1;
+                       my $new_api = $deprecated_apis{$deprecated_api};
+                       WARN("DEPRECATED_API",
+                            "Deprecated use of '$deprecated_api', prefer '$new_api' instead\n" . $herecurr);
+               }
+
 # check for various structs that are normally const (ops, kgdb, device_tree)
 # and avoid what seem like struct definitions 'struct foo {'
                if ($line !~ /\bconst\b/ &&
@@ -6461,6 +6645,12 @@ sub process {
                             "Using $1 should generally have parentheses around the comparison\n" . $herecurr);
                }
 
+# nested likely/unlikely calls
+               if ($line =~ /\b(?:(?:un)?likely)\s*\(\s*!?\s*(IS_ERR(?:_OR_NULL|_VALUE)?|WARN)/) {
+                       WARN("LIKELY_MISUSE",
+                            "nested (un)?likely() calls, $1 already uses unlikely() internally\n" . $herecurr);
+               }
+
 # whine mightly about in_atomic
                if ($line =~ /\bin_atomic\s*\(/) {
                        if ($realfile =~ m@^drivers/@) {
@@ -6620,6 +6810,12 @@ sub process {
                                     "unknown module license " . $extracted_string . "\n" . $herecurr);
                        }
                }
+
+# check for sysctl duplicate constants
+               if ($line =~ /\.extra[12]\s*=\s*&(zero|one|int_max)\b/) {
+                       WARN("DUPLICATED_SYSCTL_CONST",
+                               "duplicated sysctl range checking value '$1', consider using the shared one in include/linux/sysctl.h\n" . $herecurr);
+               }
        }
 
        # If we have no input at all, then there is nothing to report on
index 3908985..c67895c 100644 (file)
@@ -554,7 +554,7 @@ from glob import iglob
 from os.path import dirname, exists, expandvars, islink, join, realpath
 
 
-VERSION = (12, 14, 0)
+VERSION = (14, 1, 0)
 
 
 # File layout:
@@ -773,8 +773,8 @@ class Kconfig(object):
       See Kconfig.load_config() as well.
 
     srctree:
-      The value of the $srctree environment variable when the configuration was
-      loaded, or the empty string if $srctree wasn't set. This gives nice
+      The value the $srctree environment variable had when the Kconfig instance
+      was created, or the empty string if $srctree wasn't set. This gives nice
       behavior with os.path.join(), which treats "" as the current directory,
       without adding "./".
 
@@ -789,13 +789,22 @@ class Kconfig(object):
       if multiple configurations are loaded with different values for $srctree.
 
     config_prefix:
-      The value of the $CONFIG_ environment variable when the configuration was
-      loaded. This is the prefix used (and expected) on symbol names in .config
-      files and C headers. Defaults to "CONFIG_". Used in the same way in the C
-      tools.
-
-      Like for srctree, only the value of $CONFIG_ when the configuration is
-      loaded matters.
+      The value the CONFIG_ environment variable had when the Kconfig instance
+      was created, or "CONFIG_" if CONFIG_ wasn't set. This is the prefix used
+      (and expected) on symbol names in .config files and C headers. Used in
+      the same way in the C tools.
+
+    config_header:
+      The value the KCONFIG_CONFIG_HEADER environment variable had when the
+      Kconfig instance was created, or the empty string if
+      KCONFIG_CONFIG_HEADER wasn't set. This string is inserted verbatim at the
+      beginning of configuration files. See write_config().
+
+    header_header:
+      The value the KCONFIG_AUTOHEADER_HEADER environment variable had when the
+      Kconfig instance was created, or the empty string if
+      KCONFIG_AUTOHEADER_HEADER wasn't set. This string is inserted verbatim at
+      the beginning of header files. See write_autoconf().
 
     filename/linenr:
       The current parsing location, for use in Python preprocessor functions.
@@ -810,11 +819,13 @@ class Kconfig(object):
         "_warn_assign_no_prompt",
         "choices",
         "comments",
+        "config_header",
         "config_prefix",
         "const_syms",
         "defconfig_list",
         "defined_syms",
         "env_vars",
+        "header_header",
         "kconfig_filenames",
         "m",
         "menus",
@@ -854,7 +865,7 @@ class Kconfig(object):
     #
 
     def __init__(self, filename="Kconfig", warn=True, warn_to_stderr=True,
-                 encoding="utf-8"):
+                 encoding="utf-8", suppress_traceback=False):
         """
         Creates a new Kconfig object by parsing Kconfig files.
         Note that Kconfig files are not the same as .config files (which store
@@ -919,7 +930,35 @@ class Kconfig(object):
           anyway.
 
           Related PEP: https://www.python.org/dev/peps/pep-0538/
+
+        suppress_traceback (default: False):
+          Helper for tools. When True, any EnvironmentError or KconfigError
+          generated during parsing is caught, the exception message is printed
+          to stderr together with the command name, and sys.exit(1) is called
+          (which generates SystemExit).
+
+          This hides the Python traceback for "expected" errors like syntax
+          errors in Kconfig files.
+
+          Other exceptions besides EnvironmentError and KconfigError are still
+          propagated when suppress_traceback is True.
         """
+        try:
+            self._init(filename, warn, warn_to_stderr, encoding)
+        except (EnvironmentError, KconfigError) as e:
+            if suppress_traceback:
+                cmd = sys.argv[0]  # Empty string if missing
+                if cmd:
+                    cmd += ": "
+                # Some long exception messages have extra newlines for better
+                # formatting when reported as an unhandled exception. Strip
+                # them here.
+                sys.exit(cmd + str(e).strip())
+            raise
+
+    def _init(self, filename, warn, warn_to_stderr, encoding):
+        # See __init__()
+
         self._encoding = encoding
 
         self.srctree = os.getenv("srctree", "")
@@ -943,6 +982,9 @@ class Kconfig(object):
         self._unset_match = _re_match(r"# {}([^ ]+) is not set".format(
             self.config_prefix))
 
+        self.config_header = os.getenv("KCONFIG_CONFIG_HEADER", "")
+        self.header_header = os.getenv("KCONFIG_AUTOHEADER_HEADER", "")
+
         self.syms = {}
         self.const_syms = {}
         self.defined_syms = []
@@ -1038,8 +1080,9 @@ class Kconfig(object):
         self._readline = self._open(join(self.srctree, filename), "r").readline
 
         try:
-            # Parse the Kconfig files
-            self._parse_block(None, self.top_node, self.top_node)
+            # Parse the Kconfig files. Returns the last node, which we
+            # terminate with '.next = None'.
+            self._parse_block(None, self.top_node, self.top_node).next = None
             self.top_node.list = self.top_node.next
             self.top_node.next = None
         except UnicodeDecodeError as e:
@@ -1245,7 +1288,7 @@ class Kconfig(object):
                             self._warn("'{}' is not a valid value for the {} "
                                        "symbol {}. Assignment ignored."
                                        .format(val, TYPE_TO_STR[sym.orig_type],
-                                               _name_and_loc(sym)),
+                                               sym.name_and_loc),
                                        filename, linenr)
                             continue
 
@@ -1272,7 +1315,7 @@ class Kconfig(object):
                         if not match:
                             self._warn("malformed string literal in "
                                        "assignment to {}. Assignment ignored."
-                                       .format(_name_and_loc(sym)),
+                                       .format(sym.name_and_loc),
                                        filename, linenr)
                             continue
 
@@ -1341,7 +1384,7 @@ class Kconfig(object):
             user_val = sym.user_value
 
         msg = '{} set more than once. Old value "{}", new value "{}".'.format(
-            _name_and_loc(sym), user_val, new_val)
+            sym.name_and_loc, user_val, new_val)
 
         if user_val == new_val:
             if self.warn_assign_redun:
@@ -1349,8 +1392,29 @@ class Kconfig(object):
         elif self.warn_assign_override:
             self._warn(msg, filename, linenr)
 
-    def write_autoconf(self, filename,
-                       header="/* Generated by Kconfiglib (https://github.com/ulfalizer/Kconfiglib) */\n"):
+    def load_allconfig(self, filename):
+        """
+        Helper for all*config. Loads (merges) the configuration file specified
+        by KCONFIG_ALLCONFIG, if any. See Documentation/kbuild/kconfig.txt in
+        the Linux kernel.
+
+        Disables warnings for duplicated assignments within configuration files
+        for the duration of the call
+        (kconf.warn_assign_override/warn_assign_redun = False), and restores
+        the previous warning settings at the end. The KCONFIG_ALLCONFIG
+        configuration file is expected to override symbols.
+
+        Exits with sys.exit() (which raises a SystemExit exception) and prints
+        an error to stderr if KCONFIG_ALLCONFIG is set but the configuration
+        file can't be opened.
+
+        filename:
+          Command-specific configuration filename - "allyes.config",
+          "allno.config", etc.
+        """
+        load_allconfig(self, filename)
+
+    def write_autoconf(self, filename=None, header=None):
         r"""
         Writes out symbol values as a C header file, matching the format used
         by include/generated/autoconf.h in the kernel.
@@ -1364,22 +1428,43 @@ class Kconfig(object):
         like the modification time and possibly triggering redundant work in
         build tools.
 
-        filename:
-          Self-explanatory.
+        filename (default: None):
+          Path to write header to.
 
-        header (default: "/* Generated by Kconfiglib (https://github.com/ulfalizer/Kconfiglib) */\n"):
-          Text that will be inserted verbatim at the beginning of the file. You
-          would usually want it enclosed in '/* */' to make it a C comment,
-          and include a final terminating newline.
+          If None (the default), the path in the environment variable
+          KCONFIG_AUTOHEADER is used if set, and "include/generated/autoconf.h"
+          otherwise. This is compatible with the C tools.
+
+        header (default: None):
+          Text inserted verbatim at the beginning of the file. You would
+          usually want it enclosed in '/* */' to make it a C comment, and
+          include a trailing newline.
+
+          If None (the default), the value of the environment variable
+          KCONFIG_AUTOHEADER_HEADER had when the Kconfig instance was created
+          will be used if it was set, and no header otherwise. See the
+          Kconfig.header_header attribute.
+
+        Returns a string with a message saying that the header got saved, or
+        that there were no changes to it. This is meant to reduce boilerplate
+        in tools, which can do e.g. print(kconf.write_autoconf()).
         """
-        self._write_if_changed(filename, self._autoconf_contents(header))
+        if filename is None:
+            filename = os.getenv("KCONFIG_AUTOHEADER",
+                                 "include/generated/autoconf.h")
+
+        if self._write_if_changed(filename, self._autoconf_contents(header)):
+            return "Kconfig header saved to '{}'".format(filename)
+        return "No change to Kconfig header in '{}'".format(filename)
 
     def _autoconf_contents(self, header):
         # write_autoconf() helper. Returns the contents to write as a string,
-        # with 'header' at the beginning.
+        # with 'header' or KCONFIG_AUTOHEADER_HEADER at the beginning.
 
-        # "".join()ed later
-        chunks = [header]
+        if header is None:
+            header = self.header_header
+
+        chunks = [header]  # "".join()ed later
         add = chunks.append
 
         for sym in self.unique_defined_syms:
@@ -1415,9 +1500,8 @@ class Kconfig(object):
 
         return "".join(chunks)
 
-    def write_config(self, filename=None,
-                     header="# Generated by Kconfiglib (https://github.com/ulfalizer/Kconfiglib)\n",
-                     save_old=True, verbose=None):
+    def write_config(self, filename=None, header=None, save_old=True,
+                     verbose=None):
         r"""
         Writes out symbol values in the .config format. The format matches the
         C implementation, including ordering.
@@ -1439,16 +1523,21 @@ class Kconfig(object):
         (OSError/IOError). KconfigError is never raised here.
 
         filename (default: None):
-          Filename to save configuration to (a string).
+          Path to write configuration to (a string).
 
-          If None (the default), the filename in the environment variable
+          If None (the default), the path in the environment variable
           KCONFIG_CONFIG is used if set, and ".config" otherwise. See
           standard_config_filename().
 
-        header (default: "# Generated by Kconfiglib (https://github.com/ulfalizer/Kconfiglib)\n"):
-          Text that will be inserted verbatim at the beginning of the file. You
-          would usually want each line to start with '#' to make it a comment,
-          and include a final terminating newline.
+        header (default: None):
+          Text inserted verbatim at the beginning of the file. You would
+          usually want each line to start with '#' to make it a comment, and
+          include a trailing newline.
+
+          if None (the default), the value of the environment variable
+          KCONFIG_CONFIG_HEADER had when the Kconfig instance was created will
+          be used if it was set, and no header otherwise. See the
+          Kconfig.config_header attribute.
 
         save_old (default: True):
           If True and <filename> already exists, a copy of it will be saved to
@@ -1481,7 +1570,7 @@ class Kconfig(object):
 
         contents = self._config_contents(header)
         if self._contents_eq(filename, contents):
-            return "No change to '{}'".format(filename)
+            return "No change to configuration in '{}'".format(filename)
 
         if save_old:
             _save_old(filename)
@@ -1493,7 +1582,7 @@ class Kconfig(object):
 
     def _config_contents(self, header):
         # write_config() helper. Returns the contents to write as a string,
-        # with 'header' at the beginning.
+        # with 'header' or KCONFIG_CONFIG_HEADER at the beginning.
         #
         # More memory friendly would be to 'yield' the strings and
         # "".join(_config_contents()), but it was a bit slower on my system.
@@ -1505,13 +1594,15 @@ class Kconfig(object):
         for sym in self.unique_defined_syms:
             sym._visited = False
 
-        # Did we just print an '# end of ...' comment?
-        after_end_comment = False
+        if header is None:
+            header = self.config_header
 
-        # "".join()ed later
-        chunks = [header]
+        chunks = [header]  # "".join()ed later
         add = chunks.append
 
+        # Did we just print an '# end of ...' comment?
+        after_end_comment = False
+
         node = self.top_node
         while 1:
             # Jump to the next node with an iterative tree walk
@@ -1564,8 +1655,7 @@ class Kconfig(object):
                 add("\n#\n# {}\n#\n".format(node.prompt[0]))
                 after_end_comment = False
 
-    def write_min_config(self, filename,
-                         header="# Generated by Kconfiglib (https://github.com/ulfalizer/Kconfiglib)\n"):
+    def write_min_config(self, filename, header=None):
         """
         Writes out a "minimal" configuration file, omitting symbols whose value
         matches their default value. The format matches the one produced by
@@ -1581,31 +1671,35 @@ class Kconfig(object):
         (OSError/IOError). KconfigError is never raised here.
 
         filename:
-          Self-explanatory.
+          Path to write minimal configuration to.
 
-        header (default: "# Generated by Kconfiglib (https://github.com/ulfalizer/Kconfiglib)\n"):
-          Text that will be inserted verbatim at the beginning of the file. You
-          would usually want each line to start with '#' to make it a comment,
-          and include a final terminating newline.
+        header (default: None):
+          Text inserted verbatim at the beginning of the file. You would
+          usually want each line to start with '#' to make it a comment, and
+          include a final terminating newline.
 
-        Returns a string with a message saying which file got saved. This is
-        meant to reduce boilerplate in tools, which can do e.g.
+          if None (the default), the value of the environment variable
+          KCONFIG_CONFIG_HEADER had when the Kconfig instance was created will
+          be used if it was set, and no header otherwise. See the
+          Kconfig.config_header attribute.
+
+        Returns a string with a message saying the minimal configuration got
+        saved, or that there were no changes to it. This is meant to reduce
+        boilerplate in tools, which can do e.g.
         print(kconf.write_min_config()).
         """
-        contents = self._min_config_contents(header)
-        if self._contents_eq(filename, contents):
-            return "No change to '{}'".format(filename)
-
-        with self._open(filename, "w") as f:
-            f.write(contents)
-
-        return "Minimal configuration saved to '{}'".format(filename)
+        if self._write_if_changed(filename, self._min_config_contents(header)):
+            return "Minimal configuration saved to '{}'".format(filename)
+        return "No change to minimal configuration in '{}'".format(filename)
 
     def _min_config_contents(self, header):
         # write_min_config() helper. Returns the contents to write as a string,
-        # with 'header' at the beginning.
+        # with 'header' or KCONFIG_CONFIG_HEADER at the beginning.
 
-        chunks = [header]
+        if header is None:
+            header = self.config_header
+
+        chunks = [header]  # "".join()ed later
         add = chunks.append
 
         for sym in self.unique_defined_syms:
@@ -2122,9 +2216,9 @@ class Kconfig(object):
         # it's part of a different construct
         if self._reuse_tokens:
             self._reuse_tokens = False
-            # self._tokens_i is known to be 1 here, because _parse_properties()
-            # leaves it like that when it can't recognize a line (or parses
-            # help text)
+            # self._tokens_i is known to be 1 here, because _parse_props()
+            # leaves it like that when it can't recognize a line (or parses a
+            # help text)
             return True
 
         # readline() returns '' over and over at EOF, which we rely on for help
@@ -2141,7 +2235,7 @@ class Kconfig(object):
 
         self._tokens = self._tokenize(line)
         # Initialize to 1 instead of 0 to factor out code from _parse_block()
-        # and _parse_properties(). They immediately fetch self._tokens[0].
+        # and _parse_props(). They immediately fetch self._tokens[0].
         self._tokens_i = 1
 
         return True
@@ -2172,10 +2266,15 @@ class Kconfig(object):
         # differs, but it breaks stuff like write_config("/dev/null"), which is
         # used out there to force evaluation-related warnings to be generated.
         # This simple version is pretty failsafe and portable.
+        #
+        # Returns True if the file has changed and is updated, and False
+        # otherwise.
 
-        if not self._contents_eq(filename, contents):
-            with self._open(filename, "w") as f:
-                f.write(contents)
+        if self._contents_eq(filename, contents):
+            return False
+        with self._open(filename, "w") as f:
+            f.write(contents)
+        return True
 
     def _contents_eq(self, filename, contents):
         # Returns True if the contents of 'filename' is 'contents' (a string),
@@ -2603,10 +2702,9 @@ class Kconfig(object):
         while 1:
             match = _name_special_search(s, i)
 
-            if match.group() == "$(":
-                s, i = self._expand_macro(s, match.start(), ())
-            else:
+            if match.group() != "$(":
                 return (s, match.start())
+            s, i = self._expand_macro(s, match.start(), ())
 
     def _expand_str(self, s, i):
         # Expands a quoted string starting at index 'i' in 's'. Handles both
@@ -2649,14 +2747,12 @@ class Kconfig(object):
         # Returns the expanded 's' (including the part before the macro) and
         # the index of the first character after the expanded macro in 's'.
 
-        start = i
+        res = s[:i]
         i += 2  # Skip over "$("
 
-        # Start of current macro argument
-        arg_start = i
-
-        # Arguments of this macro call
-        new_args = []
+        arg_start = i  # Start of current macro argument
+        new_args = []  # Arguments of this macro call
+        nesting = 0  # Current parentheses nesting level
 
         while 1:
             match = _macro_special_search(s, i)
@@ -2664,32 +2760,42 @@ class Kconfig(object):
                 self._parse_error("missing end parenthesis in macro expansion")
 
 
-            if match.group() == ")":
+            if match.group() == "(":
+                nesting += 1
+                i = match.end()
+
+            elif match.group() == ")":
+                if nesting:
+                    nesting -= 1
+                    i = match.end()
+                    continue
+
                 # Found the end of the macro
 
                 new_args.append(s[arg_start:match.start()])
 
-                prefix = s[:start]
-
                 # $(1) is replaced by the first argument to the function, etc.,
                 # provided at least that many arguments were passed
 
                 try:
                     # Does the macro look like an integer, with a corresponding
                     # argument? If so, expand it to the value of the argument.
-                    prefix += args[int(new_args[0])]
+                    res += args[int(new_args[0])]
                 except (ValueError, IndexError):
                     # Regular variables are just functions without arguments,
                     # and also go through the function value path
-                    prefix += self._fn_val(new_args)
+                    res += self._fn_val(new_args)
 
-                return (prefix + s[match.end():],
-                        len(prefix))
+                return (res + s[match.end():], len(res))
 
             elif match.group() == ",":
+                i = match.end()
+                if nesting:
+                    continue
+
                 # Found the end of a macro argument
                 new_args.append(s[arg_start:match.start()])
-                arg_start = i = match.end()
+                arg_start = i
 
             else:  # match.group() == "$("
                 # A nested macro call within the macro
@@ -2796,7 +2902,7 @@ class Kconfig(object):
         #
         # prev:
         #   The previous menu node. New nodes will be added after this one (by
-        #   modifying their 'next' pointer).
+        #   modifying 'next' pointers).
         #
         #   'prev' is reused to parse a list of child menu nodes (for a menu or
         #   Choice): After parsing the children, the 'next' pointer is assigned
@@ -2832,11 +2938,11 @@ class Kconfig(object):
 
                 sym.nodes.append(node)
 
-                self._parse_properties(node)
+                self._parse_props(node)
 
                 if node.is_menuconfig and not node.prompt:
                     self._warn("the menuconfig symbol {} has no prompt"
-                               .format(_name_and_loc(sym)))
+                               .format(sym.name_and_loc))
 
                 # Equivalent to
                 #
@@ -2918,7 +3024,7 @@ class Kconfig(object):
 
                 self.menus.append(node)
 
-                self._parse_properties(node)
+                self._parse_props(node)
                 self._parse_block(_T_ENDMENU, node, node)
                 node.list = node.next
 
@@ -2938,7 +3044,7 @@ class Kconfig(object):
 
                 self.comments.append(node)
 
-                self._parse_properties(node)
+                self._parse_props(node)
 
                 prev.next = prev = node
 
@@ -2970,7 +3076,7 @@ class Kconfig(object):
 
                 choice.nodes.append(node)
 
-                self._parse_properties(node)
+                self._parse_props(node)
                 self._parse_block(_T_ENDCHOICE, node, node)
                 node.list = node.next
 
@@ -2988,17 +3094,16 @@ class Kconfig(object):
                     "no corresponding 'menu'"   if t0 is _T_ENDMENU else
                     "unrecognized construct")
 
-        # End of file reached. Terminate the final node and return it.
+        # End of file reached. Return the last node.
 
         if end_token:
             raise KconfigError(
-                "expected '{}' at end of '{}'"
+                "error: expected '{}' at end of '{}'"
                 .format("endchoice" if end_token is _T_ENDCHOICE else
                         "endif"     if end_token is _T_ENDIF else
                         "endmenu",
                         self.filename))
 
-        prev.next = None
         return prev
 
     def _parse_cond(self):
@@ -3012,7 +3117,7 @@ class Kconfig(object):
 
         return expr
 
-    def _parse_properties(self, node):
+    def _parse_props(self, node):
         # Parses and adds properties to the MenuNode 'node' (type, 'prompt',
         # 'default's, etc.) Properties are later copied up to symbols and
         # choices in a separate pass after parsing, in e.g.
@@ -3038,7 +3143,7 @@ class Kconfig(object):
 
             if t0 in _TYPE_TOKENS:
                 # Relies on '_T_BOOL is BOOL', etc., to save a conversion
-                self._set_type(node, t0)
+                self._set_type(node.item, t0)
                 if self._tokens[1] is not None:
                     self._parse_prompt(node)
 
@@ -3068,7 +3173,7 @@ class Kconfig(object):
                                       self._parse_cond()))
 
             elif t0 in _DEF_TOKEN_TO_TYPE:
-                self._set_type(node, _DEF_TOKEN_TO_TYPE[t0])
+                self._set_type(node.item, _DEF_TOKEN_TO_TYPE[t0])
                 node.defaults.append((self._parse_expr(False),
                                       self._parse_cond()))
 
@@ -3169,14 +3274,15 @@ class Kconfig(object):
                 self._reuse_tokens = True
                 return
 
-    def _set_type(self, node, new_type):
+    def _set_type(self, sc, new_type):
+        # Sets the type of 'sc' (symbol or choice) to 'new_type'
+
         # UNKNOWN is falsy
-        if node.item.orig_type and node.item.orig_type is not new_type:
+        if sc.orig_type and sc.orig_type is not new_type:
             self._warn("{} defined with multiple types, {} will be used"
-                       .format(_name_and_loc(node.item),
-                               TYPE_TO_STR[new_type]))
+                       .format(sc.name_and_loc, TYPE_TO_STR[new_type]))
 
-        node.item.orig_type = new_type
+        sc.orig_type = new_type
 
     def _parse_prompt(self, node):
         # 'prompt' properties override each other within a single definition of
@@ -3184,7 +3290,7 @@ class Kconfig(object):
         # multiple times
 
         if node.prompt:
-            self._warn(_name_and_loc(node.item) +
+            self._warn(node.item.name_and_loc +
                        " defined with multiple prompts in single location")
 
         prompt = self._tokens[1]
@@ -3194,7 +3300,7 @@ class Kconfig(object):
             self._parse_error("expected prompt string")
 
         if prompt != prompt.strip():
-            self._warn(_name_and_loc(node.item) +
+            self._warn(node.item.name_and_loc +
                        " has leading or trailing whitespace in its prompt")
 
             # This avoid issues for e.g. reStructuredText documentation, where
@@ -3205,7 +3311,7 @@ class Kconfig(object):
 
     def _parse_help(self, node):
         if node.help is not None:
-            self._warn(_name_and_loc(node.item) + " defined with more than "
+            self._warn(node.item.name_and_loc + " defined with more than "
                        "one help text -- only the last one will be used")
 
         # Micro-optimization. This code is pretty hot.
@@ -3261,7 +3367,7 @@ class Kconfig(object):
             self._line_after_help(line)
 
     def _empty_help(self, node, line):
-        self._warn(_name_and_loc(node.item) +
+        self._warn(node.item.name_and_loc +
                    " has 'help' but empty help text")
         node.help = ""
         if line:
@@ -3366,7 +3472,7 @@ class Kconfig(object):
         # The calculated sets might be larger than necessary as we don't do any
         # complex analysis of the expressions.
 
-        make_depend_on = _make_depend_on  # Micro-optimization
+        depend_on = _depend_on  # Micro-optimization
 
         # Only calculate _dependents for defined symbols. Constant and
         # undefined symbols could theoretically be selected/implied, but it
@@ -3377,29 +3483,29 @@ class Kconfig(object):
             # The prompt conditions
             for node in sym.nodes:
                 if node.prompt:
-                    make_depend_on(sym, node.prompt[1])
+                    depend_on(sym, node.prompt[1])
 
             # The default values and their conditions
             for value, cond in sym.defaults:
-                make_depend_on(sym, value)
-                make_depend_on(sym, cond)
+                depend_on(sym, value)
+                depend_on(sym, cond)
 
             # The reverse and weak reverse dependencies
-            make_depend_on(sym, sym.rev_dep)
-            make_depend_on(sym, sym.weak_rev_dep)
+            depend_on(sym, sym.rev_dep)
+            depend_on(sym, sym.weak_rev_dep)
 
             # The ranges along with their conditions
             for low, high, cond in sym.ranges:
-                make_depend_on(sym, low)
-                make_depend_on(sym, high)
-                make_depend_on(sym, cond)
+                depend_on(sym, low)
+                depend_on(sym, high)
+                depend_on(sym, cond)
 
             # The direct dependencies. This is usually redundant, as the direct
             # dependencies get propagated to properties, but it's needed to get
             # invalidation solid for 'imply', which only checks the direct
             # dependencies (even if there are no properties to propagate it
             # to).
-            make_depend_on(sym, sym.direct_dep)
+            depend_on(sym, sym.direct_dep)
 
             # In addition to the above, choice symbols depend on the choice
             # they're in, but that's handled automatically since the Choice is
@@ -3412,11 +3518,11 @@ class Kconfig(object):
             # The prompt conditions
             for node in choice.nodes:
                 if node.prompt:
-                    make_depend_on(choice, node.prompt[1])
+                    depend_on(choice, node.prompt[1])
 
             # The default symbol conditions
             for _, cond in choice.defaults:
-                make_depend_on(choice, cond)
+                depend_on(choice, cond)
 
     def _add_choice_deps(self):
         # Choices also depend on the choice symbols themselves, because the
@@ -3641,26 +3747,26 @@ class Kconfig(object):
                     if target_sym.orig_type not in _BOOL_TRISTATE_UNKNOWN:
                         self._warn("{} selects the {} symbol {}, which is not "
                                    "bool or tristate"
-                                   .format(_name_and_loc(sym),
+                                   .format(sym.name_and_loc,
                                            TYPE_TO_STR[target_sym.orig_type],
-                                           _name_and_loc(target_sym)))
+                                           target_sym.name_and_loc))
 
                 for target_sym, _ in sym.implies:
                     if target_sym.orig_type not in _BOOL_TRISTATE_UNKNOWN:
                         self._warn("{} implies the {} symbol {}, which is not "
                                    "bool or tristate"
-                                   .format(_name_and_loc(sym),
+                                   .format(sym.name_and_loc,
                                            TYPE_TO_STR[target_sym.orig_type],
-                                           _name_and_loc(target_sym)))
+                                           target_sym.name_and_loc))
 
             elif sym.orig_type:  # STRING/INT/HEX
                 for default, _ in sym.defaults:
                     if default.__class__ is not Symbol:
                         raise KconfigError(
-                            "the {} symbol {} has a malformed default {} -- expected "
-                            "a single symbol"
-                            .format(TYPE_TO_STR[sym.orig_type], _name_and_loc(sym),
-                                    expr_str(default)))
+                            "the {} symbol {} has a malformed default {} -- "
+                            "expected a single symbol"
+                            .format(TYPE_TO_STR[sym.orig_type],
+                                    sym.name_and_loc, expr_str(default)))
 
                     if sym.orig_type is STRING:
                         if not default.is_constant and not default.nodes and \
@@ -3671,22 +3777,22 @@ class Kconfig(object):
                             # (and no symbol named 'foo' exists).
                             self._warn("style: quotes recommended around "
                                        "default value for string symbol "
-                                       + _name_and_loc(sym))
+                                       + sym.name_and_loc)
 
                     elif not num_ok(default, sym.orig_type):  # INT/HEX
                         self._warn("the {0} symbol {1} has a non-{0} default {2}"
                                    .format(TYPE_TO_STR[sym.orig_type],
-                                           _name_and_loc(sym),
-                                           _name_and_loc(default)))
+                                           sym.name_and_loc,
+                                           default.name_and_loc))
 
                 if sym.selects or sym.implies:
                     self._warn("the {} symbol {} has selects or implies"
                                .format(TYPE_TO_STR[sym.orig_type],
-                                       _name_and_loc(sym)))
+                                       sym.name_and_loc))
 
             else:  # UNKNOWN
                 self._warn("{} defined without a type"
-                           .format(_name_and_loc(sym)))
+                           .format(sym.name_and_loc))
 
 
             if sym.ranges:
@@ -3694,7 +3800,7 @@ class Kconfig(object):
                     self._warn(
                         "the {} symbol {} has ranges, but is not int or hex"
                         .format(TYPE_TO_STR[sym.orig_type],
-                                _name_and_loc(sym)))
+                                sym.name_and_loc))
                 else:
                     for low, high, _ in sym.ranges:
                         if not num_ok(low, sym.orig_type) or \
@@ -3703,9 +3809,9 @@ class Kconfig(object):
                             self._warn("the {0} symbol {1} has a non-{0} "
                                        "range [{2}, {3}]"
                                        .format(TYPE_TO_STR[sym.orig_type],
-                                               _name_and_loc(sym),
-                                               _name_and_loc(low),
-                                               _name_and_loc(high)))
+                                               sym.name_and_loc,
+                                               low.name_and_loc,
+                                               high.name_and_loc))
 
     def _check_choice_sanity(self):
         # Checks various choice properties that are handiest to check after
@@ -3714,43 +3820,43 @@ class Kconfig(object):
         def warn_select_imply(sym, expr, expr_type):
             msg = "the choice symbol {} is {} by the following symbols, but " \
                   "select/imply has no effect on choice symbols" \
-                  .format(_name_and_loc(sym), expr_type)
+                  .format(sym.name_and_loc, expr_type)
 
             # si = select/imply
             for si in split_expr(expr, OR):
-                msg += "\n - " + _name_and_loc(split_expr(si, AND)[0])
+                msg += "\n - " + split_expr(si, AND)[0].name_and_loc
 
             self._warn(msg)
 
         for choice in self.unique_choices:
             if choice.orig_type not in _BOOL_TRISTATE:
                 self._warn("{} defined with type {}"
-                           .format(_name_and_loc(choice),
+                           .format(choice.name_and_loc,
                                    TYPE_TO_STR[choice.orig_type]))
 
             for node in choice.nodes:
                 if node.prompt:
                     break
             else:
-                self._warn(_name_and_loc(choice) + " defined without a prompt")
+                self._warn(choice.name_and_loc + " defined without a prompt")
 
             for default, _ in choice.defaults:
                 if default.__class__ is not Symbol:
                     raise KconfigError(
                         "{} has a malformed default {}"
-                        .format(_name_and_loc(choice), expr_str(default)))
+                        .format(choice.name_and_loc, expr_str(default)))
 
                 if default.choice is not choice:
                     self._warn("the default selection {} of {} is not "
                                "contained in the choice"
-                               .format(_name_and_loc(default),
-                                       _name_and_loc(choice)))
+                               .format(default.name_and_loc,
+                                       choice.name_and_loc))
 
             for sym in choice.syms:
                 if sym.defaults:
                     self._warn("default on the choice symbol {} will have "
                                "no effect, as defaults do not affect choice "
-                               "symbols".format(_name_and_loc(sym)))
+                               "symbols".format(sym.name_and_loc))
 
                 if sym.rev_dep is not sym.kconfig.n:
                     warn_select_imply(sym, sym.rev_dep, "selected")
@@ -3762,15 +3868,15 @@ class Kconfig(object):
                     if node.parent.item is choice:
                         if not node.prompt:
                             self._warn("the choice symbol {} has no prompt"
-                                       .format(_name_and_loc(sym)))
+                                       .format(sym.name_and_loc))
 
                     elif node.prompt:
                         self._warn("the choice symbol {} is defined with a "
                                    "prompt outside the choice"
-                                   .format(_name_and_loc(sym)))
+                                   .format(sym.name_and_loc))
 
     def _parse_error(self, msg):
-        raise KconfigError("{}couldn't parse '{}': {}".format(
+        raise KconfigError("{}error: couldn't parse '{}': {}".format(
             "" if self.filename is None else
                 "{}:{}: ".format(self.filename, self.linenr),
             self._line.strip(), msg))
@@ -3907,6 +4013,13 @@ class Symbol(object):
       The type as given in the Kconfig file, without any magic applied. Used
       when printing the symbol.
 
+    tri_value:
+      The tristate value of the symbol as an integer. One of 0, 1, 2,
+      representing n, m, y. Always 0 (n) for non-bool/tristate symbols.
+
+      This is the symbol value that's used outside of relation expressions
+      (A, !A, A && B, A || B).
+
     str_value:
       The value of the symbol as a string. Gives the value for string/int/hex
       symbols. For bool/tristate symbols, gives "n", "m", or "y".
@@ -3914,17 +4027,20 @@ class Symbol(object):
       This is the symbol value that's used in relational expressions
       (A = B, A != B, etc.)
 
-      Gotcha: For int/hex symbols, the exact format of the value must often be
-      preserved (e.g., when writing a .config file), hence why you can't get it
+      Gotcha: For int/hex symbols, the exact format of the value is often
+      preserved (e.g. when writing a .config file), hence why you can't get it
       directly as an int. Do int(int_sym.str_value) or
       int(hex_sym.str_value, 16) to get the integer value.
 
-    tri_value:
-      The tristate value of the symbol as an integer. One of 0, 1, 2,
-      representing n, m, y. Always 0 (n) for non-bool/tristate symbols.
+    user_value:
+      The user value of the symbol. None if no user value has been assigned
+      (via Kconfig.load_config() or Symbol.set_value()).
 
-      This is the symbol value that's used outside of relation expressions
-      (A, !A, A && B, A || B).
+      Holds 0, 1, or 2 for bool/tristate symbols, and a string for the other
+      symbol types.
+
+      WARNING: Do not assign directly to this. It will break things. Use
+      Symbol.set_value().
 
     assignable:
       A tuple containing the tristate user values that can currently be
@@ -3965,16 +4081,6 @@ class Symbol(object):
       The visibility of the symbol. One of 0, 1, 2, representing n, m, y. See
       the module documentation for an overview of symbol values and visibility.
 
-    user_value:
-      The user value of the symbol. None if no user value has been assigned
-      (via Kconfig.load_config() or Symbol.set_value()).
-
-      Holds 0, 1, or 2 for bool/tristate symbols, and a string for the other
-      symbol types.
-
-      WARNING: Do not assign directly to this. It will break things. Use
-      Symbol.set_value().
-
     config_string:
       The .config assignment string that would get written out for the symbol
       by Kconfig.write_config(). Returns the empty string if no .config
@@ -4002,6 +4108,15 @@ class Symbol(object):
       though you might get some special symbols and possibly some "redundant"
       n-valued symbol entries in there.
 
+    name_and_loc:
+      Holds a string like
+
+        "MY_SYMBOL (defined at foo/Kconfig:12, bar/Kconfig:14)"
+
+      , giving the name of the symbol and its definition location(s).
+
+      If the symbol is undefined, the location is given as "(undefined)".
+
     nodes:
       A list of MenuNodes for this symbol. Will contain a single MenuNode for
       most symbols. Undefined and constant symbols have an empty nodes list.
@@ -4232,7 +4347,7 @@ class Symbol(object):
                         "being outside the active range ([{}, {}]) -- falling "
                         "back on defaults"
                         .format(num2str(user_val), TYPE_TO_STR[self.orig_type],
-                                _name_and_loc(self),
+                                self.name_and_loc,
                                 num2str(low), num2str(high)))
                 else:
                     # If the user value is well-formed and satisfies range
@@ -4282,7 +4397,7 @@ class Symbol(object):
                             self.kconfig._warn(
                                 "default value {} on {} clamped to {} due to "
                                 "being outside the active range ([{}, {}])"
-                                .format(val_num, _name_and_loc(self),
+                                .format(val_num, self.name_and_loc,
                                         num2str(clamp), num2str(low),
                                         num2str(high)))
 
@@ -4323,7 +4438,7 @@ class Symbol(object):
                 self.kconfig._warn(
                     "The {} symbol {} is being evaluated in a logical context "
                     "somewhere. It will always evaluate to n."
-                    .format(TYPE_TO_STR[self.orig_type], _name_and_loc(self)))
+                    .format(TYPE_TO_STR[self.orig_type], self.name_and_loc))
 
             self._cached_tri_val = 0
             return 0
@@ -4433,6 +4548,13 @@ class Symbol(object):
         return '{}{}="{}"\n' \
                .format(self.kconfig.config_prefix, self.name, escape(val))
 
+    @property
+    def name_and_loc(self):
+        """
+        See the class documentation.
+        """
+        return self.name + " " + _locs(self)
+
     def set_value(self, value):
         """
         Sets the user value of the symbol.
@@ -4454,8 +4576,8 @@ class Symbol(object):
         value:
           The user value to give to the symbol. For bool and tristate symbols,
           n/m/y can be specified either as 0/1/2 (the usual format for tristate
-          values in Kconfiglib) or as one of the strings "n"/"m"/"y". For other
-          symbol types, pass a string.
+          values in Kconfiglib) or as one of the strings "n", "m", or "y". For
+          other symbol types, pass a string.
 
           Note that the value for an int/hex symbol is passed as a string, e.g.
           "123" or "0x0123". The format of this string is preserved in the
@@ -4502,7 +4624,7 @@ class Symbol(object):
                 "assignment ignored"
                 .format(TRI_TO_STR[value] if value in TRI_TO_STR else
                             "'{}'".format(value),
-                        _name_and_loc(self), TYPE_TO_STR[self.orig_type]))
+                        self.name_and_loc, TYPE_TO_STR[self.orig_type]))
 
             return False
 
@@ -4790,7 +4912,7 @@ class Symbol(object):
                 return
 
         if self.kconfig._warn_assign_no_prompt:
-            self.kconfig._warn(_name_and_loc(self) + " has no prompt, meaning "
+            self.kconfig._warn(self.name_and_loc + " has no prompt, meaning "
                                "user values have no effect on it")
 
     def _str_default(self):
@@ -4836,7 +4958,7 @@ class Symbol(object):
 
         msg = "{} has direct dependencies {} with value {}, but is " \
               "currently being {}-selected by the following symbols:" \
-              .format(_name_and_loc(self), expr_str(self.direct_dep),
+              .format(self.name_and_loc, expr_str(self.direct_dep),
                       TRI_TO_STR[expr_value(self.direct_dep)],
                       TRI_TO_STR[expr_value(self.rev_dep)])
 
@@ -4854,7 +4976,7 @@ class Symbol(object):
 
             msg += "\n - {}, with value {}, direct dependencies {} " \
                    "(value: {})" \
-                   .format(_name_and_loc(selecting_sym),
+                   .format(selecting_sym.name_and_loc,
                            selecting_sym.str_value,
                            expr_str(selecting_sym.direct_dep),
                            TRI_TO_STR[expr_value(selecting_sym.direct_dep)])
@@ -4938,12 +5060,21 @@ class Choice(object):
         Corresponding attributes have the same name in the Symbol and Choice
         classes, for consistency and compatibility.
 
+    str_value:
+      Like choice.tri_value, but gives the value as one of the strings
+      "n", "m", or "y"
+
+    user_value:
+      The value (mode) selected by the user through Choice.set_value(). Either
+      0, 1, or 2, or None if the user hasn't selected a mode. See
+      Symbol.user_value.
+
+      WARNING: Do not assign directly to this. It will break things. Use
+      Choice.set_value() instead.
+
     assignable:
       See the symbol class documentation. Gives the assignable values (modes).
 
-    visibility:
-      See the Symbol class documentation. Acts on the value (mode).
-
     selection:
       The Symbol instance of the currently selected symbol. None if the Choice
       is not in y mode or has no selected symbol (due to unsatisfied
@@ -4952,14 +5083,6 @@ class Choice(object):
       WARNING: Do not assign directly to this. It will break things. Call
       sym.set_value(2) on the choice symbol you want to select instead.
 
-    user_value:
-      The value (mode) selected by the user through Choice.set_value(). Either
-      0, 1, or 2, or None if the user hasn't selected a mode. See
-      Symbol.user_value.
-
-      WARNING: Do not assign directly to this. It will break things. Use
-      Choice.set_value() instead.
-
     user_selection:
       The symbol selected by the user (by setting it to y). Ignored if the
       choice is not in y mode, but still remembered so that the choice "snaps
@@ -4969,6 +5092,19 @@ class Choice(object):
       WARNING: Do not assign directly to this. It will break things. Call
       sym.set_value(2) on the choice symbol to be selected instead.
 
+    visibility:
+      See the Symbol class documentation. Acts on the value (mode).
+
+    name_and_loc:
+      Holds a string like
+
+        "<choice MY_CHOICE> (defined at foo/Kconfig:12)"
+
+      , giving the name of the choice and its definition location(s). If the
+      choice has no name (isn't defined with 'choice MY_CHOICE'), then it will
+      be shown as "<choice>" before the list of locations (always a single one
+      in that case).
+
     syms:
       List of symbols contained in the choice.
 
@@ -5089,6 +5225,14 @@ class Choice(object):
         return self._cached_vis
 
     @property
+    def name_and_loc(self):
+        """
+        See the class documentation.
+        """
+        # Reuse the expression format, which is '<choice (name, if any)>'.
+        return standard_sc_expr_str(self) + " " + _locs(self)
+
+    @property
     def selection(self):
         """
         See the class documentation.
@@ -5128,7 +5272,7 @@ class Choice(object):
                 "assignment ignored"
                 .format(TRI_TO_STR[value] if value in TRI_TO_STR else
                             "'{}'".format(value),
-                        _name_and_loc(self), TYPE_TO_STR[self.orig_type]))
+                        self.name_and_loc, TYPE_TO_STR[self.orig_type]))
 
             return False
 
@@ -5251,8 +5395,8 @@ class Choice(object):
 
         self._cached_selection = _NO_CACHED_SELECTION
 
-        # is_constant is checked by _make_depend_on(). Just set it to avoid
-        # having to special-case choices.
+        # is_constant is checked by _depend_on(). Just set it to avoid having
+        # to special-case choices.
         self.is_constant = self.is_optional = False
 
         # See Kconfig._build_dep()
@@ -6050,25 +6194,32 @@ def unescape(s):
 _unescape_sub = re.compile(r"\\(.)").sub
 
 
-def standard_kconfig():
+def standard_kconfig(description=None):
     """
-    Helper for tools. Loads the top-level Kconfig specified as the first
-    command-line argument, or "Kconfig" if there are no command-line arguments.
-    Returns the Kconfig instance.
+    Argument parsing helper for tools that take a single optional Kconfig file
+    argument (default: Kconfig). Returns the Kconfig instance for the parsed
+    configuration. Uses argparse internally.
+
+    Exits with sys.exit() (which raises SystemExit) on errors.
 
-    Exits with sys.exit() (which raises a SystemExit exception) and prints a
-    usage note to stderr if more than one command-line argument is passed.
+    description (default: None):
+      The 'description' passed to argparse.ArgumentParser().
+      argparse.RawDescriptionHelpFormatter is used, so formatting is preserved.
     """
-    if len(sys.argv) > 2:
-        sys.exit("usage: {} [Kconfig]".format(sys.argv[0]))
+    import argparse
 
-    # Only show backtraces for unexpected exceptions
-    try:
-        return Kconfig("Kconfig" if len(sys.argv) < 2 else sys.argv[1])
-    except (EnvironmentError, KconfigError) as e:
-        # Some long exception messages have extra newlines for better
-        # formatting when reported as an unhandled exception. Strip them here.
-        sys.exit(str(e).strip())
+    parser = argparse.ArgumentParser(
+        formatter_class=argparse.RawDescriptionHelpFormatter,
+        description=description)
+
+    parser.add_argument(
+        "kconfig",
+        metavar="KCONFIG",
+        default="Kconfig",
+        nargs="?",
+        help="Top-level Kconfig file (default: Kconfig)")
+
+    return Kconfig(parser.parse_args().kconfig, suppress_traceback=True)
 
 
 def standard_config_filename():
@@ -6084,25 +6235,9 @@ def standard_config_filename():
 
 def load_allconfig(kconf, filename):
     """
-    Helper for all*config. Loads (merges) the configuration file specified by
-    KCONFIG_ALLCONFIG, if any. See Documentation/kbuild/kconfig.txt in the
-    Linux kernel.
-
-    Disables warnings for duplicated assignments within configuration files for
-    the duration of the call (kconf.warn_assign_override/warn_assign_redun = False),
-    and restores the previous warning settings at the end. The
-    KCONFIG_ALLCONFIG configuration file is expected to override symbols.
-
-    Exits with sys.exit() (which raises a SystemExit exception) and prints an
-    error to stderr if KCONFIG_ALLCONFIG is set but the configuration file
-    can't be opened.
-
-    kconf:
-      Kconfig instance to load the configuration in.
-
-    filename:
-      Command-specific configuration filename - "allyes.config",
-      "allno.config", etc.
+    Use Kconfig.load_allconfig() instead, which was added in Kconfiglib 13.4.0.
+    Supported for backwards compatibility. Might be removed at some point after
+    a long period of deprecation warnings.
     """
     allconfig = os.getenv("KCONFIG_ALLCONFIG")
     if allconfig is None:
@@ -6178,7 +6313,7 @@ def _visibility(sc):
     return vis
 
 
-def _make_depend_on(sc, expr):
+def _depend_on(sc, expr):
     # Adds 'sc' (symbol or choice) as a "dependee" to all symbols in 'expr'.
     # Constant symbols in 'expr' are skipped as they can never change value
     # anyway.
@@ -6186,11 +6321,11 @@ def _make_depend_on(sc, expr):
     if expr.__class__ is tuple:
         # AND, OR, NOT, or relation
 
-        _make_depend_on(sc, expr[1])
+        _depend_on(sc, expr[1])
 
         # NOTs only have a single operand
         if expr[0] is not NOT:
-            _make_depend_on(sc, expr[2])
+            _depend_on(sc, expr[2])
 
     elif not expr.is_constant:
         # Non-constant symbol, or choice
@@ -6286,20 +6421,16 @@ def _save_old(path):
         pass
 
 
-def _name_and_loc(sc):
-    # Helper for giving the symbol/choice name and location(s) in e.g. warnings
+def _locs(sc):
+    # Symbol/Choice.name_and_loc helper. Returns the "(defined at ...)" part of
+    # the string. 'sc' is a Symbol or Choice.
 
-    # Reuse the expression format. That way choices show up as
-    # '<choice (name, if any)>'
-    name = standard_sc_expr_str(sc)
+    if sc.nodes:
+        return "(defined at {})".format(
+            ", ".join("{0.filename}:{0.linenr}".format(node)
+                      for node in sc.nodes))
 
-    if not sc.nodes:
-        return name + " (undefined)"
-
-    return "{} (defined at {})".format(
-        name,
-        ", ".join("{}:{}".format(node.filename, node.linenr)
-                  for node in sc.nodes))
+    return "(undefined)"
 
 
 # Menu manipulation
@@ -6554,7 +6685,7 @@ def _found_dep_loop(loop, cur):
                 msg += "the choice symbol "
 
         msg += "{}, with definition...\n\n{}\n\n" \
-               .format(_name_and_loc(item), item)
+               .format(item.name_and_loc, item)
 
         # Small wart: Since we reuse the already calculated
         # Symbol/Choice._dependents sets for recursive dependency detection, we
@@ -6578,7 +6709,7 @@ def _found_dep_loop(loop, cur):
                 msg += "(imply-related dependencies: {})\n\n" \
                        .format(expr_str(item.rev_dep))
 
-    msg += "...depends again on {}".format(_name_and_loc(loop[0]))
+    msg += "...depends again on " + loop[0].name_and_loc
 
     raise KconfigError(msg)
 
@@ -6648,8 +6779,7 @@ def _error_if_fn(kconf, _, cond, msg):
 
 
 def _shell_fn(kconf, _, command):
-    # Only import as needed, to save some startup time
-    import subprocess
+    import subprocess  # Only import as needed, to save some startup time
 
     stdout, stderr = subprocess.Popen(
         command, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE
@@ -7015,8 +7145,8 @@ _assignment_lhs_fragment_match = _re_match("[A-Za-z0-9_-]*")
 # variable assignment
 _assignment_rhs_match = _re_match(r"\s*(=|:=|\+=)\s*(.*)")
 
-# Special characters/strings while expanding a macro (')', ',', and '$(')
-_macro_special_search = _re_search(r"\)|,|\$\(")
+# Special characters/strings while expanding a macro ('(', ')', ',', and '$(')
+_macro_special_search = _re_search(r"\(|\)|,|\$\(")
 
 # Special characters/strings while expanding a string (quotes, '\', and '$(')
 _string_special_search = _re_search(r'"|\'|\\|\$\(')