提交 6b90bd4b 编写于 作者: E Emese Revfy 提交者: Michal Marek

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: NEmese Revfy <re.emese@gmail.com>
Acked-by: NKees Cook <keescook@chromium.org>
Signed-off-by: NMichal Marek <mmarek@suse.com>
上级 24403874
......@@ -37,6 +37,7 @@ modules.builtin
Module.symvers
*.dwo
*.su
*.c.[012]*.*
#
# Top-level generic files
......
......@@ -3,6 +3,7 @@
*.bc
*.bin
*.bz2
*.c.[012]*.*
*.cis
*.cpio
*.csp
......
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.
......@@ -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
......
......@@ -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
......
......@@ -357,6 +357,21 @@ 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
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 HAVE_CC_STACKPROTECTOR
bool
help
......
......@@ -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
......
......@@ -76,6 +76,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
......
......@@ -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
......
......@@ -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
......
......@@ -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)
......
......@@ -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
ifdef CONFIG_GCC_PLUGINS
__PLUGINCC := $(call cc-ifversion, -ge, 0408, $(HOSTCXX), $(HOSTCC))
PLUGINCC := $(shell $(CONFIG_SHELL) $(srctree)/scripts/gcc-plugin.sh "$(__PLUGINCC)" "$(HOSTCXX)" "$(CC)")
GCC_PLUGINS_CFLAGS := $(addprefix -fplugin=$(objtree)/scripts/gcc-plugins/, $(gcc-plugin-y))
export PLUGINCC GCC_PLUGINS_CFLAGS GCC_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
endif
KBUILD_CFLAGS += $(GCC_PLUGINS_CFLAGS)
GCC_PLUGIN := $(gcc-plugin-y)
endif
#!/bin/sh
srctree=$(dirname "$0")
gccplugins_dir=$($3 -print-file-name=plugin)
plugincc=$($1 -E -x c++ - -o /dev/null -I"${srctree}"/gcc-plugins -I"${gccplugins_dir}"/include 2>&1 <<EOF
#include "gcc-common.h"
#if BUILDING_GCC_VERSION >= 4008 || defined(ENABLE_BUILD_WITH_CXX)
#warning $2 CXX
#else
#warning $1 CC
#endif
EOF
)
if [ $? -ne 0 ]
then
exit 1
fi
case "$plugincc" in
*"$1 CC"*)
echo "$1"
exit 0
;;
*"$2 CXX"*)
# the c++ compiler needs another test, see below
;;
*)
exit 1
;;
esac
# we need a c++ compiler that supports the designated initializer GNU extension
plugincc=$($2 -c -x c++ -std=gnu++98 - -fsyntax-only -I"${srctree}"/gcc-plugins -I"${gccplugins_dir}"/include 2>&1 <<EOF
#include "gcc-common.h"
class test {
public:
int test;
} test = {
.test = 1
};
EOF
)
if [ $? -eq 0 ]
then
echo "$2"
exit 0
fi
exit 1
GCC_PLUGINS_DIR := $(shell $(CC) -print-file-name=plugin)
ifeq ($(PLUGINCC),$(HOSTCC))
HOSTLIBS := hostlibs
HOST_EXTRACFLAGS += -I$(GCC_PLUGINS_DIR)/include -I$(src) -std=gnu99 -ggdb
export HOST_EXTRACFLAGS
else
HOSTLIBS := hostcxxlibs
HOST_EXTRACXXFLAGS += -I$(GCC_PLUGINS_DIR)/include -I$(src) -std=gnu++98 -fno-rtti
HOST_EXTRACXXFLAGS += -fno-exceptions -fasynchronous-unwind-tables -ggdb
HOST_EXTRACXXFLAGS += -Wno-narrowing -Wno-unused-variable
export HOST_EXTRACXXFLAGS
endif
export GCCPLUGINS_DIR HOSTLIBS
$(HOSTLIBS)-y := $(GCC_PLUGIN)
always := $($(HOSTLIBS)-y)
clean-files += *.so
此差异已折叠。
/*
* Generator for GIMPLE pass related boilerplate code/data
*
* Supports gcc 4.5-6
*
* Usage:
*
* 1. before inclusion define PASS_NAME
* 2. before inclusion define NO_* for unimplemented callbacks
* NO_GATE
* NO_EXECUTE
* 3. before inclusion define PROPERTIES_* and TODO_FLAGS_* to override
* the default 0 values
* 4. for convenience, all the above will be undefined after inclusion!
* 5. the only exported name is make_PASS_NAME_pass() to register with gcc
*/
#ifndef PASS_NAME
#error at least PASS_NAME must be defined
#else
#define __GCC_PLUGIN_STRINGIFY(n) #n
#define _GCC_PLUGIN_STRINGIFY(n) __GCC_PLUGIN_STRINGIFY(n)
#define _GCC_PLUGIN_CONCAT2(x, y) x ## y
#define _GCC_PLUGIN_CONCAT3(x, y, z) x ## y ## z
#define __PASS_NAME_PASS_DATA(n) _GCC_PLUGIN_CONCAT2(n, _pass_data)
#define _PASS_NAME_PASS_DATA __PASS_NAME_PASS_DATA(PASS_NAME)
#define __PASS_NAME_PASS(n) _GCC_PLUGIN_CONCAT2(n, _pass)
#define _PASS_NAME_PASS __PASS_NAME_PASS(PASS_NAME)
#define _PASS_NAME_NAME _GCC_PLUGIN_STRINGIFY(PASS_NAME)
#define __MAKE_PASS_NAME_PASS(n) _GCC_PLUGIN_CONCAT3(make_, n, _pass)
#define _MAKE_PASS_NAME_PASS __MAKE_PASS_NAME_PASS(PASS_NAME)
#ifdef NO_GATE
#define _GATE NULL
#define _HAS_GATE false
#else
#define __GATE(n) _GCC_PLUGIN_CONCAT2(n, _gate)
#define _GATE __GATE(PASS_NAME)
#define _HAS_GATE true
#endif
#ifdef NO_EXECUTE
#define _EXECUTE NULL
#define _HAS_EXECUTE false
#else
#define __EXECUTE(n) _GCC_PLUGIN_CONCAT2(n, _execute)
#define _EXECUTE __EXECUTE(PASS_NAME)
#define _HAS_EXECUTE true
#endif
#ifndef PROPERTIES_REQUIRED
#define PROPERTIES_REQUIRED 0
#endif
#ifndef PROPERTIES_PROVIDED
#define PROPERTIES_PROVIDED 0
#endif
#ifndef PROPERTIES_DESTROYED
#define PROPERTIES_DESTROYED 0
#endif
#ifndef TODO_FLAGS_START
#define TODO_FLAGS_START 0
#endif
#ifndef TODO_FLAGS_FINISH
#define TODO_FLAGS_FINISH 0
#endif
#if BUILDING_GCC_VERSION >= 4009
namespace {
static const pass_data _PASS_NAME_PASS_DATA = {
#else
static struct gimple_opt_pass _PASS_NAME_PASS = {
.pass = {
#endif
.type = GIMPLE_PASS,
.name = _PASS_NAME_NAME,
#if BUILDING_GCC_VERSION >= 4008
.optinfo_flags = OPTGROUP_NONE,
#endif
#if BUILDING_GCC_VERSION >= 5000
#elif BUILDING_GCC_VERSION == 4009
.has_gate = _HAS_GATE,
.has_execute = _HAS_EXECUTE,
#else
.gate = _GATE,
.execute = _EXECUTE,
.sub = NULL,
.next = NULL,
.static_pass_number = 0,
#endif
.tv_id = TV_NONE,
.properties_required = PROPERTIES_REQUIRED,
.properties_provided = PROPERTIES_PROVIDED,
.properties_destroyed = PROPERTIES_DESTROYED,
.todo_flags_start = TODO_FLAGS_START,
.todo_flags_finish = TODO_FLAGS_FINISH,
#if BUILDING_GCC_VERSION < 4009
}
#endif
};
#if BUILDING_GCC_VERSION >= 4009
class _PASS_NAME_PASS : public gimple_opt_pass {
public:
_PASS_NAME_PASS() : gimple_opt_pass(_PASS_NAME_PASS_DATA, g) {}
#ifndef NO_GATE
#if BUILDING_GCC_VERSION >= 5000
virtual bool gate(function *) { return _GATE(); }
#else
virtual bool gate(void) { return _GATE(); }
#endif
#endif
virtual opt_pass * clone () { return new _PASS_NAME_PASS(); }
#ifndef NO_EXECUTE
#if BUILDING_GCC_VERSION >= 5000
virtual unsigned int execute(function *) { return _EXECUTE(); }
#else
virtual unsigned int execute(void) { return _EXECUTE(); }
#endif
#endif
};
}
opt_pass *_MAKE_PASS_NAME_PASS(void)
{
return new _PASS_NAME_PASS();
}
#else
struct opt_pass *_MAKE_PASS_NAME_PASS(void)
{
return &_PASS_NAME_PASS.pass;
}
#endif
/* clean up user provided defines */
#undef PASS_NAME
#undef NO_GATE
#undef NO_EXECUTE
#undef PROPERTIES_DESTROYED
#undef PROPERTIES_PROVIDED
#undef PROPERTIES_REQUIRED
#undef TODO_FLAGS_FINISH
#undef TODO_FLAGS_START
/* clean up generated defines */
#undef _EXECUTE
#undef __EXECUTE
#undef _GATE
#undef __GATE
#undef _GCC_PLUGIN_CONCAT2
#undef _GCC_PLUGIN_CONCAT3
#undef _GCC_PLUGIN_STRINGIFY
#undef __GCC_PLUGIN_STRINGIFY
#undef _HAS_EXECUTE
#undef _HAS_GATE
#undef _MAKE_PASS_NAME_PASS
#undef __MAKE_PASS_NAME_PASS
#undef _PASS_NAME_NAME
#undef _PASS_NAME_PASS
#undef __PASS_NAME_PASS
#undef _PASS_NAME_PASS_DATA
#undef __PASS_NAME_PASS_DATA
#endif /* PASS_NAME */
/*
* Generator for IPA pass related boilerplate code/data
*
* Supports gcc 4.5-6
*
* Usage:
*
* 1. before inclusion define PASS_NAME
* 2. before inclusion define NO_* for unimplemented callbacks
* NO_GENERATE_SUMMARY
* NO_READ_SUMMARY
* NO_WRITE_SUMMARY
* NO_READ_OPTIMIZATION_SUMMARY
* NO_WRITE_OPTIMIZATION_SUMMARY
* NO_STMT_FIXUP
* NO_FUNCTION_TRANSFORM
* NO_VARIABLE_TRANSFORM
* NO_GATE
* NO_EXECUTE
* 3. before inclusion define PROPERTIES_* and *TODO_FLAGS_* to override
* the default 0 values
* 4. for convenience, all the above will be undefined after inclusion!
* 5. the only exported name is make_PASS_NAME_pass() to register with gcc
*/
#ifndef PASS_NAME
#error at least PASS_NAME must be defined
#else
#define __GCC_PLUGIN_STRINGIFY(n) #n
#define _GCC_PLUGIN_STRINGIFY(n) __GCC_PLUGIN_STRINGIFY(n)
#define _GCC_PLUGIN_CONCAT2(x, y) x ## y
#define _GCC_PLUGIN_CONCAT3(x, y, z) x ## y ## z
#define __PASS_NAME_PASS_DATA(n) _GCC_PLUGIN_CONCAT2(n, _pass_data)
#define _PASS_NAME_PASS_DATA __PASS_NAME_PASS_DATA(PASS_NAME)
#define __PASS_NAME_PASS(n) _GCC_PLUGIN_CONCAT2(n, _pass)
#define _PASS_NAME_PASS __PASS_NAME_PASS(PASS_NAME)
#define _PASS_NAME_NAME _GCC_PLUGIN_STRINGIFY(PASS_NAME)
#define __MAKE_PASS_NAME_PASS(n) _GCC_PLUGIN_CONCAT3(make_, n, _pass)
#define _MAKE_PASS_NAME_PASS __MAKE_PASS_NAME_PASS(PASS_NAME)
#ifdef NO_GENERATE_SUMMARY
#define _GENERATE_SUMMARY NULL
#else
#define __GENERATE_SUMMARY(n) _GCC_PLUGIN_CONCAT2(n, _generate_summary)
#define _GENERATE_SUMMARY __GENERATE_SUMMARY(PASS_NAME)
#endif
#ifdef NO_READ_SUMMARY
#define _READ_SUMMARY NULL
#else
#define __READ_SUMMARY(n) _GCC_PLUGIN_CONCAT2(n, _read_summary)
#define _READ_SUMMARY __READ_SUMMARY(PASS_NAME)
#endif
#ifdef NO_WRITE_SUMMARY
#define _WRITE_SUMMARY NULL
#else
#define __WRITE_SUMMARY(n) _GCC_PLUGIN_CONCAT2(n, _write_summary)
#define _WRITE_SUMMARY __WRITE_SUMMARY(PASS_NAME)
#endif
#ifdef NO_READ_OPTIMIZATION_SUMMARY
#define _READ_OPTIMIZATION_SUMMARY NULL
#else
#define __READ_OPTIMIZATION_SUMMARY(n) _GCC_PLUGIN_CONCAT2(n, _read_optimization_summary)
#define _READ_OPTIMIZATION_SUMMARY __READ_OPTIMIZATION_SUMMARY(PASS_NAME)
#endif
#ifdef NO_WRITE_OPTIMIZATION_SUMMARY
#define _WRITE_OPTIMIZATION_SUMMARY NULL
#else
#define __WRITE_OPTIMIZATION_SUMMARY(n) _GCC_PLUGIN_CONCAT2(n, _write_optimization_summary)
#define _WRITE_OPTIMIZATION_SUMMARY __WRITE_OPTIMIZATION_SUMMARY(PASS_NAME)
#endif
#ifdef NO_STMT_FIXUP
#define _STMT_FIXUP NULL
#else
#define __STMT_FIXUP(n) _GCC_PLUGIN_CONCAT2(n, _stmt_fixup)
#define _STMT_FIXUP __STMT_FIXUP(PASS_NAME)
#endif
#ifdef NO_FUNCTION_TRANSFORM
#define _FUNCTION_TRANSFORM NULL
#else
#define __FUNCTION_TRANSFORM(n) _GCC_PLUGIN_CONCAT2(n, _function_transform)
#define _FUNCTION_TRANSFORM __FUNCTION_TRANSFORM(PASS_NAME)
#endif
#ifdef NO_VARIABLE_TRANSFORM
#define _VARIABLE_TRANSFORM NULL
#else
#define __VARIABLE_TRANSFORM(n) _GCC_PLUGIN_CONCAT2(n, _variable_transform)
#define _VARIABLE_TRANSFORM __VARIABLE_TRANSFORM(PASS_NAME)
#endif
#ifdef NO_GATE
#define _GATE NULL
#define _HAS_GATE false
#else
#define __GATE(n) _GCC_PLUGIN_CONCAT2(n, _gate)
#define _GATE __GATE(PASS_NAME)
#define _HAS_GATE true
#endif
#ifdef NO_EXECUTE
#define _EXECUTE NULL
#define _HAS_EXECUTE false
#else
#define __EXECUTE(n) _GCC_PLUGIN_CONCAT2(n, _execute)
#define _EXECUTE __EXECUTE(PASS_NAME)
#define _HAS_EXECUTE true
#endif
#ifndef PROPERTIES_REQUIRED
#define PROPERTIES_REQUIRED 0
#endif
#ifndef PROPERTIES_PROVIDED
#define PROPERTIES_PROVIDED 0
#endif
#ifndef PROPERTIES_DESTROYED
#define PROPERTIES_DESTROYED 0
#endif
#ifndef TODO_FLAGS_START
#define TODO_FLAGS_START 0
#endif
#ifndef TODO_FLAGS_FINISH
#define TODO_FLAGS_FINISH 0
#endif
#ifndef FUNCTION_TRANSFORM_TODO_FLAGS_START
#define FUNCTION_TRANSFORM_TODO_FLAGS_START 0
#endif
#if BUILDING_GCC_VERSION >= 4009
namespace {
static const pass_data _PASS_NAME_PASS_DATA = {
#else
static struct ipa_opt_pass_d _PASS_NAME_PASS = {
.pass = {
#endif
.type = IPA_PASS,
.name = _PASS_NAME_NAME,
#if BUILDING_GCC_VERSION >= 4008
.optinfo_flags = OPTGROUP_NONE,
#endif
#if BUILDING_GCC_VERSION >= 5000
#elif BUILDING_GCC_VERSION == 4009
.has_gate = _HAS_GATE,
.has_execute = _HAS_EXECUTE,
#else
.gate = _GATE,
.execute = _EXECUTE,
.sub = NULL,
.next = NULL,
.static_pass_number = 0,
#endif
.tv_id = TV_NONE,
.properties_required = PROPERTIES_REQUIRED,
.properties_provided = PROPERTIES_PROVIDED,
.properties_destroyed = PROPERTIES_DESTROYED,
.todo_flags_start = TODO_FLAGS_START,
.todo_flags_finish = TODO_FLAGS_FINISH,
#if BUILDING_GCC_VERSION < 4009
},
.generate_summary = _GENERATE_SUMMARY,
.write_summary = _WRITE_SUMMARY,
.read_summary = _READ_SUMMARY,
#if BUILDING_GCC_VERSION >= 4006
.write_optimization_summary = _WRITE_OPTIMIZATION_SUMMARY,
.read_optimization_summary = _READ_OPTIMIZATION_SUMMARY,
#endif
.stmt_fixup = _STMT_FIXUP,
.function_transform_todo_flags_start = FUNCTION_TRANSFORM_TODO_FLAGS_START,
.function_transform = _FUNCTION_TRANSFORM,
.variable_transform = _VARIABLE_TRANSFORM,
#endif
};
#if BUILDING_GCC_VERSION >= 4009
class _PASS_NAME_PASS : public ipa_opt_pass_d {
public:
_PASS_NAME_PASS() : ipa_opt_pass_d(_PASS_NAME_PASS_DATA,
g,
_GENERATE_SUMMARY,
_WRITE_SUMMARY,
_READ_SUMMARY,
_WRITE_OPTIMIZATION_SUMMARY,
_READ_OPTIMIZATION_SUMMARY,
_STMT_FIXUP,
FUNCTION_TRANSFORM_TODO_FLAGS_START,
_FUNCTION_TRANSFORM,
_VARIABLE_TRANSFORM) {}
#ifndef NO_GATE
#if BUILDING_GCC_VERSION >= 5000
virtual bool gate(function *) { return _GATE(); }
#else
virtual bool gate(void) { return _GATE(); }
#endif
#endif
virtual opt_pass *clone() { return new _PASS_NAME_PASS(); }
#ifndef NO_EXECUTE
#if BUILDING_GCC_VERSION >= 5000
virtual unsigned int execute(function *) { return _EXECUTE(); }
#else
virtual unsigned int execute(void) { return _EXECUTE(); }
#endif
#endif
};
}
opt_pass *_MAKE_PASS_NAME_PASS(void)
{
return new _PASS_NAME_PASS();
}
#else
struct opt_pass *_MAKE_PASS_NAME_PASS(void)
{
return &_PASS_NAME_PASS.pass;
}
#endif
/* clean up user provided defines */
#undef PASS_NAME
#undef NO_GENERATE_SUMMARY
#undef NO_WRITE_SUMMARY
#undef NO_READ_SUMMARY
#undef NO_WRITE_OPTIMIZATION_SUMMARY
#undef NO_READ_OPTIMIZATION_SUMMARY
#undef NO_STMT_FIXUP
#undef NO_FUNCTION_TRANSFORM
#undef NO_VARIABLE_TRANSFORM
#undef NO_GATE
#undef NO_EXECUTE
#undef FUNCTION_TRANSFORM_TODO_FLAGS_START
#undef PROPERTIES_DESTROYED
#undef PROPERTIES_PROVIDED
#undef PROPERTIES_REQUIRED
#undef TODO_FLAGS_FINISH
#undef TODO_FLAGS_START
/* clean up generated defines */
#undef _EXECUTE
#undef __EXECUTE
#undef _FUNCTION_TRANSFORM
#undef __FUNCTION_TRANSFORM
#undef _GATE
#undef __GATE
#undef _GCC_PLUGIN_CONCAT2
#undef _GCC_PLUGIN_CONCAT3
#undef _GCC_PLUGIN_STRINGIFY
#undef __GCC_PLUGIN_STRINGIFY
#undef _GENERATE_SUMMARY
#undef __GENERATE_SUMMARY
#undef _HAS_EXECUTE
#undef _HAS_GATE
#undef _MAKE_PASS_NAME_PASS
#undef __MAKE_PASS_NAME_PASS
#undef _PASS_NAME_NAME
#undef _PASS_NAME_PASS
#undef __PASS_NAME_PASS
#undef _PASS_NAME_PASS_DATA
#undef __PASS_NAME_PASS_DATA
#undef _READ_OPTIMIZATION_SUMMARY
#undef __READ_OPTIMIZATION_SUMMARY
#undef _READ_SUMMARY
#undef __READ_SUMMARY
#undef _STMT_FIXUP
#undef __STMT_FIXUP
#undef _VARIABLE_TRANSFORM
#undef __VARIABLE_TRANSFORM
#undef _WRITE_OPTIMIZATION_SUMMARY
#undef __WRITE_OPTIMIZATION_SUMMARY
#undef _WRITE_SUMMARY
#undef __WRITE_SUMMARY
#endif /* PASS_NAME */
/*
* Generator for RTL pass related boilerplate code/data
*
* Supports gcc 4.5-6
*
* Usage:
*
* 1. before inclusion define PASS_NAME
* 2. before inclusion define NO_* for unimplemented callbacks
* NO_GATE
* NO_EXECUTE
* 3. before inclusion define PROPERTIES_* and TODO_FLAGS_* to override
* the default 0 values
* 4. for convenience, all the above will be undefined after inclusion!
* 5. the only exported name is make_PASS_NAME_pass() to register with gcc
*/
#ifndef PASS_NAME
#error at least PASS_NAME must be defined
#else
#define __GCC_PLUGIN_STRINGIFY(n) #n
#define _GCC_PLUGIN_STRINGIFY(n) __GCC_PLUGIN_STRINGIFY(n)
#define _GCC_PLUGIN_CONCAT2(x, y) x ## y
#define _GCC_PLUGIN_CONCAT3(x, y, z) x ## y ## z
#define __PASS_NAME_PASS_DATA(n) _GCC_PLUGIN_CONCAT2(n, _pass_data)
#define _PASS_NAME_PASS_DATA __PASS_NAME_PASS_DATA(PASS_NAME)
#define __PASS_NAME_PASS(n) _GCC_PLUGIN_CONCAT2(n, _pass)
#define _PASS_NAME_PASS __PASS_NAME_PASS(PASS_NAME)
#define _PASS_NAME_NAME _GCC_PLUGIN_STRINGIFY(PASS_NAME)
#define __MAKE_PASS_NAME_PASS(n) _GCC_PLUGIN_CONCAT3(make_, n, _pass)
#define _MAKE_PASS_NAME_PASS __MAKE_PASS_NAME_PASS(PASS_NAME)
#ifdef NO_GATE
#define _GATE NULL
#define _HAS_GATE false
#else
#define __GATE(n) _GCC_PLUGIN_CONCAT2(n, _gate)
#define _GATE __GATE(PASS_NAME)
#define _HAS_GATE true
#endif
#ifdef NO_EXECUTE
#define _EXECUTE NULL
#define _HAS_EXECUTE false
#else
#define __EXECUTE(n) _GCC_PLUGIN_CONCAT2(n, _execute)
#define _EXECUTE __EXECUTE(PASS_NAME)
#define _HAS_EXECUTE true
#endif
#ifndef PROPERTIES_REQUIRED
#define PROPERTIES_REQUIRED 0
#endif
#ifndef PROPERTIES_PROVIDED
#define PROPERTIES_PROVIDED 0
#endif
#ifndef PROPERTIES_DESTROYED
#define PROPERTIES_DESTROYED 0
#endif
#ifndef TODO_FLAGS_START
#define TODO_FLAGS_START 0
#endif
#ifndef TODO_FLAGS_FINISH
#define TODO_FLAGS_FINISH 0
#endif
#if BUILDING_GCC_VERSION >= 4009
namespace {
static const pass_data _PASS_NAME_PASS_DATA = {
#else
static struct rtl_opt_pass _PASS_NAME_PASS = {
.pass = {
#endif
.type = RTL_PASS,
.name = _PASS_NAME_NAME,
#if BUILDING_GCC_VERSION >= 4008
.optinfo_flags = OPTGROUP_NONE,
#endif
#if BUILDING_GCC_VERSION >= 5000
#elif BUILDING_GCC_VERSION == 4009
.has_gate = _HAS_GATE,
.has_execute = _HAS_EXECUTE,
#else
.gate = _GATE,
.execute = _EXECUTE,
.sub = NULL,
.next = NULL,
.static_pass_number = 0,
#endif
.tv_id = TV_NONE,
.properties_required = PROPERTIES_REQUIRED,
.properties_provided = PROPERTIES_PROVIDED,
.properties_destroyed = PROPERTIES_DESTROYED,
.todo_flags_start = TODO_FLAGS_START,
.todo_flags_finish = TODO_FLAGS_FINISH,
#if BUILDING_GCC_VERSION < 4009
}
#endif
};
#if BUILDING_GCC_VERSION >= 4009
class _PASS_NAME_PASS : public rtl_opt_pass {
public:
_PASS_NAME_PASS() : rtl_opt_pass(_PASS_NAME_PASS_DATA, g) {}
#ifndef NO_GATE
#if BUILDING_GCC_VERSION >= 5000
virtual bool gate(function *) { return _GATE(); }
#else
virtual bool gate(void) { return _GATE(); }
#endif
#endif
virtual opt_pass *clone() { return new _PASS_NAME_PASS(); }
#ifndef NO_EXECUTE
#if BUILDING_GCC_VERSION >= 5000
virtual unsigned int execute(function *) { return _EXECUTE(); }
#else
virtual unsigned int execute(void) { return _EXECUTE(); }
#endif
#endif
};
}
opt_pass *_MAKE_PASS_NAME_PASS(void)
{
return new _PASS_NAME_PASS();
}
#else
struct opt_pass *_MAKE_PASS_NAME_PASS(void)
{
return &_PASS_NAME_PASS.pass;
}
#endif
/* clean up user provided defines */
#undef PASS_NAME
#undef NO_GATE
#undef NO_EXECUTE
#undef PROPERTIES_DESTROYED
#undef PROPERTIES_PROVIDED
#undef PROPERTIES_REQUIRED
#undef TODO_FLAGS_FINISH
#undef TODO_FLAGS_START
/* clean up generated defines */
#undef _EXECUTE
#undef __EXECUTE
#undef _GATE
#undef __GATE
#undef _GCC_PLUGIN_CONCAT2
#undef _GCC_PLUGIN_CONCAT3
#undef _GCC_PLUGIN_STRINGIFY
#undef __GCC_PLUGIN_STRINGIFY
#undef _HAS_EXECUTE
#undef _HAS_GATE
#undef _MAKE_PASS_NAME_PASS
#undef __MAKE_PASS_NAME_PASS
#undef _PASS_NAME_NAME
#undef _PASS_NAME_PASS
#undef __PASS_NAME_PASS
#undef _PASS_NAME_PASS_DATA
#undef __PASS_NAME_PASS_DATA
#endif /* PASS_NAME */
/*
* Generator for SIMPLE_IPA pass related boilerplate code/data
*
* Supports gcc 4.5-6
*
* Usage:
*
* 1. before inclusion define PASS_NAME
* 2. before inclusion define NO_* for unimplemented callbacks
* NO_GATE
* NO_EXECUTE
* 3. before inclusion define PROPERTIES_* and TODO_FLAGS_* to override
* the default 0 values
* 4. for convenience, all the above will be undefined after inclusion!
* 5. the only exported name is make_PASS_NAME_pass() to register with gcc
*/
#ifndef PASS_NAME
#error at least PASS_NAME must be defined
#else
#define __GCC_PLUGIN_STRINGIFY(n) #n
#define _GCC_PLUGIN_STRINGIFY(n) __GCC_PLUGIN_STRINGIFY(n)
#define _GCC_PLUGIN_CONCAT2(x, y) x ## y
#define _GCC_PLUGIN_CONCAT3(x, y, z) x ## y ## z
#define __PASS_NAME_PASS_DATA(n) _GCC_PLUGIN_CONCAT2(n, _pass_data)
#define _PASS_NAME_PASS_DATA __PASS_NAME_PASS_DATA(PASS_NAME)
#define __PASS_NAME_PASS(n) _GCC_PLUGIN_CONCAT2(n, _pass)
#define _PASS_NAME_PASS __PASS_NAME_PASS(PASS_NAME)
#define _PASS_NAME_NAME _GCC_PLUGIN_STRINGIFY(PASS_NAME)
#define __MAKE_PASS_NAME_PASS(n) _GCC_PLUGIN_CONCAT3(make_, n, _pass)
#define _MAKE_PASS_NAME_PASS __MAKE_PASS_NAME_PASS(PASS_NAME)
#ifdef NO_GATE
#define _GATE NULL
#define _HAS_GATE false
#else
#define __GATE(n) _GCC_PLUGIN_CONCAT2(n, _gate)
#define _GATE __GATE(PASS_NAME)
#define _HAS_GATE true
#endif
#ifdef NO_EXECUTE
#define _EXECUTE NULL
#define _HAS_EXECUTE false
#else
#define __EXECUTE(n) _GCC_PLUGIN_CONCAT2(n, _execute)
#define _EXECUTE __EXECUTE(PASS_NAME)
#define _HAS_EXECUTE true
#endif
#ifndef PROPERTIES_REQUIRED
#define PROPERTIES_REQUIRED 0
#endif
#ifndef PROPERTIES_PROVIDED
#define PROPERTIES_PROVIDED 0
#endif
#ifndef PROPERTIES_DESTROYED
#define PROPERTIES_DESTROYED 0
#endif
#ifndef TODO_FLAGS_START
#define TODO_FLAGS_START 0
#endif
#ifndef TODO_FLAGS_FINISH
#define TODO_FLAGS_FINISH 0
#endif
#if BUILDING_GCC_VERSION >= 4009
namespace {
static const pass_data _PASS_NAME_PASS_DATA = {
#else
static struct simple_ipa_opt_pass _PASS_NAME_PASS = {
.pass = {
#endif
.type = SIMPLE_IPA_PASS,
.name = _PASS_NAME_NAME,
#if BUILDING_GCC_VERSION >= 4008
.optinfo_flags = OPTGROUP_NONE,
#endif
#if BUILDING_GCC_VERSION >= 5000
#elif BUILDING_GCC_VERSION == 4009
.has_gate = _HAS_GATE,
.has_execute = _HAS_EXECUTE,
#else
.gate = _GATE,
.execute = _EXECUTE,
.sub = NULL,
.next = NULL,
.static_pass_number = 0,
#endif
.tv_id = TV_NONE,
.properties_required = PROPERTIES_REQUIRED,
.properties_provided = PROPERTIES_PROVIDED,
.properties_destroyed = PROPERTIES_DESTROYED,
.todo_flags_start = TODO_FLAGS_START,
.todo_flags_finish = TODO_FLAGS_FINISH,
#if BUILDING_GCC_VERSION < 4009
}
#endif
};
#if BUILDING_GCC_VERSION >= 4009
class _PASS_NAME_PASS : public simple_ipa_opt_pass {
public:
_PASS_NAME_PASS() : simple_ipa_opt_pass(_PASS_NAME_PASS_DATA, g) {}
#ifndef NO_GATE
#if BUILDING_GCC_VERSION >= 5000
virtual bool gate(function *) { return _GATE(); }
#else
virtual bool gate(void) { return _GATE(); }
#endif
#endif
virtual opt_pass *clone() { return new _PASS_NAME_PASS(); }
#ifndef NO_EXECUTE
#if BUILDING_GCC_VERSION >= 5000
virtual unsigned int execute(function *) { return _EXECUTE(); }
#else
virtual unsigned int execute(void) { return _EXECUTE(); }
#endif
#endif
};
}
opt_pass *_MAKE_PASS_NAME_PASS(void)
{
return new _PASS_NAME_PASS();
}
#else
struct opt_pass *_MAKE_PASS_NAME_PASS(void)
{
return &_PASS_NAME_PASS.pass;
}
#endif
/* clean up user provided defines */
#undef PASS_NAME
#undef NO_GATE
#undef NO_EXECUTE
#undef PROPERTIES_DESTROYED
#undef PROPERTIES_PROVIDED
#undef PROPERTIES_REQUIRED
#undef TODO_FLAGS_FINISH
#undef TODO_FLAGS_START
/* clean up generated defines */
#undef _EXECUTE
#undef __EXECUTE
#undef _GATE
#undef __GATE
#undef _GCC_PLUGIN_CONCAT2
#undef _GCC_PLUGIN_CONCAT3
#undef _GCC_PLUGIN_STRINGIFY
#undef __GCC_PLUGIN_STRINGIFY
#undef _HAS_EXECUTE
#undef _HAS_GATE
#undef _MAKE_PASS_NAME_PASS
#undef __MAKE_PASS_NAME_PASS
#undef _PASS_NAME_NAME
#undef _PASS_NAME_PASS
#undef __PASS_NAME_PASS
#undef _PASS_NAME_PASS_DATA
#undef __PASS_NAME_PASS_DATA
#endif /* PASS_NAME */
......@@ -180,7 +180,7 @@ else
fi;
# final build of init/
${MAKE} -f "${srctree}/scripts/Makefile.build" obj=init
${MAKE} -f "${srctree}/scripts/Makefile.build" obj=init GCC_PLUGINS_CFLAGS="${GCC_PLUGINS_CFLAGS}"
kallsymso=""
kallsyms_vmlinux=""
......
......@@ -329,6 +329,7 @@ fi
(cd $srctree; find arch/$SRCARCH -name module.lds -o -name Kbuild.platforms -o -name Platform) >> "$objtree/debian/hdrsrcfiles"
(cd $srctree; find $(find arch/$SRCARCH -name include -o -name scripts -type d) -type f) >> "$objtree/debian/hdrsrcfiles"
(cd $objtree; find arch/$SRCARCH/include Module.symvers include scripts -type f) >> "$objtree/debian/hdrobjfiles"
(cd $objtree; find scripts/gcc-plugins -name \*.so -o -name gcc-common.h) >> "$objtree/debian/hdrobjfiles"
destdir=$kernel_headers_dir/usr/src/linux-headers-$version
mkdir -p "$destdir"
(cd $srctree; tar -c -f - -T -) < "$objtree/debian/hdrsrcfiles" | (cd $destdir; tar -xf -)
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册