aboutsummaryrefslogtreecommitdiffstats
path: root/scripts/gcc-plugins/gcc-generate-ipa-pass.h
diff options
context:
space:
mode:
authorEmese Revfy <re.emese@gmail.com>2016-05-23 18:09:38 -0400
committerMichal Marek <mmarek@suse.com>2016-06-07 16:57:10 -0400
commit6b90bd4ba40b38dc13c2782469c1c77e4ed79915 (patch)
tree02d65b38b76e3543d33088ae9149010bae0290b0 /scripts/gcc-plugins/gcc-generate-ipa-pass.h
parent24403874316a7180d367e51d7f7e25d5de1f78dd (diff)
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: Emese Revfy <re.emese@gmail.com> Acked-by: Kees Cook <keescook@chromium.org> Signed-off-by: Michal Marek <mmarek@suse.com>
Diffstat (limited to 'scripts/gcc-plugins/gcc-generate-ipa-pass.h')
-rw-r--r--scripts/gcc-plugins/gcc-generate-ipa-pass.h289
1 files changed, 289 insertions, 0 deletions
diff --git a/scripts/gcc-plugins/gcc-generate-ipa-pass.h b/scripts/gcc-plugins/gcc-generate-ipa-pass.h
new file mode 100644
index 000000000000..9bd926e072f0
--- /dev/null
+++ b/scripts/gcc-plugins/gcc-generate-ipa-pass.h
@@ -0,0 +1,289 @@
1/*
2 * Generator for IPA pass related boilerplate code/data
3 *
4 * Supports gcc 4.5-6
5 *
6 * Usage:
7 *
8 * 1. before inclusion define PASS_NAME
9 * 2. before inclusion define NO_* for unimplemented callbacks
10 * NO_GENERATE_SUMMARY
11 * NO_READ_SUMMARY
12 * NO_WRITE_SUMMARY
13 * NO_READ_OPTIMIZATION_SUMMARY
14 * NO_WRITE_OPTIMIZATION_SUMMARY
15 * NO_STMT_FIXUP
16 * NO_FUNCTION_TRANSFORM
17 * NO_VARIABLE_TRANSFORM
18 * NO_GATE
19 * NO_EXECUTE
20 * 3. before inclusion define PROPERTIES_* and *TODO_FLAGS_* to override
21 * the default 0 values
22 * 4. for convenience, all the above will be undefined after inclusion!
23 * 5. the only exported name is make_PASS_NAME_pass() to register with gcc
24 */
25
26#ifndef PASS_NAME
27#error at least PASS_NAME must be defined
28#else
29#define __GCC_PLUGIN_STRINGIFY(n) #n
30#define _GCC_PLUGIN_STRINGIFY(n) __GCC_PLUGIN_STRINGIFY(n)
31#define _GCC_PLUGIN_CONCAT2(x, y) x ## y
32#define _GCC_PLUGIN_CONCAT3(x, y, z) x ## y ## z
33
34#define __PASS_NAME_PASS_DATA(n) _GCC_PLUGIN_CONCAT2(n, _pass_data)
35#define _PASS_NAME_PASS_DATA __PASS_NAME_PASS_DATA(PASS_NAME)
36
37#define __PASS_NAME_PASS(n) _GCC_PLUGIN_CONCAT2(n, _pass)
38#define _PASS_NAME_PASS __PASS_NAME_PASS(PASS_NAME)
39
40#define _PASS_NAME_NAME _GCC_PLUGIN_STRINGIFY(PASS_NAME)
41
42#define __MAKE_PASS_NAME_PASS(n) _GCC_PLUGIN_CONCAT3(make_, n, _pass)
43#define _MAKE_PASS_NAME_PASS __MAKE_PASS_NAME_PASS(PASS_NAME)
44
45#ifdef NO_GENERATE_SUMMARY
46#define _GENERATE_SUMMARY NULL
47#else
48#define __GENERATE_SUMMARY(n) _GCC_PLUGIN_CONCAT2(n, _generate_summary)
49#define _GENERATE_SUMMARY __GENERATE_SUMMARY(PASS_NAME)
50#endif
51
52#ifdef NO_READ_SUMMARY
53#define _READ_SUMMARY NULL
54#else
55#define __READ_SUMMARY(n) _GCC_PLUGIN_CONCAT2(n, _read_summary)
56#define _READ_SUMMARY __READ_SUMMARY(PASS_NAME)
57#endif
58
59#ifdef NO_WRITE_SUMMARY
60#define _WRITE_SUMMARY NULL
61#else
62#define __WRITE_SUMMARY(n) _GCC_PLUGIN_CONCAT2(n, _write_summary)
63#define _WRITE_SUMMARY __WRITE_SUMMARY(PASS_NAME)
64#endif
65
66#ifdef NO_READ_OPTIMIZATION_SUMMARY
67#define _READ_OPTIMIZATION_SUMMARY NULL
68#else
69#define __READ_OPTIMIZATION_SUMMARY(n) _GCC_PLUGIN_CONCAT2(n, _read_optimization_summary)
70#define _READ_OPTIMIZATION_SUMMARY __READ_OPTIMIZATION_SUMMARY(PASS_NAME)
71#endif
72
73#ifdef NO_WRITE_OPTIMIZATION_SUMMARY
74#define _WRITE_OPTIMIZATION_SUMMARY NULL
75#else
76#define __WRITE_OPTIMIZATION_SUMMARY(n) _GCC_PLUGIN_CONCAT2(n, _write_optimization_summary)
77#define _WRITE_OPTIMIZATION_SUMMARY __WRITE_OPTIMIZATION_SUMMARY(PASS_NAME)
78#endif
79
80#ifdef NO_STMT_FIXUP
81#define _STMT_FIXUP NULL
82#else
83#define __STMT_FIXUP(n) _GCC_PLUGIN_CONCAT2(n, _stmt_fixup)
84#define _STMT_FIXUP __STMT_FIXUP(PASS_NAME)
85#endif
86
87#ifdef NO_FUNCTION_TRANSFORM
88#define _FUNCTION_TRANSFORM NULL
89#else
90#define __FUNCTION_TRANSFORM(n) _GCC_PLUGIN_CONCAT2(n, _function_transform)
91#define _FUNCTION_TRANSFORM __FUNCTION_TRANSFORM(PASS_NAME)
92#endif
93
94#ifdef NO_VARIABLE_TRANSFORM
95#define _VARIABLE_TRANSFORM NULL
96#else
97#define __VARIABLE_TRANSFORM(n) _GCC_PLUGIN_CONCAT2(n, _variable_transform)
98#define _VARIABLE_TRANSFORM __VARIABLE_TRANSFORM(PASS_NAME)
99#endif
100
101#ifdef NO_GATE
102#define _GATE NULL
103#define _HAS_GATE false
104#else
105#define __GATE(n) _GCC_PLUGIN_CONCAT2(n, _gate)
106#define _GATE __GATE(PASS_NAME)
107#define _HAS_GATE true
108#endif
109
110#ifdef NO_EXECUTE
111#define _EXECUTE NULL
112#define _HAS_EXECUTE false
113#else
114#define __EXECUTE(n) _GCC_PLUGIN_CONCAT2(n, _execute)
115#define _EXECUTE __EXECUTE(PASS_NAME)
116#define _HAS_EXECUTE true
117#endif
118
119#ifndef PROPERTIES_REQUIRED
120#define PROPERTIES_REQUIRED 0
121#endif
122
123#ifndef PROPERTIES_PROVIDED
124#define PROPERTIES_PROVIDED 0
125#endif
126
127#ifndef PROPERTIES_DESTROYED
128#define PROPERTIES_DESTROYED 0
129#endif
130
131#ifndef TODO_FLAGS_START
132#define TODO_FLAGS_START 0
133#endif
134
135#ifndef TODO_FLAGS_FINISH
136#define TODO_FLAGS_FINISH 0
137#endif
138
139#ifndef FUNCTION_TRANSFORM_TODO_FLAGS_START
140#define FUNCTION_TRANSFORM_TODO_FLAGS_START 0
141#endif
142
143#if BUILDING_GCC_VERSION >= 4009
144namespace {
145static const pass_data _PASS_NAME_PASS_DATA = {
146#else
147static struct ipa_opt_pass_d _PASS_NAME_PASS = {
148 .pass = {
149#endif
150 .type = IPA_PASS,
151 .name = _PASS_NAME_NAME,
152#if BUILDING_GCC_VERSION >= 4008
153 .optinfo_flags = OPTGROUP_NONE,
154#endif
155#if BUILDING_GCC_VERSION >= 5000
156#elif BUILDING_GCC_VERSION == 4009
157 .has_gate = _HAS_GATE,
158 .has_execute = _HAS_EXECUTE,
159#else
160 .gate = _GATE,
161 .execute = _EXECUTE,
162 .sub = NULL,
163 .next = NULL,
164 .static_pass_number = 0,
165#endif
166 .tv_id = TV_NONE,
167 .properties_required = PROPERTIES_REQUIRED,
168 .properties_provided = PROPERTIES_PROVIDED,
169 .properties_destroyed = PROPERTIES_DESTROYED,
170 .todo_flags_start = TODO_FLAGS_START,
171 .todo_flags_finish = TODO_FLAGS_FINISH,
172#if BUILDING_GCC_VERSION < 4009
173 },
174 .generate_summary = _GENERATE_SUMMARY,
175 .write_summary = _WRITE_SUMMARY,
176 .read_summary = _READ_SUMMARY,
177#if BUILDING_GCC_VERSION >= 4006
178 .write_optimization_summary = _WRITE_OPTIMIZATION_SUMMARY,
179 .read_optimization_summary = _READ_OPTIMIZATION_SUMMARY,
180#endif
181 .stmt_fixup = _STMT_FIXUP,
182 .function_transform_todo_flags_start = FUNCTION_TRANSFORM_TODO_FLAGS_START,
183 .function_transform = _FUNCTION_TRANSFORM,
184 .variable_transform = _VARIABLE_TRANSFORM,
185#endif
186};
187
188#if BUILDING_GCC_VERSION >= 4009
189class _PASS_NAME_PASS : public ipa_opt_pass_d {
190public:
191 _PASS_NAME_PASS() : ipa_opt_pass_d(_PASS_NAME_PASS_DATA,
192 g,
193 _GENERATE_SUMMARY,
194 _WRITE_SUMMARY,
195 _READ_SUMMARY,
196 _WRITE_OPTIMIZATION_SUMMARY,
197 _READ_OPTIMIZATION_SUMMARY,
198 _STMT_FIXUP,
199 FUNCTION_TRANSFORM_TODO_FLAGS_START,
200 _FUNCTION_TRANSFORM,
201 _VARIABLE_TRANSFORM) {}
202
203#ifndef NO_GATE
204#if BUILDING_GCC_VERSION >= 5000
205 virtual bool gate(function *) { return _GATE(); }
206#else
207 virtual bool gate(void) { return _GATE(); }
208#endif
209#endif
210
211 virtual opt_pass *clone() { return new _PASS_NAME_PASS(); }
212
213#ifndef NO_EXECUTE
214#if BUILDING_GCC_VERSION >= 5000
215 virtual unsigned int execute(function *) { return _EXECUTE(); }
216#else
217 virtual unsigned int execute(void) { return _EXECUTE(); }
218#endif
219#endif
220};
221}
222
223opt_pass *_MAKE_PASS_NAME_PASS(void)
224{
225 return new _PASS_NAME_PASS();
226}
227#else
228struct opt_pass *_MAKE_PASS_NAME_PASS(void)
229{
230 return &_PASS_NAME_PASS.pass;
231}
232#endif
233
234/* clean up user provided defines */
235#undef PASS_NAME
236#undef NO_GENERATE_SUMMARY
237#undef NO_WRITE_SUMMARY
238#undef NO_READ_SUMMARY
239#undef NO_WRITE_OPTIMIZATION_SUMMARY
240#undef NO_READ_OPTIMIZATION_SUMMARY
241#undef NO_STMT_FIXUP
242#undef NO_FUNCTION_TRANSFORM
243#undef NO_VARIABLE_TRANSFORM
244#undef NO_GATE
245#undef NO_EXECUTE
246
247#undef FUNCTION_TRANSFORM_TODO_FLAGS_START
248#undef PROPERTIES_DESTROYED
249#undef PROPERTIES_PROVIDED
250#undef PROPERTIES_REQUIRED
251#undef TODO_FLAGS_FINISH
252#undef TODO_FLAGS_START
253
254/* clean up generated defines */
255#undef _EXECUTE
256#undef __EXECUTE
257#undef _FUNCTION_TRANSFORM
258#undef __FUNCTION_TRANSFORM
259#undef _GATE
260#undef __GATE
261#undef _GCC_PLUGIN_CONCAT2
262#undef _GCC_PLUGIN_CONCAT3
263#undef _GCC_PLUGIN_STRINGIFY
264#undef __GCC_PLUGIN_STRINGIFY
265#undef _GENERATE_SUMMARY
266#undef __GENERATE_SUMMARY
267#undef _HAS_EXECUTE
268#undef _HAS_GATE
269#undef _MAKE_PASS_NAME_PASS
270#undef __MAKE_PASS_NAME_PASS
271#undef _PASS_NAME_NAME
272#undef _PASS_NAME_PASS
273#undef __PASS_NAME_PASS
274#undef _PASS_NAME_PASS_DATA
275#undef __PASS_NAME_PASS_DATA
276#undef _READ_OPTIMIZATION_SUMMARY
277#undef __READ_OPTIMIZATION_SUMMARY
278#undef _READ_SUMMARY
279#undef __READ_SUMMARY
280#undef _STMT_FIXUP
281#undef __STMT_FIXUP
282#undef _VARIABLE_TRANSFORM
283#undef __VARIABLE_TRANSFORM
284#undef _WRITE_OPTIMIZATION_SUMMARY
285#undef __WRITE_OPTIMIZATION_SUMMARY
286#undef _WRITE_SUMMARY
287#undef __WRITE_SUMMARY
288
289#endif /* PASS_NAME */