1 |
commit: 280308c77f05895c44d9eadd35ca8e505e9be30c |
2 |
Author: Aric Belsito <lluixhi <AT> gmail <DOT> com> |
3 |
AuthorDate: Tue Jan 16 04:49:39 2018 +0000 |
4 |
Commit: Aric Belsito <lluixhi <AT> gmail <DOT> com> |
5 |
CommitDate: Tue Jan 16 04:49:39 2018 +0000 |
6 |
URL: https://gitweb.gentoo.org/proj/musl.git/commit/?id=280308c7 |
7 |
|
8 |
sys-devel/gcc: sync 7.2.0-r1 with upstream |
9 |
|
10 |
Add patches for spectre *WARNING, EXPERIMENTAL PORT* |
11 |
|
12 |
The gcc-7.2.0-move-struct-ix86_frame-to-machine-function patches are |
13 |
designed for gcc 7, but the spectre patches are taken from the final |
14 |
version of the gcc 8 patchset, adapted for gcc 7. |
15 |
|
16 |
...ove-struct-ix86_frame-to-machine-function.patch | 237 +++ |
17 |
...ove-struct-ix86_frame-to-machine-function.patch | 68 + |
18 |
...ove-struct-ix86_frame-to-machine-function.patch | 53 + |
19 |
.../gcc/files/spectre-0001-mindirect-branch.patch | 2111 ++++++++++++++++++++ |
20 |
.../gcc/files/spectre-0002-mfunction-return.patch | 1200 +++++++++++ |
21 |
.../spectre-0003-mindirect-branch-register.patch | 887 ++++++++ |
22 |
.../files/spectre-0004-v-register-modifier.patch | 128 ++ |
23 |
.../gcc/files/spectre-0005-mcmodel-large.patch | 292 +++ |
24 |
sys-devel/gcc/gcc-7.2.0-r1.ebuild | 14 +- |
25 |
9 files changed, 4988 insertions(+), 2 deletions(-) |
26 |
|
27 |
diff --git a/sys-devel/gcc/files/0001-gcc-7.2.0-move-struct-ix86_frame-to-machine-function.patch b/sys-devel/gcc/files/0001-gcc-7.2.0-move-struct-ix86_frame-to-machine-function.patch |
28 |
new file mode 100644 |
29 |
index 0000000..d85ed2c |
30 |
--- /dev/null |
31 |
+++ b/sys-devel/gcc/files/0001-gcc-7.2.0-move-struct-ix86_frame-to-machine-function.patch |
32 |
@@ -0,0 +1,237 @@ |
33 |
+From: "H.J. Lu" <hjl.tools@×××××.com> |
34 |
+To: gcc-patches@×××××××.org |
35 |
+Subject: [1/3] GCC 7: i386: Move struct ix86_frame to machine_function |
36 |
+Date: Sun, 14 Jan 2018 07:02:35 -0800 |
37 |
+ |
38 |
+Make ix86_frame available to i386 code generation. This is needed to |
39 |
+backport the patch set of -mindirect-branch= to mitigate variant #2 of |
40 |
+the speculative execution vulnerabilities on x86 processors identified |
41 |
+by CVE-2017-5715, aka Spectre. |
42 |
+ |
43 |
+ Backport from mainline |
44 |
+ * config/i386/i386.c (ix86_frame): Moved to ... |
45 |
+ * config/i386/i386.h (ix86_frame): Here. |
46 |
+ (machine_function): Add frame. |
47 |
+ * config/i386/i386.c (ix86_compute_frame_layout): Repace the |
48 |
+ frame argument with &cfun->machine->frame. |
49 |
+ (ix86_can_use_return_insn_p): Don't pass &frame to |
50 |
+ ix86_compute_frame_layout. Copy frame from cfun->machine->frame. |
51 |
+ (ix86_can_eliminate): Likewise. |
52 |
+ (ix86_expand_prologue): Likewise. |
53 |
+ (ix86_expand_epilogue): Likewise. |
54 |
+ (ix86_expand_split_stack_prologue): Likewise. |
55 |
+--- |
56 |
+ gcc/config/i386/i386.c | 68 ++++++++++---------------------------------------- |
57 |
+ gcc/config/i386/i386.h | 53 ++++++++++++++++++++++++++++++++++++++- |
58 |
+ 2 files changed, 65 insertions(+), 56 deletions(-) |
59 |
+ |
60 |
+diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c |
61 |
+index 8a3782c0298..813337242d8 100644 |
62 |
+--- a/gcc/config/i386/i386.c |
63 |
++++ b/gcc/config/i386/i386.c |
64 |
+@@ -2444,53 +2444,6 @@ struct GTY(()) stack_local_entry { |
65 |
+ struct stack_local_entry *next; |
66 |
+ }; |
67 |
+ |
68 |
+-/* Structure describing stack frame layout. |
69 |
+- Stack grows downward: |
70 |
+- |
71 |
+- [arguments] |
72 |
+- <- ARG_POINTER |
73 |
+- saved pc |
74 |
+- |
75 |
+- saved static chain if ix86_static_chain_on_stack |
76 |
+- |
77 |
+- saved frame pointer if frame_pointer_needed |
78 |
+- <- HARD_FRAME_POINTER |
79 |
+- [saved regs] |
80 |
+- <- regs_save_offset |
81 |
+- [padding0] |
82 |
+- |
83 |
+- [saved SSE regs] |
84 |
+- <- sse_regs_save_offset |
85 |
+- [padding1] | |
86 |
+- | <- FRAME_POINTER |
87 |
+- [va_arg registers] | |
88 |
+- | |
89 |
+- [frame] | |
90 |
+- | |
91 |
+- [padding2] | = to_allocate |
92 |
+- <- STACK_POINTER |
93 |
+- */ |
94 |
+-struct ix86_frame |
95 |
+-{ |
96 |
+- int nsseregs; |
97 |
+- int nregs; |
98 |
+- int va_arg_size; |
99 |
+- int red_zone_size; |
100 |
+- int outgoing_arguments_size; |
101 |
+- |
102 |
+- /* The offsets relative to ARG_POINTER. */ |
103 |
+- HOST_WIDE_INT frame_pointer_offset; |
104 |
+- HOST_WIDE_INT hard_frame_pointer_offset; |
105 |
+- HOST_WIDE_INT stack_pointer_offset; |
106 |
+- HOST_WIDE_INT hfp_save_offset; |
107 |
+- HOST_WIDE_INT reg_save_offset; |
108 |
+- HOST_WIDE_INT sse_reg_save_offset; |
109 |
+- |
110 |
+- /* When save_regs_using_mov is set, emit prologue using |
111 |
+- move instead of push instructions. */ |
112 |
+- bool save_regs_using_mov; |
113 |
+-}; |
114 |
+- |
115 |
+ /* Which cpu are we scheduling for. */ |
116 |
+ enum attr_cpu ix86_schedule; |
117 |
+ |
118 |
+@@ -2582,7 +2535,7 @@ static unsigned int ix86_function_arg_boundary (machine_mode, |
119 |
+ const_tree); |
120 |
+ static rtx ix86_static_chain (const_tree, bool); |
121 |
+ static int ix86_function_regparm (const_tree, const_tree); |
122 |
+-static void ix86_compute_frame_layout (struct ix86_frame *); |
123 |
++static void ix86_compute_frame_layout (void); |
124 |
+ static bool ix86_expand_vector_init_one_nonzero (bool, machine_mode, |
125 |
+ rtx, rtx, int); |
126 |
+ static void ix86_add_new_builtins (HOST_WIDE_INT, HOST_WIDE_INT); |
127 |
+@@ -11903,7 +11856,8 @@ ix86_can_use_return_insn_p (void) |
128 |
+ if (crtl->args.pops_args && crtl->args.size >= 32768) |
129 |
+ return 0; |
130 |
+ |
131 |
+- ix86_compute_frame_layout (&frame); |
132 |
++ ix86_compute_frame_layout (); |
133 |
++ frame = cfun->machine->frame; |
134 |
+ return (frame.stack_pointer_offset == UNITS_PER_WORD |
135 |
+ && (frame.nregs + frame.nsseregs) == 0); |
136 |
+ } |
137 |
+@@ -12389,8 +12343,8 @@ ix86_can_eliminate (const int from, const int to) |
138 |
+ HOST_WIDE_INT |
139 |
+ ix86_initial_elimination_offset (int from, int to) |
140 |
+ { |
141 |
+- struct ix86_frame frame; |
142 |
+- ix86_compute_frame_layout (&frame); |
143 |
++ ix86_compute_frame_layout (); |
144 |
++ struct ix86_frame frame = cfun->machine->frame; |
145 |
+ |
146 |
+ if (from == ARG_POINTER_REGNUM && to == HARD_FRAME_POINTER_REGNUM) |
147 |
+ return frame.hard_frame_pointer_offset; |
148 |
+@@ -12429,8 +12383,9 @@ ix86_builtin_setjmp_frame_value (void) |
149 |
+ /* Fill structure ix86_frame about frame of currently computed function. */ |
150 |
+ |
151 |
+ static void |
152 |
+-ix86_compute_frame_layout (struct ix86_frame *frame) |
153 |
++ix86_compute_frame_layout (void) |
154 |
+ { |
155 |
++ struct ix86_frame *frame = &cfun->machine->frame; |
156 |
+ unsigned HOST_WIDE_INT stack_alignment_needed; |
157 |
+ HOST_WIDE_INT offset; |
158 |
+ unsigned HOST_WIDE_INT preferred_alignment; |
159 |
+@@ -13737,7 +13692,8 @@ ix86_expand_prologue (void) |
160 |
+ m->fs.sp_offset = INCOMING_FRAME_SP_OFFSET; |
161 |
+ m->fs.sp_valid = true; |
162 |
+ |
163 |
+- ix86_compute_frame_layout (&frame); |
164 |
++ ix86_compute_frame_layout (); |
165 |
++ frame = m->frame; |
166 |
+ |
167 |
+ if (!TARGET_64BIT && ix86_function_ms_hook_prologue (current_function_decl)) |
168 |
+ { |
169 |
+@@ -14405,7 +14361,8 @@ ix86_expand_epilogue (int style) |
170 |
+ bool using_drap; |
171 |
+ |
172 |
+ ix86_finalize_stack_realign_flags (); |
173 |
+- ix86_compute_frame_layout (&frame); |
174 |
++ ix86_compute_frame_layout (); |
175 |
++ frame = m->frame; |
176 |
+ |
177 |
+ m->fs.sp_valid = (!frame_pointer_needed |
178 |
+ || (crtl->sp_is_unchanging |
179 |
+@@ -14915,7 +14872,8 @@ ix86_expand_split_stack_prologue (void) |
180 |
+ gcc_assert (flag_split_stack && reload_completed); |
181 |
+ |
182 |
+ ix86_finalize_stack_realign_flags (); |
183 |
+- ix86_compute_frame_layout (&frame); |
184 |
++ ix86_compute_frame_layout (); |
185 |
++ frame = cfun->machine->frame; |
186 |
+ allocate = frame.stack_pointer_offset - INCOMING_FRAME_SP_OFFSET; |
187 |
+ |
188 |
+ /* This is the label we will branch to if we have enough stack |
189 |
+diff --git a/gcc/config/i386/i386.h b/gcc/config/i386/i386.h |
190 |
+index 9c776dc5172..f9b91286a01 100644 |
191 |
+--- a/gcc/config/i386/i386.h |
192 |
++++ b/gcc/config/i386/i386.h |
193 |
+@@ -2451,9 +2451,56 @@ enum avx_u128_state |
194 |
+ |
195 |
+ #define FASTCALL_PREFIX '@' |
196 |
+ |
197 |
++#ifndef USED_FOR_TARGET |
198 |
++/* Structure describing stack frame layout. |
199 |
++ Stack grows downward: |
200 |
++ |
201 |
++ [arguments] |
202 |
++ <- ARG_POINTER |
203 |
++ saved pc |
204 |
++ |
205 |
++ saved static chain if ix86_static_chain_on_stack |
206 |
++ |
207 |
++ saved frame pointer if frame_pointer_needed |
208 |
++ <- HARD_FRAME_POINTER |
209 |
++ [saved regs] |
210 |
++ <- regs_save_offset |
211 |
++ [padding0] |
212 |
++ |
213 |
++ [saved SSE regs] |
214 |
++ <- sse_regs_save_offset |
215 |
++ [padding1] | |
216 |
++ | <- FRAME_POINTER |
217 |
++ [va_arg registers] | |
218 |
++ | |
219 |
++ [frame] | |
220 |
++ | |
221 |
++ [padding2] | = to_allocate |
222 |
++ <- STACK_POINTER |
223 |
++ */ |
224 |
++struct GTY(()) ix86_frame |
225 |
++{ |
226 |
++ int nsseregs; |
227 |
++ int nregs; |
228 |
++ int va_arg_size; |
229 |
++ int red_zone_size; |
230 |
++ int outgoing_arguments_size; |
231 |
++ |
232 |
++ /* The offsets relative to ARG_POINTER. */ |
233 |
++ HOST_WIDE_INT frame_pointer_offset; |
234 |
++ HOST_WIDE_INT hard_frame_pointer_offset; |
235 |
++ HOST_WIDE_INT stack_pointer_offset; |
236 |
++ HOST_WIDE_INT hfp_save_offset; |
237 |
++ HOST_WIDE_INT reg_save_offset; |
238 |
++ HOST_WIDE_INT sse_reg_save_offset; |
239 |
++ |
240 |
++ /* When save_regs_using_mov is set, emit prologue using |
241 |
++ move instead of push instructions. */ |
242 |
++ bool save_regs_using_mov; |
243 |
++}; |
244 |
++ |
245 |
+ /* Machine specific frame tracking during prologue/epilogue generation. */ |
246 |
+ |
247 |
+-#ifndef USED_FOR_TARGET |
248 |
+ struct GTY(()) machine_frame_state |
249 |
+ { |
250 |
+ /* This pair tracks the currently active CFA as reg+offset. When reg |
251 |
+@@ -2512,6 +2559,9 @@ struct GTY(()) machine_function { |
252 |
+ int varargs_fpr_size; |
253 |
+ int optimize_mode_switching[MAX_386_ENTITIES]; |
254 |
+ |
255 |
++ /* Cached initial frame layout for the current function. */ |
256 |
++ struct ix86_frame frame; |
257 |
++ |
258 |
+ /* Number of saved registers USE_FAST_PROLOGUE_EPILOGUE |
259 |
+ has been computed for. */ |
260 |
+ int use_fast_prologue_epilogue_nregs; |
261 |
+@@ -2594,6 +2644,7 @@ struct GTY(()) machine_function { |
262 |
+ #define ix86_current_function_calls_tls_descriptor \ |
263 |
+ (ix86_tls_descriptor_calls_expanded_in_cfun && df_regs_ever_live_p (SP_REG)) |
264 |
+ #define ix86_static_chain_on_stack (cfun->machine->static_chain_on_stack) |
265 |
++#define ix86_red_zone_size (cfun->machine->frame.red_zone_size) |
266 |
+ |
267 |
+ /* Control behavior of x86_file_start. */ |
268 |
+ #define X86_FILE_START_VERSION_DIRECTIVE false |
269 |
+ |
270 |
|
271 |
diff --git a/sys-devel/gcc/files/0002-gcc-7.2.0-move-struct-ix86_frame-to-machine-function.patch b/sys-devel/gcc/files/0002-gcc-7.2.0-move-struct-ix86_frame-to-machine-function.patch |
272 |
new file mode 100644 |
273 |
index 0000000..a086d03 |
274 |
--- /dev/null |
275 |
+++ b/sys-devel/gcc/files/0002-gcc-7.2.0-move-struct-ix86_frame-to-machine-function.patch |
276 |
@@ -0,0 +1,68 @@ |
277 |
+From: "H.J. Lu" <hjl.tools@×××××.com> |
278 |
+To: gcc-patches@×××××××.org |
279 |
+Subject: [2/3] GCC 7: i386: Use reference of struct ix86_frame to avoid copy |
280 |
+Date: Sun, 14 Jan 2018 07:02:36 -0800 |
281 |
+ |
282 |
+When there is no need to make a copy of ix86_frame, we can use reference |
283 |
+of struct ix86_frame to avoid copy. |
284 |
+ |
285 |
+Tested on x86-64. |
286 |
+ |
287 |
+ Backport from mainline |
288 |
+ * config/i386/i386.c (ix86_can_use_return_insn_p): Use reference |
289 |
+ of struct ix86_frame. |
290 |
+ (ix86_initial_elimination_offset): Likewise. |
291 |
+ (ix86_expand_split_stack_prologue): Likewise. |
292 |
+--- |
293 |
+ gcc/config/i386/i386.c | 9 +++------ |
294 |
+ 1 file changed, 3 insertions(+), 6 deletions(-) |
295 |
+ |
296 |
+diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c |
297 |
+index 813337242d8..397ef7cac26 100644 |
298 |
+--- a/gcc/config/i386/i386.c |
299 |
++++ b/gcc/config/i386/i386.c |
300 |
+@@ -11843,8 +11843,6 @@ symbolic_reference_mentioned_p (rtx op) |
301 |
+ bool |
302 |
+ ix86_can_use_return_insn_p (void) |
303 |
+ { |
304 |
+- struct ix86_frame frame; |
305 |
+- |
306 |
+ /* Don't use `ret' instruction in interrupt handler. */ |
307 |
+ if (! reload_completed |
308 |
+ || frame_pointer_needed |
309 |
+@@ -11857,7 +11855,7 @@ ix86_can_use_return_insn_p (void) |
310 |
+ return 0; |
311 |
+ |
312 |
+ ix86_compute_frame_layout (); |
313 |
+- frame = cfun->machine->frame; |
314 |
++ struct ix86_frame &frame = cfun->machine->frame; |
315 |
+ return (frame.stack_pointer_offset == UNITS_PER_WORD |
316 |
+ && (frame.nregs + frame.nsseregs) == 0); |
317 |
+ } |
318 |
+@@ -12344,7 +12342,7 @@ HOST_WIDE_INT |
319 |
+ ix86_initial_elimination_offset (int from, int to) |
320 |
+ { |
321 |
+ ix86_compute_frame_layout (); |
322 |
+- struct ix86_frame frame = cfun->machine->frame; |
323 |
++ struct ix86_frame &frame = cfun->machine->frame; |
324 |
+ |
325 |
+ if (from == ARG_POINTER_REGNUM && to == HARD_FRAME_POINTER_REGNUM) |
326 |
+ return frame.hard_frame_pointer_offset; |
327 |
+@@ -14860,7 +14858,6 @@ static GTY(()) rtx split_stack_fn_large; |
328 |
+ void |
329 |
+ ix86_expand_split_stack_prologue (void) |
330 |
+ { |
331 |
+- struct ix86_frame frame; |
332 |
+ HOST_WIDE_INT allocate; |
333 |
+ unsigned HOST_WIDE_INT args_size; |
334 |
+ rtx_code_label *label; |
335 |
+@@ -14873,7 +14870,7 @@ ix86_expand_split_stack_prologue (void) |
336 |
+ |
337 |
+ ix86_finalize_stack_realign_flags (); |
338 |
+ ix86_compute_frame_layout (); |
339 |
+- frame = cfun->machine->frame; |
340 |
++ struct ix86_frame &frame = cfun->machine->frame; |
341 |
+ allocate = frame.stack_pointer_offset - INCOMING_FRAME_SP_OFFSET; |
342 |
+ |
343 |
+ /* This is the label we will branch to if we have enough stack |
344 |
+ |
345 |
|
346 |
diff --git a/sys-devel/gcc/files/0003-gcc-7.2.0-move-struct-ix86_frame-to-machine-function.patch b/sys-devel/gcc/files/0003-gcc-7.2.0-move-struct-ix86_frame-to-machine-function.patch |
347 |
new file mode 100644 |
348 |
index 0000000..2f27301 |
349 |
--- /dev/null |
350 |
+++ b/sys-devel/gcc/files/0003-gcc-7.2.0-move-struct-ix86_frame-to-machine-function.patch |
351 |
@@ -0,0 +1,53 @@ |
352 |
+From: "H.J. Lu" <hjl.tools@×××××.com> |
353 |
+To: gcc-patches@×××××××.org |
354 |
+Subject: [3/3] GCC 7: i386: More use reference of struct ix86_frame to avoid |
355 |
+ copy |
356 |
+Date: Sun, 14 Jan 2018 07:02:37 -0800 |
357 |
+ |
358 |
+When there is no need to make a copy of ix86_frame, we can use reference |
359 |
+of struct ix86_frame to avoid copy. |
360 |
+ |
361 |
+ Backport from mainline |
362 |
+ * config/i386/i386.c (ix86_expand_prologue): Use reference of |
363 |
+ struct ix86_frame. |
364 |
+ (ix86_expand_epilogue): Likewise. |
365 |
+--- |
366 |
+ gcc/config/i386/i386.c | 6 ++---- |
367 |
+ 1 file changed, 2 insertions(+), 4 deletions(-) |
368 |
+ |
369 |
+diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c |
370 |
+index 397ef7cac26..986e6d79584 100644 |
371 |
+--- a/gcc/config/i386/i386.c |
372 |
++++ b/gcc/config/i386/i386.c |
373 |
+@@ -13667,7 +13667,6 @@ ix86_expand_prologue (void) |
374 |
+ { |
375 |
+ struct machine_function *m = cfun->machine; |
376 |
+ rtx insn, t; |
377 |
+- struct ix86_frame frame; |
378 |
+ HOST_WIDE_INT allocate; |
379 |
+ bool int_registers_saved; |
380 |
+ bool sse_registers_saved; |
381 |
+@@ -13691,7 +13690,7 @@ ix86_expand_prologue (void) |
382 |
+ m->fs.sp_valid = true; |
383 |
+ |
384 |
+ ix86_compute_frame_layout (); |
385 |
+- frame = m->frame; |
386 |
++ struct ix86_frame &frame = cfun->machine->frame; |
387 |
+ |
388 |
+ if (!TARGET_64BIT && ix86_function_ms_hook_prologue (current_function_decl)) |
389 |
+ { |
390 |
+@@ -14354,13 +14353,12 @@ ix86_expand_epilogue (int style) |
391 |
+ { |
392 |
+ struct machine_function *m = cfun->machine; |
393 |
+ struct machine_frame_state frame_state_save = m->fs; |
394 |
+- struct ix86_frame frame; |
395 |
+ bool restore_regs_via_mov; |
396 |
+ bool using_drap; |
397 |
+ |
398 |
+ ix86_finalize_stack_realign_flags (); |
399 |
+ ix86_compute_frame_layout (); |
400 |
+- frame = m->frame; |
401 |
++ struct ix86_frame &frame = cfun->machine->frame; |
402 |
+ |
403 |
+ m->fs.sp_valid = (!frame_pointer_needed |
404 |
+ || (crtl->sp_is_unchanging |
405 |
|
406 |
diff --git a/sys-devel/gcc/files/spectre-0001-mindirect-branch.patch b/sys-devel/gcc/files/spectre-0001-mindirect-branch.patch |
407 |
new file mode 100644 |
408 |
index 0000000..2e03cee |
409 |
--- /dev/null |
410 |
+++ b/sys-devel/gcc/files/spectre-0001-mindirect-branch.patch |
411 |
@@ -0,0 +1,2111 @@ |
412 |
+From: "H dot J dot Lu" <hjl dot tools at gmail dot com> |
413 |
+To: gcc-patches at gcc dot gnu dot org |
414 |
+Subject: [PATCH 1/4] x86: Add -mindirect-branch= |
415 |
+Date: Fri, 12 Jan 2018 05:15:46 -0800 |
416 |
+ |
417 |
+Add -mindirect-branch= option to convert indirect call and jump to call |
418 |
+and return thunks. The default is 'keep', which keeps indirect call and |
419 |
+jump unmodified. 'thunk' converts indirect call and jump to call and |
420 |
+return thunk. 'thunk-inline' converts indirect call and jump to inlined |
421 |
+call and return thunk. 'thunk-extern' converts indirect call and jump to |
422 |
+external call and return thunk provided in a separate object file. You |
423 |
+can control this behavior for a specific function by using the function |
424 |
+attribute indirect_branch. |
425 |
+ |
426 |
+2 kinds of thunks are geneated. Memory thunk where the function address |
427 |
+is at the top of the stack: |
428 |
+ |
429 |
+__x86_indirect_thunk: |
430 |
+ call L2 |
431 |
+L1: |
432 |
+ pause |
433 |
+ jmp L1 |
434 |
+L2: |
435 |
+ lea 8(%rsp), %rsp|lea 4(%esp), %esp |
436 |
+ ret |
437 |
+ |
438 |
+Indirect jmp via memory, "jmp mem", is converted to |
439 |
+ |
440 |
+ push memory |
441 |
+ jmp __x86_indirect_thunk |
442 |
+ |
443 |
+Indirect call via memory, "call mem", is converted to |
444 |
+ |
445 |
+ jmp L2 |
446 |
+L1: |
447 |
+ push [mem] |
448 |
+ jmp __x86_indirect_thunk |
449 |
+L2: |
450 |
+ call L1 |
451 |
+ |
452 |
+Register thunk where the function address is in a register, reg: |
453 |
+ |
454 |
+__x86_indirect_thunk_reg: |
455 |
+ call L2 |
456 |
+L1: |
457 |
+ pause |
458 |
+ jmp L1 |
459 |
+L2: |
460 |
+ movq %reg, (%rsp)|movl %reg, (%esp) |
461 |
+ ret |
462 |
+ |
463 |
+where reg is one of (r|e)ax, (r|e)dx, (r|e)cx, (r|e)bx, (r|e)si, (r|e)di, |
464 |
+(r|e)bp, r8, r9, r10, r11, r12, r13, r14 and r15. |
465 |
+ |
466 |
+Indirect jmp via register, "jmp reg", is converted to |
467 |
+ |
468 |
+ jmp __x86_indirect_thunk_reg |
469 |
+ |
470 |
+Indirect call via register, "call reg", is converted to |
471 |
+ |
472 |
+ call __x86_indirect_thunk_reg |
473 |
+ |
474 |
+gcc/ |
475 |
+ |
476 |
+ * config/i386/i386-opts.h (indirect_branch): New. |
477 |
+ * config/i386/i386-protos.h (ix86_output_indirect_jmp): Likewise. |
478 |
+ * config/i386/i386.c (ix86_using_red_zone): Disallow red-zone |
479 |
+ with local indirect jump when converting indirect call and jump. |
480 |
+ (ix86_set_indirect_branch_type): New. |
481 |
+ (ix86_set_current_function): Call ix86_set_indirect_branch_type. |
482 |
+ (indirectlabelno): New. |
483 |
+ (indirect_thunk_needed): Likewise. |
484 |
+ (indirect_thunk_bnd_needed): Likewise. |
485 |
+ (indirect_thunks_used): Likewise. |
486 |
+ (indirect_thunks_bnd_used): Likewise. |
487 |
+ (INDIRECT_LABEL): Likewise. |
488 |
+ (indirect_thunk_name): Likewise. |
489 |
+ (output_indirect_thunk): Likewise. |
490 |
+ (output_indirect_thunk_function): Likewise. |
491 |
+ (ix86_output_indirect_branch): Likewise. |
492 |
+ (ix86_output_indirect_jmp): Likewise. |
493 |
+ (ix86_code_end): Call output_indirect_thunk_function if needed. |
494 |
+ (ix86_output_call_insn): Call ix86_output_indirect_branch if |
495 |
+ needed. |
496 |
+ (ix86_handle_fndecl_attribute): Handle indirect_branch. |
497 |
+ (ix86_attribute_table): Add indirect_branch. |
498 |
+ * config/i386/i386.h (machine_function): Add indirect_branch_type |
499 |
+ and has_local_indirect_jump. |
500 |
+ * config/i386/i386.md (indirect_jump): Set has_local_indirect_jump |
501 |
+ to true. |
502 |
+ (tablejump): Likewise. |
503 |
+ (*indirect_jump): Use ix86_output_indirect_jmp. |
504 |
+ (*tablejump_1): Likewise. |
505 |
+ (simple_return_indirect_internal): Likewise. |
506 |
+ * config/i386/i386.opt (mindirect-branch=): New option. |
507 |
+ (indirect_branch): New. |
508 |
+ (keep): Likewise. |
509 |
+ (thunk): Likewise. |
510 |
+ (thunk-inline): Likewise. |
511 |
+ (thunk-extern): Likewise. |
512 |
+ * doc/extend.texi: Document indirect_branch function attribute. |
513 |
+ * doc/invoke.texi: Document -mindirect-branch= option. |
514 |
+ |
515 |
+gcc/testsuite/ |
516 |
+ |
517 |
+ * gcc.target/i386/indirect-thunk-1.c: New test. |
518 |
+ * gcc.target/i386/indirect-thunk-2.c: Likewise. |
519 |
+ * gcc.target/i386/indirect-thunk-3.c: Likewise. |
520 |
+ * gcc.target/i386/indirect-thunk-4.c: Likewise. |
521 |
+ * gcc.target/i386/indirect-thunk-5.c: Likewise. |
522 |
+ * gcc.target/i386/indirect-thunk-6.c: Likewise. |
523 |
+ * gcc.target/i386/indirect-thunk-7.c: Likewise. |
524 |
+ * gcc.target/i386/indirect-thunk-attr-1.c: Likewise. |
525 |
+ * gcc.target/i386/indirect-thunk-attr-2.c: Likewise. |
526 |
+ * gcc.target/i386/indirect-thunk-attr-3.c: Likewise. |
527 |
+ * gcc.target/i386/indirect-thunk-attr-4.c: Likewise. |
528 |
+ * gcc.target/i386/indirect-thunk-attr-5.c: Likewise. |
529 |
+ * gcc.target/i386/indirect-thunk-attr-6.c: Likewise. |
530 |
+ * gcc.target/i386/indirect-thunk-attr-7.c: Likewise. |
531 |
+ * gcc.target/i386/indirect-thunk-attr-8.c: Likewise. |
532 |
+ * gcc.target/i386/indirect-thunk-bnd-1.c: Likewise. |
533 |
+ * gcc.target/i386/indirect-thunk-bnd-2.c: Likewise. |
534 |
+ * gcc.target/i386/indirect-thunk-bnd-3.c: Likewise. |
535 |
+ * gcc.target/i386/indirect-thunk-bnd-4.c: Likewise. |
536 |
+ * gcc.target/i386/indirect-thunk-extern-1.c: Likewise. |
537 |
+ * gcc.target/i386/indirect-thunk-extern-2.c: Likewise. |
538 |
+ * gcc.target/i386/indirect-thunk-extern-3.c: Likewise. |
539 |
+ * gcc.target/i386/indirect-thunk-extern-4.c: Likewise. |
540 |
+ * gcc.target/i386/indirect-thunk-extern-5.c: Likewise. |
541 |
+ * gcc.target/i386/indirect-thunk-extern-6.c: Likewise. |
542 |
+ * gcc.target/i386/indirect-thunk-extern-7.c: Likewise. |
543 |
+ * gcc.target/i386/indirect-thunk-inline-1.c: Likewise. |
544 |
+ * gcc.target/i386/indirect-thunk-inline-2.c: Likewise. |
545 |
+ * gcc.target/i386/indirect-thunk-inline-3.c: Likewise. |
546 |
+ * gcc.target/i386/indirect-thunk-inline-4.c: Likewise. |
547 |
+ * gcc.target/i386/indirect-thunk-inline-5.c: Likewise. |
548 |
+ * gcc.target/i386/indirect-thunk-inline-6.c: Likewise. |
549 |
+ * gcc.target/i386/indirect-thunk-inline-7.c: Likewise. |
550 |
+--- |
551 |
+ gcc/config/i386/i386-opts.h | 8 + |
552 |
+ gcc/config/i386/i386-protos.h | 1 + |
553 |
+ gcc/config/i386/i386.c | 512 ++++++++++++++++++++- |
554 |
+ gcc/config/i386/i386.h | 7 + |
555 |
+ gcc/config/i386/i386.md | 8 +- |
556 |
+ gcc/config/i386/i386.opt | 20 + |
557 |
+ gcc/doc/extend.texi | 10 + |
558 |
+ gcc/doc/invoke.texi | 14 +- |
559 |
+ gcc/testsuite/gcc.target/i386/indirect-thunk-1.c | 19 + |
560 |
+ gcc/testsuite/gcc.target/i386/indirect-thunk-2.c | 19 + |
561 |
+ gcc/testsuite/gcc.target/i386/indirect-thunk-3.c | 20 + |
562 |
+ gcc/testsuite/gcc.target/i386/indirect-thunk-4.c | 20 + |
563 |
+ gcc/testsuite/gcc.target/i386/indirect-thunk-5.c | 16 + |
564 |
+ gcc/testsuite/gcc.target/i386/indirect-thunk-6.c | 17 + |
565 |
+ gcc/testsuite/gcc.target/i386/indirect-thunk-7.c | 43 ++ |
566 |
+ .../gcc.target/i386/indirect-thunk-attr-1.c | 22 + |
567 |
+ .../gcc.target/i386/indirect-thunk-attr-2.c | 20 + |
568 |
+ .../gcc.target/i386/indirect-thunk-attr-3.c | 21 + |
569 |
+ .../gcc.target/i386/indirect-thunk-attr-4.c | 20 + |
570 |
+ .../gcc.target/i386/indirect-thunk-attr-5.c | 22 + |
571 |
+ .../gcc.target/i386/indirect-thunk-attr-6.c | 21 + |
572 |
+ .../gcc.target/i386/indirect-thunk-attr-7.c | 44 ++ |
573 |
+ .../gcc.target/i386/indirect-thunk-attr-8.c | 41 ++ |
574 |
+ .../gcc.target/i386/indirect-thunk-bnd-1.c | 19 + |
575 |
+ .../gcc.target/i386/indirect-thunk-bnd-2.c | 20 + |
576 |
+ .../gcc.target/i386/indirect-thunk-bnd-3.c | 18 + |
577 |
+ .../gcc.target/i386/indirect-thunk-bnd-4.c | 19 + |
578 |
+ .../gcc.target/i386/indirect-thunk-extern-1.c | 19 + |
579 |
+ .../gcc.target/i386/indirect-thunk-extern-2.c | 19 + |
580 |
+ .../gcc.target/i386/indirect-thunk-extern-3.c | 20 + |
581 |
+ .../gcc.target/i386/indirect-thunk-extern-4.c | 20 + |
582 |
+ .../gcc.target/i386/indirect-thunk-extern-5.c | 16 + |
583 |
+ .../gcc.target/i386/indirect-thunk-extern-6.c | 17 + |
584 |
+ .../gcc.target/i386/indirect-thunk-extern-7.c | 43 ++ |
585 |
+ .../gcc.target/i386/indirect-thunk-inline-1.c | 18 + |
586 |
+ .../gcc.target/i386/indirect-thunk-inline-2.c | 18 + |
587 |
+ .../gcc.target/i386/indirect-thunk-inline-3.c | 19 + |
588 |
+ .../gcc.target/i386/indirect-thunk-inline-4.c | 19 + |
589 |
+ .../gcc.target/i386/indirect-thunk-inline-5.c | 15 + |
590 |
+ .../gcc.target/i386/indirect-thunk-inline-6.c | 16 + |
591 |
+ .../gcc.target/i386/indirect-thunk-inline-7.c | 42 ++ |
592 |
+ 41 files changed, 1306 insertions(+), 16 deletions(-) |
593 |
+ create mode 100644 gcc/testsuite/gcc.target/i386/indirect-thunk-1.c |
594 |
+ create mode 100644 gcc/testsuite/gcc.target/i386/indirect-thunk-2.c |
595 |
+ create mode 100644 gcc/testsuite/gcc.target/i386/indirect-thunk-3.c |
596 |
+ create mode 100644 gcc/testsuite/gcc.target/i386/indirect-thunk-4.c |
597 |
+ create mode 100644 gcc/testsuite/gcc.target/i386/indirect-thunk-5.c |
598 |
+ create mode 100644 gcc/testsuite/gcc.target/i386/indirect-thunk-6.c |
599 |
+ create mode 100644 gcc/testsuite/gcc.target/i386/indirect-thunk-7.c |
600 |
+ create mode 100644 gcc/testsuite/gcc.target/i386/indirect-thunk-attr-1.c |
601 |
+ create mode 100644 gcc/testsuite/gcc.target/i386/indirect-thunk-attr-2.c |
602 |
+ create mode 100644 gcc/testsuite/gcc.target/i386/indirect-thunk-attr-3.c |
603 |
+ create mode 100644 gcc/testsuite/gcc.target/i386/indirect-thunk-attr-4.c |
604 |
+ create mode 100644 gcc/testsuite/gcc.target/i386/indirect-thunk-attr-5.c |
605 |
+ create mode 100644 gcc/testsuite/gcc.target/i386/indirect-thunk-attr-6.c |
606 |
+ create mode 100644 gcc/testsuite/gcc.target/i386/indirect-thunk-attr-7.c |
607 |
+ create mode 100644 gcc/testsuite/gcc.target/i386/indirect-thunk-attr-8.c |
608 |
+ create mode 100644 gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-1.c |
609 |
+ create mode 100644 gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-2.c |
610 |
+ create mode 100644 gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-3.c |
611 |
+ create mode 100644 gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-4.c |
612 |
+ create mode 100644 gcc/testsuite/gcc.target/i386/indirect-thunk-extern-1.c |
613 |
+ create mode 100644 gcc/testsuite/gcc.target/i386/indirect-thunk-extern-2.c |
614 |
+ create mode 100644 gcc/testsuite/gcc.target/i386/indirect-thunk-extern-3.c |
615 |
+ create mode 100644 gcc/testsuite/gcc.target/i386/indirect-thunk-extern-4.c |
616 |
+ create mode 100644 gcc/testsuite/gcc.target/i386/indirect-thunk-extern-5.c |
617 |
+ create mode 100644 gcc/testsuite/gcc.target/i386/indirect-thunk-extern-6.c |
618 |
+ create mode 100644 gcc/testsuite/gcc.target/i386/indirect-thunk-extern-7.c |
619 |
+ create mode 100644 gcc/testsuite/gcc.target/i386/indirect-thunk-inline-1.c |
620 |
+ create mode 100644 gcc/testsuite/gcc.target/i386/indirect-thunk-inline-2.c |
621 |
+ create mode 100644 gcc/testsuite/gcc.target/i386/indirect-thunk-inline-3.c |
622 |
+ create mode 100644 gcc/testsuite/gcc.target/i386/indirect-thunk-inline-4.c |
623 |
+ create mode 100644 gcc/testsuite/gcc.target/i386/indirect-thunk-inline-5.c |
624 |
+ create mode 100644 gcc/testsuite/gcc.target/i386/indirect-thunk-inline-6.c |
625 |
+ create mode 100644 gcc/testsuite/gcc.target/i386/indirect-thunk-inline-7.c |
626 |
+ |
627 |
+diff -Naur gcc-7.2.0.orig/gcc/config/i386/i386-opts.h gcc-7.2.0/gcc/config/i386/i386-opts.h |
628 |
+--- gcc-7.2.0.orig/gcc/config/i386/i386-opts.h 2018-01-15 17:52:48.888745684 -0800 |
629 |
++++ gcc-7.2.0/gcc/config/i386/i386-opts.h 2018-01-15 17:54:02.363744368 -0800 |
630 |
+@@ -99,4 +99,17 @@ |
631 |
+ SSP_GLOBAL /* global canary */ |
632 |
+ }; |
633 |
+ |
634 |
++/* This is used to mitigate variant #2 of the speculative execution |
635 |
++ vulnerabilities on x86 processors identified by CVE-2017-5715, aka |
636 |
++ Spectre. They convert indirect branches and function returns to |
637 |
++ call and return thunks to avoid speculative execution via indirect |
638 |
++ call, jmp and ret. */ |
639 |
++enum indirect_branch { |
640 |
++ indirect_branch_unset = 0, |
641 |
++ indirect_branch_keep, |
642 |
++ indirect_branch_thunk, |
643 |
++ indirect_branch_thunk_inline, |
644 |
++ indirect_branch_thunk_extern |
645 |
++}; |
646 |
++ |
647 |
+ #endif |
648 |
+diff -Naur gcc-7.2.0.orig/gcc/config/i386/i386-protos.h gcc-7.2.0/gcc/config/i386/i386-protos.h |
649 |
+--- gcc-7.2.0.orig/gcc/config/i386/i386-protos.h 2018-01-15 17:52:48.894745684 -0800 |
650 |
++++ gcc-7.2.0/gcc/config/i386/i386-protos.h 2018-01-15 17:54:28.538743900 -0800 |
651 |
+@@ -315,6 +315,7 @@ |
652 |
+ #endif |
653 |
+ |
654 |
+ extern const char * ix86_output_call_insn (rtx_insn *insn, rtx call_op); |
655 |
++extern const char * ix86_output_indirect_jmp (rtx call_op, bool ret_p); |
656 |
+ extern bool ix86_operands_ok_for_move_multiple (rtx *operands, bool load, |
657 |
+ enum machine_mode mode); |
658 |
+ |
659 |
+diff -Naur gcc-7.2.0.orig/gcc/config/i386/i386.c gcc-7.2.0/gcc/config/i386/i386.c |
660 |
+--- gcc-7.2.0.orig/gcc/config/i386/i386.c 2018-01-15 17:52:48.896745684 -0800 |
661 |
++++ gcc-7.2.0/gcc/config/i386/i386.c 2018-01-15 18:13:56.240722988 -0800 |
662 |
+@@ -4209,12 +4209,23 @@ |
663 |
+ return new pass_stv (ctxt); |
664 |
+ } |
665 |
+ |
666 |
+-/* Return true if a red-zone is in use. */ |
667 |
++/* Return true if a red-zone is in use. We can't use red-zone when |
668 |
++ there are local indirect jumps, like "indirect_jump" or "tablejump", |
669 |
++ which jumps to another place in the function, since "call" in the |
670 |
++ indirect thunk pushes the return address onto stack, destroying |
671 |
++ red-zone. |
672 |
++ |
673 |
++ TODO: If we can reserve the first 2 WORDs, for PUSH and, another |
674 |
++ for CALL, in red-zone, we can allow local indirect jumps with |
675 |
++ indirect thunk. */ |
676 |
+ |
677 |
+ bool |
678 |
+ ix86_using_red_zone (void) |
679 |
+ { |
680 |
+- return TARGET_RED_ZONE && !TARGET_64BIT_MS_ABI; |
681 |
++ return (TARGET_RED_ZONE |
682 |
++ && !TARGET_64BIT_MS_ABI |
683 |
++ && (!cfun->machine->has_local_indirect_jump |
684 |
++ || cfun->machine->indirect_branch_type == indirect_branch_keep)); |
685 |
+ } |
686 |
+ |
687 |
+ /* Return a string that documents the current -m options. The caller is |
688 |
+@@ -7137,6 +7144,37 @@ |
689 |
+ } |
690 |
+ } |
691 |
+ |
692 |
++/* Set the indirect_branch_type field from the function FNDECL. */ |
693 |
++ |
694 |
++static void |
695 |
++ix86_set_indirect_branch_type (tree fndecl) |
696 |
++{ |
697 |
++ if (cfun->machine->indirect_branch_type == indirect_branch_unset) |
698 |
++ { |
699 |
++ tree attr = lookup_attribute ("indirect_branch", |
700 |
++ DECL_ATTRIBUTES (fndecl)); |
701 |
++ if (attr != NULL) |
702 |
++ { |
703 |
++ tree args = TREE_VALUE (attr); |
704 |
++ if (args == NULL) |
705 |
++ gcc_unreachable (); |
706 |
++ tree cst = TREE_VALUE (args); |
707 |
++ if (strcmp (TREE_STRING_POINTER (cst), "keep") == 0) |
708 |
++ cfun->machine->indirect_branch_type = indirect_branch_keep; |
709 |
++ else if (strcmp (TREE_STRING_POINTER (cst), "thunk") == 0) |
710 |
++ cfun->machine->indirect_branch_type = indirect_branch_thunk; |
711 |
++ else if (strcmp (TREE_STRING_POINTER (cst), "thunk-inline") == 0) |
712 |
++ cfun->machine->indirect_branch_type = indirect_branch_thunk_inline; |
713 |
++ else if (strcmp (TREE_STRING_POINTER (cst), "thunk-extern") == 0) |
714 |
++ cfun->machine->indirect_branch_type = indirect_branch_thunk_extern; |
715 |
++ else |
716 |
++ gcc_unreachable (); |
717 |
++ } |
718 |
++ else |
719 |
++ cfun->machine->indirect_branch_type = ix86_indirect_branch; |
720 |
++ } |
721 |
++} |
722 |
++ |
723 |
+ /* Establish appropriate back-end context for processing the function |
724 |
+ FNDECL. The argument might be NULL to indicate processing at top |
725 |
+ level, outside of any function scope. */ |
726 |
+@@ -7152,7 +7190,10 @@ |
727 |
+ one is extern inline and one isn't. Call ix86_set_func_type |
728 |
+ to set the func_type field. */ |
729 |
+ if (fndecl != NULL_TREE) |
730 |
+- ix86_set_func_type (fndecl); |
731 |
++ { |
732 |
++ ix86_set_func_type (fndecl); |
733 |
++ ix86_set_indirect_branch_type (fndecl); |
734 |
++ } |
735 |
+ return; |
736 |
+ } |
737 |
+ |
738 |
+@@ -7172,6 +7213,7 @@ |
739 |
+ } |
740 |
+ |
741 |
+ ix86_set_func_type (fndecl); |
742 |
++ ix86_set_indirect_branch_type (fndecl); |
743 |
+ |
744 |
+ tree new_tree = DECL_FUNCTION_SPECIFIC_TARGET (fndecl); |
745 |
+ if (new_tree == NULL_TREE) |
746 |
+@@ -11909,6 +11951,220 @@ |
747 |
+ # endif |
748 |
+ #endif |
749 |
+ |
750 |
++/* Label count for call and return thunks. It is used to make unique |
751 |
++ labels in call and return thunks. */ |
752 |
++static int indirectlabelno; |
753 |
++ |
754 |
++/* True if call and return thunk functions are needed. */ |
755 |
++static bool indirect_thunk_needed = false; |
756 |
++/* True if call and return thunk functions with the BND prefix are |
757 |
++ needed. */ |
758 |
++static bool indirect_thunk_bnd_needed = false; |
759 |
++ |
760 |
++/* Bit masks of integer registers, which contain branch target, used |
761 |
++ by call and return thunks functions. */ |
762 |
++static int indirect_thunks_used; |
763 |
++/* Bit masks of integer registers, which contain branch target, used |
764 |
++ by call and return thunks functions with the BND prefix. */ |
765 |
++static int indirect_thunks_bnd_used; |
766 |
++ |
767 |
++#ifndef INDIRECT_LABEL |
768 |
++# define INDIRECT_LABEL "LIND" |
769 |
++#endif |
770 |
++ |
771 |
++/* Fills in the label name that should be used for the indirect thunk. */ |
772 |
++ |
773 |
++static void |
774 |
++indirect_thunk_name (char name[32], int regno, bool need_bnd_p) |
775 |
++{ |
776 |
++ if (USE_HIDDEN_LINKONCE) |
777 |
++ { |
778 |
++ const char *bnd = need_bnd_p ? "_bnd" : ""; |
779 |
++ if (regno >= 0) |
780 |
++ { |
781 |
++ const char *reg_prefix; |
782 |
++ if (LEGACY_INT_REGNO_P (regno)) |
783 |
++ reg_prefix = TARGET_64BIT ? "r" : "e"; |
784 |
++ else |
785 |
++ reg_prefix = ""; |
786 |
++ sprintf (name, "__x86_indirect_thunk%s_%s%s", |
787 |
++ bnd, reg_prefix, reg_names[regno]); |
788 |
++ } |
789 |
++ else |
790 |
++ sprintf (name, "__x86_indirect_thunk%s", bnd); |
791 |
++ } |
792 |
++ else |
793 |
++ { |
794 |
++ if (regno >= 0) |
795 |
++ { |
796 |
++ if (need_bnd_p) |
797 |
++ ASM_GENERATE_INTERNAL_LABEL (name, "LITBR", regno); |
798 |
++ else |
799 |
++ ASM_GENERATE_INTERNAL_LABEL (name, "LITR", regno); |
800 |
++ } |
801 |
++ else |
802 |
++ { |
803 |
++ if (need_bnd_p) |
804 |
++ ASM_GENERATE_INTERNAL_LABEL (name, "LITB", 0); |
805 |
++ else |
806 |
++ ASM_GENERATE_INTERNAL_LABEL (name, "LIT", 0); |
807 |
++ } |
808 |
++ } |
809 |
++} |
810 |
++ |
811 |
++/* Output a call and return thunk for indirect branch. If BND_P is |
812 |
++ true, the BND prefix is needed. If REGNO != -1, the function |
813 |
++ address is in REGNO and the call and return thunk looks like: |
814 |
++ |
815 |
++ call L2 |
816 |
++ L1: |
817 |
++ pause |
818 |
++ jmp L1 |
819 |
++ L2: |
820 |
++ mov %REG, (%sp) |
821 |
++ ret |
822 |
++ |
823 |
++ Otherwise, the function address is on the top of stack and the |
824 |
++ call and return thunk looks like: |
825 |
++ |
826 |
++ call L2 |
827 |
++ L1: |
828 |
++ pause |
829 |
++ jmp L1 |
830 |
++ L2: |
831 |
++ lea WORD_SIZE(%sp), %sp |
832 |
++ ret |
833 |
++ */ |
834 |
++ |
835 |
++static void |
836 |
++output_indirect_thunk (bool need_bnd_p, int regno) |
837 |
++{ |
838 |
++ char indirectlabel1[32]; |
839 |
++ char indirectlabel2[32]; |
840 |
++ |
841 |
++ ASM_GENERATE_INTERNAL_LABEL (indirectlabel1, INDIRECT_LABEL, |
842 |
++ indirectlabelno++); |
843 |
++ ASM_GENERATE_INTERNAL_LABEL (indirectlabel2, INDIRECT_LABEL, |
844 |
++ indirectlabelno++); |
845 |
++ |
846 |
++ /* Call */ |
847 |
++ if (need_bnd_p) |
848 |
++ fputs ("\tbnd call\t", asm_out_file); |
849 |
++ else |
850 |
++ fputs ("\tcall\t", asm_out_file); |
851 |
++ assemble_name_raw (asm_out_file, indirectlabel2); |
852 |
++ fputc ('\n', asm_out_file); |
853 |
++ |
854 |
++ ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, indirectlabel1); |
855 |
++ |
856 |
++ /* Pause . */ |
857 |
++ fprintf (asm_out_file, "\tpause\n"); |
858 |
++ |
859 |
++ /* Jump. */ |
860 |
++ fputs ("\tjmp\t", asm_out_file); |
861 |
++ assemble_name_raw (asm_out_file, indirectlabel1); |
862 |
++ fputc ('\n', asm_out_file); |
863 |
++ |
864 |
++ ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, indirectlabel2); |
865 |
++ |
866 |
++ if (regno >= 0) |
867 |
++ { |
868 |
++ /* MOV. */ |
869 |
++ rtx xops[2]; |
870 |
++ xops[0] = gen_rtx_MEM (word_mode, stack_pointer_rtx); |
871 |
++ xops[1] = gen_rtx_REG (word_mode, regno); |
872 |
++ output_asm_insn ("mov\t{%1, %0|%0, %1}", xops); |
873 |
++ } |
874 |
++ else |
875 |
++ { |
876 |
++ /* LEA. */ |
877 |
++ rtx xops[2]; |
878 |
++ xops[0] = stack_pointer_rtx; |
879 |
++ xops[1] = plus_constant (Pmode, stack_pointer_rtx, UNITS_PER_WORD); |
880 |
++ output_asm_insn ("lea\t{%E1, %0|%0, %E1}", xops); |
881 |
++ } |
882 |
++ |
883 |
++ if (need_bnd_p) |
884 |
++ fputs ("\tbnd ret\n", asm_out_file); |
885 |
++ else |
886 |
++ fputs ("\tret\n", asm_out_file); |
887 |
++} |
888 |
++ |
889 |
++/* Output a funtion with a call and return thunk for indirect branch. |
890 |
++ If BND_P is true, the BND prefix is needed. If REGNO != -1, the |
891 |
++ function address is in REGNO. Otherwise, the function address is |
892 |
++ on the top of stack. */ |
893 |
++ |
894 |
++static void |
895 |
++output_indirect_thunk_function (bool need_bnd_p, int regno) |
896 |
++{ |
897 |
++ char name[32]; |
898 |
++ tree decl; |
899 |
++ |
900 |
++ /* Create __x86_indirect_thunk/__x86_indirect_thunk_bnd. */ |
901 |
++ indirect_thunk_name (name, regno, need_bnd_p); |
902 |
++ decl = build_decl (BUILTINS_LOCATION, FUNCTION_DECL, |
903 |
++ get_identifier (name), |
904 |
++ build_function_type_list (void_type_node, NULL_TREE)); |
905 |
++ DECL_RESULT (decl) = build_decl (BUILTINS_LOCATION, RESULT_DECL, |
906 |
++ NULL_TREE, void_type_node); |
907 |
++ TREE_PUBLIC (decl) = 1; |
908 |
++ TREE_STATIC (decl) = 1; |
909 |
++ DECL_IGNORED_P (decl) = 1; |
910 |
++ |
911 |
++#if TARGET_MACHO |
912 |
++ if (TARGET_MACHO) |
913 |
++ { |
914 |
++ switch_to_section (darwin_sections[picbase_thunk_section]); |
915 |
++ fputs ("\t.weak_definition\t", asm_out_file); |
916 |
++ assemble_name (asm_out_file, name); |
917 |
++ fputs ("\n\t.private_extern\t", asm_out_file); |
918 |
++ assemble_name (asm_out_file, name); |
919 |
++ putc ('\n', asm_out_file); |
920 |
++ ASM_OUTPUT_LABEL (asm_out_file, name); |
921 |
++ DECL_WEAK (decl) = 1; |
922 |
++ } |
923 |
++ else |
924 |
++#endif |
925 |
++ if (USE_HIDDEN_LINKONCE) |
926 |
++ { |
927 |
++ cgraph_node::create (decl)->set_comdat_group (DECL_ASSEMBLER_NAME (decl)); |
928 |
++ |
929 |
++ targetm.asm_out.unique_section (decl, 0); |
930 |
++ switch_to_section (get_named_section (decl, NULL, 0)); |
931 |
++ |
932 |
++ targetm.asm_out.globalize_label (asm_out_file, name); |
933 |
++ fputs ("\t.hidden\t", asm_out_file); |
934 |
++ assemble_name (asm_out_file, name); |
935 |
++ putc ('\n', asm_out_file); |
936 |
++ ASM_DECLARE_FUNCTION_NAME (asm_out_file, name, decl); |
937 |
++ } |
938 |
++ else |
939 |
++ { |
940 |
++ switch_to_section (text_section); |
941 |
++ ASM_OUTPUT_LABEL (asm_out_file, name); |
942 |
++ } |
943 |
++ |
944 |
++ DECL_INITIAL (decl) = make_node (BLOCK); |
945 |
++ current_function_decl = decl; |
946 |
++ allocate_struct_function (decl, false); |
947 |
++ init_function_start (decl); |
948 |
++ /* We're about to hide the function body from callees of final_* by |
949 |
++ emitting it directly; tell them we're a thunk, if they care. */ |
950 |
++ cfun->is_thunk = true; |
951 |
++ first_function_block_is_cold = false; |
952 |
++ /* Make sure unwind info is emitted for the thunk if needed. */ |
953 |
++ final_start_function (emit_barrier (), asm_out_file, 1); |
954 |
++ |
955 |
++ output_indirect_thunk (need_bnd_p, regno); |
956 |
++ |
957 |
++ final_end_function (); |
958 |
++ init_insn_lengths (); |
959 |
++ free_after_compilation (cfun); |
960 |
++ set_cfun (NULL); |
961 |
++ current_function_decl = NULL; |
962 |
++} |
963 |
++ |
964 |
+ static int pic_labels_used; |
965 |
+ |
966 |
+ /* Fills in the label name that should be used for a pc thunk for |
967 |
+@@ -11935,11 +12162,32 @@ |
968 |
+ rtx xops[2]; |
969 |
+ int regno; |
970 |
+ |
971 |
++ if (indirect_thunk_needed) |
972 |
++ output_indirect_thunk_function (false, -1); |
973 |
++ if (indirect_thunk_bnd_needed) |
974 |
++ output_indirect_thunk_function (true, -1); |
975 |
++ |
976 |
++ for (regno = FIRST_REX_INT_REG; regno <= LAST_REX_INT_REG; regno++) |
977 |
++ { |
978 |
++ int i = regno - FIRST_REX_INT_REG + SP_REG + 1; |
979 |
++ if ((indirect_thunks_used & (1 << i))) |
980 |
++ output_indirect_thunk_function (false, regno); |
981 |
++ |
982 |
++ if ((indirect_thunks_bnd_used & (1 << i))) |
983 |
++ output_indirect_thunk_function (true, regno); |
984 |
++ } |
985 |
++ |
986 |
+ for (regno = AX_REG; regno <= SP_REG; regno++) |
987 |
+ { |
988 |
+ char name[32]; |
989 |
+ tree decl; |
990 |
+ |
991 |
++ if ((indirect_thunks_used & (1 << regno))) |
992 |
++ output_indirect_thunk_function (false, regno); |
993 |
++ |
994 |
++ if ((indirect_thunks_bnd_used & (1 << regno))) |
995 |
++ output_indirect_thunk_function (true, regno); |
996 |
++ |
997 |
+ if (!(pic_labels_used & (1 << regno))) |
998 |
+ continue; |
999 |
+ |
1000 |
+@@ -28452,12 +28700,292 @@ |
1001 |
+ return false; |
1002 |
+ } |
1003 |
+ |
1004 |
++/* Output indirect branch via a call and return thunk. CALL_OP is a |
1005 |
++ register which contains the branch target. XASM is the assembly |
1006 |
++ template for CALL_OP. Branch is a tail call if SIBCALL_P is true. |
1007 |
++ A normal call is converted to: |
1008 |
++ |
1009 |
++ call __x86_indirect_thunk_reg |
1010 |
++ |
1011 |
++ and a tail call is converted to: |
1012 |
++ |
1013 |
++ jmp __x86_indirect_thunk_reg |
1014 |
++ */ |
1015 |
++ |
1016 |
++static void |
1017 |
++ix86_output_indirect_branch_via_reg (rtx call_op, bool sibcall_p) |
1018 |
++{ |
1019 |
++ char thunk_name_buf[32]; |
1020 |
++ char *thunk_name; |
1021 |
++ bool need_bnd_p = ix86_bnd_prefixed_insn_p (current_output_insn); |
1022 |
++ int regno = REGNO (call_op); |
1023 |
++ |
1024 |
++ if (cfun->machine->indirect_branch_type |
1025 |
++ != indirect_branch_thunk_inline) |
1026 |
++ { |
1027 |
++ if (cfun->machine->indirect_branch_type == indirect_branch_thunk) |
1028 |
++ { |
1029 |
++ int i = regno; |
1030 |
++ if (i >= FIRST_REX_INT_REG) |
1031 |
++ i -= (FIRST_REX_INT_REG - SP_REG - 1); |
1032 |
++ if (need_bnd_p) |
1033 |
++ indirect_thunks_bnd_used |= 1 << i; |
1034 |
++ else |
1035 |
++ indirect_thunks_used |= 1 << i; |
1036 |
++ } |
1037 |
++ indirect_thunk_name (thunk_name_buf, regno, need_bnd_p); |
1038 |
++ thunk_name = thunk_name_buf; |
1039 |
++ } |
1040 |
++ else |
1041 |
++ thunk_name = NULL; |
1042 |
++ |
1043 |
++ if (sibcall_p) |
1044 |
++ { |
1045 |
++ if (thunk_name != NULL) |
1046 |
++ { |
1047 |
++ if (need_bnd_p) |
1048 |
++ fprintf (asm_out_file, "\tbnd jmp\t%s\n", thunk_name); |
1049 |
++ else |
1050 |
++ fprintf (asm_out_file, "\tjmp\t%s\n", thunk_name); |
1051 |
++ } |
1052 |
++ else |
1053 |
++ output_indirect_thunk (need_bnd_p, regno); |
1054 |
++ } |
1055 |
++ else |
1056 |
++ { |
1057 |
++ if (thunk_name != NULL) |
1058 |
++ { |
1059 |
++ if (need_bnd_p) |
1060 |
++ fprintf (asm_out_file, "\tbnd call\t%s\n", thunk_name); |
1061 |
++ else |
1062 |
++ fprintf (asm_out_file, "\tcall\t%s\n", thunk_name); |
1063 |
++ return; |
1064 |
++ } |
1065 |
++ |
1066 |
++ char indirectlabel1[32]; |
1067 |
++ char indirectlabel2[32]; |
1068 |
++ |
1069 |
++ ASM_GENERATE_INTERNAL_LABEL (indirectlabel1, |
1070 |
++ INDIRECT_LABEL, |
1071 |
++ indirectlabelno++); |
1072 |
++ ASM_GENERATE_INTERNAL_LABEL (indirectlabel2, |
1073 |
++ INDIRECT_LABEL, |
1074 |
++ indirectlabelno++); |
1075 |
++ |
1076 |
++ /* Jump. */ |
1077 |
++ if (need_bnd_p) |
1078 |
++ fputs ("\tbnd jmp\t", asm_out_file); |
1079 |
++ else |
1080 |
++ fputs ("\tjmp\t", asm_out_file); |
1081 |
++ assemble_name_raw (asm_out_file, indirectlabel2); |
1082 |
++ fputc ('\n', asm_out_file); |
1083 |
++ |
1084 |
++ ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, indirectlabel1); |
1085 |
++ |
1086 |
++ if (thunk_name != NULL) |
1087 |
++ { |
1088 |
++ if (need_bnd_p) |
1089 |
++ fprintf (asm_out_file, "\tbnd jmp\t%s\n", thunk_name); |
1090 |
++ else |
1091 |
++ fprintf (asm_out_file, "\tjmp\t%s\n", thunk_name); |
1092 |
++ } |
1093 |
++ else |
1094 |
++ output_indirect_thunk (need_bnd_p, regno); |
1095 |
++ |
1096 |
++ ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, indirectlabel2); |
1097 |
++ |
1098 |
++ /* Call. */ |
1099 |
++ if (need_bnd_p) |
1100 |
++ fputs ("\tbnd call\t", asm_out_file); |
1101 |
++ else |
1102 |
++ fputs ("\tcall\t", asm_out_file); |
1103 |
++ assemble_name_raw (asm_out_file, indirectlabel1); |
1104 |
++ fputc ('\n', asm_out_file); |
1105 |
++ } |
1106 |
++} |
1107 |
++ |
1108 |
++/* Output indirect branch via a call and return thunk. CALL_OP is |
1109 |
++ the branch target. XASM is the assembly template for CALL_OP. |
1110 |
++ Branch is a tail call if SIBCALL_P is true. A normal call is |
1111 |
++ converted to: |
1112 |
++ |
1113 |
++ jmp L2 |
1114 |
++ L1: |
1115 |
++ push CALL_OP |
1116 |
++ jmp __x86_indirect_thunk |
1117 |
++ L2: |
1118 |
++ call L1 |
1119 |
++ |
1120 |
++ and a tail call is converted to: |
1121 |
++ |
1122 |
++ push CALL_OP |
1123 |
++ jmp __x86_indirect_thunk |
1124 |
++ */ |
1125 |
++ |
1126 |
++static void |
1127 |
++ix86_output_indirect_branch_via_push (rtx call_op, const char *xasm, |
1128 |
++ bool sibcall_p) |
1129 |
++{ |
1130 |
++ char thunk_name_buf[32]; |
1131 |
++ char *thunk_name; |
1132 |
++ char push_buf[64]; |
1133 |
++ bool need_bnd_p = ix86_bnd_prefixed_insn_p (current_output_insn); |
1134 |
++ int regno = -1; |
1135 |
++ |
1136 |
++ if (cfun->machine->indirect_branch_type |
1137 |
++ != indirect_branch_thunk_inline) |
1138 |
++ { |
1139 |
++ if (cfun->machine->indirect_branch_type == indirect_branch_thunk) |
1140 |
++ { |
1141 |
++ if (need_bnd_p) |
1142 |
++ indirect_thunk_bnd_needed = true; |
1143 |
++ else |
1144 |
++ indirect_thunk_needed = true; |
1145 |
++ } |
1146 |
++ indirect_thunk_name (thunk_name_buf, regno, need_bnd_p); |
1147 |
++ thunk_name = thunk_name_buf; |
1148 |
++ } |
1149 |
++ else |
1150 |
++ thunk_name = NULL; |
1151 |
++ |
1152 |
++ snprintf (push_buf, sizeof (push_buf), "push{%c}\t%s", |
1153 |
++ TARGET_64BIT ? 'q' : 'l', xasm); |
1154 |
++ |
1155 |
++ if (sibcall_p) |
1156 |
++ { |
1157 |
++ output_asm_insn (push_buf, &call_op); |
1158 |
++ if (thunk_name != NULL) |
1159 |
++ { |
1160 |
++ if (need_bnd_p) |
1161 |
++ fprintf (asm_out_file, "\tbnd jmp\t%s\n", thunk_name); |
1162 |
++ else |
1163 |
++ fprintf (asm_out_file, "\tjmp\t%s\n", thunk_name); |
1164 |
++ } |
1165 |
++ else |
1166 |
++ output_indirect_thunk (need_bnd_p, regno); |
1167 |
++ } |
1168 |
++ else |
1169 |
++ { |
1170 |
++ char indirectlabel1[32]; |
1171 |
++ char indirectlabel2[32]; |
1172 |
++ |
1173 |
++ ASM_GENERATE_INTERNAL_LABEL (indirectlabel1, |
1174 |
++ INDIRECT_LABEL, |
1175 |
++ indirectlabelno++); |
1176 |
++ ASM_GENERATE_INTERNAL_LABEL (indirectlabel2, |
1177 |
++ INDIRECT_LABEL, |
1178 |
++ indirectlabelno++); |
1179 |
++ |
1180 |
++ /* Jump. */ |
1181 |
++ if (need_bnd_p) |
1182 |
++ fputs ("\tbnd jmp\t", asm_out_file); |
1183 |
++ else |
1184 |
++ fputs ("\tjmp\t", asm_out_file); |
1185 |
++ assemble_name_raw (asm_out_file, indirectlabel2); |
1186 |
++ fputc ('\n', asm_out_file); |
1187 |
++ |
1188 |
++ ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, indirectlabel1); |
1189 |
++ |
1190 |
++ /* An external function may be called via GOT, instead of PLT. */ |
1191 |
++ if (MEM_P (call_op)) |
1192 |
++ { |
1193 |
++ struct ix86_address parts; |
1194 |
++ rtx addr = XEXP (call_op, 0); |
1195 |
++ if (ix86_decompose_address (addr, &parts) |
1196 |
++ && parts.base == stack_pointer_rtx) |
1197 |
++ { |
1198 |
++ /* Since call will adjust stack by -UNITS_PER_WORD, |
1199 |
++ we must convert "disp(stack, index, scale)" to |
1200 |
++ "disp+UNITS_PER_WORD(stack, index, scale)". */ |
1201 |
++ if (parts.index) |
1202 |
++ { |
1203 |
++ addr = gen_rtx_MULT (Pmode, parts.index, |
1204 |
++ GEN_INT (parts.scale)); |
1205 |
++ addr = gen_rtx_PLUS (Pmode, stack_pointer_rtx, |
1206 |
++ addr); |
1207 |
++ } |
1208 |
++ else |
1209 |
++ addr = stack_pointer_rtx; |
1210 |
++ |
1211 |
++ rtx disp; |
1212 |
++ if (parts.disp != NULL_RTX) |
1213 |
++ disp = plus_constant (Pmode, parts.disp, |
1214 |
++ UNITS_PER_WORD); |
1215 |
++ else |
1216 |
++ disp = GEN_INT (UNITS_PER_WORD); |
1217 |
++ |
1218 |
++ addr = gen_rtx_PLUS (Pmode, addr, disp); |
1219 |
++ call_op = gen_rtx_MEM (GET_MODE (call_op), addr); |
1220 |
++ } |
1221 |
++ } |
1222 |
++ |
1223 |
++ output_asm_insn (push_buf, &call_op); |
1224 |
++ |
1225 |
++ if (thunk_name != NULL) |
1226 |
++ { |
1227 |
++ if (need_bnd_p) |
1228 |
++ fprintf (asm_out_file, "\tbnd jmp\t%s\n", thunk_name); |
1229 |
++ else |
1230 |
++ fprintf (asm_out_file, "\tjmp\t%s\n", thunk_name); |
1231 |
++ } |
1232 |
++ else |
1233 |
++ output_indirect_thunk (need_bnd_p, regno); |
1234 |
++ |
1235 |
++ ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, indirectlabel2); |
1236 |
++ |
1237 |
++ /* Call. */ |
1238 |
++ if (need_bnd_p) |
1239 |
++ fputs ("\tbnd call\t", asm_out_file); |
1240 |
++ else |
1241 |
++ fputs ("\tcall\t", asm_out_file); |
1242 |
++ assemble_name_raw (asm_out_file, indirectlabel1); |
1243 |
++ fputc ('\n', asm_out_file); |
1244 |
++ } |
1245 |
++} |
1246 |
++ |
1247 |
++/* Output indirect branch via a call and return thunk. CALL_OP is |
1248 |
++ the branch target. XASM is the assembly template for CALL_OP. |
1249 |
++ Branch is a tail call if SIBCALL_P is true. */ |
1250 |
++ |
1251 |
++static void |
1252 |
++ix86_output_indirect_branch (rtx call_op, const char *xasm, |
1253 |
++ bool sibcall_p) |
1254 |
++{ |
1255 |
++ if (REG_P (call_op)) |
1256 |
++ ix86_output_indirect_branch_via_reg (call_op, sibcall_p); |
1257 |
++ else |
1258 |
++ ix86_output_indirect_branch_via_push (call_op, xasm, sibcall_p); |
1259 |
++} |
1260 |
++/* Output indirect jump. CALL_OP is the jump target. Jump is a |
1261 |
++ function return if RET_P is true. */ |
1262 |
++ |
1263 |
++const char * |
1264 |
++ix86_output_indirect_jmp (rtx call_op, bool ret_p) |
1265 |
++{ |
1266 |
++ if (cfun->machine->indirect_branch_type != indirect_branch_keep) |
1267 |
++ { |
1268 |
++ /* We can't have red-zone if this isn't a function return since |
1269 |
++ "call" in the indirect thunk pushes the return address onto |
1270 |
++ stack, destroying red-zone. */ |
1271 |
++ if (!ret_p && ix86_red_zone_size != 0) |
1272 |
++ gcc_unreachable (); |
1273 |
++ |
1274 |
++ ix86_output_indirect_branch (call_op, "%0", true); |
1275 |
++ return ""; |
1276 |
++ } |
1277 |
++ else |
1278 |
++ return "%!jmp\t%A0"; |
1279 |
++} |
1280 |
++ |
1281 |
+ /* Output the assembly for a call instruction. */ |
1282 |
+ |
1283 |
+ const char * |
1284 |
+ ix86_output_call_insn (rtx_insn *insn, rtx call_op) |
1285 |
+ { |
1286 |
+ bool direct_p = constant_call_address_operand (call_op, VOIDmode); |
1287 |
++ bool output_indirect_p |
1288 |
++ = (!TARGET_SEH |
1289 |
++ && cfun->machine->indirect_branch_type != indirect_branch_keep); |
1290 |
+ bool seh_nop_p = false; |
1291 |
+ const char *xasm; |
1292 |
+ |
1293 |
+@@ -28467,10 +28892,21 @@ |
1294 |
+ { |
1295 |
+ if (ix86_nopic_noplt_attribute_p (call_op)) |
1296 |
+ { |
1297 |
++ direct_p = false; |
1298 |
+ if (TARGET_64BIT) |
1299 |
+- xasm = "%!jmp\t{*%p0@GOTPCREL(%%rip)|[QWORD PTR %p0@GOTPCREL[rip]]}"; |
1300 |
++ { |
1301 |
++ if (output_indirect_p) |
1302 |
++ xasm = "{%p0@GOTPCREL(%%rip)|[QWORD PTR %p0@GOTPCREL[rip]]}"; |
1303 |
++ else |
1304 |
++ xasm = "%!jmp\t{*%p0@GOTPCREL(%%rip)|[QWORD PTR %p0@GOTPCREL[rip]]}"; |
1305 |
++ } |
1306 |
+ else |
1307 |
+- xasm = "%!jmp\t{*%p0@GOT|[DWORD PTR %p0@GOT]}"; |
1308 |
++ { |
1309 |
++ if (output_indirect_p) |
1310 |
++ xasm = "{%p0@GOT|[DWORD PTR %p0@GOT]}"; |
1311 |
++ else |
1312 |
++ xasm = "%!jmp\t{*%p0@GOT|[DWORD PTR %p0@GOT]}"; |
1313 |
++ } |
1314 |
+ } |
1315 |
+ else |
1316 |
+ xasm = "%!jmp\t%P0"; |
1317 |
+@@ -28480,9 +28916,17 @@ |
1318 |
+ else if (TARGET_SEH) |
1319 |
+ xasm = "%!rex.W jmp\t%A0"; |
1320 |
+ else |
1321 |
+- xasm = "%!jmp\t%A0"; |
1322 |
++ { |
1323 |
++ if (output_indirect_p) |
1324 |
++ xasm = "%0"; |
1325 |
++ else |
1326 |
++ xasm = "%!jmp\t%A0"; |
1327 |
++ } |
1328 |
+ |
1329 |
+- output_asm_insn (xasm, &call_op); |
1330 |
++ if (output_indirect_p && !direct_p) |
1331 |
++ ix86_output_indirect_branch (call_op, xasm, true); |
1332 |
++ else |
1333 |
++ output_asm_insn (xasm, &call_op); |
1334 |
+ return ""; |
1335 |
+ } |
1336 |
+ |
1337 |
+@@ -28520,18 +28964,37 @@ |
1338 |
+ { |
1339 |
+ if (ix86_nopic_noplt_attribute_p (call_op)) |
1340 |
+ { |
1341 |
++ direct_p = false; |
1342 |
+ if (TARGET_64BIT) |
1343 |
+- xasm = "%!call\t{*%p0@GOTPCREL(%%rip)|[QWORD PTR %p0@GOTPCREL[rip]]}"; |
1344 |
++ { |
1345 |
++ if (output_indirect_p) |
1346 |
++ xasm = "{%p0@GOTPCREL(%%rip)|[QWORD PTR %p0@GOTPCREL[rip]]}"; |
1347 |
++ else |
1348 |
++ xasm = "%!call\t{*%p0@GOTPCREL(%%rip)|[QWORD PTR %p0@GOTPCREL[rip]]}"; |
1349 |
++ } |
1350 |
+ else |
1351 |
+- xasm = "%!call\t{*%p0@GOT|[DWORD PTR %p0@GOT]}"; |
1352 |
++ { |
1353 |
++ if (output_indirect_p) |
1354 |
++ xasm = "{%p0@GOT|[DWORD PTR %p0@GOT]}"; |
1355 |
++ else |
1356 |
++ xasm = "%!call\t{*%p0@GOT|[DWORD PTR %p0@GOT]}"; |
1357 |
++ } |
1358 |
+ } |
1359 |
+ else |
1360 |
+ xasm = "%!call\t%P0"; |
1361 |
+ } |
1362 |
+ else |
1363 |
+- xasm = "%!call\t%A0"; |
1364 |
++ { |
1365 |
++ if (output_indirect_p) |
1366 |
++ xasm = "%0"; |
1367 |
++ else |
1368 |
++ xasm = "%!call\t%A0"; |
1369 |
++ } |
1370 |
+ |
1371 |
+- output_asm_insn (xasm, &call_op); |
1372 |
++ if (output_indirect_p && !direct_p) |
1373 |
++ ix86_output_indirect_branch (call_op, xasm, false); |
1374 |
++ else |
1375 |
++ output_asm_insn (xasm, &call_op); |
1376 |
+ |
1377 |
+ if (seh_nop_p) |
1378 |
+ return "nop"; |
1379 |
+@@ -41435,7 +41898,7 @@ |
1380 |
+ } |
1381 |
+ |
1382 |
+ static tree |
1383 |
+-ix86_handle_fndecl_attribute (tree *node, tree name, tree, int, |
1384 |
++ix86_handle_fndecl_attribute (tree *node, tree name, tree args, int, |
1385 |
+ bool *no_add_attrs) |
1386 |
+ { |
1387 |
+ if (TREE_CODE (*node) != FUNCTION_DECL) |
1388 |
+@@ -41444,6 +41907,29 @@ |
1389 |
+ name); |
1390 |
+ *no_add_attrs = true; |
1391 |
+ } |
1392 |
++ |
1393 |
++ if (is_attribute_p ("indirect_branch", name)) |
1394 |
++ { |
1395 |
++ tree cst = TREE_VALUE (args); |
1396 |
++ if (TREE_CODE (cst) != STRING_CST) |
1397 |
++ { |
1398 |
++ warning (OPT_Wattributes, |
1399 |
++ "%qE attribute requires a string constant argument", |
1400 |
++ name); |
1401 |
++ *no_add_attrs = true; |
1402 |
++ } |
1403 |
++ else if (strcmp (TREE_STRING_POINTER (cst), "keep") != 0 |
1404 |
++ && strcmp (TREE_STRING_POINTER (cst), "thunk") != 0 |
1405 |
++ && strcmp (TREE_STRING_POINTER (cst), "thunk-inline") != 0 |
1406 |
++ && strcmp (TREE_STRING_POINTER (cst), "thunk-extern") != 0) |
1407 |
++ { |
1408 |
++ warning (OPT_Wattributes, |
1409 |
++ "argument to %qE attribute is not " |
1410 |
++ "(keep|thunk|thunk-inline|thunk-extern)", name); |
1411 |
++ *no_add_attrs = true; |
1412 |
++ } |
1413 |
++ } |
1414 |
++ |
1415 |
+ return NULL_TREE; |
1416 |
+ } |
1417 |
+ |
1418 |
+@@ -45738,6 +46224,8 @@ |
1419 |
+ ix86_handle_interrupt_attribute, false }, |
1420 |
+ { "no_caller_saved_registers", 0, 0, false, true, true, |
1421 |
+ ix86_handle_no_caller_saved_registers_attribute, false }, |
1422 |
++ { "indirect_branch", 1, 1, true, false, false, |
1423 |
++ ix86_handle_fndecl_attribute, NULL }, |
1424 |
+ |
1425 |
+ /* End element. */ |
1426 |
+ { NULL, 0, 0, false, false, false, NULL, false } |
1427 |
+diff -Naur gcc-7.2.0.orig/gcc/config/i386/i386.h gcc-7.2.0/gcc/config/i386/i386.h |
1428 |
+--- gcc-7.2.0.orig/gcc/config/i386/i386.h 2018-01-15 17:52:48.895745684 -0800 |
1429 |
++++ gcc-7.2.0/gcc/config/i386/i386.h 2018-01-15 18:14:15.055722651 -0800 |
1430 |
+@@ -2604,6 +2604,13 @@ |
1431 |
+ /* Function type. */ |
1432 |
+ ENUM_BITFIELD(function_type) func_type : 2; |
1433 |
+ |
1434 |
++ /* How to generate indirec branch. */ |
1435 |
++ ENUM_BITFIELD(indirect_branch) indirect_branch_type : 3; |
1436 |
++ |
1437 |
++ /* If true, the current function has local indirect jumps, like |
1438 |
++ "indirect_jump" or "tablejump". */ |
1439 |
++ BOOL_BITFIELD has_local_indirect_jump : 1; |
1440 |
++ |
1441 |
+ /* If true, the current function is a function specified with |
1442 |
+ the "interrupt" or "no_caller_saved_registers" attribute. */ |
1443 |
+ BOOL_BITFIELD no_caller_saved_registers : 1; |
1444 |
+diff -Naur gcc-7.2.0.orig/gcc/config/i386/i386.md gcc-7.2.0/gcc/config/i386/i386.md |
1445 |
+--- gcc-7.2.0.orig/gcc/config/i386/i386.md 2018-01-15 17:52:48.888745684 -0800 |
1446 |
++++ gcc-7.2.0/gcc/config/i386/i386.md 2018-01-15 18:16:32.476720190 -0800 |
1447 |
+@@ -11610,12 +11610,17 @@ |
1448 |
+ { |
1449 |
+ if (TARGET_X32) |
1450 |
+ operands[0] = convert_memory_address (word_mode, operands[0]); |
1451 |
++ cfun->machine->has_local_indirect_jump = true; |
1452 |
+ }) |
1453 |
+ |
1454 |
+ (define_insn "*indirect_jump" |
1455 |
+ [(set (pc) (match_operand:W 0 "indirect_branch_operand" "rBw"))] |
1456 |
+ "" |
1457 |
+- "%!jmp\t%A0" |
1458 |
+- [(set_attr "type" "ibr") |
1459 |
++ "* return ix86_output_indirect_jmp (operands[0], false);" |
1460 |
++ [(set (attr "type") |
1461 |
++ (if_then_else (match_test "(cfun->machine->indirect_branch_type |
1462 |
++ != indirect_branch_keep)") |
1463 |
++ (const_string "multi") |
1464 |
++ (const_string "ibr"))) |
1465 |
+ (set_attr "length_immediate" "0") |
1466 |
+ (set_attr "maybe_prefix_bnd" "1")]) |
1467 |
+@@ -11659,13 +11660,18 @@ |
1468 |
+ |
1469 |
+ if (TARGET_X32) |
1470 |
+ operands[0] = convert_memory_address (word_mode, operands[0]); |
1471 |
++ cfun->machine->has_local_indirect_jump = true; |
1472 |
+ }) |
1473 |
+ |
1474 |
+ (define_insn "*tablejump_1" |
1475 |
+ [(set (pc) (match_operand:W 0 "indirect_branch_operand" "rBw")) |
1476 |
+ (use (label_ref (match_operand 1)))] |
1477 |
+ "" |
1478 |
+- "%!jmp\t%A0" |
1479 |
+- [(set_attr "type" "ibr") |
1480 |
++ "* return ix86_output_indirect_jmp (operands[0], false);" |
1481 |
++ [(set (attr "type") |
1482 |
++ (if_then_else (match_test "(cfun->machine->indirect_branch_type |
1483 |
++ != indirect_branch_keep)") |
1484 |
++ (const_string "multi") |
1485 |
++ (const_string "ibr"))) |
1486 |
+ (set_attr "length_immediate" "0") |
1487 |
+ (set_attr "maybe_prefix_bnd" "1")]) |
1488 |
+@@ -12337,7 +12339,11 @@ |
1489 |
+ [(simple_return) |
1490 |
+ (use (match_operand:SI 0 "register_operand" "r"))] |
1491 |
+ "reload_completed" |
1492 |
+- "%!jmp\t%A0" |
1493 |
+- [(set_attr "type" "ibr") |
1494 |
++ "* return ix86_output_indirect_jmp (operands[0], true);" |
1495 |
++ [(set (attr "type") |
1496 |
++ (if_then_else (match_test "(cfun->machine->indirect_branch_type |
1497 |
++ != indirect_branch_keep)") |
1498 |
++ (const_string "multi") |
1499 |
++ (const_string "ibr"))) |
1500 |
+ (set_attr "length_immediate" "0") |
1501 |
+ (set_attr "maybe_prefix_bnd" "1")]) |
1502 |
+diff -Naur gcc-7.2.0.orig/gcc/config/i386/i386.opt gcc-7.2.0/gcc/config/i386/i386.opt |
1503 |
+--- gcc-7.2.0.orig/gcc/config/i386/i386.opt 2018-01-15 17:52:48.890745684 -0800 |
1504 |
++++ gcc-7.2.0/gcc/config/i386/i386.opt 2018-01-15 18:17:13.972719447 -0800 |
1505 |
+@@ -927,3 +927,23 @@ |
1506 |
+ mgeneral-regs-only |
1507 |
+ Target Report RejectNegative Mask(GENERAL_REGS_ONLY) Var(ix86_target_flags) Save |
1508 |
+ Generate code which uses only the general registers. |
1509 |
++ |
1510 |
++mindirect-branch= |
1511 |
++Target Report RejectNegative Joined Enum(indirect_branch) Var(ix86_indirect_branch) Init(indirect_branch_keep) |
1512 |
++Convert indirect call and jump to call and return thunks. |
1513 |
++ |
1514 |
++Enum |
1515 |
++Name(indirect_branch) Type(enum indirect_branch) |
1516 |
++Known indirect branch choices (for use with the -mindirect-branch= option): |
1517 |
++ |
1518 |
++EnumValue |
1519 |
++Enum(indirect_branch) String(keep) Value(indirect_branch_keep) |
1520 |
++ |
1521 |
++EnumValue |
1522 |
++Enum(indirect_branch) String(thunk) Value(indirect_branch_thunk) |
1523 |
++ |
1524 |
++EnumValue |
1525 |
++Enum(indirect_branch) String(thunk-inline) Value(indirect_branch_thunk_inline) |
1526 |
++ |
1527 |
++EnumValue |
1528 |
++Enum(indirect_branch) String(thunk-extern) Value(indirect_branch_thunk_extern) |
1529 |
+diff -Naur gcc-7.2.0.orig/gcc/doc/extend.texi gcc-7.2.0/gcc/doc/extend.texi |
1530 |
+--- gcc-7.2.0.orig/gcc/doc/extend.texi 2018-01-15 17:52:47.196745715 -0800 |
1531 |
++++ gcc-7.2.0/gcc/doc/extend.texi 2018-01-15 18:17:49.790718806 -0800 |
1532 |
+@@ -5540,6 +5540,16 @@ |
1533 |
+ @code{target("fpmath=sse,387")} option as |
1534 |
+ @code{target("fpmath=sse+387")} because the comma would separate |
1535 |
+ different options. |
1536 |
++ |
1537 |
++@item indirect_branch("@var{choice}") |
1538 |
++@cindex @code{indirect_branch} function attribute, x86 |
1539 |
++On x86 targets, the @code{indirect_branch} attribute causes the compiler |
1540 |
++to convert indirect call and jump with @var{choice}. @samp{keep} |
1541 |
++keeps indirect call and jump unmodified. @samp{thunk} converts indirect |
1542 |
++call and jump to call and return thunk. @samp{thunk-inline} converts |
1543 |
++indirect call and jump to inlined call and return thunk. |
1544 |
++@samp{thunk-extern} converts indirect call and jump to external call |
1545 |
++and return thunk provided in a separate object file. |
1546 |
+ @end table |
1547 |
+ |
1548 |
+ On the x86, the inliner does not inline a |
1549 |
+diff -Naur gcc-7.2.0.orig/gcc/doc/invoke.texi gcc-7.2.0/gcc/doc/invoke.texi |
1550 |
+--- gcc-7.2.0.orig/gcc/doc/invoke.texi 2018-01-15 17:52:47.197745715 -0800 |
1551 |
++++ gcc-7.2.0/gcc/doc/invoke.texi 2018-01-15 18:20:56.174715468 -0800 |
1552 |
+@@ -1210,7 +1210,8 @@ |
1553 |
+ -msse2avx -mfentry -mrecord-mcount -mnop-mcount -m8bit-idiv @gol |
1554 |
+ -mavx256-split-unaligned-load -mavx256-split-unaligned-store @gol |
1555 |
+ -malign-data=@var{type} -mstack-protector-guard=@var{guard} @gol |
1556 |
+--mmitigate-rop -mgeneral-regs-only} |
1557 |
++-mmitigate-rop -mgeneral-regs-only @gol |
1558 |
++-mindirect-branch=@var{choice}} |
1559 |
+ |
1560 |
+ @emph{x86 Windows Options} |
1561 |
+ @gccoptlist{-mconsole -mcygwin -mno-cygwin -mdll @gol |
1562 |
+@@ -25648,6 +25649,17 @@ |
1563 |
+ prevents the compiler from using floating-point, vector, mask and bound |
1564 |
+ registers. |
1565 |
+ |
1566 |
++@item -mindirect-branch=@var{choice} |
1567 |
++@opindex -mindirect-branch |
1568 |
++Convert indirect call and jump with @var{choice}. The default is |
1569 |
++@samp{keep}, which keeps indirect call and jump unmodified. |
1570 |
++@samp{thunk} converts indirect call and jump to call and return thunk. |
1571 |
++@samp{thunk-inline} converts indirect call and jump to inlined call |
1572 |
++and return thunk. @samp{thunk-extern} converts indirect call and jump |
1573 |
++to external call and return thunk provided in a separate object file. |
1574 |
++You can control this behavior for a specific function by using the |
1575 |
++function attribute @code{indirect_branch}. @xref{Function Attributes}. |
1576 |
++ |
1577 |
+ @end table |
1578 |
+ |
1579 |
+ These @samp{-m} switches are supported in addition to the above |
1580 |
+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-1.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-1.c |
1581 |
+new file mode 100644 |
1582 |
+index 00000000000..d1d2ee78797 |
1583 |
+--- /dev/null |
1584 |
++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-1.c |
1585 |
+@@ -0,0 +1,19 @@ |
1586 |
++/* { dg-do compile } */ |
1587 |
++/* { dg-options "-O2 -mindirect-branch=thunk -fno-pic" } */ |
1588 |
++ |
1589 |
++typedef void (*dispatch_t)(long offset); |
1590 |
++ |
1591 |
++dispatch_t dispatch; |
1592 |
++ |
1593 |
++void |
1594 |
++male_indirect_jump (long offset) |
1595 |
++{ |
1596 |
++ dispatch(offset); |
1597 |
++} |
1598 |
++ |
1599 |
++/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { ! x32 } } } } */ |
1600 |
++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" { target { ! x32 } } } } */ |
1601 |
++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk_(r|e)ax" { target x32 } } } */ |
1602 |
++/* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */ |
1603 |
++/* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */ |
1604 |
++/* { dg-final { scan-assembler {\tpause} } } */ |
1605 |
+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-2.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-2.c |
1606 |
+new file mode 100644 |
1607 |
+index 00000000000..08646c6b823 |
1608 |
+--- /dev/null |
1609 |
++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-2.c |
1610 |
+@@ -0,0 +1,19 @@ |
1611 |
++/* { dg-do compile } */ |
1612 |
++/* { dg-options "-O2 -mindirect-branch=thunk -fno-pic" } */ |
1613 |
++ |
1614 |
++typedef void (*dispatch_t)(long offset); |
1615 |
++ |
1616 |
++dispatch_t dispatch[256]; |
1617 |
++ |
1618 |
++void |
1619 |
++male_indirect_jump (long offset) |
1620 |
++{ |
1621 |
++ dispatch[offset](offset); |
1622 |
++} |
1623 |
++ |
1624 |
++/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { ! x32 } } } } */ |
1625 |
++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" { target { ! x32 } } } } */ |
1626 |
++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk_(r|e)ax" { target x32 } } } */ |
1627 |
++/* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */ |
1628 |
++/* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */ |
1629 |
++/* { dg-final { scan-assembler {\tpause} } } */ |
1630 |
+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-3.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-3.c |
1631 |
+new file mode 100644 |
1632 |
+index 00000000000..af244de2238 |
1633 |
+--- /dev/null |
1634 |
++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-3.c |
1635 |
+@@ -0,0 +1,20 @@ |
1636 |
++/* { dg-do compile } */ |
1637 |
++/* { dg-options "-O2 -mindirect-branch=thunk -fno-pic" } */ |
1638 |
++ |
1639 |
++typedef void (*dispatch_t)(long offset); |
1640 |
++ |
1641 |
++dispatch_t dispatch; |
1642 |
++ |
1643 |
++int |
1644 |
++male_indirect_jump (long offset) |
1645 |
++{ |
1646 |
++ dispatch(offset); |
1647 |
++ return 0; |
1648 |
++} |
1649 |
++ |
1650 |
++/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { ! x32 } } } } */ |
1651 |
++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" { target { ! x32 } } } } */ |
1652 |
++/* { dg-final { scan-assembler "call\[ \t\]*__x86_indirect_thunk_(r|e)ax" { target x32 } } } */ |
1653 |
++/* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */ |
1654 |
++/* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */ |
1655 |
++/* { dg-final { scan-assembler {\tpause} } } */ |
1656 |
+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-4.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-4.c |
1657 |
+new file mode 100644 |
1658 |
+index 00000000000..b8aedd5a4e6 |
1659 |
+--- /dev/null |
1660 |
++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-4.c |
1661 |
+@@ -0,0 +1,20 @@ |
1662 |
++/* { dg-do compile } */ |
1663 |
++/* { dg-options "-O2 -mindirect-branch=thunk -fno-pic" } */ |
1664 |
++ |
1665 |
++typedef void (*dispatch_t)(long offset); |
1666 |
++ |
1667 |
++dispatch_t dispatch[256]; |
1668 |
++ |
1669 |
++int |
1670 |
++male_indirect_jump (long offset) |
1671 |
++{ |
1672 |
++ dispatch[offset](offset); |
1673 |
++ return 0; |
1674 |
++} |
1675 |
++ |
1676 |
++/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { ! x32 } } } } */ |
1677 |
++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" { target { ! x32 } } } } */ |
1678 |
++/* { dg-final { scan-assembler "call\[ \t\]*__x86_indirect_thunk_(r|e)ax" { target x32 } } } */ |
1679 |
++/* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */ |
1680 |
++/* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */ |
1681 |
++/* { dg-final { scan-assembler {\tpause} } } */ |
1682 |
+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-5.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-5.c |
1683 |
+new file mode 100644 |
1684 |
+index 00000000000..6ffb9235f94 |
1685 |
+--- /dev/null |
1686 |
++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-5.c |
1687 |
+@@ -0,0 +1,16 @@ |
1688 |
++/* { dg-do compile { target *-*-linux* } } */ |
1689 |
++/* { dg-options "-O2 -fpic -fno-plt -mindirect-branch=thunk" } */ |
1690 |
++ |
1691 |
++extern void bar (void); |
1692 |
++ |
1693 |
++void |
1694 |
++foo (void) |
1695 |
++{ |
1696 |
++ bar (); |
1697 |
++} |
1698 |
++ |
1699 |
++/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*bar@GOT" } } */ |
1700 |
++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" } } */ |
1701 |
++/* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */ |
1702 |
++/* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */ |
1703 |
++/* { dg-final { scan-assembler {\tpause} } } */ |
1704 |
+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-6.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-6.c |
1705 |
+new file mode 100644 |
1706 |
+index 00000000000..e6d9d148cd2 |
1707 |
+--- /dev/null |
1708 |
++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-6.c |
1709 |
+@@ -0,0 +1,17 @@ |
1710 |
++/* { dg-do compile { target *-*-linux* } } */ |
1711 |
++/* { dg-options "-O2 -fpic -fno-plt -mindirect-branch=thunk" } */ |
1712 |
++ |
1713 |
++extern void bar (void); |
1714 |
++ |
1715 |
++int |
1716 |
++foo (void) |
1717 |
++{ |
1718 |
++ bar (); |
1719 |
++ return 0; |
1720 |
++} |
1721 |
++ |
1722 |
++/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*bar@GOT" } } */ |
1723 |
++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" } } */ |
1724 |
++/* { dg-final { scan-assembler-times "jmp\[ \t\]*\.LIND" 2 } } */ |
1725 |
++/* { dg-final { scan-assembler-times "call\[ \t\]*\.LIND" 2 } } */ |
1726 |
++/* { dg-final { scan-assembler {\tpause} } } */ |
1727 |
+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-7.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-7.c |
1728 |
+new file mode 100644 |
1729 |
+index 00000000000..d892d8f5992 |
1730 |
+--- /dev/null |
1731 |
++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-7.c |
1732 |
+@@ -0,0 +1,43 @@ |
1733 |
++/* { dg-do compile } */ |
1734 |
++/* { dg-options "-O2 -mindirect-branch=thunk -fno-pic" } */ |
1735 |
++ |
1736 |
++void func0 (void); |
1737 |
++void func1 (void); |
1738 |
++void func2 (void); |
1739 |
++void func3 (void); |
1740 |
++void func4 (void); |
1741 |
++void func4 (void); |
1742 |
++void func5 (void); |
1743 |
++ |
1744 |
++void |
1745 |
++bar (int i) |
1746 |
++{ |
1747 |
++ switch (i) |
1748 |
++ { |
1749 |
++ default: |
1750 |
++ func0 (); |
1751 |
++ break; |
1752 |
++ case 1: |
1753 |
++ func1 (); |
1754 |
++ break; |
1755 |
++ case 2: |
1756 |
++ func2 (); |
1757 |
++ break; |
1758 |
++ case 3: |
1759 |
++ func3 (); |
1760 |
++ break; |
1761 |
++ case 4: |
1762 |
++ func4 (); |
1763 |
++ break; |
1764 |
++ case 5: |
1765 |
++ func5 (); |
1766 |
++ break; |
1767 |
++ } |
1768 |
++} |
1769 |
++ |
1770 |
++/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*\.L\[0-9\]+\\(,%" { target { ! x32 } } } } */ |
1771 |
++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" { target { ! x32 } } } } */ |
1772 |
++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk_(r|e)ax" { target x32 } } } */ |
1773 |
++/* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */ |
1774 |
++/* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */ |
1775 |
++/* { dg-final { scan-assembler {\tpause} } } */ |
1776 |
+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-1.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-1.c |
1777 |
+new file mode 100644 |
1778 |
+index 00000000000..24188d0b62d |
1779 |
+--- /dev/null |
1780 |
++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-1.c |
1781 |
+@@ -0,0 +1,22 @@ |
1782 |
++/* { dg-do compile } */ |
1783 |
++/* { dg-options "-O2 -fno-pic" } */ |
1784 |
++ |
1785 |
++typedef void (*dispatch_t)(long offset); |
1786 |
++ |
1787 |
++dispatch_t dispatch; |
1788 |
++ |
1789 |
++extern void male_indirect_jump (long) |
1790 |
++ __attribute__ ((indirect_branch("thunk"))); |
1791 |
++ |
1792 |
++void |
1793 |
++male_indirect_jump (long offset) |
1794 |
++{ |
1795 |
++ dispatch(offset); |
1796 |
++} |
1797 |
++ |
1798 |
++/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { ! x32 } } } } */ |
1799 |
++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" { target { ! x32 } } } } */ |
1800 |
++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk_(r|e)ax" { target x32 } } } */ |
1801 |
++/* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */ |
1802 |
++/* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */ |
1803 |
++/* { dg-final { scan-assembler {\tpause} } } */ |
1804 |
+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-2.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-2.c |
1805 |
+new file mode 100644 |
1806 |
+index 00000000000..03184b90cda |
1807 |
+--- /dev/null |
1808 |
++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-2.c |
1809 |
+@@ -0,0 +1,20 @@ |
1810 |
++/* { dg-do compile } */ |
1811 |
++/* { dg-options "-O2 -fno-pic" } */ |
1812 |
++ |
1813 |
++typedef void (*dispatch_t)(long offset); |
1814 |
++ |
1815 |
++dispatch_t dispatch[256]; |
1816 |
++ |
1817 |
++__attribute__ ((indirect_branch("thunk"))) |
1818 |
++void |
1819 |
++male_indirect_jump (long offset) |
1820 |
++{ |
1821 |
++ dispatch[offset](offset); |
1822 |
++} |
1823 |
++ |
1824 |
++/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { ! x32 } } } } */ |
1825 |
++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" { target { ! x32 } } } } */ |
1826 |
++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk_(r|e)ax" { target x32 } } } */ |
1827 |
++/* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */ |
1828 |
++/* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */ |
1829 |
++/* { dg-final { scan-assembler {\tpause} } } */ |
1830 |
+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-3.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-3.c |
1831 |
+new file mode 100644 |
1832 |
+index 00000000000..af167840b81 |
1833 |
+--- /dev/null |
1834 |
++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-3.c |
1835 |
+@@ -0,0 +1,21 @@ |
1836 |
++/* { dg-do compile } */ |
1837 |
++/* { dg-options "-O2 -fno-pic" } */ |
1838 |
++ |
1839 |
++typedef void (*dispatch_t)(long offset); |
1840 |
++ |
1841 |
++dispatch_t dispatch; |
1842 |
++extern int male_indirect_jump (long) |
1843 |
++ __attribute__ ((indirect_branch("thunk-inline"))); |
1844 |
++ |
1845 |
++int |
1846 |
++male_indirect_jump (long offset) |
1847 |
++{ |
1848 |
++ dispatch(offset); |
1849 |
++ return 0; |
1850 |
++} |
1851 |
++ |
1852 |
++/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { ! x32 } } } } */ |
1853 |
++/* { dg-final { scan-assembler-times "jmp\[ \t\]*\.LIND" 2 } } */ |
1854 |
++/* { dg-final { scan-assembler-times "call\[ \t\]*\.LIND" 2 } } */ |
1855 |
++/* { dg-final { scan-assembler-not "__x86_indirect_thunk" } } */ |
1856 |
++/* { dg-final { scan-assembler-not "pushq\[ \t\]%rax" { target x32 } } } */ |
1857 |
+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-4.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-4.c |
1858 |
+new file mode 100644 |
1859 |
+index 00000000000..146124894a0 |
1860 |
+--- /dev/null |
1861 |
++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-4.c |
1862 |
+@@ -0,0 +1,20 @@ |
1863 |
++/* { dg-do compile } */ |
1864 |
++/* { dg-options "-O2 -fno-pic" } */ |
1865 |
++ |
1866 |
++typedef void (*dispatch_t)(long offset); |
1867 |
++ |
1868 |
++dispatch_t dispatch[256]; |
1869 |
++ |
1870 |
++__attribute__ ((indirect_branch("thunk-inline"))) |
1871 |
++int |
1872 |
++male_indirect_jump (long offset) |
1873 |
++{ |
1874 |
++ dispatch[offset](offset); |
1875 |
++ return 0; |
1876 |
++} |
1877 |
++ |
1878 |
++/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { ! x32 } } } } */ |
1879 |
++/* { dg-final { scan-assembler-times "jmp\[ \t\]*\.LIND" 2 } } */ |
1880 |
++/* { dg-final { scan-assembler-times "call\[ \t\]*\.LIND" 2 } } */ |
1881 |
++/* { dg-final { scan-assembler-not "__x86_indirect_thunk" } } */ |
1882 |
++/* { dg-final { scan-assembler-not "pushq\[ \t\]%rax" { target x32 } } } */ |
1883 |
+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-5.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-5.c |
1884 |
+new file mode 100644 |
1885 |
+index 00000000000..568327cd8e7 |
1886 |
+--- /dev/null |
1887 |
++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-5.c |
1888 |
+@@ -0,0 +1,22 @@ |
1889 |
++/* { dg-do compile } */ |
1890 |
++/* { dg-options "-O2 -fno-pic" } */ |
1891 |
++ |
1892 |
++typedef void (*dispatch_t)(long offset); |
1893 |
++ |
1894 |
++dispatch_t dispatch; |
1895 |
++extern int male_indirect_jump (long) |
1896 |
++ __attribute__ ((indirect_branch("thunk-extern"))); |
1897 |
++ |
1898 |
++int |
1899 |
++male_indirect_jump (long offset) |
1900 |
++{ |
1901 |
++ dispatch(offset); |
1902 |
++ return 0; |
1903 |
++} |
1904 |
++ |
1905 |
++/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { ! x32 } } } } */ |
1906 |
++/* { dg-final { scan-assembler-times "jmp\[ \t\]*\.LIND" 1 { target { ! x32 } } } } */ |
1907 |
++/* { dg-final { scan-assembler-times "call\[ \t\]*\.LIND" 1 { target { ! x32 } } } } */ |
1908 |
++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" { target { ! x32 } } } } */ |
1909 |
++/* { dg-final { scan-assembler "call\[ \t\]*__x86_indirect_thunk_(r|e)ax" { target x32 } } } */ |
1910 |
++/* { dg-final { scan-assembler-not {\t(pause|pause)} } } */ |
1911 |
+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-6.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-6.c |
1912 |
+new file mode 100644 |
1913 |
+index 00000000000..bd8a99e7828 |
1914 |
+--- /dev/null |
1915 |
++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-6.c |
1916 |
+@@ -0,0 +1,21 @@ |
1917 |
++/* { dg-do compile } */ |
1918 |
++/* { dg-options "-O2 -fno-pic" } */ |
1919 |
++ |
1920 |
++typedef void (*dispatch_t)(long offset); |
1921 |
++ |
1922 |
++dispatch_t dispatch[256]; |
1923 |
++ |
1924 |
++__attribute__ ((indirect_branch("thunk-extern"))) |
1925 |
++int |
1926 |
++male_indirect_jump (long offset) |
1927 |
++{ |
1928 |
++ dispatch[offset](offset); |
1929 |
++ return 0; |
1930 |
++} |
1931 |
++ |
1932 |
++/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { ! x32 } } } } */ |
1933 |
++/* { dg-final { scan-assembler-times "jmp\[ \t\]*\.LIND" 1 { target { ! x32 } } } } */ |
1934 |
++/* { dg-final { scan-assembler-times "call\[ \t\]*\.LIND" 1 { target { ! x32 } } } } */ |
1935 |
++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" { target { ! x32 } } } } */ |
1936 |
++/* { dg-final { scan-assembler "call\[ \t\]*__x86_indirect_thunk_(r|e)ax" { target x32 } } } */ |
1937 |
++/* { dg-final { scan-assembler-not {\t(pause|pause)} } } */ |
1938 |
+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-7.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-7.c |
1939 |
+new file mode 100644 |
1940 |
+index 00000000000..356015c9799 |
1941 |
+--- /dev/null |
1942 |
++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-7.c |
1943 |
+@@ -0,0 +1,44 @@ |
1944 |
++/* { dg-do compile } */ |
1945 |
++/* { dg-options "-O2 -fno-pic" } */ |
1946 |
++ |
1947 |
++void func0 (void); |
1948 |
++void func1 (void); |
1949 |
++void func2 (void); |
1950 |
++void func3 (void); |
1951 |
++void func4 (void); |
1952 |
++void func4 (void); |
1953 |
++void func5 (void); |
1954 |
++ |
1955 |
++__attribute__ ((indirect_branch("thunk-extern"))) |
1956 |
++void |
1957 |
++bar (int i) |
1958 |
++{ |
1959 |
++ switch (i) |
1960 |
++ { |
1961 |
++ default: |
1962 |
++ func0 (); |
1963 |
++ break; |
1964 |
++ case 1: |
1965 |
++ func1 (); |
1966 |
++ break; |
1967 |
++ case 2: |
1968 |
++ func2 (); |
1969 |
++ break; |
1970 |
++ case 3: |
1971 |
++ func3 (); |
1972 |
++ break; |
1973 |
++ case 4: |
1974 |
++ func4 (); |
1975 |
++ break; |
1976 |
++ case 5: |
1977 |
++ func5 (); |
1978 |
++ break; |
1979 |
++ } |
1980 |
++} |
1981 |
++ |
1982 |
++/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*\.L\[0-9\]+\\(,%" { target { ! x32 } } } } */ |
1983 |
++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk_(r|e)ax" { target x32 } } } */ |
1984 |
++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" } } */ |
1985 |
++/* { dg-final { scan-assembler-not {\t(pause|pause)} } } */ |
1986 |
++/* { dg-final { scan-assembler-not "jmp\[ \t\]*\.LIND" } } */ |
1987 |
++/* { dg-final { scan-assembler-not "call\[ \t\]*\.LIND" } } */ |
1988 |
+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-8.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-8.c |
1989 |
+new file mode 100644 |
1990 |
+index 00000000000..6960fa0bbfb |
1991 |
+--- /dev/null |
1992 |
++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-8.c |
1993 |
+@@ -0,0 +1,41 @@ |
1994 |
++/* { dg-do compile } */ |
1995 |
++/* { dg-options "-O2 -mindirect-branch=thunk -fno-pic" } */ |
1996 |
++ |
1997 |
++void func0 (void); |
1998 |
++void func1 (void); |
1999 |
++void func2 (void); |
2000 |
++void func3 (void); |
2001 |
++void func4 (void); |
2002 |
++void func4 (void); |
2003 |
++void func5 (void); |
2004 |
++ |
2005 |
++__attribute__ ((indirect_branch("keep"))) |
2006 |
++void |
2007 |
++bar (int i) |
2008 |
++{ |
2009 |
++ switch (i) |
2010 |
++ { |
2011 |
++ default: |
2012 |
++ func0 (); |
2013 |
++ break; |
2014 |
++ case 1: |
2015 |
++ func1 (); |
2016 |
++ break; |
2017 |
++ case 2: |
2018 |
++ func2 (); |
2019 |
++ break; |
2020 |
++ case 3: |
2021 |
++ func3 (); |
2022 |
++ break; |
2023 |
++ case 4: |
2024 |
++ func4 (); |
2025 |
++ break; |
2026 |
++ case 5: |
2027 |
++ func5 (); |
2028 |
++ break; |
2029 |
++ } |
2030 |
++} |
2031 |
++ |
2032 |
++/* { dg-final { scan-assembler-not "__x86_indirect_thunk" } } */ |
2033 |
++/* { dg-final { scan-assembler-not "jmp\[ \t\]*\.LIND" } } */ |
2034 |
++/* { dg-final { scan-assembler-not "call\[ \t\]*\.LIND" } } */ |
2035 |
+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-1.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-1.c |
2036 |
+new file mode 100644 |
2037 |
+index 00000000000..febf32d76ea |
2038 |
+--- /dev/null |
2039 |
++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-1.c |
2040 |
+@@ -0,0 +1,19 @@ |
2041 |
++/* { dg-do compile { target { ! x32 } } } */ |
2042 |
++/* { dg-options "-O2 -mindirect-branch=thunk -fcheck-pointer-bounds -mmpx -fno-pic" } */ |
2043 |
++ |
2044 |
++void (*dispatch) (char *); |
2045 |
++char buf[10]; |
2046 |
++ |
2047 |
++void |
2048 |
++foo (void) |
2049 |
++{ |
2050 |
++ dispatch (buf); |
2051 |
++} |
2052 |
++ |
2053 |
++/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { ! x32 } } } } */ |
2054 |
++/* { dg-final { scan-assembler "pushq\[ \t\]%rax" { target x32 } } } */ |
2055 |
++/* { dg-final { scan-assembler "bnd jmp\[ \t\]*__x86_indirect_thunk_bnd" } } */ |
2056 |
++/* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */ |
2057 |
++/* { dg-final { scan-assembler "bnd call\[ \t\]*\.LIND" } } */ |
2058 |
++/* { dg-final { scan-assembler "bnd ret" } } */ |
2059 |
++/* { dg-final { scan-assembler {\tpause} } } */ |
2060 |
+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-2.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-2.c |
2061 |
+new file mode 100644 |
2062 |
+index 00000000000..319ba30b78b |
2063 |
+--- /dev/null |
2064 |
++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-2.c |
2065 |
+@@ -0,0 +1,20 @@ |
2066 |
++/* { dg-do compile { target { ! x32 } } } */ |
2067 |
++/* { dg-options "-O2 -mindirect-branch=thunk -fcheck-pointer-bounds -mmpx -fno-pic" } */ |
2068 |
++ |
2069 |
++void (*dispatch) (char *); |
2070 |
++char buf[10]; |
2071 |
++ |
2072 |
++int |
2073 |
++foo (void) |
2074 |
++{ |
2075 |
++ dispatch (buf); |
2076 |
++ return 0; |
2077 |
++} |
2078 |
++ |
2079 |
++/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { ! x32 } } } } */ |
2080 |
++/* { dg-final { scan-assembler "pushq\[ \t\]%rax" { target x32 } } } */ |
2081 |
++/* { dg-final { scan-assembler "bnd jmp\[ \t\]*__x86_indirect_thunk_bnd" } } */ |
2082 |
++/* { dg-final { scan-assembler "bnd jmp\[ \t\]*\.LIND" } } */ |
2083 |
++/* { dg-final { scan-assembler "bnd call\[ \t\]*\.LIND" } } */ |
2084 |
++/* { dg-final { scan-assembler "bnd ret" } } */ |
2085 |
++/* { dg-final { scan-assembler {\tpause} } } */ |
2086 |
+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-3.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-3.c |
2087 |
+new file mode 100644 |
2088 |
+index 00000000000..9168b3146f5 |
2089 |
+--- /dev/null |
2090 |
++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-3.c |
2091 |
+@@ -0,0 +1,18 @@ |
2092 |
++/* { dg-do compile { target { *-*-linux* && { ! x32 } } } } */ |
2093 |
++/* { dg-options "-O2 -mindirect-branch=thunk -fcheck-pointer-bounds -mmpx -fpic -fno-plt" } */ |
2094 |
++ |
2095 |
++void bar (char *); |
2096 |
++char buf[10]; |
2097 |
++ |
2098 |
++void |
2099 |
++foo (void) |
2100 |
++{ |
2101 |
++ bar (buf); |
2102 |
++} |
2103 |
++ |
2104 |
++/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*bar@GOT" } } */ |
2105 |
++/* { dg-final { scan-assembler "bnd jmp\[ \t\]*__x86_indirect_thunk_bnd" } } */ |
2106 |
++/* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */ |
2107 |
++/* { dg-final { scan-assembler "bnd call\[ \t\]*\.LIND" } } */ |
2108 |
++/* { dg-final { scan-assembler "bnd ret" } } */ |
2109 |
++/* { dg-final { scan-assembler {\tpause} } } */ |
2110 |
+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-4.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-4.c |
2111 |
+new file mode 100644 |
2112 |
+index 00000000000..d3b36d44c7c |
2113 |
+--- /dev/null |
2114 |
++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-4.c |
2115 |
+@@ -0,0 +1,19 @@ |
2116 |
++/* { dg-do compile { target { *-*-linux* && { ! x32 } } } } */ |
2117 |
++/* { dg-options "-O2 -mindirect-branch=thunk -fcheck-pointer-bounds -mmpx -fpic -fno-plt" } */ |
2118 |
++ |
2119 |
++void bar (char *); |
2120 |
++char buf[10]; |
2121 |
++ |
2122 |
++int |
2123 |
++foo (void) |
2124 |
++{ |
2125 |
++ bar (buf); |
2126 |
++ return 0; |
2127 |
++} |
2128 |
++ |
2129 |
++/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*bar@GOT" } } */ |
2130 |
++/* { dg-final { scan-assembler "bnd jmp\[ \t\]*__x86_indirect_thunk" } } */ |
2131 |
++/* { dg-final { scan-assembler "bnd jmp\[ \t\]*\.LIND" } } */ |
2132 |
++/* { dg-final { scan-assembler-times "bnd call\[ \t\]*\.LIND" 2 } } */ |
2133 |
++/* { dg-final { scan-assembler "bnd ret" } } */ |
2134 |
++/* { dg-final { scan-assembler {\tpause} } } */ |
2135 |
+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-1.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-1.c |
2136 |
+new file mode 100644 |
2137 |
+index 00000000000..9e50b282f77 |
2138 |
+--- /dev/null |
2139 |
++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-1.c |
2140 |
+@@ -0,0 +1,19 @@ |
2141 |
++/* { dg-do compile } */ |
2142 |
++/* { dg-options "-O2 -mindirect-branch=thunk-extern -fno-pic" } */ |
2143 |
++ |
2144 |
++typedef void (*dispatch_t)(long offset); |
2145 |
++ |
2146 |
++dispatch_t dispatch; |
2147 |
++ |
2148 |
++void |
2149 |
++male_indirect_jump (long offset) |
2150 |
++{ |
2151 |
++ dispatch(offset); |
2152 |
++} |
2153 |
++ |
2154 |
++/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { ! x32 } } } } */ |
2155 |
++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" { target { ! x32 } } } } */ |
2156 |
++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk_(r|e)ax" { target x32 } } } */ |
2157 |
++/* { dg-final { scan-assembler-not {\t(pause|pause)} } } */ |
2158 |
++/* { dg-final { scan-assembler-not "jmp\[ \t\]*\.LIND" } } */ |
2159 |
++/* { dg-final { scan-assembler-not "call\[ \t\]*\.LIND" } } */ |
2160 |
+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-2.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-2.c |
2161 |
+new file mode 100644 |
2162 |
+index 00000000000..f897d1c0497 |
2163 |
+--- /dev/null |
2164 |
++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-2.c |
2165 |
+@@ -0,0 +1,19 @@ |
2166 |
++/* { dg-do compile } */ |
2167 |
++/* { dg-options "-O2 -mindirect-branch=thunk-extern -fno-pic" } */ |
2168 |
++ |
2169 |
++typedef void (*dispatch_t)(long offset); |
2170 |
++ |
2171 |
++dispatch_t dispatch[256]; |
2172 |
++ |
2173 |
++void |
2174 |
++male_indirect_jump (long offset) |
2175 |
++{ |
2176 |
++ dispatch[offset](offset); |
2177 |
++} |
2178 |
++ |
2179 |
++/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { ! x32 } } } } */ |
2180 |
++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" { target { ! x32 } } } } */ |
2181 |
++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk_(r|e)ax" { target x32 } } } */ |
2182 |
++/* { dg-final { scan-assembler-not {\t(pause|pause)} } } */ |
2183 |
++/* { dg-final { scan-assembler-not "jmp\[ \t\]*\.LIND" } } */ |
2184 |
++/* { dg-final { scan-assembler-not "call\[ \t\]*\.LIND" } } */ |
2185 |
+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-3.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-3.c |
2186 |
+new file mode 100644 |
2187 |
+index 00000000000..25905cd0016 |
2188 |
+--- /dev/null |
2189 |
++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-3.c |
2190 |
+@@ -0,0 +1,20 @@ |
2191 |
++/* { dg-do compile } */ |
2192 |
++/* { dg-options "-O2 -mindirect-branch=thunk-extern -fno-pic" } */ |
2193 |
++ |
2194 |
++typedef void (*dispatch_t)(long offset); |
2195 |
++ |
2196 |
++dispatch_t dispatch; |
2197 |
++ |
2198 |
++int |
2199 |
++male_indirect_jump (long offset) |
2200 |
++{ |
2201 |
++ dispatch(offset); |
2202 |
++ return 0; |
2203 |
++} |
2204 |
++ |
2205 |
++/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { ! x32 } } } } */ |
2206 |
++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" { target { ! x32 } } } } */ |
2207 |
++/* { dg-final { scan-assembler-times "jmp\[ \t\]*\.LIND" 1 { target { ! x32 } } } } */ |
2208 |
++/* { dg-final { scan-assembler-times "call\[ \t\]*\.LIND" 1 { target { ! x32 } } } } */ |
2209 |
++/* { dg-final { scan-assembler "call\[ \t\]*__x86_indirect_thunk_(r|e)ax" { target x32 } } } */ |
2210 |
++/* { dg-final { scan-assembler-not {\t(pause|pause)} } } */ |
2211 |
+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-4.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-4.c |
2212 |
+new file mode 100644 |
2213 |
+index 00000000000..a7fa12183af |
2214 |
+--- /dev/null |
2215 |
++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-4.c |
2216 |
+@@ -0,0 +1,20 @@ |
2217 |
++/* { dg-do compile } */ |
2218 |
++/* { dg-options "-O2 -mindirect-branch=thunk-extern -fno-pic" } */ |
2219 |
++ |
2220 |
++typedef void (*dispatch_t)(long offset); |
2221 |
++ |
2222 |
++dispatch_t dispatch[256]; |
2223 |
++ |
2224 |
++int |
2225 |
++male_indirect_jump (long offset) |
2226 |
++{ |
2227 |
++ dispatch[offset](offset); |
2228 |
++ return 0; |
2229 |
++} |
2230 |
++ |
2231 |
++/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { ! x32 } } } } */ |
2232 |
++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" { target { ! x32 } } } } */ |
2233 |
++/* { dg-final { scan-assembler-times "jmp\[ \t\]*\.LIND" 1 { target { ! x32 } } } } */ |
2234 |
++/* { dg-final { scan-assembler-times "call\[ \t\]*\.LIND" 1 { target { ! x32 } } } } */ |
2235 |
++/* { dg-final { scan-assembler "call\[ \t\]*__x86_indirect_thunk_(r|e)ax" { target x32 } } } */ |
2236 |
++/* { dg-final { scan-assembler-not {\t(pause|pause)} } } */ |
2237 |
+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-5.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-5.c |
2238 |
+new file mode 100644 |
2239 |
+index 00000000000..48a49760be6 |
2240 |
+--- /dev/null |
2241 |
++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-5.c |
2242 |
+@@ -0,0 +1,16 @@ |
2243 |
++/* { dg-do compile { target *-*-linux* } } */ |
2244 |
++/* { dg-options "-O2 -fpic -fno-plt -mindirect-branch=thunk-extern" } */ |
2245 |
++ |
2246 |
++extern void bar (void); |
2247 |
++ |
2248 |
++void |
2249 |
++foo (void) |
2250 |
++{ |
2251 |
++ bar (); |
2252 |
++} |
2253 |
++ |
2254 |
++/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*bar@GOT" } } */ |
2255 |
++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" } } */ |
2256 |
++/* { dg-final { scan-assembler-not {\t(pause|pause)} } } */ |
2257 |
++/* { dg-final { scan-assembler-not "jmp\[ \t\]*\.LIND" } } */ |
2258 |
++/* { dg-final { scan-assembler-not "call\[ \t\]*\.LIND" } } */ |
2259 |
+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-6.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-6.c |
2260 |
+new file mode 100644 |
2261 |
+index 00000000000..a1c662f7d23 |
2262 |
+--- /dev/null |
2263 |
++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-6.c |
2264 |
+@@ -0,0 +1,17 @@ |
2265 |
++/* { dg-do compile { target *-*-linux* } } */ |
2266 |
++/* { dg-options "-O2 -fpic -fno-plt -mindirect-branch=thunk-extern" } */ |
2267 |
++ |
2268 |
++extern void bar (void); |
2269 |
++ |
2270 |
++int |
2271 |
++foo (void) |
2272 |
++{ |
2273 |
++ bar (); |
2274 |
++ return 0; |
2275 |
++} |
2276 |
++ |
2277 |
++/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*bar@GOT" } } */ |
2278 |
++/* { dg-final { scan-assembler-times "jmp\[ \t\]*\.LIND" 1 } } */ |
2279 |
++/* { dg-final { scan-assembler-times "call\[ \t\]*\.LIND" 1 } } */ |
2280 |
++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" } } */ |
2281 |
++/* { dg-final { scan-assembler-not {\t(pause|pause)} } } */ |
2282 |
+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-7.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-7.c |
2283 |
+new file mode 100644 |
2284 |
+index 00000000000..40a665ea640 |
2285 |
+--- /dev/null |
2286 |
++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-7.c |
2287 |
+@@ -0,0 +1,43 @@ |
2288 |
++/* { dg-do compile } */ |
2289 |
++/* { dg-options "-O2 -mindirect-branch=thunk-extern -fno-pic" } */ |
2290 |
++ |
2291 |
++void func0 (void); |
2292 |
++void func1 (void); |
2293 |
++void func2 (void); |
2294 |
++void func3 (void); |
2295 |
++void func4 (void); |
2296 |
++void func4 (void); |
2297 |
++void func5 (void); |
2298 |
++ |
2299 |
++void |
2300 |
++bar (int i) |
2301 |
++{ |
2302 |
++ switch (i) |
2303 |
++ { |
2304 |
++ default: |
2305 |
++ func0 (); |
2306 |
++ break; |
2307 |
++ case 1: |
2308 |
++ func1 (); |
2309 |
++ break; |
2310 |
++ case 2: |
2311 |
++ func2 (); |
2312 |
++ break; |
2313 |
++ case 3: |
2314 |
++ func3 (); |
2315 |
++ break; |
2316 |
++ case 4: |
2317 |
++ func4 (); |
2318 |
++ break; |
2319 |
++ case 5: |
2320 |
++ func5 (); |
2321 |
++ break; |
2322 |
++ } |
2323 |
++} |
2324 |
++ |
2325 |
++/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*\.L\[0-9\]+\\(,%" { target { ! x32 } } } } */ |
2326 |
++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" { target { ! x32 } } } } */ |
2327 |
++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk_(r|e)ax" { target x32 } } } */ |
2328 |
++/* { dg-final { scan-assembler-not {\t(pause|pause)} } } */ |
2329 |
++/* { dg-final { scan-assembler-not "jmp\[ \t\]*\.LIND" } } */ |
2330 |
++/* { dg-final { scan-assembler-not "call\[ \t\]*\.LIND" } } */ |
2331 |
+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-1.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-1.c |
2332 |
+new file mode 100644 |
2333 |
+index 00000000000..3ace8d1b031 |
2334 |
+--- /dev/null |
2335 |
++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-1.c |
2336 |
+@@ -0,0 +1,18 @@ |
2337 |
++/* { dg-do compile } */ |
2338 |
++/* { dg-options "-O2 -mindirect-branch=thunk-inline -fno-pic" } */ |
2339 |
++ |
2340 |
++typedef void (*dispatch_t)(long offset); |
2341 |
++ |
2342 |
++dispatch_t dispatch; |
2343 |
++ |
2344 |
++void |
2345 |
++male_indirect_jump (long offset) |
2346 |
++{ |
2347 |
++ dispatch(offset); |
2348 |
++} |
2349 |
++ |
2350 |
++/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { ! x32 } } } } */ |
2351 |
++/* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */ |
2352 |
++/* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */ |
2353 |
++/* { dg-final { scan-assembler-not "__x86_indirect_thunk" } } */ |
2354 |
++/* { dg-final { scan-assembler-not "pushq\[ \t\]%rax" { target x32 } } } */ |
2355 |
+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-2.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-2.c |
2356 |
+new file mode 100644 |
2357 |
+index 00000000000..6c97b96f1f2 |
2358 |
+--- /dev/null |
2359 |
++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-2.c |
2360 |
+@@ -0,0 +1,18 @@ |
2361 |
++/* { dg-do compile } */ |
2362 |
++/* { dg-options "-O2 -mindirect-branch=thunk-inline -fno-pic" } */ |
2363 |
++ |
2364 |
++typedef void (*dispatch_t)(long offset); |
2365 |
++ |
2366 |
++dispatch_t dispatch[256]; |
2367 |
++ |
2368 |
++void |
2369 |
++male_indirect_jump (long offset) |
2370 |
++{ |
2371 |
++ dispatch[offset](offset); |
2372 |
++} |
2373 |
++ |
2374 |
++/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { ! x32 } } } } */ |
2375 |
++/* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */ |
2376 |
++/* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */ |
2377 |
++/* { dg-final { scan-assembler-not "__x86_indirect_thunk" } } */ |
2378 |
++/* { dg-final { scan-assembler-not "pushq\[ \t\]%rax" { target x32 } } } */ |
2379 |
+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-3.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-3.c |
2380 |
+new file mode 100644 |
2381 |
+index 00000000000..8f6759cbf06 |
2382 |
+--- /dev/null |
2383 |
++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-3.c |
2384 |
+@@ -0,0 +1,19 @@ |
2385 |
++/* { dg-do compile } */ |
2386 |
++/* { dg-options "-O2 -mindirect-branch=thunk-inline -fno-pic" } */ |
2387 |
++ |
2388 |
++typedef void (*dispatch_t)(long offset); |
2389 |
++ |
2390 |
++dispatch_t dispatch; |
2391 |
++ |
2392 |
++int |
2393 |
++male_indirect_jump (long offset) |
2394 |
++{ |
2395 |
++ dispatch(offset); |
2396 |
++ return 0; |
2397 |
++} |
2398 |
++ |
2399 |
++/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { ! x32 } } } } */ |
2400 |
++/* { dg-final { scan-assembler-times "jmp\[ \t\]*\.LIND" 2 } } */ |
2401 |
++/* { dg-final { scan-assembler-times "call\[ \t\]*\.LIND" 2 } } */ |
2402 |
++/* { dg-final { scan-assembler-not "__x86_indirect_thunk" } } */ |
2403 |
++/* { dg-final { scan-assembler-not "pushq\[ \t\]%rax" { target x32 } } } */ |
2404 |
+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-4.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-4.c |
2405 |
+new file mode 100644 |
2406 |
+index 00000000000..b07d08cab0f |
2407 |
+--- /dev/null |
2408 |
++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-4.c |
2409 |
+@@ -0,0 +1,19 @@ |
2410 |
++/* { dg-do compile } */ |
2411 |
++/* { dg-options "-O2 -mindirect-branch=thunk-inline -fno-pic" } */ |
2412 |
++ |
2413 |
++typedef void (*dispatch_t)(long offset); |
2414 |
++ |
2415 |
++dispatch_t dispatch[256]; |
2416 |
++ |
2417 |
++int |
2418 |
++male_indirect_jump (long offset) |
2419 |
++{ |
2420 |
++ dispatch[offset](offset); |
2421 |
++ return 0; |
2422 |
++} |
2423 |
++ |
2424 |
++/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { ! x32 } } } } */ |
2425 |
++/* { dg-final { scan-assembler-times "jmp\[ \t\]*\.LIND" 2 } } */ |
2426 |
++/* { dg-final { scan-assembler-times "call\[ \t\]*\.LIND" 2 } } */ |
2427 |
++/* { dg-final { scan-assembler-not "__x86_indirect_thunk" } } */ |
2428 |
++/* { dg-final { scan-assembler-not "pushq\[ \t\]%rax" { target x32 } } } */ |
2429 |
+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-5.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-5.c |
2430 |
+new file mode 100644 |
2431 |
+index 00000000000..10794886b1b |
2432 |
+--- /dev/null |
2433 |
++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-5.c |
2434 |
+@@ -0,0 +1,15 @@ |
2435 |
++/* { dg-do compile { target *-*-linux* } } */ |
2436 |
++/* { dg-options "-O2 -fpic -fno-plt -mindirect-branch=thunk-inline" } */ |
2437 |
++ |
2438 |
++extern void bar (void); |
2439 |
++ |
2440 |
++void |
2441 |
++foo (void) |
2442 |
++{ |
2443 |
++ bar (); |
2444 |
++} |
2445 |
++ |
2446 |
++/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*bar@GOT" } } */ |
2447 |
++/* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */ |
2448 |
++/* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */ |
2449 |
++/* { dg-final { scan-assembler-not "__x86_indirect_thunk" } } */ |
2450 |
+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-6.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-6.c |
2451 |
+new file mode 100644 |
2452 |
+index 00000000000..a26ec4b06ed |
2453 |
+--- /dev/null |
2454 |
++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-6.c |
2455 |
+@@ -0,0 +1,16 @@ |
2456 |
++/* { dg-do compile { target *-*-linux* } } */ |
2457 |
++/* { dg-options "-O2 -fpic -fno-plt -mindirect-branch=thunk-inline" } */ |
2458 |
++ |
2459 |
++extern void bar (void); |
2460 |
++ |
2461 |
++int |
2462 |
++foo (void) |
2463 |
++{ |
2464 |
++ bar (); |
2465 |
++ return 0; |
2466 |
++} |
2467 |
++ |
2468 |
++/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*bar@GOT" } } */ |
2469 |
++/* { dg-final { scan-assembler-times "jmp\[ \t\]*\.LIND" 2 } } */ |
2470 |
++/* { dg-final { scan-assembler-times "call\[ \t\]*\.LIND" 2 } } */ |
2471 |
++/* { dg-final { scan-assembler-not "__x86_indirect_thunk" } } */ |
2472 |
+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-7.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-7.c |
2473 |
+new file mode 100644 |
2474 |
+index 00000000000..77253af17c6 |
2475 |
+--- /dev/null |
2476 |
++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-7.c |
2477 |
+@@ -0,0 +1,42 @@ |
2478 |
++/* { dg-do compile } */ |
2479 |
++/* { dg-options "-O2 -mindirect-branch=thunk-inline -fno-pic" } */ |
2480 |
++ |
2481 |
++void func0 (void); |
2482 |
++void func1 (void); |
2483 |
++void func2 (void); |
2484 |
++void func3 (void); |
2485 |
++void func4 (void); |
2486 |
++void func4 (void); |
2487 |
++void func5 (void); |
2488 |
++ |
2489 |
++void |
2490 |
++bar (int i) |
2491 |
++{ |
2492 |
++ switch (i) |
2493 |
++ { |
2494 |
++ default: |
2495 |
++ func0 (); |
2496 |
++ break; |
2497 |
++ case 1: |
2498 |
++ func1 (); |
2499 |
++ break; |
2500 |
++ case 2: |
2501 |
++ func2 (); |
2502 |
++ break; |
2503 |
++ case 3: |
2504 |
++ func3 (); |
2505 |
++ break; |
2506 |
++ case 4: |
2507 |
++ func4 (); |
2508 |
++ break; |
2509 |
++ case 5: |
2510 |
++ func5 (); |
2511 |
++ break; |
2512 |
++ } |
2513 |
++} |
2514 |
++ |
2515 |
++/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*\.L\[0-9\]+\\(,%" { target { ! x32 } } } } */ |
2516 |
++/* { dg-final { scan-assembler-not "pushq\[ \t\]%rax" { target x32 } } } */ |
2517 |
++/* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */ |
2518 |
++/* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */ |
2519 |
++/* { dg-final { scan-assembler-not "__x86_indirect_thunk" } } */ |
2520 |
+-- |
2521 |
+2.14.3 |
2522 |
+ |
2523 |
|
2524 |
diff --git a/sys-devel/gcc/files/spectre-0002-mfunction-return.patch b/sys-devel/gcc/files/spectre-0002-mfunction-return.patch |
2525 |
new file mode 100644 |
2526 |
index 0000000..d3fa601 |
2527 |
--- /dev/null |
2528 |
+++ b/sys-devel/gcc/files/spectre-0002-mfunction-return.patch |
2529 |
@@ -0,0 +1,1200 @@ |
2530 |
+From: "H dot J dot Lu" <hjl dot tools at gmail dot com> |
2531 |
+To: gcc-patches at gcc dot gnu dot org |
2532 |
+Subject: [PATCH 2/4] x86: Add -mfunction-return= |
2533 |
+Date: Fri, 12 Jan 2018 05:15:47 -0800 |
2534 |
+ |
2535 |
+Add -mfunction-return= option to convert function return to call and |
2536 |
+return thunks. The default is 'keep', which keeps function return |
2537 |
+unmodified. 'thunk' converts function return to call and return thunk. |
2538 |
+'thunk-inline' converts function return to inlined call and return thunk. |
2539 |
+'thunk-extern' converts function return to external call and return |
2540 |
+thunk provided in a separate object file. You can control this behavior |
2541 |
+for a specific function by using the function attribute function_return. |
2542 |
+ |
2543 |
+Function return thunk is the same as memory thunk for -mindirect-branch= |
2544 |
+where the return address is at the top of the stack: |
2545 |
+ |
2546 |
+__x86_return_thunk: |
2547 |
+ call L2 |
2548 |
+L1: |
2549 |
+ pause |
2550 |
+ jmp L1 |
2551 |
+L2: |
2552 |
+ lea 8(%rsp), %rsp|lea 4(%esp), %esp |
2553 |
+ ret |
2554 |
+ |
2555 |
+and function return becomes |
2556 |
+ |
2557 |
+ jmp __x86_return_thunk |
2558 |
+ |
2559 |
+-mindirect-branch= tests are updated with -mfunction-return=keep to |
2560 |
+avoid false test failures when -mfunction-return=thunk is added to |
2561 |
+RUNTESTFLAGS for "make check". |
2562 |
+ |
2563 |
+gcc/ |
2564 |
+ |
2565 |
+ * config/i386/i386-protos.h (ix86_output_function_return): New. |
2566 |
+ * config/i386/i386.c (ix86_set_indirect_branch_type): Also |
2567 |
+ set function_return_type. |
2568 |
+ (indirect_thunk_name): Add ret_p to indicate thunk for function |
2569 |
+ return. |
2570 |
+ (output_indirect_thunk_function): Pass false to |
2571 |
+ indirect_thunk_name. |
2572 |
+ (ix86_output_indirect_branch): Likewise. |
2573 |
+ (output_indirect_thunk_function): Create alias for function |
2574 |
+ return thunk if regno < 0. |
2575 |
+ (ix86_output_function_return): New function. |
2576 |
+ (ix86_handle_fndecl_attribute): Handle function_return. |
2577 |
+ (ix86_attribute_table): Add function_return. |
2578 |
+ * config/i386/i386.h (machine_function): Add |
2579 |
+ function_return_type. |
2580 |
+ * config/i386/i386.md (simple_return_internal): Use |
2581 |
+ ix86_output_function_return. |
2582 |
+ (simple_return_internal_long): Likewise. |
2583 |
+ * config/i386/i386.opt (mfunction-return=): New option. |
2584 |
+ (indirect_branch): Mention -mfunction-return=. |
2585 |
+ * doc/extend.texi: Document function_return function attribute. |
2586 |
+ * doc/invoke.texi: Document -mfunction-return= option. |
2587 |
+ |
2588 |
+gcc/testsuite/ |
2589 |
+ |
2590 |
+ * gcc.target/i386/indirect-thunk-1.c (dg-options): Add |
2591 |
+ -mfunction-return=keep. |
2592 |
+ * gcc.target/i386/indirect-thunk-2.c: Likewise. |
2593 |
+ * gcc.target/i386/indirect-thunk-3.c: Likewise. |
2594 |
+ * gcc.target/i386/indirect-thunk-4.c: Likewise. |
2595 |
+ * gcc.target/i386/indirect-thunk-5.c: Likewise. |
2596 |
+ * gcc.target/i386/indirect-thunk-6.c: Likewise. |
2597 |
+ * gcc.target/i386/indirect-thunk-7.c: Likewise. |
2598 |
+ * gcc.target/i386/indirect-thunk-attr-1.c: Likewise. |
2599 |
+ * gcc.target/i386/indirect-thunk-attr-2.c: Likewise. |
2600 |
+ * gcc.target/i386/indirect-thunk-attr-3.c: Likewise. |
2601 |
+ * gcc.target/i386/indirect-thunk-attr-4.c: Likewise. |
2602 |
+ * gcc.target/i386/indirect-thunk-attr-5.c: Likewise. |
2603 |
+ * gcc.target/i386/indirect-thunk-attr-6.c: Likewise. |
2604 |
+ * gcc.target/i386/indirect-thunk-attr-7.c: Likewise. |
2605 |
+ * gcc.target/i386/indirect-thunk-attr-8.c: Likewise. |
2606 |
+ * gcc.target/i386/indirect-thunk-bnd-1.c: Likewise. |
2607 |
+ * gcc.target/i386/indirect-thunk-bnd-2.c: Likewise. |
2608 |
+ * gcc.target/i386/indirect-thunk-bnd-3.c: Likewise. |
2609 |
+ * gcc.target/i386/indirect-thunk-bnd-4.c: Likewise. |
2610 |
+ * gcc.target/i386/indirect-thunk-extern-1.c: Likewise. |
2611 |
+ * gcc.target/i386/indirect-thunk-extern-2.c: Likewise. |
2612 |
+ * gcc.target/i386/indirect-thunk-extern-3.c: Likewise. |
2613 |
+ * gcc.target/i386/indirect-thunk-extern-4.c: Likewise. |
2614 |
+ * gcc.target/i386/indirect-thunk-extern-5.c: Likewise. |
2615 |
+ * gcc.target/i386/indirect-thunk-extern-6.c: Likewise. |
2616 |
+ * gcc.target/i386/indirect-thunk-extern-7.c: Likewise. |
2617 |
+ * gcc.target/i386/indirect-thunk-inline-1.c: Likewise. |
2618 |
+ * gcc.target/i386/indirect-thunk-inline-2.c: Likewise. |
2619 |
+ * gcc.target/i386/indirect-thunk-inline-3.c: Likewise. |
2620 |
+ * gcc.target/i386/indirect-thunk-inline-4.c: Likewise. |
2621 |
+ * gcc.target/i386/indirect-thunk-inline-5.c: Likewise. |
2622 |
+ * gcc.target/i386/indirect-thunk-inline-6.c: Likewise. |
2623 |
+ * gcc.target/i386/indirect-thunk-inline-7.c: Likewise. |
2624 |
+ * gcc.target/i386/ret-thunk-1.c: New test. |
2625 |
+ * gcc.target/i386/ret-thunk-10.c: Likewise. |
2626 |
+ * gcc.target/i386/ret-thunk-11.c: Likewise. |
2627 |
+ * gcc.target/i386/ret-thunk-12.c: Likewise. |
2628 |
+ * gcc.target/i386/ret-thunk-13.c: Likewise. |
2629 |
+ * gcc.target/i386/ret-thunk-14.c: Likewise. |
2630 |
+ * gcc.target/i386/ret-thunk-15.c: Likewise. |
2631 |
+ * gcc.target/i386/ret-thunk-16.c: Likewise. |
2632 |
+ * gcc.target/i386/ret-thunk-2.c: Likewise. |
2633 |
+ * gcc.target/i386/ret-thunk-3.c: Likewise. |
2634 |
+ * gcc.target/i386/ret-thunk-4.c: Likewise. |
2635 |
+ * gcc.target/i386/ret-thunk-5.c: Likewise. |
2636 |
+ * gcc.target/i386/ret-thunk-6.c: Likewise. |
2637 |
+ * gcc.target/i386/ret-thunk-7.c: Likewise. |
2638 |
+ * gcc.target/i386/ret-thunk-8.c: Likewise. |
2639 |
+ * gcc.target/i386/ret-thunk-9.c: Likewise. |
2640 |
+--- |
2641 |
+ gcc/config/i386/i386-protos.h | 1 + |
2642 |
+ gcc/config/i386/i386.c | 149 ++++++++++++++++++++- |
2643 |
+ gcc/config/i386/i386.h | 3 + |
2644 |
+ gcc/config/i386/i386.md | 9 +- |
2645 |
+ gcc/config/i386/i386.opt | 6 +- |
2646 |
+ gcc/doc/extend.texi | 9 ++ |
2647 |
+ gcc/doc/invoke.texi | 13 +- |
2648 |
+ gcc/testsuite/gcc.target/i386/indirect-thunk-1.c | 2 +- |
2649 |
+ gcc/testsuite/gcc.target/i386/indirect-thunk-2.c | 2 +- |
2650 |
+ gcc/testsuite/gcc.target/i386/indirect-thunk-3.c | 2 +- |
2651 |
+ gcc/testsuite/gcc.target/i386/indirect-thunk-4.c | 2 +- |
2652 |
+ gcc/testsuite/gcc.target/i386/indirect-thunk-5.c | 2 +- |
2653 |
+ gcc/testsuite/gcc.target/i386/indirect-thunk-6.c | 2 +- |
2654 |
+ gcc/testsuite/gcc.target/i386/indirect-thunk-7.c | 2 +- |
2655 |
+ .../gcc.target/i386/indirect-thunk-attr-1.c | 2 +- |
2656 |
+ .../gcc.target/i386/indirect-thunk-attr-2.c | 2 +- |
2657 |
+ .../gcc.target/i386/indirect-thunk-attr-3.c | 2 +- |
2658 |
+ .../gcc.target/i386/indirect-thunk-attr-4.c | 2 +- |
2659 |
+ .../gcc.target/i386/indirect-thunk-attr-5.c | 2 +- |
2660 |
+ .../gcc.target/i386/indirect-thunk-attr-6.c | 2 +- |
2661 |
+ .../gcc.target/i386/indirect-thunk-attr-7.c | 2 +- |
2662 |
+ .../gcc.target/i386/indirect-thunk-attr-8.c | 2 +- |
2663 |
+ .../gcc.target/i386/indirect-thunk-bnd-1.c | 2 +- |
2664 |
+ .../gcc.target/i386/indirect-thunk-bnd-2.c | 2 +- |
2665 |
+ .../gcc.target/i386/indirect-thunk-bnd-3.c | 2 +- |
2666 |
+ .../gcc.target/i386/indirect-thunk-bnd-4.c | 2 +- |
2667 |
+ .../gcc.target/i386/indirect-thunk-extern-1.c | 2 +- |
2668 |
+ .../gcc.target/i386/indirect-thunk-extern-2.c | 2 +- |
2669 |
+ .../gcc.target/i386/indirect-thunk-extern-3.c | 2 +- |
2670 |
+ .../gcc.target/i386/indirect-thunk-extern-4.c | 2 +- |
2671 |
+ .../gcc.target/i386/indirect-thunk-extern-5.c | 2 +- |
2672 |
+ .../gcc.target/i386/indirect-thunk-extern-6.c | 2 +- |
2673 |
+ .../gcc.target/i386/indirect-thunk-extern-7.c | 2 +- |
2674 |
+ .../gcc.target/i386/indirect-thunk-inline-1.c | 2 +- |
2675 |
+ .../gcc.target/i386/indirect-thunk-inline-2.c | 2 +- |
2676 |
+ .../gcc.target/i386/indirect-thunk-inline-3.c | 2 +- |
2677 |
+ .../gcc.target/i386/indirect-thunk-inline-4.c | 2 +- |
2678 |
+ .../gcc.target/i386/indirect-thunk-inline-5.c | 2 +- |
2679 |
+ .../gcc.target/i386/indirect-thunk-inline-6.c | 2 +- |
2680 |
+ .../gcc.target/i386/indirect-thunk-inline-7.c | 2 +- |
2681 |
+ gcc/testsuite/gcc.target/i386/ret-thunk-1.c | 12 ++ |
2682 |
+ gcc/testsuite/gcc.target/i386/ret-thunk-10.c | 22 +++ |
2683 |
+ gcc/testsuite/gcc.target/i386/ret-thunk-11.c | 22 +++ |
2684 |
+ gcc/testsuite/gcc.target/i386/ret-thunk-12.c | 21 +++ |
2685 |
+ gcc/testsuite/gcc.target/i386/ret-thunk-13.c | 21 +++ |
2686 |
+ gcc/testsuite/gcc.target/i386/ret-thunk-14.c | 21 +++ |
2687 |
+ gcc/testsuite/gcc.target/i386/ret-thunk-15.c | 21 +++ |
2688 |
+ gcc/testsuite/gcc.target/i386/ret-thunk-16.c | 18 +++ |
2689 |
+ gcc/testsuite/gcc.target/i386/ret-thunk-2.c | 12 ++ |
2690 |
+ gcc/testsuite/gcc.target/i386/ret-thunk-3.c | 12 ++ |
2691 |
+ gcc/testsuite/gcc.target/i386/ret-thunk-4.c | 12 ++ |
2692 |
+ gcc/testsuite/gcc.target/i386/ret-thunk-5.c | 14 ++ |
2693 |
+ gcc/testsuite/gcc.target/i386/ret-thunk-6.c | 13 ++ |
2694 |
+ gcc/testsuite/gcc.target/i386/ret-thunk-7.c | 13 ++ |
2695 |
+ gcc/testsuite/gcc.target/i386/ret-thunk-8.c | 14 ++ |
2696 |
+ gcc/testsuite/gcc.target/i386/ret-thunk-9.c | 23 ++++ |
2697 |
+ 56 files changed, 478 insertions(+), 49 deletions(-) |
2698 |
+ create mode 100644 gcc/testsuite/gcc.target/i386/ret-thunk-1.c |
2699 |
+ create mode 100644 gcc/testsuite/gcc.target/i386/ret-thunk-10.c |
2700 |
+ create mode 100644 gcc/testsuite/gcc.target/i386/ret-thunk-11.c |
2701 |
+ create mode 100644 gcc/testsuite/gcc.target/i386/ret-thunk-12.c |
2702 |
+ create mode 100644 gcc/testsuite/gcc.target/i386/ret-thunk-13.c |
2703 |
+ create mode 100644 gcc/testsuite/gcc.target/i386/ret-thunk-14.c |
2704 |
+ create mode 100644 gcc/testsuite/gcc.target/i386/ret-thunk-15.c |
2705 |
+ create mode 100644 gcc/testsuite/gcc.target/i386/ret-thunk-16.c |
2706 |
+ create mode 100644 gcc/testsuite/gcc.target/i386/ret-thunk-2.c |
2707 |
+ create mode 100644 gcc/testsuite/gcc.target/i386/ret-thunk-3.c |
2708 |
+ create mode 100644 gcc/testsuite/gcc.target/i386/ret-thunk-4.c |
2709 |
+ create mode 100644 gcc/testsuite/gcc.target/i386/ret-thunk-5.c |
2710 |
+ create mode 100644 gcc/testsuite/gcc.target/i386/ret-thunk-6.c |
2711 |
+ create mode 100644 gcc/testsuite/gcc.target/i386/ret-thunk-7.c |
2712 |
+ create mode 100644 gcc/testsuite/gcc.target/i386/ret-thunk-8.c |
2713 |
+ create mode 100644 gcc/testsuite/gcc.target/i386/ret-thunk-9.c |
2714 |
+ |
2715 |
+diff -Naur gcc-7.2.0.orig/gcc/config/i386/i386-protos.h gcc-7.2.0/gcc/config/i386/i386-protos.h |
2716 |
+--- gcc-7.2.0.orig/gcc/config/i386/i386-protos.h 2018-01-15 19:51:30.252618154 -0800 |
2717 |
++++ gcc-7.2.0/gcc/config/i386/i386-protos.h 2018-01-15 19:51:44.370617901 -0800 |
2718 |
+@@ -316,6 +316,7 @@ |
2719 |
+ |
2720 |
+ extern const char * ix86_output_call_insn (rtx_insn *insn, rtx call_op); |
2721 |
+ extern const char * ix86_output_indirect_jmp (rtx call_op, bool ret_p); |
2722 |
++extern const char * ix86_output_function_return (bool long_p); |
2723 |
+ extern bool ix86_operands_ok_for_move_multiple (rtx *operands, bool load, |
2724 |
+ enum machine_mode mode); |
2725 |
+ |
2726 |
+diff -Naur gcc-7.2.0.orig/gcc/config/i386/i386.c gcc-7.2.0/gcc/config/i386/i386.c |
2727 |
+--- gcc-7.2.0.orig/gcc/config/i386/i386.c 2018-01-15 19:51:30.252618154 -0800 |
2728 |
++++ gcc-7.2.0/gcc/config/i386/i386.c 2018-01-15 19:54:59.663614404 -0800 |
2729 |
+@@ -7177,6 +7177,31 @@ |
2730 |
+ else |
2731 |
+ cfun->machine->indirect_branch_type = ix86_indirect_branch; |
2732 |
+ } |
2733 |
++ |
2734 |
++ if (cfun->machine->function_return_type == indirect_branch_unset) |
2735 |
++ { |
2736 |
++ tree attr = lookup_attribute ("function_return", |
2737 |
++ DECL_ATTRIBUTES (fndecl)); |
2738 |
++ if (attr != NULL) |
2739 |
++ { |
2740 |
++ tree args = TREE_VALUE (attr); |
2741 |
++ if (args == NULL) |
2742 |
++ gcc_unreachable (); |
2743 |
++ tree cst = TREE_VALUE (args); |
2744 |
++ if (strcmp (TREE_STRING_POINTER (cst), "keep") == 0) |
2745 |
++ cfun->machine->function_return_type = indirect_branch_keep; |
2746 |
++ else if (strcmp (TREE_STRING_POINTER (cst), "thunk") == 0) |
2747 |
++ cfun->machine->function_return_type = indirect_branch_thunk; |
2748 |
++ else if (strcmp (TREE_STRING_POINTER (cst), "thunk-inline") == 0) |
2749 |
++ cfun->machine->function_return_type = indirect_branch_thunk_inline; |
2750 |
++ else if (strcmp (TREE_STRING_POINTER (cst), "thunk-extern") == 0) |
2751 |
++ cfun->machine->function_return_type = indirect_branch_thunk_extern; |
2752 |
++ else |
2753 |
++ gcc_unreachable (); |
2754 |
++ } |
2755 |
++ else |
2756 |
++ cfun->machine->function_return_type = ix86_function_return; |
2757 |
++ } |
2758 |
+ } |
2759 |
+ |
2760 |
+ /* Establish appropriate back-end context for processing the function |
2761 |
+@@ -11979,8 +12004,12 @@ |
2762 |
+ /* Fills in the label name that should be used for the indirect thunk. */ |
2763 |
+ |
2764 |
+ static void |
2765 |
+-indirect_thunk_name (char name[32], int regno, bool need_bnd_p) |
2766 |
++indirect_thunk_name (char name[32], int regno, bool need_bnd_p, |
2767 |
++ bool ret_p) |
2768 |
+ { |
2769 |
++ if (regno >= 0 && ret_p) |
2770 |
++ gcc_unreachable (); |
2771 |
++ |
2772 |
+ if (USE_HIDDEN_LINKONCE) |
2773 |
+ { |
2774 |
+ const char *bnd = need_bnd_p ? "_bnd" : ""; |
2775 |
+@@ -11995,7 +12024,10 @@ |
2776 |
+ bnd, reg_prefix, reg_names[regno]); |
2777 |
+ } |
2778 |
+ else |
2779 |
+- sprintf (name, "__x86_indirect_thunk%s", bnd); |
2780 |
++ { |
2781 |
++ const char *ret = ret_p ? "return" : "indirect"; |
2782 |
++ sprintf (name, "__x86_%s_thunk%s", ret, bnd); |
2783 |
++ } |
2784 |
+ } |
2785 |
+ else |
2786 |
+ { |
2787 |
+@@ -12008,10 +12040,20 @@ |
2788 |
+ } |
2789 |
+ else |
2790 |
+ { |
2791 |
+- if (need_bnd_p) |
2792 |
+- ASM_GENERATE_INTERNAL_LABEL (name, "LITB", 0); |
2793 |
++ if (ret_p) |
2794 |
++ { |
2795 |
++ if (need_bnd_p) |
2796 |
++ ASM_GENERATE_INTERNAL_LABEL (name, "LRTB", 0); |
2797 |
++ else |
2798 |
++ ASM_GENERATE_INTERNAL_LABEL (name, "LRT", 0); |
2799 |
++ } |
2800 |
+ else |
2801 |
+- ASM_GENERATE_INTERNAL_LABEL (name, "LIT", 0); |
2802 |
++ { |
2803 |
++ if (need_bnd_p) |
2804 |
++ ASM_GENERATE_INTERNAL_LABEL (name, "LITB", 0); |
2805 |
++ else |
2806 |
++ ASM_GENERATE_INTERNAL_LABEL (name, "LIT", 0); |
2807 |
++ } |
2808 |
+ } |
2809 |
+ } |
2810 |
+ } |
2811 |
+@@ -12106,7 +12148,7 @@ |
2812 |
+ tree decl; |
2813 |
+ |
2814 |
+ /* Create __x86_indirect_thunk/__x86_indirect_thunk_bnd. */ |
2815 |
+- indirect_thunk_name (name, regno, need_bnd_p); |
2816 |
++ indirect_thunk_name (name, regno, need_bnd_p, false); |
2817 |
+ decl = build_decl (BUILTINS_LOCATION, FUNCTION_DECL, |
2818 |
+ get_identifier (name), |
2819 |
+ build_function_type_list (void_type_node, NULL_TREE)); |
2820 |
+@@ -12149,6 +12191,35 @@ |
2821 |
+ ASM_OUTPUT_LABEL (asm_out_file, name); |
2822 |
+ } |
2823 |
+ |
2824 |
++ if (regno < 0) |
2825 |
++ { |
2826 |
++ /* Create alias for __x86.return_thunk/__x86.return_thunk_bnd. */ |
2827 |
++ char alias[32]; |
2828 |
++ |
2829 |
++ indirect_thunk_name (alias, regno, need_bnd_p, true); |
2830 |
++ ASM_OUTPUT_DEF (asm_out_file, alias, name); |
2831 |
++#if TARGET_MACHO |
2832 |
++ if (TARGET_MACHO) |
2833 |
++ { |
2834 |
++ fputs ("\t.weak_definition\t", asm_out_file); |
2835 |
++ assemble_name (asm_out_file, alias); |
2836 |
++ fputs ("\n\t.private_extern\t", asm_out_file); |
2837 |
++ assemble_name (asm_out_file, alias); |
2838 |
++ putc ('\n', asm_out_file); |
2839 |
++ } |
2840 |
++#else |
2841 |
++ if (USE_HIDDEN_LINKONCE) |
2842 |
++ { |
2843 |
++ fputs ("\t.globl\t", asm_out_file); |
2844 |
++ assemble_name (asm_out_file, alias); |
2845 |
++ putc ('\n', asm_out_file); |
2846 |
++ fputs ("\t.hidden\t", asm_out_file); |
2847 |
++ assemble_name (asm_out_file, alias); |
2848 |
++ putc ('\n', asm_out_file); |
2849 |
++ } |
2850 |
++#endif |
2851 |
++ } |
2852 |
++ |
2853 |
+ DECL_INITIAL (decl) = make_node (BLOCK); |
2854 |
+ current_function_decl = decl; |
2855 |
+ allocate_struct_function (decl, false); |
2856 |
+@@ -28766,7 +28837,7 @@ |
2857 |
+ else |
2858 |
+ indirect_thunks_used |= 1 << i; |
2859 |
+ } |
2860 |
+- indirect_thunk_name (thunk_name_buf, regno, need_bnd_p); |
2861 |
++ indirect_thunk_name (thunk_name_buf, regno, need_bnd_p, false); |
2862 |
+ thunk_name = thunk_name_buf; |
2863 |
+ } |
2864 |
+ else |
2865 |
+@@ -28875,7 +28946,7 @@ |
2866 |
+ else |
2867 |
+ indirect_thunk_needed = true; |
2868 |
+ } |
2869 |
+- indirect_thunk_name (thunk_name_buf, regno, need_bnd_p); |
2870 |
++ indirect_thunk_name (thunk_name_buf, regno, need_bnd_p, false); |
2871 |
+ thunk_name = thunk_name_buf; |
2872 |
+ } |
2873 |
+ else |
2874 |
+@@ -29010,6 +29081,46 @@ |
2875 |
+ return "%!jmp\t%A0"; |
2876 |
+ } |
2877 |
+ |
2878 |
++/* Output function return. CALL_OP is the jump target. Add a REP |
2879 |
++ prefix to RET if LONG_P is true and function return is kept. */ |
2880 |
++ |
2881 |
++const char * |
2882 |
++ix86_output_function_return (bool long_p) |
2883 |
++{ |
2884 |
++ if (cfun->machine->function_return_type != indirect_branch_keep) |
2885 |
++ { |
2886 |
++ char thunk_name[32]; |
2887 |
++ bool need_bnd_p = ix86_bnd_prefixed_insn_p (current_output_insn); |
2888 |
++ |
2889 |
++ if (cfun->machine->function_return_type |
2890 |
++ != indirect_branch_thunk_inline) |
2891 |
++ { |
2892 |
++ bool need_thunk = (cfun->machine->function_return_type |
2893 |
++ == indirect_branch_thunk); |
2894 |
++ indirect_thunk_name (thunk_name, -1, need_bnd_p, true); |
2895 |
++ if (need_bnd_p) |
2896 |
++ { |
2897 |
++ indirect_thunk_bnd_needed |= need_thunk; |
2898 |
++ fprintf (asm_out_file, "\tbnd jmp\t%s\n", thunk_name); |
2899 |
++ } |
2900 |
++ else |
2901 |
++ { |
2902 |
++ indirect_thunk_needed |= need_thunk; |
2903 |
++ fprintf (asm_out_file, "\tjmp\t%s\n", thunk_name); |
2904 |
++ } |
2905 |
++ } |
2906 |
++ else |
2907 |
++ output_indirect_thunk (need_bnd_p, -1); |
2908 |
++ |
2909 |
++ return ""; |
2910 |
++ } |
2911 |
++ |
2912 |
++ if (!long_p || ix86_bnd_prefixed_insn_p (current_output_insn)) |
2913 |
++ return "%!ret"; |
2914 |
++ |
2915 |
++ return "rep%; ret"; |
2916 |
++} |
2917 |
++ |
2918 |
+ /* Output the assembly for a call instruction. */ |
2919 |
+ |
2920 |
+ const char * |
2921 |
+@@ -42066,6 +42177,28 @@ |
2922 |
+ } |
2923 |
+ } |
2924 |
+ |
2925 |
++ if (is_attribute_p ("function_return", name)) |
2926 |
++ { |
2927 |
++ tree cst = TREE_VALUE (args); |
2928 |
++ if (TREE_CODE (cst) != STRING_CST) |
2929 |
++ { |
2930 |
++ warning (OPT_Wattributes, |
2931 |
++ "%qE attribute requires a string constant argument", |
2932 |
++ name); |
2933 |
++ *no_add_attrs = true; |
2934 |
++ } |
2935 |
++ else if (strcmp (TREE_STRING_POINTER (cst), "keep") != 0 |
2936 |
++ && strcmp (TREE_STRING_POINTER (cst), "thunk") != 0 |
2937 |
++ && strcmp (TREE_STRING_POINTER (cst), "thunk-inline") != 0 |
2938 |
++ && strcmp (TREE_STRING_POINTER (cst), "thunk-extern") != 0) |
2939 |
++ { |
2940 |
++ warning (OPT_Wattributes, |
2941 |
++ "argument to %qE attribute is not " |
2942 |
++ "(keep|thunk|thunk-inline|thunk-extern)", name); |
2943 |
++ *no_add_attrs = true; |
2944 |
++ } |
2945 |
++ } |
2946 |
++ |
2947 |
+ return NULL_TREE; |
2948 |
+ } |
2949 |
+ |
2950 |
+@@ -46362,6 +46495,8 @@ |
2951 |
+ ix86_handle_no_caller_saved_registers_attribute, false }, |
2952 |
+ { "indirect_branch", 1, 1, true, false, false, |
2953 |
+ ix86_handle_fndecl_attribute, NULL }, |
2954 |
++ { "function_return", 1, 1, true, false, false, |
2955 |
++ ix86_handle_fndecl_attribute, NULL }, |
2956 |
+ |
2957 |
+ /* End element. */ |
2958 |
+ { NULL, 0, 0, false, false, false, NULL, false } |
2959 |
+diff -Naur gcc-7.2.0.orig/gcc/config/i386/i386.h gcc-7.2.0/gcc/config/i386/i386.h |
2960 |
+--- gcc-7.2.0.orig/gcc/config/i386/i386.h 2018-01-15 19:51:30.252618154 -0800 |
2961 |
++++ gcc-7.2.0/gcc/config/i386/i386.h 2018-01-15 19:51:44.381617901 -0800 |
2962 |
+@@ -2611,6 +2611,9 @@ |
2963 |
+ "indirect_jump" or "tablejump". */ |
2964 |
+ BOOL_BITFIELD has_local_indirect_jump : 1; |
2965 |
+ |
2966 |
++ /* How to generate function return. */ |
2967 |
++ ENUM_BITFIELD(indirect_branch) function_return_type : 3; |
2968 |
++ |
2969 |
+ /* If true, the current function is a function specified with |
2970 |
+ the "interrupt" or "no_caller_saved_registers" attribute. */ |
2971 |
+ BOOL_BITFIELD no_caller_saved_registers : 1; |
2972 |
+diff -Naur gcc-7.2.0.orig/gcc/config/i386/i386.md gcc-7.2.0/gcc/config/i386/i386.md |
2973 |
+--- gcc-7.2.0.orig/gcc/config/i386/i386.md 2018-01-15 19:51:30.252618154 -0800 |
2974 |
++++ gcc-7.2.0/gcc/config/i386/i386.md 2018-01-15 19:51:44.385617901 -0800 |
2975 |
+@@ -12298,7 +12298,7 @@ |
2976 |
+ (define_insn "simple_return_internal" |
2977 |
+ [(simple_return)] |
2978 |
+ "reload_completed" |
2979 |
+- "%!ret" |
2980 |
++ "* return ix86_output_function_return (false);" |
2981 |
+ [(set_attr "length" "1") |
2982 |
+ (set_attr "atom_unit" "jeu") |
2983 |
+ (set_attr "length_immediate" "0") |
2984 |
+@@ -12320,12 +12320,7 @@ |
2985 |
+ [(simple_return) |
2986 |
+ (unspec [(const_int 0)] UNSPEC_REP)] |
2987 |
+ "reload_completed" |
2988 |
+-{ |
2989 |
+- if (ix86_bnd_prefixed_insn_p (insn)) |
2990 |
+- return "%!ret"; |
2991 |
+- |
2992 |
+- return "rep%; ret"; |
2993 |
+-} |
2994 |
++ "* return ix86_output_function_return (true);" |
2995 |
+ [(set_attr "length" "2") |
2996 |
+ (set_attr "atom_unit" "jeu") |
2997 |
+ (set_attr "length_immediate" "0") |
2998 |
+diff -Naur gcc-7.2.0.orig/gcc/config/i386/i386.opt gcc-7.2.0/gcc/config/i386/i386.opt |
2999 |
+--- gcc-7.2.0.orig/gcc/config/i386/i386.opt 2018-01-15 19:51:30.252618154 -0800 |
3000 |
++++ gcc-7.2.0/gcc/config/i386/i386.opt 2018-01-15 19:51:44.386617901 -0800 |
3001 |
+@@ -932,9 +932,13 @@ |
3002 |
+ Target Report RejectNegative Joined Enum(indirect_branch) Var(ix86_indirect_branch) Init(indirect_branch_keep) |
3003 |
+ Convert indirect call and jump to call and return thunks. |
3004 |
+ |
3005 |
++mfunction-return= |
3006 |
++Target Report RejectNegative Joined Enum(indirect_branch) Var(ix86_function_return) Init(indirect_branch_keep) |
3007 |
++Convert function return to call and return thunk. |
3008 |
++ |
3009 |
+ Enum |
3010 |
+ Name(indirect_branch) Type(enum indirect_branch) |
3011 |
+-Known indirect branch choices (for use with the -mindirect-branch= option): |
3012 |
++Known indirect branch choices (for use with the -mindirect-branch=/-mfunction-return= options): |
3013 |
+ |
3014 |
+ EnumValue |
3015 |
+ Enum(indirect_branch) String(keep) Value(indirect_branch_keep) |
3016 |
+diff -Naur gcc-7.2.0.orig/gcc/doc/extend.texi gcc-7.2.0/gcc/doc/extend.texi |
3017 |
+--- gcc-7.2.0.orig/gcc/doc/extend.texi 2018-01-15 19:51:28.536618185 -0800 |
3018 |
++++ gcc-7.2.0/gcc/doc/extend.texi 2018-01-15 19:51:44.392617901 -0800 |
3019 |
+@@ -5550,6 +5550,15 @@ |
3020 |
+ indirect call and jump to inlined call and return thunk. |
3021 |
+ @samp{thunk-extern} converts indirect call and jump to external call |
3022 |
+ and return thunk provided in a separate object file. |
3023 |
++ |
3024 |
++@item function_return("@var{choice}") |
3025 |
++@cindex @code{function_return} function attribute, x86 |
3026 |
++On x86 targets, the @code{function_return} attribute causes the compiler |
3027 |
++to convert function return with @var{choice}. @samp{keep} keeps function |
3028 |
++return unmodified. @samp{thunk} converts function return to call and |
3029 |
++return thunk. @samp{thunk-inline} converts function return to inlined |
3030 |
++call and return thunk. @samp{thunk-extern} converts function return to |
3031 |
++external call and return thunk provided in a separate object file. |
3032 |
+ @end table |
3033 |
+ |
3034 |
+ On the x86, the inliner does not inline a |
3035 |
+diff -Naur gcc-7.2.0.orig/gcc/doc/invoke.texi gcc-7.2.0/gcc/doc/invoke.texi |
3036 |
+--- gcc-7.2.0.orig/gcc/doc/invoke.texi 2018-01-15 19:51:28.537618185 -0800 |
3037 |
++++ gcc-7.2.0/gcc/doc/invoke.texi 2018-01-15 19:51:44.397617901 -0800 |
3038 |
+@@ -1211,7 +1211,7 @@ |
3039 |
+ -mavx256-split-unaligned-load -mavx256-split-unaligned-store @gol |
3040 |
+ -malign-data=@var{type} -mstack-protector-guard=@var{guard} @gol |
3041 |
+ -mmitigate-rop -mgeneral-regs-only @gol |
3042 |
+--mindirect-branch=@var{choice}} |
3043 |
++-mindirect-branch=@var{choice} -mfunction-return==@var{choice}} |
3044 |
+ |
3045 |
+ @emph{x86 Windows Options} |
3046 |
+ @gccoptlist{-mconsole -mcygwin -mno-cygwin -mdll @gol |
3047 |
+@@ -25660,6 +25660,17 @@ |
3048 |
+ You can control this behavior for a specific function by using the |
3049 |
+ function attribute @code{indirect_branch}. @xref{Function Attributes}. |
3050 |
+ |
3051 |
++@item -mfunction-return=@var{choice} |
3052 |
++@opindex -mfunction-return |
3053 |
++Convert function return with @var{choice}. The default is @samp{keep}, |
3054 |
++which keeps function return unmodified. @samp{thunk} converts function |
3055 |
++return to call and return thunk. @samp{thunk-inline} converts function |
3056 |
++return to inlined call and return thunk. @samp{thunk-extern} converts |
3057 |
++function return to external call and return thunk provided in a separate |
3058 |
++object file. You can control this behavior for a specific function by |
3059 |
++using the function attribute @code{function_return}. |
3060 |
++@xref{Function Attributes}. |
3061 |
++ |
3062 |
+ @end table |
3063 |
+ |
3064 |
+ These @samp{-m} switches are supported in addition to the above |
3065 |
+diff -Naur gcc-7.2.0.orig/gcc/testsuite/gcc.target/i386/indirect-thunk-1.c gcc-7.2.0/gcc/testsuite/gcc.target/i386/indirect-thunk-1.c |
3066 |
+--- gcc-7.2.0.orig/gcc/testsuite/gcc.target/i386/indirect-thunk-1.c 2018-01-15 19:51:28.901618178 -0800 |
3067 |
++++ gcc-7.2.0/gcc/testsuite/gcc.target/i386/indirect-thunk-1.c 2018-01-15 19:51:44.398617901 -0800 |
3068 |
+@@ -1,5 +1,5 @@ |
3069 |
+ /* { dg-do compile } */ |
3070 |
+-/* { dg-options "-O2 -mindirect-branch=thunk -fno-pic" } */ |
3071 |
++/* { dg-options "-O2 -mfunction-return=keep -mindirect-branch=thunk -fno-pic" } */ |
3072 |
+ |
3073 |
+ typedef void (*dispatch_t)(long offset); |
3074 |
+ |
3075 |
+diff -Naur gcc-7.2.0.orig/gcc/testsuite/gcc.target/i386/indirect-thunk-2.c gcc-7.2.0/gcc/testsuite/gcc.target/i386/indirect-thunk-2.c |
3076 |
+--- gcc-7.2.0.orig/gcc/testsuite/gcc.target/i386/indirect-thunk-2.c 2018-01-15 19:51:28.901618178 -0800 |
3077 |
++++ gcc-7.2.0/gcc/testsuite/gcc.target/i386/indirect-thunk-2.c 2018-01-15 19:51:44.398617901 -0800 |
3078 |
+@@ -1,5 +1,5 @@ |
3079 |
+ /* { dg-do compile } */ |
3080 |
+-/* { dg-options "-O2 -mindirect-branch=thunk -fno-pic" } */ |
3081 |
++/* { dg-options "-O2 -mfunction-return=keep -mindirect-branch=thunk -fno-pic" } */ |
3082 |
+ |
3083 |
+ typedef void (*dispatch_t)(long offset); |
3084 |
+ |
3085 |
+diff -Naur gcc-7.2.0.orig/gcc/testsuite/gcc.target/i386/indirect-thunk-3.c gcc-7.2.0/gcc/testsuite/gcc.target/i386/indirect-thunk-3.c |
3086 |
+--- gcc-7.2.0.orig/gcc/testsuite/gcc.target/i386/indirect-thunk-3.c 2018-01-15 19:51:28.901618178 -0800 |
3087 |
++++ gcc-7.2.0/gcc/testsuite/gcc.target/i386/indirect-thunk-3.c 2018-01-15 19:51:44.398617901 -0800 |
3088 |
+@@ -1,5 +1,5 @@ |
3089 |
+ /* { dg-do compile } */ |
3090 |
+-/* { dg-options "-O2 -mindirect-branch=thunk -fno-pic" } */ |
3091 |
++/* { dg-options "-O2 -mfunction-return=keep -mindirect-branch=thunk -fno-pic" } */ |
3092 |
+ |
3093 |
+ typedef void (*dispatch_t)(long offset); |
3094 |
+ |
3095 |
+diff -Naur gcc-7.2.0.orig/gcc/testsuite/gcc.target/i386/indirect-thunk-4.c gcc-7.2.0/gcc/testsuite/gcc.target/i386/indirect-thunk-4.c |
3096 |
+--- gcc-7.2.0.orig/gcc/testsuite/gcc.target/i386/indirect-thunk-4.c 2018-01-15 19:51:28.901618178 -0800 |
3097 |
++++ gcc-7.2.0/gcc/testsuite/gcc.target/i386/indirect-thunk-4.c 2018-01-15 19:51:44.398617901 -0800 |
3098 |
+@@ -1,5 +1,5 @@ |
3099 |
+ /* { dg-do compile } */ |
3100 |
+-/* { dg-options "-O2 -mindirect-branch=thunk -fno-pic" } */ |
3101 |
++/* { dg-options "-O2 -mfunction-return=keep -mindirect-branch=thunk -fno-pic" } */ |
3102 |
+ |
3103 |
+ typedef void (*dispatch_t)(long offset); |
3104 |
+ |
3105 |
+diff -Naur gcc-7.2.0.orig/gcc/testsuite/gcc.target/i386/indirect-thunk-5.c gcc-7.2.0/gcc/testsuite/gcc.target/i386/indirect-thunk-5.c |
3106 |
+--- gcc-7.2.0.orig/gcc/testsuite/gcc.target/i386/indirect-thunk-5.c 2018-01-15 19:51:28.901618178 -0800 |
3107 |
++++ gcc-7.2.0/gcc/testsuite/gcc.target/i386/indirect-thunk-5.c 2018-01-15 19:51:44.398617901 -0800 |
3108 |
+@@ -1,5 +1,5 @@ |
3109 |
+ /* { dg-do compile { target *-*-linux* } } */ |
3110 |
+-/* { dg-options "-O2 -fpic -fno-plt -mindirect-branch=thunk" } */ |
3111 |
++/* { dg-options "-O2 -mfunction-return=keep -fpic -fno-plt -mindirect-branch=thunk" } */ |
3112 |
+ |
3113 |
+ extern void bar (void); |
3114 |
+ |
3115 |
+diff -Naur gcc-7.2.0.orig/gcc/testsuite/gcc.target/i386/indirect-thunk-6.c gcc-7.2.0/gcc/testsuite/gcc.target/i386/indirect-thunk-6.c |
3116 |
+--- gcc-7.2.0.orig/gcc/testsuite/gcc.target/i386/indirect-thunk-6.c 2018-01-15 19:51:28.901618178 -0800 |
3117 |
++++ gcc-7.2.0/gcc/testsuite/gcc.target/i386/indirect-thunk-6.c 2018-01-15 19:51:44.398617901 -0800 |
3118 |
+@@ -1,5 +1,5 @@ |
3119 |
+ /* { dg-do compile { target *-*-linux* } } */ |
3120 |
+-/* { dg-options "-O2 -fpic -fno-plt -mindirect-branch=thunk" } */ |
3121 |
++/* { dg-options "-O2 -mfunction-return=keep -fpic -fno-plt -mindirect-branch=thunk" } */ |
3122 |
+ |
3123 |
+ extern void bar (void); |
3124 |
+ |
3125 |
+diff -Naur gcc-7.2.0.orig/gcc/testsuite/gcc.target/i386/indirect-thunk-7.c gcc-7.2.0/gcc/testsuite/gcc.target/i386/indirect-thunk-7.c |
3126 |
+--- gcc-7.2.0.orig/gcc/testsuite/gcc.target/i386/indirect-thunk-7.c 2018-01-15 19:51:28.901618178 -0800 |
3127 |
++++ gcc-7.2.0/gcc/testsuite/gcc.target/i386/indirect-thunk-7.c 2018-01-15 19:51:44.398617901 -0800 |
3128 |
+@@ -1,5 +1,5 @@ |
3129 |
+ /* { dg-do compile } */ |
3130 |
+-/* { dg-options "-O2 -mindirect-branch=thunk -fno-pic" } */ |
3131 |
++/* { dg-options "-O2 -mfunction-return=keep -mindirect-branch=thunk -fno-pic" } */ |
3132 |
+ |
3133 |
+ void func0 (void); |
3134 |
+ void func1 (void); |
3135 |
+diff -Naur gcc-7.2.0.orig/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-1.c gcc-7.2.0/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-1.c |
3136 |
+--- gcc-7.2.0.orig/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-1.c 2018-01-15 19:51:28.901618178 -0800 |
3137 |
++++ gcc-7.2.0/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-1.c 2018-01-15 19:51:44.398617901 -0800 |
3138 |
+@@ -1,5 +1,5 @@ |
3139 |
+ /* { dg-do compile } */ |
3140 |
+-/* { dg-options "-O2 -fno-pic" } */ |
3141 |
++/* { dg-options "-O2 -mfunction-return=keep -fno-pic" } */ |
3142 |
+ |
3143 |
+ typedef void (*dispatch_t)(long offset); |
3144 |
+ |
3145 |
+diff -Naur gcc-7.2.0.orig/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-2.c gcc-7.2.0/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-2.c |
3146 |
+--- gcc-7.2.0.orig/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-2.c 2018-01-15 19:51:28.901618178 -0800 |
3147 |
++++ gcc-7.2.0/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-2.c 2018-01-15 19:51:44.398617901 -0800 |
3148 |
+@@ -1,5 +1,5 @@ |
3149 |
+ /* { dg-do compile } */ |
3150 |
+-/* { dg-options "-O2 -fno-pic" } */ |
3151 |
++/* { dg-options "-O2 -mfunction-return=keep -fno-pic" } */ |
3152 |
+ |
3153 |
+ typedef void (*dispatch_t)(long offset); |
3154 |
+ |
3155 |
+diff -Naur gcc-7.2.0.orig/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-3.c gcc-7.2.0/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-3.c |
3156 |
+--- gcc-7.2.0.orig/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-3.c 2018-01-15 19:51:28.902618178 -0800 |
3157 |
++++ gcc-7.2.0/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-3.c 2018-01-15 19:51:44.398617901 -0800 |
3158 |
+@@ -1,5 +1,5 @@ |
3159 |
+ /* { dg-do compile } */ |
3160 |
+-/* { dg-options "-O2 -fno-pic" } */ |
3161 |
++/* { dg-options "-O2 -mfunction-return=keep -fno-pic" } */ |
3162 |
+ |
3163 |
+ typedef void (*dispatch_t)(long offset); |
3164 |
+ |
3165 |
+diff -Naur gcc-7.2.0.orig/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-4.c gcc-7.2.0/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-4.c |
3166 |
+--- gcc-7.2.0.orig/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-4.c 2018-01-15 19:51:28.902618178 -0800 |
3167 |
++++ gcc-7.2.0/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-4.c 2018-01-15 19:51:44.399617901 -0800 |
3168 |
+@@ -1,5 +1,5 @@ |
3169 |
+ /* { dg-do compile } */ |
3170 |
+-/* { dg-options "-O2 -fno-pic" } */ |
3171 |
++/* { dg-options "-O2 -mfunction-return=keep -fno-pic" } */ |
3172 |
+ |
3173 |
+ typedef void (*dispatch_t)(long offset); |
3174 |
+ |
3175 |
+diff -Naur gcc-7.2.0.orig/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-5.c gcc-7.2.0/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-5.c |
3176 |
+--- gcc-7.2.0.orig/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-5.c 2018-01-15 19:51:28.902618178 -0800 |
3177 |
++++ gcc-7.2.0/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-5.c 2018-01-15 19:51:44.399617901 -0800 |
3178 |
+@@ -1,5 +1,5 @@ |
3179 |
+ /* { dg-do compile } */ |
3180 |
+-/* { dg-options "-O2 -fno-pic" } */ |
3181 |
++/* { dg-options "-O2 -mfunction-return=keep -fno-pic" } */ |
3182 |
+ |
3183 |
+ typedef void (*dispatch_t)(long offset); |
3184 |
+ |
3185 |
+diff -Naur gcc-7.2.0.orig/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-6.c gcc-7.2.0/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-6.c |
3186 |
+--- gcc-7.2.0.orig/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-6.c 2018-01-15 19:51:28.901618178 -0800 |
3187 |
++++ gcc-7.2.0/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-6.c 2018-01-15 19:51:44.399617901 -0800 |
3188 |
+@@ -1,5 +1,5 @@ |
3189 |
+ /* { dg-do compile } */ |
3190 |
+-/* { dg-options "-O2 -fno-pic" } */ |
3191 |
++/* { dg-options "-O2 -mfunction-return=keep -fno-pic" } */ |
3192 |
+ |
3193 |
+ typedef void (*dispatch_t)(long offset); |
3194 |
+ |
3195 |
+diff -Naur gcc-7.2.0.orig/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-7.c gcc-7.2.0/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-7.c |
3196 |
+--- gcc-7.2.0.orig/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-7.c 2018-01-15 19:51:28.902618178 -0800 |
3197 |
++++ gcc-7.2.0/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-7.c 2018-01-15 19:51:44.399617901 -0800 |
3198 |
+@@ -1,5 +1,5 @@ |
3199 |
+ /* { dg-do compile } */ |
3200 |
+-/* { dg-options "-O2 -fno-pic" } */ |
3201 |
++/* { dg-options "-O2 -mfunction-return=keep -fno-pic" } */ |
3202 |
+ |
3203 |
+ void func0 (void); |
3204 |
+ void func1 (void); |
3205 |
+diff -Naur gcc-7.2.0.orig/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-8.c gcc-7.2.0/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-8.c |
3206 |
+--- gcc-7.2.0.orig/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-8.c 2018-01-15 19:51:28.902618178 -0800 |
3207 |
++++ gcc-7.2.0/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-8.c 2018-01-15 19:51:44.399617901 -0800 |
3208 |
+@@ -1,5 +1,5 @@ |
3209 |
+ /* { dg-do compile } */ |
3210 |
+-/* { dg-options "-O2 -mindirect-branch=thunk -fno-pic" } */ |
3211 |
++/* { dg-options "-O2 -mfunction-return=keep -mindirect-branch=thunk -fno-pic" } */ |
3212 |
+ |
3213 |
+ void func0 (void); |
3214 |
+ void func1 (void); |
3215 |
+diff -Naur gcc-7.2.0.orig/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-1.c gcc-7.2.0/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-1.c |
3216 |
+--- gcc-7.2.0.orig/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-1.c 2018-01-15 19:51:28.902618178 -0800 |
3217 |
++++ gcc-7.2.0/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-1.c 2018-01-15 19:51:44.399617901 -0800 |
3218 |
+@@ -1,5 +1,5 @@ |
3219 |
+ /* { dg-do compile { target { ! x32 } } } */ |
3220 |
+-/* { dg-options "-O2 -mindirect-branch=thunk -fcheck-pointer-bounds -mmpx -fno-pic" } */ |
3221 |
++/* { dg-options "-O2 -mfunction-return=keep -mindirect-branch=thunk -fcheck-pointer-bounds -mmpx -fno-pic" } */ |
3222 |
+ |
3223 |
+ void (*dispatch) (char *); |
3224 |
+ char buf[10]; |
3225 |
+diff -Naur gcc-7.2.0.orig/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-2.c gcc-7.2.0/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-2.c |
3226 |
+--- gcc-7.2.0.orig/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-2.c 2018-01-15 19:51:28.902618178 -0800 |
3227 |
++++ gcc-7.2.0/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-2.c 2018-01-15 19:51:44.399617901 -0800 |
3228 |
+@@ -1,5 +1,5 @@ |
3229 |
+ /* { dg-do compile { target { ! x32 } } } */ |
3230 |
+-/* { dg-options "-O2 -mindirect-branch=thunk -fcheck-pointer-bounds -mmpx -fno-pic" } */ |
3231 |
++/* { dg-options "-O2 -mfunction-return=keep -mindirect-branch=thunk -fcheck-pointer-bounds -mmpx -fno-pic" } */ |
3232 |
+ |
3233 |
+ void (*dispatch) (char *); |
3234 |
+ char buf[10]; |
3235 |
+diff -Naur gcc-7.2.0.orig/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-3.c gcc-7.2.0/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-3.c |
3236 |
+--- gcc-7.2.0.orig/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-3.c 2018-01-15 19:51:28.902618178 -0800 |
3237 |
++++ gcc-7.2.0/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-3.c 2018-01-15 19:51:44.399617901 -0800 |
3238 |
+@@ -1,5 +1,5 @@ |
3239 |
+ /* { dg-do compile { target { *-*-linux* && { ! x32 } } } } */ |
3240 |
+-/* { dg-options "-O2 -mindirect-branch=thunk -fcheck-pointer-bounds -mmpx -fpic -fno-plt" } */ |
3241 |
++/* { dg-options "-O2 -mfunction-return=keep -mindirect-branch=thunk -fcheck-pointer-bounds -mmpx -fpic -fno-plt" } */ |
3242 |
+ |
3243 |
+ void bar (char *); |
3244 |
+ char buf[10]; |
3245 |
+diff -Naur gcc-7.2.0.orig/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-4.c gcc-7.2.0/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-4.c |
3246 |
+--- gcc-7.2.0.orig/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-4.c 2018-01-15 19:51:28.902618178 -0800 |
3247 |
++++ gcc-7.2.0/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-4.c 2018-01-15 19:51:44.399617901 -0800 |
3248 |
+@@ -1,5 +1,5 @@ |
3249 |
+ /* { dg-do compile { target { *-*-linux* && { ! x32 } } } } */ |
3250 |
+-/* { dg-options "-O2 -mindirect-branch=thunk -fcheck-pointer-bounds -mmpx -fpic -fno-plt" } */ |
3251 |
++/* { dg-options "-O2 -mfunction-return=keep -mindirect-branch=thunk -fcheck-pointer-bounds -mmpx -fpic -fno-plt" } */ |
3252 |
+ |
3253 |
+ void bar (char *); |
3254 |
+ char buf[10]; |
3255 |
+diff -Naur gcc-7.2.0.orig/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-1.c gcc-7.2.0/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-1.c |
3256 |
+--- gcc-7.2.0.orig/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-1.c 2018-01-15 19:51:28.902618178 -0800 |
3257 |
++++ gcc-7.2.0/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-1.c 2018-01-15 19:51:44.399617901 -0800 |
3258 |
+@@ -1,5 +1,5 @@ |
3259 |
+ /* { dg-do compile } */ |
3260 |
+-/* { dg-options "-O2 -mindirect-branch=thunk-extern -fno-pic" } */ |
3261 |
++/* { dg-options "-O2 -mfunction-return=keep -mindirect-branch=thunk-extern -fno-pic" } */ |
3262 |
+ |
3263 |
+ typedef void (*dispatch_t)(long offset); |
3264 |
+ |
3265 |
+diff -Naur gcc-7.2.0.orig/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-2.c gcc-7.2.0/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-2.c |
3266 |
+--- gcc-7.2.0.orig/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-2.c 2018-01-15 19:51:28.902618178 -0800 |
3267 |
++++ gcc-7.2.0/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-2.c 2018-01-15 19:51:44.400617901 -0800 |
3268 |
+@@ -1,5 +1,5 @@ |
3269 |
+ /* { dg-do compile } */ |
3270 |
+-/* { dg-options "-O2 -mindirect-branch=thunk-extern -fno-pic" } */ |
3271 |
++/* { dg-options "-O2 -mfunction-return=keep -mindirect-branch=thunk-extern -fno-pic" } */ |
3272 |
+ |
3273 |
+ typedef void (*dispatch_t)(long offset); |
3274 |
+ |
3275 |
+diff -Naur gcc-7.2.0.orig/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-3.c gcc-7.2.0/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-3.c |
3276 |
+--- gcc-7.2.0.orig/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-3.c 2018-01-15 19:51:28.902618178 -0800 |
3277 |
++++ gcc-7.2.0/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-3.c 2018-01-15 19:51:44.400617901 -0800 |
3278 |
+@@ -1,5 +1,5 @@ |
3279 |
+ /* { dg-do compile } */ |
3280 |
+-/* { dg-options "-O2 -mindirect-branch=thunk-extern -fno-pic" } */ |
3281 |
++/* { dg-options "-O2 -mfunction-return=keep -mindirect-branch=thunk-extern -fno-pic" } */ |
3282 |
+ |
3283 |
+ typedef void (*dispatch_t)(long offset); |
3284 |
+ |
3285 |
+diff -Naur gcc-7.2.0.orig/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-4.c gcc-7.2.0/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-4.c |
3286 |
+--- gcc-7.2.0.orig/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-4.c 2018-01-15 19:51:28.902618178 -0800 |
3287 |
++++ gcc-7.2.0/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-4.c 2018-01-15 19:51:44.400617901 -0800 |
3288 |
+@@ -1,5 +1,5 @@ |
3289 |
+ /* { dg-do compile } */ |
3290 |
+-/* { dg-options "-O2 -mindirect-branch=thunk-extern -fno-pic" } */ |
3291 |
++/* { dg-options "-O2 -mfunction-return=keep -mindirect-branch=thunk-extern -fno-pic" } */ |
3292 |
+ |
3293 |
+ typedef void (*dispatch_t)(long offset); |
3294 |
+ |
3295 |
+diff -Naur gcc-7.2.0.orig/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-5.c gcc-7.2.0/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-5.c |
3296 |
+--- gcc-7.2.0.orig/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-5.c 2018-01-15 19:51:28.902618178 -0800 |
3297 |
++++ gcc-7.2.0/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-5.c 2018-01-15 19:51:44.400617901 -0800 |
3298 |
+@@ -1,5 +1,5 @@ |
3299 |
+ /* { dg-do compile { target *-*-linux* } } */ |
3300 |
+-/* { dg-options "-O2 -fpic -fno-plt -mindirect-branch=thunk-extern" } */ |
3301 |
++/* { dg-options "-O2 -mfunction-return=keep -fpic -fno-plt -mindirect-branch=thunk-extern" } */ |
3302 |
+ |
3303 |
+ extern void bar (void); |
3304 |
+ |
3305 |
+diff -Naur gcc-7.2.0.orig/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-6.c gcc-7.2.0/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-6.c |
3306 |
+--- gcc-7.2.0.orig/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-6.c 2018-01-15 19:51:28.902618178 -0800 |
3307 |
++++ gcc-7.2.0/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-6.c 2018-01-15 19:51:44.400617901 -0800 |
3308 |
+@@ -1,5 +1,5 @@ |
3309 |
+ /* { dg-do compile { target *-*-linux* } } */ |
3310 |
+-/* { dg-options "-O2 -fpic -fno-plt -mindirect-branch=thunk-extern" } */ |
3311 |
++/* { dg-options "-O2 -mfunction-return=keep -fpic -fno-plt -mindirect-branch=thunk-extern" } */ |
3312 |
+ |
3313 |
+ extern void bar (void); |
3314 |
+ |
3315 |
+diff -Naur gcc-7.2.0.orig/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-7.c gcc-7.2.0/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-7.c |
3316 |
+--- gcc-7.2.0.orig/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-7.c 2018-01-15 19:51:28.902618178 -0800 |
3317 |
++++ gcc-7.2.0/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-7.c 2018-01-15 19:51:44.400617901 -0800 |
3318 |
+@@ -1,5 +1,5 @@ |
3319 |
+ /* { dg-do compile } */ |
3320 |
+-/* { dg-options "-O2 -mindirect-branch=thunk-extern -fno-pic" } */ |
3321 |
++/* { dg-options "-O2 -mfunction-return=keep -mindirect-branch=thunk-extern -fno-pic" } */ |
3322 |
+ |
3323 |
+ void func0 (void); |
3324 |
+ void func1 (void); |
3325 |
+diff -Naur gcc-7.2.0.orig/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-1.c gcc-7.2.0/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-1.c |
3326 |
+--- gcc-7.2.0.orig/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-1.c 2018-01-15 19:51:28.902618178 -0800 |
3327 |
++++ gcc-7.2.0/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-1.c 2018-01-15 19:51:44.400617901 -0800 |
3328 |
+@@ -1,5 +1,5 @@ |
3329 |
+ /* { dg-do compile } */ |
3330 |
+-/* { dg-options "-O2 -mindirect-branch=thunk-inline -fno-pic" } */ |
3331 |
++/* { dg-options "-O2 -mfunction-return=keep -mindirect-branch=thunk-inline -fno-pic" } */ |
3332 |
+ |
3333 |
+ typedef void (*dispatch_t)(long offset); |
3334 |
+ |
3335 |
+diff -Naur gcc-7.2.0.orig/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-2.c gcc-7.2.0/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-2.c |
3336 |
+--- gcc-7.2.0.orig/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-2.c 2018-01-15 19:51:28.902618178 -0800 |
3337 |
++++ gcc-7.2.0/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-2.c 2018-01-15 19:51:44.400617901 -0800 |
3338 |
+@@ -1,5 +1,5 @@ |
3339 |
+ /* { dg-do compile } */ |
3340 |
+-/* { dg-options "-O2 -mindirect-branch=thunk-inline -fno-pic" } */ |
3341 |
++/* { dg-options "-O2 -mfunction-return=keep -mindirect-branch=thunk-inline -fno-pic" } */ |
3342 |
+ |
3343 |
+ typedef void (*dispatch_t)(long offset); |
3344 |
+ |
3345 |
+diff -Naur gcc-7.2.0.orig/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-3.c gcc-7.2.0/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-3.c |
3346 |
+--- gcc-7.2.0.orig/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-3.c 2018-01-15 19:51:28.902618178 -0800 |
3347 |
++++ gcc-7.2.0/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-3.c 2018-01-15 19:51:44.400617901 -0800 |
3348 |
+@@ -1,5 +1,5 @@ |
3349 |
+ /* { dg-do compile } */ |
3350 |
+-/* { dg-options "-O2 -mindirect-branch=thunk-inline -fno-pic" } */ |
3351 |
++/* { dg-options "-O2 -mfunction-return=keep -mindirect-branch=thunk-inline -fno-pic" } */ |
3352 |
+ |
3353 |
+ typedef void (*dispatch_t)(long offset); |
3354 |
+ |
3355 |
+diff -Naur gcc-7.2.0.orig/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-4.c gcc-7.2.0/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-4.c |
3356 |
+--- gcc-7.2.0.orig/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-4.c 2018-01-15 19:51:28.902618178 -0800 |
3357 |
++++ gcc-7.2.0/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-4.c 2018-01-15 19:51:44.401617901 -0800 |
3358 |
+@@ -1,5 +1,5 @@ |
3359 |
+ /* { dg-do compile } */ |
3360 |
+-/* { dg-options "-O2 -mindirect-branch=thunk-inline -fno-pic" } */ |
3361 |
++/* { dg-options "-O2 -mfunction-return=keep -mindirect-branch=thunk-inline -fno-pic" } */ |
3362 |
+ |
3363 |
+ typedef void (*dispatch_t)(long offset); |
3364 |
+ |
3365 |
+diff -Naur gcc-7.2.0.orig/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-5.c gcc-7.2.0/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-5.c |
3366 |
+--- gcc-7.2.0.orig/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-5.c 2018-01-15 19:51:28.902618178 -0800 |
3367 |
++++ gcc-7.2.0/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-5.c 2018-01-15 19:51:44.401617901 -0800 |
3368 |
+@@ -1,5 +1,5 @@ |
3369 |
+ /* { dg-do compile { target *-*-linux* } } */ |
3370 |
+-/* { dg-options "-O2 -fpic -fno-plt -mindirect-branch=thunk-inline" } */ |
3371 |
++/* { dg-options "-O2 -mfunction-return=keep -fpic -fno-plt -mindirect-branch=thunk-inline" } */ |
3372 |
+ |
3373 |
+ extern void bar (void); |
3374 |
+ |
3375 |
+diff -Naur gcc-7.2.0.orig/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-6.c gcc-7.2.0/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-6.c |
3376 |
+--- gcc-7.2.0.orig/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-6.c 2018-01-15 19:51:28.902618178 -0800 |
3377 |
++++ gcc-7.2.0/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-6.c 2018-01-15 19:51:44.401617901 -0800 |
3378 |
+@@ -1,5 +1,5 @@ |
3379 |
+ /* { dg-do compile { target *-*-linux* } } */ |
3380 |
+-/* { dg-options "-O2 -fpic -fno-plt -mindirect-branch=thunk-inline" } */ |
3381 |
++/* { dg-options "-O2 -mfunction-return=keep -fpic -fno-plt -mindirect-branch=thunk-inline" } */ |
3382 |
+ |
3383 |
+ extern void bar (void); |
3384 |
+ |
3385 |
+diff -Naur gcc-7.2.0.orig/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-7.c gcc-7.2.0/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-7.c |
3386 |
+--- gcc-7.2.0.orig/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-7.c 2018-01-15 19:51:28.902618178 -0800 |
3387 |
++++ gcc-7.2.0/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-7.c 2018-01-15 19:51:44.401617901 -0800 |
3388 |
+@@ -1,5 +1,5 @@ |
3389 |
+ /* { dg-do compile } */ |
3390 |
+-/* { dg-options "-O2 -mindirect-branch=thunk-inline -fno-pic" } */ |
3391 |
++/* { dg-options "-O2 -mfunction-return=keep -mindirect-branch=thunk-inline -fno-pic" } */ |
3392 |
+ |
3393 |
+ void func0 (void); |
3394 |
+ void func1 (void); |
3395 |
+diff -Naur gcc-7.2.0.orig/gcc/testsuite/gcc.target/i386/ret-thunk-1.c gcc-7.2.0/gcc/testsuite/gcc.target/i386/ret-thunk-1.c |
3396 |
+--- gcc-7.2.0.orig/gcc/testsuite/gcc.target/i386/ret-thunk-1.c 1969-12-31 16:00:00.000000000 -0800 |
3397 |
++++ gcc-7.2.0/gcc/testsuite/gcc.target/i386/ret-thunk-1.c 2018-01-15 19:51:44.401617901 -0800 |
3398 |
+@@ -0,0 +1,12 @@ |
3399 |
++/* { dg-do compile } */ |
3400 |
++/* { dg-options "-O2 -mfunction-return=thunk" } */ |
3401 |
++ |
3402 |
++void |
3403 |
++foo (void) |
3404 |
++{ |
3405 |
++} |
3406 |
++ |
3407 |
++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_return_thunk" } } */ |
3408 |
++/* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */ |
3409 |
++/* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */ |
3410 |
++/* { dg-final { scan-assembler {\tpause} } } */ |
3411 |
+diff -Naur gcc-7.2.0.orig/gcc/testsuite/gcc.target/i386/ret-thunk-10.c gcc-7.2.0/gcc/testsuite/gcc.target/i386/ret-thunk-10.c |
3412 |
+--- gcc-7.2.0.orig/gcc/testsuite/gcc.target/i386/ret-thunk-10.c 1969-12-31 16:00:00.000000000 -0800 |
3413 |
++++ gcc-7.2.0/gcc/testsuite/gcc.target/i386/ret-thunk-10.c 2018-01-15 19:51:44.401617901 -0800 |
3414 |
+@@ -0,0 +1,22 @@ |
3415 |
++/* { dg-do compile } */ |
3416 |
++/* { dg-options "-O2 -mfunction-return=thunk-inline -mindirect-branch=thunk -fno-pic" } */ |
3417 |
++ |
3418 |
++extern void (*bar) (void); |
3419 |
++ |
3420 |
++int |
3421 |
++foo (void) |
3422 |
++{ |
3423 |
++ bar (); |
3424 |
++ return 0; |
3425 |
++} |
3426 |
++ |
3427 |
++/* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */ |
3428 |
++/* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */ |
3429 |
++/* { dg-final { scan-assembler-not "jmp\[ \t\]*__x86_return_thunk" } } */ |
3430 |
++/* { dg-final { scan-assembler-times {\tpause} 2 } } */ |
3431 |
++/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?bar" { target { ! x32 } } } } */ |
3432 |
++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" { target { ! x32 } } } } */ |
3433 |
++/* { dg-final { scan-assembler "__x86_indirect_thunk:" { target { ! x32 } } } } */ |
3434 |
++/* { dg-final { scan-assembler "call\[ \t\]*__x86_indirect_thunk_(r|e)ax" { target { x32 } } } } */ |
3435 |
++/* { dg-final { scan-assembler "__x86_indirect_thunk_(r|e)ax:" { target { x32 } } } } */ |
3436 |
++/* { dg-final { scan-assembler-not "pushq\[ \t\]%rax" { target x32 } } } */ |
3437 |
+diff -Naur gcc-7.2.0.orig/gcc/testsuite/gcc.target/i386/ret-thunk-11.c gcc-7.2.0/gcc/testsuite/gcc.target/i386/ret-thunk-11.c |
3438 |
+--- gcc-7.2.0.orig/gcc/testsuite/gcc.target/i386/ret-thunk-11.c 1969-12-31 16:00:00.000000000 -0800 |
3439 |
++++ gcc-7.2.0/gcc/testsuite/gcc.target/i386/ret-thunk-11.c 2018-01-15 19:51:44.401617901 -0800 |
3440 |
+@@ -0,0 +1,22 @@ |
3441 |
++/* { dg-do compile } */ |
3442 |
++/* { dg-options "-O2 -mfunction-return=thunk-extern -mindirect-branch=thunk -fno-pic" } */ |
3443 |
++ |
3444 |
++extern void (*bar) (void); |
3445 |
++ |
3446 |
++int |
3447 |
++foo (void) |
3448 |
++{ |
3449 |
++ bar (); |
3450 |
++ return 0; |
3451 |
++} |
3452 |
++ |
3453 |
++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_return_thunk" } } */ |
3454 |
++/* { dg-final { scan-assembler-times {\tpause} 1 } } */ |
3455 |
++/* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */ |
3456 |
++/* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */ |
3457 |
++/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?bar" { target { ! x32 } } } } */ |
3458 |
++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" { target { ! x32 } } } } */ |
3459 |
++/* { dg-final { scan-assembler "__x86_indirect_thunk:" { target { ! x32 } } } } */ |
3460 |
++/* { dg-final { scan-assembler "call\[ \t\]*__x86_indirect_thunk_(r|e)ax" { target { x32 } } } } */ |
3461 |
++/* { dg-final { scan-assembler "__x86_indirect_thunk_(r|e)ax:" { target { x32 } } } } */ |
3462 |
++/* { dg-final { scan-assembler-not "pushq\[ \t\]%rax" { target x32 } } } */ |
3463 |
+diff -Naur gcc-7.2.0.orig/gcc/testsuite/gcc.target/i386/ret-thunk-12.c gcc-7.2.0/gcc/testsuite/gcc.target/i386/ret-thunk-12.c |
3464 |
+--- gcc-7.2.0.orig/gcc/testsuite/gcc.target/i386/ret-thunk-12.c 1969-12-31 16:00:00.000000000 -0800 |
3465 |
++++ gcc-7.2.0/gcc/testsuite/gcc.target/i386/ret-thunk-12.c 2018-01-15 19:51:44.401617901 -0800 |
3466 |
+@@ -0,0 +1,21 @@ |
3467 |
++/* { dg-do compile } */ |
3468 |
++/* { dg-options "-O2 -mfunction-return=keep -mindirect-branch=thunk -fno-pic" } */ |
3469 |
++ |
3470 |
++extern void (*bar) (void); |
3471 |
++ |
3472 |
++int |
3473 |
++foo (void) |
3474 |
++{ |
3475 |
++ bar (); |
3476 |
++ return 0; |
3477 |
++} |
3478 |
++ |
3479 |
++/* { dg-final { scan-assembler-not "jmp\[ \t\]*__x86_return_thunk" } } */ |
3480 |
++/* { dg-final { scan-assembler-times {\tpause} 1 } } */ |
3481 |
++/* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */ |
3482 |
++/* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */ |
3483 |
++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" { target { ! x32 } } } } */ |
3484 |
++/* { dg-final { scan-assembler "__x86_indirect_thunk:" { target { ! x32 } } } } */ |
3485 |
++/* { dg-final { scan-assembler "call\[ \t\]*__x86_indirect_thunk_(r|e)ax" { target { x32 } } } } */ |
3486 |
++/* { dg-final { scan-assembler "__x86_indirect_thunk_(r|e)ax:" { target { x32 } } } } */ |
3487 |
++/* { dg-final { scan-assembler-not "pushq\[ \t\]%rax" { target x32 } } } */ |
3488 |
+diff -Naur gcc-7.2.0.orig/gcc/testsuite/gcc.target/i386/ret-thunk-13.c gcc-7.2.0/gcc/testsuite/gcc.target/i386/ret-thunk-13.c |
3489 |
+--- gcc-7.2.0.orig/gcc/testsuite/gcc.target/i386/ret-thunk-13.c 1969-12-31 16:00:00.000000000 -0800 |
3490 |
++++ gcc-7.2.0/gcc/testsuite/gcc.target/i386/ret-thunk-13.c 2018-01-15 19:51:44.401617901 -0800 |
3491 |
+@@ -0,0 +1,21 @@ |
3492 |
++/* { dg-do compile } */ |
3493 |
++/* { dg-options "-O2 -mfunction-return=keep -mindirect-branch=thunk-inline -fno-pic" } */ |
3494 |
++ |
3495 |
++extern void (*bar) (void); |
3496 |
++extern int foo (void) __attribute__ ((function_return("thunk"))); |
3497 |
++ |
3498 |
++int |
3499 |
++foo (void) |
3500 |
++{ |
3501 |
++ bar (); |
3502 |
++ return 0; |
3503 |
++} |
3504 |
++ |
3505 |
++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_return_thunk" } } */ |
3506 |
++/* { dg-final { scan-assembler-times {\tpause} 2 } } */ |
3507 |
++/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?bar" { target { ! x32 } } } } */ |
3508 |
++/* { dg-final { scan-assembler-times "jmp\[ \t\]*\.LIND" 3 } } */ |
3509 |
++/* { dg-final { scan-assembler-times "call\[ \t\]*\.LIND" 3 } } */ |
3510 |
++/* { dg-final { scan-assembler-not "jmp\[ \t\]*__x86_indirect_thunk" } } */ |
3511 |
++/* { dg-final { scan-assembler-not "call\[ \t\]*__x86_indirect_thunk_(r|e)ax" { target { x32 } } } } */ |
3512 |
++/* { dg-final { scan-assembler-not "pushq\[ \t\]%rax" { target x32 } } } */ |
3513 |
+diff -Naur gcc-7.2.0.orig/gcc/testsuite/gcc.target/i386/ret-thunk-14.c gcc-7.2.0/gcc/testsuite/gcc.target/i386/ret-thunk-14.c |
3514 |
+--- gcc-7.2.0.orig/gcc/testsuite/gcc.target/i386/ret-thunk-14.c 1969-12-31 16:00:00.000000000 -0800 |
3515 |
++++ gcc-7.2.0/gcc/testsuite/gcc.target/i386/ret-thunk-14.c 2018-01-15 19:51:44.401617901 -0800 |
3516 |
+@@ -0,0 +1,21 @@ |
3517 |
++/* { dg-do compile } */ |
3518 |
++/* { dg-options "-O2 -mfunction-return=keep -mindirect-branch=thunk-extern -fno-pic" } */ |
3519 |
++ |
3520 |
++extern void (*bar) (void); |
3521 |
++ |
3522 |
++__attribute__ ((function_return("thunk-inline"))) |
3523 |
++int |
3524 |
++foo (void) |
3525 |
++{ |
3526 |
++ bar (); |
3527 |
++ return 0; |
3528 |
++} |
3529 |
++ |
3530 |
++/* { dg-final { scan-assembler-times {\tpause} 1 } } */ |
3531 |
++/* { dg-final { scan-assembler-not "jmp\[ \t\]*__x86_return_thunk" } } */ |
3532 |
++/* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */ |
3533 |
++/* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */ |
3534 |
++/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?bar" { target { ! x32 } } } } */ |
3535 |
++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" { target { ! x32 } } } } */ |
3536 |
++/* { dg-final { scan-assembler "call\[ \t\]*__x86_indirect_thunk_(r|e)ax" { target { x32 } } } } */ |
3537 |
++/* { dg-final { scan-assembler-not "pushq\[ \t\]%rax" { target x32 } } } */ |
3538 |
+diff -Naur gcc-7.2.0.orig/gcc/testsuite/gcc.target/i386/ret-thunk-15.c gcc-7.2.0/gcc/testsuite/gcc.target/i386/ret-thunk-15.c |
3539 |
+--- gcc-7.2.0.orig/gcc/testsuite/gcc.target/i386/ret-thunk-15.c 1969-12-31 16:00:00.000000000 -0800 |
3540 |
++++ gcc-7.2.0/gcc/testsuite/gcc.target/i386/ret-thunk-15.c 2018-01-15 19:51:44.402617901 -0800 |
3541 |
+@@ -0,0 +1,21 @@ |
3542 |
++/* { dg-do compile } */ |
3543 |
++/* { dg-options "-O2 -mfunction-return=keep -mindirect-branch=keep -fno-pic" } */ |
3544 |
++ |
3545 |
++extern void (*bar) (void); |
3546 |
++ |
3547 |
++__attribute__ ((function_return("thunk-extern"), indirect_branch("thunk"))) |
3548 |
++int |
3549 |
++foo (void) |
3550 |
++{ |
3551 |
++ bar (); |
3552 |
++ return 0; |
3553 |
++} |
3554 |
++ |
3555 |
++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_return_thunk" } } */ |
3556 |
++/* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */ |
3557 |
++/* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */ |
3558 |
++/* { dg-final { scan-assembler-times {\tpause} 1 } } */ |
3559 |
++/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?bar" { target { ! x32 } } } } */ |
3560 |
++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" { target { ! x32 } } } } */ |
3561 |
++/* { dg-final { scan-assembler "call\[ \t\]*__x86_indirect_thunk_(r|e)ax" { target x32 } } } */ |
3562 |
++/* { dg-final { scan-assembler-not "pushq\[ \t\]%rax" { target x32 } } } */ |
3563 |
+diff -Naur gcc-7.2.0.orig/gcc/testsuite/gcc.target/i386/ret-thunk-16.c gcc-7.2.0/gcc/testsuite/gcc.target/i386/ret-thunk-16.c |
3564 |
+--- gcc-7.2.0.orig/gcc/testsuite/gcc.target/i386/ret-thunk-16.c 1969-12-31 16:00:00.000000000 -0800 |
3565 |
++++ gcc-7.2.0/gcc/testsuite/gcc.target/i386/ret-thunk-16.c 2018-01-15 19:51:44.402617901 -0800 |
3566 |
+@@ -0,0 +1,18 @@ |
3567 |
++/* { dg-do compile } */ |
3568 |
++/* { dg-options "-O2 -mfunction-return=thunk-inline -mindirect-branch=thunk-extern -fno-pic" } */ |
3569 |
++ |
3570 |
++extern void (*bar) (void); |
3571 |
++ |
3572 |
++__attribute__ ((function_return("keep"), indirect_branch("keep"))) |
3573 |
++int |
3574 |
++foo (void) |
3575 |
++{ |
3576 |
++ bar (); |
3577 |
++ return 0; |
3578 |
++} |
3579 |
++ |
3580 |
++/* { dg-final { scan-assembler-not "__x86_indirect_thunk" } } */ |
3581 |
++/* { dg-final { scan-assembler-not "__x86_return_thunk" } } */ |
3582 |
++/* { dg-final { scan-assembler-not {\tpause} } } */ |
3583 |
++/* { dg-final { scan-assembler-not "jmp\[ \t\]*\.LIND" } } */ |
3584 |
++/* { dg-final { scan-assembler-not "call\[ \t\]*\.LIND" } } */ |
3585 |
+diff -Naur gcc-7.2.0.orig/gcc/testsuite/gcc.target/i386/ret-thunk-2.c gcc-7.2.0/gcc/testsuite/gcc.target/i386/ret-thunk-2.c |
3586 |
+--- gcc-7.2.0.orig/gcc/testsuite/gcc.target/i386/ret-thunk-2.c 1969-12-31 16:00:00.000000000 -0800 |
3587 |
++++ gcc-7.2.0/gcc/testsuite/gcc.target/i386/ret-thunk-2.c 2018-01-15 19:51:44.402617901 -0800 |
3588 |
+@@ -0,0 +1,12 @@ |
3589 |
++/* { dg-do compile } */ |
3590 |
++/* { dg-options "-O2 -mfunction-return=thunk-inline" } */ |
3591 |
++ |
3592 |
++void |
3593 |
++foo (void) |
3594 |
++{ |
3595 |
++} |
3596 |
++ |
3597 |
++/* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */ |
3598 |
++/* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */ |
3599 |
++/* { dg-final { scan-assembler {\tpause} } } */ |
3600 |
++/* { dg-final { scan-assembler-not "jmp\[ \t\]*__x86_return_thunk" } } */ |
3601 |
+diff -Naur gcc-7.2.0.orig/gcc/testsuite/gcc.target/i386/ret-thunk-3.c gcc-7.2.0/gcc/testsuite/gcc.target/i386/ret-thunk-3.c |
3602 |
+--- gcc-7.2.0.orig/gcc/testsuite/gcc.target/i386/ret-thunk-3.c 1969-12-31 16:00:00.000000000 -0800 |
3603 |
++++ gcc-7.2.0/gcc/testsuite/gcc.target/i386/ret-thunk-3.c 2018-01-15 19:51:44.402617901 -0800 |
3604 |
+@@ -0,0 +1,12 @@ |
3605 |
++/* { dg-do compile } */ |
3606 |
++/* { dg-options "-O2 -mfunction-return=thunk-extern" } */ |
3607 |
++ |
3608 |
++void |
3609 |
++foo (void) |
3610 |
++{ |
3611 |
++} |
3612 |
++ |
3613 |
++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_return_thunk" } } */ |
3614 |
++/* { dg-final { scan-assembler-not {\tpause} } } */ |
3615 |
++/* { dg-final { scan-assembler-not "jmp\[ \t\]*\.LIND" } } */ |
3616 |
++/* { dg-final { scan-assembler-not "call\[ \t\]*\.LIND" } } */ |
3617 |
+diff -Naur gcc-7.2.0.orig/gcc/testsuite/gcc.target/i386/ret-thunk-4.c gcc-7.2.0/gcc/testsuite/gcc.target/i386/ret-thunk-4.c |
3618 |
+--- gcc-7.2.0.orig/gcc/testsuite/gcc.target/i386/ret-thunk-4.c 1969-12-31 16:00:00.000000000 -0800 |
3619 |
++++ gcc-7.2.0/gcc/testsuite/gcc.target/i386/ret-thunk-4.c 2018-01-15 19:51:44.402617901 -0800 |
3620 |
+@@ -0,0 +1,12 @@ |
3621 |
++/* { dg-do compile } */ |
3622 |
++/* { dg-options "-O2 -mfunction-return=keep" } */ |
3623 |
++ |
3624 |
++void |
3625 |
++foo (void) |
3626 |
++{ |
3627 |
++} |
3628 |
++ |
3629 |
++/* { dg-final { scan-assembler-not "jmp\[ \t\]*__x86_return_thunk" } } */ |
3630 |
++/* { dg-final { scan-assembler-not {\tpause} } } */ |
3631 |
++/* { dg-final { scan-assembler-not "jmp\[ \t\]*\.LIND" } } */ |
3632 |
++/* { dg-final { scan-assembler-not "call\[ \t\]*\.LIND" } } */ |
3633 |
+diff -Naur gcc-7.2.0.orig/gcc/testsuite/gcc.target/i386/ret-thunk-5.c gcc-7.2.0/gcc/testsuite/gcc.target/i386/ret-thunk-5.c |
3634 |
+--- gcc-7.2.0.orig/gcc/testsuite/gcc.target/i386/ret-thunk-5.c 1969-12-31 16:00:00.000000000 -0800 |
3635 |
++++ gcc-7.2.0/gcc/testsuite/gcc.target/i386/ret-thunk-5.c 2018-01-15 19:51:44.402617901 -0800 |
3636 |
+@@ -0,0 +1,14 @@ |
3637 |
++/* { dg-do compile } */ |
3638 |
++/* { dg-options "-O2 -mfunction-return=keep" } */ |
3639 |
++ |
3640 |
++extern void foo (void) __attribute__ ((function_return("thunk"))); |
3641 |
++ |
3642 |
++void |
3643 |
++foo (void) |
3644 |
++{ |
3645 |
++} |
3646 |
++ |
3647 |
++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_return_thunk" } } */ |
3648 |
++/* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */ |
3649 |
++/* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */ |
3650 |
++/* { dg-final { scan-assembler {\tpause} } } */ |
3651 |
+diff -Naur gcc-7.2.0.orig/gcc/testsuite/gcc.target/i386/ret-thunk-6.c gcc-7.2.0/gcc/testsuite/gcc.target/i386/ret-thunk-6.c |
3652 |
+--- gcc-7.2.0.orig/gcc/testsuite/gcc.target/i386/ret-thunk-6.c 1969-12-31 16:00:00.000000000 -0800 |
3653 |
++++ gcc-7.2.0/gcc/testsuite/gcc.target/i386/ret-thunk-6.c 2018-01-15 19:51:44.403617901 -0800 |
3654 |
+@@ -0,0 +1,13 @@ |
3655 |
++/* { dg-do compile } */ |
3656 |
++/* { dg-options "-O2 -mfunction-return=keep" } */ |
3657 |
++ |
3658 |
++__attribute__ ((function_return("thunk-inline"))) |
3659 |
++void |
3660 |
++foo (void) |
3661 |
++{ |
3662 |
++} |
3663 |
++ |
3664 |
++/* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */ |
3665 |
++/* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */ |
3666 |
++/* { dg-final { scan-assembler {\tpause} } } */ |
3667 |
++/* { dg-final { scan-assembler-not "jmp\[ \t\]*__x86_return_thunk" } } */ |
3668 |
+diff -Naur gcc-7.2.0.orig/gcc/testsuite/gcc.target/i386/ret-thunk-7.c gcc-7.2.0/gcc/testsuite/gcc.target/i386/ret-thunk-7.c |
3669 |
+--- gcc-7.2.0.orig/gcc/testsuite/gcc.target/i386/ret-thunk-7.c 1969-12-31 16:00:00.000000000 -0800 |
3670 |
++++ gcc-7.2.0/gcc/testsuite/gcc.target/i386/ret-thunk-7.c 2018-01-15 19:51:44.403617901 -0800 |
3671 |
+@@ -0,0 +1,13 @@ |
3672 |
++/* { dg-do compile } */ |
3673 |
++/* { dg-options "-O2 -mfunction-return=keep" } */ |
3674 |
++ |
3675 |
++__attribute__ ((function_return("thunk-extern"))) |
3676 |
++void |
3677 |
++foo (void) |
3678 |
++{ |
3679 |
++} |
3680 |
++ |
3681 |
++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_return_thunk" } } */ |
3682 |
++/* { dg-final { scan-assembler-not {\tpause} } } */ |
3683 |
++/* { dg-final { scan-assembler-not "jmp\[ \t\]*\.LIND" } } */ |
3684 |
++/* { dg-final { scan-assembler-not "call\[ \t\]*\.LIND" } } */ |
3685 |
+diff -Naur gcc-7.2.0.orig/gcc/testsuite/gcc.target/i386/ret-thunk-8.c gcc-7.2.0/gcc/testsuite/gcc.target/i386/ret-thunk-8.c |
3686 |
+--- gcc-7.2.0.orig/gcc/testsuite/gcc.target/i386/ret-thunk-8.c 1969-12-31 16:00:00.000000000 -0800 |
3687 |
++++ gcc-7.2.0/gcc/testsuite/gcc.target/i386/ret-thunk-8.c 2018-01-15 19:51:44.403617901 -0800 |
3688 |
+@@ -0,0 +1,14 @@ |
3689 |
++/* { dg-do compile } */ |
3690 |
++/* { dg-options "-O2 -mfunction-return=thunk-inline" } */ |
3691 |
++ |
3692 |
++extern void foo (void) __attribute__ ((function_return("keep"))); |
3693 |
++ |
3694 |
++void |
3695 |
++foo (void) |
3696 |
++{ |
3697 |
++} |
3698 |
++ |
3699 |
++/* { dg-final { scan-assembler-not "jmp\[ \t\]*__x86_return_thunk" } } */ |
3700 |
++/* { dg-final { scan-assembler-not {\tpause} } } */ |
3701 |
++/* { dg-final { scan-assembler-not "jmp\[ \t\]*\.LIND" } } */ |
3702 |
++/* { dg-final { scan-assembler-not "call\[ \t\]*\.LIND" } } */ |
3703 |
+diff -Naur gcc-7.2.0.orig/gcc/testsuite/gcc.target/i386/ret-thunk-9.c gcc-7.2.0/gcc/testsuite/gcc.target/i386/ret-thunk-9.c |
3704 |
+--- gcc-7.2.0.orig/gcc/testsuite/gcc.target/i386/ret-thunk-9.c 1969-12-31 16:00:00.000000000 -0800 |
3705 |
++++ gcc-7.2.0/gcc/testsuite/gcc.target/i386/ret-thunk-9.c 2018-01-15 19:51:44.403617901 -0800 |
3706 |
+@@ -0,0 +1,23 @@ |
3707 |
++/* { dg-do compile } */ |
3708 |
++/* { dg-options "-O2 -mfunction-return=thunk -mindirect-branch=thunk -fno-pic" } */ |
3709 |
++ |
3710 |
++extern void (*bar) (void); |
3711 |
++ |
3712 |
++int |
3713 |
++foo (void) |
3714 |
++{ |
3715 |
++ bar (); |
3716 |
++ return 0; |
3717 |
++} |
3718 |
++ |
3719 |
++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_return_thunk" } } */ |
3720 |
++/* { dg-final { scan-assembler-not "__x86_return_thunk:" } } */ |
3721 |
++/* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */ |
3722 |
++/* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */ |
3723 |
++/* { dg-final { scan-assembler "__x86_indirect_thunk:" } } */ |
3724 |
++/* { dg-final { scan-assembler-times {\tpause} 1 { target { ! x32 } } } } */ |
3725 |
++/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?bar" { target { ! x32 } } } } */ |
3726 |
++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" { target { ! x32 } } } } */ |
3727 |
++/* { dg-final { scan-assembler-times {\tpause} 2 { target { x32 } } } } */ |
3728 |
++/* { dg-final { scan-assembler "call\[ \t\]*__x86_indirect_thunk_(r|e)ax" { target { x32 } } } } */ |
3729 |
++/* { dg-final { scan-assembler-not "pushq\[ \t\]%rax" { target x32 } } } */ |
3730 |
|
3731 |
diff --git a/sys-devel/gcc/files/spectre-0003-mindirect-branch-register.patch b/sys-devel/gcc/files/spectre-0003-mindirect-branch-register.patch |
3732 |
new file mode 100644 |
3733 |
index 0000000..50aff5a |
3734 |
--- /dev/null |
3735 |
+++ b/sys-devel/gcc/files/spectre-0003-mindirect-branch-register.patch |
3736 |
@@ -0,0 +1,887 @@ |
3737 |
+From: "H dot J dot Lu" <hjl dot tools at gmail dot com> |
3738 |
+To: gcc-patches at gcc dot gnu dot org |
3739 |
+Subject: [PATCH 3/4] x86: Add -mindirect-branch-register |
3740 |
+Date: Fri, 12 Jan 2018 05:15:48 -0800 |
3741 |
+ |
3742 |
+Add -mindirect-branch-register to force indirect branch via register. |
3743 |
+This is implemented by disabling patterns of indirect branch via memory, |
3744 |
+similar to TARGET_X32. |
3745 |
+ |
3746 |
+-mindirect-branch= and -mfunction-return= tests are updated with |
3747 |
+-mno-indirect-branch-register to avoid false test failures when |
3748 |
+-mindirect-branch-register is added to RUNTESTFLAGS for "make check". |
3749 |
+ |
3750 |
+gcc/ |
3751 |
+ |
3752 |
+ * config/i386/constraints.md (Bs): Disallow memory operand for |
3753 |
+ -mindirect-branch-register. |
3754 |
+ (Bw): Likewise. |
3755 |
+ * config/i386/predicates.md (indirect_branch_operand): Likewise. |
3756 |
+ (GOT_memory_operand): Likewise. |
3757 |
+ (call_insn_operand): Likewise. |
3758 |
+ (sibcall_insn_operand): Likewise. |
3759 |
+ (GOT32_symbol_operand): Likewise. |
3760 |
+ * config/i386/i386.md (indirect_jump): Call convert_memory_address |
3761 |
+ for -mindirect-branch-register. |
3762 |
+ (tablejump): Likewise. |
3763 |
+ (*sibcall_memory): Likewise. |
3764 |
+ (*sibcall_value_memory): Likewise. |
3765 |
+ Disallow peepholes of indirect call and jump via memory for |
3766 |
+ -mindirect-branch-register. |
3767 |
+ (*call_pop): Replace m with Bw. |
3768 |
+ (*call_value_pop): Likewise. |
3769 |
+ (*sibcall_pop_memory): Replace m with Bs. |
3770 |
+ * config/i386/i386.opt (mindirect-branch-register): New option. |
3771 |
+ * doc/invoke.texi: Document -mindirect-branch-register option. |
3772 |
+ |
3773 |
+gcc/testsuite/ |
3774 |
+ |
3775 |
+ * gcc.target/i386/indirect-thunk-1.c (dg-options): Add |
3776 |
+ -mno-indirect-branch-register. |
3777 |
+ * gcc.target/i386/indirect-thunk-2.c: Likewise. |
3778 |
+ * gcc.target/i386/indirect-thunk-3.c: Likewise. |
3779 |
+ * gcc.target/i386/indirect-thunk-4.c: Likewise. |
3780 |
+ * gcc.target/i386/indirect-thunk-5.c: Likewise. |
3781 |
+ * gcc.target/i386/indirect-thunk-6.c: Likewise. |
3782 |
+ * gcc.target/i386/indirect-thunk-7.c: Likewise. |
3783 |
+ * gcc.target/i386/indirect-thunk-attr-1.c: Likewise. |
3784 |
+ * gcc.target/i386/indirect-thunk-attr-2.c: Likewise. |
3785 |
+ * gcc.target/i386/indirect-thunk-attr-3.c: Likewise. |
3786 |
+ * gcc.target/i386/indirect-thunk-attr-4.c: Likewise. |
3787 |
+ * gcc.target/i386/indirect-thunk-attr-5.c: Likewise. |
3788 |
+ * gcc.target/i386/indirect-thunk-attr-6.c: Likewise. |
3789 |
+ * gcc.target/i386/indirect-thunk-attr-7.c: Likewise. |
3790 |
+ * gcc.target/i386/indirect-thunk-bnd-1.c: Likewise. |
3791 |
+ * gcc.target/i386/indirect-thunk-bnd-2.c: Likewise. |
3792 |
+ * gcc.target/i386/indirect-thunk-bnd-3.c: Likewise. |
3793 |
+ * gcc.target/i386/indirect-thunk-bnd-4.c: Likewise. |
3794 |
+ * gcc.target/i386/indirect-thunk-extern-1.c: Likewise. |
3795 |
+ * gcc.target/i386/indirect-thunk-extern-2.c: Likewise. |
3796 |
+ * gcc.target/i386/indirect-thunk-extern-3.c: Likewise. |
3797 |
+ * gcc.target/i386/indirect-thunk-extern-4.c: Likewise. |
3798 |
+ * gcc.target/i386/indirect-thunk-extern-5.c: Likewise. |
3799 |
+ * gcc.target/i386/indirect-thunk-extern-6.c: Likewise. |
3800 |
+ * gcc.target/i386/indirect-thunk-extern-7.c: Likewise. |
3801 |
+ * gcc.target/i386/indirect-thunk-inline-1.c: Likewise. |
3802 |
+ * gcc.target/i386/indirect-thunk-inline-2.c: Likewise. |
3803 |
+ * gcc.target/i386/indirect-thunk-inline-3.c: Likewise. |
3804 |
+ * gcc.target/i386/indirect-thunk-inline-4.c: Likewise. |
3805 |
+ * gcc.target/i386/indirect-thunk-inline-5.c: Likewise. |
3806 |
+ * gcc.target/i386/indirect-thunk-inline-6.c: Likewise. |
3807 |
+ * gcc.target/i386/indirect-thunk-inline-7.c: Likewise. |
3808 |
+ * gcc.target/i386/ret-thunk-10.c: Likewise. |
3809 |
+ * gcc.target/i386/ret-thunk-11.c: Likewise. |
3810 |
+ * gcc.target/i386/ret-thunk-12.c: Likewise. |
3811 |
+ * gcc.target/i386/ret-thunk-13.c: Likewise. |
3812 |
+ * gcc.target/i386/ret-thunk-14.c: Likewise. |
3813 |
+ * gcc.target/i386/ret-thunk-15.c: Likewise. |
3814 |
+ * gcc.target/i386/ret-thunk-9.c: Likewise. |
3815 |
+ * gcc.target/i386/indirect-thunk-register-1.c: New test. |
3816 |
+ * gcc.target/i386/indirect-thunk-register-2.c: Likewise. |
3817 |
+ * gcc.target/i386/indirect-thunk-register-3.c: Likewise. |
3818 |
+--- |
3819 |
+ gcc/config/i386/constraints.md | 12 +++++--- |
3820 |
+ gcc/config/i386/i386.md | 34 ++++++++++++++-------- |
3821 |
+ gcc/config/i386/i386.opt | 4 +++ |
3822 |
+ gcc/config/i386/predicates.md | 21 ++++++++----- |
3823 |
+ gcc/doc/invoke.texi | 7 ++++- |
3824 |
+ gcc/testsuite/gcc.target/i386/indirect-thunk-1.c | 2 +- |
3825 |
+ gcc/testsuite/gcc.target/i386/indirect-thunk-2.c | 2 +- |
3826 |
+ gcc/testsuite/gcc.target/i386/indirect-thunk-3.c | 2 +- |
3827 |
+ gcc/testsuite/gcc.target/i386/indirect-thunk-4.c | 2 +- |
3828 |
+ gcc/testsuite/gcc.target/i386/indirect-thunk-5.c | 2 +- |
3829 |
+ gcc/testsuite/gcc.target/i386/indirect-thunk-6.c | 2 +- |
3830 |
+ gcc/testsuite/gcc.target/i386/indirect-thunk-7.c | 2 +- |
3831 |
+ .../gcc.target/i386/indirect-thunk-attr-1.c | 2 +- |
3832 |
+ .../gcc.target/i386/indirect-thunk-attr-2.c | 2 +- |
3833 |
+ .../gcc.target/i386/indirect-thunk-attr-3.c | 2 +- |
3834 |
+ .../gcc.target/i386/indirect-thunk-attr-4.c | 2 +- |
3835 |
+ .../gcc.target/i386/indirect-thunk-attr-5.c | 2 +- |
3836 |
+ .../gcc.target/i386/indirect-thunk-attr-6.c | 2 +- |
3837 |
+ .../gcc.target/i386/indirect-thunk-attr-7.c | 2 +- |
3838 |
+ .../gcc.target/i386/indirect-thunk-bnd-1.c | 2 +- |
3839 |
+ .../gcc.target/i386/indirect-thunk-bnd-2.c | 2 +- |
3840 |
+ .../gcc.target/i386/indirect-thunk-bnd-3.c | 2 +- |
3841 |
+ .../gcc.target/i386/indirect-thunk-bnd-4.c | 2 +- |
3842 |
+ .../gcc.target/i386/indirect-thunk-extern-1.c | 2 +- |
3843 |
+ .../gcc.target/i386/indirect-thunk-extern-2.c | 2 +- |
3844 |
+ .../gcc.target/i386/indirect-thunk-extern-3.c | 2 +- |
3845 |
+ .../gcc.target/i386/indirect-thunk-extern-4.c | 2 +- |
3846 |
+ .../gcc.target/i386/indirect-thunk-extern-5.c | 2 +- |
3847 |
+ .../gcc.target/i386/indirect-thunk-extern-6.c | 2 +- |
3848 |
+ .../gcc.target/i386/indirect-thunk-extern-7.c | 2 +- |
3849 |
+ .../gcc.target/i386/indirect-thunk-inline-1.c | 2 +- |
3850 |
+ .../gcc.target/i386/indirect-thunk-inline-2.c | 2 +- |
3851 |
+ .../gcc.target/i386/indirect-thunk-inline-3.c | 2 +- |
3852 |
+ .../gcc.target/i386/indirect-thunk-inline-4.c | 2 +- |
3853 |
+ .../gcc.target/i386/indirect-thunk-inline-5.c | 2 +- |
3854 |
+ .../gcc.target/i386/indirect-thunk-inline-6.c | 2 +- |
3855 |
+ .../gcc.target/i386/indirect-thunk-inline-7.c | 2 +- |
3856 |
+ .../gcc.target/i386/indirect-thunk-register-1.c | 22 ++++++++++++++ |
3857 |
+ .../gcc.target/i386/indirect-thunk-register-2.c | 20 +++++++++++++ |
3858 |
+ .../gcc.target/i386/indirect-thunk-register-3.c | 19 ++++++++++++ |
3859 |
+ gcc/testsuite/gcc.target/i386/ret-thunk-10.c | 2 +- |
3860 |
+ gcc/testsuite/gcc.target/i386/ret-thunk-11.c | 2 +- |
3861 |
+ gcc/testsuite/gcc.target/i386/ret-thunk-12.c | 2 +- |
3862 |
+ gcc/testsuite/gcc.target/i386/ret-thunk-13.c | 2 +- |
3863 |
+ gcc/testsuite/gcc.target/i386/ret-thunk-14.c | 2 +- |
3864 |
+ gcc/testsuite/gcc.target/i386/ret-thunk-15.c | 2 +- |
3865 |
+ gcc/testsuite/gcc.target/i386/ret-thunk-9.c | 2 +- |
3866 |
+ 47 files changed, 154 insertions(+), 63 deletions(-) |
3867 |
+ create mode 100644 gcc/testsuite/gcc.target/i386/indirect-thunk-register-1.c |
3868 |
+ create mode 100644 gcc/testsuite/gcc.target/i386/indirect-thunk-register-2.c |
3869 |
+ create mode 100644 gcc/testsuite/gcc.target/i386/indirect-thunk-register-3.c |
3870 |
+ |
3871 |
+diff -Naur gcc-7.2.0.orig/gcc/config/i386/constraints.md gcc-7.2.0/gcc/config/i386/constraints.md |
3872 |
+--- gcc-7.2.0.orig/gcc/config/i386/constraints.md 2018-01-15 18:36:46.557698449 -0800 |
3873 |
++++ gcc-7.2.0/gcc/config/i386/constraints.md 2018-01-15 18:39:17.685695742 -0800 |
3874 |
+@@ -198,16 +198,20 @@ |
3875 |
+ |
3876 |
+ (define_constraint "Bs" |
3877 |
+ "@internal Sibcall memory operand." |
3878 |
+- (ior (and (not (match_test "TARGET_X32")) |
3879 |
++ (ior (and (not (match_test "TARGET_X32 |
3880 |
++ || ix86_indirect_branch_thunk_register")) |
3881 |
+ (match_operand 0 "sibcall_memory_operand")) |
3882 |
+- (and (match_test "TARGET_X32 && Pmode == DImode") |
3883 |
++ (and (match_test "TARGET_X32 && Pmode == DImode |
3884 |
++ && !ix86_indirect_branch_thunk_register") |
3885 |
+ (match_operand 0 "GOT_memory_operand")))) |
3886 |
+ |
3887 |
+ (define_constraint "Bw" |
3888 |
+ "@internal Call memory operand." |
3889 |
+- (ior (and (not (match_test "TARGET_X32")) |
3890 |
++ (ior (and (not (match_test "TARGET_X32 |
3891 |
++ || ix86_indirect_branch_thunk_register")) |
3892 |
+ (match_operand 0 "memory_operand")) |
3893 |
+- (and (match_test "TARGET_X32 && Pmode == DImode") |
3894 |
++ (and (match_test "TARGET_X32 && Pmode == DImode |
3895 |
++ && !ix86_indirect_branch_thunk_register") |
3896 |
+ (match_operand 0 "GOT_memory_operand")))) |
3897 |
+ |
3898 |
+ (define_constraint "Bz" |
3899 |
+diff -Naur gcc-7.2.0.orig/gcc/config/i386/i386.md gcc-7.2.0/gcc/config/i386/i386.md |
3900 |
+--- gcc-7.2.0.orig/gcc/config/i386/i386.md 2018-01-15 18:36:46.571698448 -0800 |
3901 |
++++ gcc-7.2.0/gcc/config/i386/i386.md 2018-01-15 18:44:19.035690346 -0800 |
3902 |
+@@ -11608,7 +11608,7 @@ |
3903 |
+ [(set (pc) (match_operand 0 "indirect_branch_operand"))] |
3904 |
+ "" |
3905 |
+ { |
3906 |
+- if (TARGET_X32) |
3907 |
++ if (TARGET_X32 || ix86_indirect_branch_thunk_register) |
3908 |
+ operands[0] = convert_memory_address (word_mode, operands[0]); |
3909 |
+ cfun->machine->has_local_indirect_jump = true; |
3910 |
+ }) |
3911 |
+@@ -11658,7 +11658,7 @@ |
3912 |
+ OPTAB_DIRECT); |
3913 |
+ } |
3914 |
+ |
3915 |
+- if (TARGET_X32) |
3916 |
++ if (TARGET_X32 || ix86_indirect_branch_thunk_register) |
3917 |
+ operands[0] = convert_memory_address (word_mode, operands[0]); |
3918 |
+ cfun->machine->has_local_indirect_jump = true; |
3919 |
+ }) |
3920 |
+@@ -11846,7 +11846,7 @@ |
3921 |
+ [(call (mem:QI (match_operand:W 0 "memory_operand" "m")) |
3922 |
+ (match_operand 1)) |
3923 |
+ (unspec [(const_int 0)] UNSPEC_PEEPSIB)] |
3924 |
+- "!TARGET_X32" |
3925 |
++ "!TARGET_X32 && !ix86_indirect_branch_thunk_register" |
3926 |
+ "* return ix86_output_call_insn (insn, operands[0]);" |
3927 |
+ [(set_attr "type" "call")]) |
3928 |
+ |
3929 |
+@@ -11855,7 +11855,9 @@ |
3930 |
+ (match_operand:W 1 "memory_operand")) |
3931 |
+ (call (mem:QI (match_dup 0)) |
3932 |
+ (match_operand 3))] |
3933 |
+- "!TARGET_X32 && SIBLING_CALL_P (peep2_next_insn (1)) |
3934 |
++ "!TARGET_X32 |
3935 |
++ && !ix86_indirect_branch_thunk_register |
3936 |
++ && SIBLING_CALL_P (peep2_next_insn (1)) |
3937 |
+ && !reg_mentioned_p (operands[0], |
3938 |
+ CALL_INSN_FUNCTION_USAGE (peep2_next_insn (1)))" |
3939 |
+ [(parallel [(call (mem:QI (match_dup 1)) |
3940 |
+@@ -11868,7 +11870,9 @@ |
3941 |
+ (unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE) |
3942 |
+ (call (mem:QI (match_dup 0)) |
3943 |
+ (match_operand 3))] |
3944 |
+- "!TARGET_X32 && SIBLING_CALL_P (peep2_next_insn (2)) |
3945 |
++ "!TARGET_X32 |
3946 |
++ && !ix86_indirect_branch_thunk_register |
3947 |
++ && SIBLING_CALL_P (peep2_next_insn (2)) |
3948 |
+ && !reg_mentioned_p (operands[0], |
3949 |
+ CALL_INSN_FUNCTION_USAGE (peep2_next_insn (2)))" |
3950 |
+ [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE) |
3951 |
+@@ -11890,7 +11894,7 @@ |
3952 |
+ }) |
3953 |
+ |
3954 |
+ (define_insn "*call_pop" |
3955 |
+- [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lmBz")) |
3956 |
++ [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lBwBz")) |
3957 |
+ (match_operand 1)) |
3958 |
+ (set (reg:SI SP_REG) |
3959 |
+ (plus:SI (reg:SI SP_REG) |
3960 |
+@@ -11910,7 +11914,7 @@ |
3961 |
+ [(set_attr "type" "call")]) |
3962 |
+ |
3963 |
+ (define_insn "*sibcall_pop_memory" |
3964 |
+- [(call (mem:QI (match_operand:SI 0 "memory_operand" "m")) |
3965 |
++ [(call (mem:QI (match_operand:SI 0 "memory_operand" "Bs")) |
3966 |
+ (match_operand 1)) |
3967 |
+ (set (reg:SI SP_REG) |
3968 |
+ (plus:SI (reg:SI SP_REG) |
3969 |
+@@ -11964,7 +11968,9 @@ |
3970 |
+ [(set (match_operand:W 0 "register_operand") |
3971 |
+ (match_operand:W 1 "memory_operand")) |
3972 |
+ (set (pc) (match_dup 0))] |
3973 |
+- "!TARGET_X32 && peep2_reg_dead_p (2, operands[0])" |
3974 |
++ "!TARGET_X32 |
3975 |
++ && !ix86_indirect_branch_thunk_register |
3976 |
++ && peep2_reg_dead_p (2, operands[0])" |
3977 |
+ [(set (pc) (match_dup 1))]) |
3978 |
+ |
3979 |
+ ;; Call subroutine, returning value in operand 0 |
3980 |
+@@ -12045,7 +12051,7 @@ |
3981 |
+ (call (mem:QI (match_operand:W 1 "memory_operand" "m")) |
3982 |
+ (match_operand 2))) |
3983 |
+ (unspec [(const_int 0)] UNSPEC_PEEPSIB)] |
3984 |
+- "!TARGET_X32" |
3985 |
++ "!TARGET_X32 && !ix86_indirect_branch_thunk_register" |
3986 |
+ "* return ix86_output_call_insn (insn, operands[1]);" |
3987 |
+ [(set_attr "type" "callv")]) |
3988 |
+ |
3989 |
+@@ -12055,7 +12061,9 @@ |
3990 |
+ (set (match_operand 2) |
3991 |
+ (call (mem:QI (match_dup 0)) |
3992 |
+ (match_operand 3)))] |
3993 |
+- "!TARGET_X32 && SIBLING_CALL_P (peep2_next_insn (1)) |
3994 |
++ "!TARGET_X32 |
3995 |
++ && !ix86_indirect_branch_thunk_register |
3996 |
++ && SIBLING_CALL_P (peep2_next_insn (1)) |
3997 |
+ && !reg_mentioned_p (operands[0], |
3998 |
+ CALL_INSN_FUNCTION_USAGE (peep2_next_insn (1)))" |
3999 |
+ [(parallel [(set (match_dup 2) |
4000 |
+@@ -12070,7 +12078,9 @@ |
4001 |
+ (set (match_operand 2) |
4002 |
+ (call (mem:QI (match_dup 0)) |
4003 |
+ (match_operand 3)))] |
4004 |
+- "!TARGET_X32 && SIBLING_CALL_P (peep2_next_insn (2)) |
4005 |
++ "!TARGET_X32 |
4006 |
++ && !ix86_indirect_branch_thunk_register |
4007 |
++ && SIBLING_CALL_P (peep2_next_insn (2)) |
4008 |
+ && !reg_mentioned_p (operands[0], |
4009 |
+ CALL_INSN_FUNCTION_USAGE (peep2_next_insn (2)))" |
4010 |
+ [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE) |
4011 |
+@@ -12095,7 +12105,7 @@ |
4012 |
+ |
4013 |
+ (define_insn "*call_value_pop" |
4014 |
+ [(set (match_operand 0) |
4015 |
+- (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lmBz")) |
4016 |
++ (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lBwBz")) |
4017 |
+ (match_operand 2))) |
4018 |
+ (set (reg:SI SP_REG) |
4019 |
+ (plus:SI (reg:SI SP_REG) |
4020 |
+diff -Naur gcc-7.2.0.orig/gcc/config/i386/i386.opt gcc-7.2.0/gcc/config/i386/i386.opt |
4021 |
+--- gcc-7.2.0.orig/gcc/config/i386/i386.opt 2018-01-15 18:36:46.572698448 -0800 |
4022 |
++++ gcc-7.2.0/gcc/config/i386/i386.opt 2018-01-15 18:44:35.515690050 -0800 |
4023 |
+@@ -951,3 +951,7 @@ |
4024 |
+ |
4025 |
+ EnumValue |
4026 |
+ Enum(indirect_branch) String(thunk-extern) Value(indirect_branch_thunk_extern) |
4027 |
++ |
4028 |
++mindirect-branch-register |
4029 |
++Target Report Var(ix86_indirect_branch_thunk_register) Init(0) |
4030 |
++Force indirect call and jump via register. |
4031 |
+diff -Naur gcc-7.2.0.orig/gcc/config/i386/predicates.md gcc-7.2.0/gcc/config/i386/predicates.md |
4032 |
+--- gcc-7.2.0.orig/gcc/config/i386/predicates.md 2018-01-15 18:36:46.564698448 -0800 |
4033 |
++++ gcc-7.2.0/gcc/config/i386/predicates.md 2018-01-15 18:46:50.757687629 -0800 |
4034 |
+@@ -635,7 +635,8 @@ |
4035 |
+ ;; Test for a valid operand for indirect branch. |
4036 |
+ (define_predicate "indirect_branch_operand" |
4037 |
+ (ior (match_operand 0 "register_operand") |
4038 |
+- (and (not (match_test "TARGET_X32")) |
4039 |
++ (and (not (match_test "TARGET_X32 |
4040 |
++ || ix86_indirect_branch_thunk_register")) |
4041 |
+ (match_operand 0 "memory_operand")))) |
4042 |
+ |
4043 |
+ ;; Return true if OP is a memory operands that can be used in sibcalls. |
4044 |
+@@ -664,7 +665,8 @@ |
4045 |
+ |
4046 |
+ ;; Return true if OP is a GOT memory operand. |
4047 |
+ (define_predicate "GOT_memory_operand" |
4048 |
+- (match_operand 0 "memory_operand") |
4049 |
++ (and (match_test "!ix86_indirect_branch_thunk_register") |
4050 |
++ (match_operand 0 "memory_operand")) |
4051 |
+ { |
4052 |
+ op = XEXP (op, 0); |
4053 |
+ return (GET_CODE (op) == CONST |
4054 |
+@@ -678,9 +680,11 @@ |
4055 |
+ (ior (match_test "constant_call_address_operand |
4056 |
+ (op, mode == VOIDmode ? mode : Pmode)") |
4057 |
+ (match_operand 0 "call_register_no_elim_operand") |
4058 |
+- (ior (and (not (match_test "TARGET_X32")) |
4059 |
++ (ior (and (not (match_test "TARGET_X32 |
4060 |
++ || ix86_indirect_branch_thunk_register")) |
4061 |
+ (match_operand 0 "memory_operand")) |
4062 |
+- (and (match_test "TARGET_X32 && Pmode == DImode") |
4063 |
++ (and (match_test "TARGET_X32 && Pmode == DImode |
4064 |
++ && !ix86_indirect_branch_thunk_register") |
4065 |
+ (match_operand 0 "GOT_memory_operand"))))) |
4066 |
+ |
4067 |
+ ;; Similarly, but for tail calls, in which we cannot allow memory references. |
4068 |
+@@ -688,14 +692,17 @@ |
4069 |
+ (ior (match_test "constant_call_address_operand |
4070 |
+ (op, mode == VOIDmode ? mode : Pmode)") |
4071 |
+ (match_operand 0 "register_no_elim_operand") |
4072 |
+- (ior (and (not (match_test "TARGET_X32")) |
4073 |
++ (ior (and (not (match_test "TARGET_X32 |
4074 |
++ || ix86_indirect_branch_thunk_register")) |
4075 |
+ (match_operand 0 "sibcall_memory_operand")) |
4076 |
+- (and (match_test "TARGET_X32 && Pmode == DImode") |
4077 |
++ (and (match_test "TARGET_X32 && Pmode == DImode |
4078 |
++ && !ix86_indirect_branch_thunk_register") |
4079 |
+ (match_operand 0 "GOT_memory_operand"))))) |
4080 |
+ |
4081 |
+ ;; Return true if OP is a 32-bit GOT symbol operand. |
4082 |
+ (define_predicate "GOT32_symbol_operand" |
4083 |
+- (match_test "GET_CODE (op) == CONST |
4084 |
++ (match_test "!ix86_indirect_branch_thunk_register |
4085 |
++ && GET_CODE (op) == CONST |
4086 |
+ && GET_CODE (XEXP (op, 0)) == UNSPEC |
4087 |
+ && XINT (XEXP (op, 0), 1) == UNSPEC_GOT")) |
4088 |
+ |
4089 |
+diff -Naur gcc-7.2.0.orig/gcc/doc/invoke.texi gcc-7.2.0/gcc/doc/invoke.texi |
4090 |
+--- gcc-7.2.0.orig/gcc/doc/invoke.texi 2018-01-15 18:36:44.485698486 -0800 |
4091 |
++++ gcc-7.2.0/gcc/doc/invoke.texi 2018-01-15 18:47:25.682687003 -0800 |
4092 |
+@@ -1211,7 +1211,8 @@ |
4093 |
+ -mavx256-split-unaligned-load -mavx256-split-unaligned-store @gol |
4094 |
+ -malign-data=@var{type} -mstack-protector-guard=@var{guard} @gol |
4095 |
+ -mmitigate-rop -mgeneral-regs-only @gol |
4096 |
+--mindirect-branch=@var{choice} -mfunction-return==@var{choice}} |
4097 |
++-mindirect-branch=@var{choice} -mfunction-return==@var{choice} @gol |
4098 |
++-mindirect-branch-register} |
4099 |
+ |
4100 |
+ @emph{x86 Windows Options} |
4101 |
+ @gccoptlist{-mconsole -mcygwin -mno-cygwin -mdll @gol |
4102 |
+@@ -25671,6 +25672,10 @@ |
4103 |
+ using the function attribute @code{function_return}. |
4104 |
+ @xref{Function Attributes}. |
4105 |
+ |
4106 |
++@item -mindirect-branch-register |
4107 |
++@opindex -mindirect-branch-register |
4108 |
++Force indirect call and jump via register. |
4109 |
++ |
4110 |
+ @end table |
4111 |
+ |
4112 |
+ These @samp{-m} switches are supported in addition to the above |
4113 |
+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-1.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-1.c |
4114 |
+index 527e447aea5..3f9b5f58ecc 100644 |
4115 |
+--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-1.c |
4116 |
++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-1.c |
4117 |
+@@ -1,5 +1,5 @@ |
4118 |
+ /* { dg-do compile } */ |
4119 |
+-/* { dg-options "-O2 -mfunction-return=keep -mindirect-branch=thunk -fno-pic" } */ |
4120 |
++/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=keep -mindirect-branch=thunk -fno-pic" } */ |
4121 |
+ |
4122 |
+ typedef void (*dispatch_t)(long offset); |
4123 |
+ |
4124 |
+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-2.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-2.c |
4125 |
+index 7dbc7607e2e..19f4d5e3a1e 100644 |
4126 |
+--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-2.c |
4127 |
++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-2.c |
4128 |
+@@ -1,5 +1,5 @@ |
4129 |
+ /* { dg-do compile } */ |
4130 |
+-/* { dg-options "-O2 -mfunction-return=keep -mindirect-branch=thunk -fno-pic" } */ |
4131 |
++/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=keep -mindirect-branch=thunk -fno-pic" } */ |
4132 |
+ |
4133 |
+ typedef void (*dispatch_t)(long offset); |
4134 |
+ |
4135 |
+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-3.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-3.c |
4136 |
+index c085b21582c..304a641db28 100644 |
4137 |
+--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-3.c |
4138 |
++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-3.c |
4139 |
+@@ -1,5 +1,5 @@ |
4140 |
+ /* { dg-do compile } */ |
4141 |
+-/* { dg-options "-O2 -mfunction-return=keep -mindirect-branch=thunk -fno-pic" } */ |
4142 |
++/* { dg-options "-O2 -mno-indirect-branch-register -mno-indirect-branch-register -mno-indirect-branch-register -mfunction-return=keep -mindirect-branch=thunk -fno-pic" } */ |
4143 |
+ |
4144 |
+ typedef void (*dispatch_t)(long offset); |
4145 |
+ |
4146 |
+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-4.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-4.c |
4147 |
+index f92968bf616..c4eabadea7d 100644 |
4148 |
+--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-4.c |
4149 |
++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-4.c |
4150 |
+@@ -1,5 +1,5 @@ |
4151 |
+ /* { dg-do compile } */ |
4152 |
+-/* { dg-options "-O2 -mfunction-return=keep -mindirect-branch=thunk -fno-pic" } */ |
4153 |
++/* { dg-options "-O2 -mno-indirect-branch-register -mno-indirect-branch-register -mno-indirect-branch-register -mfunction-return=keep -mindirect-branch=thunk -fno-pic" } */ |
4154 |
+ |
4155 |
+ typedef void (*dispatch_t)(long offset); |
4156 |
+ |
4157 |
+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-5.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-5.c |
4158 |
+index 4d19fac21d8..defe4389354 100644 |
4159 |
+--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-5.c |
4160 |
++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-5.c |
4161 |
+@@ -1,5 +1,5 @@ |
4162 |
+ /* { dg-do compile { target *-*-linux* } } */ |
4163 |
+-/* { dg-options "-O2 -mfunction-return=keep -fpic -fno-plt -mindirect-branch=thunk" } */ |
4164 |
++/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=keep -fpic -fno-plt -mindirect-branch=thunk" } */ |
4165 |
+ |
4166 |
+ extern void bar (void); |
4167 |
+ |
4168 |
+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-6.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-6.c |
4169 |
+index 5cbdd85303e..5b202526968 100644 |
4170 |
+--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-6.c |
4171 |
++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-6.c |
4172 |
+@@ -1,5 +1,5 @@ |
4173 |
+ /* { dg-do compile { target *-*-linux* } } */ |
4174 |
+-/* { dg-options "-O2 -mfunction-return=keep -fpic -fno-plt -mindirect-branch=thunk" } */ |
4175 |
++/* { dg-options "-O2 -mno-indirect-branch-register -mno-indirect-branch-register -mno-indirect-branch-register -mfunction-return=keep -fpic -fno-plt -mindirect-branch=thunk" } */ |
4176 |
+ |
4177 |
+ extern void bar (void); |
4178 |
+ |
4179 |
+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-7.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-7.c |
4180 |
+index c59dd049883..d5aa68f52ca 100644 |
4181 |
+--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-7.c |
4182 |
++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-7.c |
4183 |
+@@ -1,5 +1,5 @@ |
4184 |
+ /* { dg-do compile } */ |
4185 |
+-/* { dg-options "-O2 -mfunction-return=keep -mindirect-branch=thunk -fno-pic" } */ |
4186 |
++/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=keep -mindirect-branch=thunk -fno-pic" } */ |
4187 |
+ |
4188 |
+ void func0 (void); |
4189 |
+ void func1 (void); |
4190 |
+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-1.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-1.c |
4191 |
+index 61b9c80de33..09c35e73443 100644 |
4192 |
+--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-1.c |
4193 |
++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-1.c |
4194 |
+@@ -1,5 +1,5 @@ |
4195 |
+ /* { dg-do compile } */ |
4196 |
+-/* { dg-options "-O2 -mfunction-return=keep -fno-pic" } */ |
4197 |
++/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=keep -fno-pic" } */ |
4198 |
+ |
4199 |
+ typedef void (*dispatch_t)(long offset); |
4200 |
+ |
4201 |
+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-2.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-2.c |
4202 |
+index dcd2381c514..246300e8d71 100644 |
4203 |
+--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-2.c |
4204 |
++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-2.c |
4205 |
+@@ -1,5 +1,5 @@ |
4206 |
+ /* { dg-do compile } */ |
4207 |
+-/* { dg-options "-O2 -mfunction-return=keep -fno-pic" } */ |
4208 |
++/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=keep -fno-pic" } */ |
4209 |
+ |
4210 |
+ typedef void (*dispatch_t)(long offset); |
4211 |
+ |
4212 |
+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-3.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-3.c |
4213 |
+index 21b69728796..02223f8d0f4 100644 |
4214 |
+--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-3.c |
4215 |
++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-3.c |
4216 |
+@@ -1,5 +1,5 @@ |
4217 |
+ /* { dg-do compile } */ |
4218 |
+-/* { dg-options "-O2 -mfunction-return=keep -fno-pic" } */ |
4219 |
++/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=keep -fno-pic" } */ |
4220 |
+ |
4221 |
+ typedef void (*dispatch_t)(long offset); |
4222 |
+ |
4223 |
+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-4.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-4.c |
4224 |
+index 0bd6aab2fd6..a80b46af934 100644 |
4225 |
+--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-4.c |
4226 |
++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-4.c |
4227 |
+@@ -1,5 +1,5 @@ |
4228 |
+ /* { dg-do compile } */ |
4229 |
+-/* { dg-options "-O2 -mfunction-return=keep -fno-pic" } */ |
4230 |
++/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=keep -fno-pic" } */ |
4231 |
+ |
4232 |
+ typedef void (*dispatch_t)(long offset); |
4233 |
+ |
4234 |
+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-5.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-5.c |
4235 |
+index 99226dbdd1f..e85057bc098 100644 |
4236 |
+--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-5.c |
4237 |
++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-5.c |
4238 |
+@@ -1,5 +1,5 @@ |
4239 |
+ /* { dg-do compile } */ |
4240 |
+-/* { dg-options "-O2 -mfunction-return=keep -fno-pic" } */ |
4241 |
++/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=keep -fno-pic" } */ |
4242 |
+ |
4243 |
+ typedef void (*dispatch_t)(long offset); |
4244 |
+ |
4245 |
+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-6.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-6.c |
4246 |
+index aceb4041275..50a2d72ae16 100644 |
4247 |
+--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-6.c |
4248 |
++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-6.c |
4249 |
+@@ -1,5 +1,5 @@ |
4250 |
+ /* { dg-do compile } */ |
4251 |
+-/* { dg-options "-O2 -mfunction-return=keep -fno-pic" } */ |
4252 |
++/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=keep -fno-pic" } */ |
4253 |
+ |
4254 |
+ typedef void (*dispatch_t)(long offset); |
4255 |
+ |
4256 |
+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-7.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-7.c |
4257 |
+index 43d19bbe876..eac9b3dee22 100644 |
4258 |
+--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-7.c |
4259 |
++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-7.c |
4260 |
+@@ -1,5 +1,5 @@ |
4261 |
+ /* { dg-do compile } */ |
4262 |
+-/* { dg-options "-O2 -mfunction-return=keep -fno-pic" } */ |
4263 |
++/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=keep -fno-pic" } */ |
4264 |
+ |
4265 |
+ void func0 (void); |
4266 |
+ void func1 (void); |
4267 |
+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-1.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-1.c |
4268 |
+index bbfaf6ba7e7..58285f6ee6c 100644 |
4269 |
+--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-1.c |
4270 |
++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-1.c |
4271 |
+@@ -1,5 +1,5 @@ |
4272 |
+ /* { dg-do compile { target { ! x32 } } } */ |
4273 |
+-/* { dg-options "-O2 -mfunction-return=keep -mindirect-branch=thunk -fcheck-pointer-bounds -mmpx -fno-pic" } */ |
4274 |
++/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=keep -mindirect-branch=thunk -fcheck-pointer-bounds -mmpx -fno-pic" } */ |
4275 |
+ |
4276 |
+ void (*dispatch) (char *); |
4277 |
+ char buf[10]; |
4278 |
+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-2.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-2.c |
4279 |
+index 6c82a236c1b..d3dec5623eb 100644 |
4280 |
+--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-2.c |
4281 |
++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-2.c |
4282 |
+@@ -1,5 +1,5 @@ |
4283 |
+ /* { dg-do compile { target { ! x32 } } } */ |
4284 |
+-/* { dg-options "-O2 -mfunction-return=keep -mindirect-branch=thunk -fcheck-pointer-bounds -mmpx -fno-pic" } */ |
4285 |
++/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=keep -mindirect-branch=thunk -fcheck-pointer-bounds -mmpx -fno-pic" } */ |
4286 |
+ |
4287 |
+ void (*dispatch) (char *); |
4288 |
+ char buf[10]; |
4289 |
+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-3.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-3.c |
4290 |
+index 299940de399..c2e07d59ca4 100644 |
4291 |
+--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-3.c |
4292 |
++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-3.c |
4293 |
+@@ -1,5 +1,5 @@ |
4294 |
+ /* { dg-do compile { target { *-*-linux* && { ! x32 } } } } */ |
4295 |
+-/* { dg-options "-O2 -mfunction-return=keep -mindirect-branch=thunk -fcheck-pointer-bounds -mmpx -fpic -fno-plt" } */ |
4296 |
++/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=keep -mindirect-branch=thunk -fcheck-pointer-bounds -mmpx -fpic -fno-plt" } */ |
4297 |
+ |
4298 |
+ void bar (char *); |
4299 |
+ char buf[10]; |
4300 |
+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-4.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-4.c |
4301 |
+index 77ee84b938b..16b64a46dbd 100644 |
4302 |
+--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-4.c |
4303 |
++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-4.c |
4304 |
+@@ -1,5 +1,5 @@ |
4305 |
+ /* { dg-do compile { target { *-*-linux* && { ! x32 } } } } */ |
4306 |
+-/* { dg-options "-O2 -mfunction-return=keep -mindirect-branch=thunk -fcheck-pointer-bounds -mmpx -fpic -fno-plt" } */ |
4307 |
++/* { dg-options "-O2 -mno-indirect-branch-register -mno-indirect-branch-register -mfunction-return=keep -mindirect-branch=thunk -fcheck-pointer-bounds -mmpx -fpic -fno-plt" } */ |
4308 |
+ |
4309 |
+ void bar (char *); |
4310 |
+ char buf[10]; |
4311 |
+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-1.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-1.c |
4312 |
+index 782960375af..cf499879513 100644 |
4313 |
+--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-1.c |
4314 |
++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-1.c |
4315 |
+@@ -1,5 +1,5 @@ |
4316 |
+ /* { dg-do compile } */ |
4317 |
+-/* { dg-options "-O2 -mfunction-return=keep -mindirect-branch=thunk-extern -fno-pic" } */ |
4318 |
++/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=keep -mindirect-branch=thunk-extern -fno-pic" } */ |
4319 |
+ |
4320 |
+ typedef void (*dispatch_t)(long offset); |
4321 |
+ |
4322 |
+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-2.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-2.c |
4323 |
+index 240c15be8a6..54c6e300295 100644 |
4324 |
+--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-2.c |
4325 |
++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-2.c |
4326 |
+@@ -1,5 +1,5 @@ |
4327 |
+ /* { dg-do compile } */ |
4328 |
+-/* { dg-options "-O2 -mfunction-return=keep -mindirect-branch=thunk-extern -fno-pic" } */ |
4329 |
++/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=keep -mindirect-branch=thunk-extern -fno-pic" } */ |
4330 |
+ |
4331 |
+ typedef void (*dispatch_t)(long offset); |
4332 |
+ |
4333 |
+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-3.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-3.c |
4334 |
+index 6e49707875e..925c7943662 100644 |
4335 |
+--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-3.c |
4336 |
++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-3.c |
4337 |
+@@ -1,5 +1,5 @@ |
4338 |
+ /* { dg-do compile } */ |
4339 |
+-/* { dg-options "-O2 -mfunction-return=keep -mindirect-branch=thunk-extern -fno-pic" } */ |
4340 |
++/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=keep -mindirect-branch=thunk-extern -fno-pic" } */ |
4341 |
+ |
4342 |
+ typedef void (*dispatch_t)(long offset); |
4343 |
+ |
4344 |
+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-4.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-4.c |
4345 |
+index e1d8891380c..0f7e39f914a 100644 |
4346 |
+--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-4.c |
4347 |
++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-4.c |
4348 |
+@@ -1,5 +1,5 @@ |
4349 |
+ /* { dg-do compile } */ |
4350 |
+-/* { dg-options "-O2 -mfunction-return=keep -mindirect-branch=thunk-extern -fno-pic" } */ |
4351 |
++/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=keep -mindirect-branch=thunk-extern -fno-pic" } */ |
4352 |
+ |
4353 |
+ typedef void (*dispatch_t)(long offset); |
4354 |
+ |
4355 |
+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-5.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-5.c |
4356 |
+index 6ad05b70604..1d34cb197a7 100644 |
4357 |
+--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-5.c |
4358 |
++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-5.c |
4359 |
+@@ -1,5 +1,5 @@ |
4360 |
+ /* { dg-do compile { target *-*-linux* } } */ |
4361 |
+-/* { dg-options "-O2 -mfunction-return=keep -fpic -fno-plt -mindirect-branch=thunk-extern" } */ |
4362 |
++/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=keep -fpic -fno-plt -mindirect-branch=thunk-extern" } */ |
4363 |
+ |
4364 |
+ extern void bar (void); |
4365 |
+ |
4366 |
+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-6.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-6.c |
4367 |
+index cfb0894ae49..8d591d562a5 100644 |
4368 |
+--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-6.c |
4369 |
++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-6.c |
4370 |
+@@ -1,5 +1,5 @@ |
4371 |
+ /* { dg-do compile { target *-*-linux* } } */ |
4372 |
+-/* { dg-options "-O2 -mfunction-return=keep -fpic -fno-plt -mindirect-branch=thunk-extern" } */ |
4373 |
++/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=keep -fpic -fno-plt -mindirect-branch=thunk-extern" } */ |
4374 |
+ |
4375 |
+ extern void bar (void); |
4376 |
+ |
4377 |
+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-7.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-7.c |
4378 |
+index 205b9b405bf..a288e3d61b9 100644 |
4379 |
+--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-7.c |
4380 |
++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-7.c |
4381 |
+@@ -1,5 +1,5 @@ |
4382 |
+ /* { dg-do compile } */ |
4383 |
+-/* { dg-options "-O2 -mfunction-return=keep -mindirect-branch=thunk-extern -fno-pic" } */ |
4384 |
++/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=keep -mindirect-branch=thunk-extern -fno-pic" } */ |
4385 |
+ |
4386 |
+ void func0 (void); |
4387 |
+ void func1 (void); |
4388 |
+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-1.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-1.c |
4389 |
+index efa0096e1e0..f7fad345ca4 100644 |
4390 |
+--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-1.c |
4391 |
++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-1.c |
4392 |
+@@ -1,5 +1,5 @@ |
4393 |
+ /* { dg-do compile } */ |
4394 |
+-/* { dg-options "-O2 -mfunction-return=keep -mindirect-branch=thunk-inline -fno-pic" } */ |
4395 |
++/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=keep -mindirect-branch=thunk-inline -fno-pic" } */ |
4396 |
+ |
4397 |
+ typedef void (*dispatch_t)(long offset); |
4398 |
+ |
4399 |
+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-2.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-2.c |
4400 |
+index 775d0b8c53e..91388544a20 100644 |
4401 |
+--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-2.c |
4402 |
++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-2.c |
4403 |
+@@ -1,5 +1,5 @@ |
4404 |
+ /* { dg-do compile } */ |
4405 |
+-/* { dg-options "-O2 -mfunction-return=keep -mindirect-branch=thunk-inline -fno-pic" } */ |
4406 |
++/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=keep -mindirect-branch=thunk-inline -fno-pic" } */ |
4407 |
+ |
4408 |
+ typedef void (*dispatch_t)(long offset); |
4409 |
+ |
4410 |
+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-3.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-3.c |
4411 |
+index 788271f049f..69f03e6472e 100644 |
4412 |
+--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-3.c |
4413 |
++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-3.c |
4414 |
+@@ -1,5 +1,5 @@ |
4415 |
+ /* { dg-do compile } */ |
4416 |
+-/* { dg-options "-O2 -mfunction-return=keep -mindirect-branch=thunk-inline -fno-pic" } */ |
4417 |
++/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=keep -mindirect-branch=thunk-inline -fno-pic" } */ |
4418 |
+ |
4419 |
+ typedef void (*dispatch_t)(long offset); |
4420 |
+ |
4421 |
+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-4.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-4.c |
4422 |
+index ef8a2c746a7..226b776abcf 100644 |
4423 |
+--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-4.c |
4424 |
++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-4.c |
4425 |
+@@ -1,5 +1,5 @@ |
4426 |
+ /* { dg-do compile } */ |
4427 |
+-/* { dg-options "-O2 -mfunction-return=keep -mindirect-branch=thunk-inline -fno-pic" } */ |
4428 |
++/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=keep -mindirect-branch=thunk-inline -fno-pic" } */ |
4429 |
+ |
4430 |
+ typedef void (*dispatch_t)(long offset); |
4431 |
+ |
4432 |
+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-5.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-5.c |
4433 |
+index 848ceefca02..b9120017c10 100644 |
4434 |
+--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-5.c |
4435 |
++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-5.c |
4436 |
+@@ -1,5 +1,5 @@ |
4437 |
+ /* { dg-do compile { target *-*-linux* } } */ |
4438 |
+-/* { dg-options "-O2 -mfunction-return=keep -fpic -fno-plt -mindirect-branch=thunk-inline" } */ |
4439 |
++/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=keep -fpic -fno-plt -mindirect-branch=thunk-inline" } */ |
4440 |
+ |
4441 |
+ extern void bar (void); |
4442 |
+ |
4443 |
+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-6.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-6.c |
4444 |
+index 64608100782..fbd6f9ec457 100644 |
4445 |
+--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-6.c |
4446 |
++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-6.c |
4447 |
+@@ -1,5 +1,5 @@ |
4448 |
+ /* { dg-do compile { target *-*-linux* } } */ |
4449 |
+-/* { dg-options "-O2 -mfunction-return=keep -fpic -fno-plt -mindirect-branch=thunk-inline" } */ |
4450 |
++/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=keep -fpic -fno-plt -mindirect-branch=thunk-inline" } */ |
4451 |
+ |
4452 |
+ extern void bar (void); |
4453 |
+ |
4454 |
+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-7.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-7.c |
4455 |
+index 3c2758360f5..2553c56f97f 100644 |
4456 |
+--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-7.c |
4457 |
++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-7.c |
4458 |
+@@ -1,5 +1,5 @@ |
4459 |
+ /* { dg-do compile } */ |
4460 |
+-/* { dg-options "-O2 -mfunction-return=keep -mindirect-branch=thunk-inline -fno-pic" } */ |
4461 |
++/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=keep -mindirect-branch=thunk-inline -fno-pic" } */ |
4462 |
+ |
4463 |
+ void func0 (void); |
4464 |
+ void func1 (void); |
4465 |
+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-register-1.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-register-1.c |
4466 |
+new file mode 100644 |
4467 |
+index 00000000000..7d396a31953 |
4468 |
+--- /dev/null |
4469 |
++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-register-1.c |
4470 |
+@@ -0,0 +1,22 @@ |
4471 |
++/* { dg-do compile } */ |
4472 |
++/* { dg-options "-O2 -mindirect-branch=thunk -mindirect-branch-register -fno-pic" } */ |
4473 |
++ |
4474 |
++typedef void (*dispatch_t)(long offset); |
4475 |
++ |
4476 |
++dispatch_t dispatch; |
4477 |
++ |
4478 |
++void |
4479 |
++male_indirect_jump (long offset) |
4480 |
++{ |
4481 |
++ dispatch(offset); |
4482 |
++} |
4483 |
++ |
4484 |
++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk_(r|e)ax" } } */ |
4485 |
++/* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */ |
4486 |
++/* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */ |
4487 |
++/* { dg-final { scan-assembler "mov\[ \t\](%eax|%rax), \\((%esp|%rsp)\\)" } } */ |
4488 |
++/* { dg-final { scan-assembler {\tpause} } } */ |
4489 |
++/* { dg-final { scan-assembler-not "push(?:l|q)\[ \t\]*_?dispatch" } } */ |
4490 |
++/* { dg-final { scan-assembler-not "pushq\[ \t\]%rax" } } */ |
4491 |
++/* { dg-final { scan-assembler-not "__x86_indirect_thunk\n" } } */ |
4492 |
++/* { dg-final { scan-assembler-not "__x86_indirect_thunk_bnd\n" } } */ |
4493 |
+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-register-2.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-register-2.c |
4494 |
+new file mode 100644 |
4495 |
+index 00000000000..e7e616bb271 |
4496 |
+--- /dev/null |
4497 |
++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-register-2.c |
4498 |
+@@ -0,0 +1,20 @@ |
4499 |
++/* { dg-do compile } */ |
4500 |
++/* { dg-options "-O2 -mindirect-branch=thunk-inline -mindirect-branch-register -fno-pic" } */ |
4501 |
++ |
4502 |
++typedef void (*dispatch_t)(long offset); |
4503 |
++ |
4504 |
++dispatch_t dispatch; |
4505 |
++ |
4506 |
++void |
4507 |
++male_indirect_jump (long offset) |
4508 |
++{ |
4509 |
++ dispatch(offset); |
4510 |
++} |
4511 |
++ |
4512 |
++/* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */ |
4513 |
++/* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */ |
4514 |
++/* { dg-final { scan-assembler "mov\[ \t\](%eax|%rax), \\((%esp|%rsp)\\)" } } */ |
4515 |
++/* { dg-final { scan-assembler {\tpause} } } */ |
4516 |
++/* { dg-final { scan-assembler-not "push(?:l|q)\[ \t\]*_?dispatch" } } */ |
4517 |
++/* { dg-final { scan-assembler-not "pushq\[ \t\]%rax" } } */ |
4518 |
++/* { dg-final { scan-assembler-not "__x86_indirect_thunk" } } */ |
4519 |
+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-register-3.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-register-3.c |
4520 |
+new file mode 100644 |
4521 |
+index 00000000000..5320e923be2 |
4522 |
+--- /dev/null |
4523 |
++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-register-3.c |
4524 |
+@@ -0,0 +1,19 @@ |
4525 |
++/* { dg-do compile } */ |
4526 |
++/* { dg-options "-O2 -mindirect-branch=thunk-extern -mindirect-branch-register -fno-pic" } */ |
4527 |
++ |
4528 |
++typedef void (*dispatch_t)(long offset); |
4529 |
++ |
4530 |
++dispatch_t dispatch; |
4531 |
++ |
4532 |
++void |
4533 |
++male_indirect_jump (long offset) |
4534 |
++{ |
4535 |
++ dispatch(offset); |
4536 |
++} |
4537 |
++ |
4538 |
++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk_(r|e)ax" } } */ |
4539 |
++/* { dg-final { scan-assembler-not "push(?:l|q)\[ \t\]*_?dispatch" } } */ |
4540 |
++/* { dg-final { scan-assembler-not "pushq\[ \t\]%rax" } } */ |
4541 |
++/* { dg-final { scan-assembler-not {\t(pause|pause|nop)} } } */ |
4542 |
++/* { dg-final { scan-assembler-not "jmp\[ \t\]*\.LIND" } } */ |
4543 |
++/* { dg-final { scan-assembler-not "call\[ \t\]*\.LIND" } } */ |
4544 |
+diff --git a/gcc/testsuite/gcc.target/i386/ret-thunk-10.c b/gcc/testsuite/gcc.target/i386/ret-thunk-10.c |
4545 |
+index b5164bfc5ad..c440d68ec0d 100644 |
4546 |
+--- a/gcc/testsuite/gcc.target/i386/ret-thunk-10.c |
4547 |
++++ b/gcc/testsuite/gcc.target/i386/ret-thunk-10.c |
4548 |
+@@ -1,5 +1,5 @@ |
4549 |
+ /* { dg-do compile } */ |
4550 |
+-/* { dg-options "-O2 -mfunction-return=thunk-inline -mindirect-branch=thunk -fno-pic" } */ |
4551 |
++/* { dg-options "-O2 -mno-indirect-branch-register -mno-indirect-branch-register -mfunction-return=thunk-inline -mindirect-branch=thunk -fno-pic" } */ |
4552 |
+ |
4553 |
+ extern void (*bar) (void); |
4554 |
+ |
4555 |
+diff --git a/gcc/testsuite/gcc.target/i386/ret-thunk-11.c b/gcc/testsuite/gcc.target/i386/ret-thunk-11.c |
4556 |
+index a26ac963ea5..674a6bf96e8 100644 |
4557 |
+--- a/gcc/testsuite/gcc.target/i386/ret-thunk-11.c |
4558 |
++++ b/gcc/testsuite/gcc.target/i386/ret-thunk-11.c |
4559 |
+@@ -1,5 +1,5 @@ |
4560 |
+ /* { dg-do compile } */ |
4561 |
+-/* { dg-options "-O2 -mfunction-return=thunk-extern -mindirect-branch=thunk -fno-pic" } */ |
4562 |
++/* { dg-options "-O2 -mno-indirect-branch-register -mno-indirect-branch-register -mno-indirect-branch-register -mno-indirect-branch-register -mfunction-return=thunk-extern -mindirect-branch=thunk -fno-pic" } */ |
4563 |
+ |
4564 |
+ extern void (*bar) (void); |
4565 |
+ |
4566 |
+diff --git a/gcc/testsuite/gcc.target/i386/ret-thunk-12.c b/gcc/testsuite/gcc.target/i386/ret-thunk-12.c |
4567 |
+index d0106da38ee..3f37e4375de 100644 |
4568 |
+--- a/gcc/testsuite/gcc.target/i386/ret-thunk-12.c |
4569 |
++++ b/gcc/testsuite/gcc.target/i386/ret-thunk-12.c |
4570 |
+@@ -1,5 +1,5 @@ |
4571 |
+ /* { dg-do compile } */ |
4572 |
+-/* { dg-options "-O2 -mfunction-return=keep -mindirect-branch=thunk -fno-pic" } */ |
4573 |
++/* { dg-options "-O2 -mno-indirect-branch-register -mno-indirect-branch-register -mno-indirect-branch-register -mno-indirect-branch-register -mfunction-return=keep -mindirect-branch=thunk -fno-pic" } */ |
4574 |
+ |
4575 |
+ extern void (*bar) (void); |
4576 |
+ |
4577 |
+diff --git a/gcc/testsuite/gcc.target/i386/ret-thunk-13.c b/gcc/testsuite/gcc.target/i386/ret-thunk-13.c |
4578 |
+index 185ad366190..f96e6847f13 100644 |
4579 |
+--- a/gcc/testsuite/gcc.target/i386/ret-thunk-13.c |
4580 |
++++ b/gcc/testsuite/gcc.target/i386/ret-thunk-13.c |
4581 |
+@@ -1,5 +1,5 @@ |
4582 |
+ /* { dg-do compile } */ |
4583 |
+-/* { dg-options "-O2 -mfunction-return=keep -mindirect-branch=thunk-inline -fno-pic" } */ |
4584 |
++/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=keep -mindirect-branch=thunk-inline -fno-pic" } */ |
4585 |
+ |
4586 |
+ extern void (*bar) (void); |
4587 |
+ extern int foo (void) __attribute__ ((function_return("thunk"))); |
4588 |
+diff --git a/gcc/testsuite/gcc.target/i386/ret-thunk-14.c b/gcc/testsuite/gcc.target/i386/ret-thunk-14.c |
4589 |
+index cce8b20b5f1..4c47b28691e 100644 |
4590 |
+--- a/gcc/testsuite/gcc.target/i386/ret-thunk-14.c |
4591 |
++++ b/gcc/testsuite/gcc.target/i386/ret-thunk-14.c |
4592 |
+@@ -1,5 +1,5 @@ |
4593 |
+ /* { dg-do compile } */ |
4594 |
+-/* { dg-options "-O2 -mfunction-return=keep -mindirect-branch=thunk-extern -fno-pic" } */ |
4595 |
++/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=keep -mindirect-branch=thunk-extern -fno-pic" } */ |
4596 |
+ |
4597 |
+ extern void (*bar) (void); |
4598 |
+ |
4599 |
+diff --git a/gcc/testsuite/gcc.target/i386/ret-thunk-15.c b/gcc/testsuite/gcc.target/i386/ret-thunk-15.c |
4600 |
+index 0316d301d9c..43d84743851 100644 |
4601 |
+--- a/gcc/testsuite/gcc.target/i386/ret-thunk-15.c |
4602 |
++++ b/gcc/testsuite/gcc.target/i386/ret-thunk-15.c |
4603 |
+@@ -1,5 +1,5 @@ |
4604 |
+ /* { dg-do compile } */ |
4605 |
+-/* { dg-options "-O2 -mfunction-return=keep -mindirect-branch=keep -fno-pic" } */ |
4606 |
++/* { dg-options "-O2 -mno-indirect-branch-register -mno-indirect-branch-register -mno-indirect-branch-register -mno-indirect-branch-register -mfunction-return=keep -mindirect-branch=keep -fno-pic" } */ |
4607 |
+ |
4608 |
+ extern void (*bar) (void); |
4609 |
+ |
4610 |
+diff --git a/gcc/testsuite/gcc.target/i386/ret-thunk-9.c b/gcc/testsuite/gcc.target/i386/ret-thunk-9.c |
4611 |
+index 92298c362ec..a56a4849f76 100644 |
4612 |
+--- a/gcc/testsuite/gcc.target/i386/ret-thunk-9.c |
4613 |
++++ b/gcc/testsuite/gcc.target/i386/ret-thunk-9.c |
4614 |
+@@ -1,5 +1,5 @@ |
4615 |
+ /* { dg-do compile } */ |
4616 |
+-/* { dg-options "-O2 -mfunction-return=thunk -mindirect-branch=thunk -fno-pic" } */ |
4617 |
++/* { dg-options "-O2 -mno-indirect-branch-register -mno-indirect-branch-register -mfunction-return=thunk -mindirect-branch=thunk -fno-pic" } */ |
4618 |
+ |
4619 |
+ extern void (*bar) (void); |
4620 |
+ |
4621 |
+-- |
4622 |
+2.14.3 |
4623 |
+ |
4624 |
|
4625 |
diff --git a/sys-devel/gcc/files/spectre-0004-v-register-modifier.patch b/sys-devel/gcc/files/spectre-0004-v-register-modifier.patch |
4626 |
new file mode 100644 |
4627 |
index 0000000..afbccca |
4628 |
--- /dev/null |
4629 |
+++ b/sys-devel/gcc/files/spectre-0004-v-register-modifier.patch |
4630 |
@@ -0,0 +1,128 @@ |
4631 |
+From: "H dot J dot Lu" <hjl dot tools at gmail dot com> |
4632 |
+To: gcc-patches at gcc dot gnu dot org |
4633 |
+Subject: [PATCH 4/4] x86: Add 'V' register operand modifier |
4634 |
+Date: Fri, 12 Jan 2018 05:15:49 -0800 |
4635 |
+ |
4636 |
+Add 'V', a special modifier which prints the name of the full integer |
4637 |
+register without '%'. For |
4638 |
+ |
4639 |
+extern void (*func_p) (void); |
4640 |
+ |
4641 |
+void |
4642 |
+foo (void) |
4643 |
+{ |
4644 |
+ asm ("call __x86_indirect_thunk_%V0" : : "a" (func_p)); |
4645 |
+} |
4646 |
+ |
4647 |
+it generates: |
4648 |
+ |
4649 |
+foo: |
4650 |
+ movq func_p(%rip), %rax |
4651 |
+ call __x86_indirect_thunk_rax |
4652 |
+ ret |
4653 |
+ |
4654 |
+gcc/ |
4655 |
+ |
4656 |
+ * config/i386/i386.c (print_reg): Print the name of the full |
4657 |
+ integer register without '%'. |
4658 |
+ (ix86_print_operand): Handle 'V'. |
4659 |
+ * doc/extend.texi: Document 'V' modifier. |
4660 |
+ |
4661 |
+gcc/testsuite/ |
4662 |
+ |
4663 |
+ * gcc.target/i386/indirect-thunk-register-4.c: New test. |
4664 |
+--- |
4665 |
+ gcc/config/i386/i386.c | 13 ++++++++++++- |
4666 |
+ gcc/doc/extend.texi | 3 +++ |
4667 |
+ gcc/testsuite/gcc.target/i386/indirect-thunk-register-4.c | 13 +++++++++++++ |
4668 |
+ 3 files changed, 28 insertions(+), 1 deletion(-) |
4669 |
+ create mode 100644 gcc/testsuite/gcc.target/i386/indirect-thunk-register-4.c |
4670 |
+ |
4671 |
+diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c |
4672 |
+index 9ffcb69d6d7..e69135d7191 100644 |
4673 |
+--- a/gcc/config/i386/i386.c |
4674 |
++++ b/gcc/config/i386/i386.c |
4675 |
+@@ -17617,6 +17617,7 @@ put_condition_code (enum rtx_code code, machine_mode mode, bool reverse, |
4676 |
+ If CODE is 'h', pretend the reg is the 'high' byte register. |
4677 |
+ If CODE is 'y', print "st(0)" instead of "st", if the reg is stack op. |
4678 |
+ If CODE is 'd', duplicate the operand for AVX instruction. |
4679 |
++ If CODE is 'V', print naked full integer register name without %. |
4680 |
+ */ |
4681 |
+ |
4682 |
+ void |
4683 |
+@@ -17627,7 +17628,7 @@ print_reg (rtx x, int code, FILE *file) |
4684 |
+ unsigned int regno; |
4685 |
+ bool duplicated; |
4686 |
+ |
4687 |
+- if (ASSEMBLER_DIALECT == ASM_ATT) |
4688 |
++ if (ASSEMBLER_DIALECT == ASM_ATT && code != 'V') |
4689 |
+ putc ('%', file); |
4690 |
+ |
4691 |
+ if (x == pc_rtx) |
4692 |
+@@ -17679,6 +17680,14 @@ print_reg (rtx x, int code, FILE *file) |
4693 |
+ return; |
4694 |
+ } |
4695 |
+ |
4696 |
++ if (code == 'V') |
4697 |
++ { |
4698 |
++ if (GENERAL_REGNO_P (regno)) |
4699 |
++ msize = GET_MODE_SIZE (word_mode); |
4700 |
++ else |
4701 |
++ error ("'V' modifier on non-integer register"); |
4702 |
++ } |
4703 |
++ |
4704 |
+ duplicated = code == 'd' && TARGET_AVX; |
4705 |
+ |
4706 |
+ switch (msize) |
4707 |
+@@ -17798,6 +17807,7 @@ print_reg (rtx x, int code, FILE *file) |
4708 |
+ & -- print some in-use local-dynamic symbol name. |
4709 |
+ H -- print a memory address offset by 8; used for sse high-parts |
4710 |
+ Y -- print condition for XOP pcom* instruction. |
4711 |
++ V -- print naked full integer register name without %. |
4712 |
+ + -- print a branch hint as 'cs' or 'ds' prefix |
4713 |
+ ; -- print a semicolon (after prefixes due to bug in older gas). |
4714 |
+ ~ -- print "i" if TARGET_AVX2, "f" otherwise. |
4715 |
+@@ -18021,6 +18031,7 @@ ix86_print_operand (FILE *file, rtx x, int code) |
4716 |
+ case 'X': |
4717 |
+ case 'P': |
4718 |
+ case 'p': |
4719 |
++ case 'V': |
4720 |
+ break; |
4721 |
+ |
4722 |
+ case 's': |
4723 |
+diff --git a/gcc/doc/extend.texi b/gcc/doc/extend.texi |
4724 |
+index f120b2a1429..dce808f1eab 100644 |
4725 |
+--- a/gcc/doc/extend.texi |
4726 |
++++ b/gcc/doc/extend.texi |
4727 |
+@@ -9292,6 +9292,9 @@ The table below shows the list of supported modifiers and their effects. |
4728 |
+ @tab @code{2} |
4729 |
+ @end multitable |
4730 |
+ |
4731 |
++@code{V} is a special modifier which prints the name of the full integer |
4732 |
++register without @code{%}. |
4733 |
++ |
4734 |
+ @anchor{x86floatingpointasmoperands} |
4735 |
+ @subsubsection x86 Floating-Point @code{asm} Operands |
4736 |
+ |
4737 |
+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-register-4.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-register-4.c |
4738 |
+new file mode 100644 |
4739 |
+index 00000000000..f0cd9b75be8 |
4740 |
+--- /dev/null |
4741 |
++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-register-4.c |
4742 |
+@@ -0,0 +1,13 @@ |
4743 |
++/* { dg-do compile } */ |
4744 |
++/* { dg-options "-O2 -mindirect-branch=keep -fno-pic" } */ |
4745 |
++ |
4746 |
++extern void (*func_p) (void); |
4747 |
++ |
4748 |
++void |
4749 |
++foo (void) |
4750 |
++{ |
4751 |
++ asm("call __x86_indirect_thunk_%V0" : : "a" (func_p)); |
4752 |
++} |
4753 |
++ |
4754 |
++/* { dg-final { scan-assembler "call\[ \t\]*__x86_indirect_thunk_eax" { target ia32 } } } */ |
4755 |
++/* { dg-final { scan-assembler "call\[ \t\]*__x86_indirect_thunk_rax" { target { ! ia32 } } } } */ |
4756 |
+-- |
4757 |
+2.14.3 |
4758 |
+ |
4759 |
|
4760 |
diff --git a/sys-devel/gcc/files/spectre-0005-mcmodel-large.patch b/sys-devel/gcc/files/spectre-0005-mcmodel-large.patch |
4761 |
new file mode 100644 |
4762 |
index 0000000..51c56c9 |
4763 |
--- /dev/null |
4764 |
+++ b/sys-devel/gcc/files/spectre-0005-mcmodel-large.patch |
4765 |
@@ -0,0 +1,292 @@ |
4766 |
+From: "H dot J dot Lu" <hjl dot tools at gmail dot com> |
4767 |
+To: gcc-patches at gcc dot gnu dot org |
4768 |
+Subject: [PATCH 5/5] x86: Disallow -mindirect-branch=/-mfunction-return= with -mcmodel=large |
4769 |
+Date: Sat, 13 Jan 2018 19:37:07 -0800 |
4770 |
+ |
4771 |
+Since the thunk function may not be reachable in large code model, |
4772 |
+-mcmodel=large is incompatible with -mindirect-branch=thunk, |
4773 |
+-mindirect-branch=thunk-extern, -mfunction-return=thunk and |
4774 |
+-mfunction-return=thunk-extern. Issue an error when they are used with |
4775 |
+-mcmodel=large. |
4776 |
+ |
4777 |
+gcc/ |
4778 |
+ |
4779 |
+ * config/i386/i386.c (ix86_set_indirect_branch_type): Disallow |
4780 |
+ -mcmodel=large with -mindirect-branch=thunk, |
4781 |
+ -mindirect-branch=thunk-extern, -mfunction-return=thunk and |
4782 |
+ -mfunction-return=thunk-extern. |
4783 |
+ * doc/invoke.texi: Document -mcmodel=large is incompatible with |
4784 |
+ -mindirect-branch=thunk, -mindirect-branch=thunk-extern, |
4785 |
+ -mfunction-return=thunk and -mfunction-return=thunk-extern. |
4786 |
+ |
4787 |
+gcc/testsuite/ |
4788 |
+ |
4789 |
+ * gcc.target/i386/indirect-thunk-10.c: New test. |
4790 |
+ * gcc.target/i386/indirect-thunk-8.c: Likewise. |
4791 |
+ * gcc.target/i386/indirect-thunk-9.c: Likewise. |
4792 |
+ * gcc.target/i386/indirect-thunk-attr-10.c: Likewise. |
4793 |
+ * gcc.target/i386/indirect-thunk-attr-11.c: Likewise. |
4794 |
+ * gcc.target/i386/indirect-thunk-attr-9.c: Likewise. |
4795 |
+ * gcc.target/i386/ret-thunk-17.c: Likewise. |
4796 |
+ * gcc.target/i386/ret-thunk-18.c: Likewise. |
4797 |
+ * gcc.target/i386/ret-thunk-19.c: Likewise. |
4798 |
+ * gcc.target/i386/ret-thunk-20.c: Likewise. |
4799 |
+ * gcc.target/i386/ret-thunk-21.c: Likewise. |
4800 |
+--- |
4801 |
+ gcc/config/i386/i386.c | 26 ++++++++++++++++++++++ |
4802 |
+ gcc/doc/invoke.texi | 11 +++++++++ |
4803 |
+ gcc/testsuite/gcc.target/i386/indirect-thunk-10.c | 7 ++++++ |
4804 |
+ gcc/testsuite/gcc.target/i386/indirect-thunk-8.c | 7 ++++++ |
4805 |
+ gcc/testsuite/gcc.target/i386/indirect-thunk-9.c | 7 ++++++ |
4806 |
+ .../gcc.target/i386/indirect-thunk-attr-10.c | 9 ++++++++ |
4807 |
+ .../gcc.target/i386/indirect-thunk-attr-11.c | 9 ++++++++ |
4808 |
+ .../gcc.target/i386/indirect-thunk-attr-9.c | 9 ++++++++ |
4809 |
+ gcc/testsuite/gcc.target/i386/ret-thunk-17.c | 7 ++++++ |
4810 |
+ gcc/testsuite/gcc.target/i386/ret-thunk-18.c | 8 +++++++ |
4811 |
+ gcc/testsuite/gcc.target/i386/ret-thunk-19.c | 8 +++++++ |
4812 |
+ gcc/testsuite/gcc.target/i386/ret-thunk-20.c | 9 ++++++++ |
4813 |
+ gcc/testsuite/gcc.target/i386/ret-thunk-21.c | 9 ++++++++ |
4814 |
+ 13 files changed, 126 insertions(+) |
4815 |
+ create mode 100644 gcc/testsuite/gcc.target/i386/indirect-thunk-10.c |
4816 |
+ create mode 100644 gcc/testsuite/gcc.target/i386/indirect-thunk-8.c |
4817 |
+ create mode 100644 gcc/testsuite/gcc.target/i386/indirect-thunk-9.c |
4818 |
+ create mode 100644 gcc/testsuite/gcc.target/i386/indirect-thunk-attr-10.c |
4819 |
+ create mode 100644 gcc/testsuite/gcc.target/i386/indirect-thunk-attr-11.c |
4820 |
+ create mode 100644 gcc/testsuite/gcc.target/i386/indirect-thunk-attr-9.c |
4821 |
+ create mode 100644 gcc/testsuite/gcc.target/i386/ret-thunk-17.c |
4822 |
+ create mode 100644 gcc/testsuite/gcc.target/i386/ret-thunk-18.c |
4823 |
+ create mode 100644 gcc/testsuite/gcc.target/i386/ret-thunk-19.c |
4824 |
+ create mode 100644 gcc/testsuite/gcc.target/i386/ret-thunk-20.c |
4825 |
+ create mode 100644 gcc/testsuite/gcc.target/i386/ret-thunk-21.c |
4826 |
+ |
4827 |
+diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c |
4828 |
+index 9807de0c117..92b328ebfc2 100644 |
4829 |
+--- a/gcc/config/i386/i386.c |
4830 |
++++ b/gcc/config/i386/i386.c |
4831 |
+@@ -5836,6 +5836,19 @@ ix86_set_indirect_branch_type (tree fndecl) |
4832 |
+ } |
4833 |
+ else |
4834 |
+ cfun->machine->indirect_branch_type = ix86_indirect_branch; |
4835 |
++ |
4836 |
++ /* -mcmodel=large is not compatible with -mindirect-branch=thunk |
4837 |
++ nor -mindirect-branch=thunk-extern. */ |
4838 |
++ if ((ix86_cmodel == CM_LARGE || ix86_cmodel == CM_LARGE_PIC) |
4839 |
++ && ((cfun->machine->indirect_branch_type |
4840 |
++ == indirect_branch_thunk_extern) |
4841 |
++ || (cfun->machine->indirect_branch_type |
4842 |
++ == indirect_branch_thunk))) |
4843 |
++ error ("%<-mindirect-branch=%s%> and %<-mcmodel=large%> are not " |
4844 |
++ "compatible", |
4845 |
++ ((cfun->machine->indirect_branch_type |
4846 |
++ == indirect_branch_thunk_extern) |
4847 |
++ ? "thunk-extern" : "thunk")); |
4848 |
+ } |
4849 |
+ |
4850 |
+ if (cfun->machine->function_return_type == indirect_branch_unset) |
4851 |
+@@ -5861,6 +5874,19 @@ ix86_set_indirect_branch_type (tree fndecl) |
4852 |
+ } |
4853 |
+ else |
4854 |
+ cfun->machine->function_return_type = ix86_function_return; |
4855 |
++ |
4856 |
++ /* -mcmodel=large is not compatible with -mfunction-return=thunk |
4857 |
++ nor -mfunction-return=thunk-extern. */ |
4858 |
++ if ((ix86_cmodel == CM_LARGE || ix86_cmodel == CM_LARGE_PIC) |
4859 |
++ && ((cfun->machine->function_return_type |
4860 |
++ == indirect_branch_thunk_extern) |
4861 |
++ || (cfun->machine->function_return_type |
4862 |
++ == indirect_branch_thunk))) |
4863 |
++ error ("%<-mfunction-return=%s%> and %<-mcmodel=large%> are not " |
4864 |
++ "compatible", |
4865 |
++ ((cfun->machine->function_return_type |
4866 |
++ == indirect_branch_thunk_extern) |
4867 |
++ ? "thunk-extern" : "thunk")); |
4868 |
+ } |
4869 |
+ } |
4870 |
+ |
4871 |
+diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi |
4872 |
+index d16006e653a..2495a45c957 100644 |
4873 |
+--- a/gcc/doc/invoke.texi |
4874 |
++++ b/gcc/doc/invoke.texi |
4875 |
+@@ -26851,6 +26851,11 @@ to external call and return thunk provided in a separate object file. |
4876 |
+ You can control this behavior for a specific function by using the |
4877 |
+ function attribute @code{indirect_branch}. @xref{Function Attributes}. |
4878 |
+ |
4879 |
++Note that @option{-mcmodel=large} is incompatible with |
4880 |
++@option{-mindirect-branch=thunk} nor |
4881 |
++@option{-mindirect-branch=thunk-extern} since the thunk function may |
4882 |
++not be reachable in large code model. |
4883 |
++ |
4884 |
+ @item -mfunction-return=@var{choice} |
4885 |
+ @opindex -mfunction-return |
4886 |
+ Convert function return with @var{choice}. The default is @samp{keep}, |
4887 |
+@@ -26862,6 +26867,12 @@ object file. You can control this behavior for a specific function by |
4888 |
+ using the function attribute @code{function_return}. |
4889 |
+ @xref{Function Attributes}. |
4890 |
+ |
4891 |
++Note that @option{-mcmodel=large} is incompatible with |
4892 |
++@option{-mfunction-return=thunk} nor |
4893 |
++@option{-mfunction-return=thunk-extern} since the thunk function may |
4894 |
++not be reachable in large code model. |
4895 |
++ |
4896 |
++ |
4897 |
+ @item -mindirect-branch-register |
4898 |
+ @opindex -mindirect-branch-register |
4899 |
+ Force indirect call and jump via register. |
4900 |
+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-10.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-10.c |
4901 |
+new file mode 100644 |
4902 |
+index 00000000000..5623f162dea |
4903 |
+--- /dev/null |
4904 |
++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-10.c |
4905 |
+@@ -0,0 +1,7 @@ |
4906 |
++/* { dg-do compile { target { ! ia32 } } } */ |
4907 |
++/* { dg-options "-O2 -mindirect-branch=thunk-inline -mfunction-return=keep -mcmodel=large" } */ |
4908 |
++ |
4909 |
++void |
4910 |
++bar (void) |
4911 |
++{ |
4912 |
++} |
4913 |
+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-8.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-8.c |
4914 |
+new file mode 100644 |
4915 |
+index 00000000000..d6c1437bcf1 |
4916 |
+--- /dev/null |
4917 |
++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-8.c |
4918 |
+@@ -0,0 +1,7 @@ |
4919 |
++/* { dg-do compile { target { ! ia32 } } } */ |
4920 |
++/* { dg-options "-O2 -mindirect-branch=thunk -mfunction-return=keep -mcmodel=large" } */ |
4921 |
++ |
4922 |
++void |
4923 |
++bar (void) |
4924 |
++{ /* { dg-error "'-mindirect-branch=thunk' and '-mcmodel=large' are not compatible" } */ |
4925 |
++} |
4926 |
+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-9.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-9.c |
4927 |
+new file mode 100644 |
4928 |
+index 00000000000..6914dac27ce |
4929 |
+--- /dev/null |
4930 |
++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-9.c |
4931 |
+@@ -0,0 +1,7 @@ |
4932 |
++/* { dg-do compile { target { ! ia32 } } } */ |
4933 |
++/* { dg-options "-O2 -mindirect-branch=thunk-extern -mfunction-return=keep -mcmodel=large" } */ |
4934 |
++ |
4935 |
++void |
4936 |
++bar (void) |
4937 |
++{ /* { dg-error "'-mindirect-branch=thunk-extern' and '-mcmodel=large' are not compatible" } */ |
4938 |
++} |
4939 |
+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-10.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-10.c |
4940 |
+new file mode 100644 |
4941 |
+index 00000000000..87c7684aa92 |
4942 |
+--- /dev/null |
4943 |
++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-10.c |
4944 |
+@@ -0,0 +1,9 @@ |
4945 |
++/* { dg-do compile { target { ! ia32 } } } */ |
4946 |
++/* { dg-options "-O2 -mindirect-branch=keep -mfunction-return=keep -mcmodel=large" } */ |
4947 |
++/* { dg-additional-options "-fPIC" { target fpic } } */ |
4948 |
++ |
4949 |
++__attribute__ ((indirect_branch("thunk-extern"))) |
4950 |
++void |
4951 |
++bar (void) |
4952 |
++{ /* { dg-error "'-mindirect-branch=thunk-extern' and '-mcmodel=large' are not compatible" } */ |
4953 |
++} |
4954 |
+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-11.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-11.c |
4955 |
+new file mode 100644 |
4956 |
+index 00000000000..0499c1d7d27 |
4957 |
+--- /dev/null |
4958 |
++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-11.c |
4959 |
+@@ -0,0 +1,9 @@ |
4960 |
++/* { dg-do compile { target { ! ia32 } } } */ |
4961 |
++/* { dg-options "-O2 -mindirect-branch=keep -mfunction-return=keep -mcmodel=large" } */ |
4962 |
++/* { dg-additional-options "-fPIC" { target fpic } } */ |
4963 |
++ |
4964 |
++__attribute__ ((indirect_branch("thunk-inline"))) |
4965 |
++void |
4966 |
++bar (void) |
4967 |
++{ |
4968 |
++} |
4969 |
+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-9.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-9.c |
4970 |
+new file mode 100644 |
4971 |
+index 00000000000..3f1d4f54884 |
4972 |
+--- /dev/null |
4973 |
++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-9.c |
4974 |
+@@ -0,0 +1,9 @@ |
4975 |
++/* { dg-do compile { target { ! ia32 } } } */ |
4976 |
++/* { dg-options "-O2 -mindirect-branch=keep -mfunction-return=keep -mcmodel=large" } */ |
4977 |
++/* { dg-additional-options "-fPIC" { target fpic } } */ |
4978 |
++ |
4979 |
++__attribute__ ((indirect_branch("thunk"))) |
4980 |
++void |
4981 |
++bar (void) |
4982 |
++{ /* { dg-error "'-mindirect-branch=thunk' and '-mcmodel=large' are not compatible" } */ |
4983 |
++} |
4984 |
+diff --git a/gcc/testsuite/gcc.target/i386/ret-thunk-17.c b/gcc/testsuite/gcc.target/i386/ret-thunk-17.c |
4985 |
+new file mode 100644 |
4986 |
+index 00000000000..930f72713ae |
4987 |
+--- /dev/null |
4988 |
++++ b/gcc/testsuite/gcc.target/i386/ret-thunk-17.c |
4989 |
+@@ -0,0 +1,7 @@ |
4990 |
++/* { dg-do compile { target { ! ia32 } } } */ |
4991 |
++/* { dg-options "-O2 -mfunction-return=thunk -mindirect-branch=keep -mcmodel=large" } */ |
4992 |
++ |
4993 |
++void |
4994 |
++bar (void) |
4995 |
++{ /* { dg-error "'-mfunction-return=thunk' and '-mcmodel=large' are not compatible" } */ |
4996 |
++} |
4997 |
+diff --git a/gcc/testsuite/gcc.target/i386/ret-thunk-18.c b/gcc/testsuite/gcc.target/i386/ret-thunk-18.c |
4998 |
+new file mode 100644 |
4999 |
+index 00000000000..5763fde84b1 |
5000 |
+--- /dev/null |
5001 |
++++ b/gcc/testsuite/gcc.target/i386/ret-thunk-18.c |
5002 |
+@@ -0,0 +1,8 @@ |
5003 |
++/* { dg-do compile { target { ! ia32 } } } */ |
5004 |
++/* { dg-options "-O2 -mfunction-return=thunk-extern -mindirect-branch=keep -mcmodel=large" } */ |
5005 |
++/* { dg-additional-options "-fPIC" { target fpic } } */ |
5006 |
++ |
5007 |
++void |
5008 |
++bar (void) |
5009 |
++{ /* { dg-error "'-mfunction-return=thunk-extern' and '-mcmodel=large' are not compatible" } */ |
5010 |
++} |
5011 |
+diff --git a/gcc/testsuite/gcc.target/i386/ret-thunk-19.c b/gcc/testsuite/gcc.target/i386/ret-thunk-19.c |
5012 |
+new file mode 100644 |
5013 |
+index 00000000000..ff710d4c1fe |
5014 |
+--- /dev/null |
5015 |
++++ b/gcc/testsuite/gcc.target/i386/ret-thunk-19.c |
5016 |
+@@ -0,0 +1,8 @@ |
5017 |
++/* { dg-do compile { target { ! ia32 } } } */ |
5018 |
++/* { dg-options "-O2 -mfunction-return=keep -mindirect-branch=keep -mcmodel=large" } */ |
5019 |
++ |
5020 |
++__attribute__ ((function_return("thunk"))) |
5021 |
++void |
5022 |
++bar (void) |
5023 |
++{ /* { dg-error "'-mfunction-return=thunk' and '-mcmodel=large' are not compatible" } */ |
5024 |
++} |
5025 |
+diff --git a/gcc/testsuite/gcc.target/i386/ret-thunk-20.c b/gcc/testsuite/gcc.target/i386/ret-thunk-20.c |
5026 |
+new file mode 100644 |
5027 |
+index 00000000000..eeffbd2289a |
5028 |
+--- /dev/null |
5029 |
++++ b/gcc/testsuite/gcc.target/i386/ret-thunk-20.c |
5030 |
+@@ -0,0 +1,9 @@ |
5031 |
++/* { dg-do compile { target { ! ia32 } } } */ |
5032 |
++/* { dg-options "-O2 -mfunction-return=keep -mindirect-branch=keep -mcmodel=large" } */ |
5033 |
++/* { dg-additional-options "-fPIC" { target fpic } } */ |
5034 |
++ |
5035 |
++__attribute__ ((function_return("thunk-extern"))) |
5036 |
++void |
5037 |
++bar (void) |
5038 |
++{ /* { dg-error "'-mfunction-return=thunk-extern' and '-mcmodel=large' are not compatible" } */ |
5039 |
++} |
5040 |
+diff --git a/gcc/testsuite/gcc.target/i386/ret-thunk-21.c b/gcc/testsuite/gcc.target/i386/ret-thunk-21.c |
5041 |
+new file mode 100644 |
5042 |
+index 00000000000..49ab118e04f |
5043 |
+--- /dev/null |
5044 |
++++ b/gcc/testsuite/gcc.target/i386/ret-thunk-21.c |
5045 |
+@@ -0,0 +1,9 @@ |
5046 |
++/* { dg-do compile { target { ! ia32 } } } */ |
5047 |
++/* { dg-options "-O2 -mfunction-return=keep -mindirect-branch=keep -mcmodel=large" } */ |
5048 |
++/* { dg-additional-options "-fPIC" { target fpic } } */ |
5049 |
++ |
5050 |
++__attribute__ ((function_return("thunk-inline"))) |
5051 |
++void |
5052 |
++bar (void) |
5053 |
++{ |
5054 |
++} |
5055 |
+-- |
5056 |
+2.14.3 |
5057 |
+ |
5058 |
|
5059 |
diff --git a/sys-devel/gcc/gcc-7.2.0-r1.ebuild b/sys-devel/gcc/gcc-7.2.0-r1.ebuild |
5060 |
index 1ef1af3..c6f78df 100644 |
5061 |
--- a/sys-devel/gcc/gcc-7.2.0-r1.ebuild |
5062 |
+++ b/sys-devel/gcc/gcc-7.2.0-r1.ebuild |
5063 |
@@ -8,8 +8,7 @@ PATCH_VER="1.1" |
5064 |
|
5065 |
inherit epatch toolchain |
5066 |
|
5067 |
-# unkeyworded for testing bug #641474 |
5068 |
-#KEYWORDS="~alpha ~amd64 ~arm ~arm64 ~hppa ~ia64 ~m68k ~mips ~ppc ~ppc64 ~s390 ~sh ~sparc ~x86 ~amd64-fbsd ~x86-fbsd" |
5069 |
+KEYWORDS="~alpha ~amd64 ~arm ~arm64 ~hppa ~ia64 ~m68k ~mips ~ppc ~ppc64 ~s390 ~sh ~sparc ~x86 ~amd64-fbsd ~x86-fbsd" |
5070 |
|
5071 |
RDEPEND="" |
5072 |
DEPEND="${RDEPEND} |
5073 |
@@ -25,6 +24,17 @@ src_prepare() { |
5074 |
|
5075 |
epatch "${FILESDIR}"/gcc-7.2.0-pr69728.patch |
5076 |
|
5077 |
+ # Meltdown/Spectre |
5078 |
+ epatch "${FILESDIR}"/0001-gcc-7.2.0-move-struct-ix86_frame-to-machine-function.patch |
5079 |
+ epatch "${FILESDIR}"/0002-gcc-7.2.0-move-struct-ix86_frame-to-machine-function.patch |
5080 |
+ epatch "${FILESDIR}"/0003-gcc-7.2.0-move-struct-ix86_frame-to-machine-function.patch |
5081 |
+ |
5082 |
+ epatch "${FILESDIR}"/spectre-0001-mindirect-branch.patch |
5083 |
+ epatch "${FILESDIR}"/spectre-0002-mfunction-return.patch |
5084 |
+ epatch "${FILESDIR}"/spectre-0003-mindirect-branch-register.patch |
5085 |
+ epatch "${FILESDIR}"/spectre-0004-v-register-modifier.patch |
5086 |
+ epatch "${FILESDIR}"/spectre-0005-mcmodel-large.patch |
5087 |
+ |
5088 |
if use elibc_musl || [[ ${CATEGORY} = cross-*-musl* ]]; then |
5089 |
epatch "${FILESDIR}"/6.3.0/cpu_indicator.patch |
5090 |
epatch "${FILESDIR}"/7.1.0/posix_memalign.patch |