Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 6b90bd4b authored by Emese Revfy's avatar Emese Revfy Committed by Michal Marek
Browse files

GCC plugin infrastructure



This patch allows to build the whole kernel with GCC plugins. It was ported from
grsecurity/PaX. The infrastructure supports building out-of-tree modules and
building in a separate directory. Cross-compilation is supported too.
Currently the x86, arm, arm64 and uml architectures enable plugins.

The directory of the gcc plugins is scripts/gcc-plugins. You can use a file or a directory
there. The plugins compile with these options:
 * -fno-rtti: gcc is compiled with this option so the plugins must use it too
 * -fno-exceptions: this is inherited from gcc too
 * -fasynchronous-unwind-tables: this is inherited from gcc too
 * -ggdb: it is useful for debugging a plugin (better backtrace on internal
    errors)
 * -Wno-narrowing: to suppress warnings from gcc headers (ipa-utils.h)
 * -Wno-unused-variable: to suppress warnings from gcc headers (gcc_version
    variable, plugin-version.h)

The infrastructure introduces a new Makefile target called gcc-plugins. It
supports all gcc versions from 4.5 to 6.0. The scripts/gcc-plugin.sh script
chooses the proper host compiler (gcc-4.7 can be built by either gcc or g++).
This script also checks the availability of the included headers in
scripts/gcc-plugins/gcc-common.h.

The gcc-common.h header contains frequently included headers for GCC plugins
and it has a compatibility layer for the supported gcc versions.

The gcc-generate-*-pass.h headers automatically generate the registration
structures for GIMPLE, SIMPLE_IPA, IPA and RTL passes.

Note that 'make clean' keeps the *.so files (only the distclean or mrproper
targets clean all) because they are needed for out-of-tree modules.

Based on work created by the PaX Team.

Signed-off-by: default avatarEmese Revfy <re.emese@gmail.com>
Acked-by: default avatarKees Cook <keescook@chromium.org>
Signed-off-by: default avatarMichal Marek <mmarek@suse.com>
parent 24403874
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -37,6 +37,7 @@ modules.builtin
Module.symvers
*.dwo
*.su
*.c.[012]*.*

#
# Top-level generic files
+1 −0
Original line number Diff line number Diff line
@@ -3,6 +3,7 @@
*.bc
*.bin
*.bz2
*.c.[012]*.*
*.cis
*.cpio
*.csp
+87 −0
Original line number Diff line number Diff line
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.
+9 −0
Original line number Diff line number Diff line
@@ -4979,6 +4979,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
+12 −2
Original line number Diff line number Diff line
@@ -552,7 +552,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
@@ -631,6 +631,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
@@ -1026,7 +1035,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..
@@ -1507,6 +1516,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
Loading