diff options
43 files changed, 2252 insertions, 54 deletions
diff --git a/.gitignore b/.gitignore index 0c320bf02586..2be25f771bd8 100644 --- a/.gitignore +++ b/.gitignore @@ -37,6 +37,7 @@ modules.builtin Module.symvers *.dwo *.su +*.c.[012]*.* # # Top-level generic files diff --git a/Documentation/dontdiff b/Documentation/dontdiff index 8ea834f6b289..5385cba941d2 100644 --- a/Documentation/dontdiff +++ b/Documentation/dontdiff @@ -3,6 +3,7 @@ *.bc *.bin *.bz2 +*.c.[012]*.* *.cis *.cpio *.csp diff --git a/Documentation/gcc-plugins.txt b/Documentation/gcc-plugins.txt new file mode 100644 index 000000000000..891c69464434 --- /dev/null +++ b/Documentation/gcc-plugins.txt @@ -0,0 +1,87 @@ +GCC plugin infrastructure +========================= + + +1. Introduction +=============== + +GCC plugins are loadable modules that provide extra features to the +compiler [1]. They are useful for runtime instrumentation and static analysis. +We can analyse, change and add further code during compilation via +callbacks [2], GIMPLE [3], IPA [4] and RTL passes [5]. + +The GCC plugin infrastructure of the kernel supports all gcc versions from +4.5 to 6.0, building out-of-tree modules, cross-compilation and building in a +separate directory. +Plugin source files have to be compilable by both a C and a C++ compiler as well +because gcc versions 4.5 and 4.6 are compiled by a C compiler, +gcc-4.7 can be compiled by a C or a C++ compiler, +and versions 4.8+ can only be compiled by a C++ compiler. + +Currently the GCC plugin infrastructure supports only the x86, arm and arm64 +architectures. + +This infrastructure was ported from grsecurity [6] and PaX [7]. + +-- +[1] https://gcc.gnu.org/onlinedocs/gccint/Plugins.html +[2] https://gcc.gnu.org/onlinedocs/gccint/Plugin-API.html#Plugin-API +[3] https://gcc.gnu.org/onlinedocs/gccint/GIMPLE.html +[4] https://gcc.gnu.org/onlinedocs/gccint/IPA.html +[5] https://gcc.gnu.org/onlinedocs/gccint/RTL.html +[6] https://grsecurity.net/ +[7] https://pax.grsecurity.net/ + + +2. Files +======== + +$(src)/scripts/gcc-plugins + This is the directory of the GCC plugins. + +$(src)/scripts/gcc-plugins/gcc-common.h + This is a compatibility header for GCC plugins. + It should be always included instead of individual gcc headers. + +$(src)/scripts/gcc-plugin.sh + This script checks the availability of the included headers in + gcc-common.h and chooses the proper host compiler to build the plugins + (gcc-4.7 can be built by either gcc or g++). + +$(src)/scripts/gcc-plugins/gcc-generate-gimple-pass.h +$(src)/scripts/gcc-plugins/gcc-generate-ipa-pass.h +$(src)/scripts/gcc-plugins/gcc-generate-simple_ipa-pass.h +$(src)/scripts/gcc-plugins/gcc-generate-rtl-pass.h + These headers automatically generate the registration structures for + GIMPLE, SIMPLE_IPA, IPA and RTL passes. They support all gcc versions + from 4.5 to 6.0. + They should be preferred to creating the structures by hand. + + +3. Usage +======== + +You must install the gcc plugin headers for your gcc version, +e.g., on Ubuntu for gcc-4.9: + + apt-get install gcc-4.9-plugin-dev + +Enable a GCC plugin based feature in the kernel config: + + CONFIG_GCC_PLUGIN_CYC_COMPLEXITY = y + +To compile only the plugin(s): + + make gcc-plugins + +or just run the kernel make and compile the whole kernel with +the cyclomatic complexity GCC plugin. + + +4. How to add a new GCC plugin +============================== + +The GCC plugins are in $(src)/scripts/gcc-plugins/. You can use a file or a directory +here. It must be added to $(src)/scripts/gcc-plugins/Makefile, +$(src)/scripts/Makefile.gcc-plugins and $(src)/arch/Kconfig. +See the cyc_complexity_plugin.c (CONFIG_GCC_PLUGIN_CYC_COMPLEXITY) GCC plugin. diff --git a/MAINTAINERS b/MAINTAINERS index 25f43204014d..8f950e2752de 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -5094,6 +5094,15 @@ L: linux-scsi@vger.kernel.org S: Odd Fixes (e.g., new signatures) F: drivers/scsi/fdomain.* +GCC PLUGINS +M: Kees Cook <keescook@chromium.org> +R: Emese Revfy <re.emese@gmail.com> +L: kernel-hardening@lists.openwall.com +S: Maintained +F: scripts/gcc-plugins/ +F: scripts/gcc-plugin.sh +F: Documentation/gcc-plugins.txt + GCOV BASED KERNEL PROFILING M: Peter Oberparleiter <oberpar@linux.vnet.ibm.com> S: Maintained @@ -371,26 +371,27 @@ CFLAGS_KERNEL = AFLAGS_KERNEL = LDFLAGS_vmlinux = CFLAGS_GCOV = -fprofile-arcs -ftest-coverage -fno-tree-loop-im -CFLAGS_KCOV = -fsanitize-coverage=trace-pc +CFLAGS_KCOV := $(call cc-option,-fsanitize-coverage=trace-pc,) # Use USERINCLUDE when you must reference the UAPI directories only. USERINCLUDE := \ -I$(srctree)/arch/$(hdr-arch)/include/uapi \ - -Iarch/$(hdr-arch)/include/generated/uapi \ + -I$(objtree)/arch/$(hdr-arch)/include/generated/uapi \ -I$(srctree)/include/uapi \ - -Iinclude/generated/uapi \ + -I$(objtree)/include/generated/uapi \ -include $(srctree)/include/linux/kconfig.h # Use LINUXINCLUDE when you must reference the include/ directory. # Needed to be compatible with the O= option LINUXINCLUDE := \ -I$(srctree)/arch/$(hdr-arch)/include \ - -Iarch/$(hdr-arch)/include/generated/uapi \ - -Iarch/$(hdr-arch)/include/generated \ + -I$(objtree)/arch/$(hdr-arch)/include/generated/uapi \ + -I$(objtree)/arch/$(hdr-arch)/include/generated \ $(if $(KBUILD_SRC), -I$(srctree)/include) \ - -Iinclude \ - $(USERINCLUDE) + -I$(objtree)/include + +LINUXINCLUDE += $(filter-out $(LINUXINCLUDE),$(USERINCLUDE)) KBUILD_CPPFLAGS := -D__KERNEL__ @@ -554,7 +555,7 @@ ifeq ($(KBUILD_EXTMOD),) # in parallel PHONY += scripts scripts: scripts_basic include/config/auto.conf include/config/tristate.conf \ - asm-generic + asm-generic gcc-plugins $(Q)$(MAKE) $(build)=$(@) # Objects we will link into vmlinux / subdirs we need to visit @@ -635,6 +636,15 @@ endif # Tell gcc to never replace conditional load with a non-conditional one KBUILD_CFLAGS += $(call cc-option,--param=allow-store-data-races=0) +PHONY += gcc-plugins +gcc-plugins: scripts_basic +ifdef CONFIG_GCC_PLUGINS + $(Q)$(MAKE) $(build)=scripts/gcc-plugins +endif + @: + +include scripts/Makefile.gcc-plugins + ifdef CONFIG_READABLE_ASM # Disable optimizations that make assembler listings hard to read. # reorder blocks reorders the control in the function @@ -666,21 +676,11 @@ endif endif # Find arch-specific stack protector compiler sanity-checking script. ifdef CONFIG_CC_STACKPROTECTOR - stackp-path := $(srctree)/scripts/gcc-$(ARCH)_$(BITS)-has-stack-protector.sh - ifneq ($(wildcard $(stackp-path)),) - stackp-check := $(stackp-path) - endif + stackp-path := $(srctree)/scripts/gcc-$(SRCARCH)_$(BITS)-has-stack-protector.sh + stackp-check := $(wildcard $(stackp-path)) endif KBUILD_CFLAGS += $(stackp-flag) -ifdef CONFIG_KCOV - ifeq ($(call cc-option, $(CFLAGS_KCOV)),) - $(warning Cannot use CONFIG_KCOV: \ - -fsanitize-coverage=trace-pc is not supported by compiler) - CFLAGS_KCOV = - endif -endif - ifeq ($(cc-name),clang) KBUILD_CPPFLAGS += $(call cc-option,-Qunused-arguments,) KBUILD_CPPFLAGS += $(call cc-option,-Wno-unknown-warning-option,) @@ -1019,7 +1019,7 @@ prepare1: prepare2 $(version_h) include/generated/utsrelease.h \ archprepare: archheaders archscripts prepare1 scripts_basic -prepare0: archprepare +prepare0: archprepare gcc-plugins $(Q)$(MAKE) $(build)=. # All the preparing.. @@ -1531,6 +1531,7 @@ clean: $(clean-dirs) -o -name '.*.d' -o -name '.*.tmp' -o -name '*.mod.c' \ -o -name '*.symtypes' -o -name 'modules.order' \ -o -name modules.builtin -o -name '.tmp_*.o.*' \ + -o -name '*.c.[012]*.*' \ -o -name '*.gcno' \) -type f -print | xargs rm -f # Generate tags for editors @@ -1641,7 +1642,7 @@ endif $(Q)$(MAKE) KBUILD_MODULES=$(if $(CONFIG_MODULES),1) \ $(build)=$(build-dir) # Make sure the latest headers are built for Documentation -Documentation/: headers_install +Documentation/ samples/: headers_install %/: prepare scripts FORCE $(cmd_crmodverdir) $(Q)$(MAKE) KBUILD_MODULES=$(if $(CONFIG_MODULES),1) \ diff --git a/arch/Kconfig b/arch/Kconfig index 15996290fed4..bd8056b5b246 100644 --- a/arch/Kconfig +++ b/arch/Kconfig @@ -357,6 +357,43 @@ config SECCOMP_FILTER See Documentation/prctl/seccomp_filter.txt for details. +config HAVE_GCC_PLUGINS + bool + help + An arch should select this symbol if it supports building with + GCC plugins. + +menuconfig GCC_PLUGINS + bool "GCC plugins" + depends on HAVE_GCC_PLUGINS + depends on !COMPILE_TEST + help + GCC plugins are loadable modules that provide extra features to the + compiler. They are useful for runtime instrumentation and static analysis. + + See Documentation/gcc-plugins.txt for details. + +config GCC_PLUGIN_CYC_COMPLEXITY + bool "Compute the cyclomatic complexity of a function" + depends on GCC_PLUGINS + help + The complexity M of a function's control flow graph is defined as: + M = E - N + 2P + where + + E = the number of edges + N = the number of nodes + P = the number of connected components (exit nodes). + +config GCC_PLUGIN_SANCOV + bool + depends on GCC_PLUGINS + help + This plugin inserts a __sanitizer_cov_trace_pc() call at the start of + basic blocks. It supports all gcc versions with plugin support (from + gcc-4.5 on). It is based on the commit "Add fuzzing coverage support" + by Dmitry Vyukov <dvyukov@google.com>. + config HAVE_CC_STACKPROTECTOR bool help diff --git a/arch/alpha/boot/Makefile b/arch/alpha/boot/Makefile index 8399bd0e68e8..0cbe4c59d3ce 100644 --- a/arch/alpha/boot/Makefile +++ b/arch/alpha/boot/Makefile @@ -15,7 +15,7 @@ targets := vmlinux.gz vmlinux \ OBJSTRIP := $(obj)/tools/objstrip HOSTCFLAGS := -Wall -I$(objtree)/usr/include -BOOTCFLAGS += -I$(obj) -I$(srctree)/$(obj) +BOOTCFLAGS += -I$(objtree)/$(obj) -I$(srctree)/$(obj) # SRM bootable image. Copy to offset 512 of a partition. $(obj)/bootimage: $(addprefix $(obj)/tools/,mkbb lxboot bootlx) $(obj)/vmlinux.nh diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 14b4cf75ceec..fc3dc0b90be2 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -54,6 +54,7 @@ config ARM select HAVE_FTRACE_MCOUNT_RECORD if (!XIP_KERNEL) select HAVE_FUNCTION_GRAPH_TRACER if (!THUMB2_KERNEL) select HAVE_FUNCTION_TRACER if (!XIP_KERNEL) + select HAVE_GCC_PLUGINS select HAVE_GENERIC_DMA_COHERENT select HAVE_HW_BREAKPOINT if (PERF_EVENTS && (CPU_V6 || CPU_V6K || CPU_V7)) select HAVE_IDE if PCI || ISA || PCMCIA diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig index 9f8b99e20557..1b06db571fff 100644 --- a/arch/arm64/Kconfig +++ b/arch/arm64/Kconfig @@ -78,6 +78,7 @@ config ARM64 select HAVE_FTRACE_MCOUNT_RECORD select HAVE_FUNCTION_TRACER select HAVE_FUNCTION_GRAPH_TRACER + select HAVE_GCC_PLUGINS select HAVE_GENERIC_DMA_COHERENT select HAVE_HW_BREAKPOINT if PERF_EVENTS select HAVE_IRQ_TIME_ACCOUNTING diff --git a/arch/powerpc/boot/Makefile b/arch/powerpc/boot/Makefile index 4cd612a6e272..1a2a6e8dc40d 100644 --- a/arch/powerpc/boot/Makefile +++ b/arch/powerpc/boot/Makefile @@ -43,7 +43,7 @@ ifeq ($(call cc-option-yn, -fstack-protector),y) BOOTCFLAGS += -fno-stack-protector endif -BOOTCFLAGS += -I$(obj) -I$(srctree)/$(obj) +BOOTCFLAGS += -I$(objtree)/$(obj) -I$(srctree)/$(obj) DTC_FLAGS ?= -p 1024 diff --git a/arch/powerpc/kvm/Makefile b/arch/powerpc/kvm/Makefile index eba0bea6e032..1f9e5529e692 100644 --- a/arch/powerpc/kvm/Makefile +++ b/arch/powerpc/kvm/Makefile @@ -20,7 +20,7 @@ common-objs-y += powerpc.o emulate.o emulate_loadstore.o obj-$(CONFIG_KVM_EXIT_TIMING) += timing.o obj-$(CONFIG_KVM_BOOK3S_HANDLER) += book3s_exports.o -AFLAGS_booke_interrupts.o := -I$(obj) +AFLAGS_booke_interrupts.o := -I$(objtree)/$(obj) kvm-e500-objs := \ $(common-objs-y) \ diff --git a/arch/s390/boot/compressed/Makefile b/arch/s390/boot/compressed/Makefile index 13723c39e58e..33ba697c782d 100644 --- a/arch/s390/boot/compressed/Makefile +++ b/arch/s390/boot/compressed/Makefile @@ -33,10 +33,10 @@ quiet_cmd_sizes = GEN $@ $(obj)/sizes.h: vmlinux $(call if_changed,sizes) -AFLAGS_head.o += -I$(obj) +AFLAGS_head.o += -I$(objtree)/$(obj) $(obj)/head.o: $(obj)/sizes.h -CFLAGS_misc.o += -I$(obj) +CFLAGS_misc.o += -I$(objtree)/$(obj) $(obj)/misc.o: $(obj)/sizes.h OBJCOPYFLAGS_vmlinux.bin := -R .comment -S diff --git a/arch/um/Kconfig.common b/arch/um/Kconfig.common index cc0013475444..58650d098fb4 100644 --- a/arch/um/Kconfig.common +++ b/arch/um/Kconfig.common @@ -9,6 +9,7 @@ config UML select GENERIC_CPU_DEVICES select GENERIC_IO select GENERIC_CLOCKEVENTS + select HAVE_GCC_PLUGINS select TTY # Needed for line.c config MMU diff --git a/arch/um/Makefile b/arch/um/Makefile index e3abe6f3156d..0ca46ededfc7 100644 --- a/arch/um/Makefile +++ b/arch/um/Makefile @@ -78,8 +78,8 @@ include $(ARCH_DIR)/Makefile-os-$(OS) KBUILD_CPPFLAGS += -I$(srctree)/$(HOST_DIR)/include \ -I$(srctree)/$(HOST_DIR)/include/uapi \ - -I$(HOST_DIR)/include/generated \ - -I$(HOST_DIR)/include/generated/uapi + -I$(objtree)/$(HOST_DIR)/include/generated \ + -I$(objtree)/$(HOST_DIR)/include/generated/uapi # -Derrno=kernel_errno - This turns all kernel references to errno into # kernel_errno to separate them from the libc errno. This allows -fno-common diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig index 2fa55851d2a9..3a9add58d794 100644 --- a/arch/x86/Kconfig +++ b/arch/x86/Kconfig @@ -111,6 +111,7 @@ config X86 select HAVE_FUNCTION_GRAPH_FP_TEST select HAVE_FUNCTION_GRAPH_TRACER select HAVE_FUNCTION_TRACER + select HAVE_GCC_PLUGINS select HAVE_GENERIC_DMA_COHERENT if X86_32 select HAVE_HW_BREAKPOINT select HAVE_IDE diff --git a/arch/x86/boot/Makefile b/arch/x86/boot/Makefile index be8e688fa0d4..12ea8f8384f4 100644 --- a/arch/x86/boot/Makefile +++ b/arch/x86/boot/Makefile @@ -96,7 +96,7 @@ $(obj)/zoffset.h: $(obj)/compressed/vmlinux FORCE $(call if_changed,zoffset) -AFLAGS_header.o += -I$(obj) +AFLAGS_header.o += -I$(objtree)/$(obj) $(obj)/header.o: $(obj)/zoffset.h LDFLAGS_setup.elf := -T diff --git a/arch/x86/entry/vdso/Makefile b/arch/x86/entry/vdso/Makefile index 6ba89a1ab0e5..d5409660f5de 100644 --- a/arch/x86/entry/vdso/Makefile +++ b/arch/x86/entry/vdso/Makefile @@ -75,7 +75,7 @@ CFL := $(PROFILING) -mcmodel=small -fPIC -O2 -fasynchronous-unwind-tables -m64 \ -fno-omit-frame-pointer -foptimize-sibling-calls \ -DDISABLE_BRANCH_PROFILING -DBUILD_VDSO -$(vobjs): KBUILD_CFLAGS += $(CFL) +$(vobjs): KBUILD_CFLAGS := $(filter-out $(GCC_PLUGINS_CFLAGS),$(KBUILD_CFLAGS)) $(CFL) # # vDSO code runs in userspace and -pg doesn't help with profiling anyway. @@ -145,6 +145,7 @@ KBUILD_CFLAGS_32 := $(filter-out -m64,$(KBUILD_CFLAGS)) KBUILD_CFLAGS_32 := $(filter-out -mcmodel=kernel,$(KBUILD_CFLAGS_32)) KBUILD_CFLAGS_32 := $(filter-out -fno-pic,$(KBUILD_CFLAGS_32)) KBUILD_CFLAGS_32 := $(filter-out -mfentry,$(KBUILD_CFLAGS_32)) +KBUILD_CFLAGS_32 := $(filter-out $(GCC_PLUGINS_CFLAGS),$(KBUILD_CFLAGS_32)) KBUILD_CFLAGS_32 += -m32 -msoft-float -mregparm=0 -fpic KBUILD_CFLAGS_32 += $(call cc-option, -fno-stack-protector) KBUILD_CFLAGS_32 += $(call cc-option, -foptimize-sibling-calls) diff --git a/arch/x86/purgatory/Makefile b/arch/x86/purgatory/Makefile index 12734a96df47..ac58c1616408 100644 --- a/arch/x86/purgatory/Makefile +++ b/arch/x86/purgatory/Makefile @@ -8,6 +8,8 @@ PURGATORY_OBJS = $(addprefix $(obj)/,$(purgatory-y)) LDFLAGS_purgatory.ro := -e purgatory_start -r --no-undefined -nostdlib -z nodefaultlib targets += purgatory.ro +KCOV_INSTRUMENT := n + # Default KBUILD_CFLAGS can have -pg option set when FTRACE is enabled. That # in turn leaves some undefined symbols like __fentry__ in purgatory and not # sure how to relocate those. Like kexec-tools, use custom flags. diff --git a/arch/x86/realmode/rm/Makefile b/arch/x86/realmode/rm/Makefile index c556c5ae8de5..25012abc3409 100644 --- a/arch/x86/realmode/rm/Makefile +++ b/arch/x86/realmode/rm/Makefile @@ -48,7 +48,7 @@ targets += realmode.lds $(obj)/realmode.lds: $(obj)/pasyms.h LDFLAGS_realmode.elf := --emit-relocs -T -CPPFLAGS_realmode.lds += -P -C -I$(obj) +CPPFLAGS_realmode.lds += -P -C -I$(objtree)/$(obj) targets += realmode.elf $(obj)/realmode.elf: $(obj)/realmode.lds $(REALMODE_OBJS) FORCE diff --git a/include/asm-generic/vmlinux.lds.h b/include/asm-generic/vmlinux.lds.h index 54643d1f5af4..24563970ff7b 100644 --- a/include/asm-generic/vmlinux.lds.h +++ b/include/asm-generic/vmlinux.lds.h @@ -164,7 +164,7 @@ #define ___OF_TABLE(cfg, name) _OF_TABLE_##cfg(name) #define __OF_TABLE(cfg, name) ___OF_TABLE(cfg, name) -#define OF_TABLE(cfg, name) __OF_TABLE(config_enabled(cfg), name) +#define OF_TABLE(cfg, name) __OF_TABLE(IS_ENABLED(cfg), name) #define _OF_TABLE_0(name) #define _OF_TABLE_1(name) \ . = ALIGN(8); \ diff --git a/include/linux/export.h b/include/linux/export.h index 2f9ccbe6a639..c565f87f005e 100644 --- a/include/linux/export.h +++ b/include/linux/export.h @@ -82,7 +82,7 @@ extern struct module __this_module; #include <generated/autoksyms.h> #define __EXPORT_SYMBOL(sym, sec) \ - __cond_export_sym(sym, sec, config_enabled(__KSYM_##sym)) + __cond_export_sym(sym, sec, __is_defined(__KSYM_##sym)) #define __cond_export_sym(sym, sec, conf) \ ___cond_export_sym(sym, sec, conf) #define ___cond_export_sym(sym, sec, enabled) \ diff --git a/include/linux/kconfig.h b/include/linux/kconfig.h index b33c7797eb57..15ec117ec537 100644 --- a/include/linux/kconfig.h +++ b/include/linux/kconfig.h @@ -3,6 +3,21 @@ #include <generated/autoconf.h> +#define __ARG_PLACEHOLDER_1 0, +#define __take_second_arg(__ignored, val, ...) val + +/* + * The use of "&&" / "||" is limited in certain expressions. + * The followings enable to calculate "and" / "or" with macro expansion only. + */ +#define __and(x, y) ___and(x, y) +#define ___and(x, y) ____and(__ARG_PLACEHOLDER_##x, y) +#define ____and(arg1_or_junk, y) __take_second_arg(arg1_or_junk y, 0) + +#define __or(x, y) ___or(x, y) +#define ___or(x, y) ____or(__ARG_PLACEHOLDER_##x, y) +#define ____or(arg1_or_junk, y) __take_second_arg(arg1_or_junk 1, y) + /* * Helper macros to use CONFIG_ options in C/CPP expressions. Note that * these only work with boolean and tristate options. @@ -16,11 +31,10 @@ * When CONFIG_BOOGER is not defined, we generate a (... 1, 0) pair, and when * the last step cherry picks the 2nd arg, we get a zero. */ -#define __ARG_PLACEHOLDER_1 0, -#define config_enabled(cfg) _config_enabled(cfg) -#define _config_enabled(value) __config_enabled(__ARG_PLACEHOLDER_##value) -#define __config_enabled(arg1_or_junk) ___config_enabled(arg1_or_junk 1, 0) -#define ___config_enabled(__ignored, val, ...) val +#define config_enabled(cfg) ___is_defined(cfg) +#define __is_defined(x) ___is_defined(x) +#define ___is_defined(val) ____is_defined(__ARG_PLACEHOLDER_##val) +#define ____is_defined(arg1_or_junk) __take_second_arg(arg1_or_junk 1, 0) /* * IS_BUILTIN(CONFIG_FOO) evaluates to 1 if CONFIG_FOO is set to 'y', 0 @@ -41,14 +55,13 @@ * This is similar to IS_ENABLED(), but returns false when invoked from * built-in code when CONFIG_FOO is set to 'm'. */ -#define IS_REACHABLE(option) (config_enabled(option) || \ - (config_enabled(option##_MODULE) && config_enabled(MODULE))) +#define IS_REACHABLE(option) __or(IS_BUILTIN(option), \ + __and(IS_MODULE(option), __is_defined(MODULE))) /* * IS_ENABLED(CONFIG_FOO) evaluates to 1 if CONFIG_FOO is set to 'y' or 'm', * 0 otherwise. */ -#define IS_ENABLED(option) \ - (IS_BUILTIN(option) || IS_MODULE(option)) +#define IS_ENABLED(option) __or(IS_BUILTIN(option), IS_MODULE(option)) #endif /* __LINUX_KCONFIG_H */ diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug index f07842e2d69f..eb8917a71489 100644 --- a/lib/Kconfig.debug +++ b/lib/Kconfig.debug @@ -709,6 +709,8 @@ config KCOV bool "Code coverage for fuzzing" depends on ARCH_HAS_KCOV select DEBUG_FS + select GCC_PLUGINS if !COMPILE_TEST + select GCC_PLUGIN_SANCOV if !COMPILE_TEST help KCOV exposes kernel code coverage information in a form suitable for coverage-guided fuzzing (randomized testing). diff --git a/scripts/Kbuild.include b/scripts/Kbuild.include index 0f82314621f2..15b196fc2f49 100644 --- a/scripts/Kbuild.include +++ b/scripts/Kbuild.include @@ -202,7 +202,7 @@ hdr-inst := -f $(srctree)/scripts/Makefile.headersinst obj # Prefix -I with $(srctree) if it is not an absolute path. # skip if -I has no parameter addtree = $(if $(patsubst -I%,%,$(1)), \ -$(if $(filter-out -I/%,$(1)),$(patsubst -I%,-I$(srctree)/%,$(1))) $(1)) +$(if $(filter-out -I/% -I./% -I../%,$(1)),$(patsubst -I%,-I$(srctree)/%,$(1)),$(1))) # Find all -I options and call addtree flags = $(foreach o,$($(1)),$(if $(filter -I%,$(o)),$(call addtree,$(o)),$(o))) diff --git a/scripts/Makefile b/scripts/Makefile index 822ab4a6a4aa..1d80897a9644 100644 --- a/scripts/Makefile +++ b/scripts/Makefile @@ -47,4 +47,4 @@ subdir-$(CONFIG_DTC) += dtc subdir-$(CONFIG_GDB_SCRIPTS) += gdb # Let clean descend into subdirs -subdir- += basic kconfig package +subdir- += basic kconfig package gcc-plugins diff --git a/scripts/Makefile.build b/scripts/Makefile.build index 0d1ca5bf42fb..11602e5efb3b 100644 --- a/scripts/Makefile.build +++ b/scripts/Makefile.build @@ -60,7 +60,7 @@ endif endif # Do not include host rules unless needed -ifneq ($(hostprogs-y)$(hostprogs-m),) +ifneq ($(hostprogs-y)$(hostprogs-m)$(hostlibs-y)$(hostlibs-m)$(hostcxxlibs-y)$(hostcxxlibs-m),) include scripts/Makefile.host endif diff --git a/scripts/Makefile.clean b/scripts/Makefile.clean index 55c96cb8070f..50616ea25131 100644 --- a/scripts/Makefile.clean +++ b/scripts/Makefile.clean @@ -38,7 +38,9 @@ subdir-ymn := $(addprefix $(obj)/,$(subdir-ymn)) __clean-files := $(extra-y) $(extra-m) $(extra-) \ $(always) $(targets) $(clean-files) \ $(host-progs) \ - $(hostprogs-y) $(hostprogs-m) $(hostprogs-) + $(hostprogs-y) $(hostprogs-m) $(hostprogs-) \ + $(hostlibs-y) $(hostlibs-m) $(hostlibs-) \ + $(hostcxxlibs-y) $(hostcxxlibs-m) __clean-files := $(filter-out $(no-clean-files), $(__clean-files)) diff --git a/scripts/Makefile.gcc-plugins b/scripts/Makefile.gcc-plugins new file mode 100644 index 000000000000..5e22b60589c1 --- /dev/null +++ b/scripts/Makefile.gcc-plugins @@ -0,0 +1,43 @@ +ifdef CONFIG_GCC_PLUGINS + __PLUGINCC := $(call cc-ifversion, -ge, 0408, $(HOSTCXX), $(HOSTCC)) + PLUGINCC := $(shell $(CONFIG_SHELL) $(srctree)/scripts/gcc-plugin.sh "$(__PLUGINCC)" "$(HOSTCXX)" "$(CC)") + + SANCOV_PLUGIN := -fplugin=$(objtree)/scripts/gcc-plugins/sancov_plugin.so + + gcc-plugin-$(CONFIG_GCC_PLUGIN_CYC_COMPLEXITY) += cyc_complexity_plugin.so + + ifdef CONFIG_GCC_PLUGIN_SANCOV + ifeq ($(CFLAGS_KCOV),) + # It is needed because of the gcc-plugin.sh and gcc version checks. + gcc-plugin-$(CONFIG_GCC_PLUGIN_SANCOV) += sancov_plugin.so + + ifneq ($(PLUGINCC),) + CFLAGS_KCOV := $(SANCOV_PLUGIN) + else + $(warning warning: cannot use CONFIG_KCOV: -fsanitize-coverage=trace-pc is not supported by compiler) + endif + endif + endif + + GCC_PLUGINS_CFLAGS := $(addprefix -fplugin=$(objtree)/scripts/gcc-plugins/, $(gcc-plugin-y)) + + export PLUGINCC GCC_PLUGINS_CFLAGS GCC_PLUGIN SANCOV_PLUGIN + + ifeq ($(PLUGINCC),) + ifneq ($(GCC_PLUGINS_CFLAGS),) + ifeq ($(call cc-ifversion, -ge, 0405, y), y) + PLUGINCC := $(shell $(CONFIG_SHELL) -x $(srctree)/scripts/gcc-plugin.sh "$(__PLUGINCC)" "$(HOSTCXX)" "$(CC)") + $(warning warning: your gcc installation does not support plugins, perhaps the necessary headers are missing?) + else + $(warning warning: your gcc version does not support plugins, you should upgrade it to gcc 4.5 at least) + endif + endif + else + # SANCOV_PLUGIN can be only in CFLAGS_KCOV because avoid duplication. + GCC_PLUGINS_CFLAGS := $(filter-out $(SANCOV_PLUGIN), $(GCC_PLUGINS_CFLAGS)) + endif + + KBUILD_CFLAGS += $(GCC_PLUGINS_CFLAGS) + GCC_PLUGIN := $(gcc-plugin-y) + +endif diff --git a/scripts/Makefile.host b/scripts/Makefile.host index 133edfae5b8a..45b5b1aaedbd 100644 --- a/scripts/Makefile.host +++ b/scripts/Makefile.host @@ -20,7 +20,15 @@ # Will compile qconf as a C++ program, and menu as a C program. # They are linked as C++ code to the executable qconf +# hostcc-option +# Usage: cflags-y += $(call hostcc-option,-march=winchip-c6,-march=i586) + +hostcc-option = $(call try-run,\ + $(HOSTCC) $(HOSTCFLAGS) $(HOST_EXTRACFLAGS) $(1) -c -x c /dev/null -o "$$TMP",$(1),$(2)) + __hostprogs := $(sort $(hostprogs-y) $(hostprogs-m)) +host-cshlib := $( |