[PATCH] gnu: gcc@7: Use retpoline options when building itself.

DoneSubmitted by Alex Vong.
Details
6 participants
  • Alex Vong
  • Gábor Boskovits
  • Efraim Flashner
  • Leo Famulari
  • Ludovic Courtès
  • zimoun
Owner
unassigned
Severity
normal
A
A
Alex Vong wrote on 14 Jan 2018 14:07
gnu: gcc@7: Apply the 'retpoline' mitigation technique.
(address . guix-patches@gnu.org)
877esksi62.fsf@gmail.com
Hello,
This patch adds the repoline patches (totally 17 of them) taken from the'retpoline-20180107' branch at``http://git.infradead.org/users/dwmw2/gcc-retpoline.git''to gcc@7.
Last time it builds fine on my laptop. I am now re-building since I addsome comments on the patches. I will reply asap if anything goes wrongwith the re-build.
From 5be54f7ebe9b0ab6dc65ea974584be0850604b14 Mon Sep 17 00:00:00 2001From: Alex Vong <alexvong1995@gmail.com>Date: Sun, 14 Jan 2018 20:12:19 +0800Subject: [PATCH] gnu: gcc@7: Apply the 'retpoline' mitigation technique.
This is part of Spectre (branch target injection) [CVE-2017-5715]mitigation. Suggested by Mark H Weaver <mhw@netris.org>.
* gnu/local.mk (dist_patch_DATA): Add them.* gnu/packages/gcc.scm (gcc@7): Use them.* gnu/packages/patches/gcc-retpoline-Add-indirect_branch-attribute-with-tests.patch,gnu/packages/patches/gcc-retpoline-Add-mfunction-return-and-function_return-attribute.patch,gnu/packages/patches/gcc-retpoline-Add-mfunction-return-keep-to-indirect-branch-tests.patch,gnu/packages/patches/gcc-retpoline-Add-mindirect-branch-loop.patch,gnu/packages/patches/gcc-retpoline-Add-mindirect-branch-register-and-tests.patch,gnu/packages/patches/gcc-retpoline-Add-mindirect-branch-thunk-extern.patch,gnu/packages/patches/gcc-retpoline-Add-mindirect-branch-thunk-inline.patch,gnu/packages/patches/gcc-retpoline-Add-mindirect-branch-thunk.patch,gnu/packages/patches/gcc-retpoline-Add-mno-indirect-branch-register-to-indirect-branch-.patch,gnu/packages/patches/gcc-retpoline-Add-tests-for-mindirect-branch-thunk-fcheck-pointer-.patch,gnu/packages/patches/gcc-retpoline-Disable-red-zone-with-local-indirect-jump.patch,gnu/packages/patches/gcc-retpoline-Rename-thunks-to-__x86_indirect_thunk_rax-etc.-to-re.patch,gnu/packages/patches/gcc-retpoline-Use-__x86.indirect_thunk.reg-for-indirect-branch-via.patch,gnu/packages/patches/gcc-retpoline-i386-Add-V-register-operand-modifier.patch,gnu/packages/patches/gcc-retpoline-i386-More-use-reference-of-struct-ix86_frame-to-avoi.patch,gnu/packages/patches/gcc-retpoline-i386-Move-struct-ix86_frame-to-machine_function.patch,gnu/packages/patches/gcc-retpoline-i386-Use-reference-of-struct-ix86_frame-to-avoid-cop.patch:New files.--- gnu/local.mk | 19 +- gnu/packages/gcc.scm | 20 +- ...-Add-indirect_branch-attribute-with-tests.patch | 475 +++++++++++ ...tion-return-and-function_return-attribute.patch | 740 ++++++++++++++++ ...tion-return-keep-to-indirect-branch-tests.patch | 421 ++++++++++ .../gcc-retpoline-Add-mindirect-branch-loop.patch | 233 ++++++ ...e-Add-mindirect-branch-register-and-tests.patch | 403 +++++++++ ...tpoline-Add-mindirect-branch-thunk-extern.patch | 263 ++++++ ...tpoline-Add-mindirect-branch-thunk-inline.patch | 310 +++++++ .../gcc-retpoline-Add-mindirect-branch-thunk.patch | 729 ++++++++++++++++ ...irect-branch-register-to-indirect-branch-.patch | 554 ++++++++++++ ...or-mindirect-branch-thunk-fcheck-pointer-.patch | 134 +++ ...Disable-red-zone-with-local-indirect-jump.patch | 147 ++++ ...ks-to-__x86_indirect_thunk_rax-etc.-to-re.patch | 926 +++++++++++++++++++++ ...ndirect_thunk.reg-for-indirect-branch-via.patch | 623 ++++++++++++++ ...line-i386-Add-V-register-operand-modifier.patch | 76 ++ ...se-reference-of-struct-ix86_frame-to-avoi.patch | 69 ++ ...ove-struct-ix86_frame-to-machine_function.patch | 249 ++++++ ...ference-of-struct-ix86_frame-to-avoid-cop.patch | 85 ++ 19 files changed, 6474 insertions(+), 2 deletions(-) create mode 100644 gnu/packages/patches/gcc-retpoline-Add-indirect_branch-attribute-with-tests.patch create mode 100644 gnu/packages/patches/gcc-retpoline-Add-mfunction-return-and-function_return-attribute.patch create mode 100644 gnu/packages/patches/gcc-retpoline-Add-mfunction-return-keep-to-indirect-branch-tests.patch create mode 100644 gnu/packages/patches/gcc-retpoline-Add-mindirect-branch-loop.patch create mode 100644 gnu/packages/patches/gcc-retpoline-Add-mindirect-branch-register-and-tests.patch create mode 100644 gnu/packages/patches/gcc-retpoline-Add-mindirect-branch-thunk-extern.patch create mode 100644 gnu/packages/patches/gcc-retpoline-Add-mindirect-branch-thunk-inline.patch create mode 100644 gnu/packages/patches/gcc-retpoline-Add-mindirect-branch-thunk.patch create mode 100644 gnu/packages/patches/gcc-retpoline-Add-mno-indirect-branch-register-to-indirect-branch-.patch create mode 100644 gnu/packages/patches/gcc-retpoline-Add-tests-for-mindirect-branch-thunk-fcheck-pointer-.patch create mode 100644 gnu/packages/patches/gcc-retpoline-Disable-red-zone-with-local-indirect-jump.patch create mode 100644 gnu/packages/patches/gcc-retpoline-Rename-thunks-to-__x86_indirect_thunk_rax-etc.-to-re.patch create mode 100644 gnu/packages/patches/gcc-retpoline-Use-__x86.indirect_thunk.reg-for-indirect-branch-via.patch create mode 100644 gnu/packages/patches/gcc-retpoline-i386-Add-V-register-operand-modifier.patch create mode 100644 gnu/packages/patches/gcc-retpoline-i386-More-use-reference-of-struct-ix86_frame-to-avoi.patch create mode 100644 gnu/packages/patches/gcc-retpoline-i386-Move-struct-ix86_frame-to-machine_function.patch create mode 100644 gnu/packages/patches/gcc-retpoline-i386-Use-reference-of-struct-ix86_frame-to-avoid-cop.patch
Toggle diff (6616 lines)diff --git a/gnu/local.mk b/gnu/local.mkindex 6af8bfc4b..122e8ef0c 100644--- a/gnu/local.mk+++ b/gnu/local.mk@@ -9,7 +9,7 @@ # Copyright © 2016 Adonay "adfeno" Felipe Nogueira <https://libreplanet.org/wiki/User:Adfeno> <adfeno@openmailbox.org> # Copyright © 2016, 2017 Ricardo Wurmus <rekado@elephly.net> # Copyright © 2016 Ben Woodcroft <donttrustben@gmail.com>-# Copyright © 2016, 2017 Alex Vong <alexvong1995@gmail.com>+# Copyright © 2016, 2017, 2018 Alex Vong <alexvong1995@gmail.com> # Copyright © 2016, 2017 Efraim Flashner <efraim@flashner.co.il> # Copyright © 2016, 2017 Jan Nieuwenhuizen <janneke@gnu.org> # Copyright © 2017 Tobias Geerinckx-Rice <me@tobias.gr>@@ -652,6 +652,23 @@ dist_patch_DATA = \ %D%/packages/patches/gcc-asan-powerpc-missing-include.patch \ %D%/packages/patches/gcc-cross-environment-variables.patch \ %D%/packages/patches/gcc-libvtv-runpath.patch \+ %D%/packages/patches/gcc-retpoline-i386-Move-struct-ix86_frame-to-machine_function.patch \+ %D%/packages/patches/gcc-retpoline-i386-Use-reference-of-struct-ix86_frame-to-avoid-cop.patch \+ %D%/packages/patches/gcc-retpoline-i386-More-use-reference-of-struct-ix86_frame-to-avoi.patch \+ %D%/packages/patches/gcc-retpoline-Add-mindirect-branch-thunk.patch \+ %D%/packages/patches/gcc-retpoline-Add-tests-for-mindirect-branch-thunk-fcheck-pointer-.patch \+ %D%/packages/patches/gcc-retpoline-Add-mindirect-branch-thunk-inline.patch \+ %D%/packages/patches/gcc-retpoline-Add-mindirect-branch-thunk-extern.patch \+ %D%/packages/patches/gcc-retpoline-Add-indirect_branch-attribute-with-tests.patch \+ %D%/packages/patches/gcc-retpoline-Use-__x86.indirect_thunk.reg-for-indirect-branch-via.patch \+ %D%/packages/patches/gcc-retpoline-Add-mindirect-branch-loop.patch \+ %D%/packages/patches/gcc-retpoline-Add-mfunction-return-and-function_return-attribute.patch \+ %D%/packages/patches/gcc-retpoline-Add-mfunction-return-keep-to-indirect-branch-tests.patch \+ %D%/packages/patches/gcc-retpoline-Add-mindirect-branch-register-and-tests.patch \+ %D%/packages/patches/gcc-retpoline-Add-mno-indirect-branch-register-to-indirect-branch-.patch \+ %D%/packages/patches/gcc-retpoline-Disable-red-zone-with-local-indirect-jump.patch \+ %D%/packages/patches/gcc-retpoline-i386-Add-V-register-operand-modifier.patch \+ %D%/packages/patches/gcc-retpoline-Rename-thunks-to-__x86_indirect_thunk_rax-etc.-to-re.patch \ %D%/packages/patches/gcc-strmov-store-file-names.patch \ %D%/packages/patches/gcc-4-compile-with-gcc-5.patch \ %D%/packages/patches/gcc-4.6-gnu-inline.patch \diff --git a/gnu/packages/gcc.scm b/gnu/packages/gcc.scmindex ad8992289..6b913aff9 100644--- a/gnu/packages/gcc.scm+++ b/gnu/packages/gcc.scm@@ -5,6 +5,7 @@ ;;; Copyright © 2015 Andreas Enge <andreas@enge.fr> ;;; Copyright © 2015, 2016, 2017 Efraim Flashner <efraim@flashner.co.il> ;;; Copyright © 2016 Carlos Sánchez de La Lama <csanchezdll@gmail.com>+;;; Copyright © 2018 ALex Vong <alexvong1995@gmail.com> ;;; ;;; This file is part of GNU Guix. ;;;@@ -427,7 +428,24 @@ Go. It also includes runtime support libraries for these languages.") (base32 "16j7i0888j2f1yp9l0nhji6cq65dy6y4nwy8868a8njbzzwavxqw")) (patches (search-patches "gcc-strmov-store-file-names.patch"- "gcc-5.0-libvtv-runpath.patch"))))+ "gcc-5.0-libvtv-runpath.patch"+ "gcc-retpoline-i386-Move-struct-ix86_frame-to-machine_function.patch"+ "gcc-retpoline-i386-Use-reference-of-struct-ix86_frame-to-avoid-cop.patch"+ "gcc-retpoline-i386-More-use-reference-of-struct-ix86_frame-to-avoi.patch"+ "gcc-retpoline-Add-mindirect-branch-thunk.patch"+ "gcc-retpoline-Add-tests-for-mindirect-branch-thunk-fcheck-pointer-.patch"+ "gcc-retpoline-Add-mindirect-branch-thunk-inline.patch"+ "gcc-retpoline-Add-mindirect-branch-thunk-extern.patch"+ "gcc-retpoline-Add-indirect_branch-attribute-with-tests.patch"+ "gcc-retpoline-Use-__x86.indirect_thunk.reg-for-indirect-branch-via.patch"+ "gcc-retpoline-Add-mindirect-branch-loop.patch"+ "gcc-retpoline-Add-mfunction-return-and-function_return-attribute.patch"+ "gcc-retpoline-Add-mfunction-return-keep-to-indirect-branch-tests.patch"+ "gcc-retpoline-Add-mindirect-branch-register-and-tests.patch"+ "gcc-retpoline-Add-mno-indirect-branch-register-to-indirect-branch-.patch"+ "gcc-retpoline-Disable-red-zone-with-local-indirect-jump.patch"+ "gcc-retpoline-i386-Add-V-register-operand-modifier.patch"+ "gcc-retpoline-Rename-thunks-to-__x86_indirect_thunk_rax-etc.-to-re.patch")))) (description "GCC is the GNU Compiler Collection. It provides compiler front-ends for several languages, including C, C++, Objective-C, Fortran, Ada, and Go.diff --git a/gnu/packages/patches/gcc-retpoline-Add-indirect_branch-attribute-with-tests.patch b/gnu/packages/patches/gcc-retpoline-Add-indirect_branch-attribute-with-tests.patchnew file mode 100644index 000000000..5129a8273--- /dev/null+++ b/gnu/packages/patches/gcc-retpoline-Add-indirect_branch-attribute-with-tests.patch@@ -0,0 +1,475 @@+'Retpoline' mitigation technique for Spectre (branch target injection)+[CVE-2017-5715]:++https://security.googleblog.com/2018/01/more-details-about-mitigations-for-cpu_4.html+https://support.google.com/faqs/answer/7625886+https://spectreattack.com/+https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2017-5715++Patch copied from the 'retpoline-20180107' branch of upstream source repository+(please add new / update existing patches when new 'retpoline-xxxxxxxx' branch+appears):++http://git.infradead.org/users/dwmw2/gcc-retpoline.git++From e9794727bb0384be6d27ad1edaefc71c23cc0d86 Mon Sep 17 00:00:00 2001+From: "H.J. Lu" <hjl.tools@gmail.com>+Date: Tue, 28 Nov 2017 06:10:39 -0800+Subject: [PATCH 08/17] Add indirect_branch attribute with tests++__attribute__ ((indirect_branch("thunk")))+__attribute__ ((indirect_branch("thunk-inline")))+__attribute__ ((indirect_branch("thunk-extern")))+__attribute__ ((indirect_branch("keep")))+---+ gcc/config/i386/i386-opts.h | 1 ++ gcc/config/i386/i386.c | 74 ++++++++++++++++++++--+ gcc/config/i386/i386.h | 3 ++ .../gcc.target/i386/indirect-thunk-attr-1.c | 22 ++++++++ .../gcc.target/i386/indirect-thunk-attr-2.c | 20 +++++++ .../gcc.target/i386/indirect-thunk-attr-3.c | 21 +++++++ .../gcc.target/i386/indirect-thunk-attr-4.c | 20 +++++++ .../gcc.target/i386/indirect-thunk-attr-5.c | 22 ++++++++ .../gcc.target/i386/indirect-thunk-attr-6.c | 21 +++++++ .../gcc.target/i386/indirect-thunk-attr-7.c | 44 ++++++++++++++ .../gcc.target/i386/indirect-thunk-attr-8.c | 41 +++++++++++++ 11 files changed, 283 insertions(+), 6 deletions(-)+ create mode 100644 gcc/testsuite/gcc.target/i386/indirect-thunk-attr-1.c+ create mode 100644 gcc/testsuite/gcc.target/i386/indirect-thunk-attr-2.c+ create mode 100644 gcc/testsuite/gcc.target/i386/indirect-thunk-attr-3.c+ create mode 100644 gcc/testsuite/gcc.target/i386/indirect-thunk-attr-4.c+ create mode 100644 gcc/testsuite/gcc.target/i386/indirect-thunk-attr-5.c+ create mode 100644 gcc/testsuite/gcc.target/i386/indirect-thunk-attr-6.c+ create mode 100644 gcc/testsuite/gcc.target/i386/indirect-thunk-attr-7.c+ create mode 100644 gcc/testsuite/gcc.target/i386/indirect-thunk-attr-8.c++diff --git a/gcc/config/i386/i386-opts.h b/gcc/config/i386/i386-opts.h+index f8d80ba7ec6..9e56d7f2d12 100644+--- a/gcc/config/i386/i386-opts.h++++ b/gcc/config/i386/i386-opts.h+@@ -100,6 +100,7 @@ enum stack_protector_guard {+ };+ + enum indirect_branch {++ indirect_branch_unset = 0,+ indirect_branch_keep,+ indirect_branch_thunk,+ indirect_branch_thunk_inline,+diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c+index ac542f79846..5e66af08066 100644+--- a/gcc/config/i386/i386.c++++ b/gcc/config/i386/i386.c+@@ -7137,6 +7137,37 @@ ix86_set_func_type (tree fndecl)+ }+ }+ ++/* Set the indirect_branch_type field from the function FNDECL. */++++static void++ix86_set_indirect_branch_type (tree fndecl)++{++ if (cfun->machine->indirect_branch_type == indirect_branch_unset)++ {++ tree attr = lookup_attribute ("indirect_branch",++ DECL_ATTRIBUTES (fndecl));++ if (attr != NULL)++ {++ tree args = TREE_VALUE (attr);++ if (args == NULL)++ gcc_unreachable ();++ tree cst = TREE_VALUE (args);++ if (strcmp (TREE_STRING_POINTER (cst), "keep") == 0)++ cfun->machine->indirect_branch_type = indirect_branch_keep;++ else if (strcmp (TREE_STRING_POINTER (cst), "thunk") == 0)++ cfun->machine->indirect_branch_type = indirect_branch_thunk;++ else if (strcmp (TREE_STRING_POINTER (cst), "thunk-inline") == 0)++ cfun->machine->indirect_branch_type = indirect_branch_thunk_inline;++ else if (strcmp (TREE_STRING_POINTER (cst), "thunk-extern") == 0)++ cfun->machine->indirect_branch_type = indirect_branch_thunk_extern;++ else++ gcc_unreachable ();++ }++ else++ cfun->machine->indirect_branch_type = ix86_indirect_branch;++ }++}+++ /* Establish appropriate back-end context for processing the function+ FNDECL. The argument might be NULL to indicate processing at top+ level, outside of any function scope. */+@@ -7152,7 +7183,10 @@ ix86_set_current_function (tree fndecl)+ one is extern inline and one isn't. Call ix86_set_func_type+ to set the func_type field. */+ if (fndecl != NULL_TREE)+- ix86_set_func_type (fndecl);++ {++ ix86_set_func_type (fndecl);++ ix86_set_indirect_branch_type (fndecl);++ }+ return;+ }+ +@@ -7172,6 +7206,7 @@ ix86_set_current_function (tree fndecl)+ }+ + ix86_set_func_type (fndecl);++ ix86_set_indirect_branch_type (fndecl);+ + tree new_tree = DECL_FUNCTION_SPECIFIC_TARGET (fndecl);+ if (new_tree == NULL_TREE)+@@ -28605,9 +28640,11 @@ ix86_output_indirect_branch (rtx call_op, const char *xasm,+ char push_buf[64];+ bool need_bnd_p = ix86_bnd_prefixed_insn_p (current_output_insn);+ +- if (ix86_indirect_branch != indirect_branch_thunk_inline)++ if (cfun->machine->indirect_branch_type++ != indirect_branch_thunk_inline)+ {+- bool need_thunk = ix86_indirect_branch == indirect_branch_thunk;++ bool need_thunk++ = cfun->machine->indirect_branch_type == indirect_branch_thunk;+ if (need_bnd_p)+ indirect_thunk_bnd_needed |= need_thunk;+ else+@@ -28716,7 +28753,7 @@ const char *+ ix86_output_indirect_jmp (rtx call_op)+ {+ if (ix86_red_zone_size == 0+- && ix86_indirect_branch != indirect_branch_keep)++ && cfun->machine->indirect_branch_type != indirect_branch_keep)+ {+ ix86_output_indirect_branch (call_op, "%0", true);+ return "";+@@ -28733,7 +28770,7 @@ ix86_output_call_insn (rtx_insn *insn, rtx call_op)+ bool direct_p = constant_call_address_operand (call_op, VOIDmode);+ bool output_indirect_p+ = (!TARGET_SEH+- && ix86_indirect_branch != indirect_branch_keep);++ && cfun->machine->indirect_branch_type != indirect_branch_keep);+ bool seh_nop_p = false;+ const char *xasm;+ +@@ -41749,7 +41786,7 @@ ix86_handle_struct_attribute (tree *node, tree name, tree, int,+ }+ + static tree+-ix86_handle_fndecl_attribute (tree *node, tree name, tree, int,++ix86_handle_fndecl_attribute (tree *node, tree name, tree args, int,+ bool *no_add_attrs)+ {+ if (TREE_CODE (*node) != FUNCTION_DECL)+@@ -41758,6 +41795,29 @@ ix86_handle_fndecl_attribute (tree *node, tree name, tree, int,+ name);+ *no_add_attrs = true;+ }++++ if (is_attribute_p ("indirect_branch", name))++ {++ tree cst = TREE_VALUE (args);++ if (TREE_CODE (cst) != STRING_CST)++ {++ warning (OPT_Wattributes,++ "%qE attribute requires a string constant argument",++ name);++ *no_add_attrs = true;++ }++ else if (strcmp (TREE_STRING_POINTER (cst), "keep") != 0++ && strcmp (TREE_STRING_POINTER (cst), "thunk") != 0++ && strcmp (TREE_STRING_POINTER (cst), "thunk-inline") != 0++ && strcmp (TREE_STRING_POINTER (cst), "thunk-extern") != 0)++ {++ warning (OPT_Wattributes,++ "argument to %qE attribute is not "++ "(keep|thunk|thunk-inline|thunk-extern)", name);++ *no_add_attrs = true;++ }++ }+++ return NULL_TREE;+ }+ +@@ -46052,6 +46112,8 @@ static const struct attribute_spec ix86_attribute_table[] =+ ix86_handle_interrupt_attribute, false },+ { "no_caller_saved_registers", 0, 0, false, true, true,+ ix86_handle_no_caller_saved_registers_attribute, false },++ { "indirect_branch", 1, 1, true, false, false,++ ix86_handle_fndecl_attribute, false },+ + /* End element. */+ { NULL, 0, 0, false, false, false, NULL, false }+diff --git a/gcc/config/i386/i386.h b/gcc/config/i386/i386.h+index 7d9f9020fb3..a9c199a107c 100644+--- a/gcc/config/i386/i386.h++++ b/gcc/config/i386/i386.h+@@ -2604,6 +2604,9 @@ struct GTY(()) machine_function {+ /* Function type. */+ ENUM_BITFIELD(function_type) func_type : 2;+ ++ /* How to generate indirec branch. */++ ENUM_BITFIELD(indirect_branch) indirect_branch_type : 3;+++ /* If true, the current function is a function specified with+ the "interrupt" or "no_caller_saved_registers" attribute. */+ BOOL_BITFIELD no_caller_saved_registers : 1;+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-1.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-1.c+new file mode 100644+index 00000000000..26550fad4c8+--- /dev/null++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-1.c+@@ -0,0 +1,22 @@++/* { dg-do compile } */++/* { dg-options "-O2 -fno-pic" } */++++typedef void (*dispatch_t)(long offset);++++dispatch_t dispatch;++++extern void male_indirect_jump (long)++ __attribute__ ((indirect_branch("thunk")));++++void++male_indirect_jump (long offset)++{++ dispatch(offset);++}++++/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { ! x32 } } } } */++/* { dg-final { scan-assembler "pushq\[ \t\]%rax" { target x32 } } } */++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" } } */++/* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */++/* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */++/* { dg-final { scan-assembler {\tlfence} } } */+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-2.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-2.c+new file mode 100644+index 00000000000..f57bb2a92d6+--- /dev/null++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-2.c+@@ -0,0 +1,20 @@++/* { dg-do compile } */++/* { dg-options "-O2 -fno-pic" } */++++typedef void (*dispatch_t)(long offset);++++dispatch_t dispatch[256];++++__attribute__ ((indirect_branch("thunk")))++void++male_indirect_jump (long offset)++{++ dispatch[offset](offset);++}++++/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { ! x32 } } } } */++/* { dg-final { scan-assembler "pushq\[ \t\]%rax" { target x32 } } } */++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" } } */++/* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */++/* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */++/* { dg-final { scan-assembler {\tlfence} } } */+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-3.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-3.c+new file mode 100644+index 00000000000..a3668a6586c+--- /dev/null++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-3.c+@@ -0,0 +1,21 @@++/* { dg-do compile } */++/* { dg-options "-O2 -fno-pic" } */++++typedef void (*dispatch_t)(long offset);++++dispatch_t dispatch;++extern int male_indirect_jump (long)++ __attribute__ ((indirect_branch("thunk-inline")));++++int++male_indirect_jump (long offset)++{++ dispatch(offset);++ return 0;++}++++/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { ! x32 } } } } */++/* { dg-final { scan-assembler "pushq\[ \t\]%rax" { target x32 } } } */++/* { dg-final { scan-assembler-times "jmp\[ \t\]*\.LIND" 2 } } */++/* { dg-final { scan-assembler-times "call\[ \t\]*\.LIND" 2 } } */++/* { dg-final { scan-assembler-not "__x86.indirect_thunk" } } */+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-4.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-4.c+new file mode 100644+index 00000000000..a9c4a137dd4+--- /dev/null++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-4.c+@@ -0,0 +1,20 @@++/* { dg-do compile } */++/* { dg-options "-O2 -fno-pic" } */++++typedef void (*dispatch_t)(long offset);++++dispatch_t dispatch[256];++++__attribute__ ((indirect_branch("thunk-inline")))++int++male_indirect_jump (long offset)++{++ dispatch[offset](offset);++ return 0;++}++++/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { ! x32 } } } } */++/* { dg-final { scan-assembler "pushq\[ \t\]%rax" { target x32 } } } */++/* { dg-final { scan-assembler-times "jmp\[ \t\]*\.LIND" 2 } } */++/* { dg-final { scan-assembler-times "call\[ \t\]*\.LIND" 2 } } */++/* { dg-final { scan-assembler-not "__x86.indirect_thunk" } } */+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-5.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-5.c+new file mode 100644+index 00000000000..9582e0c5824+--- /dev/null++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-5.c+@@ -0,0 +1,22 @@++/* { dg-do compile } */++/* { dg-options "-O2 -fno-pic" } */++++typedef void (*dispatch_t)(long offset);++++dispatch_t dispatch;++extern int male_indirect_jump (long)++ __attribute__ ((indirect_branch("thunk-extern")));++++int++male_indirect_jump (long offset)++{++ dispatch(offset);++ return 0;++}++++/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { ! x32 } } } } */++/* { dg-final { scan-assembler "pushq\[ \t\]%rax" { target x32 } } } */++/* { dg-final { scan-assembler-times "jmp\[ \t\]*\.LIND" 1 } } */++/* { dg-final { scan-assembler-times "call\[ \t\]*\.LIND" 1 } } */++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" } } */++/* { dg-final { scan-assembler-not {\t(lfence|pause)} } } */+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-6.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-6.c+new file mode 100644+index 00000000000..66442cacfe8+--- /dev/null++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-6.c+@@ -0,0 +1,21 @@++/* { dg-do compile } */++/* { dg-options "-O2 -fno-pic" } */++++typedef void (*dispatch_t)(long offset);++++dispatch_t dispatch[256];++++__attribute__ ((indirect_branch("thunk-extern")))++int++male_indirect_jump (long offset)++{++ dispatch[offset](offset);++ return 0;++}++++/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { ! x32 } } } } */++/* { dg-final { scan-assembler "pushq\[ \t\]%rax" { target x32 } } } */++/* { dg-final { scan-assembler-times "jmp\[ \t\]*\.LIND" 1 } } */++/* { dg-final { scan-assembler-times "call\[ \t\]*\.LIND" 1 } } */++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" } } */++/* { dg-final { scan-assembler-not {\t(lfence|pause)} } } */+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-7.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-7.c+new file mode 100644+index 00000000000..2a19b54cd2e+--- /dev/null++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-7.c+@@ -0,0 +1,44 @@++/* { dg-do compile } */++/* { dg-options "-O2 -fno-pic" } */++++void func0 (void);++void func1 (void);++void func2 (void);++void func3 (void);++void func4 (void);++void func4 (void);++void func5 (void);++++__attribute__ ((indirect_branch("thunk-extern")))++void++bar (int i)++{++ switch (i)++ {++ default:++ func0 ();++ break;++ case 1:++ func1 ();++ break;++ case 2:++ func2 ();++ break;++ case 3:++ func3 ();++ break;++ case 4:++ func4 ();++ break;++ case 5:++ func5 ();++ break;++ }++}++++/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*\.L\[0-9\]+\\(,%" { target { ! x32 } } } } */++/* { dg-final { scan-assembler "pushq\[ \t\]%rax" { target x32 } } } */++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" } } */++/* { dg-final { scan-assembler-not {\t(lfence|pause)} } } */++/* { dg-final { scan-assembler-not "jmp\[ \t\]*\.LIND" } } */++/* { dg-final { scan-assembler-not "call\[ \t\]*\.LIND" } } */+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-8.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-8.c+new file mode 100644+index 00000000000..9f6d12d74a1+--- /dev/null++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-8.c+@@ -0,0 +1,41 @@++/* { dg-do compile } */++/* { dg-options "-O2 -mindirect-branch=thunk -fno-pic" } */++++void func0 (void);++void func1 (void);++void func2 (void);++void func3 (void);++void func4 (void);++void func4 (void);++void func5 (void);++++__attribute__ ((indirect_branch("keep")))++void++bar (int i)++{++ switch (i)++ {++ default:++ func0 ();++ break;++ case 1:++ func1 ();++ break;++ case 2:++ func2 ();++ break;++ case 3:++ func3 ();++ break;++ case 4:++ func4 ();++ break;++ case 5:++ func5 ();++ break;++ }++}++++/* { dg-final { scan-assembler-not "__x86.indirect_thunk" } } */++/* { dg-final { scan-assembler-not "jmp\[ \t\]*\.LIND" } } */++/* { dg-final { scan-assembler-not "call\[ \t\]*\.LIND" } } */+-- +2.15.1+diff --git a/gnu/packages/patches/gcc-retpoline-Add-mfunction-return-and-function_return-attribute.patch b/gnu/packages/patches/gcc-retpoline-Add-mfunction-return-and-function_return-attribute.patchnew file mode 100644index 000000000..0845de4b2--- /dev/null+++ b/gnu/packages/patches/gcc-retpoline-Add-mfunction-return-and-function_return-attribute.patch@@ -0,0 +1,740 @@+'Retpoline' mitigation technique for Spectre (branch target injection)+[CVE-2017-5715]:++https://security.googleblog.com/2018/01/more-details-about-mitigations-for-cpu_4.html+https://support.google.com/faqs/answer/7625886+https://spectreattack.com/+https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2017-5715++Patch copied from the 'retpoline-20180107' branch of upstream source repository+(please add new / update existing patches when new 'retpoline-xxxxxxxx' branch+appears):++http://git.infradead.org/users/dwmw2/gcc-retpoline.git++From 29d5a3f23c18c96944dd3230a41380a6edcd25fd Mon Sep 17 00:00:00 2001+From: "H.J. Lu" <hjl.tools@gmail.com>+Date: Tue, 5 Dec 2017 13:29:06 -0800+Subject: [PATCH 11/17] Add -mfunction-return= and function_return attribute++Add -mfunction-return= and function_return attribute tests++-mfunction-return=thunk+ Convert function return instruction to PC-relative call thunk.+-mfunction-return=thunk-inline+ Convert function return instruction to PC-relative call thunk with+ thunk inlined.+-mfunction-return=thunk-extern+ Convert function return instruction to PC-relative call to external+ thunk.++Add function_return attribute to function declaration++__attribute__ ((function_return("thunk")))+__attribute__ ((function_return("thunk-inline")))+__attribute__ ((function_return("thunk-extern")))+__attribute__ ((function_return("keep")))+---+ gcc/config/i386/i386-protos.h | 1 ++ gcc/config/i386/i386.c | 146 +++++++++++++++++++++++++--+ gcc/config/i386/i386.h | 3 ++ gcc/config/i386/i386.md | 9 +-+ gcc/config/i386/i386.opt | 6 +-+ gcc/testsuite/gcc.target/i386/ret-thunk-1.c | 12 ++++ gcc/testsuite/gcc.target/i386/ret-thunk-10.c | 22 +++++ gcc/testsuite/gcc.target/i386/ret-thunk-11.c | 22 +++++ gcc/testsuite/gcc.target/i386/ret-thunk-12.c | 21 +++++ gcc/testsuite/gcc.target/i386/ret-thunk-13.c | 21 +++++ gcc/testsuite/gcc.target/i386/ret-thunk-14.c | 21 +++++ gcc/testsuite/gcc.target/i386/ret-thunk-15.c | 21 +++++ gcc/testsuite/gcc.target/i386/ret-thunk-16.c | 18 +++++ gcc/testsuite/gcc.target/i386/ret-thunk-2.c | 12 ++++ gcc/testsuite/gcc.target/i386/ret-thunk-3.c | 12 ++++ gcc/testsuite/gcc.target/i386/ret-thunk-4.c | 12 ++++ gcc/testsuite/gcc.target/i386/ret-thunk-5.c | 14 ++++ gcc/testsuite/gcc.target/i386/ret-thunk-6.c | 13 ++++ gcc/testsuite/gcc.target/i386/ret-thunk-7.c | 13 ++++ gcc/testsuite/gcc.target/i386/ret-thunk-8.c | 14 ++++ gcc/testsuite/gcc.target/i386/ret-thunk-9.c | 23 ++++++ 21 files changed, 421 insertions(+), 15 deletions(-)+ create mode 100644 gcc/testsuite/gcc.target/i386/ret-thunk-1.c+ create mode 100644 gcc/testsuite/gcc.target/i386/ret-thunk-10.c+ create mode 100644 gcc/testsuite/gcc.target/i386/ret-thunk-11.c+ create mode 100644 gcc/testsuite/gcc.target/i386/ret-thunk-12.c+ create mode 100644 gcc/testsuite/gcc.target/i386/ret-thunk-13.c+ create mode 100644 gcc/testsuite/gcc.target/i386/ret-thunk-14.c+ create mode 100644 gcc/testsuite/gcc.target/i386/ret-thunk-15.c+ create mode 100644 gcc/testsuite/gcc.target/i386/ret-thunk-16.c+ create mode 100644 gcc/testsuite/gcc.target/i386/ret-thunk-2.c+ create mode 100644 gcc/testsuite/gcc.target/i386/ret-thunk-3.c+ create mode 100644 gcc/testsuite/gcc.target/i386/ret-thunk-4.c+ create mode 100644 gcc/testsuite/gcc.target/i386/ret-thunk-5.c+ create mode 100644 gcc/testsuite/gcc.target/i386/ret-thunk-6.c+ create mode 100644 gcc/testsuite/gcc.target/i386/ret-thunk-7.c+ create mode 100644 gcc/testsuite/gcc.target/i386/ret-thunk-8.c+ create mode 100644 gcc/testsuite/gcc.target/i386/ret-thunk-9.c++diff --git a/gcc/config/i386/i386-protos.h b/gcc/config/i386/i386-protos.h+index b746429f420..213663811de 100644+--- a/gcc/config/i386/i386-protos.h++++ b/gcc/config/i386/i386-protos.h+@@ -316,6 +316,7 @@ extern enum attr_cpu ix86_schedule;+ + extern const char * ix86_output_call_insn (rtx_insn *insn, rtx call_op);+ extern const char * ix86_output_indirect_jmp (rtx call_op);++extern const char * ix86_output_function_return (bool long_p);+ extern bool ix86_operands_ok_for_move_multiple (rtx *operands, bool load,+ enum machine_mode mode);+ +diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c+index be1ff4752a9..7ae3523095c 100644+--- a/gcc/config/i386/i386.c++++ b/gcc/config/i386/i386.c+@@ -7166,6 +7166,31 @@ ix86_set_indirect_branch_type (tree fndecl)+ else+ cfun->machine->indirect_branch_type = ix86_indirect_branch;+ }++++ if (cfun->machine->function_return_type == indirect_branch_unset)++ {++ tree attr = lookup_attribute ("function_return",++ DECL_ATTRIBUTES (fndecl));++ if (attr != NULL)++ {++ tree args = TREE_VALUE (attr);++ if (args == NULL)++ gcc_unreachable ();++ tree cst = TREE_VALUE (args);++ if (strcmp (TREE_STRING_POINTER (cst), "keep") == 0)++ cfun->machine->function_return_type = indirect_branch_keep;++ else if (strcmp (TREE_STRING_POINTER (cst), "thunk") == 0)++ cfun->machine->function_return_type = indirect_branch_thunk;++ else if (strcmp (TREE_STRING_POINTER (cst), "thunk-inline") == 0)++ cfun->machine->function_return_type = indirect_branch_thunk_inline;++ else if (strcmp (TREE_STRING_POINTER (cst), "thunk-extern") == 0)++ cfun->machine->function_return_type = indirect_branch_thunk_extern;++ else++ gcc_unreachable ();++ }++ else++ cfun->machine->function_return_type = ix86_function_return;++ }+ }+ + /* Establish appropriate back-end context for processing the function+@@ -11958,8 +11983,12 @@ static int indirect_thunks_bnd_used;+ /* Fills in the label name that should be used for the indirect thunk. */+ + static void+-indirect_thunk_name (char name[32], int regno, bool need_bnd_p)++indirect_thunk_name (char name[32], int regno, bool need_bnd_p,++ bool ret_p)+ {++ if (regno >= 0 && ret_p)++ gcc_unreachable ();+++ if (USE_HIDDEN_LINKONCE)+ {+ const char *bnd = need_bnd_p ? "_bnd" : "";+@@ -11974,7 +12003,10 @@ indirect_thunk_name (char name[32], int regno, bool need_bnd_p)+ bnd, reg_prefix, reg_names[regno]);+ }+ else+- sprintf (name, "__x86.indirect_thunk%s", bnd);++ {++ const char *ret = ret_p ? "return" : "indirect";++ sprintf (name, "__x86.%s_thunk%s", ret, bnd);++ }+ }+ else+ {+@@ -11987,10 +12019,20 @@ indirect_thunk_name (char name[32], int regno, bool need_bnd_p)+ }+ else+ {+- if (need_bnd_p)+- ASM_GENERATE_INTERNAL_LABEL (name, "LITB", 0);++ if (ret_p)++ {++ if (need_bnd_p)++ ASM_GENERATE_INTERNAL_LABEL (name, "LRTB", 0);++ else++ ASM_GENERATE_INTERNAL_LABEL (name, "LRT", 0);++ }+ else+- ASM_GENERATE_INTERNAL_LABEL (name, "LIT", 0);++ {++ if (need_bnd_p)++ ASM_GENERATE_INTERNAL_LABEL (name, "LITB", 0);++ else++ ASM_GENERATE_INTERNAL_LABEL (name, "LIT", 0);++ }+ }+ }+ }+@@ -12071,7 +12113,7 @@ output_indirect_thunk_function (bool need_bnd_p, int regno)+ tree decl;+ + /* Create __x86.indirect_thunk/__x86.indirect_thunk_bnd. */+- indirect_thunk_name (name, regno, need_bnd_p);++ indirect_thunk_name (name, regno, need_bnd_p, false);+ decl = build_decl (BUILTINS_LOCATION, FUNCTION_DECL,+ get_identifier (name),+ build_function_type_list (void_type_node, NULL_TREE));+@@ -12114,6 +12156,35 @@ output_indirect_thunk_function (bool need_bnd_p, int regno)+ ASM_OUTPUT_LABEL (asm_out_file, name);+ }+ ++ if (regno < 0)++ {++ /* Create alias for __x86.return_thunk/__x86.return_thunk_bnd. */++ char alias[32];++++ indirect_thunk_name (alias, regno, need_bnd_p, true);++ ASM_OUTPUT_DEF (asm_out_file, alias, name);++#if TARGET_MACHO++ if (TARGET_MACHO)++ {++ fputs ("\t.weak_definition\t", asm_out_file);++ assemble_name (asm_out_file, alias);++ fputs ("\n\t.private_extern\t", asm_out_file);++ assemble_name (asm_out_file, alias);++ putc ('\n', asm_out_file);++ }++#else++ if (USE_HIDDEN_LINKONCE)++ {++ fputs ("\t.globl\t", asm_out_file);++ assemble_name (asm_out_file, alias);++ putc ('\n', asm_out_file);++ fputs ("\t.hidden\t", asm_out_file);++ assemble_name (asm_out_file, alias);++ putc ('\n', asm_out_file);++ }++#endif++ }+++ DECL_INITIAL (decl) = make_node (BLOCK);+ current_function_decl = decl;+ allocate_struct_function (decl, false);+@@ -28736,7 +28807,7 @@ ix86_output_indirect_branch (rtx call_op, const char *xasm,+ indirect_thunk_needed = true;+ }+ }+- indirect_thunk_name (thunk_name_buf, regno, need_bnd_p);++ indirect_thunk_name (thunk_name_buf, regno, need_bnd_p, false);+ thunk_name = thunk_name_buf;+ }+ else+@@ -28860,6 +28931,43 @@ ix86_output_indirect_jmp (rtx call_op)+ return "%!jmp\t%A0";+ }+ ++const char *++ix86_output_function_return (bool long_p)++{++ if (cfun->machine->function_return_type != indirect_branch_keep)++ {++ char thunk_name[32];++ bool need_bnd_p = ix86_bnd_prefixed_insn_p (current_output_insn);++++ if (cfun->machine->function_return_type++ != indirect_branch_thunk_inline)++ {++ bool need_thunk = (cfun->machine->function_return_type++ == indirect_branch_thunk);++ indirect_thunk_name (thunk_name, -1, need_bnd_p, true);++ if (need_bnd_p)++ {++ indirect_thunk_bnd_needed |= need_thunk;++ fprintf (asm_out_file, "\tbnd jmp\t%s\n", thunk_name);++ }++ else++ {++ indirect_thunk_needed |= need_thunk;++ fprintf (asm_out_file, "\tjmp\t%s\n", thunk_name);++ }++ }++ else++ output_indirect_thunk (need_bnd_p, -1);++++ return "";++ }++++ if (!long_p || ix86_bnd_prefixed_insn_p (current_output_insn))++ return "%!ret";++++ return "rep%; ret";++}+++ /* Output the assembly for a call instruction. */+ + const char *+@@ -41916,6 +42024,28 @@ ix86_handle_fndecl_attribute (tree *node, tree name, tree args, int,+ }+ }+ ++ if (is_attribute_p ("function_return", name))++ {++ tree cst = TREE_VALUE (args);++ if (TREE_CODE (cst) != STRING_CST)++ {++ warning (OPT_Wattributes,++ "%qE attribute requires a string constant argument",++ name);++ *no_add_attrs = true;++ }++ else if (strcmp (TREE_STRING_POINTER (cst), "keep") != 0++ && strcmp (TREE_STRING_POINTER (cst), "thunk") != 0++ && strcmp (TREE_STRING_POINTER (cst), "thunk-inline") != 0++ && strcmp (TREE_STRING_POINTER (cst), "thunk-extern") != 0)++ {++ warning (OPT_Wattributes,++ "argument to %qE attribute is not "++ "(keep|thunk|thunk-inline|thunk-extern)", name);++ *no_add_attrs = true;++ }++ }+++ return NULL_TREE;+ }+ +@@ -46212,6 +46342,8 @@ static const struct attribute_spec ix86_attribute_table[] =+ ix86_handle_no_caller_saved_registers_attribute, false },+ { "indirect_branch", 1, 1, true, false, false,+ ix86_handle_fndecl_attribute, false },++ { "function_return", 1, 1, true, false, false,++ ix86_handle_fndecl_attribute, false },+ + /* End element. */+ { NULL, 0, 0, false, false, false, NULL, false }+diff --git a/gcc/config/i386/i386.h b/gcc/config/i386/i386.h+index a9c199a107c..f248f3ba2f5 100644+--- a/gcc/config/i386/i386.h++++ b/gcc/config/i386/i386.h+@@ -2607,6 +2607,9 @@ struct GTY(()) machine_function {+ /* How to generate indirec branch. */+ ENUM_BITFIELD(indirect_branch) indirect_branch_type : 3;+ ++ /* How to generate function return. */++ ENUM_BITFIELD(indirect_branch) function_return_type : 3;+++ /* If true, the current function is a function specified with+ the "interrupt" or "no_caller_saved_registers" attribute. */+ BOOL_BITFIELD no_caller_saved_registers : 1;+diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md+index 01b7b2039e6..00a9afef225 100644+--- a/gcc/config/i386/i386.md++++ b/gcc/config/i386/i386.md+@@ -12288,7 +12288,7 @@+ (define_insn "simple_return_internal"+ [(simple_return)]+ "reload_completed"+- "%!ret"++ "* return ix86_output_function_return (false);"+ [(set_attr "length" "1")+ (set_attr "atom_unit" "jeu")+ (set_attr "length_immediate" "0")+@@ -12310,12 +12310,7 @@+ [(simple_return)+ (unspec [(const_int 0)] UNSPEC_REP)]+ "reload_completed"+-{+- if (ix86_bnd_prefixed_insn_p (insn))+- return "%!ret";+-+- return "rep%; ret";+-}++ "* return ix86_output_function_return (true);"+ [(set_attr "length" "2")+ (set_attr "atom_unit" "jeu")+ (set_attr "length_immediate" "0")+diff --git a/gcc/config/i386/i386.opt b/gcc/config/i386/i386.opt+index bc81e6bea86..fc2c81c3fb5 100644+--- a/gcc/config/i386/i386.opt++++ b/gcc/config/i386/i386.opt+@@ -932,9 +932,13 @@ mindirect-branch=+ Target Report RejectNegative Joined Enum(indirect_branch) Var(ix86_indirect_branch) Init(indirect_branch_keep)+ Update indirect call and jump.+ ++mfunction-return=++Target Report RejectNegative Joined Enum(indirect_branch) Var(ix86_function_return) Init(indirect_branch_keep)++Update function return.+++ Enum+ Name(indirect_branch) Type(enum indirect_branch)+-Known indirect branch choices (for use with the -mindirect-branch= option):++Known indirect branch choices (for use with the -mindirect-branch=/-mfunction-return= options):+ + EnumValue+ Enum(indirect_branch) String(keep) Value(indirect_branch_keep)+diff --git a/gcc/testsuite/gcc.target/i386/ret-thunk-1.c b/gcc/testsuite/gcc.target/i386/ret-thunk-1.c+new file mode 100644+index 00000000000..406956f48e5+--- /dev/null++++ b/gcc/testsuite/gcc.target/i386/ret-thunk-1.c+@@ -0,0 +1,12 @@++/* { dg-do compile } */++/* { dg-options "-O2 -mfunction-return=thunk" } */++++void++foo (void)++{++}++++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.return_thunk" } } */++/* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */++/* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */++/* { dg-final { scan-assembler {\tlfence} } } */+diff --git a/gcc/testsuite/gcc.target/i386/ret-thunk-10.c b/gcc/testsuite/gcc.target/i386/ret-thunk-10.c+new file mode 100644+index 00000000000..aecea4224f9+--- /dev/null++++ b/gcc/testsuite/gcc.target/i386/ret-thunk-10.c+@@ -0,0 +1,22 @@++/* { dg-do compile } */++/* { dg-options "-O2 -mfunction-return=thunk-inline -mindirect-branch=thunk -fno-pic" } */++++extern void (*bar) (void);++++int++foo (void)++{++ bar ();++ return 0;++}++++/* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */++/* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */++/* { dg-final { scan-assembler-not "jmp\[ \t\]*__x86.return_thunk" } } */++/* { dg-final { scan-assembler-times {\tlfence} 2 } } */++/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?bar" { target { ! x32 } } } } */++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" { target { ! x32 } } } } */++/* { dg-final { scan-assembler "__x86.indirect_thunk:" { target { ! x32 } } } } */++/* { dg-final { scan-assembler "call\[ \t\]*__x86.indirect_thunk\.(r|e)ax" { target { x32 } } } } */++/* { dg-final { scan-assembler "__x86.indirect_thunk\.(r|e)ax:" { target { x32 } } } } */++/* { dg-final { scan-assembler-not "pushq\[ \t\]%rax" { target x32 } } } */+diff --git a/gcc/testsuite/gcc.target/i386/ret-thunk-11.c b/gcc/testsuite/gcc.target/i386/ret-thunk-11.c+new file mode 100644+index 00000000000..3bacfb54dfd+--- /dev/null++++ b/gcc/testsuite/gcc.target/i386/ret-thunk-11.c+@@ -0,0 +1,22 @@++/* { dg-do compile } */++/* { dg-options "-O2 -mfunction-return=thunk-extern -mindirect-branch=thunk -fno-pic" } */++++extern void (*bar) (void);++++int++foo (void)++{++ bar ();++ return 0;++}++++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.return_thunk" } } */++/* { dg-final { scan-assembler-times {\tlfence} 1 } } */++/* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */++/* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */++/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?bar" { target { ! x32 } } } } */++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" { target { ! x32 } } } } */++/* { dg-final { scan-assembler "__x86.indirect_thunk:" { target { ! x32 } } } } */++/* { dg-final { scan-assembler "call\[ \t\]*__x86.indirect_thunk\.(r|e)ax" { target { x32 } } } } */++/* { dg-final { scan-assembler "__x86.indirect_thunk\.(r|e)ax:" { target { x32 } } } } */++/* { dg-final { scan-assembler-not "pushq\[ \t\]%rax" { target x32 } } } */+diff --git a/gcc/testsuite/gcc.target/i386/ret-thunk-12.c b/gcc/testsuite/gcc.target/i386/ret-thunk-12.c+new file mode 100644+index 00000000000..851115ac507+--- /dev/null++++ b/gcc/testsuite/gcc.target/i386/ret-thunk-12.c+@@ -0,0 +1,21 @@++/* { dg-do compile } */++/* { dg-options "-O2 -mfunction-return=keep -mindirect-branch=thunk -fno-pic" } */++++extern void (*bar) (void);++++int++foo (void)++{++ bar ();++ return 0;++}++++/* { dg-final { scan-assembler-not "jmp\[ \t\]*__x86.return_thunk" } } */++/* { dg-final { scan-assembler-times {\tlfence} 1 } } */++/* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */++/* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" { target { ! x32 } } } } */++/* { dg-final { scan-assembler "__x86.indirect_thunk:" { target { ! x32 } } } } */++/* { dg-final { scan-assembler "call\[ \t\]*__x86.indirect_thunk\.(r|e)ax" { target { x32 } } } } */++/* { dg-final { scan-assembler "__x86.indirect_thunk\.(r|e)ax:" { target { x32 } } } } */++/* { dg-final { scan-assembler-not "pushq\[ \t\]%rax" { target x32 } } } */+diff --git a/gcc/testsuite/gcc.target/i386/ret-thunk-13.c b/gcc/testsuite/gcc.target/i386/ret-thunk-13.c+new file mode 100644+index 00000000000..7acb6fa5eae+--- /dev/null++++ b/gcc/testsuite/gcc.target/i386/ret-thunk-13.c+@@ -0,0 +1,21 @@++/* { dg-do compile } */++/* { dg-options "-O2 -mfunction-return=keep -mindirect-branch=thunk-inline -fno-pic" } */++++extern void (*bar) (void);++extern int foo (void) __attribute__ ((function_return("thunk")));++++int++foo (void)++{++ bar ();++ return 0;++}++++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.return_thunk" } } */++/* { dg-final { scan-assembler-times {\tlfence} 2 } } */++/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?bar" { target { ! x32 } } } } */++/* { dg-final { scan-assembler-times "jmp\[ \t\]*\.LIND" 3 } } */++/* { dg-final { scan-assembler-times "call\[ \t\]*\.LIND" 3 } } */++/* { dg-final { scan-assembler-not "jmp\[ \t\]*__x86.indirect_thunk" } } */++/* { dg-final { scan-assembler-not "call\[ \t\]*__x86.indirect_thunk\.(r|e)ax" { target { x32 } } } } */++/* { dg-final { scan-assembler-not "pushq\[ \t\]%rax" { target x32 } } } */+diff --git a/gcc/testsuite/gcc.target/i386/ret-thunk-14.c b/gcc/testsuite/gcc.target/i386/ret-thunk-14.c+new file mode 100644+index 00000000000..bf340fac7c6+--- /dev/null++++ b/gcc/testsuite/gcc.target/i386/ret-thunk-14.c+@@ -0,0 +1,21 @@++/* { dg-do compile } */++/* { dg-options "-O2 -mfunction-return=keep -mindirect-branch=thunk-extern -fno-pic" } */++++extern void (*bar) (void);++++__attribute__ ((function_return("thunk-inline")))++int++foo (void)++{++ bar ();++ return 0;++}++++/* { dg-final { scan-assembler-times {\tlfence} 1 } } */++/* { dg-final { scan-assembler-not "jmp\[ \t\]*__x86.return_thunk" } } */++/* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */++/* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */++/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?bar" { target { ! x32 } } } } */++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" { target { ! x32 } } } } */++/* { dg-final { scan-assembler "call\[ \t\]*__x86.indirect_thunk\.(r|e)ax" { target { x32 } } } } */++/* { dg-final { scan-assembler-not "pushq\[ \t\]%rax" { target x32 } } } */+diff --git a/gcc/testsuite/gcc.target/i386/ret-thunk-15.c b/gcc/testsuite/gcc.target/i386/ret-thunk-15.c+new file mode 100644+index 00000000000..735f8648c96+--- /dev/null++++ b/gcc/testsuite/gcc.target/i386/ret-thunk-15.c+@@ -0,0 +1,21 @@++/* { dg-do compile } */++/* { dg-options "-O2 -mfunction-return=keep -mindirect-branch=keep -fno-pic" } */++++extern void (*bar) (void);++++__attribute__ ((function_return("thunk-extern"), indirect_branch("thunk")))++int++foo (void)++{++ bar ();++ return 0;++}++++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.return_thunk" } } */++/* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */++/* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */++/* { dg-final { scan-assembler-times {\tlfence} 1 } } */++/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?bar" { target { ! x32 } } } } */++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" { target { ! x32 } } } } */++/* { dg-final { scan-assembler "call\[ \t\]*__x86.indirect_thunk\.(r|e)ax" { target x32 } } } */++/* { dg-final { scan-assembler-not "pushq\[ \t\]%rax" { target x32 } } } */+diff --git a/gcc/testsuite/gcc.target/i386/ret-thunk-16.c b/gcc/testsuite/gcc.target/i386/ret-thunk-16.c+new file mode 100644+index 00000000000..cf3920563e0+--- /dev/null++++ b/gcc/testsuite/gcc.target/i386/ret-thunk-16.c+@@ -0,0 +1,18 @@++/* { dg-do compile } */++/* { dg-options "-O2 -mfunction-return=thunk-inline -mindirect-branch=thunk-extern -fno-pic" } */++++extern void (*bar) (void);++++__attribute__ ((function_return("keep"), indirect_branch("keep")))++int++foo (void)++{++ bar ();++ return 0;++}++++/* { dg-final { scan-assembler-not "__x86.indirect_thunk" } } */++/* { dg-final { scan-assembler-not "__x86.return_thunk" } } */++/* { dg-final { scan-assembler-not {\tlfence} } } */++/* { dg-final { scan-assembler-not "jmp\[ \t\]*\.LIND" } } */++/* { dg-final { scan-assembler-not "call\[ \t\]*\.LIND" } } */+diff --git a/gcc/testsuite/gcc.target/i386/ret-thunk-2.c b/gcc/testsuite/gcc.target/i386/ret-thunk-2.c+new file mode 100644+index 00000000000..190947cc2ca+--- /dev/null++++ b/gcc/testsuite/gcc.target/i386/ret-thunk-2.c+@@ -0,0 +1,12 @@++/* { dg-do compile } */++/* { dg-options "-O2 -mfunction-return=thunk-inline" } */++++void++foo (void)++{++}++++/* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */++/* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */++/* { dg-final { scan-assembler {\tlfence} } } */++/* { dg-final { scan-assembler-not "jmp\[ \t\]*__x86.return_thunk" } } */+diff --git a/gcc/testsuite/gcc.target/i386/ret-thunk-3.c b/gcc/testsuite/gcc.target/i386/ret-thunk-3.c+new file mode 100644+index 00000000000..d71de3ac520+--- /dev/null++++ b/gcc/testsuite/gcc.target/i386/ret-thunk-3.c+@@ -0,0 +1,12 @@++/* { dg-do compile } */++/* { dg-options "-O2 -mfunction-return=thunk-extern" } */++++void++foo (void)++{++}++++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.return_thunk" } } */++/* { dg-final { scan-assembler-not {\tlfence} } } */++/* { dg-final { scan-assembler-not "jmp\[ \t\]*\.LIND" } } */++/* { dg-final { scan-assembler-not "call\[ \t\]*\.LIND" } } */+diff --git a/gcc/testsuite/gcc.target/i386/ret-thunk-4.c b/gcc/testsuite/gcc.target/i386/ret-thunk-4.c+new file mode 100644+index 00000000000..68c22122f0d+--- /dev/null++++ b/gcc/testsuite/gcc.target/i386/ret-thunk-4.c+@@ -0,0 +1,12 @@++/* { dg-do compile } */++/* { dg-options "-O2 -mfunction-return=keep" } */++++void++foo (void)++{++}++++/* { dg-final { scan-assembler-not "jmp\[ \t\]*__x86.return_thunk" } } */++/* { dg-final { scan-assembler-not {\tlfence} } } */++/* { dg-final { scan-assembler-not "jmp\[ \t\]*\.LIND" } } */++/* { dg-final { scan-assembler-not "call\[ \t\]*\.LIND" } } */+diff --git a/gcc/testsuite/gcc.target/i386/ret-thunk-5.c b/gcc/testsuite/gcc.target/i386/ret-thunk-5.c+new file mode 100644+index 00000000000..28c576e2267+--- /dev/null++++ b/gcc/testsuite/gcc.target/i386/ret-thunk-5.c+@@ -0,0 +1,14 @@++/* { dg-do compile } */++/* { dg-options "-O2 -mfunction-return=keep" } */++++extern void foo (void) __attribute__ ((function_return("thunk")));++++void++foo (void)++{++}++++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.return_thunk" } } */++/* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */++/* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */++/* { dg-final { scan-assembler {\tlfence} } } */+diff --git a/gcc/testsuite/gcc.target/i386/ret-thunk-6.c b/gcc/testsuite/gcc.target/i386/ret-thunk-6.c+new file mode 100644+index 00000000000..10ad40b9c26+--- /dev/null++++ b/gcc/testsuite/gcc.target/i386/ret-thunk-6.c+@@ -0,0 +1,13 @@++/* { dg-do compile } */++/* { dg-options "-O2 -mfunction-return=keep" } */++++__attribute__ ((function_return("thunk-inline")))++void++foo (void)++{++}++++/* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */++/* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */++/* { dg-final { scan-assembler {\tlfence} } } */++/* { dg-final { scan-assembler-not "jmp\[ \t\]*__x86.return_thunk" } } */+diff --git a/gcc/testsuite/gcc.target/i386/ret-thunk-7.c b/gcc/testsuite/gcc.target/i386/ret-thunk-7.c+new file mode 100644+index 00000000000..7ac0beaa73e+--- /dev/null++++ b/gcc/testsuite/gcc.target/i386/ret-thunk-7.c+@@ -0,0 +1,13 @@++/* { dg-do compile } */++/* { dg-options "-O2 -mfunction-return=keep" } */++++__attribute__ ((function_return("thunk-extern")))++void++foo (void)++{++}++++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.return_thunk" } } */++/* { dg-final { scan-assembler-not {\tlfence} } } */++/* { dg-final { scan-assembler-not "jmp\[ \t\]*\.LIND" } } */++/* { dg-final { scan-assembler-not "call\[ \t\]*\.LIND" } } */+diff --git a/gcc/testsuite/gcc.target/i386/ret-thunk-8.c b/gcc/testsuite/gcc.target/i386/ret-thunk-8.c+new file mode 100644+index 00000000000..777ab7c8088+--- /dev/null++++ b/gcc/testsuite/gcc.target/i386/ret-thunk-8.c+@@ -0,0 +1,14 @@++/* { dg-do compile } */++/* { dg-options "-O2 -mfunction-return=thunk-inline" } */++++extern void foo (void) __attribute__ ((function_return("keep")));++++void++foo (void)++{++}++++/* { dg-final { scan-assembler-not "jmp\[ \t\]*__x86.return_thunk" } } */++/* { dg-final { scan-assembler-not {\tlfence} } } */++/* { dg-final { scan-assembler-not "jmp\[ \t\]*\.LIND" } } */++/* { dg-final { scan-assembler-not "call\[ \t\]*\.LIND" } } */+diff --git a/gcc/testsuite/gcc.target/i386/ret-thunk-9.c b/gcc/testsuite/gcc.target/i386/ret-thunk-9.c+new file mode 100644+index 00000000000..569e5f47973+--- /dev/null++++ b/gcc/testsuite/gcc.target/i386/ret-thunk-9.c+@@ -0,0 +1,23 @@++/* { dg-do compile } */++/* { dg-options "-O2 -mfunction-return=thunk -mindirect-branch=thunk -fno-pic" } */++++extern void (*bar) (void);++++int++foo (void)++{++ bar ();++ return 0;++}++++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.return_thunk" } } */++/* { dg-final { scan-assembler-not "__x86.return_thunk:" } } */++/* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */++/* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */++/* { dg-final { scan-assembler "__x86.indirect_thunk:" } } */++/* { dg-final { scan-assembler-times {\tlfence} 1 { target { ! x32 } } } } */++/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?bar" { target { ! x32 } } } } */++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" { target { ! x32 } } } } */++/* { dg-final { scan-assembler-times {\tlfence} 2 { target { x32 } } } } */++/* { dg-final { scan-assembler "call\[ \t\]*__x86.indirect_thunk\.(r|e)ax" { target { x32 } } } } */++/* { dg-final { scan-assembler-not "pushq\[ \t\]%rax" { target x32 } } } */+-- +2.15.1+diff --git a/gnu/packages/patches/gcc-retpoline-Add-mfunction-return-keep-to-indirect-branch-tests.patch b/gnu/packages/patches/gcc-retpoline-Add-mfunction-return-keep-to-indirect-branch-tests.patchnew file mode 100644index 000000000..ac900bab0--- /dev/null+++ b/gnu/packages/patches/gcc-retpoline-Add-mfunction-return-keep-to-indirect-branch-tests.patch@@ -0,0 +1,421 @@+'Retpoline' mitigation technique for Spectre (branch target injection)+[CVE-2017-5715]:++https://security.googleblog.com/2018/01/more-details-about-mitigations-for-cpu_4.html+https://support.google.com/faqs/answer/7625886+https://spectreattack.com/+https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2017-5715++Patch copied from the 'retpoline-20180107' branch of upstream source repository+(please add new / update existing patches when new 'retpoline-xxxxxxxx' branch+appears):++http://git.infradead.org/users/dwmw2/gcc-retpoline.git++From def2b5d75fd6234984ec969f4586fcb8c516a3b9 Mon Sep 17 00:00:00 2001+From: "H.J. Lu" <hjl.tools@gmail.com>+Date: Wed, 6 Dec 2017 09:58:42 -0800+Subject: [PATCH 12/17] Add -mfunction-return=keep to indirect branch tests++---+ gcc/testsuite/gcc.target/i386/indirect-thunk-1.c | 2 +-+ gcc/testsuite/gcc.target/i386/indirect-thunk-2.c | 2 +-+ gcc/testsuite/gcc.target/i386/indirect-thunk-3.c | 2 +-+ gcc/testsuite/gcc.target/i386/indirect-thunk-4.c | 2 +-+ gcc/testsuite/gcc.target/i386/indirect-thunk-5.c | 2 +-+ gcc/testsuite/gcc.target/i386/indirect-thunk-6.c | 2 +-+ gcc/testsuite/gcc.target/i386/indirect-thunk-7.c | 2 +-+ gcc/testsuite/gcc.target/i386/indirect-thunk-attr-1.c | 2 +-+ gcc/testsuite/gcc.target/i386/indirect-thunk-attr-2.c | 2 +-+ gcc/testsuite/gcc.target/i386/indirect-thunk-attr-3.c | 2 +-+ gcc/testsuite/gcc.target/i386/indirect-thunk-attr-4.c | 2 +-+ gcc/testsuite/gcc.target/i386/indirect-thunk-attr-5.c | 2 +-+ gcc/testsuite/gcc.target/i386/indirect-thunk-attr-6.c | 2 +-+ gcc/testsuite/gcc.target/i386/indirect-thunk-attr-7.c | 2 +-+ gcc/testsuite/gcc.target/i386/indirect-thunk-attr-8.c | 2 +-+ gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-1.c | 2 +-+ gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-2.c | 2 +-+ gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-3.c | 2 +-+ gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-4.c | 2 +-+ gcc/testsuite/gcc.target/i386/indirect-thunk-extern-1.c | 2 +-+ gcc/testsuite/gcc.target/i386/indirect-thunk-extern-2.c | 2 +-+ gcc/testsuite/gcc.target/i386/indirect-thunk-extern-3.c | 2 +-+ gcc/testsuite/gcc.target/i386/indirect-thunk-extern-4.c | 2 +-+ gcc/testsuite/gcc.target/i386/indirect-thunk-extern-5.c | 2 +-+ gcc/testsuite/gcc.target/i386/indirect-thunk-extern-6.c | 2 +-+ gcc/testsuite/gcc.target/i386/indirect-thunk-extern-7.c | 2 +-+ gcc/testsuite/gcc.target/i386/indirect-thunk-inline-1.c | 2 +-+ gcc/testsuite/gcc.target/i386/indirect-thunk-inline-2.c | 2 +-+ gcc/testsuite/gcc.target/i386/indirect-thunk-inline-3.c | 2 +-+ gcc/testsuite/gcc.target/i386/indirect-thunk-inline-4.c | 2 +-+ gcc/testsuite/gcc.target/i386/indirect-thunk-inline-5.c | 2 +-+ gcc/testsuite/gcc.target/i386/indirect-thunk-inline-6.c | 2 +-+ gcc/testsuite/gcc.target/i386/indirect-thunk-inline-7.c | 2 +-+ 33 files changed, 33 insertions(+), 33 deletions(-)++diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-1.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-1.c+index 785e593405f..318db1e7f5c 100644+--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-1.c++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-1.c+@@ -1,5 +1,5 @@+ /* { dg-do compile } */+-/* { dg-options "-O2 -mindirect-branch=thunk -fno-pic" } */++/* { dg-options "-O2 -mfunction-return=keep -mindirect-branch=thunk -fno-pic" } */+ + typedef void (*dispatch_t)(long offset);+ +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-2.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-2.c+index b69075e6483..f2700dd36cf 100644+--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-2.c++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-2.c+@@ -1,5 +1,5 @@+ /* { dg-do compile } */+-/* { dg-options "-O2 -mindirect-branch=thunk -fno-pic" } */++/* { dg-options "-O2 -mfunction-return=keep -mindirect-branch=thunk -fno-pic" } */+ + typedef void (*dispatch_t)(long offset);+ +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-3.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-3.c+index df8109baf55..46685d9a674 100644+--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-3.c++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-3.c+@@ -1,5 +1,5 @@+ /* { dg-do compile } */+-/* { dg-options "-O2 -mindirect-branch=thunk -fno-pic" } */++/* { dg-options "-O2 -mfunction-return=keep -mindirect-branch=thunk -fno-pic" } */+ + typedef void (*dispatch_t)(long offset);+ +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-4.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-4.c+index 8f3b9f4d8a5..8f701775cea 100644+--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-4.c++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-4.c+@@ -1,5 +1,5 @@+ /* { dg-do compile } */+-/* { dg-options "-O2 -mindirect-branch=thunk -fno-pic" } */++/* { dg-options "-O2 -mfunction-return=keep -mindirect-branch=thunk -fno-pic" } */+ + typedef void (*dispatch_t)(long offset);+ +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-5.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-5.c+index 1a9bb0e431e..f88ac31d07a 100644+--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-5.c++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-5.c+@@ -1,5 +1,5 @@+ /* { dg-do compile { target *-*-linux* } } */+-/* { dg-options "-O2 -fpic -fno-plt -mindirect-branch=thunk" } */++/* { dg-options "-O2 -mfunction-return=keep -fpic -fno-plt -mindirect-branch=thunk" } */+ + extern void bar (void);+ +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-6.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-6.c+index bc7d20ec6ad..d745116d321 100644+--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-6.c++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-6.c+@@ -1,5 +1,5 @@+ /* { dg-do compile { target *-*-linux* } } */+-/* { dg-options "-O2 -fpic -fno-plt -mindirect-branch=thunk" } */++/* { dg-options "-O2 -mfunction-return=keep -fpic -fno-plt -mindirect-branch=thunk" } */+ + extern void bar (void);+ +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-7.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-7.c+index f0e1cfe1893..969cb8c6ddc 100644+--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-7.c++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-7.c+@@ -1,5 +1,5 @@+ /* { dg-do compile } */+-/* { dg-options "-O2 -mindirect-branch=thunk -fno-pic" } */++/* { dg-options "-O2 -mfunction-return=keep -mindirect-branch=thunk -fno-pic" } */+ + void func0 (void);+ void func1 (void);+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-1.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-1.c+index 8b88449e625..12a61c3bbc7 100644+--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-1.c++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-1.c+@@ -1,5 +1,5 @@+ /* { dg-do compile } */+-/* { dg-options "-O2 -fno-pic" } */++/* { dg-options "-O2 -mfunction-return=keep -fno-pic" } */+ + typedef void (*dispatch_t)(long offset);+ +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-2.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-2.c+index c69f7bf4f60..a06907933a2 100644+--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-2.c++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-2.c+@@ -1,5 +1,5 @@+ /* { dg-do compile } */+-/* { dg-options "-O2 -fno-pic" } */++/* { dg-options "-O2 -mfunction-return=keep -fno-pic" } */+ + typedef void (*dispatch_t)(long offset);+ +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-3.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-3.c+index c845099a83e..7f56725e6b6 100644+--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-3.c++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-3.c+@@ -1,5 +1,5 @@+ /* { dg-do compile } */+-/* { dg-options "-O2 -fno-pic" } */++/* { dg-options "-O2 -mfunction-return=keep -fno-pic" } */+ + typedef void (*dispatch_t)(long offset);+ +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-4.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-4.c+index f636f3422fd..fd4ab1dbaa0 100644+--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-4.c++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-4.c+@@ -1,5 +1,5 @@+ /* { dg-do compile } */+-/* { dg-options "-O2 -fno-pic" } */++/* { dg-options "-O2 -mfunction-return=keep -fno-pic" } */+ + typedef void (*dispatch_t)(long offset);+ +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-5.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-5.c+index 5f1d6a78041..1ffbf3b1181 100644+--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-5.c++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-5.c+@@ -1,5 +1,5 @@+ /* { dg-do compile } */+-/* { dg-options "-O2 -fno-pic" } */++/* { dg-options "-O2 -mfunction-return=keep -fno-pic" } */+ + typedef void (*dispatch_t)(long offset);+ +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-6.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-6.c+index 56c92da9812..1559072919a 100644+--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-6.c++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-6.c+@@ -1,5 +1,5 @@+ /* { dg-do compile } */+-/* { dg-options "-O2 -fno-pic" } */++/* { dg-options "-O2 -mfunction-return=keep -fno-pic" } */+ + typedef void (*dispatch_t)(long offset);+ +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-7.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-7.c+index cfb6f5b234b..1717e7bb436 100644+--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-7.c++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-7.c+@@ -1,5 +1,5 @@+ /* { dg-do compile } */+-/* { dg-options "-O2 -fno-pic" } */++/* { dg-options "-O2 -mfunction-return=keep -fno-pic" } */+ + void func0 (void);+ void func1 (void);+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-8.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-8.c+index 9f6d12d74a1..af1bb125a22 100644+--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-8.c++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-8.c+@@ -1,5 +1,5 @@+ /* { dg-do compile } */+-/* { dg-options "-O2 -mindirect-branch=thunk -fno-pic" } */++/* { dg-options "-O2 -mfunction-return=keep -mindirect-branch=thunk -fno-pic" } */+ + void func0 (void);+ void func1 (void);+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-1.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-1.c+index a5b1d38e061..20903b0f79d 100644+--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-1.c++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-1.c+@@ -1,5 +1,5 @@+ /* { dg-do compile { target { ! x32 } } } */+-/* { dg-options "-O2 -mindirect-branch=thunk -fcheck-pointer-bounds -mmpx -fno-pic" } */++/* { dg-options "-O2 -mfunction-return=keep -mindirect-branch=thunk -fcheck-pointer-bounds -mmpx -fno-pic" } */+ + void (*dispatch) (char *);+ char buf[10];+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-2.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-2.c+index a42add209e2..aef4bd144f4 100644+--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-2.c++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-2.c+@@ -1,5 +1,5 @@+ /* { dg-do compile { target { ! x32 } } } */+-/* { dg-options "-O2 -mindirect-branch=thunk -fcheck-pointer-bounds -mmpx -fno-pic" } */++/* { dg-options "-O2 -mfunction-return=keep -mindirect-branch=thunk -fcheck-pointer-bounds -mmpx -fno-pic" } */+ + void (*dispatch) (char *);+ char buf[10];+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-3.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-3.c+index 265e010a0fe..2cc0343f828 100644+--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-3.c++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-3.c+@@ -1,5 +1,5 @@+ /* { dg-do compile { target { *-*-linux* && { ! x32 } } } } */+-/* { dg-options "-O2 -mindirect-branch=thunk -fcheck-pointer-bounds -mmpx -fpic -fno-plt" } */++/* { dg-options "-O2 -mfunction-return=keep -mindirect-branch=thunk -fcheck-pointer-bounds -mmpx -fpic -fno-plt" } */+ + void bar (char *);+ char buf[10];+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-4.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-4.c+index 1c01bcb7fc6..91560fef661 100644+--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-4.c++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-4.c+@@ -1,5 +1,5 @@+ /* { dg-do compile { target { *-*-linux* && { ! x32 } } } } */+-/* { dg-options "-O2 -mindirect-branch=thunk -fcheck-pointer-bounds -mmpx -fpic -fno-plt" } */++/* { dg-options "-O2 -mfunction-return=keep -mindirect-branch=thunk -fcheck-pointer-bounds -mmpx -fpic -fno-plt" } */+ + void bar (char *);+ char buf[10];+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-1.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-1.c+index f1fa0a11922..dc6bd10af4c 100644+--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-1.c++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-1.c+@@ -1,5 +1,5 @@+ /* { dg-do compile } */+-/* { dg-options "-O2 -mindirect-branch=thunk-extern -fno-pic" } */++/* { dg-options "-O2 -mfunction-return=keep -mindirect-branch=thunk-extern -fno-pic" } */+ + typedef void (*dispatch_t)(long offset);+ +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-2.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-2.c+index d6e078d594b..955aa256529 100644+--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-2.c++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-2.c+@@ -1,5 +1,5 @@+ /* { dg-do compile } */+-/* { dg-options "-O2 -mindirect-branch=thunk-extern -fno-pic" } */++/* { dg-options "-O2 -mfunction-return=keep -mindirect-branch=thunk-extern -fno-pic" } */+ + typedef void (*dispatch_t)(long offset);+ +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-3.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-3.c+index 3bbe2646955..1537239416f 100644+--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-3.c++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-3.c+@@ -1,5 +1,5 @@+ /* { dg-do compile } */+-/* { dg-options "-O2 -mindirect-branch=thunk-extern -fno-pic" } */++/* { dg-options "-O2 -mfunction-return=keep -mindirect-branch=thunk-extern -fno-pic" } */+ + typedef void (*dispatch_t)(long offset);+ +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-4.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-4.c+index 596fac599f6..c82e53068fe 100644+--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-4.c++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-4.c+@@ -1,5 +1,5 @@+ /* { dg-do compile } */+-/* { dg-options "-O2 -mindirect-branch=thunk-extern -fno-pic" } */++/* { dg-options "-O2 -mfunction-return=keep -mindirect-branch=thunk-extern -fno-pic" } */+ + typedef void (*dispatch_t)(long offset);+ +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-5.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-5.c+index ad54aaeac4c..23548d85f78 100644+--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-5.c++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-5.c+@@ -1,5 +1,5 @@+ /* { dg-do compile { target *-*-linux* } } */+-/* { dg-options "-O2 -fpic -fno-plt -mindirect-branch=thunk-extern" } */++/* { dg-options "-O2 -mfunction-return=keep -fpic -fno-plt -mindirect-branch=thunk-extern" } */+ + extern void bar (void);+ +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-6.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-6.c+index a8e75254cfe..56c2fe92f25 100644+--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-6.c++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-6.c+@@ -1,5 +1,5 @@+ /* { dg-do compile { target *-*-linux* } } */+-/* { dg-options "-O2 -fpic -fno-plt -mindirect-branch=thunk-extern" } */++/* { dg-options "-O2 -mfunction-return=keep -fpic -fno-plt -mindirect-branch=thunk-extern" } */+ + extern void bar (void);+ +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-7.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-7.c+index ab367951c45..e12b88593fe 100644+--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-7.c++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-7.c+@@ -1,5 +1,5 @@+ /* { dg-do compile } */+-/* { dg-options "-O2 -mindirect-branch=thunk-extern -fno-pic" } */++/* { dg-options "-O2 -mfunction-return=keep -mindirect-branch=thunk-extern -fno-pic" } */+ + void func0 (void);+ void func1 (void);+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-1.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-1.c+index 09b8ad7d879..87b5429702f 100644+--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-1.c++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-1.c+@@ -1,5 +1,5 @@+ /* { dg-do compile } */+-/* { dg-options "-O2 -mindirect-branch=thunk-inline -fno-pic" } */++/* { dg-options "-O2 -mfunction-return=keep -mindirect-branch=thunk-inline -fno-pic" } */+ + typedef void (*dispatch_t)(long offset);+ +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-2.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-2.c+index 1f873758fbe..a496a41a918 100644+--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-2.c++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-2.c+@@ -1,5 +1,5 @@+ /* { dg-do compile } */+-/* { dg-options "-O2 -mindirect-branch=thunk-inline -fno-pic" } */++/* { dg-options "-O2 -mfunction-return=keep -mindirect-branch=thunk-inline -fno-pic" } */+ + typedef void (*dispatch_t)(long offset);+ +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-3.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-3.c+index b24af1da963..6fe5ce71abf 100644+--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-3.c++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-3.c+@@ -1,5 +1,5 @@+ /* { dg-do compile } */+-/* { dg-options "-O2 -mindirect-branch=thunk-inline -fno-pic" } */++/* { dg-options "-O2 -mfunction-return=keep -mindirect-branch=thunk-inline -fno-pic" } */+ + typedef void (*dispatch_t)(long offset);+ +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-4.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-4.c+index 1a86608f727..65cd997a33f 100644+--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-4.c++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-4.c+@@ -1,5 +1,5 @@+ /* { dg-do compile } */+-/* { dg-options "-O2 -mindirect-branch=thunk-inline -fno-pic" } */++/* { dg-options "-O2 -mfunction-return=keep -mindirect-branch=thunk-inline -fno-pic" } */+ + typedef void (*dispatch_t)(long offset);+ +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-5.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-5.c+index f4890fe97b2..7321d015c02 100644+--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-5.c++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-5.c+@@ -1,5 +1,5 @@+ /* { dg-do compile { target *-*-linux* } } */+-/* { dg-options "-O2 -fpic -fno-plt -mindirect-branch=thunk-inline" } */++/* { dg-options "-O2 -mfunction-return=keep -fpic -fno-plt -mindirect-branch=thunk-inline" } */+ + extern void bar (void);+ +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-6.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-6.c+index 81b09e73ab8..6ec2e5621ab 100644+--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-6.c++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-6.c+@@ -1,5 +1,5 @@+ /* { dg-do compile { target *-*-linux* } } */+-/* { dg-options "-O2 -fpic -fno-plt -mindirect-branch=thunk-inline" } */++/* { dg-options "-O2 -mfunction-return=keep -fpic -fno-plt -mindirect-branch=thunk-inline" } */+ + extern void bar (void);+ +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-7.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-7.c+index 01d45782185..a3d1a13cded 100644+--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-7.c++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-7.c+@@ -1,5 +1,5 @@+ /* { dg-do compile } */+-/* { dg-options "-O2 -mindirect-branch=thunk-inline -fno-pic" } */++/* { dg-options "-O2 -mfunction-return=keep -mindirect-branch=thunk-inline -fno-pic" } */+ + void func0 (void);+ void func1 (void);+-- +2.15.1+diff --git a/gnu/packages/patches/gcc-retpoline-Add-mindirect-branch-loop.patch b/gnu/packages/patches/gcc-retpoline-Add-mindirect-branch-loop.patchnew file mode 100644index 000000000..ab715f46a--- /dev/null+++ b/gnu/packages/patches/gcc-retpoline-Add-mindirect-branch-loop.patch@@ -0,0 +1,233 @@+'Retpoline' mitigation technique for Spectre (branch target injection)+[CVE-2017-5715]:++https://security.googleblog.com/2018/01/more-details-about-mitigations-for-cpu_4.html+https://support.google.com/faqs/answer/7625886+https://spectreattack.com/+https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2017-5715++Patch copied from the 'retpoline-20180107' branch of upstream source repository+(please add new / update existing patches when new 'retpoline-xxxxxxxx' branch+appears):++http://git.infradead.org/users/dwmw2/gcc-retpoline.git++From d667049b53e3d45de057fba2f1ed0e3f268201c1 Mon Sep 17 00:00:00 2001+From: "H.J. Lu" <hjl.tools@gmail.com>+Date: Thu, 16 Nov 2017 14:46:20 -0800+Subject: [PATCH 10/17] Add -mindirect-branch-loop=++Add -mindirect-branch-loop= tests.+---+ gcc/config/i386/i386-opts.h | 6 +++++++ gcc/config/i386/i386.c | 19 +++++++++++++++++--+ gcc/config/i386/i386.opt | 16 +++++++++++++++++ gcc/testsuite/gcc.target/i386/indirect-thunk-loop-1.c | 19 ++++++++++++++++++++ gcc/testsuite/gcc.target/i386/indirect-thunk-loop-2.c | 19 ++++++++++++++++++++ gcc/testsuite/gcc.target/i386/indirect-thunk-loop-3.c | 19 ++++++++++++++++++++ gcc/testsuite/gcc.target/i386/indirect-thunk-loop-4.c | 19 ++++++++++++++++++++ gcc/testsuite/gcc.target/i386/indirect-thunk-loop-5.c | 19 ++++++++++++++++++++ 8 files changed, 134 insertions(+), 2 deletions(-)+ create mode 100644 gcc/testsuite/gcc.target/i386/indirect-thunk-loop-1.c+ create mode 100644 gcc/testsuite/gcc.target/i386/indirect-thunk-loop-2.c+ create mode 100644 gcc/testsuite/gcc.target/i386/indirect-thunk-loop-3.c+ create mode 100644 gcc/testsuite/gcc.target/i386/indirect-thunk-loop-4.c+ create mode 100644 gcc/testsuite/gcc.target/i386/indirect-thunk-loop-5.c++diff --git a/gcc/config/i386/i386-opts.h b/gcc/config/i386/i386-opts.h+index 9e56d7f2d12..b7b8fd280a3 100644+--- a/gcc/config/i386/i386-opts.h++++ b/gcc/config/i386/i386-opts.h+@@ -107,4 +107,10 @@ enum indirect_branch {+ indirect_branch_thunk_extern+ };+ ++enum indirect_branch_loop {++ indirect_branch_loop_lfence,++ indirect_branch_loop_pause,++ indirect_branch_loop_nop++};+++ #endif+diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c+index 590729b3f87..be1ff4752a9 100644+--- a/gcc/config/i386/i386.c++++ b/gcc/config/i386/i386.c+@@ -12016,8 +12016,23 @@ output_indirect_thunk (bool need_bnd_p, int regno)+ + ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, indirectlabel1);+ +- /* lfence . */+- fprintf (asm_out_file, "\tlfence\n");++ switch (ix86_indirect_branch_loop)++ {++ case indirect_branch_loop_lfence:++ /* lfence. */++ fprintf (asm_out_file, "\tlfence\n");++ break;++ case indirect_branch_loop_pause:++ /* pause. */++ fprintf (asm_out_file, "\tpause\n");++ break;++ case indirect_branch_loop_nop:++ /* nop. */++ fprintf (asm_out_file, "\tnop\n");++ break;++ default:++ gcc_unreachable ();++ }+ + /* Jump. */+ fputs ("\tjmp\t", asm_out_file);+diff --git a/gcc/config/i386/i386.opt b/gcc/config/i386/i386.opt+index 4a932e11bf6..bc81e6bea86 100644+--- a/gcc/config/i386/i386.opt++++ b/gcc/config/i386/i386.opt+@@ -947,3 +947,19 @@ Enum(indirect_branch) String(thunk-inline) Value(indirect_branch_thunk_inline)+ + EnumValue+ Enum(indirect_branch) String(thunk-extern) Value(indirect_branch_thunk_extern)++++mindirect-branch-loop=++Target Report RejectNegative Joined Enum(indirect_branch_loop) Var(ix86_indirect_branch_loop) Undocumented Init(indirect_branch_loop_lfence)++++Enum++Name(indirect_branch_loop) Type(enum indirect_branch_loop)++Known looop choices (for use with the -mindirect-branch-loop= option):++++EnumValue++Enum(indirect_branch_loop) String(lfence) Value(indirect_branch_loop_lfence)++++EnumValue++Enum(indirect_branch_loop) String(pause) Value(indirect_branch_loop_pause)++++EnumValue++Enum(indirect_branch_loop) String(nop) Value(indirect_branch_loop_nop)+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-loop-1.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-loop-1.c+new file mode 100644+index 00000000000..f0e8f4949c8+--- /dev/null++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-loop-1.c+@@ -0,0 +1,19 @@++/* { dg-do compile } */++/* { dg-options "-O2 -mindirect-branch=thunk -mindirect-branch-loop=pause -fno-pic" } */++++typedef void (*dispatch_t)(long offset);++++dispatch_t dispatch;++++void++male_indirect_jump (long offset)++{++ dispatch(offset);++}++++/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { ! x32 } } } } */++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" { target { ! x32 } } } } */++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk\.(r|e)ax" { target x32 } } } */++/* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */++/* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */++/* { dg-final { scan-assembler {\tpause} } } */+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-loop-2.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-loop-2.c+new file mode 100644+index 00000000000..a577ac2568a+--- /dev/null++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-loop-2.c+@@ -0,0 +1,19 @@++/* { dg-do compile } */++/* { dg-options "-O2 -mindirect-branch=thunk -mindirect-branch-loop=nop -fno-pic" } */++++typedef void (*dispatch_t)(long offset);++++dispatch_t dispatch[256];++++void++male_indirect_jump (long offset)++{++ dispatch[offset](offset);++}++++/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { ! x32 } } } } */++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" { target { ! x32 } } } } */++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk\.(r|e)ax" { target x32 } } } */++/* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */++/* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */++/* { dg-final { scan-assembler {\tnop} } } */+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-loop-3.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-loop-3.c+new file mode 100644+index 00000000000..c8dcb9639c4+--- /dev/null++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-loop-3.c+@@ -0,0 +1,19 @@++/* { dg-do compile } */++/* { dg-options "-O2 -mindirect-branch=thunk -mindirect-branch-loop=lfence -fno-pic" } */++++typedef void (*dispatch_t)(long offset);++++dispatch_t dispatch;++++void++male_indirect_jump (long offset)++{++ dispatch(offset);++}++++/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { ! x32 } } } } */++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" { target { ! x32 } } } } */++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk\.(r|e)ax" { target x32 } } } */++/* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */++/* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */++/* { dg-final { scan-assembler {\tlfence} } } */+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-loop-4.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-loop-4.c+new file mode 100644+index 00000000000..8569dfc92c3+--- /dev/null++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-loop-4.c+@@ -0,0 +1,19 @@++/* { dg-do compile } */++/* { dg-options "-O2 -mindirect-branch=thunk-inline -mindirect-branch-loop=pause -fno-pic" } */++++typedef void (*dispatch_t)(long offset);++++dispatch_t dispatch;++++void++male_indirect_jump (long offset)++{++ dispatch(offset);++}++++/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { ! x32 } } } } */++/* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */++/* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */++/* { dg-final { scan-assembler {\tpause} } } */++/* { dg-final { scan-assembler-not "__x86.indirect_thunk" } } */++/* { dg-final { scan-assembler-not "pushq\[ \t\]%rax" { target x32 } } } */+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-loop-5.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-loop-5.c+new file mode 100644+index 00000000000..bcf19c9ede1+--- /dev/null++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-loop-5.c+@@ -0,0 +1,19 @@++/* { dg-do compile } */++/* { dg-options "-O2 -mindirect-branch=thunk-extern -mindirect-branch-loop=pause -fno-pic" } */++++typedef void (*dispatch_t)(long offset);++++dispatch_t dispatch;++++void++male_indirect_jump (long offset)++{++ dispatch(offset);++}++++/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { ! x32 } } } } */++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" { target { ! x32 } } } } */++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk\.(r|e)ax" { target x32 } } } */++/* { dg-final { scan-assembler-not {\t(lfence|pause|nop)} } } */++/* { dg-final { scan-assembler-not "jmp\[ \t\]*\.LIND" } } */++/* { dg-final { scan-assembler-not "call\[ \t\]*\.LIND" } } */+-- +2.15.1+diff --git a/gnu/packages/patches/gcc-retpoline-Add-mindirect-branch-register-and-tests.patch b/gnu/packages/patches/gcc-retpoline-Add-mindirect-branch-register-and-tests.patchnew file mode 100644index 000000000..de9e373fd--- /dev/null+++ b/gnu/packages/patches/gcc-retpoline-Add-mindirect-branch-register-and-tests.patch@@ -0,0 +1,403 @@+'Retpoline' mitigation technique for Spectre (branch target injection)+[CVE-2017-5715]:++https://security.googleblog.com/2018/01/more-details-about-mitigations-for-cpu_4.html+https://support.google.com/faqs/answer/7625886+https://spectreattack.com/+https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2017-5715++Patch copied from the 'retpoline-20180107' branch of upstream source repository+(please add new / update existing patches when new 'retpoline-xxxxxxxx' branch+appears):++http://git.infradead.org/users/dwmw2/gcc-retpoline.git++From fb8875abab630962dbcb08c822b1b960fa5a51d4 Mon Sep 17 00:00:00 2001+From: "H.J. Lu" <hjl.tools@gmail.com>+Date: Wed, 19 Jul 2017 19:23:02 -0700+Subject: [PATCH 13/17] Add -mindirect-branch-register and tests++Add -mindirect-branch-register to force indirect branch via register.+This is implemented by disabling patterns of indirect branch via memory,+similar to TARGET_X32. With -mindirect-branch-register:++void (*func) (void);++void+bar (void)+{+ func ();+}++is compiled into:++ movq func(%rip), %rax+ jmp __x86.indirect_thunk.ax++__x86.indirect_thunk.ax:+ call .LIND3+.LIND2:+ lfence+ jmp .LIND2+.LIND3:+ mov %rax, (%rsp)+ ret++and++void (*func) (void);++int+bar (void)+{+ func ();+ return 0;+}++is compiled into:++ subq $8, %rsp+ movq func(%rip), %rax+ call __x86.indirect_thunk.ax+ xorl %eax, %eax+ addq $8, %rsp+ ret++ * config/i386/constraints.md (Bs): Disallow memory operand for+ -mindirect-branch-register.+ (Bw): Likewise.+ * config/i386/predicates.md (indirect_branch_operand): Likewise.+ (GOT_memory_operand): Likewise.+ (call_insn_operand): Likewise.+ (sibcall_insn_operand): Likewise.+ (GOT32_symbol_operand): Likewise.+ * config/i386/i386.md (indirect_jump): Call convert_memory_address+ for -mindirect-branch-register.+ (tablejump): Likewise.+ (*sibcall_memory): Likewise.+ (*sibcall_value_memory): Likewise.+ Disallow peepholes of indirect call and jump via memory for+ -mindirect-branch-register.+ (*call_pop): Replace m with Bw.+ (*call_value_pop): Likewise.+ (*sibcall_pop_memory): Replace m with Bs.+---+ gcc/config/i386/constraints.md | 12 +++++---+ gcc/config/i386/i386.md | 34 ++++++++++++++--------+ gcc/config/i386/i386.opt | 4 ++++ gcc/config/i386/predicates.md | 21 ++++++++-----+ .../gcc.target/i386/indirect-thunk-register-1.c | 22 +++++++++++++++ .../gcc.target/i386/indirect-thunk-register-2.c | 20 ++++++++++++++ .../gcc.target/i386/indirect-thunk-register-3.c | 19 +++++++++++++ 7 files changed, 109 insertions(+), 23 deletions(-)+ create mode 100644 gcc/testsuite/gcc.target/i386/indirect-thunk-register-1.c+ create mode 100644 gcc/testsuite/gcc.target/i386/indirect-thunk-register-2.c+ create mode 100644 gcc/testsuite/gcc.target/i386/indirect-thunk-register-3.c++diff --git a/gcc/config/i386/constraints.md b/gcc/config/i386/constraints.md+index 38d604fdace..697caf704dd 100644+--- a/gcc/config/i386/constraints.md++++ b/gcc/config/i386/constraints.md+@@ -198,16 +198,20 @@+ + (define_constraint "Bs"+ "@internal Sibcall memory operand."+- (ior (and (not (match_test "TARGET_X32"))++ (ior (and (not (match_test "TARGET_X32++ || ix86_indirect_branch_thunk_register"))+ (match_operand 0 "sibcall_memory_operand"))+- (and (match_test "TARGET_X32 && Pmode == DImode")++ (and (match_test "TARGET_X32 && Pmode == DImode++ && !ix86_indirect_branch_thunk_register")+ (match_operand 0 "GOT_memory_operand"))))+ + (define_constraint "Bw"+ "@internal Call memory operand."+- (ior (and (not (match_test "TARGET_X32"))++ (ior (and (not (match_test "TARGET_X32++ || ix86_indirect_branch_thunk_register"))+ (match_operand 0 "memory_operand"))+- (and (match_test "TARGET_X32 && Pmode == DImode")++ (and (match_test "TARGET_X32 && Pmode == DImode++ && !ix86_indirect_branch_thunk_register")+ (match_operand 0 "GOT_memory_operand"))))+ + (define_constraint "Bz"+diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md+index 00a9afef225..473fa5c089b 100644+--- a/gcc/config/i386/i386.md++++ b/gcc/config/i386/i386.md+@@ -11608,7 +11608,7 @@+ [(set (pc) (match_operand 0 "indirect_branch_operand"))]+ ""+ {+- if (TARGET_X32)++ if (TARGET_X32 || ix86_indirect_branch_thunk_register)+ operands[0] = convert_memory_address (word_mode, operands[0]);+ })+ +@@ -11657,7 +11657,7 @@+ OPTAB_DIRECT);+ }+ +- if (TARGET_X32)++ if (TARGET_X32 || ix86_indirect_branch_thunk_register)+ operands[0] = convert_memory_address (word_mode, operands[0]);+ })+ +@@ -11844,7 +11844,7 @@+ [(call (mem:QI (match_operand:W 0 "memory_operand" "m"))+ (match_operand 1))+ (unspec [(const_int 0)] UNSPEC_PEEPSIB)]+- "!TARGET_X32"++ "!TARGET_X32 && !ix86_indirect_branch_thunk_register"+ "* return ix86_output_call_insn (insn, operands[0]);"+ [(set_attr "type" "call")])+ +@@ -11853,7 +11853,9 @@+ (match_operand:W 1 "memory_operand"))+ (call (mem:QI (match_dup 0))+ (match_operand 3))]+- "!TARGET_X32 && SIBLING_CALL_P (peep2_next_insn (1))++ "!TARGET_X32++ && !ix86_indirect_branch_thunk_register++ && SIBLING_CALL_P (peep2_next_insn (1))+ && !reg_mentioned_p (operands[0],+ CALL_INSN_FUNCTION_USAGE (peep2_next_insn (1)))"+ [(parallel [(call (mem:QI (match_dup 1))+@@ -11866,7 +11868,9 @@+ (unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)+ (call (mem:QI (match_dup 0))+ (match_operand 3))]+- "!TARGET_X32 && SIBLING_CALL_P (peep2_next_insn (2))++ "!TARGET_X32++ && !ix86_indirect_branch_thunk_register++ && SIBLING_CALL_P (peep2_next_insn (2))+ && !reg_mentioned_p (operands[0],+ CALL_INSN_FUNCTION_USAGE (peep2_next_insn (2)))"+ [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)+@@ -11888,7 +11892,7 @@+ })+ + (define_insn "*call_pop"+- [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lmBz"))++ [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lBwBz"))+ (match_operand 1))+ (set (reg:SI SP_REG)+ (plus:SI (reg:SI SP_REG)+@@ -11908,7 +11912,7 @@+ [(set_attr "type" "call")])+ + (define_insn "*sibcall_pop_memory"+- [(call (mem:QI (match_operand:SI 0 "memory_operand" "m"))++ [(call (mem:QI (match_operand:SI 0 "memory_operand" "Bs"))+ (match_operand 1))+ (set (reg:SI SP_REG)+ (plus:SI (reg:SI SP_REG)+@@ -11962,7 +11966,9 @@+ [(set (match_operand:W 0 "register_operand")+ (match_operand:W 1 "memory_operand"))+ (set (pc) (match_dup 0))]+- "!TARGET_X32 && peep2_reg_dead_p (2, operands[0])"++ "!TARGET_X32++ && !ix86_indirect_branch_thunk_register++ && peep2_reg_dead_p (2, operands[0])"+ [(set (pc) (match_dup 1))])+ + ;; Call subroutine, returning value in operand 0+@@ -12043,7 +12049,7 @@+ (call (mem:QI (match_operand:W 1 "memory_operand" "m"))+ (match_operand 2)))+ (unspec [(const_int 0)] UNSPEC_PEEPSIB)]+- "!TARGET_X32"++ "!TARGET_X32 && !ix86_indirect_branch_thunk_register"+ "* return ix86_output_call_insn (insn, operands[1]);"+ [(set_attr "type" "callv")])+ +@@ -12053,7 +12059,9 @@+ (set (match_operand 2)+ (call (mem:QI (match_dup 0))+ (match_operand 3)))]+- "!TARGET_X32 && SIBLING_CALL_P (peep2_next_insn (1))++ "!TARGET_X32++ && !ix86_indirect_branch_thunk_register++ && SIBLING_CALL_P (peep2_next_insn (1))+ && !reg_mentioned_p (operands[0],+ CALL_INSN_FUNCTION_USAGE (peep2_next_insn (1)))"+ [(parallel [(set (match_dup 2)+@@ -12068,7 +12076,9 @@+ (set (match_operand 2)+ (call (mem:QI (match_dup 0))+ (match_operand 3)))]+- "!TARGET_X32 && SIBLING_CALL_P (peep2_next_insn (2))++ "!TARGET_X32++ && !ix86_indirect_branch_thunk_register++ && SIBLING_CALL_P (peep2_next_insn (2))+ && !reg_mentioned_p (operands[0],+ CALL_INSN_FUNCTION_USAGE (peep2_next_insn (2)))"+ [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)+@@ -12093,7 +12103,7 @@+ + (define_insn "*call_value_pop"+ [(set (match_operand 0)+- (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lmBz"))++ (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lBwBz"))+ (match_operand 2)))+ (set (reg:SI SP_REG)+ (plus:SI (reg:SI SP_REG)+diff --git a/gcc/config/i386/i386.opt b/gcc/config/i386/i386.opt+index fc2c81c3fb5..802245f4efe 100644+--- a/gcc/config/i386/i386.opt++++ b/gcc/config/i386/i386.opt+@@ -952,6 +952,10 @@ Enum(indirect_branch) String(thunk-inline) Value(indirect_branch_thunk_inline)+ EnumValue+ Enum(indirect_branch) String(thunk-extern) Value(indirect_branch_thunk_extern)+ ++mindirect-branch-register++Target Report Var(ix86_indirect_branch_thunk_register) Init(0)++Force indirect call and jump via register.+++ mindirect-branch-loop=+ Target Report RejectNegative Joined Enum(indirect_branch_loop) Var(ix86_indirect_branch_loop) Undocumented Init(indirect_branch_loop_lfence)+ +diff --git a/gcc/config/i386/predicates.md b/gcc/config/i386/predicates.md+index 8f250a2e720..fc4933e4533 100644+--- a/gcc/config/i386/predicates.md++++ b/gcc/config/i386/predicates.md+@@ -635,7 +635,8 @@+ ;; Test for a valid operand for indirect branch.+ (define_predicate "indirect_branch_operand"+ (ior (match_operand 0 "register_operand")+- (and (not (match_test "TARGET_X32"))++ (and (not (match_test "TARGET_X32++ || ix86_indirect_branch_thunk_register"))+ (match_operand 0 "memory_operand"))))+ + ;; Return true if OP is a memory operands that can be used in sibcalls.+@@ -664,7 +665,8 @@+ + ;; Return true if OP is a GOT memory operand.+ (define_predicate "GOT_memory_operand"+- (match_operand 0 "memory_operand")++ (and (match_test "!ix86_indirect_branch_thunk_register")++ (match_operand 0 "memory_operand"))+ {+ op = XEXP (op, 0);+ return (GET_CODE (op) == CONST+@@ -678,9 +680,11 @@+ (ior (match_test "constant_call_address_operand+ (op, mode == VOIDmode ? mode : Pmode)")+ (match_operand 0 "call_register_no_elim_operand")+- (ior (and (not (match_test "TARGET_X32"))++ (ior (and (not (match_test "TARGET_X32++ || ix86_indirect_branch_thunk_register"))+ (match_operand 0 "memory_operand"))+- (and (match_test "TARGET_X32 && Pmode == DImode")++ (and (match_test "TARGET_X32 && Pmode == DImode++ && !ix86_indirect_branch_thunk_register")+ (match_operand 0 "GOT_memory_operand")))))+ + ;; Similarly, but for tail calls, in which we cannot allow memory references.+@@ -688,14 +692,17 @@+ (ior (match_test "constant_call_address_operand+ (op, mode == VOIDmode ? mode : Pmode)")+ (match_operand 0 "register_no_elim_operand")+- (ior (and (not (match_test "TARGET_X32"))++ (ior (and (not (match_test "TARGET_X32++ || ix86_indirect_branch_thunk_register"))+ (match_operand 0 "sibcall_memory_operand"))+- (and (match_test "TARGET_X32 && Pmode == DImode")++ (and (match_test "TARGET_X32 && Pmode == DImode++ && !ix86_indirect_branch_thunk_register")+ (match_operand 0 "GOT_memory_operand")))))+ + ;; Return true if OP is a 32-bit GOT symbol operand.+ (define_predicate "GOT32_symbol_operand"+- (match_test "GET_CODE (op) == CONST++ (match_test "!ix86_indirect_branch_thunk_register++ && GET_CODE (op) == CONST+ && GET_CODE (XEXP (op, 0)) == UNSPEC+ && XINT (XEXP (op, 0), 1) == UNSPEC_GOT"))+ +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-register-1.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-register-1.c+new file mode 100644+index 00000000000..ef493a05bbf+--- /dev/null++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-register-1.c+@@ -0,0 +1,22 @@++/* { dg-do compile } */++/* { dg-options "-O2 -mindirect-branch=thunk -mindirect-branch-register -fno-pic" } */++++typedef void (*dispatch_t)(long offset);++++dispatch_t dispatch;++++void++male_indirect_jump (long offset)++{++ dispatch(offset);++}++++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk\.(r|e)ax" } } */++/* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */++/* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */++/* { dg-final { scan-assembler "mov\[ \t\](%eax|%rax), \\((%esp|%rsp)\\)" } } */++/* { dg-final { scan-assembler {\tlfence} } } */++/* { dg-final { scan-assembler-not "push(?:l|q)\[ \t\]*_?dispatch" } } */++/* { dg-final { scan-assembler-not "pushq\[ \t\]%rax" } } */++/* { dg-final { scan-assembler-not "__x86.indirect_thunk\n" } } */++/* { dg-final { scan-assembler-not "__x86.indirect_thunk_bnd\n" } } */+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-register-2.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-register-2.c+new file mode 100644+index 00000000000..89fc8e6e6c4+--- /dev/null++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-register-2.c+@@ -0,0 +1,20 @@++/* { dg-do compile } */++/* { dg-options "-O2 -mindirect-branch=thunk-inline -mindirect-branch-register -fno-pic" } */++++typedef void (*dispatch_t)(long offset);++++dispatch_t dispatch;++++void++male_indirect_jump (long offset)++{++ dispatch(offset);++}++++/* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */++/* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */++/* { dg-final { scan-assembler "mov\[ \t\](%eax|%rax), \\((%esp|%rsp)\\)" } } */++/* { dg-final { scan-assembler {\tlfence} } } */++/* { dg-final { scan-assembler-not "push(?:l|q)\[ \t\]*_?dispatch" } } */++/* { dg-final { scan-assembler-not "pushq\[ \t\]%rax" } } */++/* { dg-final { scan-assembler-not "__x86.indirect_thunk" } } */+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-register-3.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-register-3.c+new file mode 100644+index 00000000000..31af7ac05b8+--- /dev/null++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-register-3.c+@@ -0,0 +1,19 @@++/* { dg-do compile } */++/* { dg-options "-O2 -mindirect-branch=thunk-extern -mindirect-branch-register -fno-pic" } */++++typedef void (*dispatch_t)(long offset);++++dispatch_t dispatch;++++void++male_indirect_jump (long offset)++{++ dispatch(offset);++}++++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk\.(r|e)ax" } } */++/* { dg-final { scan-assembler-not "push(?:l|q)\[ \t\]*_?dispatch" } } */++/* { dg-final { scan-assembler-not "pushq\[ \t\]%rax" } } */++/* { dg-final { scan-assembler-not {\t(lfence|pause|nop)} } } */++/* { dg-final { scan-assembler-not "jmp\[ \t\]*\.LIND" } } */++/* { dg-final { scan-assembler-not "call\[ \t\]*\.LIND" } } */+-- +2.15.1+diff --git a/gnu/packages/patches/gcc-retpoline-Add-mindirect-branch-thunk-extern.patch b/gnu/packages/patches/gcc-retpoline-Add-mindirect-branch-thunk-extern.patchnew file mode 100644index 000000000..18b2dfaea--- /dev/null+++ b/gnu/packages/patches/gcc-retpoline-Add-mindirect-branch-thunk-extern.patch@@ -0,0 +1,263 @@+'Retpoline' mitigation technique for Spectre (branch target injection)+[CVE-2017-5715]:++https://security.googleblog.com/2018/01/more-details-about-mitigations-for-cpu_4.html+https://support.google.com/faqs/answer/7625886+https://spectreattack.com/+https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2017-5715++Patch copied from the 'retpoline-20180107' branch of upstream source repository+(please add new / update existing patches when new 'retpoline-xxxxxxxx' branch+appears):++http://git.infradead.org/users/dwmw2/gcc-retpoline.git++From 4032162fb6d36e20091885d0558f91daaa0080d3 Mon Sep 17 00:00:00 2001+From: "H.J. Lu" <hjl.tools@gmail.com>+Date: Mon, 27 Nov 2017 08:38:41 -0800+Subject: [PATCH 07/17] Add -mindirect-branch=thunk-extern++Add -mindirect-branch=thunk-extern tests+---+ gcc/config/i386/i386-opts.h | 3 +-+ gcc/config/i386/i386.opt | 3 +++ .../gcc.target/i386/indirect-thunk-extern-1.c | 19 +++++++++++ .../gcc.target/i386/indirect-thunk-extern-2.c | 19 +++++++++++ .../gcc.target/i386/indirect-thunk-extern-3.c | 20 +++++++++++ .../gcc.target/i386/indirect-thunk-extern-4.c | 20 +++++++++++ .../gcc.target/i386/indirect-thunk-extern-5.c | 16 +++++++++ .../gcc.target/i386/indirect-thunk-extern-6.c | 17 ++++++++++ .../gcc.target/i386/indirect-thunk-extern-7.c | 43 +++++++++++++++++++++++ 9 files changed, 159 insertions(+), 1 deletion(-)+ create mode 100644 gcc/testsuite/gcc.target/i386/indirect-thunk-extern-1.c+ create mode 100644 gcc/testsuite/gcc.target/i386/indirect-thunk-extern-2.c+ create mode 100644 gcc/testsuite/gcc.target/i386/indirect-thunk-extern-3.c+ create mode 100644 gcc/testsuite/gcc.target/i386/indirect-thunk-extern-4.c+ create mode 100644 gcc/testsuite/gcc.target/i386/indirect-thunk-extern-5.c+ create mode 100644 gcc/testsuite/gcc.target/i386/indirect-thunk-extern-6.c+ create mode 100644 gcc/testsuite/gcc.target/i386/indirect-thunk-extern-7.c++diff --git a/gcc/config/i386/i386-opts.h b/gcc/config/i386/i386-opts.h+index f301890575a..f8d80ba7ec6 100644+--- a/gcc/config/i386/i386-opts.h++++ b/gcc/config/i386/i386-opts.h+@@ -102,7 +102,8 @@ enum stack_protector_guard {+ enum indirect_branch {+ indirect_branch_keep,+ indirect_branch_thunk,+- indirect_branch_thunk_inline++ indirect_branch_thunk_inline,++ indirect_branch_thunk_extern+ };+ + #endif+diff --git a/gcc/config/i386/i386.opt b/gcc/config/i386/i386.opt+index 68484a75022..4a932e11bf6 100644+--- a/gcc/config/i386/i386.opt++++ b/gcc/config/i386/i386.opt+@@ -944,3 +944,6 @@ Enum(indirect_branch) String(thunk) Value(indirect_branch_thunk)+ + EnumValue+ Enum(indirect_branch) String(thunk-inline) Value(indirect_branch_thunk_inline)++++EnumValue++Enum(indirect_branch) String(thunk-extern) Value(indirect_branch_thunk_extern)+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-1.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-1.c+new file mode 100644+index 00000000000..0a1f91be988+--- /dev/null++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-1.c+@@ -0,0 +1,19 @@++/* { dg-do compile } */++/* { dg-options "-O2 -mindirect-branch=thunk-extern -fno-pic" } */++++typedef void (*dispatch_t)(long offset);++++dispatch_t dispatch;++++void++male_indirect_jump (long offset)++{++ dispatch(offset);++}++++/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { ! x32 } } } } */++/* { dg-final { scan-assembler "pushq\[ \t\]%rax" { target x32 } } } */++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" } } */++/* { dg-final { scan-assembler-not {\t(lfence|pause)} } } */++/* { dg-final { scan-assembler-not "jmp\[ \t\]*\.LIND" } } */++/* { dg-final { scan-assembler-not "call\[ \t\]*\.LIND" } } */+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-2.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-2.c+new file mode 100644+index 00000000000..182520ab3dc+--- /dev/null++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-2.c+@@ -0,0 +1,19 @@++/* { dg-do compile } */++/* { dg-options "-O2 -mindirect-branch=thunk-extern -fno-pic" } */++++typedef void (*dispatch_t)(long offset);++++dispatch_t dispatch[256];++++void++male_indirect_jump (long offset)++{++ dispatch[offset](offset);++}++++/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { ! x32 } } } } */++/* { dg-final { scan-assembler "pushq\[ \t\]%rax" { target x32 } } } */++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" } } */++/* { dg-final { scan-assembler-not {\t(lfence|pause)} } } */++/* { dg-final { scan-assembler-not "jmp\[ \t\]*\.LIND" } } */++/* { dg-final { scan-assembler-not "call\[ \t\]*\.LIND" } } */+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-3.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-3.c+new file mode 100644+index 00000000000..5c31ddc34fd+--- /dev/null++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-3.c+@@ -0,0 +1,20 @@++/* { dg-do compile } */++/* { dg-options "-O2 -mindirect-branch=thunk-extern -fno-pic" } */++++typedef void (*dispatch_t)(long offset);++++dispatch_t dispatch;++++int++male_indirect_jump (long offset)++{++ dispatch(offset);++ return 0;++}++++/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { ! x32 } } } } */++/* { dg-final { scan-assembler "pushq\[ \t\]%rax" { target x32 } } } */++/* { dg-final { scan-assembler-times "jmp\[ \t\]*\.LIND" 1 } } */++/* { dg-final { scan-assembler-times "call\[ \t\]*\.LIND" 1 } } */++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" } } */++/* { dg-final { scan-assembler-not {\t(lfence|pause)} } } */+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-4.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-4.c+new file mode 100644+index 00000000000..f24d0c060f2+--- /dev/null++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-4.c+@@ -0,0 +1,20 @@++/* { dg-do compile } */++/* { dg-options "-O2 -mindirect-branch=thunk-extern -fno-pic" } */++++typedef void (*dispatch_t)(long offset);++++dispatch_t dispatch[256];++++int++male_indirect_jump (long offset)++{++ dispatch[offset](offset);++ return 0;++}++++/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { ! x32 } } } } */++/* { dg-final { scan-assembler "pushq\[ \t\]%rax" { target x32 } } } */++/* { dg-final { scan-assembler-times "jmp\[ \t\]*\.LIND" 1 } } */++/* { dg-final { scan-assembler-times "call\[ \t\]*\.LIND" 1 } } */++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" } } */++/* { dg-final { scan-assembler-not {\t(lfence|pause)} } } */+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-5.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-5.c+new file mode 100644+index 00000000000..ad54aaeac4c+--- /dev/null++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-5.c+@@ -0,0 +1,16 @@++/* { dg-do compile { target *-*-linux* } } */++/* { dg-options "-O2 -fpic -fno-plt -mindirect-branch=thunk-extern" } */++++extern void bar (void);++++void++foo (void)++{++ bar ();++}++++/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*bar@GOT" } } */++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" } } */++/* { dg-final { scan-assembler-not {\t(lfence|pause)} } } */++/* { dg-final { scan-assembler-not "jmp\[ \t\]*\.LIND" } } */++/* { dg-final { scan-assembler-not "call\[ \t\]*\.LIND" } } */+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-6.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-6.c+new file mode 100644+index 00000000000..a8e75254cfe+--- /dev/null++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-6.c+@@ -0,0 +1,17 @@++/* { dg-do compile { target *-*-linux* } } */++/* { dg-options "-O2 -fpic -fno-plt -mindirect-branch=thunk-extern" } */++++extern void bar (void);++++int++foo (void)++{++ bar ();++ return 0;++}++++/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*bar@GOT" } } */++/* { dg-final { scan-assembler-times "jmp\[ \t\]*\.LIND" 1 } } */++/* { dg-final { scan-assembler-times "call\[ \t\]*\.LIND" 1 } } */++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" } } */++/* { dg-final { scan-assembler-not {\t(lfence|pause)} } } */+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-7.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-7.c+new file mode 100644+index 00000000000..8d39fb6f939+--- /dev/null++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-7.c+@@ -0,0 +1,43 @@++/* { dg-do compile } */++/* { dg-options "-O2 -mindirect-branch=thunk-extern -fno-pic" } */++++void func0 (void);++void func1 (void);++void func2 (void);++void func3 (void);++void func4 (void);++void func4 (void);++void func5 (void);++++void++bar (int i)++{++ switch (i)++ {++ default:++ func0 ();++ break;++ case 1:++ func1 ();++ break;++ case 2:++ func2 ();++ break;++ case 3:++ func3 ();++ break;++ case 4:++ func4 ();++ break;++ case 5:++ func5 ();++ break;++ }++}++++/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*\.L\[0-9\]+\\(,%" { target { ! x32 } } } } */++/* { dg-final { scan-assembler "pushq\[ \t\]%rax" { target x32 } } } */++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" } } */++/* { dg-final { scan-assembler-not {\t(lfence|pause)} } } */++/* { dg-final { scan-assembler-not "jmp\[ \t\]*\.LIND" } } */++/* { dg-final { scan-assembler-not "call\[ \t\]*\.LIND" } } */+-- +2.15.1+diff --git a/gnu/packages/patches/gcc-retpoline-Add-mindirect-branch-thunk-inline.patch b/gnu/packages/patches/gcc-retpoline-Add-mindirect-branch-thunk-inline.patchnew file mode 100644index 000000000..bb12c0e95--- /dev/null+++ b/gnu/packages/patches/gcc-retpoline-Add-mindirect-branch-thunk-inline.patch@@ -0,0 +1,310 @@+'Retpoline' mitigation technique for Spectre (branch target injection)+[CVE-2017-5715]:++https://security.googleblog.com/2018/01/more-details-about-mitigations-for-cpu_4.html+https://support.google.com/faqs/answer/7625886+https://spectreattack.com/+https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2017-5715++Patch copied from the 'retpoline-20180107' branch of upstream source repository+(please add new / update existing patches when new 'retpoline-xxxxxxxx' branch+appears):++http://git.infradead.org/users/dwmw2/gcc-retpoline.git++From 7f4f2bf1688c81496107993080e68a29a24de702 Mon Sep 17 00:00:00 2001+From: "H.J. Lu" <hjl.tools@gmail.com>+Date: Wed, 15 Nov 2017 11:20:31 -0800+Subject: [PATCH 06/17] Add -mindirect-branch=thunk-inline++Add -mindirect-branch=thunk-inline tests+---+ gcc/config/i386/i386-opts.h | 3 +-+ gcc/config/i386/i386.c | 30 +++++++++++-----+ gcc/config/i386/i386.opt | 3 +++ .../gcc.target/i386/indirect-thunk-inline-1.c | 18 +++++++++++ .../gcc.target/i386/indirect-thunk-inline-2.c | 18 +++++++++++ .../gcc.target/i386/indirect-thunk-inline-3.c | 19 +++++++++++ .../gcc.target/i386/indirect-thunk-inline-4.c | 19 +++++++++++ .../gcc.target/i386/indirect-thunk-inline-5.c | 15 +++++++++ .../gcc.target/i386/indirect-thunk-inline-6.c | 16 ++++++++++ .../gcc.target/i386/indirect-thunk-inline-7.c | 42 +++++++++++++++++++++++ 10 files changed, 173 insertions(+), 10 deletions(-)+ create mode 100644 gcc/testsuite/gcc.target/i386/indirect-thunk-inline-1.c+ create mode 100644 gcc/testsuite/gcc.target/i386/indirect-thunk-inline-2.c+ create mode 100644 gcc/testsuite/gcc.target/i386/indirect-thunk-inline-3.c+ create mode 100644 gcc/testsuite/gcc.target/i386/indirect-thunk-inline-4.c+ create mode 100644 gcc/testsuite/gcc.target/i386/indirect-thunk-inline-5.c+ create mode 100644 gcc/testsuite/gcc.target/i386/indirect-thunk-inline-6.c+ create mode 100644 gcc/testsuite/gcc.target/i386/indirect-thunk-inline-7.c++diff --git a/gcc/config/i386/i386-opts.h b/gcc/config/i386/i386-opts.h+index 1565d8fdc65..f301890575a 100644+--- a/gcc/config/i386/i386-opts.h++++ b/gcc/config/i386/i386-opts.h+@@ -101,7 +101,8 @@ enum stack_protector_guard {+ + enum indirect_branch {+ indirect_branch_keep,+- indirect_branch_thunk++ indirect_branch_thunk,++ indirect_branch_thunk_inline+ };+ + #endif+diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c+index 96424361a1c..ac542f79846 100644+--- a/gcc/config/i386/i386.c++++ b/gcc/config/i386/i386.c+@@ -28600,16 +28600,23 @@ static void+ ix86_output_indirect_branch (rtx call_op, const char *xasm,+ bool sibcall_p)+ {+- char thunk_name[32];++ char thunk_name_buf[32];++ char *thunk_name;+ char push_buf[64];+ bool need_bnd_p = ix86_bnd_prefixed_insn_p (current_output_insn);+ +- bool need_thunk = ix86_indirect_branch == indirect_branch_thunk;+- if (need_bnd_p)+- indirect_thunk_bnd_needed |= need_thunk;++ if (ix86_indirect_branch != indirect_branch_thunk_inline)++ {++ bool need_thunk = ix86_indirect_branch == indirect_branch_thunk;++ if (need_bnd_p)++ indirect_thunk_bnd_needed |= need_thunk;++ else++ indirect_thunk_needed |= need_thunk;++ indirect_thunk_name (thunk_name_buf, need_bnd_p);++ thunk_name = thunk_name_buf;++ }+ else+- indirect_thunk_needed |= need_thunk;+- indirect_thunk_name (thunk_name, need_bnd_p);++ thunk_name = NULL;+ + snprintf (push_buf, sizeof (push_buf), "push{%c}\t%s",+ TARGET_64BIT ? 'q' : 'l', xasm);+@@ -28683,10 +28690,15 @@ ix86_output_indirect_branch (rtx call_op, const char *xasm,+ + output_asm_insn (push_buf, &call_op);+ +- if (need_bnd_p)+- fprintf (asm_out_file, "\tbnd jmp\t%s\n", thunk_name);++ if (thunk_name != NULL)++ {++ if (need_bnd_p)++ fprintf (asm_out_file, "\tbnd jmp\t%s\n", thunk_name);++ else++ fprintf (asm_out_file, "\tjmp\t%s\n", thunk_name);++ }+ else+- fprintf (asm_out_file, "\tjmp\t%s\n", thunk_name);++ output_indirect_thunk (need_bnd_p);+ + ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, indirectlabel2);+ +diff --git a/gcc/config/i386/i386.opt b/gcc/config/i386/i386.opt+index 1773e5614cf..68484a75022 100644+--- a/gcc/config/i386/i386.opt++++ b/gcc/config/i386/i386.opt+@@ -941,3 +941,6 @@ Enum(indirect_branch) String(keep) Value(indirect_branch_keep)+ + EnumValue+ Enum(indirect_branch) String(thunk) Value(indirect_branch_thunk)++++EnumValue++Enum(indirect_branch) String(thunk-inline) Value(indirect_branch_thunk_inline)+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-1.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-1.c+new file mode 100644+index 00000000000..071e6c89ac7+--- /dev/null++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-1.c+@@ -0,0 +1,18 @@++/* { dg-do compile } */++/* { dg-options "-O2 -mindirect-branch=thunk-inline -fno-pic" } */++++typedef void (*dispatch_t)(long offset);++++dispatch_t dispatch;++++void++male_indirect_jump (long offset)++{++ dispatch(offset);++}++++/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { ! x32 } } } } */++/* { dg-final { scan-assembler "pushq\[ \t\]%rax" { target x32 } } } */++/* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */++/* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */++/* { dg-final { scan-assembler-not "__x86.indirect_thunk" } } */+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-2.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-2.c+new file mode 100644+index 00000000000..804c7ccdba7+--- /dev/null++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-2.c+@@ -0,0 +1,18 @@++/* { dg-do compile } */++/* { dg-options "-O2 -mindirect-branch=thunk-inline -fno-pic" } */++++typedef void (*dispatch_t)(long offset);++++dispatch_t dispatch[256];++++void++male_indirect_jump (long offset)++{++ dispatch[offset](offset);++}++++/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { ! x32 } } } } */++/* { dg-final { scan-assembler "pushq\[ \t\]%rax" { target x32 } } } */++/* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */++/* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */++/* { dg-final { scan-assembler-not "__x86.indirect_thunk" } } */+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-3.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-3.c+new file mode 100644+index 00000000000..545a981add5+--- /dev/null++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-3.c+@@ -0,0 +1,19 @@++/* { dg-do compile } */++/* { dg-options "-O2 -mindirect-branch=thunk-inline -fno-pic" } */++++typedef void (*dispatch_t)(long offset);++++dispatch_t dispatch;++++int++male_indirect_jump (long offset)++{++ dispatch(offset);++ return 0;++}++++/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { ! x32 } } } } */++/* { dg-final { scan-assembler "pushq\[ \t\]%rax" { target x32 } } } */++/* { dg-final { scan-assembler-times "jmp\[ \t\]*\.LIND" 2 } } */++/* { dg-final { scan-assembler-times "call\[ \t\]*\.LIND" 2 } } */++/* { dg-final { scan-assembler-not "__x86.indirect_thunk" } } */+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-4.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-4.c+new file mode 100644+index 00000000000..d9ff4722cff+--- /dev/null++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-4.c+@@ -0,0 +1,19 @@++/* { dg-do compile } */++/* { dg-options "-O2 -mindirect-branch=thunk-inline -fno-pic" } */++++typedef void (*dispatch_t)(long offset);++++dispatch_t dispatch[256];++++int++male_indirect_jump (long offset)++{++ dispatch[offset](offset);++ return 0;++}++++/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { ! x32 } } } } */++/* { dg-final { scan-assembler "pushq\[ \t\]%rax" { target x32 } } } */++/* { dg-final { scan-assembler-times "jmp\[ \t\]*\.LIND" 2 } } */++/* { dg-final { scan-assembler-times "call\[ \t\]*\.LIND" 2 } } */++/* { dg-final { scan-assembler-not "__x86.indirect_thunk" } } */+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-5.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-5.c+new file mode 100644+index 00000000000..f4890fe97b2+--- /dev/null++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-5.c+@@ -0,0 +1,15 @@++/* { dg-do compile { target *-*-linux* } } */++/* { dg-options "-O2 -fpic -fno-plt -mindirect-branch=thunk-inline" } */++++extern void bar (void);++++void++foo (void)++{++ bar ();++}++++/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*bar@GOT" } } */++/* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */++/* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */++/* { dg-final { scan-assembler-not "__x86.indirect_thunk" } } */+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-6.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-6.c+new file mode 100644+index 00000000000..81b09e73ab8+--- /dev/null++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-6.c+@@ -0,0 +1,16 @@++/* { dg-do compile { target *-*-linux* } } */++/* { dg-options "-O2 -fpic -fno-plt -mindirect-branch=thunk-inline" } */++++extern void bar (void);++++int++foo (void)++{++ bar ();++ return 0;++}++++/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*bar@GOT" } } */++/* { dg-final { scan-assembler-times "jmp\[ \t\]*\.LIND" 2 } } */++/* { dg-final { scan-assembler-times "call\[ \t\]*\.LIND" 2 } } */++/* { dg-final { scan-assembler-not "__x86.indirect_thunk" } } */+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-7.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-7.c+new file mode 100644+index 00000000000..a0ce06b8232+--- /dev/null++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-7.c+@@ -0,0 +1,42 @@++/* { dg-do compile } */++/* { dg-options "-O2 -mindirect-branch=thunk-inline -fno-pic" } */++++void func0 (void);++void func1 (void);++void func2 (void);++void func3 (void);++void func4 (void);++void func4 (void);++void func5 (void);++++void++bar (int i)++{++ switch (i)++ {++ default:++ func0 ();++ break;++ case 1:++ func1 ();++ break;++ case 2:++ func2 ();++ break;++ case 3:++ func3 ();++ break;++ case 4:++ func4 ();++ break;++ case 5:++ func5 ();++ break;++ }++}++++/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*\.L\[0-9\]+\\(,%" { target { ! x32 } } } } */++/* { dg-final { scan-assembler "pushq\[ \t\]%rax" { target x32 } } } */++/* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */++/* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */++/* { dg-final { scan-assembler-not "__x86.indirect_thunk" } } */+-- +2.15.1+diff --git a/gnu/packages/patches/gcc-retpoline-Add-mindirect-branch-thunk.patch b/gnu/packages/patches/gcc-retpoline-Add-mindirect-branch-thunk.patchnew file mode 100644index 000000000..edb9a8de5--- /dev/null+++ b/gnu/packages/patches/gcc-retpoline-Add-mindirect-branch-thunk.patch@@ -0,0 +1,729 @@+'Retpoline' mitigation technique for Spectre (branch target injection)+[CVE-2017-5715]:++https://security.googleblog.com/2018/01/more-details-about-mitigations-for-cpu_4.html+https://support.google.com/faqs/answer/7625886+https://spectreattack.com/+https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2017-5715++Patch copied from the 'retpoline-20180107' branch of upstream source repository+(please add new / update existing patches when new 'retpoline-xxxxxxxx' branch+appears):++http://git.infradead.org/users/dwmw2/gcc-retpoline.git++From 63024dad9c00f1613738fd766e2f0afd455b76d1 Mon Sep 17 00:00:00 2001+From: "H.J. Lu" <hjl.tools@gmail.com>+Date: Wed, 1 Nov 2017 16:05:50 -0700+Subject: [PATCH 04/17] Add -mindirect-branch=thunk++Add tests for -mindirect-branch=thunk+---+ gcc/config/i386/i386-opts.h | 5 ++ gcc/config/i386/i386-protos.h | 1 ++ gcc/config/i386/i386.c | 318 ++++++++++++++++++++++-+ gcc/config/i386/i386.md | 6 +-+ gcc/config/i386/i386.opt | 14 ++ gcc/doc/invoke.texi | 9 +-+ gcc/testsuite/gcc.target/i386/indirect-thunk-1.c | 19 +++ gcc/testsuite/gcc.target/i386/indirect-thunk-2.c | 19 +++ gcc/testsuite/gcc.target/i386/indirect-thunk-3.c | 20 +++ gcc/testsuite/gcc.target/i386/indirect-thunk-4.c | 20 +++ gcc/testsuite/gcc.target/i386/indirect-thunk-5.c | 16 +++ gcc/testsuite/gcc.target/i386/indirect-thunk-6.c | 17 +++ gcc/testsuite/gcc.target/i386/indirect-thunk-7.c | 43 ++++ 13 files changed, 495 insertions(+), 12 deletions(-)+ create mode 100644 gcc/testsuite/gcc.target/i386/indirect-thunk-1.c+ create mode 100644 gcc/testsuite/gcc.target/i386/indirect-thunk-2.c+ create mode 100644 gcc/testsuite/gcc.target/i386/indirect-thunk-3.c+ create mode 100644 gcc/testsuite/gcc.target/i386/indirect-thunk-4.c+ create mode 100644 gcc/testsuite/gcc.target/i386/indirect-thunk-5.c+ create mode 100644 gcc/testsuite/gcc.target/i386/indirect-thunk-6.c+ create mode 100644 gcc/testsuite/gcc.target/i386/indirect-thunk-7.c++diff --git a/gcc/config/i386/i386-opts.h b/gcc/config/i386/i386-opts.h+index 542cd0f3d67..1565d8fdc65 100644+--- a/gcc/config/i386/i386-opts.h++++ b/gcc/config/i386/i386-opts.h+@@ -99,4 +99,9 @@ enum stack_protector_guard {+ SSP_GLOBAL /* global canary */+ };+ ++enum indirect_branch {++ indirect_branch_keep,++ indirect_branch_thunk++};+++ #endif+diff --git a/gcc/config/i386/i386-protos.h b/gcc/config/i386/i386-protos.h+index 8bdd67eb608..b746429f420 100644+--- a/gcc/config/i386/i386-protos.h++++ b/gcc/config/i386/i386-protos.h+@@ -315,6 +315,7 @@ extern enum attr_cpu ix86_schedule;+ #endif+ + extern const char * ix86_output_call_insn (rtx_insn *insn, rtx call_op);++extern const char * ix86_output_indirect_jmp (rtx call_op);+ extern bool ix86_operands_ok_for_move_multiple (rtx *operands, bool load,+ enum machine_mode mode);+ +diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c+index 504530a00cf..96424361a1c 100644+--- a/gcc/config/i386/i386.c++++ b/gcc/config/i386/i386.c+@@ -11909,6 +11909,145 @@ ix86_setup_frame_addresses (void)+ # endif+ #endif+ ++static int indirectlabelno;++static bool indirect_thunk_needed = false;++static bool indirect_thunk_bnd_needed = false;++++#ifndef INDIRECT_LABEL++# define INDIRECT_LABEL "LIND"++#endif++++/* Fills in the label name that should be used for the indirect thunk. */++++static void++indirect_thunk_name (char name[32], bool need_bnd_p)++{++ if (USE_HIDDEN_LINKONCE)++ {++ const char *bnd = need_bnd_p ? "_bnd" : "";++ sprintf (name, "__x86.indirect_thunk%s", bnd);++ }++ else++ {++ if (need_bnd_p)++ ASM_GENERATE_INTERNAL_LABEL (name, "LITB", 0);++ else++ ASM_GENERATE_INTERNAL_LABEL (name, "LIT", 0);++ }++}++++static void++output_indirect_thunk (bool need_bnd_p)++{++ char indirectlabel1[32];++ char indirectlabel2[32];++++ ASM_GENERATE_INTERNAL_LABEL (indirectlabel1, INDIRECT_LABEL,++ indirectlabelno++);++ ASM_GENERATE_INTERNAL_LABEL (indirectlabel2, INDIRECT_LABEL,++ indirectlabelno++);++++ /* Call */++ if (need_bnd_p)++ fputs ("\tbnd call\t", asm_out_file);++ else++ fputs ("\tcall\t", asm_out_file);++ assemble_name_raw (asm_out_file, indirectlabel2);++ fputc ('\n', asm_out_file);++++ ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, indirectlabel1);++++ /* lfence . */++ fprintf (asm_out_file, "\tlfence\n");++++ /* Jump. */++ fputs ("\tjmp\t", asm_out_file);++ assemble_name_raw (asm_out_file, indirectlabel1);++ fputc ('\n', asm_out_file);++++ ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, indirectlabel2);++++ /* LEA. */++ rtx xops[2];++ xops[0] = stack_pointer_rtx;++ xops[1] = plus_constant (Pmode, stack_pointer_rtx, UNITS_PER_WORD);++ output_asm_insn ("lea\t{%E1, %0|%0, %E1}", xops);++++ if (need_bnd_p)++ fputs ("\tbnd ret\n", asm_out_file);++ else++ fputs ("\tret\n", asm_out_file);++}++++static void++output_indirect_thunk_function (bool need_bnd_p)++{++ char name[32];++ tree decl;++++ indirect_thunk_name (name, need_bnd_p);++ decl = build_decl (BUILTINS_LOCATION, FUNCTION_DECL,++ get_identifier (name),++ build_function_type_list (void_type_node, NULL_TREE));++ DECL_RESULT (decl) = build_decl (BUILTINS_LOCATION, RESULT_DECL,++ NULL_TREE, void_type_node);++ TREE_PUBLIC (decl) = 1;++ TREE_STATIC (decl) = 1;++ DECL_IGNORED_P (decl) = 1;++++#if TARGET_MACHO++ if (TARGET_MACHO)++ {++ switch_to_section (darwin_sections[picbase_thunk_section]);++ fputs ("\t.weak_definition\t", asm_out_file);++ assemble_name (asm_out_file, name);++ fputs ("\n\t.private_extern\t", asm_out_file);++ assemble_name (asm_out_file, name);++ putc ('\n', asm_out_file);++ ASM_OUTPUT_LABEL (asm_out_file, name);++ DECL_WEAK (decl) = 1;++ }++ else++#endif++ if (USE_HIDDEN_LINKONCE)++ {++ cgraph_node::create (decl)->set_comdat_group (DECL_ASSEMBLER_NAME (decl));++++ targetm.asm_out.unique_section (decl, 0);++ switch_to_section (get_named_section (decl, NULL, 0));++++ targetm.asm_out.globalize_label (asm_out_file, name);++ fputs ("\t.hidden\t", asm_out_file);++ assemble_name (asm_out_file, name);++ putc ('\n', asm_out_file);++ ASM_DECLARE_FUNCTION_NAME (asm_out_file, name, decl);++ }++ else++ {++ switch_to_section (text_section);++ ASM_OUTPUT_LABEL (asm_out_file, name);++ }++++ DECL_INITIAL (decl) = make_node (BLOCK);++ current_function_decl = decl;++ allocate_struct_function (decl, false);++ init_function_start (decl);++ /* We're about to hide the function body from callees of final_* by++ emitting it directly; tell them we're a thunk, if they care. */++ cfun->is_thunk = true;++ first_function_block_is_cold = false;++ /* Make sure unwind info is emitted for the thunk if needed. */++ final_start_function (emit_barrier (), asm_out_file, 1);++++ output_indirect_thunk (need_bnd_p);++++ final_end_function ();++ init_insn_lengths ();++ free_after_compilation (cfun);++ set_cfun (NULL);++ current_function_decl = NULL;++}+++ static int pic_labels_used;+ + /* Fills in the label name that should be used for a pc thunk for+@@ -11935,6 +12074,11 @@ ix86_code_end (void)+ rtx xops[2];+ int regno;+ ++ if (indirect_thunk_needed)++ output_indirect_thunk_function (false);++ if (indirect_thunk_bnd_needed)++ output_indirect_thunk_function (true);+++ for (regno = AX_REG; regno <= SP_REG; regno++)+ {+ char name[32];+@@ -28452,12 +28596,132 @@ ix86_nopic_noplt_attribute_p (rtx call_op)+ return false;+ }+ ++static void++ix86_output_indirect_branch (rtx call_op, const char *xasm,++ bool sibcall_p)++{++ char thunk_name[32];++ char push_buf[64];++ bool need_bnd_p = ix86_bnd_prefixed_insn_p (current_output_insn);++++ bool need_thunk = ix86_indirect_branch == indirect_branch_thunk;++ if (need_bnd_p)++ indirect_thunk_bnd_needed |= need_thunk;++ else++ indirect_thunk_needed |= need_thunk;++ indirect_thunk_name (thunk_name, need_bnd_p);++++ snprintf (push_buf, sizeof (push_buf), "push{%c}\t%s",++ TARGET_64BIT ? 'q' : 'l', xasm);++++ if (sibcall_p)++ {++ output_asm_insn (push_buf, &call_op);++ if (thunk_name != NULL)++ {++ if (need_bnd_p)++ fprintf (asm_out_file, "\tbnd jmp\t%s\n", thunk_name);++ else++ fprintf (asm_out_file, "\tjmp\t%s\n", thunk_name);++ }++ else++ output_indirect_thunk (need_bnd_p);++ }++ else++ {++ char indirectlabel1[32];++ char indirectlabel2[32];++++ ASM_GENERATE_INTERNAL_LABEL (indirectlabel1,++ INDIRECT_LABEL,++ indirectlabelno++);++ ASM_GENERATE_INTERNAL_LABEL (indirectlabel2,++ INDIRECT_LABEL,++ indirectlabelno++);++++ /* Jump. */++ if (need_bnd_p)++ fputs ("\tbnd jmp\t", asm_out_file);++ else++ fputs ("\tjmp\t", asm_out_file);++ assemble_name_raw (asm_out_file, indirectlabel2);++ fputc ('\n', asm_out_file);++++ ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, indirectlabel1);++++ if (MEM_P (call_op))++ {++ struct ix86_address parts;++ rtx addr = XEXP (call_op, 0);++ if (ix86_decompose_address (addr, &parts)++ && parts.base == stack_pointer_rtx)++ {++ /* Since call will adjust stack by -UNITS_PER_WORD,++ we must convert "disp(stack, index, scale)" to++ "disp+UNITS_PER_WORD(stack, index, scale)". */++ if (parts.index)++ {++ addr = gen_rtx_MULT (Pmode, parts.index,++ GEN_INT (parts.scale));++ addr = gen_rtx_PLUS (Pmode, stack_pointer_rtx,++ addr);++ }++ else++ addr = stack_pointer_rtx;++++ rtx disp;++ if (parts.disp != NULL_RTX)++ disp = plus_constant (Pmode, parts.disp,++ UNITS_PER_WORD);++ else++ disp = GEN_INT (UNITS_PER_WORD);++++ addr = gen_rtx_PLUS (Pmode, addr, disp);++ call_op = gen_rtx_MEM (GET_MODE (call_op), addr);++ }++ }++++ output_asm_insn (push_buf, &call_op);++++ if (need_bnd_p)++ fprintf (asm_out_file, "\tbnd jmp\t%s\n", thunk_name);++ else++ fprintf (asm_out_file, "\tjmp\t%s\n", thunk_name);++++ ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, indirectlabel2);++++ /* Call. */++ if (need_bnd_p)++ fputs ("\tbnd call\t", asm_out_file);++ else++ fputs ("\tcall\t", asm_out_file);++ assemble_name_raw (asm_out_file, indirectlabel1);++ fputc ('\n', asm_out_file);++ }++}++++const char *++ix86_output_indirect_jmp (rtx call_op)++{++ if (ix86_red_zone_size == 0++ && ix86_indirect_branch != indirect_branch_keep)++ {++ ix86_output_indirect_branch (call_op, "%0", true);++ return "";++ }++ else++ return "%!jmp\t%A0";++}+++ /* Output the assembly for a call instruction. */+ + const char *+ ix86_output_call_insn (rtx_insn *insn, rtx call_op)+ {+ bool direct_p = constant_call_address_operand (call_op, VOIDmode);++ bool output_indirect_p++ = (!TARGET_SEH++ && ix86_indirect_branch != indirect_branch_keep);+ bool seh_nop_p = false;+ const char *xasm;+ +@@ -28467,10 +28731,21 @@ ix86_output_call_insn (rtx_insn *insn, rtx call_op)+ {+ if (ix86_nopic_noplt_attribute_p (call_op))+ {++ direct_p = false;+ if (TARGET_64BIT)+- xasm = "%!jmp\t{*%p0@GOTPCREL(%%rip)|[QWORD PTR %p0@GOTPCREL[rip]]}";++ {++ if (output_indirect_p)++ xasm = "{%p0@GOTPCREL(%%rip)|[QWORD PTR %p0@GOTPCREL[rip]]}";++ else++ xasm = "%!jmp\t{*%p0@GOTPCREL(%%rip)|[QWORD PTR %p0@GOTPCREL[rip]]}";++ }+ else+- xasm = "%!jmp\t{*%p0@GOT|[DWORD PTR %p0@GOT]}";++ {++ if (output_indirect_p)++ xasm = "{%p0@GOT|[DWORD PTR %p0@GOT]}";++ else++ xasm = "%!jmp\t{*%p0@GOT|[DWORD PTR %p0@GOT]}";++ }+ }+ else+ xasm = "%!jmp\t%P0";+@@ -28480,9 +28755,17 @@ ix86_output_call_insn (rtx_insn *insn, rtx call_op)+ else if (TARGET_SEH)+ xasm = "%!rex.W jmp\t%A0";+ else+- xasm = "%!jmp\t%A0";++ {++ if (output_indirect_p)++ xasm = "%0";++ else++ xasm = "%!jmp\t%A0";++ }+ +- output_asm_insn (xasm, &call_op);++ if (output_indirect_p && !direct_p)++ ix86_output_indirect_branch (call_op, xasm, true);++ else++ output_asm_insn (xasm, &call_op);+ return "";+ }+ +@@ -28520,18 +28803,37 @@ ix86_output_call_insn (rtx_insn *insn, rtx call_op)+ {+ if (ix86_nopic_noplt_attribute_p (call_op))+ {++ direct_p = false;+ if (TARGET_64BIT)+- xasm = "%!call\t{*%p0@GOTPCREL(%%rip)|[QWORD PTR %p0@GOTPCREL[rip]]}";++ {++ if (output_indirect_p)++ xasm = "{%p0@GOTPCREL(%%rip)|[QWORD PTR %p0@GOTPCREL[rip]]}";++ else++ xasm = "%!call\t{*%p0@GOTPCREL(%%rip)|[QWORD PTR %p0@GOTPCREL[rip]]}";++ }+ else+- xasm = "%!call\t{*%p0@GOT|[DWORD PTR %p0@GOT]}";++ {++ if (output_indirect_p)++ xasm = "{%p0@GOT|[DWORD PTR %p0@GOT]}";++ else++ xasm = "%!call\t{*%p0@GOT|[DWORD PTR %p0@GOT]}";++ }+ }+ else+ xasm = "%!call\t%P0";+ }+ else+- xasm = "%!call\t%A0";++ {++ if (output_indirect_p)++ xasm = "%0";++ else++ xasm = "%!call\t%A0";++ }+ +- output_asm_insn (xasm, &call_op);++ if (output_indirect_p && !direct_p)++ ix86_output_indirect_branch (call_op, xasm, false);++ else++ output_asm_insn (xasm, &call_op);+ + if (seh_nop_p)+ return "nop";+diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md+index 81cfba57afc..01b7b2039e6 100644+--- a/gcc/config/i386/i386.md++++ b/gcc/config/i386/i386.md+@@ -11615,7 +11615,7 @@+ (define_insn "*indirect_jump"+ [(set (pc) (match_operand:W 0 "indirect_branch_operand" "rBw"))]+ ""+- "%!jmp\t%A0"++ "* return ix86_output_indirect_jmp (operands[0]);"+ [(set_attr "type" "ibr")+ (set_attr "length_immediate" "0")+ (set_attr "maybe_prefix_bnd" "1")])+@@ -11665,7 +11665,7 @@+ [(set (pc) (match_operand:W 0 "indirect_branch_operand" "rBw"))+ (use (label_ref (match_operand 1)))]+ ""+- "%!jmp\t%A0"++ "* return ix86_output_indirect_jmp (operands[0]);"+ [(set_attr "type" "ibr")+ (set_attr "length_immediate" "0")+ (set_attr "maybe_prefix_bnd" "1")])+@@ -12337,7 +12337,7 @@+ [(simple_return)+ (use (match_operand:SI 0 "register_operand" "r"))]+ "reload_completed"+- "%!jmp\t%A0"++ "* return ix86_output_indirect_jmp (operands[0]);"+ [(set_attr "type" "ibr")+ (set_attr "length_immediate" "0")+ (set_attr "maybe_prefix_bnd" "1")])+diff --git a/gcc/config/i386/i386.opt b/gcc/config/i386/i386.opt+index 9384e29b1de..1773e5614cf 100644+--- a/gcc/config/i386/i386.opt++++ b/gcc/config/i386/i386.opt+@@ -927,3 +927,17 @@ Attempt to avoid generating instruction sequences containing ret bytes.+ mgeneral-regs-only+ Target Report RejectNegative Mask(GENERAL_REGS_ONLY) Var(ix86_target_flags) Save+ Generate code which uses only the general registers.++++mindirect-branch=++Target Report RejectNegative Joined Enum(indirect_branch) Var(ix86_indirect_branch) Init(indirect_branch_keep)++Update indirect call and jump.++++Enum++Name(indirect_branch) Type(enum indirect_branch)++Known indirect branch choices (for use with the -mindirect-branch= option):++++EnumValue++Enum(indirect_branch) String(keep) Value(indirect_branch_keep)++++EnumValue++Enum(indirect_branch) String(thunk) Value(indirect_branch_thunk)+diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi+index a0fb09eb9e1..fafda2926bd 100644+--- a/gcc/doc/invoke.texi++++ b/gcc/doc/invoke.texi+@@ -1210,7 +1210,7 @@ See RS/6000 and PowerPC Options.+ -msse2avx -mfentry -mrecord-mcount -mnop-mcount -m8bit-idiv @gol+ -mavx256-split-unaligned-load -mavx256-split-unaligned-store @gol+ -malign-data=@var{type} -mstack-protector-guard=@var{guard} @gol+--mmitigate-rop -mgeneral-regs-only}++-mmitigate-rop -mgeneral-regs-only -mindirect-branch=@var{choice}}+ + @emph{x86 Windows Options}+ @gccoptlist{-mconsole -mcygwin -mno-cygwin -mdll @gol+@@ -25648,6 +25648,13 @@ Generate code that uses only the general-purpose registers. This+ prevents the compiler from using floating-point, vector, mask and bound+ registers.+ ++@item -mindirect-branch=@var{choice}++@opindex -mindirect-branch++Update indirect call and jump with @var{choice}. The default is++@samp{keep}, which keeps indirect call and jump unmodified.++@samp{thunk} converts indirect call and jump to push and++PC-relative call thunk.+++ @end table+ + These @samp{-m} switches are supported in addition to the above+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-1.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-1.c+new file mode 100644+index 00000000000..d8b6f5a06a5+--- /dev/null++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-1.c+@@ -0,0 +1,19 @@++/* { dg-do compile } */++/* { dg-options "-O2 -mindirect-branch=thunk -fno-pic" } */++++typedef void (*dispatch_t)(long offset);++++dispatch_t dispatch;++++void++male_indirect_jump (long offset)++{++ dispatch(offset);++}++++/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { ! x32 } } } } */++/* { dg-final { scan-assembler "pushq\[ \t\]%rax" { target x32 } } } */++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" } } */++/* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */++/* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */++/* { dg-final { scan-assembler {\tlfence} } } */+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-2.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-2.c+new file mode 100644+index 00000000000..f7d5cb315a8+--- /dev/null++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-2.c+@@ -0,0 +1,19 @@++/* { dg-do compile } */++/* { dg-options "-O2 -mindirect-branch=thunk -fno-pic" } */++++typedef void (*dispatch_t)(long offset);++++dispatch_t dispatch[256];++++void++male_indirect_jump (long offset)++{++ dispatch[offset](offset);++}++++/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { ! x32 } } } } */++/* { dg-final { scan-assembler "pushq\[ \t\]%rax" { target x32 } } } */++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" } } */++/* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */++/* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */++/* { dg-final { scan-assembler {\tlfence} } } */+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-3.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-3.c+new file mode 100644+index 00000000000..736d7cda058+--- /dev/null++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-3.c+@@ -0,0 +1,20 @@++/* { dg-do compile } */++/* { dg-options "-O2 -mindirect-branch=thunk -fno-pic" } */++++typedef void (*dispatch_t)(long offset);++++dispatch_t dispatch;++++int++male_indirect_jump (long offset)++{++ dispatch(offset);++ return 0;++}++++/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { ! x32 } } } } */++/* { dg-final { scan-assembler "pushq\[ \t\]%rax" { target x32 } } } */++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" } } */++/* { dg-final { scan-assembler-times "jmp\[ \t\]*\.LIND" 2 } } */++/* { dg-final { scan-assembler-times "call\[ \t\]*\.LIND" 2 } } */++/* { dg-final { scan-assembler {\tlfence} } } */+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-4.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-4.c+new file mode 100644+index 00000000000..cef9b10513e+--- /dev/null++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-4.c+@@ -0,0 +1,20 @@++/* { dg-do compile } */++/* { dg-options "-O2 -mindirect-branch=thunk -fno-pic" } */++++typedef void (*dispatch_t)(long offset);++++dispatch_t dispatch[256];++++int++male_indirect_jump (long offset)++{++ dispatch[offset](offset);++ return 0;++}++++/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { ! x32 } } } } */++/* { dg-final { scan-assembler "pushq\[ \t\]%rax" { target x32 } } } */++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" } } */++/* { dg-final { scan-assembler-times "jmp\[ \t\]*\.LIND" 2 } } */++/* { dg-final { scan-assembler-times "call\[ \t\]*\.LIND" 2 } } */++/* { dg-final { scan-assembler {\tlfence} } } */+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-5.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-5.c+new file mode 100644+index 00000000000..1a9bb0e431e+--- /dev/null++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-5.c+@@ -0,0 +1,16 @@++/* { dg-do compile { target *-*-linux* } } */++/* { dg-options "-O2 -fpic -fno-plt -mindirect-branch=thunk" } */++++extern void bar (void);++++void++foo (void)++{++ bar ();++}++++/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*bar@GOT" } } */++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" } } */++/* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */++/* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */++/* { dg-final { scan-assembler {\tlfence} } } */+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-6.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-6.c+new file mode 100644+index 00000000000..bc7d20ec6ad+--- /dev/null++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-6.c+@@ -0,0 +1,17 @@++/* { dg-do compile { target *-*-linux* } } */++/* { dg-options "-O2 -fpic -fno-plt -mindirect-branch=thunk" } */++++extern void bar (void);++++int++foo (void)++{++ bar ();++ return 0;++}++++/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*bar@GOT" } } */++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" } } */++/* { dg-final { scan-assembler-times "jmp\[ \t\]*\.LIND" 2 } } */++/* { dg-final { scan-assembler-times "call\[ \t\]*\.LIND" 2 } } */++/* { dg-final { scan-assembler {\tlfence} } } */+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-7.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-7.c+new file mode 100644+index 00000000000..ea0fa312f64+--- /dev/null++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-7.c+@@ -0,0 +1,43 @@++/* { dg-do compile } */++/* { dg-options "-O2 -mindirect-branch=thunk -fno-pic" } */++++void func0 (void);++void func1 (void);++void func2 (void);++void func3 (void);++void func4 (void);++void func4 (void);++void func5 (void);++++void++bar (int i)++{++ switch (i)++ {++ default:++ func0 ();++ break;++ case 1:++ func1 ();++ break;++ case 2:++ func2 ();++ break;++ case 3:++ func3 ();++ break;++ case 4:++ func4 ();++ break;++ case 5:++ func5 ();++ break;++ }++}++++/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*\.L\[0-9\]+\\(,%" { target { ! x32 } } } } */++/* { dg-final { scan-assembler "pushq\[ \t\]%rax" { target x32 } } } */++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" } } */++/* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */++/* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */++/* { dg-final { scan-assembler {\tlfence} } } */+-- +2.15.1+diff --git a/gnu/packages/patches/gcc-retpoline-Add-mno-indirect-branch-register-to-indirect-branch-.patch b/gnu/packages/patches/gcc-retpoline-Add-mno-indirect-branch-register-to-indirect-branch-.patchnew file mode 100644index 000000000..2b4ac1b81--- /dev/null+++ b/gnu/packages/patches/gcc-retpoline-Add-mno-indirect-branch-register-to-indirect-branch-.patch@@ -0,0 +1,554 @@+'Retpoline' mitigation technique for Spectre (branch target injection)+[CVE-2017-5715]:++https://security.googleblog.com/2018/01/more-details-about-mitigations-for-cpu_4.html+https://support.google.com/faqs/answer/7625886+https://spectreattack.com/+https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2017-5715++Patch copied from the 'retpoline-20180107' branch of upstream source repository+(please add new / update existing patches when new 'retpoline-xxxxxxxx' branch+appears):++http://git.infradead.org/users/dwmw2/gcc-retpoline.git++From 2c14ecf03978ce6c60e021a2b0d72778a5fe0982 Mon Sep 17 00:00:00 2001+From: "H.J. Lu" <hjl.tools@gmail.com>+Date: Tue, 12 Dec 2017 12:34:26 -0800+Subject: [PATCH 14/17] Add -mno-indirect-branch-register to indirect branch+ tests++---+ gcc/testsuite/gcc.target/i386/indirect-thunk-1.c | 2 +-+ gcc/testsuite/gcc.target/i386/indirect-thunk-2.c | 2 +-+ gcc/testsuite/gcc.target/i386/indirect-thunk-3.c | 2 +-+ gcc/testsuite/gcc.target/i386/indirect-thunk-4.c | 2 +-+ gcc/testsuite/gcc.target/i386/indirect-thunk-5.c | 2 +-+ gcc/testsuite/gcc.target/i386/indirect-thunk-6.c | 2 +-+ gcc/testsuite/gcc.target/i386/indirect-thunk-7.c | 2 +-+ gcc/testsuite/gcc.target/i386/indirect-thunk-attr-1.c | 2 +-+ gcc/testsuite/gcc.target/i386/indirect-thunk-attr-2.c | 2 +-+ gcc/testsuite/gcc.target/i386/indirect-thunk-attr-3.c | 2 +-+ gcc/testsuite/gcc.target/i386/indirect-thunk-attr-4.c | 2 +-+ gcc/testsuite/gcc.target/i386/indirect-thunk-attr-5.c | 2 +-+ gcc/testsuite/gcc.target/i386/indirect-thunk-attr-6.c | 2 +-+ gcc/testsuite/gcc.target/i386/indirect-thunk-attr-7.c | 2 +-+ gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-1.c | 2 +-+ gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-2.c | 2 +-+ gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-3.c | 2 +-+ gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-4.c | 2 +-+ gcc/testsuite/gcc.target/i386/indirect-thunk-extern-1.c | 2 +-+ gcc/testsuite/gcc.target/i386/indirect-thunk-extern-2.c | 2 +-+ gcc/testsuite/gcc.target/i386/indirect-thunk-extern-3.c | 2 +-+ gcc/testsuite/gcc.target/i386/indirect-thunk-extern-4.c | 2 +-+ gcc/testsuite/gcc.target/i386/indirect-thunk-extern-5.c | 2 +-+ gcc/testsuite/gcc.target/i386/indirect-thunk-extern-6.c | 2 +-+ gcc/testsuite/gcc.target/i386/indirect-thunk-extern-7.c | 2 +-+ gcc/testsuite/gcc.target/i386/indirect-thunk-inline-1.c | 2 +-+ gcc/testsuite/gcc.target/i386/indirect-thunk-inline-2.c | 2 +-+ gcc/testsuite/gcc.target/i386/indirect-thunk-inline-3.c | 2 +-+ gcc/testsuite/gcc.target/i386/indirect-thunk-inline-4.c | 2 +-+ gcc/testsuite/gcc.target/i386/indirect-thunk-inline-5.c | 2 +-+ gcc/testsuite/gcc.target/i386/indirect-thunk-inline-6.c | 2 +-+ gcc/testsuite/gcc.target/i386/indirect-thunk-inline-7.c | 2 +-+ gcc/testsuite/gcc.target/i386/indirect-thunk-loop-1.c | 2 +-+ gcc/testsuite/gcc.target/i386/indirect-thunk-loop-2.c | 2 +-+ gcc/testsuite/gcc.target/i386/indirect-thunk-loop-3.c | 2 +-+ gcc/testsuite/gcc.target/i386/indirect-thunk-loop-4.c | 2 +-+ gcc/testsuite/gcc.target/i386/indirect-thunk-loop-5.c | 2 +-+ gcc/testsuite/gcc.target/i386/ret-thunk-10.c | 2 +-+ gcc/testsuite/gcc.target/i386/ret-thunk-11.c | 2 +-+ gcc/testsuite/gcc.target/i386/ret-thunk-12.c | 2 +-+ gcc/testsuite/gcc.target/i386/ret-thunk-13.c | 2 +-+ gcc/testsuite/gcc.target/i386/ret-thunk-14.c | 2 +-+ gcc/testsuite/gcc.target/i386/ret-thunk-15.c | 2 +-+ gcc/testsuite/gcc.target/i386/ret-thunk-9.c | 2 +-+ 44 files changed, 44 insertions(+), 44 deletions(-)++diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-1.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-1.c+index 318db1e7f5c..b0625207b92 100644+--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-1.c++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-1.c+@@ -1,5 +1,5 @@+ /* { dg-do compile } */+-/* { dg-options "-O2 -mfunction-return=keep -mindirect-branch=thunk -fno-pic" } */++/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=keep -mindirect-branch=thunk -fno-pic" } */+ + typedef void (*dispatch_t)(long offset);+ +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-2.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-2.c+index f2700dd36cf..0b289685e6b 100644+--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-2.c++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-2.c+@@ -1,5 +1,5 @@+ /* { dg-do compile } */+-/* { dg-options "-O2 -mfunction-return=keep -mindirect-branch=thunk -fno-pic" } */++/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=keep -mindirect-branch=thunk -fno-pic" } */+ + typedef void (*dispatch_t)(long offset);+ +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-3.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-3.c+index 46685d9a674..79a9f76285f 100644+--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-3.c++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-3.c+@@ -1,5 +1,5 @@+ /* { dg-do compile } */+-/* { dg-options "-O2 -mfunction-return=keep -mindirect-branch=thunk -fno-pic" } */++/* { dg-options "-O2 -mno-indirect-branch-register -mno-indirect-branch-register -mno-indirect-branch-register -mfunction-return=keep -mindirect-branch=thunk -fno-pic" } */+ + typedef void (*dispatch_t)(long offset);+ +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-4.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-4.c+index 8f701775cea..901d94213bd 100644+--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-4.c++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-4.c+@@ -1,5 +1,5 @@+ /* { dg-do compile } */+-/* { dg-options "-O2 -mfunction-return=keep -mindirect-branch=thunk -fno-pic" } */++/* { dg-options "-O2 -mno-indirect-branch-register -mno-indirect-branch-register -mno-indirect-branch-register -mfunction-return=keep -mindirect-branch=thunk -fno-pic" } */+ + typedef void (*dispatch_t)(long offset);+ +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-5.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-5.c+index f88ac31d07a..d2c9bd9d7ca 100644+--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-5.c++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-5.c+@@ -1,5 +1,5 @@+ /* { dg-do compile { target *-*-linux* } } */+-/* { dg-options "-O2 -mfunction-return=keep -fpic -fno-plt -mindirect-branch=thunk" } */++/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=keep -fpic -fno-plt -mindirect-branch=thunk" } */+ + extern void bar (void);+ +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-6.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-6.c+index d745116d321..f8b028db7a2 100644+--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-6.c++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-6.c+@@ -1,5 +1,5 @@+ /* { dg-do compile { target *-*-linux* } } */+-/* { dg-options "-O2 -mfunction-return=keep -fpic -fno-plt -mindirect-branch=thunk" } */++/* { dg-options "-O2 -mno-indirect-branch-register -mno-indirect-branch-register -mno-indirect-branch-register -mfunction-return=keep -fpic -fno-plt -mindirect-branch=thunk" } */+ + extern void bar (void);+ +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-7.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-7.c+index 969cb8c6ddc..465775407ec 100644+--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-7.c++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-7.c+@@ -1,5 +1,5 @@+ /* { dg-do compile } */+-/* { dg-options "-O2 -mfunction-return=keep -mindirect-branch=thunk -fno-pic" } */++/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=keep -mindirect-branch=thunk -fno-pic" } */+ + void func0 (void);+ void func1 (void);+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-1.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-1.c+index 12a61c3bbc7..5309d5a3eaa 100644+--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-1.c++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-1.c+@@ -1,5 +1,5 @@+ /* { dg-do compile } */+-/* { dg-options "-O2 -mfunction-return=keep -fno-pic" } */++/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=keep -fno-pic" } */+ + typedef void (*dispatch_t)(long offset);+ +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-2.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-2.c+index a06907933a2..dd1efca49fd 100644+--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-2.c++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-2.c+@@ -1,5 +1,5 @@+ /* { dg-do compile } */+-/* { dg-options "-O2 -mfunction-return=keep -fno-pic" } */++/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=keep -fno-pic" } */+ + typedef void (*dispatch_t)(long offset);+ +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-3.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-3.c+index 7f56725e6b6..e97ca636020 100644+--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-3.c++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-3.c+@@ -1,5 +1,5 @@+ /* { dg-do compile } */+-/* { dg-options "-O2 -mfunction-return=keep -fno-pic" } */++/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=keep -fno-pic" } */+ + typedef void (*dispatch_t)(long offset);+ +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-4.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-4.c+index fd4ab1dbaa0..b547cbbf255 100644+--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-4.c++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-4.c+@@ -1,5 +1,5 @@+ /* { dg-do compile } */+-/* { dg-options "-O2 -mfunction-return=keep -fno-pic" } */++/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=keep -fno-pic" } */+ + typedef void (*dispatch_t)(long offset);+ +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-5.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-5.c+index 1ffbf3b1181..353689dc415 100644+--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-5.c++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-5.c+@@ -1,5 +1,5 @@+ /* { dg-do compile } */+-/* { dg-options "-O2 -mfunction-return=keep -fno-pic" } */++/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=keep -fno-pic" } */+ + typedef void (*dispatch_t)(long offset);+ +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-6.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-6.c+index 1559072919a..1edef7208f4 100644+--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-6.c++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-6.c+@@ -1,5 +1,5 @@+ /* { dg-do compile } */+-/* { dg-options "-O2 -mfunction-return=keep -fno-pic" } */++/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=keep -fno-pic" } */+ + typedef void (*dispatch_t)(long offset);+ +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-7.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-7.c+index 1717e7bb436..c2e816cdfc6 100644+--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-7.c++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-7.c+@@ -1,5 +1,5 @@+ /* { dg-do compile } */+-/* { dg-options "-O2 -mfunction-return=keep -fno-pic" } */++/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=keep -fno-pic" } */+ + void func0 (void);+ void func1 (void);+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-1.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-1.c+index 20903b0f79d..5c10de47b7c 100644+--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-1.c++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-1.c+@@ -1,5 +1,5 @@+ /* { dg-do compile { target { ! x32 } } } */+-/* { dg-options "-O2 -mfunction-return=keep -mindirect-branch=thunk -fcheck-pointer-bounds -mmpx -fno-pic" } */++/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=keep -mindirect-branch=thunk -fcheck-pointer-bounds -mmpx -fno-pic" } */+ + void (*dispatch) (char *);+ char buf[10];+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-2.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-2.c+index aef4bd144f4..9eedd9a5a82 100644+--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-2.c++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-2.c+@@ -1,5 +1,5 @@+ /* { dg-do compile { target { ! x32 } } } */+-/* { dg-options "-O2 -mfunction-return=keep -mindirect-branch=thunk -fcheck-pointer-bounds -mmpx -fno-pic" } */++/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=keep -mindirect-branch=thunk -fcheck-pointer-bounds -mmpx -fno-pic" } */+ + void (*dispatch) (char *);+ char buf[10];+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-3.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-3.c+index 2cc0343f828..b2b8587eac7 100644+--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-3.c++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-3.c+@@ -1,5 +1,5 @@+ /* { dg-do compile { target { *-*-linux* && { ! x32 } } } } */+-/* { dg-options "-O2 -mfunction-return=keep -mindirect-branch=thunk -fcheck-pointer-bounds -mmpx -fpic -fno-plt" } */++/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=keep -mindirect-branch=thunk -fcheck-pointer-bounds -mmpx -fpic -fno-plt" } */+ + void bar (char *);+ char buf[10];+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-4.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-4.c+index 91560fef661..9459a2417f4 100644+--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-4.c++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-4.c+@@ -1,5 +1,5 @@+ /* { dg-do compile { target { *-*-linux* && { ! x32 } } } } */+-/* { dg-options "-O2 -mfunction-return=keep -mindirect-branch=thunk -fcheck-pointer-bounds -mmpx -fpic -fno-plt" } */++/* { dg-options "-O2 -mno-indirect-branch-register -mno-indirect-branch-register -mfunction-return=keep -mindirect-branch=thunk -fcheck-pointer-bounds -mmpx -fpic -fno-plt" } */+ + void bar (char *);+ char buf[10];+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-1.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-1.c+index dc6bd10af4c..b0aa3811e65 100644+--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-1.c++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-1.c+@@ -1,5 +1,5 @@+ /* { dg-do compile } */+-/* { dg-options "-O2 -mfunction-return=keep -mindirect-branch=thunk-extern -fno-pic" } */++/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=keep -mindirect-branch=thunk-extern -fno-pic" } */+ + typedef void (*dispatch_t)(long offset);+ +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-2.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-2.c+index 955aa256529..75fabcd988c 100644+--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-2.c++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-2.c+@@ -1,5 +1,5 @@+ /* { dg-do compile } */+-/* { dg-options "-O2 -mfunction-return=keep -mindirect-branch=thunk-extern -fno-pic" } */++/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=keep -mindirect-branch=thunk-extern -fno-pic" } */+ + typedef void (*dispatch_t)(long offset);+ +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-3.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-3.c+index 1537239416f..1d9dff2e834 100644+--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-3.c++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-3.c+@@ -1,5 +1,5 @@+ /* { dg-do compile } */+-/* { dg-options "-O2 -mfunction-return=keep -mindirect-branch=thunk-extern -fno-pic" } */++/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=keep -mindirect-branch=thunk-extern -fno-pic" } */+ + typedef void (*dispatch_t)(long offset);+ +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-4.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-4.c+index c82e53068fe..5b464155e38 100644+--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-4.c++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-4.c+@@ -1,5 +1,5 @@+ /* { dg-do compile } */+-/* { dg-options "-O2 -mfunction-return=keep -mindirect-branch=thunk-extern -fno-pic" } */++/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=keep -mindirect-branch=thunk-extern -fno-pic" } */+ + typedef void (*dispatch_t)(long offset);+ +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-5.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-5.c+index 23548d85f78..55ce91c73ec 100644+--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-5.c++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-5.c+@@ -1,5 +1,5 @@+ /* { dg-do compile { target *-*-linux* } } */+-/* { dg-options "-O2 -mfunction-return=keep -fpic -fno-plt -mindirect-branch=thunk-extern" } */++/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=keep -fpic -fno-plt -mindirect-branch=thunk-extern" } */+ + extern void bar (void);+ +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-6.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-6.c+index 56c2fe92f25..06180e7bee9 100644+--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-6.c++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-6.c+@@ -1,5 +1,5 @@+ /* { dg-do compile { target *-*-linux* } } */+-/* { dg-options "-O2 -mfunction-return=keep -fpic -fno-plt -mindirect-branch=thunk-extern" } */++/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=keep -fpic -fno-plt -mindirect-branch=thunk-extern" } */+ + extern void bar (void);+ +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-7.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-7.c+index e12b88593fe..790a05cec3e 100644+--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-7.c++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-7.c+@@ -1,5 +1,5 @@+ /* { dg-do compile } */+-/* { dg-options "-O2 -mfunction-return=keep -mindirect-branch=thunk-extern -fno-pic" } */++/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=keep -mindirect-branch=thunk-extern -fno-pic" } */+ + void func0 (void);+ void func1 (void);+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-1.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-1.c+index 87b5429702f..1ce8ca5aff1 100644+--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-1.c++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-1.c+@@ -1,5 +1,5 @@+ /* { dg-do compile } */+-/* { dg-options "-O2 -mfunction-return=keep -mindirect-branch=thunk-inline -fno-pic" } */++/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=keep -mindirect-branch=thunk-inline -fno-pic" } */+ + typedef void (*dispatch_t)(long offset);+ +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-2.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-2.c+index a496a41a918..f6b71e868bd 100644+--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-2.c++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-2.c+@@ -1,5 +1,5 @@+ /* { dg-do compile } */+-/* { dg-options "-O2 -mfunction-return=keep -mindirect-branch=thunk-inline -fno-pic" } */++/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=keep -mindirect-branch=thunk-inline -fno-pic" } */+ + typedef void (*dispatch_t)(long offset);+ +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-3.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-3.c+index 6fe5ce71abf..84a09d4d0d6 100644+--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-3.c++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-3.c+@@ -1,5 +1,5 @@+ /* { dg-do compile } */+-/* { dg-options "-O2 -mfunction-return=keep -mindirect-branch=thunk-inline -fno-pic" } */++/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=keep -mindirect-branch=thunk-inline -fno-pic" } */+ + typedef void (*dispatch_t)(long offset);+ +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-4.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-4.c+index 65cd997a33f..cfe3aefa0bf 100644+--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-4.c++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-4.c+@@ -1,5 +1,5 @@+ /* { dg-do compile } */+-/* { dg-options "-O2 -mfunction-return=keep -mindirect-branch=thunk-inline -fno-pic" } */++/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=keep -mindirect-branch=thunk-inline -fno-pic" } */+ + typedef void (*dispatch_t)(long offset);+ +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-5.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-5.c+index 7321d015c02..6411454243f 100644+--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-5.c++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-5.c+@@ -1,5 +1,5 @@+ /* { dg-do compile { target *-*-linux* } } */+-/* { dg-options "-O2 -mfunction-return=keep -fpic -fno-plt -mindirect-branch=thunk-inline" } */++/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=keep -fpic -fno-plt -mindirect-branch=thunk-inline" } */+ + extern void bar (void);+ +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-6.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-6.c+index 6ec2e5621ab..d4297fe21c4 100644+--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-6.c++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-6.c+@@ -1,5 +1,5 @@+ /* { dg-do compile { target *-*-linux* } } */+-/* { dg-options "-O2 -mfunction-return=keep -fpic -fno-plt -mindirect-branch=thunk-inline" } */++/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=keep -fpic -fno-plt -mindirect-branch=thunk-inline" } */+ + extern void bar (void);+ +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-7.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-7.c+index a3d1a13cded..eb318efdf4d 100644+--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-7.c++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-7.c+@@ -1,5 +1,5 @@+ /* { dg-do compile } */+-/* { dg-options "-O2 -mfunction-return=keep -mindirect-branch=thunk-inline -fno-pic" } */++/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=keep -mindirect-branch=thunk-inline -fno-pic" } */+ + void func0 (void);+ void func1 (void);+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-loop-1.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-loop-1.c+index f0e8f4949c8..605e32bb584 100644+--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-loop-1.c++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-loop-1.c+@@ -1,5 +1,5 @@+ /* { dg-do compile } */+-/* { dg-options "-O2 -mindirect-branch=thunk -mindirect-branch-loop=pause -fno-pic" } */++/* { dg-options "-O2 -mno-indirect-branch-register -mindirect-branch=thunk -mindirect-branch-loop=pause -fno-pic" } */+ + typedef void (*dispatch_t)(long offset);+ +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-loop-2.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-loop-2.c+index a577ac2568a..dd7a7b60621 100644+--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-loop-2.c++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-loop-2.c+@@ -1,5 +1,5 @@+ /* { dg-do compile } */+-/* { dg-options "-O2 -mindirect-branch=thunk -mindirect-branch-loop=nop -fno-pic" } */++/* { dg-options "-O2 -mno-indirect-branch-register -mindirect-branch=thunk -mindirect-branch-loop=nop -fno-pic" } */+ + typedef void (*dispatch_t)(long offset);+ +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-loop-3.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-loop-3.c+index c8dcb9639c4..338f22c373c 100644+--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-loop-3.c++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-loop-3.c+@@ -1,5 +1,5 @@+ /* { dg-do compile } */+-/* { dg-options "-O2 -mindirect-branch=thunk -mindirect-branch-loop=lfence -fno-pic" } */++/* { dg-options "-O2 -mno-indirect-branch-register -mindirect-branch=thunk -mindirect-branch-loop=lfence -fno-pic" } */+ + typedef void (*dispatch_t)(long offset);+ +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-loop-4.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-loop-4.c+index 8569dfc92c3..3b083ee30a8 100644+--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-loop-4.c++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-loop-4.c+@@ -1,5 +1,5 @@+ /* { dg-do compile } */+-/* { dg-options "-O2 -mindirect-branch=thunk-inline -mindirect-branch-loop=pause -fno-pic" } */++/* { dg-options "-O2 -mno-indirect-branch-register -mindirect-branch=thunk-inline -mindirect-branch-loop=pause -fno-pic" } */+ + typedef void (*dispatch_t)(long offset);+ +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-loop-5.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-loop-5.c+index bcf19c9ede1..31a9a81a911 100644+--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-loop-5.c++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-loop-5.c+@@ -1,5 +1,5 @@+ /* { dg-do compile } */+-/* { dg-options "-O2 -mindirect-branch=thunk-extern -mindirect-branch-loop=pause -fno-pic" } */++/* { dg-options "-O2 -mno-indirect-branch-register -mindirect-branch=thunk-extern -mindirect-branch-loop=pause -fno-pic" } */+ + typedef void (*dispatch_t)(long offset);+ +diff --git a/gcc/testsuite/gcc.target/i386/ret-thunk-10.c b/gcc/testsuite/gcc.target/i386/ret-thunk-10.c+index aecea4224f9..74f37ee9a62 100644+--- a/gcc/testsuite/gcc.target/i386/ret-thunk-10.c++++ b/gcc/testsuite/gcc.target/i386/ret-thunk-10.c+@@ -1,5 +1,5 @@+ /* { dg-do compile } */+-/* { dg-options "-O2 -mfunction-return=thunk-inline -mindirect-branch=thunk -fno-pic" } */++/* { dg-options "-O2 -mno-indirect-branch-register -mno-indirect-branch-register -mfunction-return=thunk-inline -mindirect-branch=thunk -fno-pic" } */+ + extern void (*bar) (void);+ +diff --git a/gcc/testsuite/gcc.target/i386/ret-thunk-11.c b/gcc/testsuite/gcc.target/i386/ret-thunk-11.c+index 3bacfb54dfd..0a52318e86b 100644+--- a/gcc/testsuite/gcc.target/i386/ret-thunk-11.c++++ b/gcc/testsuite/gcc.target/i386/ret-thunk-11.c+@@ -1,5 +1,5 @@+ /* { dg-do compile } */+-/* { dg-options "-O2 -mfunction-return=thunk-extern -mindirect-branch=thunk -fno-pic" } */++/* { 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" } */+ + extern void (*bar) (void);+ +diff --git a/gcc/testsuite/gcc.target/i386/ret-thunk-12.c b/gcc/testsuite/gcc.target/i386/ret-thunk-12.c+index 851115ac507..d2f775490ea 100644+--- a/gcc/testsuite/gcc.target/i386/ret-thunk-12.c++++ b/gcc/testsuite/gcc.target/i386/ret-thunk-12.c+@@ -1,5 +1,5 @@+ /* { dg-do compile } */+-/* { dg-options "-O2 -mfunction-return=keep -mindirect-branch=thunk -fno-pic" } */++/* { 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" } */+ + extern void (*bar) (void);+ +diff --git a/gcc/testsuite/gcc.target/i386/ret-thunk-13.c b/gcc/testsuite/gcc.target/i386/ret-thunk-13.c+index 7acb6fa5eae..82d46165f3e 100644+--- a/gcc/testsuite/gcc.target/i386/ret-thunk-13.c++++ b/gcc/testsuite/gcc.target/i386/ret-thunk-13.c+@@ -1,5 +1,5 @@+ /* { dg-do compile } */+-/* { dg-options "-O2 -mfunction-return=keep -mindirect-branch=thunk-inline -fno-pic" } */++/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=keep -mindirect-branch=thunk-inline -fno-pic" } */+ + extern void (*bar) (void);+ extern int foo (void) __attribute__ ((function_return("thunk")));+diff --git a/gcc/testsuite/gcc.target/i386/ret-thunk-14.c b/gcc/testsuite/gcc.target/i386/ret-thunk-14.c+index bf340fac7c6..6711eb27fa8 100644+--- a/gcc/testsuite/gcc.target/i386/ret-thunk-14.c++++ b/gcc/testsuite/gcc.target/i386/ret-thunk-14.c+@@ -1,5 +1,5 @@+ /* { dg-do compile } */+-/* { dg-options "-O2 -mfunction-return=keep -mindirect-branch=thunk-extern -fno-pic" } */++/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=keep -mindirect-branch=thunk-extern -fno-pic" } */+ + extern void (*bar) (void);+ +diff --git a/gcc/testsuite/gcc.target/i386/ret-thunk-15.c b/gcc/testsuite/gcc.target/i386/ret-thunk-15.c+index 735f8648c96..37758c33371 100644+--- a/gcc/testsuite/gcc.target/i386/ret-thunk-15.c++++ b/gcc/testsuite/gcc.target/i386/ret-thunk-15.c+@@ -1,5 +1,5 @@+ /* { dg-do compile } */+-/* { dg-options "-O2 -mfunction-return=keep -mindirect-branch=keep -fno-pic" } */++/* { 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" } */+ + extern void (*bar) (void);+ +diff --git a/gcc/testsuite/gcc.target/i386/ret-thunk-9.c b/gcc/testsuite/gcc.target/i386/ret-thunk-9.c+index 569e5f47973..70771ea35d7 100644+--- a/gcc/testsuite/gcc.target/i386/ret-thunk-9.c++++ b/gcc/testsuite/gcc.target/i386/ret-thunk-9.c+@@ -1,5 +1,5 @@+ /* { dg-do compile } */+-/* { dg-options "-O2 -mfunction-return=thunk -mindirect-branch=thunk -fno-pic" } */++/* { dg-options "-O2 -mno-indirect-branch-register -mno-indirect-branch-register -mfunction-return=thunk -mindirect-branch=thunk -fno-pic" } */+ + extern void (*bar) (void);+ +-- +2.15.1+diff --git a/gnu/packages/patches/gcc-retpoline-Add-tests-for-mindirect-branch-thunk-fcheck-pointer-.patch b/gnu/packages/patches/gcc-retpoline-Add-tests-for-mindirect-branch-thunk-fcheck-pointer-.patchnew file mode 100644index 000000000..e21bb5039--- /dev/null+++ b/gnu/packages/patches/gcc-retpoline-Add-tests-for-mindirect-branch-thunk-fcheck-pointer-.patch@@ -0,0 +1,134 @@+'Retpoline' mitigation technique for Spectre (branch target injection)+[CVE-2017-5715]:++https://security.googleblog.com/2018/01/more-details-about-mitigations-for-cpu_4.html+https://support.google.com/faqs/answer/7625886+https://spectreattack.com/+https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2017-5715++Patch copied from the 'retpoline-20180107' branch of upstream source repository+(please add new / update existing patches when new 'retpoline-xxxxxxxx' branch+appears):++http://git.infradead.org/users/dwmw2/gcc-retpoline.git++From ece041bc3083aabd00fab9de5ba409fbd7dcad8c Mon Sep 17 00:00:00 2001+From: "H.J. Lu" <hjl.tools@gmail.com>+Date: Mon, 4 Dec 2017 12:58:20 -0800+Subject: [PATCH 05/17] Add tests for -mindirect-branch=thunk+ -fcheck-pointer-bounds -mmpx++---+ gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-1.c | 19 ++++++++++++++++++++ gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-2.c | 20 +++++++++++++++++++++ gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-3.c | 18 +++++++++++++++++++ gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-4.c | 19 ++++++++++++++++++++ 4 files changed, 76 insertions(+)+ create mode 100644 gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-1.c+ create mode 100644 gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-2.c+ create mode 100644 gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-3.c+ create mode 100644 gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-4.c++diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-1.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-1.c+new file mode 100644+index 00000000000..a5b1d38e061+--- /dev/null++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-1.c+@@ -0,0 +1,19 @@++/* { dg-do compile { target { ! x32 } } } */++/* { dg-options "-O2 -mindirect-branch=thunk -fcheck-pointer-bounds -mmpx -fno-pic" } */++++void (*dispatch) (char *);++char buf[10];++++void++foo (void)++{++ dispatch (buf);++}++++/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { ! x32 } } } } */++/* { dg-final { scan-assembler "pushq\[ \t\]%rax" { target x32 } } } */++/* { dg-final { scan-assembler "bnd jmp\[ \t\]*__x86.indirect_thunk_bnd" } } */++/* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */++/* { dg-final { scan-assembler "bnd call\[ \t\]*\.LIND" } } */++/* { dg-final { scan-assembler "bnd ret" } } */++/* { dg-final { scan-assembler {\tlfence} } } */+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-2.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-2.c+new file mode 100644+index 00000000000..a42add209e2+--- /dev/null++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-2.c+@@ -0,0 +1,20 @@++/* { dg-do compile { target { ! x32 } } } */++/* { dg-options "-O2 -mindirect-branch=thunk -fcheck-pointer-bounds -mmpx -fno-pic" } */++++void (*dispatch) (char *);++char buf[10];++++int++foo (void)++{++ dispatch (buf);++ return 0;++}++++/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { ! x32 } } } } */++/* { dg-final { scan-assembler "pushq\[ \t\]%rax" { target x32 } } } */++/* { dg-final { scan-assembler "bnd jmp\[ \t\]*__x86.indirect_thunk_bnd" } } */++/* { dg-final { scan-assembler "bnd jmp\[ \t\]*\.LIND" } } */++/* { dg-final { scan-assembler "bnd call\[ \t\]*\.LIND" } } */++/* { dg-final { scan-assembler "bnd ret" } } */++/* { dg-final { scan-assembler {\tlfence} } } */+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-3.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-3.c+new file mode 100644+index 00000000000..265e010a0fe+--- /dev/null++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-3.c+@@ -0,0 +1,18 @@++/* { dg-do compile { target { *-*-linux* && { ! x32 } } } } */++/* { dg-options "-O2 -mindirect-branch=thunk -fcheck-pointer-bounds -mmpx -fpic -fno-plt" } */++++void bar (char *);++char buf[10];++++void++foo (void)++{++ bar (buf);++}++++/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*bar@GOT" } } */++/* { dg-final { scan-assembler "bnd jmp\[ \t\]*__x86.indirect_thunk_bnd" } } */++/* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */++/* { dg-final { scan-assembler "bnd call\[ \t\]*\.LIND" } } */++/* { dg-final { scan-assembler "bnd ret" } } */++/* { dg-final { scan-assembler {\tlfence} } } */+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-4.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-4.c+new file mode 100644+index 00000000000..1c01bcb7fc6+--- /dev/null++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-4.c+@@ -0,0 +1,19 @@++/* { dg-do compile { target { *-*-linux* && { ! x32 } } } } */++/* { dg-options "-O2 -mindirect-branch=thunk -fcheck-pointer-bounds -mmpx -fpic -fno-plt" } */++++void bar (char *);++char buf[10];++++int++foo (void)++{++ bar (buf);++ return 0;++}++++/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*bar@GOT" } } */++/* { dg-final { scan-assembler "bnd jmp\[ \t\]*__x86.indirect_thunk" } } */++/* { dg-final { scan-assembler "bnd jmp\[ \t\]*\.LIND" } } */++/* { dg-final { scan-assembler-times "bnd call\[ \t\]*\.LIND" 2 } } */++/* { dg-final { scan-assembler "bnd ret" } } */++/* { dg-final { scan-assembler {\tlfence} } } */+-- +2.15.1+diff --git a/gnu/packages/patches/gcc-retpoline-Disable-red-zone-with-local-indirect-jump.patch b/gnu/packages/patches/gcc-retpoline-Disable-red-zone-with-local-indirect-jump.patchnew file mode 100644index 000000000..b22e364af--- /dev/null+++ b/gnu/packages/patches/gcc-retpoline-Disable-red-zone-with-local-indirect-jump.patch@@ -0,0 +1,147 @@+'Retpoline' mitigation technique for Spectre (branch target injection)+[CVE-2017-5715]:++https://security.googleblog.com/2018/01/more-details-about-mitigations-for-cpu_4.html+https://support.google.com/faqs/answer/7625886+https://spectreattack.com/+https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2017-5715++Patch copied from the 'retpoline-20180107' branch of upstream source repository+(please add new / update existing patches when new 'retpoline-xxxxxxxx' branch+appears):++http://git.infradead.org/users/dwmw2/gcc-retpoline.git++From f96e28553b0f2253184441f22852d76976e19968 Mon Sep 17 00:00:00 2001+From: "H.J. Lu" <hjl.tools@gmail.com>+Date: Tue, 12 Dec 2017 19:15:25 -0800+Subject: [PATCH 15/17] Disable red zone with local indirect jump++---+ gcc/config/i386/i386-protos.h | 2 +-+ gcc/config/i386/i386.c | 22 +++++++++++++++++-----+ gcc/config/i386/i386.h | 4 +++++ gcc/config/i386/i386.md | 8 +++++---+ 4 files changed, 27 insertions(+), 9 deletions(-)++diff --git a/gcc/config/i386/i386-protos.h b/gcc/config/i386/i386-protos.h+index 213663811de..a78bfa00427 100644+--- a/gcc/config/i386/i386-protos.h++++ b/gcc/config/i386/i386-protos.h+@@ -315,7 +315,7 @@ extern enum attr_cpu ix86_schedule;+ #endif+ + extern const char * ix86_output_call_insn (rtx_insn *insn, rtx call_op);+-extern const char * ix86_output_indirect_jmp (rtx call_op);++extern const char * ix86_output_indirect_jmp (rtx call_op, bool ret_p);+ extern const char * ix86_output_function_return (bool long_p);+ extern bool ix86_operands_ok_for_move_multiple (rtx *operands, bool load,+ enum machine_mode mode);+diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c+index 7ae3523095c..344cafe3dac 100644+--- a/gcc/config/i386/i386.c++++ b/gcc/config/i386/i386.c+@@ -4209,12 +4209,19 @@ make_pass_stv (gcc::context *ctxt)+ return new pass_stv (ctxt);+ }+ +-/* Return true if a red-zone is in use. */++/* Return true if a red-zone is in use. We can't use red-zone when++ there are local indirect jumps, like "indirect_jump" or "tablejump",++ which jumps to another place in the function, since "call" in the++ indirect thunk pushes the return address onto stack, destroying++ red-zone. */+ + bool+ ix86_using_red_zone (void)+ {+- return TARGET_RED_ZONE && !TARGET_64BIT_MS_ABI;++ return (TARGET_RED_ZONE++ && !TARGET_64BIT_MS_ABI++ && (!cfun->machine->has_local_indirect_jump++ || cfun->machine->indirect_branch_type == indirect_branch_keep));+ }+ + /* Return a string that documents the current -m options. The caller is+@@ -28919,11 +28926,16 @@ ix86_output_indirect_branch (rtx call_op, const char *xasm,+ }+ + const char *+-ix86_output_indirect_jmp (rtx call_op)++ix86_output_indirect_jmp (rtx call_op, bool ret_p)+ {+- if (ix86_red_zone_size == 0+- && cfun->machine->indirect_branch_type != indirect_branch_keep)++ if (cfun->machine->indirect_branch_type != indirect_branch_keep)+ {++ /* We can't have red-zone if this isn't a function return since++ "call" in the indirect thunk pushes the return address onto++ stack, destroying red-zone. */++ if (!ret_p && ix86_red_zone_size != 0)++ gcc_unreachable ();+++ ix86_output_indirect_branch (call_op, "%0", true);+ return "";+ }+diff --git a/gcc/config/i386/i386.h b/gcc/config/i386/i386.h+index f248f3ba2f5..5f30d3f8d19 100644+--- a/gcc/config/i386/i386.h++++ b/gcc/config/i386/i386.h+@@ -2607,6 +2607,10 @@ struct GTY(()) machine_function {+ /* How to generate indirec branch. */+ ENUM_BITFIELD(indirect_branch) indirect_branch_type : 3;+ ++ /* If true, the current function has local indirect jumps, like++ "indirect_jump" or "tablejump". */++ BOOL_BITFIELD has_local_indirect_jump : 1;+++ /* How to generate function return. */+ ENUM_BITFIELD(indirect_branch) function_return_type : 3;+ +diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md+index 473fa5c089b..ea95aad7540 100644+--- a/gcc/config/i386/i386.md++++ b/gcc/config/i386/i386.md+@@ -11610,12 +11610,13 @@+ {+ if (TARGET_X32 || ix86_indirect_branch_thunk_register)+ operands[0] = convert_memory_address (word_mode, operands[0]);++ cfun->machine->has_local_indirect_jump = true;+ })+ + (define_insn "*indirect_jump"+ [(set (pc) (match_operand:W 0 "indirect_branch_operand" "rBw"))]+ ""+- "* return ix86_output_indirect_jmp (operands[0]);"++ "* return ix86_output_indirect_jmp (operands[0], false);"+ [(set_attr "type" "ibr")+ (set_attr "length_immediate" "0")+ (set_attr "maybe_prefix_bnd" "1")])+@@ -11659,13 +11660,14 @@+ + if (TARGET_X32 || ix86_indirect_branch_thunk_register)+ operands[0] = convert_memory_address (word_mode, operands[0]);++ cfun->machine->has_local_indirect_jump = true;+ })+ + (define_insn "*tablejump_1"+ [(set (pc) (match_operand:W 0 "indirect_branch_operand" "rBw"))+ (use (label_ref (match_operand 1)))]+ ""+- "* return ix86_output_indirect_jmp (operands[0]);"++ "* return ix86_output_indirect_jmp (operands[0], false);"+ [(set_attr "type" "ibr")+ (set_attr "length_immediate" "0")+ (set_attr "maybe_prefix_bnd" "1")])+@@ -12342,7 +12344,7 @@+ [(simple_return)+ (use (match_operand:SI 0 "register_operand" "r"))]+ "reload_completed"+- "* return ix86_output_indirect_jmp (operands[0]);"++ "* return ix86_output_indirect_jmp (operands[0], true);"+ [(set_attr "type" "ibr")+ (set_attr "length_immediate" "0")+ (set_attr "maybe_prefix_bnd" "1")])+-- +2.15.1+diff --git a/gnu/packages/patches/gcc-retpoline-Rename-thunks-to-__x86_indirect_thunk_rax-etc.-to-re.patch b/gnu/packages/patches/gcc-retpoline-Rename-thunks-to-__x86_indirect_thunk_rax-etc.-to-re.patchnew file mode 100644index 000000000..6379270df--- /dev/null+++ b/gnu/packages/patches/gcc-retpoline-Rename-thunks-to-__x86_indirect_thunk_rax-etc.-to-re.patch@@ -0,0 +1,926 @@+'Retpoline' mitigation technique for Spectre (branch target injection)+[CVE-2017-5715]:++https://security.googleblog.com/2018/01/more-details-about-mitigations-for-cpu_4.html+https://support.google.com/faqs/answer/7625886+https://spectreattack.com/+https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2017-5715++Patch copied from the 'retpoline-20180107' branch of upstream source repository+(please add new / update existing patches when new 'retpoline-xxxxxxxx' branch+appears):++http://git.infradead.org/users/dwmw2/gcc-retpoline.git++From a072725899c551d9f3f06f3595e2a49748ab0187 Mon Sep 17 00:00:00 2001+From: David Woodhouse <dwmw2@infradead.org>+Date: Sun, 7 Jan 2018 17:27:09 +0000+Subject: [PATCH 17/17] Rename thunks to __x86_indirect_thunk_rax etc. to+ remove dots++---+ gcc/config/i386/i386.c | 8 ++++----+ gcc/testsuite/gcc.target/i386/indirect-thunk-1.c | 4 ++--+ gcc/testsuite/gcc.target/i386/indirect-thunk-2.c | 4 ++--+ gcc/testsuite/gcc.target/i386/indirect-thunk-3.c | 4 ++--+ gcc/testsuite/gcc.target/i386/indirect-thunk-4.c | 4 ++--+ gcc/testsuite/gcc.target/i386/indirect-thunk-5.c | 2 +-+ gcc/testsuite/gcc.target/i386/indirect-thunk-6.c | 2 +-+ gcc/testsuite/gcc.target/i386/indirect-thunk-7.c | 4 ++--+ gcc/testsuite/gcc.target/i386/indirect-thunk-attr-1.c | 4 ++--+ gcc/testsuite/gcc.target/i386/indirect-thunk-attr-2.c | 4 ++--+ gcc/testsuite/gcc.target/i386/indirect-thunk-attr-3.c | 2 +-+ gcc/testsuite/gcc.target/i386/indirect-thunk-attr-4.c | 2 +-+ gcc/testsuite/gcc.target/i386/indirect-thunk-attr-5.c | 4 ++--+ gcc/testsuite/gcc.target/i386/indirect-thunk-attr-6.c | 4 ++--+ gcc/testsuite/gcc.target/i386/indirect-thunk-attr-7.c | 4 ++--+ gcc/testsuite/gcc.target/i386/indirect-thunk-attr-8.c | 2 +-+ gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-1.c | 2 +-+ gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-2.c | 2 +-+ gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-3.c | 2 +-+ gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-4.c | 2 +-+ gcc/testsuite/gcc.target/i386/indirect-thunk-extern-1.c | 4 ++--+ gcc/testsuite/gcc.target/i386/indirect-thunk-extern-2.c | 4 ++--+ gcc/testsuite/gcc.target/i386/indirect-thunk-extern-3.c | 4 ++--+ gcc/testsuite/gcc.target/i386/indirect-thunk-extern-4.c | 4 ++--+ gcc/testsuite/gcc.target/i386/indirect-thunk-extern-5.c | 2 +-+ gcc/testsuite/gcc.target/i386/indirect-thunk-extern-6.c | 2 +-+ gcc/testsuite/gcc.target/i386/indirect-thunk-extern-7.c | 4 ++--+ gcc/testsuite/gcc.target/i386/indirect-thunk-inline-1.c | 2 +-+ gcc/testsuite/gcc.target/i386/indirect-thunk-inline-2.c | 2 +-+ gcc/testsuite/gcc.target/i386/indirect-thunk-inline-3.c | 2 +-+ gcc/testsuite/gcc.target/i386/indirect-thunk-inline-4.c | 2 +-+ gcc/testsuite/gcc.target/i386/indirect-thunk-inline-5.c | 2 +-+ gcc/testsuite/gcc.target/i386/indirect-thunk-inline-6.c | 2 +-+ gcc/testsuite/gcc.target/i386/indirect-thunk-inline-7.c | 2 +-+ gcc/testsuite/gcc.target/i386/indirect-thunk-loop-1.c | 4 ++--+ gcc/testsuite/gcc.target/i386/indirect-thunk-loop-2.c | 4 ++--+ gcc/testsuite/gcc.target/i386/indirect-thunk-loop-3.c | 4 ++--+ gcc/testsuite/gcc.target/i386/indirect-thunk-loop-4.c | 2 +-+ gcc/testsuite/gcc.target/i386/indirect-thunk-loop-5.c | 4 ++--+ gcc/testsuite/gcc.target/i386/indirect-thunk-register-1.c | 6 +++---+ gcc/testsuite/gcc.target/i386/indirect-thunk-register-2.c | 2 +-+ gcc/testsuite/gcc.target/i386/indirect-thunk-register-3.c | 2 +-+ gcc/testsuite/gcc.target/i386/ret-thunk-1.c | 2 +-+ gcc/testsuite/gcc.target/i386/ret-thunk-10.c | 10 +++++-----+ gcc/testsuite/gcc.target/i386/ret-thunk-11.c | 10 +++++-----+ gcc/testsuite/gcc.target/i386/ret-thunk-12.c | 10 +++++-----+ gcc/testsuite/gcc.target/i386/ret-thunk-13.c | 6 +++---+ gcc/testsuite/gcc.target/i386/ret-thunk-14.c | 6 +++---+ gcc/testsuite/gcc.target/i386/ret-thunk-15.c | 6 +++---+ gcc/testsuite/gcc.target/i386/ret-thunk-16.c | 4 ++--+ gcc/testsuite/gcc.target/i386/ret-thunk-2.c | 2 +-+ gcc/testsuite/gcc.target/i386/ret-thunk-3.c | 2 +-+ gcc/testsuite/gcc.target/i386/ret-thunk-4.c | 2 +-+ gcc/testsuite/gcc.target/i386/ret-thunk-5.c | 2 +-+ gcc/testsuite/gcc.target/i386/ret-thunk-6.c | 2 +-+ gcc/testsuite/gcc.target/i386/ret-thunk-7.c | 2 +-+ gcc/testsuite/gcc.target/i386/ret-thunk-8.c | 2 +-+ gcc/testsuite/gcc.target/i386/ret-thunk-9.c | 10 +++++-----+ 58 files changed, 105 insertions(+), 105 deletions(-)++diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c+index 6cb0681233a..9e6c9bdb514 100644+--- a/gcc/config/i386/i386.c++++ b/gcc/config/i386/i386.c+@@ -12006,13 +12006,13 @@ indirect_thunk_name (char name[32], int regno, bool need_bnd_p,+ reg_prefix = TARGET_64BIT ? "r" : "e";+ else+ reg_prefix = "";+- sprintf (name, "__x86.indirect_thunk%s.%s%s",++ sprintf (name, "__x86_indirect_thunk%s_%s%s",+ bnd, reg_prefix, reg_names[regno]);+ }+ else+ {+ const char *ret = ret_p ? "return" : "indirect";+- sprintf (name, "__x86.%s_thunk%s", ret, bnd);++ sprintf (name, "__x86_%s_thunk%s", ret, bnd);+ }+ }+ else+@@ -12119,7 +12119,7 @@ output_indirect_thunk_function (bool need_bnd_p, int regno)+ char name[32];+ tree decl;+ +- /* Create __x86.indirect_thunk/__x86.indirect_thunk_bnd. */++ /* Create __x86_indirect_thunk/__x86_indirect_thunk_bnd. */+ indirect_thunk_name (name, regno, need_bnd_p, false);+ decl = build_decl (BUILTINS_LOCATION, FUNCTION_DECL,+ get_identifier (name),+@@ -12165,7 +12165,7 @@ output_indirect_thunk_function (bool need_bnd_p, int regno)+ + if (regno < 0)+ {+- /* Create alias for __x86.return_thunk/__x86.return_thunk_bnd. */++ /* Create alias for __x86_return_thunk/__x86_return_thunk_bnd. */+ char alias[32];+ + indirect_thunk_name (alias, regno, need_bnd_p, true);+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-1.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-1.c+index b0625207b92..f4f2b7debe0 100644+--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-1.c++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-1.c+@@ -12,8 +12,8 @@ male_indirect_jump (long offset)+ }+ + /* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { ! x32 } } } } */+-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" { target { ! x32 } } } } */+-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk\.(r|e)ax" { target x32 } } } */++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" { target { ! x32 } } } } */++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk_(r|e)ax" { target x32 } } } */+ /* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */+ /* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */+ /* { dg-final { scan-assembler {\tlfence} } } */+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-2.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-2.c+index 0b289685e6b..d4e5dadd966 100644+--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-2.c++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-2.c+@@ -12,8 +12,8 @@ male_indirect_jump (long offset)+ }+ + /* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { ! x32 } } } } */+-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" { target { ! x32 } } } } */+-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk\.(r|e)ax" { target x32 } } } */++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" { target { ! x32 } } } } */++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk_(r|e)ax" { target x32 } } } */+ /* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */+ /* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */+ /* { dg-final { scan-assembler {\tlfence} } } */+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-3.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-3.c+index 79a9f76285f..9802fae5d04 100644+--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-3.c++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-3.c+@@ -13,8 +13,8 @@ male_indirect_jump (long offset)+ }+ + /* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { ! x32 } } } } */+-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" { target { ! x32 } } } } */+-/* { dg-final { scan-assembler "call\[ \t\]*__x86.indirect_thunk\.(r|e)ax" { target x32 } } } */++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" { target { ! x32 } } } } */++/* { dg-final { scan-assembler "call\[ \t\]*__x86_indirect_thunk_(r|e)ax" { target x32 } } } */+ /* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */+ /* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */+ /* { dg-final { scan-assembler {\tlfence} } } */+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-4.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-4.c+index 901d94213bd..fad3105b50d 100644+--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-4.c++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-4.c+@@ -13,8 +13,8 @@ male_indirect_jump (long offset)+ }+ + /* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { ! x32 } } } } */+-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" { target { ! x32 } } } } */+-/* { dg-final { scan-assembler "call\[ \t\]*__x86.indirect_thunk\.(r|e)ax" { target x32 } } } */++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" { target { ! x32 } } } } */++/* { dg-final { scan-assembler "call\[ \t\]*__x86_indirect_thunk_(r|e)ax" { target x32 } } } */+ /* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */+ /* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */+ /* { dg-final { scan-assembler {\tlfence} } } */+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-5.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-5.c+index d2c9bd9d7ca..e44f2ff5682 100644+--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-5.c++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-5.c+@@ -10,7 +10,7 @@ foo (void)+ }+ + /* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*bar@GOT" } } */+-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" } } */++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" } } */+ /* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */+ /* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */+ /* { dg-final { scan-assembler {\tlfence} } } */+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-6.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-6.c+index f8b028db7a2..f1e03a30854 100644+--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-6.c++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-6.c+@@ -11,7 +11,7 @@ foo (void)+ }+ + /* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*bar@GOT" } } */+-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" } } */++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" } } */+ /* { dg-final { scan-assembler-times "jmp\[ \t\]*\.LIND" 2 } } */+ /* { dg-final { scan-assembler-times "call\[ \t\]*\.LIND" 2 } } */+ /* { dg-final { scan-assembler {\tlfence} } } */+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-7.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-7.c+index 465775407ec..fc91a334459 100644+--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-7.c++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-7.c+@@ -36,8 +36,8 @@ bar (int i)+ }+ + /* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*\.L\[0-9\]+\\(,%" { target { ! x32 } } } } */+-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" { target { ! x32 } } } } */+-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk\.(r|e)ax" { target x32 } } } */++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" { target { ! x32 } } } } */++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk_(r|e)ax" { target x32 } } } */+ /* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */+ /* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */+ /* { dg-final { scan-assembler {\tlfence} } } */+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-1.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-1.c+index 5309d5a3eaa..a8ab95b6451 100644+--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-1.c++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-1.c+@@ -15,8 +15,8 @@ male_indirect_jump (long offset)+ }+ + /* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { ! x32 } } } } */+-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" { target { ! x32 } } } } */+-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk\.(r|e)ax" { target x32 } } } */++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" { target { ! x32 } } } } */++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk_(r|e)ax" { target x32 } } } */+ /* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */+ /* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */+ /* { dg-final { scan-assembler {\tlfence} } } */+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-2.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-2.c+index dd1efca49fd..467d62324d5 100644+--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-2.c++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-2.c+@@ -13,8 +13,8 @@ male_indirect_jump (long offset)+ }+ + /* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { ! x32 } } } } */+-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" { target { ! x32 } } } } */+-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk\.(r|e)ax" { target x32 } } } */++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" { target { ! x32 } } } } */++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk_(r|e)ax" { target x32 } } } */+ /* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */+ /* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */+ /* { dg-final { scan-assembler {\tlfence} } } */+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-3.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-3.c+index e97ca636020..02223f8d0f4 100644+--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-3.c++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-3.c+@@ -17,5 +17,5 @@ male_indirect_jump (long offset)+ /* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { ! x32 } } } } */+ /* { dg-final { scan-assembler-times "jmp\[ \t\]*\.LIND" 2 } } */+ /* { dg-final { scan-assembler-times "call\[ \t\]*\.LIND" 2 } } */+-/* { dg-final { scan-assembler-not "__x86.indirect_thunk" } } */++/* { dg-final { scan-assembler-not "__x86_indirect_thunk" } } */+ /* { dg-final { scan-assembler-not "pushq\[ \t\]%rax" { target x32 } } } */+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-4.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-4.c+index b547cbbf255..a80b46af934 100644+--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-4.c++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-4.c+@@ -16,5 +16,5 @@ male_indirect_jump (long offset)+ /* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { ! x32 } } } } */+ /* { dg-final { scan-assembler-times "jmp\[ \t\]*\.LIND" 2 } } */+ /* { dg-final { scan-assembler-times "call\[ \t\]*\.LIND" 2 } } */+-/* { dg-final { scan-assembler-not "__x86.indirect_thunk" } } */++/* { dg-final { scan-assembler-not "__x86_indirect_thunk" } } */+ /* { dg-final { scan-assembler-not "pushq\[ \t\]%rax" { target x32 } } } */+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-5.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-5.c+index 353689dc415..4bb1c5f9220 100644+--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-5.c++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-5.c+@@ -17,6 +17,6 @@ male_indirect_jump (long offset)+ /* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { ! x32 } } } } */+ /* { dg-final { scan-assembler-times "jmp\[ \t\]*\.LIND" 1 { target { ! x32 } } } } */+ /* { dg-final { scan-assembler-times "call\[ \t\]*\.LIND" 1 { target { ! x32 } } } } */+-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" { target { ! x32 } } } } */+-/* { dg-final { scan-assembler "call\[ \t\]*__x86.indirect_thunk\.(r|e)ax" { target x32 } } } */++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" { target { ! x32 } } } } */++/* { dg-final { scan-assembler "call\[ \t\]*__x86_indirect_thunk_(r|e)ax" { target x32 } } } */+ /* { dg-final { scan-assembler-not {\t(lfence|pause)} } } */+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-6.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-6.c+index 1edef7208f4..4e33a638862 100644+--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-6.c++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-6.c+@@ -16,6 +16,6 @@ male_indirect_jump (long offset)+ /* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { ! x32 } } } } */+ /* { dg-final { scan-assembler-times "jmp\[ \t\]*\.LIND" 1 { target { ! x32 } } } } */+ /* { dg-final { scan-assembler-times "call\[ \t\]*\.LIND" 1 { target { ! x32 } } } } */+-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" { target { ! x32 } } } } */+-/* { dg-final { scan-assembler "call\[ \t\]*__x86.indirect_thunk\.(r|e)ax" { target x32 } } } */++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" { target { ! x32 } } } } */++/* { dg-final { scan-assembler "call\[ \t\]*__x86_indirect_thunk_(r|e)ax" { target x32 } } } */+ /* { dg-final { scan-assembler-not {\t(lfence|pause)} } } */+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-7.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-7.c+index c2e816cdfc6..427ba3ddbb4 100644+--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-7.c++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-7.c+@@ -37,8 +37,8 @@ bar (int i)+ }+ + /* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*\.L\[0-9\]+\\(,%" { target { ! x32 } } } } */+-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk\.(r|e)ax" { target x32 } } } */+-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" } } */++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk_(r|e)ax" { target x32 } } } */++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" } } */+ /* { dg-final { scan-assembler-not {\t(lfence|pause)} } } */+ /* { dg-final { scan-assembler-not "jmp\[ \t\]*\.LIND" } } */+ /* { dg-final { scan-assembler-not "call\[ \t\]*\.LIND" } } */+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-8.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-8.c+index af1bb125a22..c246f974610 100644+--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-8.c++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-8.c+@@ -36,6 +36,6 @@ bar (int i)+ }+ }+ +-/* { dg-final { scan-assembler-not "__x86.indirect_thunk" } } */++/* { dg-final { scan-assembler-not "__x86_indirect_thunk" } } */+ /* { dg-final { scan-assembler-not "jmp\[ \t\]*\.LIND" } } */+ /* { dg-final { scan-assembler-not "call\[ \t\]*\.LIND" } } */+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-1.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-1.c+index 5c10de47b7c..3399ad56a7f 100644+--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-1.c++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-1.c+@@ -12,7 +12,7 @@ foo (void)+ + /* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { ! x32 } } } } */+ /* { dg-final { scan-assembler "pushq\[ \t\]%rax" { target x32 } } } */+-/* { dg-final { scan-assembler "bnd jmp\[ \t\]*__x86.indirect_thunk_bnd" } } */++/* { dg-final { scan-assembler "bnd jmp\[ \t\]*__x86_indirect_thunk_bnd" } } */+ /* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */+ /* { dg-final { scan-assembler "bnd call\[ \t\]*\.LIND" } } */+ /* { dg-final { scan-assembler "bnd ret" } } */+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-2.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-2.c+index 9eedd9a5a82..daa9528f7bd 100644+--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-2.c++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-2.c+@@ -13,7 +13,7 @@ foo (void)+ + /* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { ! x32 } } } } */+ /* { dg-final { scan-assembler "pushq\[ \t\]%rax" { target x32 } } } */+-/* { dg-final { scan-assembler "bnd jmp\[ \t\]*__x86.indirect_thunk_bnd" } } */++/* { dg-final { scan-assembler "bnd jmp\[ \t\]*__x86_indirect_thunk_bnd" } } */+ /* { dg-final { scan-assembler "bnd jmp\[ \t\]*\.LIND" } } */+ /* { dg-final { scan-assembler "bnd call\[ \t\]*\.LIND" } } */+ /* { dg-final { scan-assembler "bnd ret" } } */+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-3.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-3.c+index b2b8587eac7..647ec5a4ade 100644+--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-3.c++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-3.c+@@ -11,7 +11,7 @@ foo (void)+ }+ + /* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*bar@GOT" } } */+-/* { dg-final { scan-assembler "bnd jmp\[ \t\]*__x86.indirect_thunk_bnd" } } */++/* { dg-final { scan-assembler "bnd jmp\[ \t\]*__x86_indirect_thunk_bnd" } } */+ /* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */+ /* { dg-final { scan-assembler "bnd call\[ \t\]*\.LIND" } } */+ /* { dg-final { scan-assembler "bnd ret" } } */+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-4.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-4.c+index 9459a2417f4..3a7a1cea8bc 100644+--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-4.c++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-4.c+@@ -12,7 +12,7 @@ foo (void)+ }+ + /* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*bar@GOT" } } */+-/* { dg-final { scan-assembler "bnd jmp\[ \t\]*__x86.indirect_thunk" } } */++/* { dg-final { scan-assembler "bnd jmp\[ \t\]*__x86_indirect_thunk" } } */+ /* { dg-final { scan-assembler "bnd jmp\[ \t\]*\.LIND" } } */+ /* { dg-final { scan-assembler-times "bnd call\[ \t\]*\.LIND" 2 } } */+ /* { dg-final { scan-assembler "bnd ret" } } */+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-1.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-1.c+index b0aa3811e65..5c20a35ecec 100644+--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-1.c++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-1.c+@@ -12,8 +12,8 @@ male_indirect_jump (long offset)+ }+ + /* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { ! x32 } } } } */+-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" { target { ! x32 } } } } */+-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk\.(r|e)ax" { target x32 } } } */++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" { target { ! x32 } } } } */++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk_(r|e)ax" { target x32 } } } */+ /* { dg-final { scan-assembler-not {\t(lfence|pause)} } } */+ /* { dg-final { scan-assembler-not "jmp\[ \t\]*\.LIND" } } */+ /* { dg-final { scan-assembler-not "call\[ \t\]*\.LIND" } } */+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-2.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-2.c+index 75fabcd988c..b2fb6e1bcd2 100644+--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-2.c++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-2.c+@@ -12,8 +12,8 @@ male_indirect_jump (long offset)+ }+ + /* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { ! x32 } } } } */+-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" { target { ! x32 } } } } */+-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk\.(r|e)ax" { target x32 } } } */++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" { target { ! x32 } } } } */++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk_(r|e)ax" { target x32 } } } */+ /* { dg-final { scan-assembler-not {\t(lfence|pause)} } } */+ /* { dg-final { scan-assembler-not "jmp\[ \t\]*\.LIND" } } */+ /* { dg-final { scan-assembler-not "call\[ \t\]*\.LIND" } } */+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-3.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-3.c+index 1d9dff2e834..9c84547cd7c 100644+--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-3.c++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-3.c+@@ -13,8 +13,8 @@ male_indirect_jump (long offset)+ }+ + /* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { ! x32 } } } } */+-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" { target { ! x32 } } } } */++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" { target { ! x32 } } } } */+ /* { dg-final { scan-assembler-times "jmp\[ \t\]*\.LIND" 1 { target { ! x32 } } } } */+ /* { dg-final { scan-assembler-times "call\[ \t\]*\.LIND" 1 { target { ! x32 } } } } */+-/* { dg-final { scan-assembler "call\[ \t\]*__x86.indirect_thunk\.(r|e)ax" { target x32 } } } */++/* { dg-final { scan-assembler "call\[ \t\]*__x86_indirect_thunk_(r|e)ax" { target x32 } } } */+ /* { dg-final { scan-assembler-not {\t(lfence|pause)} } } */+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-4.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-4.c+index 5b464155e38..457849564bb 100644+--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-4.c++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-4.c+@@ -13,8 +13,8 @@ male_indirect_jump (long offset)+ }+ + /* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { ! x32 } } } } */+-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" { target { ! x32 } } } } */++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" { target { ! x32 } } } } */+ /* { dg-final { scan-assembler-times "jmp\[ \t\]*\.LIND" 1 { target { ! x32 } } } } */+ /* { dg-final { scan-assembler-times "call\[ \t\]*\.LIND" 1 { target { ! x32 } } } } */+-/* { dg-final { scan-assembler "call\[ \t\]*__x86.indirect_thunk\.(r|e)ax" { target x32 } } } */++/* { dg-final { scan-assembler "call\[ \t\]*__x86_indirect_thunk_(r|e)ax" { target x32 } } } */+ /* { dg-final { scan-assembler-not {\t(lfence|pause)} } } */+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-5.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-5.c+index 55ce91c73ec..5c07e02df6a 100644+--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-5.c++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-5.c+@@ -10,7 +10,7 @@ foo (void)+ }+ + /* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*bar@GOT" } } */+-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" } } */++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" } } */+ /* { dg-final { scan-assembler-not {\t(lfence|pause)} } } */+ /* { dg-final { scan-assembler-not "jmp\[ \t\]*\.LIND" } } */+ /* { dg-final { scan-assembler-not "call\[ \t\]*\.LIND" } } */+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-6.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-6.c+index 06180e7bee9..3eb440693a0 100644+--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-6.c++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-6.c+@@ -13,5 +13,5 @@ foo (void)+ /* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*bar@GOT" } } */+ /* { dg-final { scan-assembler-times "jmp\[ \t\]*\.LIND" 1 } } */+ /* { dg-final { scan-assembler-times "call\[ \t\]*\.LIND" 1 } } */+-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" } } */++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" } } */+ /* { dg-final { scan-assembler-not {\t(lfence|pause)} } } */+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-7.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-7.c+index 790a05cec3e..d4747ea0764 100644+--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-7.c++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-7.c+@@ -36,8 +36,8 @@ bar (int i)+ }+ + /* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*\.L\[0-9\]+\\(,%" { target { ! x32 } } } } */+-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" { target { ! x32 } } } } */+-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk\.(r|e)ax" { target x32 } } } */++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" { target { ! x32 } } } } */++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk_(r|e)ax" { target x32 } } } */+ /* { dg-final { scan-assembler-not {\t(lfence|pause)} } } */+ /* { dg-final { scan-assembler-not "jmp\[ \t\]*\.LIND" } } */+ /* { dg-final { scan-assembler-not "call\[ \t\]*\.LIND" } } */+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-1.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-1.c+index 1ce8ca5aff1..f7fad345ca4 100644+--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-1.c++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-1.c+@@ -14,5 +14,5 @@ male_indirect_jump (long offset)+ /* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { ! x32 } } } } */+ /* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */+ /* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */+-/* { dg-final { scan-assembler-not "__x86.indirect_thunk" } } */++/* { dg-final { scan-assembler-not "__x86_indirect_thunk" } } */+ /* { dg-final { scan-assembler-not "pushq\[ \t\]%rax" { target x32 } } } */+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-2.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-2.c+index f6b71e868bd..91388544a20 100644+--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-2.c++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-2.c+@@ -14,5 +14,5 @@ male_indirect_jump (long offset)+ /* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { ! x32 } } } } */+ /* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */+ /* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */+-/* { dg-final { scan-assembler-not "__x86.indirect_thunk" } } */++/* { dg-final { scan-assembler-not "__x86_indirect_thunk" } } */+ /* { dg-final { scan-assembler-not "pushq\[ \t\]%rax" { target x32 } } } */+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-3.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-3.c+index 84a09d4d0d6..69f03e6472e 100644+--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-3.c++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-3.c+@@ -15,5 +15,5 @@ male_indirect_jump (long offset)+ /* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { ! x32 } } } } */+ /* { dg-final { scan-assembler-times "jmp\[ \t\]*\.LIND" 2 } } */+ /* { dg-final { scan-assembler-times "call\[ \t\]*\.LIND" 2 } } */+-/* { dg-final { scan-assembler-not "__x86.indirect_thunk" } } */++/* { dg-final { scan-assembler-not "__x86_indirect_thunk" } } */+ /* { dg-final { scan-assembler-not "pushq\[ \t\]%rax" { target x32 } } } */+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-4.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-4.c+index cfe3aefa0bf..226b776abcf 100644+--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-4.c++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-4.c+@@ -15,5 +15,5 @@ male_indirect_jump (long offset)+ /* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { ! x32 } } } } */+ /* { dg-final { scan-assembler-times "jmp\[ \t\]*\.LIND" 2 } } */+ /* { dg-final { scan-assembler-times "call\[ \t\]*\.LIND" 2 } } */+-/* { dg-final { scan-assembler-not "__x86.indirect_thunk" } } */++/* { dg-final { scan-assembler-not "__x86_indirect_thunk" } } */+ /* { dg-final { scan-assembler-not "pushq\[ \t\]%rax" { target x32 } } } */+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-5.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-5.c+index 6411454243f..b9120017c10 100644+--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-5.c++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-5.c+@@ -12,4 +12,4 @@ foo (void)+ /* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*bar@GOT" } } */+ /* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */+ /* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */+-/* { dg-final { scan-assembler-not "__x86.indirect_thunk" } } */++/* { dg-final { scan-assembler-not "__x86_indirect_thunk" } } */+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-6.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-6.c+index d4297fe21c4..fbd6f9ec457 100644+--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-6.c++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-6.c+@@ -13,4 +13,4 @@ foo (void)+ /* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*bar@GOT" } } */+ /* { dg-final { scan-assembler-times "jmp\[ \t\]*\.LIND" 2 } } */+ /* { dg-final { scan-assembler-times "call\[ \t\]*\.LIND" 2 } } */+-/* { dg-final { scan-assembler-not "__x86.indirect_thunk" } } */++/* { dg-final { scan-assembler-not "__x86_indirect_thunk" } } */+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-7.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-7.c+index eb318efdf4d..2553c56f97f 100644+--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-7.c++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-7.c+@@ -39,4 +39,4 @@ bar (int i)+ /* { dg-final { scan-assembler-not "pushq\[ \t\]%rax" { target x32 } } } */+ /* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */+ /* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */+-/* { dg-final { scan-assembler-not "__x86.indirect_thunk" } } */++/* { dg-final { scan-assembler-not "__x86_indirect_thunk" } } */+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-loop-1.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-loop-1.c+index 605e32bb584..c266ca6f2da 100644+--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-loop-1.c++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-loop-1.c+@@ -12,8 +12,8 @@ male_indirect_jump (long offset)+ }+ + /* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { ! x32 } } } } */+-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" { target { ! x32 } } } } */+-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk\.(r|e)ax" { target x32 } } } */++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" { target { ! x32 } } } } */++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk_(r|e)ax" { target x32 } } } */+ /* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */+ /* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */+ /* { dg-final { scan-assembler {\tpause} } } */+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-loop-2.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-loop-2.c+index dd7a7b60621..f7c1cf6c45a 100644+--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-loop-2.c++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-loop-2.c+@@ -12,8 +12,8 @@ male_indirect_jump (long offset)+ }+ + /* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { ! x32 } } } } */+-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" { target { ! x32 } } } } */+-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk\.(r|e)ax" { target x32 } } } */++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" { target { ! x32 } } } } */++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk_(r|e)ax" { target x32 } } } */+ /* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */+ /* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */+ /* { dg-final { scan-assembler {\tnop} } } */+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-loop-3.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-loop-3.c+index 338f22c373c..ef5c4b84312 100644+--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-loop-3.c++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-loop-3.c+@@ -12,8 +12,8 @@ male_indirect_jump (long offset)+ }+ + /* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { ! x32 } } } } */+-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" { target { ! x32 } } } } */+-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk\.(r|e)ax" { target x32 } } } */++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" { target { ! x32 } } } } */++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk_(r|e)ax" { target x32 } } } */+ /* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */+ /* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */+ /* { dg-final { scan-assembler {\tlfence} } } */+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-loop-4.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-loop-4.c+index 3b083ee30a8..941fcdaffb1 100644+--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-loop-4.c++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-loop-4.c+@@ -15,5 +15,5 @@ male_indirect_jump (long offset)+ /* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */+ /* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */+ /* { dg-final { scan-assembler {\tpause} } } */+-/* { dg-final { scan-assembler-not "__x86.indirect_thunk" } } */++/* { dg-final { scan-assembler-not "__x86_indirect_thunk" } } */+ /* { dg-final { scan-assembler-not "pushq\[ \t\]%rax" { target x32 } } } */+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-loop-5.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-loop-5.c+index 31a9a81a911..0c5ace58358 100644+--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-loop-5.c++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-loop-5.c+@@ -12,8 +12,8 @@ male_indirect_jump (long offset)+ }+ + /* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { ! x32 } } } } */+-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" { target { ! x32 } } } } */+-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk\.(r|e)ax" { target x32 } } } */++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" { target { ! x32 } } } } */++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk_(r|e)ax" { target x32 } } } */+ /* { dg-final { scan-assembler-not {\t(lfence|pause|nop)} } } */+ /* { dg-final { scan-assembler-not "jmp\[ \t\]*\.LIND" } } */+ /* { dg-final { scan-assembler-not "call\[ \t\]*\.LIND" } } */+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-register-1.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-register-1.c+index ef493a05bbf..1a28abb4604 100644+--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-register-1.c++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-register-1.c+@@ -11,12 +11,12 @@ male_indirect_jump (long offset)+ dispatch(offset);+ }+ +-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk\.(r|e)ax" } } */++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk_(r|e)ax" } } */+ /* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */+ /* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */+ /* { dg-final { scan-assembler "mov\[ \t\](%eax|%rax), \\((%esp|%rsp)\\)" } } */+ /* { dg-final { scan-assembler {\tlfence} } } */+ /* { dg-final { scan-assembler-not "push(?:l|q)\[ \t\]*_?dispatch" } } */+ /* { dg-final { scan-assembler-not "pushq\[ \t\]%rax" } } */+-/* { dg-final { scan-assembler-not "__x86.indirect_thunk\n" } } */+-/* { dg-final { scan-assembler-not "__x86.indirect_thunk_bnd\n" } } */++/* { dg-final { scan-assembler-not "__x86_indirect_thunk_" } } */++/* { dg-final { scan-assembler-not "__x86_indirect_thunk_bnd\n" } } */+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-register-2.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-register-2.c+index 89fc8e6e6c4..428d6f9e986 100644+--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-register-2.c++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-register-2.c+@@ -17,4 +17,4 @@ male_indirect_jump (long offset)+ /* { dg-final { scan-assembler {\tlfence} } } */+ /* { dg-final { scan-assembler-not "push(?:l|q)\[ \t\]*_?dispatch" } } */+ /* { dg-final { scan-assembler-not "pushq\[ \t\]%rax" } } */+-/* { dg-final { scan-assembler-not "__x86.indirect_thunk" } } */++/* { dg-final { scan-assembler-not "__x86_indirect_thunk" } } */+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-register-3.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-register-3.c+index 31af7ac05b8..28dcdcf2855 100644+--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-register-3.c++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-register-3.c+@@ -11,7 +11,7 @@ male_indirect_jump (long offset)+ dispatch(offset);+ }+ +-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk\.(r|e)ax" } } */++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk_(r|e)ax" } } */+ /* { dg-final { scan-assembler-not "push(?:l|q)\[ \t\]*_?dispatch" } } */+ /* { dg-final { scan-assembler-not "pushq\[ \t\]%rax" } } */+ /* { dg-final { scan-assembler-not {\t(lfence|pause|nop)} } } */+diff --git a/gcc/testsuite/gcc.target/i386/ret-thunk-1.c b/gcc/testsuite/gcc.target/i386/ret-thunk-1.c+index 406956f48e5..07f382c21b2 100644+--- a/gcc/testsuite/gcc.target/i386/ret-thunk-1.c++++ b/gcc/testsuite/gcc.target/i386/ret-thunk-1.c+@@ -6,7 +6,7 @@ foo (void)+ {+ }+ +-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.return_thunk" } } */++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_return_thunk" } } */+ /* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */+ /* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */+ /* { dg-final { scan-assembler {\tlfence} } } */+diff --git a/gcc/testsuite/gcc.target/i386/ret-thunk-10.c b/gcc/testsuite/gcc.target/i386/ret-thunk-10.c+index 74f37ee9a62..da8029bad49 100644+--- a/gcc/testsuite/gcc.target/i386/ret-thunk-10.c++++ b/gcc/testsuite/gcc.target/i386/ret-thunk-10.c+@@ -12,11 +12,11 @@ foo (void)+ + /* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */+ /* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */+-/* { dg-final { scan-assembler-not "jmp\[ \t\]*__x86.return_thunk" } } */++/* { dg-final { scan-assembler-not "jmp\[ \t\]*__x86_return_thunk" } } */+ /* { dg-final { scan-assembler-times {\tlfence} 2 } } */+ /* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?bar" { target { ! x32 } } } } */+-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" { target { ! x32 } } } } */+-/* { dg-final { scan-assembler "__x86.indirect_thunk:" { target { ! x32 } } } } */+-/* { dg-final { scan-assembler "call\[ \t\]*__x86.indirect_thunk\.(r|e)ax" { target { x32 } } } } */+-/* { dg-final { scan-assembler "__x86.indirect_thunk\.(r|e)ax:" { target { x32 } } } } */++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" { target { ! x32 } } } } */++/* { dg-final { scan-assembler "__x86_indirect_thunk:" { target { ! x32 } } } } */++/* { dg-final { scan-assembler "call\[ \t\]*__x86_indirect_thunk_(r|e)ax" { target { x32 } } } } */++/* { dg-final { scan-assembler "__x86_indirect_thunk_(r|e)ax:" { target { x32 } } } } */+ /* { dg-final { scan-assembler-not "pushq\[ \t\]%rax" { target x32 } } } */+diff --git a/gcc/testsuite/gcc.target/i386/ret-thunk-11.c b/gcc/testsuite/gcc.target/i386/ret-thunk-11.c+index 0a52318e86b..6964997871d 100644+--- a/gcc/testsuite/gcc.target/i386/ret-thunk-11.c++++ b/gcc/testsuite/gcc.target/i386/ret-thunk-11.c+@@ -10,13 +10,13 @@ foo (void)+ return 0;+ }+ +-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.return_thunk" } } */++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_return_thunk" } } */+ /* { dg-final { scan-assembler-times {\tlfence} 1 } } */+ /* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */+ /* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */+ /* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?bar" { target { ! x32 } } } } */+-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" { target { ! x32 } } } } */+-/* { dg-final { scan-assembler "__x86.indirect_thunk:" { target { ! x32 } } } } */+-/* { dg-final { scan-assembler "call\[ \t\]*__x86.indirect_thunk\.(r|e)ax" { target { x32 } } } } */+-/* { dg-final { scan-assembler "__x86.indirect_thunk\.(r|e)ax:" { target { x32 } } } } */++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" { target { ! x32 } } } } */++/* { dg-final { scan-assembler "__x86_indirect_thunk:" { target { ! x32 } } } } */++/* { dg-final { scan-assembler "call\[ \t\]*__x86_indirect_thunk_(r|e)ax" { target { x32 } } } } */++/* { dg-final { scan-assembler "__x86_indirect_thunk_(r|e)ax:" { target { x32 } } } } */+ /* { dg-final { scan-assembler-not "pushq\[ \t\]%rax" { target x32 } } } */+diff --git a/gcc/testsuite/gcc.target/i386/ret-thunk-12.c b/gcc/testsuite/gcc.target/i386/ret-thunk-12.c+index d2f775490ea..ff0234bd17d 100644+--- a/gcc/testsuite/gcc.target/i386/ret-thunk-12.c++++ b/gcc/testsuite/gcc.target/i386/ret-thunk-12.c+@@ -10,12 +10,12 @@ foo (void)+ return 0;+ }+ +-/* { dg-final { scan-assembler-not "jmp\[ \t\]*__x86.return_thunk" } } */++/* { dg-final { scan-assembler-not "jmp\[ \t\]*__x86_return_thunk" } } */+ /* { dg-final { scan-assembler-times {\tlfence} 1 } } */+ /* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */+ /* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */+-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" { target { ! x32 } } } } */+-/* { dg-final { scan-assembler "__x86.indirect_thunk:" { target { ! x32 } } } } */+-/* { dg-final { scan-assembler "call\[ \t\]*__x86.indirect_thunk\.(r|e)ax" { target { x32 } } } } */+-/* { dg-final { scan-assembler "__x86.indirect_thunk\.(r|e)ax:" { target { x32 } } } } */++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" { target { ! x32 } } } } */++/* { dg-final { scan-assembler "__x86_indirect_thunk:" { target { ! x32 } } } } */++/* { dg-final { scan-assembler "call\[ \t\]*__x86_indirect_thunk_(r|e)ax" { target { x32 } } } } */++/* { dg-final { scan-assembler "__x86_indirect_thunk_(r|e)ax:" { target { x32 } } } } */+ /* { dg-final { scan-assembler-not "pushq\[ \t\]%rax" { target x32 } } } */+diff --git a/gcc/testsuite/gcc.target/i386/ret-thunk-13.c b/gcc/testsuite/gcc.target/i386/ret-thunk-13.c+index 82d46165f3e..a5b16472051 100644+--- a/gcc/testsuite/gcc.target/i386/ret-thunk-13.c++++ b/gcc/testsuite/gcc.target/i386/ret-thunk-13.c+@@ -11,11 +11,11 @@ foo (void)+ return 0;+ }+ +-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.return_thunk" } } */++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_return_thunk" } } */+ /* { dg-final { scan-assembler-times {\tlfence} 2 } } */+ /* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?bar" { target { ! x32 } } } } */+ /* { dg-final { scan-assembler-times "jmp\[ \t\]*\.LIND" 3 } } */+ /* { dg-final { scan-assembler-times "call\[ \t\]*\.LIND" 3 } } */+-/* { dg-final { scan-assembler-not "jmp\[ \t\]*__x86.indirect_thunk" } } */+-/* { dg-final { scan-assembler-not "call\[ \t\]*__x86.indirect_thunk\.(r|e)ax" { target { x32 } } } } */++/* { dg-final { scan-assembler-not "jmp\[ \t\]*__x86_indirect_thunk" } } */++/* { dg-final { scan-assembler-not "call\[ \t\]*__x86_indirect_thunk_(r|e)ax" { target { x32 } } } } */+ /* { dg-final { scan-assembler-not "pushq\[ \t\]%rax" { target x32 } } } */+diff --git a/gcc/testsuite/gcc.target/i386/ret-thunk-14.c b/gcc/testsuite/gcc.target/i386/ret-thunk-14.c+index 6711eb27fa8..219d71548bf 100644+--- a/gcc/testsuite/gcc.target/i386/ret-thunk-14.c++++ b/gcc/testsuite/gcc.target/i386/ret-thunk-14.c+@@ -12,10 +12,10 @@ foo (void)+ }+ + /* { dg-final { scan-assembler-times {\tlfence} 1 } } */+-/* { dg-final { scan-assembler-not "jmp\[ \t\]*__x86.return_thunk" } } */++/* { dg-final { scan-assembler-not "jmp\[ \t\]*__x86_return_thunk" } } */+ /* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */+ /* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */+ /* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?bar" { target { ! x32 } } } } */+-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" { target { ! x32 } } } } */+-/* { dg-final { scan-assembler "call\[ \t\]*__x86.indirect_thunk\.(r|e)ax" { target { x32 } } } } */++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" { target { ! x32 } } } } */++/* { dg-final { scan-assembler "call\[ \t\]*__x86_indirect_thunk_(r|e)ax" { target { x32 } } } } */+ /* { dg-final { scan-assembler-not "pushq\[ \t\]%rax" { target x32 } } } */+diff --git a/gcc/testsuite/gcc.target/i386/ret-thunk-15.c b/gcc/testsuite/gcc.target/i386/ret-thunk-15.c+index 37758c33371..bad6b16820d 100644+--- a/gcc/testsuite/gcc.target/i386/ret-thunk-15.c++++ b/gcc/testsuite/gcc.target/i386/ret-thunk-15.c+@@ -11,11 +11,11 @@ foo (void)+ return 0;+ }+ +-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.return_thunk" } } */++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_return_thunk" } } */+ /* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */+ /* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */+ /* { dg-final { scan-assembler-times {\tlfence} 1 } } */+ /* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?bar" { target { ! x32 } } } } */+-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" { target { ! x32 } } } } */+-/* { dg-final { scan-assembler "call\[ \t\]*__x86.indirect_thunk\.(r|e)ax" { target x32 } } } */++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" { target { ! x32 } } } } */++/* { dg-final { scan-assembler "call\[ \t\]*__x86_indirect_thunk_(r|e)ax" { target x32 } } } */+ /* { dg-final { scan-assembler-not "pushq\[ \t\]%rax" { target x32 } } } */+diff --git a/gcc/testsuite/gcc.target/i386/ret-thunk-16.c b/gcc/testsuite/gcc.target/i386/ret-thunk-16.c+index cf3920563e0..173fe243d7b 100644+--- a/gcc/testsuite/gcc.target/i386/ret-thunk-16.c++++ b/gcc/testsuite/gcc.target/i386/ret-thunk-16.c+@@ -11,8 +11,8 @@ foo (void)+ return 0;+ }+ +-/* { dg-final { scan-assembler-not "__x86.indirect_thunk" } } */+-/* { dg-final { scan-assembler-not "__x86.return_thunk" } } */++/* { dg-final { scan-assembler-not "__x86_indirect_thunk" } } */++/* { dg-final { scan-assembler-not "__x86_return_thunk" } } */+ /* { dg-final { scan-assembler-not {\tlfence} } } */+ /* { dg-final { scan-assembler-not "jmp\[ \t\]*\.LIND" } } */+ /* { dg-final { scan-assembler-not "call\[ \t\]*\.LIND" } } */+diff --git a/gcc/testsuite/gcc.target/i386/ret-thunk-2.c b/gcc/testsuite/gcc.target/i386/ret-thunk-2.c+index 190947cc2ca..5516813a290 100644+--- a/gcc/testsuite/gcc.target/i386/ret-thunk-2.c++++ b/gcc/testsuite/gcc.target/i386/ret-thunk-2.c+@@ -9,4 +9,4 @@ foo (void)+ /* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */+ /* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */+ /* { dg-final { scan-assembler {\tlfence} } } */+-/* { dg-final { scan-assembler-not "jmp\[ \t\]*__x86.return_thunk" } } */++/* { dg-final { scan-assembler-not "jmp\[ \t\]*__x86_return_thunk" } } */+diff --git a/gcc/testsuite/gcc.target/i386/ret-thunk-3.c b/gcc/testsuite/gcc.target/i386/ret-thunk-3.c+index d71de3ac520..9f1ade857ef 100644+--- a/gcc/testsuite/gcc.target/i386/ret-thunk-3.c++++ b/gcc/testsuite/gcc.target/i386/ret-thunk-3.c+@@ -6,7 +6,7 @@ foo (void)+ {+ }+ +-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.return_thunk" } } */++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_return_thunk" } } */+ /* { dg-final { scan-assembler-not {\tlfence} } } */+ /* { dg-final { scan-assembler-not "jmp\[ \t\]*\.LIND" } } */+ /* { dg-final { scan-assembler-not "call\[ \t\]*\.LIND" } } */+diff --git a/gcc/testsuite/gcc.target/i386/ret-thunk-4.c b/gcc/testsuite/gcc.target/i386/ret-thunk-4.c+index 68c22122f0d..abecde0a550 100644+--- a/gcc/testsuite/gcc.target/i386/ret-thunk-4.c++++ b/gcc/testsuite/gcc.target/i386/ret-thunk-4.c+@@ -6,7 +6,7 @@ foo (void)+ {+ }+ +-/* { dg-final { scan-assembler-not "jmp\[ \t\]*__x86.return_thunk" } } */++/* { dg-final { scan-assembler-not "jmp\[ \t\]*__x86_return_thunk" } } */+ /* { dg-final { scan-assembler-not {\tlfence} } } */+ /* { dg-final { scan-assembler-not "jmp\[ \t\]*\.LIND" } } */+ /* { dg-final { scan-assembler-not "call\[ \t\]*\.LIND" } } */+diff --git a/gcc/testsuite/gcc.target/i386/ret-thunk-5.c b/gcc/testsuite/gcc.target/i386/ret-thunk-5.c+index 28c576e2267..3b51a9931db 100644+--- a/gcc/testsuite/gcc.target/i386/ret-thunk-5.c++++ b/gcc/testsuite/gcc.target/i386/ret-thunk-5.c+@@ -8,7 +8,7 @@ foo (void)+ {+ }+ +-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.return_thunk" } } */++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_return_thunk" } } */+ /* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */+ /* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */+ /* { dg-final { scan-assembler {\tlfence} } } */+diff --git a/gcc/testsuite/gcc.target/i386/ret-thunk-6.c b/gcc/testsuite/gcc.target/i386/ret-thunk-6.c+index 10ad40b9c26..52160e0ee77 100644+--- a/gcc/testsuite/gcc.target/i386/ret-thunk-6.c++++ b/gcc/testsuite/gcc.target/i386/ret-thunk-6.c+@@ -10,4 +10,4 @@ foo (void)+ /* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */+ /* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */+ /* { dg-final { scan-assembler {\tlfence} } } */+-/* { dg-final { scan-assembler-not "jmp\[ \t\]*__x86.return_thunk" } } */++/* { dg-final { scan-assembler-not "jmp\[ \t\]*__x86_return_thunk" } } */+diff --git a/gcc/testsuite/gcc.target/i386/ret-thunk-7.c b/gcc/testsuite/gcc.target/i386/ret-thunk-7.c+index 7ac0beaa73e..65819c2ab76 100644+--- a/gcc/testsuite/gcc.target/i386/ret-thunk-7.c++++ b/gcc/testsuite/gcc.target/i386/ret-thunk-7.c+@@ -7,7 +7,7 @@ foo (void)+ {+ }+ +-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.return_thunk" } } */++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_return_thunk" } } */+ /* { dg-final { scan-assembler-not {\tlfence} } } */+ /* { dg-final { scan-assembler-not "jmp\[ \t\]*\.LIND" } } */+ /* { dg-final { scan-assembler-not "call\[ \t\]*\.LIND" } } */+diff --git a/gcc/testsuite/gcc.target/i386/ret-thunk-8.c b/gcc/testsuite/gcc.target/i386/ret-thunk-8.c+index 777ab7c8088..a6a1bbc054b 100644+--- a/gcc/testsuite/gcc.target/i386/ret-thunk-8.c++++ b/gcc/testsuite/gcc.target/i386/ret-thunk-8.c+@@ -8,7 +8,7 @@ foo (void)+ {+ }+ +-/* { dg-final { scan-assembler-not "jmp\[ \t\]*__x86.return_thunk" } } */++/* { dg-final { scan-assembler-not "jmp\[ \t\]*__x86_return_thunk" } } */+ /* { dg-final { scan-assembler-not {\tlfence} } } */+ /* { dg-final { scan-assembler-not "jmp\[ \t\]*\.LIND" } } */+ /* { dg-final { scan-assembler-not "call\[ \t\]*\.LIND" } } */+diff --git a/gcc/testsuite/gcc.target/i386/ret-thunk-9.c b/gcc/testsuite/gcc.target/i386/ret-thunk-9.c+index 70771ea35d7..21a0e6bde3d 100644+--- a/gcc/testsuite/gcc.target/i386/ret-thunk-9.c++++ b/gcc/testsuite/gcc.target/i386/ret-thunk-9.c+@@ -10,14 +10,14 @@ foo (void)+ return 0;+ }+ +-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.return_thunk" } } */+-/* { dg-final { scan-assembler-not "__x86.return_thunk:" } } */++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_return_thunk" } } */++/* { dg-final { scan-assembler-not "__x86_return_thunk:" } } */+ /* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */+ /* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */+-/* { dg-final { scan-assembler "__x86.indirect_thunk:" } } */++/* { dg-final { scan-assembler "__x86_indirect_thunk:" } } */+ /* { dg-final { scan-assembler-times {\tlfence} 1 { target { ! x32 } } } } */+ /* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?bar" { target { ! x32 } } } } */+-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" { target { ! x32 } } } } */++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" { target { ! x32 } } } } */+ /* { dg-final { scan-assembler-times {\tlfence} 2 { target { x32 } } } } */+-/* { dg-final { scan-assembler "call\[ \t\]*__x86.indirect_thunk\.(r|e)ax" { target { x32 } } } } */++/* { dg-final { scan-assembler "call\[ \t\]*__x86_indirect_thunk_(r|e)ax" { target { x32 } } } } */+ /* { dg-final { scan-assembler-not "pushq\[ \t\]%rax" { target x32 } } } */+-- +2.15.1+diff --git a/gnu/packages/patches/gcc-retpoline-Use-__x86.indirect_thunk.reg-for-indirect-branch-via.patch b/gnu/packages/patches/gcc-retpoline-Use-__x86.indirect_thunk.reg-for-indirect-branch-via.patchnew file mode 100644index 000000000..bd6797816--- /dev/null+++ b/gnu/packages/patches/gcc-retpoline-Use-__x86.indirect_thunk.reg-for-indirect-branch-via.patch@@ -0,0 +1,623 @@+'Retpoline' mitigation technique for Spectre (branch target injection)+[CVE-2017-5715]:++https://security.googleblog.com/2018/01/more-details-about-mitigations-for-cpu_4.html+https://support.google.com/faqs/answer/7625886+https://spectreattack.com/+https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2017-5715++Patch copied from the 'retpoline-20180107' branch of upstream source repository+(please add new / update existing patches when new 'retpoline-xxxxxxxx' branch+appears):++http://git.infradead.org/users/dwmw2/gcc-retpoline.git++From e4e33b44a49eaa102806589ce12f021ab6a1e5f1 Mon Sep 17 00:00:00 2001+From: "H.J. Lu" <hjl.tools@gmail.com>+Date: Wed, 13 Dec 2017 12:59:50 -0800+Subject: [PATCH 09/17] Use __x86.indirect_thunk.reg for indirect branch via+ register++---+ gcc/config/i386/i386.c | 137 +++++++++++++++++----+ gcc/testsuite/gcc.target/i386/indirect-thunk-1.c | 4 +-+ gcc/testsuite/gcc.target/i386/indirect-thunk-2.c | 4 +-+ gcc/testsuite/gcc.target/i386/indirect-thunk-3.c | 8 +-+ gcc/testsuite/gcc.target/i386/indirect-thunk-4.c | 8 +-+ gcc/testsuite/gcc.target/i386/indirect-thunk-7.c | 4 +-+ .../gcc.target/i386/indirect-thunk-attr-1.c | 4 +-+ .../gcc.target/i386/indirect-thunk-attr-2.c | 4 +-+ .../gcc.target/i386/indirect-thunk-attr-3.c | 2 +-+ .../gcc.target/i386/indirect-thunk-attr-4.c | 2 +-+ .../gcc.target/i386/indirect-thunk-attr-5.c | 8 +-+ .../gcc.target/i386/indirect-thunk-attr-6.c | 8 +-+ .../gcc.target/i386/indirect-thunk-attr-7.c | 2 +-+ .../gcc.target/i386/indirect-thunk-extern-1.c | 4 +-+ .../gcc.target/i386/indirect-thunk-extern-2.c | 4 +-+ .../gcc.target/i386/indirect-thunk-extern-3.c | 8 +-+ .../gcc.target/i386/indirect-thunk-extern-4.c | 8 +-+ .../gcc.target/i386/indirect-thunk-extern-7.c | 4 +-+ .../gcc.target/i386/indirect-thunk-inline-1.c | 2 +-+ .../gcc.target/i386/indirect-thunk-inline-2.c | 2 +-+ .../gcc.target/i386/indirect-thunk-inline-3.c | 2 +-+ .../gcc.target/i386/indirect-thunk-inline-4.c | 2 +-+ .../gcc.target/i386/indirect-thunk-inline-7.c | 2 +-+ 23 files changed, 158 insertions(+), 75 deletions(-)++diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c+index 5e66af08066..590729b3f87 100644+--- a/gcc/config/i386/i386.c++++ b/gcc/config/i386/i386.c+@@ -11948,6 +11948,9 @@ static int indirectlabelno;+ static bool indirect_thunk_needed = false;+ static bool indirect_thunk_bnd_needed = false;+ ++static int indirect_thunks_used;++static int indirect_thunks_bnd_used;+++ #ifndef INDIRECT_LABEL+ # define INDIRECT_LABEL "LIND"+ #endif+@@ -11955,24 +11958,45 @@ static bool indirect_thunk_bnd_needed = false;+ /* Fills in the label name that should be used for the indirect thunk. */+ + static void+-indirect_thunk_name (char name[32], bool need_bnd_p)++indirect_thunk_name (char name[32], int regno, bool need_bnd_p)+ {+ if (USE_HIDDEN_LINKONCE)+ {+ const char *bnd = need_bnd_p ? "_bnd" : "";+- sprintf (name, "__x86.indirect_thunk%s", bnd);++ if (regno >= 0)++ {++ const char *reg_prefix;++ if (LEGACY_INT_REGNO_P (regno))++ reg_prefix = TARGET_64BIT ? "r" : "e";++ else++ reg_prefix = "";++ sprintf (name, "__x86.indirect_thunk%s.%s%s",++ bnd, reg_prefix, reg_names[regno]);++ }++ else++ sprintf (name, "__x86.indirect_thunk%s", bnd);+ }+ else+ {+- if (need_bnd_p)+- ASM_GENERATE_INTERNAL_LABEL (name, "LITB", 0);++ if (regno >= 0)++ {++ if (need_bnd_p)++ ASM_GENERATE_INTERNAL_LABEL (name, "LITBR", regno);++ else++ ASM_GENERATE_INTERNAL_LABEL (name, "LITR", regno);++ }+ else+- ASM_GENERATE_INTERNAL_LABEL (name, "LIT", 0);++ {++ if (need_bnd_p)++ ASM_GENERATE_INTERNAL_LABEL (name, "LITB", 0);++ else++ ASM_GENERATE_INTERNAL_LABEL (name, "LIT", 0);++ }+ }+ }+ + static void+-output_indirect_thunk (bool need_bnd_p)++output_indirect_thunk (bool need_bnd_p, int regno)+ {+ char indirectlabel1[32];+ char indirectlabel2[32];+@@ -12002,11 +12026,22 @@ output_indirect_thunk (bool need_bnd_p)+ + ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, indirectlabel2);+ +- /* LEA. */+- rtx xops[2];+- xops[0] = stack_pointer_rtx;+- xops[1] = plus_constant (Pmode, stack_pointer_rtx, UNITS_PER_WORD);+- output_asm_insn ("lea\t{%E1, %0|%0, %E1}", xops);++ if (regno >= 0)++ {++ /* MOV. */++ rtx xops[2];++ xops[0] = gen_rtx_MEM (word_mode, stack_pointer_rtx);++ xops[1] = gen_rtx_REG (word_mode, regno);++ output_asm_insn ("mov\t{%1, %0|%0, %1}", xops);++ }++ else++ {++ /* LEA. */++ rtx xops[2];++ xops[0] = stack_pointer_rtx;++ xops[1] = plus_constant (Pmode, stack_pointer_rtx, UNITS_PER_WORD);++ output_asm_insn ("lea\t{%E1, %0|%0, %E1}", xops);++ }+ + if (need_bnd_p)+ fputs ("\tbnd ret\n", asm_out_file);+@@ -12015,12 +12050,13 @@ output_indirect_thunk (bool need_bnd_p)+ }+ + static void+-output_indirect_thunk_function (bool need_bnd_p)++output_indirect_thunk_function (bool need_bnd_p, int regno)+ {+ char name[32];+ tree decl;+ +- indirect_thunk_name (name, need_bnd_p);++ /* Create __x86.indirect_thunk/__x86.indirect_thunk_bnd. */++ indirect_thunk_name (name, regno, need_bnd_p);+ decl = build_decl (BUILTINS_LOCATION, FUNCTION_DECL,+ get_identifier (name),+ build_function_type_list (void_type_node, NULL_TREE));+@@ -12074,7 +12110,7 @@ output_indirect_thunk_function (bool need_bnd_p)+ /* Make sure unwind info is emitted for the thunk if needed. */+ final_start_function (emit_barrier (), asm_out_file, 1);+ +- output_indirect_thunk (need_bnd_p);++ output_indirect_thunk (need_bnd_p, regno);+ + final_end_function ();+ init_insn_lengths ();+@@ -12110,15 +12146,31 @@ ix86_code_end (void)+ int regno;+ + if (indirect_thunk_needed)+- output_indirect_thunk_function (false);++ output_indirect_thunk_function (false, -1);+ if (indirect_thunk_bnd_needed)+- output_indirect_thunk_function (true);++ output_indirect_thunk_function (true, -1);++++ for (regno = FIRST_REX_INT_REG; regno <= LAST_REX_INT_REG; regno++)++ {++ int i = regno - FIRST_REX_INT_REG + LAST_INT_REG + 1;++ if ((indirect_thunks_used & (1 << i)))++ output_indirect_thunk_function (false, regno);++++ if ((indirect_thunks_bnd_used & (1 << i)))++ output_indirect_thunk_function (true, regno);++ }+ + for (regno = AX_REG; regno <= SP_REG; regno++)+ {+ char name[32];+ tree decl;+ ++ if ((indirect_thunks_used & (1 << regno)))++ output_indirect_thunk_function (false, regno);++++ if ((indirect_thunks_bnd_used & (1 << regno)))++ output_indirect_thunk_function (true, regno);+++ if (!(pic_labels_used & (1 << regno)))+ continue;+ +@@ -28639,17 +28691,37 @@ ix86_output_indirect_branch (rtx call_op, const char *xasm,+ char *thunk_name;+ char push_buf[64];+ bool need_bnd_p = ix86_bnd_prefixed_insn_p (current_output_insn);++ int regno;++++ if (REG_P (call_op))++ regno = REGNO (call_op);++ else++ regno = -1;+ + if (cfun->machine->indirect_branch_type+ != indirect_branch_thunk_inline)+ {+- bool need_thunk+- = cfun->machine->indirect_branch_type == indirect_branch_thunk;+- if (need_bnd_p)+- indirect_thunk_bnd_needed |= need_thunk;+- else+- indirect_thunk_needed |= need_thunk;+- indirect_thunk_name (thunk_name_buf, need_bnd_p);++ if (cfun->machine->indirect_branch_type == indirect_branch_thunk)++ {++ if (regno >= 0)++ {++ int i = regno;++ if (i >= FIRST_REX_INT_REG)++ i -= (FIRST_REX_INT_REG - LAST_INT_REG - 1);++ if (need_bnd_p)++ indirect_thunks_bnd_used |= 1 << i;++ else++ indirect_thunks_used |= 1 << i;++ }++ else++ {++ if (need_bnd_p)++ indirect_thunk_bnd_needed = true;++ else++ indirect_thunk_needed = true;++ }++ }++ indirect_thunk_name (thunk_name_buf, regno, need_bnd_p);+ thunk_name = thunk_name_buf;+ }+ else+@@ -28660,7 +28732,8 @@ ix86_output_indirect_branch (rtx call_op, const char *xasm,+ + if (sibcall_p)+ {+- output_asm_insn (push_buf, &call_op);++ if (regno < 0)++ output_asm_insn (push_buf, &call_op);+ if (thunk_name != NULL)+ {+ if (need_bnd_p)+@@ -28669,10 +28742,19 @@ ix86_output_indirect_branch (rtx call_op, const char *xasm,+ fprintf (asm_out_file, "\tjmp\t%s\n", thunk_name);+ }+ else+- output_indirect_thunk (need_bnd_p);++ output_indirect_thunk (need_bnd_p, regno);+ }+ else+ {++ if (regno >= 0 && thunk_name != NULL)++ {++ if (need_bnd_p)++ fprintf (asm_out_file, "\tbnd call\t%s\n", thunk_name);++ else++ fprintf (asm_out_file, "\tcall\t%s\n", thunk_name);++ return;++ }+++ char indirectlabel1[32];+ char indirectlabel2[32];+ +@@ -28725,7 +28807,8 @@ ix86_output_indirect_branch (rtx call_op, const char *xasm,+ }+ }+ +- output_asm_insn (push_buf, &call_op);++ if (regno < 0)++ output_asm_insn (push_buf, &call_op);+ + if (thunk_name != NULL)+ {+@@ -28735,7 +28818,7 @@ ix86_output_indirect_branch (rtx call_op, const char *xasm,+ fprintf (asm_out_file, "\tjmp\t%s\n", thunk_name);+ }+ else+- output_indirect_thunk (need_bnd_p);++ output_indirect_thunk (need_bnd_p, regno);+ + ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, indirectlabel2);+ +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-1.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-1.c+index d8b6f5a06a5..785e593405f 100644+--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-1.c++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-1.c+@@ -12,8 +12,8 @@ male_indirect_jump (long offset)+ }+ + /* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { ! x32 } } } } */+-/* { dg-final { scan-assembler "pushq\[ \t\]%rax" { target x32 } } } */+-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" } } */++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" { target { ! x32 } } } } */++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk\.(r|e)ax" { target x32 } } } */+ /* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */+ /* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */+ /* { dg-final { scan-assembler {\tlfence} } } */+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-2.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-2.c+index f7d5cb315a8..b69075e6483 100644+--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-2.c++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-2.c+@@ -12,8 +12,8 @@ male_indirect_jump (long offset)+ }+ + /* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { ! x32 } } } } */+-/* { dg-final { scan-assembler "pushq\[ \t\]%rax" { target x32 } } } */+-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" } } */++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" { target { ! x32 } } } } */++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk\.(r|e)ax" { target x32 } } } */+ /* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */+ /* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */+ /* { dg-final { scan-assembler {\tlfence} } } */+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-3.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-3.c+index 736d7cda058..df8109baf55 100644+--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-3.c++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-3.c+@@ -13,8 +13,8 @@ male_indirect_jump (long offset)+ }+ + /* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { ! x32 } } } } */+-/* { dg-final { scan-assembler "pushq\[ \t\]%rax" { target x32 } } } */+-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" } } */+-/* { dg-final { scan-assembler-times "jmp\[ \t\]*\.LIND" 2 } } */+-/* { dg-final { scan-assembler-times "call\[ \t\]*\.LIND" 2 } } */++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" { target { ! x32 } } } } */++/* { dg-final { scan-assembler "call\[ \t\]*__x86.indirect_thunk\.(r|e)ax" { target x32 } } } */++/* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */++/* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */+ /* { dg-final { scan-assembler {\tlfence} } } */+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-4.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-4.c+index cef9b10513e..8f3b9f4d8a5 100644+--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-4.c++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-4.c+@@ -13,8 +13,8 @@ male_indirect_jump (long offset)+ }+ + /* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { ! x32 } } } } */+-/* { dg-final { scan-assembler "pushq\[ \t\]%rax" { target x32 } } } */+-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" } } */+-/* { dg-final { scan-assembler-times "jmp\[ \t\]*\.LIND" 2 } } */+-/* { dg-final { scan-assembler-times "call\[ \t\]*\.LIND" 2 } } */++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" { target { ! x32 } } } } */++/* { dg-final { scan-assembler "call\[ \t\]*__x86.indirect_thunk\.(r|e)ax" { target x32 } } } */++/* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */++/* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */+ /* { dg-final { scan-assembler {\tlfence} } } */+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-7.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-7.c+index ea0fa312f64..f0e1cfe1893 100644+--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-7.c++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-7.c+@@ -36,8 +36,8 @@ bar (int i)+ }+ + /* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*\.L\[0-9\]+\\(,%" { target { ! x32 } } } } */+-/* { dg-final { scan-assembler "pushq\[ \t\]%rax" { target x32 } } } */+-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" } } */++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" { target { ! x32 } } } } */++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk\.(r|e)ax" { target x32 } } } */+ /* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */+ /* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */+ /* { dg-final { scan-assembler {\tlfence} } } */+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-1.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-1.c+index 26550fad4c8..8b88449e625 100644+--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-1.c++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-1.c+@@ -15,8 +15,8 @@ male_indirect_jump (long offset)+ }+ + /* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { ! x32 } } } } */+-/* { dg-final { scan-assembler "pushq\[ \t\]%rax" { target x32 } } } */+-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" } } */++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" { target { ! x32 } } } } */++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk\.(r|e)ax" { target x32 } } } */+ /* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */+ /* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */+ /* { dg-final { scan-assembler {\tlfence} } } */+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-2.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-2.c+index f57bb2a92d6..c69f7bf4f60 100644+--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-2.c++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-2.c+@@ -13,8 +13,8 @@ male_indirect_jump (long offset)+ }+ + /* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { ! x32 } } } } */+-/* { dg-final { scan-assembler "pushq\[ \t\]%rax" { target x32 } } } */+-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" } } */++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" { target { ! x32 } } } } */++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk\.(r|e)ax" { target x32 } } } */+ /* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */+ /* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */+ /* { dg-final { scan-assembler {\tlfence} } } */+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-3.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-3.c+index a3668a6586c..c845099a83e 100644+--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-3.c++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-3.c+@@ -15,7 +15,7 @@ male_indirect_jump (long offset)+ }+ + /* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { ! x32 } } } } */+-/* { dg-final { scan-assembler "pushq\[ \t\]%rax" { target x32 } } } */+ /* { dg-final { scan-assembler-times "jmp\[ \t\]*\.LIND" 2 } } */+ /* { dg-final { scan-assembler-times "call\[ \t\]*\.LIND" 2 } } */+ /* { dg-final { scan-assembler-not "__x86.indirect_thunk" } } */++/* { dg-final { scan-assembler-not "pushq\[ \t\]%rax" { target x32 } } } */+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-4.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-4.c+index a9c4a137dd4..f636f3422fd 100644+--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-4.c++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-4.c+@@ -14,7 +14,7 @@ male_indirect_jump (long offset)+ }+ + /* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { ! x32 } } } } */+-/* { dg-final { scan-assembler "pushq\[ \t\]%rax" { target x32 } } } */+ /* { dg-final { scan-assembler-times "jmp\[ \t\]*\.LIND" 2 } } */+ /* { dg-final { scan-assembler-times "call\[ \t\]*\.LIND" 2 } } */+ /* { dg-final { scan-assembler-not "__x86.indirect_thunk" } } */++/* { dg-final { scan-assembler-not "pushq\[ \t\]%rax" { target x32 } } } */+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-5.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-5.c+index 9582e0c5824..5f1d6a78041 100644+--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-5.c++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-5.c+@@ -15,8 +15,8 @@ male_indirect_jump (long offset)+ }+ + /* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { ! x32 } } } } */+-/* { dg-final { scan-assembler "pushq\[ \t\]%rax" { target x32 } } } */+-/* { dg-final { scan-assembler-times "jmp\[ \t\]*\.LIND" 1 } } */+-/* { dg-final { scan-assembler-times "call\[ \t\]*\.LIND" 1 } } */+-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" } } */++/* { dg-final { scan-assembler-times "jmp\[ \t\]*\.LIND" 1 { target { ! x32 } } } } */++/* { dg-final { scan-assembler-times "call\[ \t\]*\.LIND" 1 { target { ! x32 } } } } */++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" { target { ! x32 } } } } */++/* { dg-final { scan-assembler "call\[ \t\]*__x86.indirect_thunk\.(r|e)ax" { target x32 } } } */+ /* { dg-final { scan-assembler-not {\t(lfence|pause)} } } */+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-6.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-6.c+index 66442cacfe8..56c92da9812 100644+--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-6.c++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-6.c+@@ -14,8 +14,8 @@ male_indirect_jump (long offset)+ }+ + /* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { ! x32 } } } } */+-/* { dg-final { scan-assembler "pushq\[ \t\]%rax" { target x32 } } } */+-/* { dg-final { scan-assembler-times "jmp\[ \t\]*\.LIND" 1 } } */+-/* { dg-final { scan-assembler-times "call\[ \t\]*\.LIND" 1 } } */+-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" } } */++/* { dg-final { scan-assembler-times "jmp\[ \t\]*\.LIND" 1 { target { ! x32 } } } } */++/* { dg-final { scan-assembler-times "call\[ \t\]*\.LIND" 1 { target { ! x32 } } } } */++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" { target { ! x32 } } } } */++/* { dg-final { scan-assembler "call\[ \t\]*__x86.indirect_thunk\.(r|e)ax" { target x32 } } } */+ /* { dg-final { scan-assembler-not {\t(lfence|pause)} } } */+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-7.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-7.c+index 2a19b54cd2e..cfb6f5b234b 100644+--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-7.c++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-7.c+@@ -37,7 +37,7 @@ bar (int i)+ }+ + /* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*\.L\[0-9\]+\\(,%" { target { ! x32 } } } } */+-/* { dg-final { scan-assembler "pushq\[ \t\]%rax" { target x32 } } } */++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk\.(r|e)ax" { target x32 } } } */+ /* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" } } */+ /* { dg-final { scan-assembler-not {\t(lfence|pause)} } } */+ /* { dg-final { scan-assembler-not "jmp\[ \t\]*\.LIND" } } */+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-1.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-1.c+index 0a1f91be988..f1fa0a11922 100644+--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-1.c++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-1.c+@@ -12,8 +12,8 @@ male_indirect_jump (long offset)+ }+ + /* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { ! x32 } } } } */+-/* { dg-final { scan-assembler "pushq\[ \t\]%rax" { target x32 } } } */+-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" } } */++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" { target { ! x32 } } } } */++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk\.(r|e)ax" { target x32 } } } */+ /* { dg-final { scan-assembler-not {\t(lfence|pause)} } } */+ /* { dg-final { scan-assembler-not "jmp\[ \t\]*\.LIND" } } */+ /* { dg-final { scan-assembler-not "call\[ \t\]*\.LIND" } } */+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-2.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-2.c+index 182520ab3dc..d6e078d594b 100644+--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-2.c++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-2.c+@@ -12,8 +12,8 @@ male_indirect_jump (long offset)+ }+ + /* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { ! x32 } } } } */+-/* { dg-final { scan-assembler "pushq\[ \t\]%rax" { target x32 } } } */+-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" } } */++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" { target { ! x32 } } } } */++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk\.(r|e)ax" { target x32 } } } */+ /* { dg-final { scan-assembler-not {\t(lfence|pause)} } } */+ /* { dg-final { scan-assembler-not "jmp\[ \t\]*\.LIND" } } */+ /* { dg-final { scan-assembler-not "call\[ \t\]*\.LIND" } } */+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-3.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-3.c+index 5c31ddc34fd..3bbe2646955 100644+--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-3.c++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-3.c+@@ -13,8 +13,8 @@ male_indirect_jump (long offset)+ }+ + /* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { ! x32 } } } } */+-/* { dg-final { scan-assembler "pushq\[ \t\]%rax" { target x32 } } } */+-/* { dg-final { scan-assembler-times "jmp\[ \t\]*\.LIND" 1 } } */+-/* { dg-final { scan-assembler-times "call\[ \t\]*\.LIND" 1 } } */+-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" } } */++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" { target { ! x32 } } } } */++/* { dg-final { scan-assembler-times "jmp\[ \t\]*\.LIND" 1 { target { ! x32 } } } } */++/* { dg-final { scan-assembler-times "call\[ \t\]*\.LIND" 1 { target { ! x32 } } } } */++/* { dg-final { scan-assembler "call\[ \t\]*__x86.indirect_thunk\.(r|e)ax" { target x32 } } } */+ /* { dg-final { scan-assembler-not {\t(lfence|pause)} } } */+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-4.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-4.c+index f24d0c060f2..596fac599f6 100644+--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-4.c++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-4.c+@@ -13,8 +13,8 @@ male_indirect_jump (long offset)+ }+ + /* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { ! x32 } } } } */+-/* { dg-final { scan-assembler "pushq\[ \t\]%rax" { target x32 } } } */+-/* { dg-final { scan-assembler-times "jmp\[ \t\]*\.LIND" 1 } } */+-/* { dg-final { scan-assembler-times "call\[ \t\]*\.LIND" 1 } } */+-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" } } */++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" { target { ! x32 } } } } */++/* { dg-final { scan-assembler-times "jmp\[ \t\]*\.LIND" 1 { target { ! x32 } } } } */++/* { dg-final { scan-assembler-times "call\[ \t\]*\.LIND" 1 { target { ! x32 } } } } */++/* { dg-final { scan-assembler "call\[ \t\]*__x86.indirect_thunk\.(r|e)ax" { target x32 } } } */+ /* { dg-final { scan-assembler-not {\t(lfence|pause)} } } */+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-7.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-7.c+index 8d39fb6f939..ab367951c45 100644+--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-7.c++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-7.c+@@ -36,8 +36,8 @@ bar (int i)+ }+ + /* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*\.L\[0-9\]+\\(,%" { target { ! x32 } } } } */+-/* { dg-final { scan-assembler "pushq\[ \t\]%rax" { target x32 } } } */+-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" } } */++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" { target { ! x32 } } } } */++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk\.(r|e)ax" { target x32 } } } */+ /* { dg-final { scan-assembler-not {\t(lfence|pause)} } } */+ /* { dg-final { scan-assembler-not "jmp\[ \t\]*\.LIND" } } */+ /* { dg-final { scan-assembler-not "call\[ \t\]*\.LIND" } } */+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-1.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-1.c+index 071e6c89ac7..09b8ad7d879 100644+--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-1.c++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-1.c+@@ -12,7 +12,7 @@ male_indirect_jump (long offset)+ }+ + /* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { ! x32 } } } } */+-/* { dg-final { scan-assembler "pushq\[ \t\]%rax" { target x32 } } } */+ /* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */+ /* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */+ /* { dg-final { scan-assembler-not "__x86.indirect_thunk" } } */++/* { dg-final { scan-assembler-not "pushq\[ \t\]%rax" { target x32 } } } */+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-2.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-2.c+index 804c7ccdba7..1f873758fbe 100644+--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-2.c++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-2.c+@@ -12,7 +12,7 @@ male_indirect_jump (long offset)+ }+ + /* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { ! x32 } } } } */+-/* { dg-final { scan-assembler "pushq\[ \t\]%rax" { target x32 } } } */+ /* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */+ /* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */+ /* { dg-final { scan-assembler-not "__x86.indirect_thunk" } } */++/* { dg-final { scan-assembler-not "pushq\[ \t\]%rax" { target x32 } } } */+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-3.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-3.c+index 545a981add5..b24af1da963 100644+--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-3.c++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-3.c+@@ -13,7 +13,7 @@ male_indirect_jump (long offset)+ }+ + /* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { ! x32 } } } } */+-/* { dg-final { scan-assembler "pushq\[ \t\]%rax" { target x32 } } } */+ /* { dg-final { scan-assembler-times "jmp\[ \t\]*\.LIND" 2 } } */+ /* { dg-final { scan-assembler-times "call\[ \t\]*\.LIND" 2 } } */+ /* { dg-final { scan-assembler-not "__x86.indirect_thunk" } } */++/* { dg-final { scan-assembler-not "pushq\[ \t\]%rax" { target x32 } } } */+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-4.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-4.c+index d9ff4722cff..1a86608f727 100644+--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-4.c++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-4.c+@@ -13,7 +13,7 @@ male_indirect_jump (long offset)+ }+ + /* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { ! x32 } } } } */+-/* { dg-final { scan-assembler "pushq\[ \t\]%rax" { target x32 } } } */+ /* { dg-final { scan-assembler-times "jmp\[ \t\]*\.LIND" 2 } } */+ /* { dg-final { scan-assembler-times "call\[ \t\]*\.LIND" 2 } } */+ /* { dg-final { scan-assembler-not "__x86.indirect_thunk" } } */++/* { dg-final { scan-assembler-not "pushq\[ \t\]%rax" { target x32 } } } */+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-7.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-7.c+index a0ce06b8232..01d45782185 100644+--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-7.c++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-7.c+@@ -36,7 +36,7 @@ bar (int i)+ }+ + /* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*\.L\[0-9\]+\\(,%" { target { ! x32 } } } } */+-/* { dg-final { scan-assembler "pushq\[ \t\]%rax" { target x32 } } } */++/* { dg-final { scan-assembler-not "pushq\[ \t\]%rax" { target x32 } } } */+ /* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */+ /* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */+ /* { dg-final { scan-assembler-not "__x86.indirect_thunk" } } */+-- +2.15.1+diff --git a/gnu/packages/patches/gcc-retpoline-i386-Add-V-register-operand-modifier.patch b/gnu/packages/patches/gcc-retpoline-i386-Add-V-register-operand-modifier.patchnew file mode 100644index 000000000..1996a1dfe--- /dev/null+++ b/gnu/packages/patches/gcc-retpoline-i386-Add-V-register-operand-modifier.patch@@ -0,0 +1,76 @@+'Retpoline' mitigation technique for Spectre (branch target injection)+[CVE-2017-5715]:++https://security.googleblog.com/2018/01/more-details-about-mitigations-for-cpu_4.html+https://support.google.com/faqs/answer/7625886+https://spectreattack.com/+https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2017-5715++Patch copied from the 'retpoline-20180107' branch of upstream source repository+(please add new / update existing patches when new 'retpoline-xxxxxxxx' branch+appears):++http://git.infradead.org/users/dwmw2/gcc-retpoline.git++From f83391fb22471a2f1c330e2e78f64630d64f497d Mon Sep 17 00:00:00 2001+From: "H.J. Lu" <hjl.tools@gmail.com>+Date: Tue, 19 Dec 2017 08:28:36 -0800+Subject: [PATCH 16/17] i386: Add 'V' register operand modifier++For++void+bar (void (*func) (void))+{+ asm("call *%V0" : : "r"(func));+}++it generates:++bar:+ call *rdi+ ret+---+ gcc/config/i386/i386.c | 5 ++++-+ 1 file changed, 4 insertions(+), 1 deletion(-)++diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c+index 344cafe3dac..6cb0681233a 100644+--- a/gcc/config/i386/i386.c++++ b/gcc/config/i386/i386.c+@@ -17886,6 +17886,7 @@ put_condition_code (enum rtx_code code, machine_mode mode, bool reverse,+ If CODE is 'h', pretend the reg is the 'high' byte register.+ If CODE is 'y', print "st(0)" instead of "st", if the reg is stack op.+ If CODE is 'd', duplicate the operand for AVX instruction.++ If CODE is 'V', print naked register name without %.+ */+ + void+@@ -17896,7 +17897,7 @@ print_reg (rtx x, int code, FILE *file)+ unsigned int regno;+ bool duplicated;+ +- if (ASSEMBLER_DIALECT == ASM_ATT)++ if (ASSEMBLER_DIALECT == ASM_ATT && code != 'V')+ putc ('%', file);+ + if (x == pc_rtx)+@@ -18063,6 +18064,7 @@ print_reg (rtx x, int code, FILE *file)+ & -- print some in-use local-dynamic symbol name.+ H -- print a memory address offset by 8; used for sse high-parts+ Y -- print condition for XOP pcom* instruction.++ V -- print naked register name without %.+ + -- print a branch hint as 'cs' or 'ds' prefix+ ; -- print a semicolon (after prefixes due to bug in older gas).+ ~ -- print "i" if TARGET_AVX2, "f" otherwise.+@@ -18287,6 +18289,7 @@ ix86_print_operand (FILE *file, rtx x, int code)+ case 'X':+ case 'P':+ case 'p':++ case 'V':+ break;+ + case 's':+-- +2.15.1+diff --git a/gnu/packages/patches/gcc-retpoline-i386-More-use-reference-of-struct-ix86_frame-to-avoi.patch b/gnu/packages/patches/gcc-retpoline-i386-More-use-reference-of-struct-ix86_frame-to-avoi.patchnew file mode 100644index 000000000..3c42dd802--- /dev/null+++ b/gnu/packages/patches/gcc-retpoline-i386-More-use-reference-of-struct-ix86_frame-to-avoi.patch@@ -0,0 +1,69 @@+'Retpoline' mitigation technique for Spectre (branch target injection)+[CVE-2017-5715]:++https://security.googleblog.com/2018/01/more-details-about-mitigations-for-cpu_4.html+https://support.google.com/faqs/answer/7625886+https://spectreattack.com/+https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2017-5715++Patch copied from the 'retpoline-20180107' branch of upstream source repository+(please add new / update existing patches when new 'retpoline-xxxxxxxx' branch+appears):++http://git.infradead.org/users/dwmw2/gcc-retpoline.git++From d96784e4a7355aaab68dec62f31a97bd10714064 Mon Sep 17 00:00:00 2001+From: "H.J. Lu" <hjl.tools@gmail.com>+Date: Tue, 28 Nov 2017 10:26:35 -0800+Subject: [PATCH 03/17] i386: More use reference of struct ix86_frame to avoid+ copy++When there is no need to make a copy of ix86_frame, we can use reference+of struct ix86_frame to avoid copy.++ * config/i386/i386.c (ix86_expand_prologue): Use reference of+ struct ix86_frame.+ (ix86_expand_epilogue): Likewise.+---+ gcc/config/i386/i386.c | 6 ++----+ 1 file changed, 2 insertions(+), 4 deletions(-)++diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c+index 01ecda7643b..504530a00cf 100644+--- a/gcc/config/i386/i386.c++++ b/gcc/config/i386/i386.c+@@ -13656,7 +13656,6 @@ ix86_expand_prologue (void)+ {+ struct machine_function *m = cfun->machine;+ rtx insn, t;+- struct ix86_frame frame;+ HOST_WIDE_INT allocate;+ bool int_registers_saved;+ bool sse_registers_saved;+@@ -13680,7 +13679,7 @@ ix86_expand_prologue (void)+ m->fs.sp_valid = true;+ + ix86_compute_frame_layout ();+- frame = m->frame;++ struct ix86_frame &frame = cfun->machine->frame;+ + if (!TARGET_64BIT && ix86_function_ms_hook_prologue (current_function_decl))+ {+@@ -14343,13 +14342,12 @@ ix86_expand_epilogue (int style)+ {+ struct machine_function *m = cfun->machine;+ struct machine_frame_state frame_state_save = m->fs;+- struct ix86_frame frame;+ bool restore_regs_via_mov;+ bool using_drap;+ + ix86_finalize_stack_realign_flags ();+ ix86_compute_frame_layout ();+- frame = m->frame;++ struct ix86_frame &frame = cfun->machine->frame;+ + m->fs.sp_valid = (!frame_pointer_needed+ || (crtl->sp_is_unchanging+-- +2.15.1+diff --git a/gnu/packages/patches/gcc-retpoline-i386-Move-struct-ix86_frame-to-machine_function.patch b/gnu/packages/patches/gcc-retpoline-i386-Move-struct-ix86_frame-to-machine_function.patchnew file mode 100644index 000000000..908e3cd83--- /dev/null+++ b/gnu/packages/patches/gcc-retpoline-i386-Move-struct-ix86_frame-to-machine_function.patch@@ -0,0 +1,249 @@+'Retpoline' mitigation technique for Spectre (branch target injection)+[CVE-2017-5715]:++https://security.googleblog.com/2018/01/more-details-about-mitigations-for-cpu_4.html+https://support.google.com/faqs/answer/7625886+https://spectreattack.com/+https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2017-5715++Patch copied from the 'retpoline-20180107' branch of upstream source repository+(please add new / update existing patches when new 'retpoline-xxxxxxxx' branch+appears):++http://git.infradead.org/users/dwmw2/gcc-retpoline.git++From 85743811dfa4eb648edbbb637632ac53182b6e05 Mon Sep 17 00:00:00 2001+From: "H.J. Lu" <hjl.tools@gmail.com>+Date: Mon, 6 Nov 2017 09:11:08 -0800+Subject: [PATCH 01/17] i386: Move struct ix86_frame to machine_function++Make ix86_frame available to i386 code generation.++ * config/i386/i386.c (ix86_frame): Moved to ...+ * config/i386/i386.h (ix86_frame): Here.+ (machine_function): Add frame.+ * config/i386/i386.c (ix86_compute_frame_layout): Repace the+ frame argument with &cfun->machine->frame.+ (ix86_can_use_return_insn_p): Don't pass &frame to+ ix86_compute_frame_layout. Copy frame from cfun->machine->frame.+ (ix86_can_eliminate): Likewise.+ (ix86_expand_prologue): Likewise.+ (ix86_expand_epilogue): Likewise.+ (ix86_expand_split_stack_prologue): Likewise.+---+ gcc/config/i386/i386.c | 68 ++++++++++----------------------------------------+ gcc/config/i386/i386.h | 53 ++++++++++++++++++++++++++++++++++++++-+ 2 files changed, 65 insertions(+), 56 deletions(-)++diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c+index dc14d205de7..c23c259c538 100644+--- a/gcc/config/i386/i386.c++++ b/gcc/config/i386/i386.c+@@ -2441,53 +2441,6 @@ struct GTY(()) stack_local_entry {+ struct stack_local_entry *next;+ };+ +-/* Structure describing stack frame layout.+- Stack grows downward:+-+- [arguments]+- <- ARG_POINTER+- saved pc+-+- saved static chain if ix86_static_chain_on_stack+-+- saved frame pointer if frame_pointer_needed+- <- HARD_FRAME_POINTER+- [saved regs]+- <- regs_save_offset+- [padding0]+-+- [saved SSE regs]+- <- sse_regs_save_offset+- [padding1] |+- | <- FRAME_POINTER+- [va_arg registers] |+- |+- [frame] |+- |+- [padding2] | = to_allocate+- <- STACK_POINTER+- */+-struct ix86_frame+-{+- int nsseregs;+- int nregs;+- int va_arg_size;+- int red_zone_size;+- int outgoing_arguments_size;+-+- /* The offsets relative to ARG_POINTER. */+- HOST_WIDE_INT frame_pointer_offset;+- HOST_WIDE_INT hard_frame_pointer_offset;+- HOST_WIDE_INT stack_pointer_offset;+- HOST_WIDE_INT hfp_save_offset;+- HOST_WIDE_INT reg_save_offset;+- HOST_WIDE_INT sse_reg_save_offset;+-+- /* When save_regs_using_mov is set, emit prologue using+- move instead of push instructions. */+- bool save_regs_using_mov;+-};+-+ /* Which cpu are we scheduling for. */+ enum attr_cpu ix86_schedule;+ +@@ -2579,7 +2532,7 @@ static unsigned int ix86_function_arg_boundary (machine_mode,+ const_tree);+ static rtx ix86_static_chain (const_tree, bool);+ static int ix86_function_regparm (const_tree, const_tree);+-static void ix86_compute_frame_layout (struct ix86_frame *);++static void ix86_compute_frame_layout (void);+ static bool ix86_expand_vector_init_one_nonzero (bool, machine_mode,+ rtx, rtx, int);+ static void ix86_add_new_builtins (HOST_WIDE_INT, HOST_WIDE_INT);+@@ -11892,7 +11845,8 @@ ix86_can_use_return_insn_p (void)+ if (crtl->args.pops_args && crtl->args.size >= 32768)+ return 0;+ +- ix86_compute_frame_layout (&frame);++ ix86_compute_frame_layout ();++ frame = cfun->machine->frame;+ return (frame.stack_pointer_offset == UNITS_PER_WORD+ && (frame.nregs + frame.nsseregs) == 0);+ }+@@ -12378,8 +12332,8 @@ ix86_can_eliminate (const int from, const int to)+ HOST_WIDE_INT+ ix86_initial_elimination_offset (int from, int to)+ {+- struct ix86_frame frame;+- ix86_compute_frame_layout (&frame);++ ix86_compute_frame_layout ();++ struct ix86_frame frame = cfun->machine->frame;+ + if (from == ARG_POINTER_REGNUM && to == HARD_FRAME_POINTER_REGNUM)+ return frame.hard_frame_pointer_offset;+@@ -12418,8 +12372,9 @@ ix86_builtin_setjmp_frame_value (void)+ /* Fill structure ix86_frame about frame of currently computed function. */+ + static void+-ix86_compute_frame_layout (struct ix86_frame *frame)++ix86_compute_frame_layout (void)+ {++ struct ix86_frame *frame = &cfun->machine->frame;+ unsigned HOST_WIDE_INT stack_alignment_needed;+ HOST_WIDE_INT offset;+ unsigned HOST_WIDE_INT preferred_alignment;+@@ -13726,7 +13681,8 @@ ix86_expand_prologue (void)+ m->fs.sp_offset = INCOMING_FRAME_SP_OFFSET;+ m->fs.sp_valid = true;+ +- ix86_compute_frame_layout (&frame);++ ix86_compute_frame_layout ();++ frame = m->frame;+ + if (!TARGET_64BIT && ix86_function_ms_hook_prologue (current_function_decl))+ {+@@ -14394,7 +14350,8 @@ ix86_expand_epilogue (int style)+ bool using_drap;+ + ix86_finalize_stack_realign_flags ();+- ix86_compute_frame_layout (&frame);++ ix86_compute_frame_layout ();++ frame = m->frame;+ + m->fs.sp_valid = (!frame_pointer_needed+ || (crtl->sp_is_unchanging+@@ -14904,7 +14861,8 @@ ix86_expand_split_stack_prologue (void)+ gcc_assert (flag_split_stack && reload_completed);+ + ix86_finalize_stack_realign_flags ();+- ix86_compute_frame_layout (&frame);++ ix86_compute_frame_layout ();++ frame = cfun->machine->frame;+ allocate = frame.stack_pointer_offset - INCOMING_FRAME_SP_OFFSET;+ + /* This is the label we will branch to if we have enough stack+diff --git a/gcc/config/i386/i386.h b/gcc/config/i386/i386.h+index 9e5f4d857d9..7d9f9020fb3 100644+--- a/gcc/config/i386/i386.h++++ b/gcc/config/i386/i386.h+@@ -2446,9 +2446,56 @@ enum avx_u128_state+ + #define FASTCALL_PREFIX '@'+ ++#ifndef USED_FOR_TARGET++/* Structure describing stack frame layout.++ Stack grows downward:++++ [arguments]++ <- ARG_POINTER++ saved pc++++ saved static chain if ix86_static_chain_on_stack++++ saved frame pointer if frame_pointer_needed++ <- HARD_FRAME_POINTER++ [saved regs]++ <- regs_save_offset++ [padding0]++++ [saved SSE regs]++ <- sse_regs_save_offset++ [padding1] |++ | <- FRAME_POINTER++ [va_arg registers] |++ |++ [frame] |++ |++ [padding2] | = to_allocate++ <- STACK_POINTER++ */++struct GTY(()) ix86_frame++{++ int nsseregs;++ int nregs;++ int va_arg_size;++ int red_zone_size;++ int outgoing_arguments_size;++++ /* The offsets relative to ARG_POINTER. */++ HOST_WIDE_INT frame_pointer_offset;++ HOST_WIDE_INT hard_frame_pointer_offset;++ HOST_WIDE_INT stack_pointer_offset;++ HOST_WIDE_INT hfp_save_offset;++ HOST_WIDE_INT reg_save_offset;++ HOST_WIDE_INT sse_reg_save_offset;++++ /* When save_regs_using_mov is set, emit prologue using++ move instead of push instructions. */++ bool save_regs_using_mov;++};+++ /* Machine specific frame tracking during prologue/epilogue generation. */+ +-#ifndef USED_FOR_TARGET+ struct GTY(()) machine_frame_state+ {+ /* This pair tracks the currently active CFA as reg+offset. When reg+@@ -2507,6 +2554,9 @@ struct GTY(()) machine_function {+ int varargs_fpr_size;+ int optimize_mode_switching[MAX_386_ENTITIES];+ ++ /* Cached initial frame layout for the current function. */++ struct ix86_frame frame;+++ /* Number of saved registers USE_FAST_PROLOGUE_EPILOGUE+ has been computed for. */+ int use_fast_prologue_epilogue_nregs;+@@ -2589,6 +2639,7 @@ struct GTY(()) machine_function {+ #define ix86_current_function_calls_tls_descriptor \+ (ix86_tls_descriptor_calls_expanded_in_cfun && df_regs_ever_live_p (SP_REG))+ #define ix86_static_chain_on_stack (cfun->machine->static_chain_on_stack)++#define ix86_red_zone_size (cfun->machine->frame.red_zone_size)+ + /* Control behavior of x86_file_start. */+ #define X86_FILE_START_VERSION_DIRECTIVE false+-- +2.15.1+diff --git a/gnu/packages/patches/gcc-retpoline-i386-Use-reference-of-struct-ix86_frame-to-avoid-cop.patch b/gnu/packages/patches/gcc-retpoline-i386-Use-reference-of-struct-ix86_frame-to-avoid-cop.patchnew file mode 100644index 000000000..623ce5094--- /dev/null+++ b/gnu/packages/patches/gcc-retpoline-i386-Use-reference-of-struct-ix86_frame-to-avoid-cop.patch@@ -0,0 +1,85 @@+'Retpoline' mitigation technique for Spectre (branch target injection)+[CVE-2017-5715]:++https://security.googleblog.com/2018/01/more-details-about-mitigations-for-cpu_4.html+https://support.google.com/faqs/answer/7625886+https://spectreattack.com/+https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2017-5715++Patch copied from the 'retpoline-20180107' branch of upstream source repository+(please add new / update existing patches when new 'retpoline-xxxxxxxx' branch+appears):++http://git.infradead.org/users/dwmw2/gcc-retpoline.git++From 0b1769bdce27304a6a91bec234f47f102a2603d5 Mon Sep 17 00:00:00 2001+From: hjl <hjl@138bc75d-0d04-0410-961f-82ee72b054a4>+Date: Mon, 6 Nov 2017 23:04:15 +0000+Subject: [PATCH 02/17] i386: Use reference of struct ix86_frame to avoid copy++When there is no need to make a copy of ix86_frame, we can use reference+of struct ix86_frame to avoid copy.++Tested on x86-64.++ * config/i386/i386.c (ix86_can_use_return_insn_p): Use reference+ of struct ix86_frame.+ (ix86_initial_elimination_offset): Likewise.+ (ix86_expand_split_stack_prologue): Likewise.++git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@254480 138bc75d-0d04-0410-961f-82ee72b054a4+---+ gcc/config/i386/i386.c | 9 +++------+ 1 file changed, 3 insertions(+), 6 deletions(-)++diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c+index c23c259c538..01ecda7643b 100644+--- a/gcc/config/i386/i386.c++++ b/gcc/config/i386/i386.c+@@ -11832,8 +11832,6 @@ symbolic_reference_mentioned_p (rtx op)+ bool+ ix86_can_use_return_insn_p (void)+ {+- struct ix86_frame frame;+-+ /* Don't use `ret' instruction in interrupt handler. */+ if (! reload_completed+ || frame_pointer_needed+@@ -11846,7 +11844,7 @@ ix86_can_use_return_insn_p (void)+ return 0;+ + ix86_compute_frame_layout ();+- frame = cfun->machine->frame;++ struct ix86_frame &frame = cfun->machine->frame;+ return (frame.stack_pointer_offset == UNITS_PER_WORD+ && (frame.nregs + frame.nsseregs) == 0);+ }+@@ -12333,7 +12331,7 @@ HOST_WIDE_INT+ ix86_initial_elimination_offset (int from, int to)+ {+ ix86_compute_frame_layout ();+- struct ix86_frame frame = cfun->machine->frame;++ struct ix86_frame &frame = cfun->machine->frame;+ + if (from == ARG_POINTER_REGNUM && to == HARD_FRAME_POINTER_REGNUM)+ return frame.hard_frame_pointer_offset;+@@ -14849,7 +14847,6 @@ static GTY(()) rtx split_stack_fn_large;+ void+ ix86_expand_split_stack_prologue (void)+ {+- struct ix86_frame frame;+ HOST_WIDE_INT allocate;+ unsigned HOST_WIDE_INT args_size;+ rtx_code_label *label;+@@ -14862,7 +14859,7 @@ ix86_expand_split_stack_prologue (void)+ + ix86_finalize_stack_realign_flags ();+ ix86_compute_frame_layout ();+- frame = cfun->machine->frame;++ struct ix86_frame &frame = cfun->machine->frame;+ allocate = frame.stack_pointer_offset - INCOMING_FRAME_SP_OFFSET;+ + /* This is the label we will branch to if we have enough stack+-- +2.15.1+-- 2.15.1
Cheers,Alex
A
A
Alex Vong wrote on 14 Jan 2018 17:30
Add tags.
(address . control@debbugs.gnu.org)
87o9lwqu72.fsf@gmail.com
package guix-patchestags 30111 patch securitythanks
A
A
Alex Vong wrote on 14 Jan 2018 17:37
Fix title.
(address . control@debbugs.gnu.org)
87k1wkqtup.fsf@gmail.com
package guix-patchesretitle 30111 [PATCH] gnu: gcc@7: Apply the 'retpoline' mitigation technique.thanks
A
A
Alex Vong wrote on 15 Jan 2018 15:29
Re: gnu: gcc@7: Apply the 'retpoline' mitigation technique.
(address . 30111@debbugs.gnu.org)
87d12bgpqh.fsf@gmail.com
Hello,
Please do not review the last patch. It seems the author[0] hasrefactor the commits and place them into the new 'retpoline-regnames'branch. I think these commits get sent to gcc-patches for review[1].
[0]: http://git.infradead.org/users/dwmw2/gcc-retpoline.git[1]: https://gcc.gnu.org/ml/gcc-patches/2018-01/
Alex Vong <alexvong1995@gmail.com> writes:
Toggle quote (6691 lines)> Hello,>> This patch adds the repoline patches (totally 17 of them) taken from the> 'retpoline-20180107' branch at> ``http://git.infradead.org/users/dwmw2/gcc-retpoline.git'' to gcc@7.>> Last time it builds fine on my laptop. I am now re-building since I add> some comments on the patches. I will reply asap if anything goes wrong> with the re-build.>> From 5be54f7ebe9b0ab6dc65ea974584be0850604b14 Mon Sep 17 00:00:00 2001> From: Alex Vong <alexvong1995@gmail.com>> Date: Sun, 14 Jan 2018 20:12:19 +0800> Subject: [PATCH] gnu: gcc@7: Apply the 'retpoline' mitigation technique.>> This is part of Spectre (branch target injection) [CVE-2017-5715]> mitigation. Suggested by Mark H Weaver <mhw@netris.org>.>> * gnu/local.mk (dist_patch_DATA): Add them.> * gnu/packages/gcc.scm (gcc@7): Use them.> * gnu/packages/patches/gcc-retpoline-Add-indirect_branch-attribute-with-tests.patch,> gnu/packages/patches/gcc-retpoline-Add-mfunction-return-and-function_return-attribute.patch,> gnu/packages/patches/gcc-retpoline-Add-mfunction-return-keep-to-indirect-branch-tests.patch,> gnu/packages/patches/gcc-retpoline-Add-mindirect-branch-loop.patch,> gnu/packages/patches/gcc-retpoline-Add-mindirect-branch-register-and-tests.patch,> gnu/packages/patches/gcc-retpoline-Add-mindirect-branch-thunk-extern.patch,> gnu/packages/patches/gcc-retpoline-Add-mindirect-branch-thunk-inline.patch,> gnu/packages/patches/gcc-retpoline-Add-mindirect-branch-thunk.patch,> gnu/packages/patches/gcc-retpoline-Add-mno-indirect-branch-register-to-indirect-branch-.patch,> gnu/packages/patches/gcc-retpoline-Add-tests-for-mindirect-branch-thunk-fcheck-pointer-.patch,> gnu/packages/patches/gcc-retpoline-Disable-red-zone-with-local-indirect-jump.patch,> gnu/packages/patches/gcc-retpoline-Rename-thunks-to-__x86_indirect_thunk_rax-etc.-to-re.patch,> gnu/packages/patches/gcc-retpoline-Use-__x86.indirect_thunk.reg-for-indirect-branch-via.patch,> gnu/packages/patches/gcc-retpoline-i386-Add-V-register-operand-modifier.patch,> gnu/packages/patches/gcc-retpoline-i386-More-use-reference-of-struct-ix86_frame-to-avoi.patch,> gnu/packages/patches/gcc-retpoline-i386-Move-struct-ix86_frame-to-machine_function.patch,> gnu/packages/patches/gcc-retpoline-i386-Use-reference-of-struct-ix86_frame-to-avoid-cop.patch:> New files.> ---> gnu/local.mk | 19 +-> gnu/packages/gcc.scm | 20 +-> ...-Add-indirect_branch-attribute-with-tests.patch | 475 +++++++++++> ...tion-return-and-function_return-attribute.patch | 740 ++++++++++++++++> ...tion-return-keep-to-indirect-branch-tests.patch | 421 ++++++++++> .../gcc-retpoline-Add-mindirect-branch-loop.patch | 233 ++++++> ...e-Add-mindirect-branch-register-and-tests.patch | 403 +++++++++> ...tpoline-Add-mindirect-branch-thunk-extern.patch | 263 ++++++> ...tpoline-Add-mindirect-branch-thunk-inline.patch | 310 +++++++> .../gcc-retpoline-Add-mindirect-branch-thunk.patch | 729 ++++++++++++++++> ...irect-branch-register-to-indirect-branch-.patch | 554 ++++++++++++> ...or-mindirect-branch-thunk-fcheck-pointer-.patch | 134 +++> ...Disable-red-zone-with-local-indirect-jump.patch | 147 ++++> ...ks-to-__x86_indirect_thunk_rax-etc.-to-re.patch | 926 +++++++++++++++++++++> ...ndirect_thunk.reg-for-indirect-branch-via.patch | 623 ++++++++++++++> ...line-i386-Add-V-register-operand-modifier.patch | 76 ++> ...se-reference-of-struct-ix86_frame-to-avoi.patch | 69 ++> ...ove-struct-ix86_frame-to-machine_function.patch | 249 ++++++> ...ference-of-struct-ix86_frame-to-avoid-cop.patch | 85 ++> 19 files changed, 6474 insertions(+), 2 deletions(-)> create mode 100644 gnu/packages/patches/gcc-retpoline-Add-indirect_branch-attribute-with-tests.patch> create mode 100644 gnu/packages/patches/gcc-retpoline-Add-mfunction-return-and-function_return-attribute.patch> create mode 100644 gnu/packages/patches/gcc-retpoline-Add-mfunction-return-keep-to-indirect-branch-tests.patch> create mode 100644 gnu/packages/patches/gcc-retpoline-Add-mindirect-branch-loop.patch> create mode 100644 gnu/packages/patches/gcc-retpoline-Add-mindirect-branch-register-and-tests.patch> create mode 100644 gnu/packages/patches/gcc-retpoline-Add-mindirect-branch-thunk-extern.patch> create mode 100644 gnu/packages/patches/gcc-retpoline-Add-mindirect-branch-thunk-inline.patch> create mode 100644 gnu/packages/patches/gcc-retpoline-Add-mindirect-branch-thunk.patch> create mode 100644 gnu/packages/patches/gcc-retpoline-Add-mno-indirect-branch-register-to-indirect-branch-.patch> create mode 100644 gnu/packages/patches/gcc-retpoline-Add-tests-for-mindirect-branch-thunk-fcheck-pointer-.patch> create mode 100644 gnu/packages/patches/gcc-retpoline-Disable-red-zone-with-local-indirect-jump.patch> create mode 100644 gnu/packages/patches/gcc-retpoline-Rename-thunks-to-__x86_indirect_thunk_rax-etc.-to-re.patch> create mode 100644 gnu/packages/patches/gcc-retpoline-Use-__x86.indirect_thunk.reg-for-indirect-branch-via.patch> create mode 100644 gnu/packages/patches/gcc-retpoline-i386-Add-V-register-operand-modifier.patch> create mode 100644 gnu/packages/patches/gcc-retpoline-i386-More-use-reference-of-struct-ix86_frame-to-avoi.patch> create mode 100644 gnu/packages/patches/gcc-retpoline-i386-Move-struct-ix86_frame-to-machine_function.patch> create mode 100644 gnu/packages/patches/gcc-retpoline-i386-Use-reference-of-struct-ix86_frame-to-avoid-cop.patch>> diff --git a/gnu/local.mk b/gnu/local.mk> index 6af8bfc4b..122e8ef0c 100644> --- a/gnu/local.mk> +++ b/gnu/local.mk> @@ -9,7 +9,7 @@> # Copyright © 2016 Adonay "adfeno" Felipe Nogueira <https://libreplanet.org/wiki/User:Adfeno> <adfeno@openmailbox.org>> # Copyright © 2016, 2017 Ricardo Wurmus <rekado@elephly.net>> # Copyright © 2016 Ben Woodcroft <donttrustben@gmail.com>> -# Copyright © 2016, 2017 Alex Vong <alexvong1995@gmail.com>> +# Copyright © 2016, 2017, 2018 Alex Vong <alexvong1995@gmail.com>> # Copyright © 2016, 2017 Efraim Flashner <efraim@flashner.co.il>> # Copyright © 2016, 2017 Jan Nieuwenhuizen <janneke@gnu.org>> # Copyright © 2017 Tobias Geerinckx-Rice <me@tobias.gr>> @@ -652,6 +652,23 @@ dist_patch_DATA = \> %D%/packages/patches/gcc-asan-powerpc-missing-include.patch \> %D%/packages/patches/gcc-cross-environment-variables.patch \> %D%/packages/patches/gcc-libvtv-runpath.patch \> + %D%/packages/patches/gcc-retpoline-i386-Move-struct-ix86_frame-to-machine_function.patch \> + %D%/packages/patches/gcc-retpoline-i386-Use-reference-of-struct-ix86_frame-to-avoid-cop.patch \> + %D%/packages/patches/gcc-retpoline-i386-More-use-reference-of-struct-ix86_frame-to-avoi.patch \> + %D%/packages/patches/gcc-retpoline-Add-mindirect-branch-thunk.patch \> + %D%/packages/patches/gcc-retpoline-Add-tests-for-mindirect-branch-thunk-fcheck-pointer-.patch \> + %D%/packages/patches/gcc-retpoline-Add-mindirect-branch-thunk-inline.patch \> + %D%/packages/patches/gcc-retpoline-Add-mindirect-branch-thunk-extern.patch \> + %D%/packages/patches/gcc-retpoline-Add-indirect_branch-attribute-with-tests.patch \> + %D%/packages/patches/gcc-retpoline-Use-__x86.indirect_thunk.reg-for-indirect-branch-via.patch \> + %D%/packages/patches/gcc-retpoline-Add-mindirect-branch-loop.patch \> + %D%/packages/patches/gcc-retpoline-Add-mfunction-return-and-function_return-attribute.patch \> + %D%/packages/patches/gcc-retpoline-Add-mfunction-return-keep-to-indirect-branch-tests.patch \> + %D%/packages/patches/gcc-retpoline-Add-mindirect-branch-register-and-tests.patch \> + %D%/packages/patches/gcc-retpoline-Add-mno-indirect-branch-register-to-indirect-branch-.patch \> + %D%/packages/patches/gcc-retpoline-Disable-red-zone-with-local-indirect-jump.patch \> + %D%/packages/patches/gcc-retpoline-i386-Add-V-register-operand-modifier.patch \> + %D%/packages/patches/gcc-retpoline-Rename-thunks-to-__x86_indirect_thunk_rax-etc.-to-re.patch \> %D%/packages/patches/gcc-strmov-store-file-names.patch \> %D%/packages/patches/gcc-4-compile-with-gcc-5.patch \> %D%/packages/patches/gcc-4.6-gnu-inline.patch \> diff --git a/gnu/packages/gcc.scm b/gnu/packages/gcc.scm> index ad8992289..6b913aff9 100644> --- a/gnu/packages/gcc.scm> +++ b/gnu/packages/gcc.scm> @@ -5,6 +5,7 @@> ;;; Copyright © 2015 Andreas Enge <andreas@enge.fr>> ;;; Copyright © 2015, 2016, 2017 Efraim Flashner <efraim@flashner.co.il>> ;;; Copyright © 2016 Carlos Sánchez de La Lama <csanchezdll@gmail.com>> +;;; Copyright © 2018 ALex Vong <alexvong1995@gmail.com>> ;;;> ;;; This file is part of GNU Guix.> ;;;> @@ -427,7 +428,24 @@ Go. It also includes runtime support libraries for these languages.")> (base32> "16j7i0888j2f1yp9l0nhji6cq65dy6y4nwy8868a8njbzzwavxqw"))> (patches (search-patches "gcc-strmov-store-file-names.patch"> - "gcc-5.0-libvtv-runpath.patch"))))> + "gcc-5.0-libvtv-runpath.patch"> + "gcc-retpoline-i386-Move-struct-ix86_frame-to-machine_function.patch"> + "gcc-retpoline-i386-Use-reference-of-struct-ix86_frame-to-avoid-cop.patch"> + "gcc-retpoline-i386-More-use-reference-of-struct-ix86_frame-to-avoi.patch"> + "gcc-retpoline-Add-mindirect-branch-thunk.patch"> + "gcc-retpoline-Add-tests-for-mindirect-branch-thunk-fcheck-pointer-.patch"> + "gcc-retpoline-Add-mindirect-branch-thunk-inline.patch"> + "gcc-retpoline-Add-mindirect-branch-thunk-extern.patch"> + "gcc-retpoline-Add-indirect_branch-attribute-with-tests.patch"> + "gcc-retpoline-Use-__x86.indirect_thunk.reg-for-indirect-branch-via.patch"> + "gcc-retpoline-Add-mindirect-branch-loop.patch"> + "gcc-retpoline-Add-mfunction-return-and-function_return-attribute.patch"> + "gcc-retpoline-Add-mfunction-return-keep-to-indirect-branch-tests.patch"> + "gcc-retpoline-Add-mindirect-branch-register-and-tests.patch"> + "gcc-retpoline-Add-mno-indirect-branch-register-to-indirect-branch-.patch"> + "gcc-retpoline-Disable-red-zone-with-local-indirect-jump.patch"> + "gcc-retpoline-i386-Add-V-register-operand-modifier.patch"> + "gcc-retpoline-Rename-thunks-to-__x86_indirect_thunk_rax-etc.-to-re.patch"))))> (description> "GCC is the GNU Compiler Collection. It provides compiler front-ends> for several languages, including C, C++, Objective-C, Fortran, Ada, and Go.> diff --git a/gnu/packages/patches/gcc-retpoline-Add-indirect_branch-attribute-with-tests.patch b/gnu/packages/patches/gcc-retpoline-Add-indirect_branch-attribute-with-tests.patch> new file mode 100644> index 000000000..5129a8273> --- /dev/null> +++ b/gnu/packages/patches/gcc-retpoline-Add-indirect_branch-attribute-with-tests.patch> @@ -0,0 +1,475 @@> +'Retpoline' mitigation technique for Spectre (branch target injection)> +[CVE-2017-5715]:> +> +https://security.googleblog.com/2018/01/more-details-about-mitigations-for-cpu_4.html> +https://support.google.com/faqs/answer/7625886> +https://spectreattack.com/> +https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2017-5715> +> +Patch copied from the 'retpoline-20180107' branch of upstream source repository> +(please add new / update existing patches when new 'retpoline-xxxxxxxx' branch> +appears):> +> +http://git.infradead.org/users/dwmw2/gcc-retpoline.git> +> +From e9794727bb0384be6d27ad1edaefc71c23cc0d86 Mon Sep 17 00:00:00 2001> +From: "H.J. Lu" <hjl.tools@gmail.com>> +Date: Tue, 28 Nov 2017 06:10:39 -0800> +Subject: [PATCH 08/17] Add indirect_branch attribute with tests> +> +__attribute__ ((indirect_branch("thunk")))> +__attribute__ ((indirect_branch("thunk-inline")))> +__attribute__ ((indirect_branch("thunk-extern")))> +__attribute__ ((indirect_branch("keep")))> +---> + gcc/config/i386/i386-opts.h | 1 +> + gcc/config/i386/i386.c | 74 ++++++++++++++++++++--> + gcc/config/i386/i386.h | 3 +> + .../gcc.target/i386/indirect-thunk-attr-1.c | 22 +++++++> + .../gcc.target/i386/indirect-thunk-attr-2.c | 20 ++++++> + .../gcc.target/i386/indirect-thunk-attr-3.c | 21 ++++++> + .../gcc.target/i386/indirect-thunk-attr-4.c | 20 ++++++> + .../gcc.target/i386/indirect-thunk-attr-5.c | 22 +++++++> + .../gcc.target/i386/indirect-thunk-attr-6.c | 21 ++++++> + .../gcc.target/i386/indirect-thunk-attr-7.c | 44 +++++++++++++> + .../gcc.target/i386/indirect-thunk-attr-8.c | 41 ++++++++++++> + 11 files changed, 283 insertions(+), 6 deletions(-)> + create mode 100644 gcc/testsuite/gcc.target/i386/indirect-thunk-attr-1.c> + create mode 100644 gcc/testsuite/gcc.target/i386/indirect-thunk-attr-2.c> + create mode 100644 gcc/testsuite/gcc.target/i386/indirect-thunk-attr-3.c> + create mode 100644 gcc/testsuite/gcc.target/i386/indirect-thunk-attr-4.c> + create mode 100644 gcc/testsuite/gcc.target/i386/indirect-thunk-attr-5.c> + create mode 100644 gcc/testsuite/gcc.target/i386/indirect-thunk-attr-6.c> + create mode 100644 gcc/testsuite/gcc.target/i386/indirect-thunk-attr-7.c> + create mode 100644 gcc/testsuite/gcc.target/i386/indirect-thunk-attr-8.c> +> +diff --git a/gcc/config/i386/i386-opts.h b/gcc/config/i386/i386-opts.h> +index f8d80ba7ec6..9e56d7f2d12 100644> +--- a/gcc/config/i386/i386-opts.h> ++++ b/gcc/config/i386/i386-opts.h> +@@ -100,6 +100,7 @@ enum stack_protector_guard {> + };> + > + enum indirect_branch {> ++ indirect_branch_unset = 0,> + indirect_branch_keep,> + indirect_branch_thunk,> + indirect_branch_thunk_inline,> +diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c> +index ac542f79846..5e66af08066 100644> +--- a/gcc/config/i386/i386.c> ++++ b/gcc/config/i386/i386.c> +@@ -7137,6 +7137,37 @@ ix86_set_func_type (tree fndecl)> + }> + }> + > ++/* Set the indirect_branch_type field from the function FNDECL. */> ++> ++static void> ++ix86_set_indirect_branch_type (tree fndecl)> ++{> ++ if (cfun->machine->indirect_branch_type == indirect_branch_unset)> ++ {> ++ tree attr = lookup_attribute ("indirect_branch",> ++ DECL_ATTRIBUTES (fndecl));> ++ if (attr != NULL)> ++ {> ++ tree args = TREE_VALUE (attr);> ++ if (args == NULL)> ++ gcc_unreachable ();> ++ tree cst = TREE_VALUE (args);> ++ if (strcmp (TREE_STRING_POINTER (cst), "keep") == 0)> ++ cfun->machine->indirect_branch_type = indirect_branch_keep;> ++ else if (strcmp (TREE_STRING_POINTER (cst), "thunk") == 0)> ++ cfun->machine->indirect_branch_type = indirect_branch_thunk;> ++ else if (strcmp (TREE_STRING_POINTER (cst), "thunk-inline") == 0)> ++ cfun->machine->indirect_branch_type = indirect_branch_thunk_inline;> ++ else if (strcmp (TREE_STRING_POINTER (cst), "thunk-extern") == 0)> ++ cfun->machine->indirect_branch_type = indirect_branch_thunk_extern;> ++ else> ++ gcc_unreachable ();> ++ }> ++ else> ++ cfun->machine->indirect_branch_type = ix86_indirect_branch;> ++ }> ++}> ++> + /* Establish appropriate back-end context for processing the function> + FNDECL. The argument might be NULL to indicate processing at top> + level, outside of any function scope. */> +@@ -7152,7 +7183,10 @@ ix86_set_current_function (tree fndecl)> + one is extern inline and one isn't. Call ix86_set_func_type> + to set the func_type field. */> + if (fndecl != NULL_TREE)> +- ix86_set_func_type (fndecl);> ++ {> ++ ix86_set_func_type (fndecl);> ++ ix86_set_indirect_branch_type (fndecl);> ++ }> + return;> + }> + > +@@ -7172,6 +7206,7 @@ ix86_set_current_function (tree fndecl)> + }> + > + ix86_set_func_type (fndecl);> ++ ix86_set_indirect_branch_type (fndecl);> + > + tree new_tree = DECL_FUNCTION_SPECIFIC_TARGET (fndecl);> + if (new_tree == NULL_TREE)> +@@ -28605,9 +28640,11 @@ ix86_output_indirect_branch (rtx call_op, const char *xasm,> + char push_buf[64];> + bool need_bnd_p = ix86_bnd_prefixed_insn_p (current_output_insn);> + > +- if (ix86_indirect_branch != indirect_branch_thunk_inline)> ++ if (cfun->machine->indirect_branch_type> ++ != indirect_branch_thunk_inline)> + {> +- bool need_thunk = ix86_indirect_branch == indirect_branch_thunk;> ++ bool need_thunk> ++ = cfun->machine->indirect_branch_type == indirect_branch_thunk;> + if (need_bnd_p)> + indirect_thunk_bnd_needed |= need_thunk;> + else> +@@ -28716,7 +28753,7 @@ const char *> + ix86_output_indirect_jmp (rtx call_op)> + {> + if (ix86_red_zone_size == 0> +- && ix86_indirect_branch != indirect_branch_keep)> ++ && cfun->machine->indirect_branch_type != indirect_branch_keep)> + {> + ix86_output_indirect_branch (call_op, "%0", true);> + return "";> +@@ -28733,7 +28770,7 @@ ix86_output_call_insn (rtx_insn *insn, rtx call_op)> + bool direct_p = constant_call_address_operand (call_op, VOIDmode);> + bool output_indirect_p> + = (!TARGET_SEH> +- && ix86_indirect_branch != indirect_branch_keep);> ++ && cfun->machine->indirect_branch_type != indirect_branch_keep);> + bool seh_nop_p = false;> + const char *xasm;> + > +@@ -41749,7 +41786,7 @@ ix86_handle_struct_attribute (tree *node, tree name, tree, int,> + }> + > + static tree> +-ix86_handle_fndecl_attribute (tree *node, tree name, tree, int,> ++ix86_handle_fndecl_attribute (tree *node, tree name, tree args, int,> + bool *no_add_attrs)> + {> + if (TREE_CODE (*node) != FUNCTION_DECL)> +@@ -41758,6 +41795,29 @@ ix86_handle_fndecl_attribute (tree *node, tree name, tree, int,> + name);> + *no_add_attrs = true;> + }> ++> ++ if (is_attribute_p ("indirect_branch", name))> ++ {> ++ tree cst = TREE_VALUE (args);> ++ if (TREE_CODE (cst) != STRING_CST)> ++ {> ++ warning (OPT_Wattributes,> ++ "%qE attribute requires a string constant argument",> ++ name);> ++ *no_add_attrs = true;> ++ }> ++ else if (strcmp (TREE_STRING_POINTER (cst), "keep") != 0> ++ && strcmp (TREE_STRING_POINTER (cst), "thunk") != 0> ++ && strcmp (TREE_STRING_POINTER (cst), "thunk-inline") != 0> ++ && strcmp (TREE_STRING_POINTER (cst), "thunk-extern") != 0)> ++ {> ++ warning (OPT_Wattributes,> ++ "argument to %qE attribute is not "> ++ "(keep|thunk|thunk-inline|thunk-extern)", name);> ++ *no_add_attrs = true;> ++ }> ++ }> ++> + return NULL_TREE;> + }> + > +@@ -46052,6 +46112,8 @@ static const struct attribute_spec ix86_attribute_table[] => + ix86_handle_interrupt_attribute, false },> + { "no_caller_saved_registers", 0, 0, false, true, true,> + ix86_handle_no_caller_saved_registers_attribute, false },> ++ { "indirect_branch", 1, 1, true, false, false,> ++ ix86_handle_fndecl_attribute, false },> + > + /* End element. */> + { NULL, 0, 0, false, false, false, NULL, false }> +diff --git a/gcc/config/i386/i386.h b/gcc/config/i386/i386.h> +index 7d9f9020fb3..a9c199a107c 100644> +--- a/gcc/config/i386/i386.h> ++++ b/gcc/config/i386/i386.h> +@@ -2604,6 +2604,9 @@ struct GTY(()) machine_function {> + /* Function type. */> + ENUM_BITFIELD(function_type) func_type : 2;> + > ++ /* How to generate indirec branch. */> ++ ENUM_BITFIELD(indirect_branch) indirect_branch_type : 3;> ++> + /* If true, the current function is a function specified with> + the "interrupt" or "no_caller_saved_registers" attribute. */> + BOOL_BITFIELD no_caller_saved_registers : 1;> +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-1.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-1.c> +new file mode 100644> +index 00000000000..26550fad4c8> +--- /dev/null> ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-1.c> +@@ -0,0 +1,22 @@> ++/* { dg-do compile } */> ++/* { dg-options "-O2 -fno-pic" } */> ++> ++typedef void (*dispatch_t)(long offset);> ++> ++dispatch_t dispatch;> ++> ++extern void male_indirect_jump (long)> ++ __attribute__ ((indirect_branch("thunk")));> ++> ++void> ++male_indirect_jump (long offset)> ++{> ++ dispatch(offset);> ++}> ++> ++/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { ! x32 } } } } */> ++/* { dg-final { scan-assembler "pushq\[ \t\]%rax" { target x32 } } } */> ++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" } } */> ++/* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */> ++/* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */> ++/* { dg-final { scan-assembler {\tlfence} } } */> +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-2.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-2.c> +new file mode 100644> +index 00000000000..f57bb2a92d6> +--- /dev/null> ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-2.c> +@@ -0,0 +1,20 @@> ++/* { dg-do compile } */> ++/* { dg-options "-O2 -fno-pic" } */> ++> ++typedef void (*dispatch_t)(long offset);> ++> ++dispatch_t dispatch[256];> ++> ++__attribute__ ((indirect_branch("thunk")))> ++void> ++male_indirect_jump (long offset)> ++{> ++ dispatch[offset](offset);> ++}> ++> ++/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { ! x32 } } } } */> ++/* { dg-final { scan-assembler "pushq\[ \t\]%rax" { target x32 } } } */> ++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" } } */> ++/* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */> ++/* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */> ++/* { dg-final { scan-assembler {\tlfence} } } */> +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-3.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-3.c> +new file mode 100644> +index 00000000000..a3668a6586c> +--- /dev/null> ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-3.c> +@@ -0,0 +1,21 @@> ++/* { dg-do compile } */> ++/* { dg-options "-O2 -fno-pic" } */> ++> ++typedef void (*dispatch_t)(long offset);> ++> ++dispatch_t dispatch;> ++extern int male_indirect_jump (long)> ++ __attribute__ ((indirect_branch("thunk-inline")));> ++> ++int> ++male_indirect_jump (long offset)> ++{> ++ dispatch(offset);> ++ return 0;> ++}> ++> ++/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { ! x32 } } } } */> ++/* { dg-final { scan-assembler "pushq\[ \t\]%rax" { target x32 } } } */> ++/* { dg-final { scan-assembler-times "jmp\[ \t\]*\.LIND" 2 } } */> ++/* { dg-final { scan-assembler-times "call\[ \t\]*\.LIND" 2 } } */> ++/* { dg-final { scan-assembler-not "__x86.indirect_thunk" } } */> +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-4.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-4.c> +new file mode 100644> +index 00000000000..a9c4a137dd4> +--- /dev/null> ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-4.c> +@@ -0,0 +1,20 @@> ++/* { dg-do compile } */> ++/* { dg-options "-O2 -fno-pic" } */> ++> ++typedef void (*dispatch_t)(long offset);> ++> ++dispatch_t dispatch[256];> ++> ++__attribute__ ((indirect_branch("thunk-inline")))> ++int> ++male_indirect_jump (long offset)> ++{> ++ dispatch[offset](offset);> ++ return 0;> ++}> ++> ++/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { ! x32 } } } } */> ++/* { dg-final { scan-assembler "pushq\[ \t\]%rax" { target x32 } } } */> ++/* { dg-final { scan-assembler-times "jmp\[ \t\]*\.LIND" 2 } } */> ++/* { dg-final { scan-assembler-times "call\[ \t\]*\.LIND" 2 } } */> ++/* { dg-final { scan-assembler-not "__x86.indirect_thunk" } } */> +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-5.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-5.c> +new file mode 100644> +index 00000000000..9582e0c5824> +--- /dev/null> ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-5.c> +@@ -0,0 +1,22 @@> ++/* { dg-do compile } */> ++/* { dg-options "-O2 -fno-pic" } */> ++> ++typedef void (*dispatch_t)(long offset);> ++> ++dispatch_t dispatch;> ++extern int male_indirect_jump (long)> ++ __attribute__ ((indirect_branch("thunk-extern")));> ++> ++int> ++male_indirect_jump (long offset)> ++{> ++ dispatch(offset);> ++ return 0;> ++}> ++> ++/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { ! x32 } } } } */> ++/* { dg-final { scan-assembler "pushq\[ \t\]%rax" { target x32 } } } */> ++/* { dg-final { scan-assembler-times "jmp\[ \t\]*\.LIND" 1 } } */> ++/* { dg-final { scan-assembler-times "call\[ \t\]*\.LIND" 1 } } */> ++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" } } */> ++/* { dg-final { scan-assembler-not {\t(lfence|pause)} } } */> +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-6.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-6.c> +new file mode 100644> +index 00000000000..66442cacfe8> +--- /dev/null> ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-6.c> +@@ -0,0 +1,21 @@> ++/* { dg-do compile } */> ++/* { dg-options "-O2 -fno-pic" } */> ++> ++typedef void (*dispatch_t)(long offset);> ++> ++dispatch_t dispatch[256];> ++> ++__attribute__ ((indirect_branch("thunk-extern")))> ++int> ++male_indirect_jump (long offset)> ++{> ++ dispatch[offset](offset);> ++ return 0;> ++}> ++> ++/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { ! x32 } } } } */> ++/* { dg-final { scan-assembler "pushq\[ \t\]%rax" { target x32 } } } */> ++/* { dg-final { scan-assembler-times "jmp\[ \t\]*\.LIND" 1 } } */> ++/* { dg-final { scan-assembler-times "call\[ \t\]*\.LIND" 1 } } */> ++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" } } */> ++/* { dg-final { scan-assembler-not {\t(lfence|pause)} } } */> +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-7.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-7.c> +new file mode 100644> +index 00000000000..2a19b54cd2e> +--- /dev/null> ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-7.c> +@@ -0,0 +1,44 @@> ++/* { dg-do compile } */> ++/* { dg-options "-O2 -fno-pic" } */> ++> ++void func0 (void);> ++void func1 (void);> ++void func2 (void);> ++void func3 (void);> ++void func4 (void);> ++void func4 (void);> ++void func5 (void);> ++> ++__attribute__ ((indirect_branch("thunk-extern")))> ++void> ++bar (int i)> ++{> ++ switch (i)> ++ {> ++ default:> ++ func0 ();> ++ break;> ++ case 1:> ++ func1 ();> ++ break;> ++ case 2:> ++ func2 ();> ++ break;> ++ case 3:> ++ func3 ();> ++ break;> ++ case 4:> ++ func4 ();> ++ break;> ++ case 5:> ++ func5 ();> ++ break;> ++ }> ++}> ++> ++/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*\.L\[0-9\]+\\(,%" { target { ! x32 } } } } */> ++/* { dg-final { scan-assembler "pushq\[ \t\]%rax" { target x32 } } } */> ++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" } } */> ++/* { dg-final { scan-assembler-not {\t(lfence|pause)} } } */> ++/* { dg-final { scan-assembler-not "jmp\[ \t\]*\.LIND" } } */> ++/* { dg-final { scan-assembler-not "call\[ \t\]*\.LIND" } } */> +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-8.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-8.c> +new file mode 100644> +index 00000000000..9f6d12d74a1> +--- /dev/null> ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-8.c> +@@ -0,0 +1,41 @@> ++/* { dg-do compile } */> ++/* { dg-options "-O2 -mindirect-branch=thunk -fno-pic" } */> ++> ++void func0 (void);> ++void func1 (void);> ++void func2 (void);> ++void func3 (void);> ++void func4 (void);> ++void func4 (void);> ++void func5 (void);> ++> ++__attribute__ ((indirect_branch("keep")))> ++void> ++bar (int i)> ++{> ++ switch (i)> ++ {> ++ default:> ++ func0 ();> ++ break;> ++ case 1:> ++ func1 ();> ++ break;> ++ case 2:> ++ func2 ();> ++ break;> ++ case 3:> ++ func3 ();> ++ break;> ++ case 4:> ++ func4 ();> ++ break;> ++ case 5:> ++ func5 ();> ++ break;> ++ }> ++}> ++> ++/* { dg-final { scan-assembler-not "__x86.indirect_thunk" } } */> ++/* { dg-final { scan-assembler-not "jmp\[ \t\]*\.LIND" } } */> ++/* { dg-final { scan-assembler-not "call\[ \t\]*\.LIND" } } */> +-- > +2.15.1> +> diff --git a/gnu/packages/patches/gcc-retpoline-Add-mfunction-return-and-function_return-attribute.patch b/gnu/packages/patches/gcc-retpoline-Add-mfunction-return-and-function_return-attribute.patch> new file mode 100644> index 000000000..0845de4b2> --- /dev/null> +++ b/gnu/packages/patches/gcc-retpoline-Add-mfunction-return-and-function_return-attribute.patch> @@ -0,0 +1,740 @@> +'Retpoline' mitigation technique for Spectre (branch target injection)> +[CVE-2017-5715]:> +> +https://security.googleblog.com/2018/01/more-details-about-mitigations-for-cpu_4.html> +https://support.google.com/faqs/answer/7625886> +https://spectreattack.com/> +https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2017-5715> +> +Patch copied from the 'retpoline-20180107' branch of upstream source repository> +(please add new / update existing patches when new 'retpoline-xxxxxxxx' branch> +appears):> +> +http://git.infradead.org/users/dwmw2/gcc-retpoline.git> +> +From 29d5a3f23c18c96944dd3230a41380a6edcd25fd Mon Sep 17 00:00:00 2001> +From: "H.J. Lu" <hjl.tools@gmail.com>> +Date: Tue, 5 Dec 2017 13:29:06 -0800> +Subject: [PATCH 11/17] Add -mfunction-return= and function_return attribute> +> +Add -mfunction-return= and function_return attribute tests> +> +-mfunction-return=thunk> + Convert function return instruction to PC-relative call thunk.> +-mfunction-return=thunk-inline> + Convert function return instruction to PC-relative call thunk with> + thunk inlined.> +-mfunction-return=thunk-extern> + Convert function return instruction to PC-relative call to external> + thunk.> +> +Add function_return attribute to function declaration> +> +__attribute__ ((function_return("thunk")))> +__attribute__ ((function_return("thunk-inline")))> +__attribute__ ((function_return("thunk-extern")))> +__attribute__ ((function_return("keep")))> +---> + gcc/config/i386/i386-protos.h | 1 +> + gcc/config/i386/i386.c | 146 +++++++++++++++++++++++++--> + gcc/config/i386/i386.h | 3 +> + gcc/config/i386/i386.md | 9 +-> + gcc/config/i386/i386.opt | 6 +-> + gcc/testsuite/gcc.target/i386/ret-thunk-1.c | 12 +++> + gcc/testsuite/gcc.target/i386/ret-thunk-10.c | 22 ++++> + gcc/testsuite/gcc.target/i386/ret-thunk-11.c | 22 ++++> + gcc/testsuite/gcc.target/i386/ret-thunk-12.c | 21 ++++> + gcc/testsuite/gcc.target/i386/ret-thunk-13.c | 21 ++++> + gcc/testsuite/gcc.target/i386/ret-thunk-14.c | 21 ++++> + gcc/testsuite/gcc.target/i386/ret-thunk-15.c | 21 ++++> + gcc/testsuite/gcc.target/i386/ret-thunk-16.c | 18 ++++> + gcc/testsuite/gcc.target/i386/ret-thunk-2.c | 12 +++> + gcc/testsuite/gcc.target/i386/ret-thunk-3.c | 12 +++> + gcc/testsuite/gcc.target/i386/ret-thunk-4.c | 12 +++> + gcc/testsuite/gcc.target/i386/ret-thunk-5.c | 14 +++> + gcc/testsuite/gcc.target/i386/ret-thunk-6.c | 13 +++> + gcc/testsuite/gcc.target/i386/ret-thunk-7.c | 13 +++> + gcc/testsuite/gcc.target/i386/ret-thunk-8.c | 14 +++> + gcc/testsuite/gcc.target/i386/ret-thunk-9.c | 23 +++++> + 21 files changed, 421 insertions(+), 15 deletions(-)> + create mode 100644 gcc/testsuite/gcc.target/i386/ret-thunk-1.c> + create mode 100644 gcc/testsuite/gcc.target/i386/ret-thunk-10.c> + create mode 100644 gcc/testsuite/gcc.target/i386/ret-thunk-11.c> + create mode 100644 gcc/testsuite/gcc.target/i386/ret-thunk-12.c> + create mode 100644 gcc/testsuite/gcc.target/i386/ret-thunk-13.c> + create mode 100644 gcc/testsuite/gcc.target/i386/ret-thunk-14.c> + create mode 100644 gcc/testsuite/gcc.target/i386/ret-thunk-15.c> + create mode 100644 gcc/testsuite/gcc.target/i386/ret-thunk-16.c> + create mode 100644 gcc/testsuite/gcc.target/i386/ret-thunk-2.c> + create mode 100644 gcc/testsuite/gcc.target/i386/ret-thunk-3.c> + create mode 100644 gcc/testsuite/gcc.target/i386/ret-thunk-4.c> + create mode 100644 gcc/testsuite/gcc.target/i386/ret-thunk-5.c> + create mode 100644 gcc/testsuite/gcc.target/i386/ret-thunk-6.c> + create mode 100644 gcc/testsuite/gcc.target/i386/ret-thunk-7.c> + create mode 100644 gcc/testsuite/gcc.target/i386/ret-thunk-8.c> + create mode 100644 gcc/testsuite/gcc.target/i386/ret-thunk-9.c> +> +diff --git a/gcc/config/i386/i386-protos.h b/gcc/config/i386/i386-protos.h> +index b746429f420..213663811de 100644> +--- a/gcc/config/i386/i386-protos.h> ++++ b/gcc/config/i386/i386-protos.h> +@@ -316,6 +316,7 @@ extern enum attr_cpu ix86_schedule;> + > + extern const char * ix86_output_call_insn (rtx_insn *insn, rtx call_op);> + extern const char * ix86_output_indirect_jmp (rtx call_op);> ++extern const char * ix86_output_function_return (bool long_p);> + extern bool ix86_operands_ok_for_move_multiple (rtx *operands, bool load,> + enum machine_mode mode);> + > +diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c> +index be1ff4752a9..7ae3523095c 100644> +--- a/gcc/config/i386/i386.c> ++++ b/gcc/config/i386/i386.c> +@@ -7166,6 +7166,31 @@ ix86_set_indirect_branch_type (tree fndecl)> + else> + cfun->machine->indirect_branch_type = ix86_indirect_branch;> + }> ++> ++ if (cfun->machine->function_return_type == indirect_branch_unset)> ++ {> ++ tree attr = lookup_attribute ("function_return",> ++ DECL_ATTRIBUTES (fndecl));> ++ if (attr != NULL)> ++ {> ++ tree args = TREE_VALUE (attr);> ++ if (args == NULL)> ++ gcc_unreachable ();> ++ tree cst = TREE_VALUE (args);> ++ if (strcmp (TREE_STRING_POINTER (cst), "keep") == 0)> ++ cfun->machine->function_return_type = indirect_branch_keep;> ++ else if (strcmp (TREE_STRING_POINTER (cst), "thunk") == 0)> ++ cfun->machine->function_return_type = indirect_branch_thunk;> ++ else if (strcmp (TREE_STRING_POINTER (cst), "thunk-inline") == 0)> ++ cfun->machine->function_return_type = indirect_branch_thunk_inline;> ++ else if (strcmp (TREE_STRING_POINTER (cst), "thunk-extern") == 0)> ++ cfun->machine->function_return_type = indirect_branch_thunk_extern;> ++ else> ++ gcc_unreachable ();> ++ }> ++ else> ++ cfun->machine->function_return_type = ix86_function_return;> ++ }> + }> + > + /* Establish appropriate back-end context for processing the function> +@@ -11958,8 +11983,12 @@ static int indirect_thunks_bnd_used;> + /* Fills in the label name that should be used for the indirect thunk. */> + > + static void> +-indirect_thunk_name (char name[32], int regno, bool need_bnd_p)> ++indirect_thunk_name (char name[32], int regno, bool need_bnd_p,> ++ bool ret_p)> + {> ++ if (regno >= 0 && ret_p)> ++ gcc_unreachable ();> ++> + if (USE_HIDDEN_LINKONCE)> + {> + const char *bnd = need_bnd_p ? "_bnd" : "";> +@@ -11974,7 +12003,10 @@ indirect_thunk_name (char name[32], int regno, bool need_bnd_p)> + bnd, reg_prefix, reg_names[regno]);> + }> + else> +- sprintf (name, "__x86.indirect_thunk%s", bnd);> ++ {> ++ const char *ret = ret_p ? "return" : "indirect";> ++ sprintf (name, "__x86.%s_thunk%s", ret, bnd);> ++ }> + }> + else> + {> +@@ -11987,10 +12019,20 @@ indirect_thunk_name (char name[32], int regno, bool need_bnd_p)> + }> + else> + {> +- if (need_bnd_p)> +- ASM_GENERATE_INTERNAL_LABEL (name, "LITB", 0);> ++ if (ret_p)> ++ {> ++ if (need_bnd_p)> ++ ASM_GENERATE_INTERNAL_LABEL (name, "LRTB", 0);> ++ else> ++ ASM_GENERATE_INTERNAL_LABEL (name, "LRT", 0);> ++ }> + else> +- ASM_GENERATE_INTERNAL_LABEL (name, "LIT", 0);> ++ {> ++ if (need_bnd_p)> ++ ASM_GENERATE_INTERNAL_LABEL (name, "LITB", 0);> ++ else> ++ ASM_GENERATE_INTERNAL_LABEL (name, "LIT", 0);> ++ }> + }> + }> + }> +@@ -12071,7 +12113,7 @@ output_indirect_thunk_function (bool need_bnd_p, int regno)> + tree decl;> + > + /* Create __x86.indirect_thunk/__x86.indirect_thunk_bnd. */> +- indirect_thunk_name (name, regno, need_bnd_p);> ++ indirect_thunk_name (name, regno, need_bnd_p, false);> + decl = build_decl (BUILTINS_LOCATION, FUNCTION_DECL,> + get_identifier (name),> + build_function_type_list (void_type_node, NULL_TREE));> +@@ -12114,6 +12156,35 @@ output_indirect_thunk_function (bool need_bnd_p, int regno)> + ASM_OUTPUT_LABEL (asm_out_file, name);> + }> + > ++ if (regno < 0)> ++ {> ++ /* Create alias for __x86.return_thunk/__x86.return_thunk_bnd. */> ++ char alias[32];> ++> ++ indirect_thunk_name (alias, regno, need_bnd_p, true);> ++ ASM_OUTPUT_DEF (asm_out_file, alias, name);> ++#if TARGET_MACHO> ++ if (TARGET_MACHO)> ++ {> ++ fputs ("\t.weak_definition\t", asm_out_file);> ++ assemble_name (asm_out_file, alias);> ++ fputs ("\n\t.private_extern\t", asm_out_file);> ++ assemble_name (asm_out_file, alias);> ++ putc ('\n', asm_out_file);> ++ }> ++#else> ++ if (USE_HIDDEN_LINKONCE)> ++ {> ++ fputs ("\t.globl\t", asm_out_file);> ++ assemble_name (asm_out_file, alias);> ++ putc ('\n', asm_out_file);> ++ fputs ("\t.hidden\t", asm_out_file);> ++ assemble_name (asm_out_file, alias);> ++ putc ('\n', asm_out_file);> ++ }> ++#endif> ++ }> ++> + DECL_INITIAL (decl) = make_node (BLOCK);> + current_function_decl = decl;> + allocate_struct_function (decl, false);> +@@ -28736,7 +28807,7 @@ ix86_output_indirect_branch (rtx call_op, const char *xasm,> + indirect_thunk_needed = true;> + }> + }> +- indirect_thunk_name (thunk_name_buf, regno, need_bnd_p);> ++ indirect_thunk_name (thunk_name_buf, regno, need_bnd_p, false);> + thunk_name = thunk_name_buf;> + }> + else> +@@ -28860,6 +28931,43 @@ ix86_output_indirect_jmp (rtx call_op)> + return "%!jmp\t%A0";> + }> + > ++const char *> ++ix86_output_function_return (bool long_p)> ++{> ++ if (cfun->machine->function_return_type != indirect_branch_keep)> ++ {> ++ char thunk_name[32];> ++ bool need_bnd_p = ix86_bnd_prefixed_insn_p (current_output_insn);> ++> ++ if (cfun->machine->function_return_type> ++ != indirect_branch_thunk_inline)> ++ {> ++ bool need_thunk = (cfun->machine->function_return_type> ++ == indirect_branch_thunk);> ++ indirect_thunk_name (thunk_name, -1, need_bnd_p, true);> ++ if (need_bnd_p)> ++ {> ++ indirect_thunk_bnd_needed |= need_thunk;> ++ fprintf (asm_out_file, "\tbnd jmp\t%s\n", thunk_name);> ++ }> ++ else> ++ {> ++ indirect_thunk_needed |= need_thunk;> ++ fprintf (asm_out_file, "\tjmp\t%s\n", thunk_name);> ++ }> ++ }> ++ else> ++ output_indirect_thunk (need_bnd_p, -1);> ++> ++ return "";> ++ }> ++> ++ if (!long_p || ix86_bnd_prefixed_insn_p (current_output_insn))> ++ return "%!ret";> ++> ++ return "rep%; ret";> ++}> ++> + /* Output the assembly for a call instruction. */> + > + const char *> +@@ -41916,6 +42024,28 @@ ix86_handle_fndecl_attribute (tree *node, tree name, tree args, int,> + }> + }> + > ++ if (is_attribute_p ("function_return", name))> ++ {> ++ tree cst = TREE_VALUE (args);> ++ if (TREE_CODE (cst) != STRING_CST)> ++ {> ++ warning (OPT_Wattributes,> ++ "%qE attribute requires a string constant argument",> ++ name);> ++ *no_add_attrs = true;> ++ }> ++ else if (strcmp (TREE_STRING_POINTER (cst), "keep") != 0> ++ && strcmp (TREE_STRING_POINTER (cst), "thunk") != 0> ++ && strcmp (TREE_STRING_POINTER (cst), "thunk-inline") != 0> ++ && strcmp (TREE_STRING_POINTER (cst), "thunk-extern") != 0)> ++ {> ++ warning (OPT_Wattributes,> ++ "argument to %qE attribute is not "> ++ "(keep|thunk|thunk-inline|thunk-extern)", name);> ++ *no_add_attrs = true;> ++ }> ++ }> ++> + return NULL_TREE;> + }> + > +@@ -46212,6 +46342,8 @@ static const struct attribute_spec ix86_attribute_table[] => + ix86_handle_no_caller_saved_registers_attribute, false },> + { "indirect_branch", 1, 1, true, false, false,> + ix86_handle_fndecl_attribute, false },> ++ { "function_return", 1, 1, true, false, false,> ++ ix86_handle_fndecl_attribute, false },> + > + /* End element. */> + { NULL, 0, 0, false, false, false, NULL, false }> +diff --git a/gcc/config/i386/i386.h b/gcc/config/i386/i386.h> +index a9c199a107c..f248f3ba2f5 100644> +--- a/gcc/config/i386/i386.h> ++++ b/gcc/config/i386/i386.h> +@@ -2607,6 +2607,9 @@ struct GTY(()) machine_function {> + /* How to generate indirec branch. */> + ENUM_BITFIELD(indirect_branch) indirect_branch_type : 3;> + > ++ /* How to generate function return. */> ++ ENUM_BITFIELD(indirect_branch) function_return_type : 3;> ++> + /* If true, the current function is a function specified with> + the "interrupt" or "no_caller_saved_registers" attribute. */> + BOOL_BITFIELD no_caller_saved_registers : 1;> +diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md> +index 01b7b2039e6..00a9afef225 100644> +--- a/gcc/config/i386/i386.md> ++++ b/gcc/config/i386/i386.md> +@@ -12288,7 +12288,7 @@> + (define_insn "simple_return_internal"> + [(simple_return)]> + "reload_completed"> +- "%!ret"> ++ "* return ix86_output_function_return (false);"> + [(set_attr "length" "1")> + (set_attr "atom_unit" "jeu")> + (set_attr "length_immediate" "0")> +@@ -12310,12 +12310,7 @@> + [(simple_return)> + (unspec [(const_int 0)] UNSPEC_REP)]> + "reload_completed"> +-{> +- if (ix86_bnd_prefixed_insn_p (insn))> +- return "%!ret";> +-> +- return "rep%; ret";> +-}> ++ "* return ix86_output_function_return (true);"> + [(set_attr "length" "2")> + (set_attr "atom_unit" "jeu")> + (set_attr "length_immediate" "0")> +diff --git a/gcc/config/i386/i386.opt b/gcc/config/i386/i386.opt> +index bc81e6bea86..fc2c81c3fb5 100644> +--- a/gcc/config/i386/i386.opt> ++++ b/gcc/config/i386/i386.opt> +@@ -932,9 +932,13 @@ mindirect-branch=> + Target Report RejectNegative Joined Enum(indirect_branch) Var(ix86_indirect_branch) Init(indirect_branch_keep)> + Update indirect call and jump.> + > ++mfunction-return=> ++Target Report RejectNegative Joined Enum(indirect_branch) Var(ix86_function_return) Init(indirect_branch_keep)> ++Update function return.> ++> + Enum> + Name(indirect_branch) Type(enum indirect_branch)> +-Known indirect branch choices (for use with the -mindirect-branch= option):> ++Known indirect branch choices (for use with the -mindirect-branch=/-mfunction-return= options):> + > + EnumValue> + Enum(indirect_branch) String(keep) Value(indirect_branch_keep)> +diff --git a/gcc/testsuite/gcc.target/i386/ret-thunk-1.c b/gcc/testsuite/gcc.target/i386/ret-thunk-1.c> +new file mode 100644> +index 00000000000..406956f48e5> +--- /dev/null> ++++ b/gcc/testsuite/gcc.target/i386/ret-thunk-1.c> +@@ -0,0 +1,12 @@> ++/* { dg-do compile } */> ++/* { dg-options "-O2 -mfunction-return=thunk" } */> ++> ++void> ++foo (void)> ++{> ++}> ++> ++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.return_thunk" } } */> ++/* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */> ++/* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */> ++/* { dg-final { scan-assembler {\tlfence} } } */> +diff --git a/gcc/testsuite/gcc.target/i386/ret-thunk-10.c b/gcc/testsuite/gcc.target/i386/ret-thunk-10.c> +new file mode 100644> +index 00000000000..aecea4224f9> +--- /dev/null> ++++ b/gcc/testsuite/gcc.target/i386/ret-thunk-10.c> +@@ -0,0 +1,22 @@> ++/* { dg-do compile } */> ++/* { dg-options "-O2 -mfunction-return=thunk-inline -mindirect-branch=thunk -fno-pic" } */> ++> ++extern void (*bar) (void);> ++> ++int> ++foo (void)> ++{> ++ bar ();> ++ return 0;> ++}> ++> ++/* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */> ++/* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */> ++/* { dg-final { scan-assembler-not "jmp\[ \t\]*__x86.return_thunk" } } */> ++/* { dg-final { scan-assembler-times {\tlfence} 2 } } */> ++/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?bar" { target { ! x32 } } } } */> ++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" { target { ! x32 } } } } */> ++/* { dg-final { scan-assembler "__x86.indirect_thunk:" { target { ! x32 } } } } */> ++/* { dg-final { scan-assembler "call\[ \t\]*__x86.indirect_thunk\.(r|e)ax" { target { x32 } } } } */> ++/* { dg-final { scan-assembler "__x86.indirect_thunk\.(r|e)ax:" { target { x32 } } } } */> ++/* { dg-final { scan-assembler-not "pushq\[ \t\]%rax" { target x32 } } } */> +diff --git a/gcc/testsuite/gcc.target/i386/ret-thunk-11.c b/gcc/testsuite/gcc.target/i386/ret-thunk-11.c> +new file mode 100644> +index 00000000000..3bacfb54dfd> +--- /dev/null> ++++ b/gcc/testsuite/gcc.target/i386/ret-thunk-11.c> +@@ -0,0 +1,22 @@> ++/* { dg-do compile } */> ++/* { dg-options "-O2 -mfunction-return=thunk-extern -mindirect-branch=thunk -fno-pic" } */> ++> ++extern void (*bar) (void);> ++> ++int> ++foo (void)> ++{> ++ bar ();> ++ return 0;> ++}> ++> ++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.return_thunk" } } */> ++/* { dg-final { scan-assembler-times {\tlfence} 1 } } */> ++/* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */> ++/* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */> ++/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?bar" { target { ! x32 } } } } */> ++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" { target { ! x32 } } } } */> ++/* { dg-final { scan-assembler "__x86.indirect_thunk:" { target { ! x32 } } } } */> ++/* { dg-final { scan-assembler "call\[ \t\]*__x86.indirect_thunk\.(r|e)ax" { target { x32 } } } } */> ++/* { dg-final { scan-assembler "__x86.indirect_thunk\.(r|e)ax:" { target { x32 } } } } */> ++/* { dg-final { scan-assembler-not "pushq\[ \t\]%rax" { target x32 } } } */> +diff --git a/gcc/testsuite/gcc.target/i386/ret-thunk-12.c b/gcc/testsuite/gcc.target/i386/ret-thunk-12.c> +new file mode 100644> +index 00000000000..851115ac507> +--- /dev/null> ++++ b/gcc/testsuite/gcc.target/i386/ret-thunk-12.c> +@@ -0,0 +1,21 @@> ++/* { dg-do compile } */> ++/* { dg-options "-O2 -mfunction-return=keep -mindirect-branch=thunk -fno-pic" } */> ++> ++extern void (*bar) (void);> ++> ++int> ++foo (void)> ++{> ++ bar ();> ++ return 0;> ++}> ++> ++/* { dg-final { scan-assembler-not "jmp\[ \t\]*__x86.return_thunk" } } */> ++/* { dg-final { scan-assembler-times {\tlfence} 1 } } */> ++/* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */> ++/* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */> ++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" { target { ! x32 } } } } */> ++/* { dg-final { scan-assembler "__x86.indirect_thunk:" { target { ! x32 } } } } */> ++/* { dg-final { scan-assembler "call\[ \t\]*__x86.indirect_thunk\.(r|e)ax" { target { x32 } } } } */> ++/* { dg-final { scan-assembler "__x86.indirect_thunk\.(r|e)ax:" { target { x32 } } } } */> ++/* { dg-final { scan-assembler-not "pushq\[ \t\]%rax" { target x32 } } } */> +diff --git a/gcc/testsuite/gcc.target/i386/ret-thunk-13.c b/gcc/testsuite/gcc.target/i386/ret-thunk-13.c> +new file mode 100644> +index 00000000000..7acb6fa5eae> +--- /dev/null> ++++ b/gcc/testsuite/gcc.target/i386/ret-thunk-13.c> +@@ -0,0 +1,21 @@> ++/* { dg-do compile } */> ++/* { dg-options "-O2 -mfunction-return=keep -mindirect-branch=thunk-inline -fno-pic" } */> ++> ++extern void (*bar) (void);> ++extern int foo (void) __attribute__ ((function_return("thunk")));> ++> ++int> ++foo (void)> ++{> ++ bar ();> ++ return 0;> ++}> ++> ++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.return_thunk" } } */> ++/* { dg-final { scan-assembler-times {\tlfence} 2 } } */> ++/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?bar" { target { ! x32 } } } } */> ++/* { dg-final { scan-assembler-times "jmp\[ \t\]*\.LIND" 3 } } */> ++/* { dg-final { scan-assembler-times "call\[ \t\]*\.LIND" 3 } } */> ++/* { dg-final { scan-assembler-not "jmp\[ \t\]*__x86.indirect_thunk" } } */> ++/* { dg-final { scan-assembler-not "call\[ \t\]*__x86.indirect_thunk\.(r|e)ax" { target { x32 } } } } */> ++/* { dg-final { scan-assembler-not "pushq\[ \t\]%rax" { target x32 } } } */> +diff --git a/gcc/testsuite/gcc.target/i386/ret-thunk-14.c b/gcc/testsuite/gcc.target/i386/ret-thunk-14.c> +new file mode 100644> +index 00000000000..bf340fac7c6> +--- /dev/null> ++++ b/gcc/testsuite/gcc.target/i386/ret-thunk-14.c> +@@ -0,0 +1,21 @@> ++/* { dg-do compile } */> ++/* { dg-options "-O2 -mfunction-return=keep -mindirect-branch=thunk-extern -fno-pic" } */> ++> ++extern void (*bar) (void);> ++> ++__attribute__ ((function_return("thunk-inline")))> ++int> ++foo (void)> ++{> ++ bar ();> ++ return 0;> ++}> ++> ++/* { dg-final { scan-assembler-times {\tlfence} 1 } } */> ++/* { dg-final { scan-assembler-not "jmp\[ \t\]*__x86.return_thunk" } } */> ++/* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */> ++/* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */> ++/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?bar" { target { ! x32 } } } } */> ++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" { target { ! x32 } } } } */> ++/* { dg-final { scan-assembler "call\[ \t\]*__x86.indirect_thunk\.(r|e)ax" { target { x32 } } } } */> ++/* { dg-final { scan-assembler-not "pushq\[ \t\]%rax" { target x32 } } } */> +diff --git a/gcc/testsuite/gcc.target/i386/ret-thunk-15.c b/gcc/testsuite/gcc.target/i386/ret-thunk-15.c> +new file mode 100644> +index 00000000000..735f8648c96> +--- /dev/null> ++++ b/gcc/testsuite/gcc.target/i386/ret-thunk-15.c> +@@ -0,0 +1,21 @@> ++/* { dg-do compile } */> ++/* { dg-options "-O2 -mfunction-return=keep -mindirect-branch=keep -fno-pic" } */> ++> ++extern void (*bar) (void);> ++> ++__attribute__ ((function_return("thunk-extern"), indirect_branch("thunk")))> ++int> ++foo (void)> ++{> ++ bar ();> ++ return 0;> ++}> ++> ++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.return_thunk" } } */> ++/* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */> ++/* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */> ++/* { dg-final { scan-assembler-times {\tlfence} 1 } } */> ++/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?bar" { target { ! x32 } } } } */> ++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" { target { ! x32 } } } } */> ++/* { dg-final { scan-assembler "call\[ \t\]*__x86.indirect_thunk\.(r|e)ax" { target x32 } } } */> ++/* { dg-final { scan-assembler-not "pushq\[ \t\]%rax" { target x32 } } } */> +diff --git a/gcc/testsuite/gcc.target/i386/ret-thunk-16.c b/gcc/testsuite/gcc.target/i386/ret-thunk-16.c> +new file mode 100644> +index 00000000000..cf3920563e0> +--- /dev/null> ++++ b/gcc/testsuite/gcc.target/i386/ret-thunk-16.c> +@@ -0,0 +1,18 @@> ++/* { dg-do compile } */> ++/* { dg-options "-O2 -mfunction-return=thunk-inline -mindirect-branch=thunk-extern -fno-pic" } */> ++> ++extern void (*bar) (void);> ++> ++__attribute__ ((function_return("keep"), indirect_branch("keep")))> ++int> ++foo (void)> ++{> ++ bar ();> ++ return 0;> ++}> ++> ++/* { dg-final { scan-assembler-not "__x86.indirect_thunk" } } */> ++/* { dg-final { scan-assembler-not "__x86.return_thunk" } } */> ++/* { dg-final { scan-assembler-not {\tlfence} } } */> ++/* { dg-final { scan-assembler-not "jmp\[ \t\]*\.LIND" } } */> ++/* { dg-final { scan-assembler-not "call\[ \t\]*\.LIND" } } */> +diff --git a/gcc/testsuite/gcc.target/i386/ret-thunk-2.c b/gcc/testsuite/gcc.target/i386/ret-thunk-2.c> +new file mode 100644> +index 00000000000..190947cc2ca> +--- /dev/null> ++++ b/gcc/testsuite/gcc.target/i386/ret-thunk-2.c> +@@ -0,0 +1,12 @@> ++/* { dg-do compile } */> ++/* { dg-options "-O2 -mfunction-return=thunk-inline" } */> ++> ++void> ++foo (void)> ++{> ++}> ++> ++/* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */> ++/* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */> ++/* { dg-final { scan-assembler {\tlfence} } } */> ++/* { dg-final { scan-assembler-not "jmp\[ \t\]*__x86.return_thunk" } } */> +diff --git a/gcc/testsuite/gcc.target/i386/ret-thunk-3.c b/gcc/testsuite/gcc.target/i386/ret-thunk-3.c> +new file mode 100644> +index 00000000000..d71de3ac520> +--- /dev/null> ++++ b/gcc/testsuite/gcc.target/i386/ret-thunk-3.c> +@@ -0,0 +1,12 @@> ++/* { dg-do compile } */> ++/* { dg-options "-O2 -mfunction-return=thunk-extern" } */> ++> ++void> ++foo (void)> ++{> ++}> ++> ++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.return_thunk" } } */> ++/* { dg-final { scan-assembler-not {\tlfence} } } */> ++/* { dg-final { scan-assembler-not "jmp\[ \t\]*\.LIND" } } */> ++/* { dg-final { scan-assembler-not "call\[ \t\]*\.LIND" } } */> +diff --git a/gcc/testsuite/gcc.target/i386/ret-thunk-4.c b/gcc/testsuite/gcc.target/i386/ret-thunk-4.c> +new file mode 100644> +index 00000000000..68c22122f0d> +--- /dev/null> ++++ b/gcc/testsuite/gcc.target/i386/ret-thunk-4.c> +@@ -0,0 +1,12 @@> ++/* { dg-do compile } */> ++/* { dg-options "-O2 -mfunction-return=keep" } */> ++> ++void> ++foo (void)> ++{> ++}> ++> ++/* { dg-final { scan-assembler-not "jmp\[ \t\]*__x86.return_thunk" } } */> ++/* { dg-final { scan-assembler-not {\tlfence} } } */> ++/* { dg-final { scan-assembler-not "jmp\[ \t\]*\.LIND" } } */> ++/* { dg-final { scan-assembler-not "call\[ \t\]*\.LIND" } } */> +diff --git a/gcc/testsuite/gcc.target/i386/ret-thunk-5.c b/gcc/testsuite/gcc.target/i386/ret-thunk-5.c> +new file mode 100644> +index 00000000000..28c576e2267> +--- /dev/null> ++++ b/gcc/testsuite/gcc.target/i386/ret-thunk-5.c> +@@ -0,0 +1,14 @@> ++/* { dg-do compile } */> ++/* { dg-options "-O2 -mfunction-return=keep" } */> ++> ++extern void foo (void) __attribute__ ((function_return("thunk")));> ++> ++void> ++foo (void)> ++{> ++}> ++> ++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.return_thunk" } } */> ++/* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */> ++/* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */> ++/* { dg-final { scan-assembler {\tlfence} } } */> +diff --git a/gcc/testsuite/gcc.target/i386/ret-thunk-6.c b/gcc/testsuite/gcc.target/i386/ret-thunk-6.c> +new file mode 100644> +index 00000000000..10ad40b9c26> +--- /dev/null> ++++ b/gcc/testsuite/gcc.target/i386/ret-thunk-6.c> +@@ -0,0 +1,13 @@> ++/* { dg-do compile } */> ++/* { dg-options "-O2 -mfunction-return=keep" } */> ++> ++__attribute__ ((function_return("thunk-inline")))> ++void> ++foo (void)> ++{> ++}> ++> ++/* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */> ++/* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */> ++/* { dg-final { scan-assembler {\tlfence} } } */> ++/* { dg-final { scan-assembler-not "jmp\[ \t\]*__x86.return_thunk" } } */> +diff --git a/gcc/testsuite/gcc.target/i386/ret-thunk-7.c b/gcc/testsuite/gcc.target/i386/ret-thunk-7.c> +new file mode 100644> +index 00000000000..7ac0beaa73e> +--- /dev/null> ++++ b/gcc/testsuite/gcc.target/i386/ret-thunk-7.c> +@@ -0,0 +1,13 @@> ++/* { dg-do compile } */> ++/* { dg-options "-O2 -mfunction-return=keep" } */> ++> ++__attribute__ ((function_return("thunk-extern")))> ++void> ++foo (void)> ++{> ++}> ++> ++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.return_thunk" } } */> ++/* { dg-final { scan-assembler-not {\tlfence} } } */> ++/* { dg-final { scan-assembler-not "jmp\[ \t\]*\.LIND" } } */> ++/* { dg-final { scan-assembler-not "call\[ \t\]*\.LIND" } } */> +diff --git a/gcc/testsuite/gcc.target/i386/ret-thunk-8.c b/gcc/testsuite/gcc.target/i386/ret-thunk-8.c> +new file mode 100644> +index 00000000000..777ab7c8088> +--- /dev/null> ++++ b/gcc/testsuite/gcc.target/i386/ret-thunk-8.c> +@@ -0,0 +1,14 @@> ++/* { dg-do compile } */> ++/* { dg-options "-O2 -mfunction-return=thunk-inline" } */> ++> ++extern void foo (void) __attribute__ ((function_return("keep")));> ++> ++void> ++foo (void)> ++{> ++}> ++> ++/* { dg-final { scan-assembler-not "jmp\[ \t\]*__x86.return_thunk" } } */> ++/* { dg-final { scan-assembler-not {\tlfence} } } */> ++/* { dg-final { scan-assembler-not "jmp\[ \t\]*\.LIND" } } */> ++/* { dg-final { scan-assembler-not "call\[ \t\]*\.LIND" } } */> +diff --git a/gcc/testsuite/gcc.target/i386/ret-thunk-9.c b/gcc/testsuite/gcc.target/i386/ret-thunk-9.c> +new file mode 100644> +index 00000000000..569e5f47973> +--- /dev/null> ++++ b/gcc/testsuite/gcc.target/i386/ret-thunk-9.c> +@@ -0,0 +1,23 @@> ++/* { dg-do compile } */> ++/* { dg-options "-O2 -mfunction-return=thunk -mindirect-branch=thunk -fno-pic" } */> ++> ++extern void (*bar) (void);> ++> ++int> ++foo (void)> ++{> ++ bar ();> ++ return 0;> ++}> ++> ++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.return_thunk" } } */> ++/* { dg-final { scan-assembler-not "__x86.return_thunk:" } } */> ++/* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */> ++/* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */> ++/* { dg-final { scan-assembler "__x86.indirect_thunk:" } } */> ++/* { dg-final { scan-assembler-times {\tlfence} 1 { target { ! x32 } } } } */> ++/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?bar" { target { ! x32 } } } } */> ++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" { target { ! x32 } } } } */> ++/* { dg-final { scan-assembler-times {\tlfence} 2 { target { x32 } } } } */> ++/* { dg-final { scan-assembler "call\[ \t\]*__x86.indirect_thunk\.(r|e)ax" { target { x32 } } } } */> ++/* { dg-final { scan-assembler-not "pushq\[ \t\]%rax" { target x32 } } } */> +-- > +2.15.1> +> diff --git a/gnu/packages/patches/gcc-retpoline-Add-mfunction-return-keep-to-indirect-branch-tests.patch b/gnu/packages/patches/gcc-retpoline-Add-mfunction-return-keep-to-indirect-branch-tests.patch> new file mode 100644> index 000000000..ac900bab0> --- /dev/null> +++ b/gnu/packages/patches/gcc-retpoline-Add-mfunction-return-keep-to-indirect-branch-tests.patch> @@ -0,0 +1,421 @@> +'Retpoline' mitigation technique for Spectre (branch target injection)> +[CVE-2017-5715]:> +> +https://security.googleblog.com/2018/01/more-details-about-mitigations-for-cpu_4.html> +https://support.google.com/faqs/answer/7625886> +https://spectreattack.com/> +https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2017-5715> +> +Patch copied from the 'retpoline-20180107' branch of upstream source repository> +(please add new / update existing patches when new 'retpoline-xxxxxxxx' branch> +appears):> +> +http://git.infradead.org/users/dwmw2/gcc-retpoline.git> +> +From def2b5d75fd6234984ec969f4586fcb8c516a3b9 Mon Sep 17 00:00:00 2001> +From: "H.J. Lu" <hjl.tools@gmail.com>> +Date: Wed, 6 Dec 2017 09:58:42 -0800> +Subject: [PATCH 12/17] Add -mfunction-return=keep to indirect branch tests> +> +---> + gcc/testsuite/gcc.target/i386/indirect-thunk-1.c | 2 +-> + gcc/testsuite/gcc.target/i386/indirect-thunk-2.c | 2 +-> + gcc/testsuite/gcc.target/i386/indirect-thunk-3.c | 2 +-> + gcc/testsuite/gcc.target/i386/indirect-thunk-4.c | 2 +-> + gcc/testsuite/gcc.target/i386/indirect-thunk-5.c | 2 +-> + gcc/testsuite/gcc.target/i386/indirect-thunk-6.c | 2 +-> + gcc/testsuite/gcc.target/i386/indirect-thunk-7.c | 2 +-> + gcc/testsuite/gcc.target/i386/indirect-thunk-attr-1.c | 2 +-> + gcc/testsuite/gcc.target/i386/indirect-thunk-attr-2.c | 2 +-> + gcc/testsuite/gcc.target/i386/indirect-thunk-attr-3.c | 2 +-> + gcc/testsuite/gcc.target/i386/indirect-thunk-attr-4.c | 2 +-> + gcc/testsuite/gcc.target/i386/indirect-thunk-attr-5.c | 2 +-> + gcc/testsuite/gcc.target/i386/indirect-thunk-attr-6.c | 2 +-> + gcc/testsuite/gcc.target/i386/indirect-thunk-attr-7.c | 2 +-> + gcc/testsuite/gcc.target/i386/indirect-thunk-attr-8.c | 2 +-> + gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-1.c | 2 +-> + gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-2.c | 2 +-> + gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-3.c | 2 +-> + gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-4.c | 2 +-> + gcc/testsuite/gcc.target/i386/indirect-thunk-extern-1.c | 2 +-> + gcc/testsuite/gcc.target/i386/indirect-thunk-extern-2.c | 2 +-> + gcc/testsuite/gcc.target/i386/indirect-thunk-extern-3.c | 2 +-> + gcc/testsuite/gcc.target/i386/indirect-thunk-extern-4.c | 2 +-> + gcc/testsuite/gcc.target/i386/indirect-thunk-extern-5.c | 2 +-> + gcc/testsuite/gcc.target/i386/indirect-thunk-extern-6.c | 2 +-> + gcc/testsuite/gcc.target/i386/indirect-thunk-extern-7.c | 2 +-> + gcc/testsuite/gcc.target/i386/indirect-thunk-inline-1.c | 2 +-> + gcc/testsuite/gcc.target/i386/indirect-thunk-inline-2.c | 2 +-> + gcc/testsuite/gcc.target/i386/indirect-thunk-inline-3.c | 2 +-> + gcc/testsuite/gcc.target/i386/indirect-thunk-inline-4.c | 2 +-> + gcc/testsuite/gcc.target/i386/indirect-thunk-inline-5.c | 2 +-> + gcc/testsuite/gcc.target/i386/indirect-thunk-inline-6.c | 2 +-> + gcc/testsuite/gcc.target/i386/indirect-thunk-inline-7.c | 2 +-> + 33 files changed, 33 insertions(+), 33 deletions(-)> +> +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-1.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-1.c> +index 785e593405f..318db1e7f5c 100644> +--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-1.c> ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-1.c> +@@ -1,5 +1,5 @@> + /* { dg-do compile } */> +-/* { dg-options "-O2 -mindirect-branch=thunk -fno-pic" } */> ++/* { dg-options "-O2 -mfunction-return=keep -mindirect-branch=thunk -fno-pic" } */> + > + typedef void (*dispatch_t)(long offset);> + > +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-2.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-2.c> +index b69075e6483..f2700dd36cf 100644> +--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-2.c> ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-2.c> +@@ -1,5 +1,5 @@> + /* { dg-do compile } */> +-/* { dg-options "-O2 -mindirect-branch=thunk -fno-pic" } */> ++/* { dg-options "-O2 -mfunction-return=keep -mindirect-branch=thunk -fno-pic" } */> + > + typedef void (*dispatch_t)(long offset);> + > +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-3.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-3.c> +index df8109baf55..46685d9a674 100644> +--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-3.c> ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-3.c> +@@ -1,5 +1,5 @@> + /* { dg-do compile } */> +-/* { dg-options "-O2 -mindirect-branch=thunk -fno-pic" } */> ++/* { dg-options "-O2 -mfunction-return=keep -mindirect-branch=thunk -fno-pic" } */> + > + typedef void (*dispatch_t)(long offset);> + > +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-4.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-4.c> +index 8f3b9f4d8a5..8f701775cea 100644> +--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-4.c> ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-4.c> +@@ -1,5 +1,5 @@> + /* { dg-do compile } */> +-/* { dg-options "-O2 -mindirect-branch=thunk -fno-pic" } */> ++/* { dg-options "-O2 -mfunction-return=keep -mindirect-branch=thunk -fno-pic" } */> + > + typedef void (*dispatch_t)(long offset);> + > +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-5.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-5.c> +index 1a9bb0e431e..f88ac31d07a 100644> +--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-5.c> ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-5.c> +@@ -1,5 +1,5 @@> + /* { dg-do compile { target *-*-linux* } } */> +-/* { dg-options "-O2 -fpic -fno-plt -mindirect-branch=thunk" } */> ++/* { dg-options "-O2 -mfunction-return=keep -fpic -fno-plt -mindirect-branch=thunk" } */> + > + extern void bar (void);> + > +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-6.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-6.c> +index bc7d20ec6ad..d745116d321 100644> +--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-6.c> ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-6.c> +@@ -1,5 +1,5 @@> + /* { dg-do compile { target *-*-linux* } } */> +-/* { dg-options "-O2 -fpic -fno-plt -mindirect-branch=thunk" } */> ++/* { dg-options "-O2 -mfunction-return=keep -fpic -fno-plt -mindirect-branch=thunk" } */> + > + extern void bar (void);> + > +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-7.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-7.c> +index f0e1cfe1893..969cb8c6ddc 100644> +--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-7.c> ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-7.c> +@@ -1,5 +1,5 @@> + /* { dg-do compile } */> +-/* { dg-options "-O2 -mindirect-branch=thunk -fno-pic" } */> ++/* { dg-options "-O2 -mfunction-return=keep -mindirect-branch=thunk -fno-pic" } */> + > + void func0 (void);> + void func1 (void);> +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-1.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-1.c> +index 8b88449e625..12a61c3bbc7 100644> +--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-1.c> ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-1.c> +@@ -1,5 +1,5 @@> + /* { dg-do compile } */> +-/* { dg-options "-O2 -fno-pic" } */> ++/* { dg-options "-O2 -mfunction-return=keep -fno-pic" } */> + > + typedef void (*dispatch_t)(long offset);> + > +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-2.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-2.c> +index c69f7bf4f60..a06907933a2 100644> +--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-2.c> ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-2.c> +@@ -1,5 +1,5 @@> + /* { dg-do compile } */> +-/* { dg-options "-O2 -fno-pic" } */> ++/* { dg-options "-O2 -mfunction-return=keep -fno-pic" } */> + > + typedef void (*dispatch_t)(long offset);> + > +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-3.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-3.c> +index c845099a83e..7f56725e6b6 100644> +--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-3.c> ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-3.c> +@@ -1,5 +1,5 @@> + /* { dg-do compile } */> +-/* { dg-options "-O2 -fno-pic" } */> ++/* { dg-options "-O2 -mfunction-return=keep -fno-pic" } */> + > + typedef void (*dispatch_t)(long offset);> + > +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-4.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-4.c> +index f636f3422fd..fd4ab1dbaa0 100644> +--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-4.c> ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-4.c> +@@ -1,5 +1,5 @@> + /* { dg-do compile } */> +-/* { dg-options "-O2 -fno-pic" } */> ++/* { dg-options "-O2 -mfunction-return=keep -fno-pic" } */> + > + typedef void (*dispatch_t)(long offset);> + > +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-5.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-5.c> +index 5f1d6a78041..1ffbf3b1181 100644> +--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-5.c> ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-5.c> +@@ -1,5 +1,5 @@> + /* { dg-do compile } */> +-/* { dg-options "-O2 -fno-pic" } */> ++/* { dg-options "-O2 -mfunction-return=keep -fno-pic" } */> + > + typedef void (*dispatch_t)(long offset);> + > +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-6.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-6.c> +index 56c92da9812..1559072919a 100644> +--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-6.c> ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-6.c> +@@ -1,5 +1,5 @@> + /* { dg-do compile } */> +-/* { dg-options "-O2 -fno-pic" } */> ++/* { dg-options "-O2 -mfunction-return=keep -fno-pic" } */> + > + typedef void (*dispatch_t)(long offset);> + > +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-7.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-7.c> +index cfb6f5b234b..1717e7bb436 100644> +--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-7.c> ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-7.c> +@@ -1,5 +1,5 @@> + /* { dg-do compile } */> +-/* { dg-options "-O2 -fno-pic" } */> ++/* { dg-options "-O2 -mfunction-return=keep -fno-pic" } */> + > + void func0 (void);> + void func1 (void);> +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-8.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-8.c> +index 9f6d12d74a1..af1bb125a22 100644> +--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-8.c> ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-8.c> +@@ -1,5 +1,5 @@> + /* { dg-do compile } */> +-/* { dg-options "-O2 -mindirect-branch=thunk -fno-pic" } */> ++/* { dg-options "-O2 -mfunction-return=keep -mindirect-branch=thunk -fno-pic" } */> + > + void func0 (void);> + void func1 (void);> +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-1.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-1.c> +index a5b1d38e061..20903b0f79d 100644> +--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-1.c> ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-1.c> +@@ -1,5 +1,5 @@> + /* { dg-do compile { target { ! x32 } } } */> +-/* { dg-options "-O2 -mindirect-branch=thunk -fcheck-pointer-bounds -mmpx -fno-pic" } */> ++/* { dg-options "-O2 -mfunction-return=keep -mindirect-branch=thunk -fcheck-pointer-bounds -mmpx -fno-pic" } */> + > + void (*dispatch) (char *);> + char buf[10];> +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-2.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-2.c> +index a42add209e2..aef4bd144f4 100644> +--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-2.c> ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-2.c> +@@ -1,5 +1,5 @@> + /* { dg-do compile { target { ! x32 } } } */> +-/* { dg-options "-O2 -mindirect-branch=thunk -fcheck-pointer-bounds -mmpx -fno-pic" } */> ++/* { dg-options "-O2 -mfunction-return=keep -mindirect-branch=thunk -fcheck-pointer-bounds -mmpx -fno-pic" } */> + > + void (*dispatch) (char *);> + char buf[10];> +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-3.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-3.c> +index 265e010a0fe..2cc0343f828 100644> +--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-3.c> ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-3.c> +@@ -1,5 +1,5 @@> + /* { dg-do compile { target { *-*-linux* && { ! x32 } } } } */> +-/* { dg-options "-O2 -mindirect-branch=thunk -fcheck-pointer-bounds -mmpx -fpic -fno-plt" } */> ++/* { dg-options "-O2 -mfunction-return=keep -mindirect-branch=thunk -fcheck-pointer-bounds -mmpx -fpic -fno-plt" } */> + > + void bar (char *);> + char buf[10];> +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-4.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-4.c> +index 1c01bcb7fc6..91560fef661 100644> +--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-4.c> ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-4.c> +@@ -1,5 +1,5 @@> + /* { dg-do compile { target { *-*-linux* && { ! x32 } } } } */> +-/* { dg-options "-O2 -mindirect-branch=thunk -fcheck-pointer-bounds -mmpx -fpic -fno-plt" } */> ++/* { dg-options "-O2 -mfunction-return=keep -mindirect-branch=thunk -fcheck-pointer-bounds -mmpx -fpic -fno-plt" } */> + > + void bar (char *);> + char buf[10];> +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-1.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-1.c> +index f1fa0a11922..dc6bd10af4c 100644> +--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-1.c> ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-1.c> +@@ -1,5 +1,5 @@> + /* { dg-do compile } */> +-/* { dg-options "-O2 -mindirect-branch=thunk-extern -fno-pic" } */> ++/* { dg-options "-O2 -mfunction-return=keep -mindirect-branch=thunk-extern -fno-pic" } */> + > + typedef void (*dispatch_t)(long offset);> + > +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-2.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-2.c> +index d6e078d594b..955aa256529 100644> +--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-2.c> ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-2.c> +@@ -1,5 +1,5 @@> + /* { dg-do compile } */> +-/* { dg-options "-O2 -mindirect-branch=thunk-extern -fno-pic" } */> ++/* { dg-options "-O2 -mfunction-return=keep -mindirect-branch=thunk-extern -fno-pic" } */> + > + typedef void (*dispatch_t)(long offset);> + > +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-3.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-3.c> +index 3bbe2646955..1537239416f 100644> +--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-3.c> ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-3.c> +@@ -1,5 +1,5 @@> + /* { dg-do compile } */> +-/* { dg-options "-O2 -mindirect-branch=thunk-extern -fno-pic" } */> ++/* { dg-options "-O2 -mfunction-return=keep -mindirect-branch=thunk-extern -fno-pic" } */> + > + typedef void (*dispatch_t)(long offset);> + > +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-4.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-4.c> +index 596fac599f6..c82e53068fe 100644> +--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-4.c> ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-4.c> +@@ -1,5 +1,5 @@> + /* { dg-do compile } */> +-/* { dg-options "-O2 -mindirect-branch=thunk-extern -fno-pic" } */> ++/* { dg-options "-O2 -mfunction-return=keep -mindirect-branch=thunk-extern -fno-pic" } */> + > + typedef void (*dispatch_t)(long offset);> + > +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-5.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-5.c> +index ad54aaeac4c..23548d85f78 100644> +--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-5.c> ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-5.c> +@@ -1,5 +1,5 @@> + /* { dg-do compile { target *-*-linux* } } */> +-/* { dg-options "-O2 -fpic -fno-plt -mindirect-branch=thunk-extern" } */> ++/* { dg-options "-O2 -mfunction-return=keep -fpic -fno-plt -mindirect-branch=thunk-extern" } */> + > + extern void bar (void);> + > +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-6.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-6.c> +index a8e75254cfe..56c2fe92f25 100644> +--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-6.c> ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-6.c> +@@ -1,5 +1,5 @@> + /* { dg-do compile { target *-*-linux* } } */> +-/* { dg-options "-O2 -fpic -fno-plt -mindirect-branch=thunk-extern" } */> ++/* { dg-options "-O2 -mfunction-return=keep -fpic -fno-plt -mindirect-branch=thunk-extern" } */> + > + extern void bar (void);> + > +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-7.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-7.c> +index ab367951c45..e12b88593fe 100644> +--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-7.c> ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-7.c> +@@ -1,5 +1,5 @@> + /* { dg-do compile } */> +-/* { dg-options "-O2 -mindirect-branch=thunk-extern -fno-pic" } */> ++/* { dg-options "-O2 -mfunction-return=keep -mindirect-branch=thunk-extern -fno-pic" } */> + > + void func0 (void);> + void func1 (void);> +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-1.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-1.c> +index 09b8ad7d879..87b5429702f 100644> +--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-1.c> ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-1.c> +@@ -1,5 +1,5 @@> + /* { dg-do compile } */> +-/* { dg-options "-O2 -mindirect-branch=thunk-inline -fno-pic" } */> ++/* { dg-options "-O2 -mfunction-return=keep -mindirect-branch=thunk-inline -fno-pic" } */> + > + typedef void (*dispatch_t)(long offset);> + > +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-2.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-2.c> +index 1f873758fbe..a496a41a918 100644> +--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-2.c> ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-2.c> +@@ -1,5 +1,5 @@> + /* { dg-do compile } */> +-/* { dg-options "-O2 -mindirect-branch=thunk-inline -fno-pic" } */> ++/* { dg-options "-O2 -mfunction-return=keep -mindirect-branch=thunk-inline -fno-pic" } */> + > + typedef void (*dispatch_t)(long offset);> + > +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-3.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-3.c> +index b24af1da963..6fe5ce71abf 100644> +--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-3.c> ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-3.c> +@@ -1,5 +1,5 @@> + /* { dg-do compile } */> +-/* { dg-options "-O2 -mindirect-branch=thunk-inline -fno-pic" } */> ++/* { dg-options "-O2 -mfunction-return=keep -mindirect-branch=thunk-inline -fno-pic" } */> + > + typedef void (*dispatch_t)(long offset);> + > +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-4.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-4.c> +index 1a86608f727..65cd997a33f 100644> +--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-4.c> ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-4.c> +@@ -1,5 +1,5 @@> + /* { dg-do compile } */> +-/* { dg-options "-O2 -mindirect-branch=thunk-inline -fno-pic" } */> ++/* { dg-options "-O2 -mfunction-return=keep -mindirect-branch=thunk-inline -fno-pic" } */> + > + typedef void (*dispatch_t)(long offset);> + > +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-5.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-5.c> +index f4890fe97b2..7321d015c02 100644> +--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-5.c> ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-5.c> +@@ -1,5 +1,5 @@> + /* { dg-do compile { target *-*-linux* } } */> +-/* { dg-options "-O2 -fpic -fno-plt -mindirect-branch=thunk-inline" } */> ++/* { dg-options "-O2 -mfunction-return=keep -fpic -fno-plt -mindirect-branch=thunk-inline" } */> + > + extern void bar (void);> + > +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-6.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-6.c> +index 81b09e73ab8..6ec2e5621ab 100644> +--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-6.c> ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-6.c> +@@ -1,5 +1,5 @@> + /* { dg-do compile { target *-*-linux* } } */> +-/* { dg-options "-O2 -fpic -fno-plt -mindirect-branch=thunk-inline" } */> ++/* { dg-options "-O2 -mfunction-return=keep -fpic -fno-plt -mindirect-branch=thunk-inline" } */> + > + extern void bar (void);> + > +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-7.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-7.c> +index 01d45782185..a3d1a13cded 100644> +--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-7.c> ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-7.c> +@@ -1,5 +1,5 @@> + /* { dg-do compile } */> +-/* { dg-options "-O2 -mindirect-branch=thunk-inline -fno-pic" } */> ++/* { dg-options "-O2 -mfunction-return=keep -mindirect-branch=thunk-inline -fno-pic" } */> + > + void func0 (void);> + void func1 (void);> +-- > +2.15.1> +> diff --git a/gnu/packages/patches/gcc-retpoline-Add-mindirect-branch-loop.patch b/gnu/packages/patches/gcc-retpoline-Add-mindirect-branch-loop.patch> new file mode 100644> index 000000000..ab715f46a> --- /dev/null> +++ b/gnu/packages/patches/gcc-retpoline-Add-mindirect-branch-loop.patch> @@ -0,0 +1,233 @@> +'Retpoline' mitigation technique for Spectre (branch target injection)> +[CVE-2017-5715]:> +> +https://security.googleblog.com/2018/01/more-details-about-mitigations-for-cpu_4.html> +https://support.google.com/faqs/answer/7625886> +https://spectreattack.com/> +https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2017-5715> +> +Patch copied from the 'retpoline-20180107' branch of upstream source repository> +(please add new / update existing patches when new 'retpoline-xxxxxxxx' branch> +appears):> +> +http://git.infradead.org/users/dwmw2/gcc-retpoline.git> +> +From d667049b53e3d45de057fba2f1ed0e3f268201c1 Mon Sep 17 00:00:00 2001> +From: "H.J. Lu" <hjl.tools@gmail.com>> +Date: Thu, 16 Nov 2017 14:46:20 -0800> +Subject: [PATCH 10/17] Add -mindirect-branch-loop=> +> +Add -mindirect-branch-loop= tests.> +---> + gcc/config/i386/i386-opts.h | 6 ++++++> + gcc/config/i386/i386.c | 19 +++++++++++++++++--> + gcc/config/i386/i386.opt | 16 ++++++++++++++++> + gcc/testsuite/gcc.target/i386/indirect-thunk-loop-1.c | 19 +++++++++++++++++++> + gcc/testsuite/gcc.target/i386/indirect-thunk-loop-2.c | 19 +++++++++++++++++++> + gcc/testsuite/gcc.target/i386/indirect-thunk-loop-3.c | 19 +++++++++++++++++++> + gcc/testsuite/gcc.target/i386/indirect-thunk-loop-4.c | 19 +++++++++++++++++++> + gcc/testsuite/gcc.target/i386/indirect-thunk-loop-5.c | 19 +++++++++++++++++++> + 8 files changed, 134 insertions(+), 2 deletions(-)> + create mode 100644 gcc/testsuite/gcc.target/i386/indirect-thunk-loop-1.c> + create mode 100644 gcc/testsuite/gcc.target/i386/indirect-thunk-loop-2.c> + create mode 100644 gcc/testsuite/gcc.target/i386/indirect-thunk-loop-3.c> + create mode 100644 gcc/testsuite/gcc.target/i386/indirect-thunk-loop-4.c> + create mode 100644 gcc/testsuite/gcc.target/i386/indirect-thunk-loop-5.c> +> +diff --git a/gcc/config/i386/i386-opts.h b/gcc/config/i386/i386-opts.h> +index 9e56d7f2d12..b7b8fd280a3 100644> +--- a/gcc/config/i386/i386-opts.h> ++++ b/gcc/config/i386/i386-opts.h> +@@ -107,4 +107,10 @@ enum indirect_branch {> + indirect_branch_thunk_extern> + };> + > ++enum indirect_branch_loop {> ++ indirect_branch_loop_lfence,> ++ indirect_branch_loop_pause,> ++ indirect_branch_loop_nop> ++};> ++> + #endif> +diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c> +index 590729b3f87..be1ff4752a9 100644> +--- a/gcc/config/i386/i386.c> ++++ b/gcc/config/i386/i386.c> +@@ -12016,8 +12016,23 @@ output_indirect_thunk (bool need_bnd_p, int regno)> + > + ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, indirectlabel1);> + > +- /* lfence . */> +- fprintf (asm_out_file, "\tlfence\n");> ++ switch (ix86_indirect_branch_loop)> ++ {> ++ case indirect_branch_loop_lfence:> ++ /* lfence. */> ++ fprintf (asm_out_file, "\tlfence\n");> ++ break;> ++ case indirect_branch_loop_pause:> ++ /* pause. */> ++ fprintf (asm_out_file, "\tpause\n");> ++ break;> ++ case indirect_branch_loop_nop:> ++ /* nop. */> ++ fprintf (asm_out_file, "\tnop\n");> ++ break;> ++ default:> ++ gcc_unreachable ();> ++ }> + > + /* Jump. */> + fputs ("\tjmp\t", asm_out_file);> +diff --git a/gcc/config/i386/i386.opt b/gcc/config/i386/i386.opt> +index 4a932e11bf6..bc81e6bea86 100644> +--- a/gcc/config/i386/i386.opt> ++++ b/gcc/config/i386/i386.opt> +@@ -947,3 +947,19 @@ Enum(indirect_branch) String(thunk-inline) Value(indirect_branch_thunk_inline)> + > + EnumValue> + Enum(indirect_branch) String(thunk-extern) Value(indirect_branch_thunk_extern)> ++> ++mindirect-branch-loop=> ++Target Report RejectNegative Joined Enum(indirect_branch_loop) Var(ix86_indirect_branch_loop) Undocumented Init(indirect_branch_loop_lfence)> ++> ++Enum> ++Name(indirect_branch_loop) Type(enum indirect_branch_loop)> ++Known looop choices (for use with the -mindirect-branch-loop= option):> ++> ++EnumValue> ++Enum(indirect_branch_loop) String(lfence) Value(indirect_branch_loop_lfence)> ++> ++EnumValue> ++Enum(indirect_branch_loop) String(pause) Value(indirect_branch_loop_pause)> ++> ++EnumValue> ++Enum(indirect_branch_loop) String(nop) Value(indirect_branch_loop_nop)> +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-loop-1.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-loop-1.c> +new file mode 100644> +index 00000000000..f0e8f4949c8> +--- /dev/null> ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-loop-1.c> +@@ -0,0 +1,19 @@> ++/* { dg-do compile } */> ++/* { dg-options "-O2 -mindirect-branch=thunk -mindirect-branch-loop=pause -fno-pic" } */> ++> ++typedef void (*dispatch_t)(long offset);> ++> ++dispatch_t dispatch;> ++> ++void> ++male_indirect_jump (long offset)> ++{> ++ dispatch(offset);> ++}> ++> ++/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { ! x32 } } } } */> ++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" { target { ! x32 } } } } */> ++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk\.(r|e)ax" { target x32 } } } */> ++/* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */> ++/* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */> ++/* { dg-final { scan-assembler {\tpause} } } */> +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-loop-2.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-loop-2.c> +new file mode 100644> +index 00000000000..a577ac2568a> +--- /dev/null> ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-loop-2.c> +@@ -0,0 +1,19 @@> ++/* { dg-do compile } */> ++/* { dg-options "-O2 -mindirect-branch=thunk -mindirect-branch-loop=nop -fno-pic" } */> ++> ++typedef void (*dispatch_t)(long offset);> ++> ++dispatch_t dispatch[256];> ++> ++void> ++male_indirect_jump (long offset)> ++{> ++ dispatch[offset](offset);> ++}> ++> ++/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { ! x32 } } } } */> ++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" { target { ! x32 } } } } */> ++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk\.(r|e)ax" { target x32 } } } */> ++/* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */> ++/* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */> ++/* { dg-final { scan-assembler {\tnop} } } */> +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-loop-3.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-loop-3.c> +new file mode 100644> +index 00000000000..c8dcb9639c4> +--- /dev/null> ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-loop-3.c> +@@ -0,0 +1,19 @@> ++/* { dg-do compile } */> ++/* { dg-options "-O2 -mindirect-branch=thunk -mindirect-branch-loop=lfence -fno-pic" } */> ++> ++typedef void (*dispatch_t)(long offset);> ++> ++dispatch_t dispatch;> ++> ++void> ++male_indirect_jump (long offset)> ++{> ++ dispatch(offset);> ++}> ++> ++/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { ! x32 } } } } */> ++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" { target { ! x32 } } } } */> ++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk\.(r|e)ax" { target x32 } } } */> ++/* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */> ++/* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */> ++/* { dg-final { scan-assembler {\tlfence} } } */> +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-loop-4.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-loop-4.c> +new file mode 100644> +index 00000000000..8569dfc92c3> +--- /dev/null> ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-loop-4.c> +@@ -0,0 +1,19 @@> ++/* { dg-do compile } */> ++/* { dg-options "-O2 -mindirect-branch=thunk-inline -mindirect-branch-loop=pause -fno-pic" } */> ++> ++typedef void (*dispatch_t)(long offset);> ++> ++dispatch_t dispatch;> ++> ++void> ++male_indirect_jump (long offset)> ++{> ++ dispatch(offset);> ++}> ++> ++/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { ! x32 } } } } */> ++/* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */> ++/* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */> ++/* { dg-final { scan-assembler {\tpause} } } */> ++/* { dg-final { scan-assembler-not "__x86.indirect_thunk" } } */> ++/* { dg-final { scan-assembler-not "pushq\[ \t\]%rax" { target x32 } } } */> +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-loop-5.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-loop-5.c> +new file mode 100644> +index 00000000000..bcf19c9ede1> +--- /dev/null> ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-loop-5.c> +@@ -0,0 +1,19 @@> ++/* { dg-do compile } */> ++/* { dg-options "-O2 -mindirect-branch=thunk-extern -mindirect-branch-loop=pause -fno-pic" } */> ++> ++typedef void (*dispatch_t)(long offset);> ++> ++dispatch_t dispatch;> ++> ++void> ++male_indirect_jump (long offset)> ++{> ++ dispatch(offset);> ++}> ++> ++/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { ! x32 } } } } */> ++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" { target { ! x32 } } } } */> ++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk\.(r|e)ax" { target x32 } } } */> ++/* { dg-final { scan-assembler-not {\t(lfence|pause|nop)} } } */> ++/* { dg-final { scan-assembler-not "jmp\[ \t\]*\.LIND" } } */> ++/* { dg-final { scan-assembler-not "call\[ \t\]*\.LIND" } } */> +-- > +2.15.1> +> diff --git a/gnu/packages/patches/gcc-retpoline-Add-mindirect-branch-register-and-tests.patch b/gnu/packages/patches/gcc-retpoline-Add-mindirect-branch-register-and-tests.patch> new file mode 100644> index 000000000..de9e373fd> --- /dev/null> +++ b/gnu/packages/patches/gcc-retpoline-Add-mindirect-branch-register-and-tests.patch> @@ -0,0 +1,403 @@> +'Retpoline' mitigation technique for Spectre (branch target injection)> +[CVE-2017-5715]:> +> +https://security.googleblog.com/2018/01/more-details-about-mitigations-for-cpu_4.html> +https://support.google.com/faqs/answer/7625886> +https://spectreattack.com/> +https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2017-5715> +> +Patch copied from the 'retpoline-20180107' branch of upstream source repository> +(please add new / update existing patches when new 'retpoline-xxxxxxxx' branch> +appears):> +> +http://git.infradead.org/users/dwmw2/gcc-retpoline.git> +> +From fb8875abab630962dbcb08c822b1b960fa5a51d4 Mon Sep 17 00:00:00 2001> +From: "H.J. Lu" <hjl.tools@gmail.com>> +Date: Wed, 19 Jul 2017 19:23:02 -0700> +Subject: [PATCH 13/17] Add -mindirect-branch-register and tests> +> +Add -mindirect-branch-register to force indirect branch via register.> +This is implemented by disabling patterns of indirect branch via memory,> +similar to TARGET_X32. With -mindirect-branch-register:> +> +void (*func) (void);> +> +void> +bar (void)> +{> + func ();> +}> +> +is compiled into:> +> + movq func(%rip), %rax> + jmp __x86.indirect_thunk.ax> +> +__x86.indirect_thunk.ax:> + call .LIND3> +.LIND2:> + lfence> + jmp .LIND2> +.LIND3:> + mov %rax, (%rsp)> + ret> +> +and> +> +void (*func) (void);> +> +int> +bar (void)> +{> + func ();> + return 0;> +}> +> +is compiled into:> +> + subq $8, %rsp> + movq func(%rip), %rax> + call __x86.indirect_thunk.ax> + xorl %eax, %eax> + addq $8, %rsp> + ret> +> + * config/i386/constraints.md (Bs): Disallow memory operand for> + -mindirect-branch-register.> + (Bw): Likewise.> + * config/i386/predicates.md (indirect_branch_operand): Likewise.> + (GOT_memory_operand): Likewise.> + (call_insn_operand): Likewise.> + (sibcall_insn_operand): Likewise.> + (GOT32_symbol_operand): Likewise.> + * config/i386/i386.md (indirect_jump): Call convert_memory_address> + for -mindirect-branch-register.> + (tablejump): Likewise.> + (*sibcall_memory): Likewise.> + (*sibcall_value_memory): Likewise.> + Disallow peepholes of indirect call and jump via memory for> + -mindirect-branch-register.> + (*call_pop): Replace m with Bw.> + (*call_value_pop): Likewise.> + (*sibcall_pop_memory): Replace m with Bs.> +---> + gcc/config/i386/constraints.md | 12 +++++---> + gcc/config/i386/i386.md | 34 ++++++++++++++--------> + gcc/config/i386/i386.opt | 4 +++> + gcc/config/i386/predicates.md | 21 ++++++++-----> + .../gcc.target/i386/indirect-thunk-register-1.c | 22 ++++++++++++++> + .../gcc.target/i386/indirect-thunk-register-2.c | 20 +++++++++++++> + .../gcc.target/i386/indirect-thunk-register-3.c | 19 ++++++++++++> + 7 files changed, 109 insertions(+), 23 deletions(-)> + create mode 100644 gcc/testsuite/gcc.target/i386/indirect-thunk-register-1.c> + create mode 100644 gcc/testsuite/gcc.target/i386/indirect-thunk-register-2.c> + create mode 100644 gcc/testsuite/gcc.target/i386/indirect-thunk-register-3.c> +> +diff --git a/gcc/config/i386/constraints.md b/gcc/config/i386/constraints.md> +index 38d604fdace..697caf704dd 100644> +--- a/gcc/config/i386/constraints.md> ++++ b/gcc/config/i386/constraints.md> +@@ -198,16 +198,20 @@> + > + (define_constraint "Bs"> + "@internal Sibcall memory operand."> +- (ior (and (not (match_test "TARGET_X32"))> ++ (ior (and (not (match_test "TARGET_X32> ++ || ix86_indirect_branch_thunk_register"))> + (match_operand 0 "sibcall_memory_operand"))> +- (and (match_test "TARGET_X32 && Pmode == DImode")> ++ (and (match_test "TARGET_X32 && Pmode == DImode> ++ && !ix86_indirect_branch_thunk_register")> + (match_operand 0 "GOT_memory_operand"))))> + > + (define_constraint "Bw"> + "@internal Call memory operand."> +- (ior (and (not (match_test "TARGET_X32"))> ++ (ior (and (not (match_test "TARGET_X32> ++ || ix86_indirect_branch_thunk_register"))> + (match_operand 0 "memory_operand"))> +- (and (match_test "TARGET_X32 && Pmode == DImode")> ++ (and (match_test "TARGET_X32 && Pmode == DImode> ++ && !ix86_indirect_branch_thunk_register")> + (match_operand 0 "GOT_memory_operand"))))> + > + (define_constraint "Bz"> +diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md> +index 00a9afef225..473fa5c089b 100644> +--- a/gcc/config/i386/i386.md> ++++ b/gcc/config/i386/i386.md> +@@ -11608,7 +11608,7 @@> + [(set (pc) (match_operand 0 "indirect_branch_operand"))]> + ""> + {> +- if (TARGET_X32)> ++ if (TARGET_X32 || ix86_indirect_branch_thunk_register)> + operands[0] = convert_memory_address (word_mode, operands[0]);> + })> + > +@@ -11657,7 +11657,7 @@> + OPTAB_DIRECT);> + }> + > +- if (TARGET_X32)> ++ if (TARGET_X32 || ix86_indirect_branch_thunk_register)> + operands[0] = convert_memory_address (word_mode, operands[0]);> + })> + > +@@ -11844,7 +11844,7 @@> + [(call (mem:QI (match_operand:W 0 "memory_operand" "m"))> + (match_operand 1))> + (unspec [(const_int 0)] UNSPEC_PEEPSIB)]> +- "!TARGET_X32"> ++ "!TARGET_X32 && !ix86_indirect_branch_thunk_register"> + "* return ix86_output_call_insn (insn, operands[0]);"> + [(set_attr "type" "call")])> + > +@@ -11853,7 +11853,9 @@> + (match_operand:W 1 "memory_operand"))> + (call (mem:QI (match_dup 0))> + (match_operand 3))]> +- "!TARGET_X32 && SIBLING_CALL_P (peep2_next_insn (1))> ++ "!TARGET_X32> ++ && !ix86_indirect_branch_thunk_register> ++ && SIBLING_CALL_P (peep2_next_insn (1))> + && !reg_mentioned_p (operands[0],> + CALL_INSN_FUNCTION_USAGE (peep2_next_insn (1)))"> + [(parallel [(call (mem:QI (match_dup 1))> +@@ -11866,7 +11868,9 @@> + (unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)> + (call (mem:QI (match_dup 0))> + (match_operand 3))]> +- "!TARGET_X32 && SIBLING_CALL_P (peep2_next_insn (2))> ++ "!TARGET_X32> ++ && !ix86_indirect_branch_thunk_register> ++ && SIBLING_CALL_P (peep2_next_insn (2))> + && !reg_mentioned_p (operands[0],> + CALL_INSN_FUNCTION_USAGE (peep2_next_insn (2)))"> + [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)> +@@ -11888,7 +11892,7 @@> + })> + > + (define_insn "*call_pop"> +- [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lmBz"))> ++ [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lBwBz"))> + (match_operand 1))> + (set (reg:SI SP_REG)> + (plus:SI (reg:SI SP_REG)> +@@ -11908,7 +11912,7 @@> + [(set_attr "type" "call")])> + > + (define_insn "*sibcall_pop_memory"> +- [(call (mem:QI (match_operand:SI 0 "memory_operand" "m"))> ++ [(call (mem:QI (match_operand:SI 0 "memory_operand" "Bs"))> + (match_operand 1))> + (set (reg:SI SP_REG)> + (plus:SI (reg:SI SP_REG)> +@@ -11962,7 +11966,9 @@> + [(set (match_operand:W 0 "register_operand")> + (match_operand:W 1 "memory_operand"))> + (set (pc) (match_dup 0))]> +- "!TARGET_X32 && peep2_reg_dead_p (2, operands[0])"> ++ "!TARGET_X32> ++ && !ix86_indirect_branch_thunk_register> ++ && peep2_reg_dead_p (2, operands[0])"> + [(set (pc) (match_dup 1))])> + > + ;; Call subroutine, returning value in operand 0> +@@ -12043,7 +12049,7 @@> + (call (mem:QI (match_operand:W 1 "memory_operand" "m"))> + (match_operand 2)))> + (unspec [(const_int 0)] UNSPEC_PEEPSIB)]> +- "!TARGET_X32"> ++ "!TARGET_X32 && !ix86_indirect_branch_thunk_register"> + "* return ix86_output_call_insn (insn, operands[1]);"> + [(set_attr "type" "callv")])> + > +@@ -12053,7 +12059,9 @@> + (set (match_operand 2)> + (call (mem:QI (match_dup 0))> + (match_operand 3)))]> +- "!TARGET_X32 && SIBLING_CALL_P (peep2_next_insn (1))> ++ "!TARGET_X32> ++ && !ix86_indirect_branch_thunk_register> ++ && SIBLING_CALL_P (peep2_next_insn (1))> + && !reg_mentioned_p (operands[0],> + CALL_INSN_FUNCTION_USAGE (peep2_next_insn (1)))"> + [(parallel [(set (match_dup 2)> +@@ -12068,7 +12076,9 @@> + (set (match_operand 2)> + (call (mem:QI (match_dup 0))> + (match_operand 3)))]> +- "!TARGET_X32 && SIBLING_CALL_P (peep2_next_insn (2))> ++ "!TARGET_X32> ++ && !ix86_indirect_branch_thunk_register> ++ && SIBLING_CALL_P (peep2_next_insn (2))> + && !reg_mentioned_p (operands[0],> + CALL_INSN_FUNCTION_USAGE (peep2_next_insn (2)))"> + [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)> +@@ -12093,7 +12103,7 @@> + > + (define_insn "*call_value_pop"> + [(set (match_operand 0)> +- (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lmBz"))> ++ (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lBwBz"))> + (match_operand 2)))> + (set (reg:SI SP_REG)> + (plus:SI (reg:SI SP_REG)> +diff --git a/gcc/config/i386/i386.opt b/gcc/config/i386/i386.opt> +index fc2c81c3fb5..802245f4efe 100644> +--- a/gcc/config/i386/i386.opt> ++++ b/gcc/config/i386/i386.opt> +@@ -952,6 +952,10 @@ Enum(indirect_branch) String(thunk-inline) Value(indirect_branch_thunk_inline)> + EnumValue> + Enum(indirect_branch) String(thunk-extern) Value(indirect_branch_thunk_extern)> + > ++mindirect-branch-register> ++Target Report Var(ix86_indirect_branch_thunk_register) Init(0)> ++Force indirect call and jump via register.> ++> + mindirect-branch-loop=> + Target Report RejectNegative Joined Enum(indirect_branch_loop) Var(ix86_indirect_branch_loop) Undocumented Init(indirect_branch_loop_lfence)> + > +diff --git a/gcc/config/i386/predicates.md b/gcc/config/i386/predicates.md> +index 8f250a2e720..fc4933e4533 100644> +--- a/gcc/config/i386/predicates.md> ++++ b/gcc/config/i386/predicates.md> +@@ -635,7 +635,8 @@> + ;; Test for a valid operand for indirect branch.> + (define_predicate "indirect_branch_operand"> + (ior (match_operand 0 "register_operand")> +- (and (not (match_test "TARGET_X32"))> ++ (and (not (match_test "TARGET_X32> ++ || ix86_indirect_branch_thunk_register"))> + (match_operand 0 "memory_operand"))))> + > + ;; Return true if OP is a memory operands that can be used in sibcalls.> +@@ -664,7 +665,8 @@> + > + ;; Return true if OP is a GOT memory operand.> + (define_predicate "GOT_memory_operand"> +- (match_operand 0 "memory_operand")> ++ (and (match_test "!ix86_indirect_branch_thunk_register")> ++ (match_operand 0 "memory_operand"))> + {> + op = XEXP (op, 0);> + return (GET_CODE (op) == CONST> +@@ -678,9 +680,11 @@> + (ior (match_test "constant_call_address_operand> + (op, mode == VOIDmode ? mode : Pmode)")> + (match_operand 0 "call_register_no_elim_operand")> +- (ior (and (not (match_test "TARGET_X32"))> ++ (ior (and (not (match_test "TARGET_X32> ++ || ix86_indirect_branch_thunk_register"))> + (match_operand 0 "memory_operand"))> +- (and (match_test "TARGET_X32 && Pmode == DImode")> ++ (and (match_test "TARGET_X32 && Pmode == DImode> ++ && !ix86_indirect_branch_thunk_register")> + (match_operand 0 "GOT_memory_operand")))))> + > + ;; Similarly, but for tail calls, in which we cannot allow memory references.> +@@ -688,14 +692,17 @@> + (ior (match_test "constant_call_address_operand> + (op, mode == VOIDmode ? mode : Pmode)")> + (match_operand 0 "register_no_elim_operand")> +- (ior (and (not (match_test "TARGET_X32"))> ++ (ior (and (not (match_test "TARGET_X32> ++ || ix86_indirect_branch_thunk_register"))> + (match_operand 0 "sibcall_memory_operand"))> +- (and (match_test "TARGET_X32 && Pmode == DImode")> ++ (and (match_test "TARGET_X32 && Pmode == DImode> ++ && !ix86_indirect_branch_thunk_register")> + (match_operand 0 "GOT_memory_operand")))))> + > + ;; Return true if OP is a 32-bit GOT symbol operand.> + (define_predicate "GOT32_symbol_operand"> +- (match_test "GET_CODE (op) == CONST> ++ (match_test "!ix86_indirect_branch_thunk_register> ++ && GET_CODE (op) == CONST> + && GET_CODE (XEXP (op, 0)) == UNSPEC> + && XINT (XEXP (op, 0), 1) == UNSPEC_GOT"))> + > +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-register-1.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-register-1.c> +new file mode 100644> +index 00000000000..ef493a05bbf> +--- /dev/null> ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-register-1.c> +@@ -0,0 +1,22 @@> ++/* { dg-do compile } */> ++/* { dg-options "-O2 -mindirect-branch=thunk -mindirect-branch-register -fno-pic" } */> ++> ++typedef void (*dispatch_t)(long offset);> ++> ++dispatch_t dispatch;> ++> ++void> ++male_indirect_jump (long offset)> ++{> ++ dispatch(offset);> ++}> ++> ++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk\.(r|e)ax" } } */> ++/* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */> ++/* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */> ++/* { dg-final { scan-assembler "mov\[ \t\](%eax|%rax), \\((%esp|%rsp)\\)" } } */> ++/* { dg-final { scan-assembler {\tlfence} } } */> ++/* { dg-final { scan-assembler-not "push(?:l|q)\[ \t\]*_?dispatch" } } */> ++/* { dg-final { scan-assembler-not "pushq\[ \t\]%rax" } } */> ++/* { dg-final { scan-assembler-not "__x86.indirect_thunk\n" } } */> ++/* { dg-final { scan-assembler-not "__x86.indirect_thunk_bnd\n" } } */> +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-register-2.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-register-2.c> +new file mode 100644> +index 00000000000..89fc8e6e6c4> +--- /dev/null> ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-register-2.c> +@@ -0,0 +1,20 @@> ++/* { dg-do compile } */> ++/* { dg-options "-O2 -mindirect-branch=thunk-inline -mindirect-branch-register -fno-pic" } */> ++> ++typedef void (*dispatch_t)(long offset);> ++> ++dispatch_t dispatch;> ++> ++void> ++male_indirect_jump (long offset)> ++{> ++ dispatch(offset);> ++}> ++> ++/* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */> ++/* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */> ++/* { dg-final { scan-assembler "mov\[ \t\](%eax|%rax), \\((%esp|%rsp)\\)" } } */> ++/* { dg-final { scan-assembler {\tlfence} } } */> ++/* { dg-final { scan-assembler-not "push(?:l|q)\[ \t\]*_?dispatch" } } */> ++/* { dg-final { scan-assembler-not "pushq\[ \t\]%rax" } } */> ++/* { dg-final { scan-assembler-not "__x86.indirect_thunk" } } */> +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-register-3.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-register-3.c> +new file mode 100644> +index 00000000000..31af7ac05b8> +--- /dev/null> ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-register-3.c> +@@ -0,0 +1,19 @@> ++/* { dg-do compile } */> ++/* { dg-options "-O2 -mindirect-branch=thunk-extern -mindirect-branch-register -fno-pic" } */> ++> ++typedef void (*dispatch_t)(long offset);> ++> ++dispatch_t dispatch;> ++> ++void> ++male_indirect_jump (long offset)> ++{> ++ dispatch(offset);> ++}> ++> ++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk\.(r|e)ax" } } */> ++/* { dg-final { scan-assembler-not "push(?:l|q)\[ \t\]*_?dispatch" } } */> ++/* { dg-final { scan-assembler-not "pushq\[ \t\]%rax" } } */> ++/* { dg-final { scan-assembler-not {\t(lfence|pause|nop)} } } */> ++/* { dg-final { scan-assembler-not "jmp\[ \t\]*\.LIND" } } */> ++/* { dg-final { scan-assembler-not "call\[ \t\]*\.LIND" } } */> +-- > +2.15.1> +> diff --git a/gnu/packages/patches/gcc-retpoline-Add-mindirect-branch-thunk-extern.patch b/gnu/packages/patches/gcc-retpoline-Add-mindirect-branch-thunk-extern.patch> new file mode 100644> index 000000000..18b2dfaea> --- /dev/null> +++ b/gnu/packages/patches/gcc-retpoline-Add-mindirect-branch-thunk-extern.patch> @@ -0,0 +1,263 @@> +'Retpoline' mitigation technique for Spectre (branch target injection)> +[CVE-2017-5715]:> +> +https://security.googleblog.com/2018/01/more-details-about-mitigations-for-cpu_4.html> +https://support.google.com/faqs/answer/7625886> +https://spectreattack.com/> +https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2017-5715> +> +Patch copied from the 'retpoline-20180107' branch of upstream source repository> +(please add new / update existing patches when new 'retpoline-xxxxxxxx' branch> +appears):> +> +http://git.infradead.org/users/dwmw2/gcc-retpoline.git> +> +From 4032162fb6d36e20091885d0558f91daaa0080d3 Mon Sep 17 00:00:00 2001> +From: "H.J. Lu" <hjl.tools@gmail.com>> +Date: Mon, 27 Nov 2017 08:38:41 -0800> +Subject: [PATCH 07/17] Add -mindirect-branch=thunk-extern> +> +Add -mindirect-branch=thunk-extern tests> +---> + gcc/config/i386/i386-opts.h | 3 +-> + gcc/config/i386/i386.opt | 3 ++> + .../gcc.target/i386/indirect-thunk-extern-1.c | 19 ++++++++++> + .../gcc.target/i386/indirect-thunk-extern-2.c | 19 ++++++++++> + .../gcc.target/i386/indirect-thunk-extern-3.c | 20 ++++++++++> + .../gcc.target/i386/indirect-thunk-extern-4.c | 20 ++++++++++> + .../gcc.target/i386/indirect-thunk-extern-5.c | 16 ++++++++> + .../gcc.target/i386/indirect-thunk-extern-6.c | 17 +++++++++> + .../gcc.target/i386/indirect-thunk-extern-7.c | 43 ++++++++++++++++++++++> + 9 files changed, 159 insertions(+), 1 deletion(-)> + create mode 100644 gcc/testsuite/gcc.target/i386/indirect-thunk-extern-1.c> + create mode 100644 gcc/testsuite/gcc.target/i386/indirect-thunk-extern-2.c> + create mode 100644 gcc/testsuite/gcc.target/i386/indirect-thunk-extern-3.c> + create mode 100644 gcc/testsuite/gcc.target/i386/indirect-thunk-extern-4.c> + create mode 100644 gcc/testsuite/gcc.target/i386/indirect-thunk-extern-5.c> + create mode 100644 gcc/testsuite/gcc.target/i386/indirect-thunk-extern-6.c> + create mode 100644 gcc/testsuite/gcc.target/i386/indirect-thunk-extern-7.c> +> +diff --git a/gcc/config/i386/i386-opts.h b/gcc/config/i386/i386-opts.h> +index f301890575a..f8d80ba7ec6 100644> +--- a/gcc/config/i386/i386-opts.h> ++++ b/gcc/config/i386/i386-opts.h> +@@ -102,7 +102,8 @@ enum stack_protector_guard {> + enum indirect_branch {> + indirect_branch_keep,> + indirect_branch_thunk,> +- indirect_branch_thunk_inline> ++ indirect_branch_thunk_inline,> ++ indirect_branch_thunk_extern> + };> + > + #endif> +diff --git a/gcc/config/i386/i386.opt b/gcc/config/i386/i386.opt> +index 68484a75022..4a932e11bf6 100644> +--- a/gcc/config/i386/i386.opt> ++++ b/gcc/config/i386/i386.opt> +@@ -944,3 +944,6 @@ Enum(indirect_branch) String(thunk) Value(indirect_branch_thunk)> + > + EnumValue> + Enum(indirect_branch) String(thunk-inline) Value(indirect_branch_thunk_inline)> ++> ++EnumValue> ++Enum(indirect_branch) String(thunk-extern) Value(indirect_branch_thunk_extern)> +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-1.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-1.c> +new file mode 100644> +index 00000000000..0a1f91be988> +--- /dev/null> ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-1.c> +@@ -0,0 +1,19 @@> ++/* { dg-do compile } */> ++/* { dg-options "-O2 -mindirect-branch=thunk-extern -fno-pic" } */> ++> ++typedef void (*dispatch_t)(long offset);> ++> ++dispatch_t dispatch;> ++> ++void> ++male_indirect_jump (long offset)> ++{> ++ dispatch(offset);> ++}> ++> ++/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { ! x32 } } } } */> ++/* { dg-final { scan-assembler "pushq\[ \t\]%rax" { target x32 } } } */> ++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" } } */> ++/* { dg-final { scan-assembler-not {\t(lfence|pause)} } } */> ++/* { dg-final { scan-assembler-not "jmp\[ \t\]*\.LIND" } } */> ++/* { dg-final { scan-assembler-not "call\[ \t\]*\.LIND" } } */> +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-2.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-2.c> +new file mode 100644> +index 00000000000..182520ab3dc> +--- /dev/null> ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-2.c> +@@ -0,0 +1,19 @@> ++/* { dg-do compile } */> ++/* { dg-options "-O2 -mindirect-branch=thunk-extern -fno-pic" } */> ++> ++typedef void (*dispatch_t)(long offset);> ++> ++dispatch_t dispatch[256];> ++> ++void> ++male_indirect_jump (long offset)> ++{> ++ dispatch[offset](offset);> ++}> ++> ++/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { ! x32 } } } } */> ++/* { dg-final { scan-assembler "pushq\[ \t\]%rax" { target x32 } } } */> ++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" } } */> ++/* { dg-final { scan-assembler-not {\t(lfence|pause)} } } */> ++/* { dg-final { scan-assembler-not "jmp\[ \t\]*\.LIND" } } */> ++/* { dg-final { scan-assembler-not "call\[ \t\]*\.LIND" } } */> +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-3.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-3.c> +new file mode 100644> +index 00000000000..5c31ddc34fd> +--- /dev/null> ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-3.c> +@@ -0,0 +1,20 @@> ++/* { dg-do compile } */> ++/* { dg-options "-O2 -mindirect-branch=thunk-extern -fno-pic" } */> ++> ++typedef void (*dispatch_t)(long offset);> ++> ++dispatch_t dispatch;> ++> ++int> ++male_indirect_jump (long offset)> ++{> ++ dispatch(offset);> ++ return 0;> ++}> ++> ++/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { ! x32 } } } } */> ++/* { dg-final { scan-assembler "pushq\[ \t\]%rax" { target x32 } } } */> ++/* { dg-final { scan-assembler-times "jmp\[ \t\]*\.LIND" 1 } } */> ++/* { dg-final { scan-assembler-times "call\[ \t\]*\.LIND" 1 } } */> ++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" } } */> ++/* { dg-final { scan-assembler-not {\t(lfence|pause)} } } */> +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-4.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-4.c> +new file mode 100644> +index 00000000000..f24d0c060f2> +--- /dev/null> ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-4.c> +@@ -0,0 +1,20 @@> ++/* { dg-do compile } */> ++/* { dg-options "-O2 -mindirect-branch=thunk-extern -fno-pic" } */> ++> ++typedef void (*dispatch_t)(long offset);> ++> ++dispatch_t dispatch[256];> ++> ++int> ++male_indirect_jump (long offset)> ++{> ++ dispatch[offset](offset);> ++ return 0;> ++}> ++> ++/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { ! x32 } } } } */> ++/* { dg-final { scan-assembler "pushq\[ \t\]%rax" { target x32 } } } */> ++/* { dg-final { scan-assembler-times "jmp\[ \t\]*\.LIND" 1 } } */> ++/* { dg-final { scan-assembler-times "call\[ \t\]*\.LIND" 1 } } */> ++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" } } */> ++/* { dg-final { scan-assembler-not {\t(lfence|pause)} } } */> +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-5.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-5.c> +new file mode 100644> +index 00000000000..ad54aaeac4c> +--- /dev/null> ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-5.c> +@@ -0,0 +1,16 @@> ++/* { dg-do compile { target *-*-linux* } } */> ++/* { dg-options "-O2 -fpic -fno-plt -mindirect-branch=thunk-extern" } */> ++> ++extern void bar (void);> ++> ++void> ++foo (void)> ++{> ++ bar ();> ++}> ++> ++/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*bar@GOT" } } */> ++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" } } */> ++/* { dg-final { scan-assembler-not {\t(lfence|pause)} } } */> ++/* { dg-final { scan-assembler-not "jmp\[ \t\]*\.LIND" } } */> ++/* { dg-final { scan-assembler-not "call\[ \t\]*\.LIND" } } */> +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-6.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-6.c> +new file mode 100644> +index 00000000000..a8e75254cfe> +--- /dev/null> ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-6.c> +@@ -0,0 +1,17 @@> ++/* { dg-do compile { target *-*-linux* } } */> ++/* { dg-options "-O2 -fpic -fno-plt -mindirect-branch=thunk-extern" } */> ++> ++extern void bar (void);> ++> ++int> ++foo (void)> ++{> ++ bar ();> ++ return 0;> ++}> ++> ++/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*bar@GOT" } } */> ++/* { dg-final { scan-assembler-times "jmp\[ \t\]*\.LIND" 1 } } */> ++/* { dg-final { scan-assembler-times "call\[ \t\]*\.LIND" 1 } } */> ++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" } } */> ++/* { dg-final { scan-assembler-not {\t(lfence|pause)} } } */> +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-7.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-7.c> +new file mode 100644> +index 00000000000..8d39fb6f939> +--- /dev/null> ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-7.c> +@@ -0,0 +1,43 @@> ++/* { dg-do compile } */> ++/* { dg-options "-O2 -mindirect-branch=thunk-extern -fno-pic" } */> ++> ++void func0 (void);> ++void func1 (void);> ++void func2 (void);> ++void func3 (void);> ++void func4 (void);> ++void func4 (void);> ++void func5 (void);> ++> ++void> ++bar (int i)> ++{> ++ switch (i)> ++ {> ++ default:> ++ func0 ();> ++ break;> ++ case 1:> ++ func1 ();> ++ break;> ++ case 2:> ++ func2 ();> ++ break;> ++ case 3:> ++ func3 ();> ++ break;> ++ case 4:> ++ func4 ();> ++ break;> ++ case 5:> ++ func5 ();> ++ break;> ++ }> ++}> ++> ++/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*\.L\[0-9\]+\\(,%" { target { ! x32 } } } } */> ++/* { dg-final { scan-assembler "pushq\[ \t\]%rax" { target x32 } } } */> ++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" } } */> ++/* { dg-final { scan-assembler-not {\t(lfence|pause)} } } */> ++/* { dg-final { scan-assembler-not "jmp\[ \t\]*\.LIND" } } */> ++/* { dg-final { scan-assembler-not "call\[ \t\]*\.LIND" } } */> +-- > +2.15.1> +> diff --git a/gnu/packages/patches/gcc-retpoline-Add-mindirect-branch-thunk-inline.patch b/gnu/packages/patches/gcc-retpoline-Add-mindirect-branch-thunk-inline.patch> new file mode 100644> index 000000000..bb12c0e95> --- /dev/null> +++ b/gnu/packages/patches/gcc-retpoline-Add-mindirect-branch-thunk-inline.patch> @@ -0,0 +1,310 @@> +'Retpoline' mitigation technique for Spectre (branch target injection)> +[CVE-2017-5715]:> +> +https://security.googleblog.com/2018/01/more-details-about-mitigations-for-cpu_4.html> +https://support.google.com/faqs/answer/7625886> +https://spectreattack.com/> +https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2017-5715> +> +Patch copied from the 'retpoline-20180107' branch of upstream source repository> +(please add new / update existing patches when new 'retpoline-xxxxxxxx' branch> +appears):> +> +http://git.infradead.org/users/dwmw2/gcc-retpoline.git> +> +From 7f4f2bf1688c81496107993080e68a29a24de702 Mon Sep 17 00:00:00 2001> +From: "H.J. Lu" <hjl.tools@gmail.com>> +Date: Wed, 15 Nov 2017 11:20:31 -0800> +Subject: [PATCH 06/17] Add -mindirect-branch=thunk-inline> +> +Add -mindirect-branch=thunk-inline tests> +---> + gcc/config/i386/i386-opts.h | 3 +-> + gcc/config/i386/i386.c | 30 +++++++++++-----> + gcc/config/i386/i386.opt | 3 ++> + .../gcc.target/i386/indirect-thunk-inline-1.c | 18 ++++++++++> + .../gcc.target/i386/indirect-thunk-inline-2.c | 18 ++++++++++> + .../gcc.target/i386/indirect-thunk-inline-3.c | 19 ++++++++++> + .../gcc.target/i386/indirect-thunk-inline-4.c | 19 ++++++++++> + .../gcc.target/i386/indirect-thunk-inline-5.c | 15 ++++++++> + .../gcc.target/i386/indirect-thunk-inline-6.c | 16 +++++++++> + .../gcc.target/i386/indirect-thunk-inline-7.c | 42 ++++++++++++++++++++++> + 10 files changed, 173 insertions(+), 10 deletions(-)> + create mode 100644 gcc/testsuite/gcc.target/i386/indirect-thunk-inline-1.c> + create mode 100644 gcc/testsuite/gcc.target/i386/indirect-thunk-inline-2.c> + create mode 100644 gcc/testsuite/gcc.target/i386/indirect-thunk-inline-3.c> + create mode 100644 gcc/testsuite/gcc.target/i386/indirect-thunk-inline-4.c> + create mode 100644 gcc/testsuite/gcc.target/i386/indirect-thunk-inline-5.c> + create mode 100644 gcc/testsuite/gcc.target/i386/indirect-thunk-inline-6.c> + create mode 100644 gcc/testsuite/gcc.target/i386/indirect-thunk-inline-7.c> +> +diff --git a/gcc/config/i386/i386-opts.h b/gcc/config/i386/i386-opts.h> +index 1565d8fdc65..f301890575a 100644> +--- a/gcc/config/i386/i386-opts.h> ++++ b/gcc/config/i386/i386-opts.h> +@@ -101,7 +101,8 @@ enum stack_protector_guard {> + > + enum indirect_branch {> + indirect_branch_keep,> +- indirect_branch_thunk> ++ indirect_branch_thunk,> ++ indirect_branch_thunk_inline> + };> + > + #endif> +diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c> +index 96424361a1c..ac542f79846 100644> +--- a/gcc/config/i386/i386.c> ++++ b/gcc/config/i386/i386.c> +@@ -28600,16 +28600,23 @@ static void> + ix86_output_indirect_branch (rtx call_op, const char *xasm,> + bool sibcall_p)> + {> +- char thunk_name[32];> ++ char thunk_name_buf[32];> ++ char *thunk_name;> + char push_buf[64];> + bool need_bnd_p = ix86_bnd_prefixed_insn_p (current_output_insn);> + > +- bool need_thunk = ix86_indirect_branch == indirect_branch_thunk;> +- if (need_bnd_p)> +- indirect_thunk_bnd_needed |= need_thunk;> ++ if (ix86_indirect_branch != indirect_branch_thunk_inline)> ++ {> ++ bool need_thunk = ix86_indirect_branch == indirect_branch_thunk;> ++ if (need_bnd_p)> ++ indirect_thunk_bnd_needed |= need_thunk;> ++ else> ++ indirect_thunk_needed |= need_thunk;> ++ indirect_thunk_name (thunk_name_buf, need_bnd_p);> ++ thunk_name = thunk_name_buf;> ++ }> + else> +- indirect_thunk_needed |= need_thunk;> +- indirect_thunk_name (thunk_name, need_bnd_p);> ++ thunk_name = NULL;> + > + snprintf (push_buf, sizeof (push_buf), "push{%c}\t%s",> + TARGET_64BIT ? 'q' : 'l', xasm);> +@@ -28683,10 +28690,15 @@ ix86_output_indirect_branch (rtx call_op, const char *xasm,> + > + output_asm_insn (push_buf, &call_op);> + > +- if (need_bnd_p)> +- fprintf (asm_out_file, "\tbnd jmp\t%s\n", thunk_name);> ++ if (thunk_name != NULL)> ++ {> ++ if (need_bnd_p)> ++ fprintf (asm_out_file, "\tbnd jmp\t%s\n", thunk_name);> ++ else> ++ fprintf (asm_out_file, "\tjmp\t%s\n", thunk_name);> ++ }> + else> +- fprintf (asm_out_file, "\tjmp\t%s\n", thunk_name);> ++ output_indirect_thunk (need_bnd_p);> + > + ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, indirectlabel2);> + > +diff --git a/gcc/config/i386/i386.opt b/gcc/config/i386/i386.opt> +index 1773e5614cf..68484a75022 100644> +--- a/gcc/config/i386/i386.opt> ++++ b/gcc/config/i386/i386.opt> +@@ -941,3 +941,6 @@ Enum(indirect_branch) String(keep) Value(indirect_branch_keep)> + > + EnumValue> + Enum(indirect_branch) String(thunk) Value(indirect_branch_thunk)> ++> ++EnumValue> ++Enum(indirect_branch) String(thunk-inline) Value(indirect_branch_thunk_inline)> +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-1.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-1.c> +new file mode 100644> +index 00000000000..071e6c89ac7> +--- /dev/null> ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-1.c> +@@ -0,0 +1,18 @@> ++/* { dg-do compile } */> ++/* { dg-options "-O2 -mindirect-branch=thunk-inline -fno-pic" } */> ++> ++typedef void (*dispatch_t)(long offset);> ++> ++dispatch_t dispatch;> ++> ++void> ++male_indirect_jump (long offset)> ++{> ++ dispatch(offset);> ++}> ++> ++/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { ! x32 } } } } */> ++/* { dg-final { scan-assembler "pushq\[ \t\]%rax" { target x32 } } } */> ++/* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */> ++/* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */> ++/* { dg-final { scan-assembler-not "__x86.indirect_thunk" } } */> +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-2.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-2.c> +new file mode 100644> +index 00000000000..804c7ccdba7> +--- /dev/null> ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-2.c> +@@ -0,0 +1,18 @@> ++/* { dg-do compile } */> ++/* { dg-options "-O2 -mindirect-branch=thunk-inline -fno-pic" } */> ++> ++typedef void (*dispatch_t)(long offset);> ++> ++dispatch_t dispatch[256];> ++> ++void> ++male_indirect_jump (long offset)> ++{> ++ dispatch[offset](offset);> ++}> ++> ++/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { ! x32 } } } } */> ++/* { dg-final { scan-assembler "pushq\[ \t\]%rax" { target x32 } } } */> ++/* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */> ++/* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */> ++/* { dg-final { scan-assembler-not "__x86.indirect_thunk" } } */> +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-3.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-3.c> +new file mode 100644> +index 00000000000..545a981add5> +--- /dev/null> ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-3.c> +@@ -0,0 +1,19 @@> ++/* { dg-do compile } */> ++/* { dg-options "-O2 -mindirect-branch=thunk-inline -fno-pic" } */> ++> ++typedef void (*dispatch_t)(long offset);> ++> ++dispatch_t dispatch;> ++> ++int> ++male_indirect_jump (long offset)> ++{> ++ dispatch(offset);> ++ return 0;> ++}> ++> ++/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { ! x32 } } } } */> ++/* { dg-final { scan-assembler "pushq\[ \t\]%rax" { target x32 } } } */> ++/* { dg-final { scan-assembler-times "jmp\[ \t\]*\.LIND" 2 } } */> ++/* { dg-final { scan-assembler-times "call\[ \t\]*\.LIND" 2 } } */> ++/* { dg-final { scan-assembler-not "__x86.indirect_thunk" } } */> +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-4.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-4.c> +new file mode 100644> +index 00000000000..d9ff4722cff> +--- /dev/null> ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-4.c> +@@ -0,0 +1,19 @@> ++/* { dg-do compile } */> ++/* { dg-options "-O2 -mindirect-branch=thunk-inline -fno-pic" } */> ++> ++typedef void (*dispatch_t)(long offset);> ++> ++dispatch_t dispatch[256];> ++> ++int> ++male_indirect_jump (long offset)> ++{> ++ dispatch[offset](offset);> ++ return 0;> ++}> ++> ++/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { ! x32 } } } } */> ++/* { dg-final { scan-assembler "pushq\[ \t\]%rax" { target x32 } } } */> ++/* { dg-final { scan-assembler-times "jmp\[ \t\]*\.LIND" 2 } } */> ++/* { dg-final { scan-assembler-times "call\[ \t\]*\.LIND" 2 } } */> ++/* { dg-final { scan-assembler-not "__x86.indirect_thunk" } } */> +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-5.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-5.c> +new file mode 100644> +index 00000000000..f4890fe97b2> +--- /dev/null> ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-5.c> +@@ -0,0 +1,15 @@> ++/* { dg-do compile { target *-*-linux* } } */> ++/* { dg-options "-O2 -fpic -fno-plt -mindirect-branch=thunk-inline" } */> ++> ++extern void bar (void);> ++> ++void> ++foo (void)> ++{> ++ bar ();> ++}> ++> ++/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*bar@GOT" } } */> ++/* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */> ++/* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */> ++/* { dg-final { scan-assembler-not "__x86.indirect_thunk" } } */> +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-6.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-6.c> +new file mode 100644> +index 00000000000..81b09e73ab8> +--- /dev/null> ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-6.c> +@@ -0,0 +1,16 @@> ++/* { dg-do compile { target *-*-linux* } } */> ++/* { dg-options "-O2 -fpic -fno-plt -mindirect-branch=thunk-inline" } */> ++> ++extern void bar (void);> ++> ++int> ++foo (void)> ++{> ++ bar ();> ++ return 0;> ++}> ++> ++/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*bar@GOT" } } */> ++/* { dg-final { scan-assembler-times "jmp\[ \t\]*\.LIND" 2 } } */> ++/* { dg-final { scan-assembler-times "call\[ \t\]*\.LIND" 2 } } */> ++/* { dg-final { scan-assembler-not "__x86.indirect_thunk" } } */> +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-7.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-7.c> +new file mode 100644> +index 00000000000..a0ce06b8232> +--- /dev/null> ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-7.c> +@@ -0,0 +1,42 @@> ++/* { dg-do compile } */> ++/* { dg-options "-O2 -mindirect-branch=thunk-inline -fno-pic" } */> ++> ++void func0 (void);> ++void func1 (void);> ++void func2 (void);> ++void func3 (void);> ++void func4 (void);> ++void func4 (void);> ++void func5 (void);> ++> ++void> ++bar (int i)> ++{> ++ switch (i)> ++ {> ++ default:> ++ func0 ();> ++ break;> ++ case 1:> ++ func1 ();> ++ break;> ++ case 2:> ++ func2 ();> ++ break;> ++ case 3:> ++ func3 ();> ++ break;> ++ case 4:> ++ func4 ();> ++ break;> ++ case 5:> ++ func5 ();> ++ break;> ++ }> ++}> ++> ++/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*\.L\[0-9\]+\\(,%" { target { ! x32 } } } } */> ++/* { dg-final { scan-assembler "pushq\[ \t\]%rax" { target x32 } } } */> ++/* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */> ++/* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */> ++/* { dg-final { scan-assembler-not "__x86.indirect_thunk" } } */> +-- > +2.15.1> +> diff --git a/gnu/packages/patches/gcc-retpoline-Add-mindirect-branch-thunk.patch b/gnu/packages/patches/gcc-retpoline-Add-mindirect-branch-thunk.patch> new file mode 100644> index 000000000..edb9a8de5> --- /dev/null> +++ b/gnu/packages/patches/gcc-retpoline-Add-mindirect-branch-thunk.patch> @@ -0,0 +1,729 @@> +'Retpoline' mitigation technique for Spectre (branch target injection)> +[CVE-2017-5715]:> +> +https://security.googleblog.com/2018/01/more-details-about-mitigations-for-cpu_4.html> +https://support.google.com/faqs/answer/7625886> +https://spectreattack.com/> +https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2017-5715> +> +Patch copied from the 'retpoline-20180107' branch of upstream source repository> +(please add new / update existing patches when new 'retpoline-xxxxxxxx' branch> +appears):> +> +http://git.infradead.org/users/dwmw2/gcc-retpoline.git> +> +From 63024dad9c00f1613738fd766e2f0afd455b76d1 Mon Sep 17 00:00:00 2001> +From: "H.J. Lu" <hjl.tools@gmail.com>> +Date: Wed, 1 Nov 2017 16:05:50 -0700> +Subject: [PATCH 04/17] Add -mindirect-branch=thunk> +> +Add tests for -mindirect-branch=thunk> +---> + gcc/config/i386/i386-opts.h | 5 +> + gcc/config/i386/i386-protos.h | 1 +> + gcc/config/i386/i386.c | 318 ++++++++++++++++++++++-> + gcc/config/i386/i386.md | 6 +-> + gcc/config/i386/i386.opt | 14 +> + gcc/doc/invoke.texi | 9 +-> + gcc/testsuite/gcc.target/i386/indirect-thunk-1.c | 19 ++> + gcc/testsuite/gcc.target/i386/indirect-thunk-2.c | 19 ++> + gcc/testsuite/gcc.target/i386/indirect-thunk-3.c | 20 ++> + gcc/testsuite/gcc.target/i386/indirect-thunk-4.c | 20 ++> + gcc/testsuite/gcc.target/i386/indirect-thunk-5.c | 16 ++> + gcc/testsuite/gcc.target/i386/indirect-thunk-6.c | 17 ++> + gcc/testsuite/gcc.target/i386/indirect-thunk-7.c | 43 +++> + 13 files changed, 495 insertions(+), 12 deletions(-)> + create mode 100644 gcc/testsuite/gcc.target/i386/indirect-thunk-1.c> + create mode 100644 gcc/testsuite/gcc.target/i386/indirect-thunk-2.c> + create mode 100644 gcc/testsuite/gcc.target/i386/indirect-thunk-3.c> + create mode 100644 gcc/testsuite/gcc.target/i386/indirect-thunk-4.c> + create mode 100644 gcc/testsuite/gcc.target/i386/indirect-thunk-5.c> + create mode 100644 gcc/testsuite/gcc.target/i386/indirect-thunk-6.c> + create mode 100644 gcc/testsuite/gcc.target/i386/indirect-thunk-7.c> +> +diff --git a/gcc/config/i386/i386-opts.h b/gcc/config/i386/i386-opts.h> +index 542cd0f3d67..1565d8fdc65 100644> +--- a/gcc/config/i386/i386-opts.h> ++++ b/gcc/config/i386/i386-opts.h> +@@ -99,4 +99,9 @@ enum stack_protector_guard {> + SSP_GLOBAL /* global canary */> + };> + > ++enum indirect_branch {> ++ indirect_branch_keep,> ++ indirect_branch_thunk> ++};> ++> + #endif> +diff --git a/gcc/config/i386/i386-protos.h b/gcc/config/i386/i386-protos.h> +index 8bdd67eb608..b746429f420 100644> +--- a/gcc/config/i386/i386-protos.h> ++++ b/gcc/config/i386/i386-protos.h> +@@ -315,6 +315,7 @@ extern enum attr_cpu ix86_schedule;> + #endif> + > + extern const char * ix86_output_call_insn (rtx_insn *insn, rtx call_op);> ++extern const char * ix86_output_indirect_jmp (rtx call_op);> + extern bool ix86_operands_ok_for_move_multiple (rtx *operands, bool load,> + enum machine_mode mode);> + > +diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c> +index 504530a00cf..96424361a1c 100644> +--- a/gcc/config/i386/i386.c> ++++ b/gcc/config/i386/i386.c> +@@ -11909,6 +11909,145 @@ ix86_setup_frame_addresses (void)> + # endif> + #endif> + > ++static int indirectlabelno;> ++static bool indirect_thunk_needed = false;> ++static bool indirect_thunk_bnd_needed = false;> ++> ++#ifndef INDIRECT_LABEL> ++# define INDIRECT_LABEL "LIND"> ++#endif> ++> ++/* Fills in the label name that should be used for the indirect thunk. */> ++> ++static void> ++indirect_thunk_name (char name[32], bool need_bnd_p)> ++{> ++ if (USE_HIDDEN_LINKONCE)> ++ {> ++ const char *bnd = need_bnd_p ? "_bnd" : "";> ++ sprintf (name, "__x86.indirect_thunk%s", bnd);> ++ }> ++ else> ++ {> ++ if (need_bnd_p)> ++ ASM_GENERATE_INTERNAL_LABEL (name, "LITB", 0);> ++ else> ++ ASM_GENERATE_INTERNAL_LABEL (name, "LIT", 0);> ++ }> ++}> ++> ++static void> ++output_indirect_thunk (bool need_bnd_p)> ++{> ++ char indirectlabel1[32];> ++ char indirectlabel2[32];> ++> ++ ASM_GENERATE_INTERNAL_LABEL (indirectlabel1, INDIRECT_LABEL,> ++ indirectlabelno++);> ++ ASM_GENERATE_INTERNAL_LABEL (indirectlabel2, INDIRECT_LABEL,> ++ indirectlabelno++);> ++> ++ /* Call */> ++ if (need_bnd_p)> ++ fputs ("\tbnd call\t", asm_out_file);> ++ else> ++ fputs ("\tcall\t", asm_out_file);> ++ assemble_name_raw (asm_out_file, indirectlabel2);> ++ fputc ('\n', asm_out_file);> ++> ++ ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, indirectlabel1);> ++> ++ /* lfence . */> ++ fprintf (asm_out_file, "\tlfence\n");> ++> ++ /* Jump. */> ++ fputs ("\tjmp\t", asm_out_file);> ++ assemble_name_raw (asm_out_file, indirectlabel1);> ++ fputc ('\n', asm_out_file);> ++> ++ ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, indirectlabel2);> ++> ++ /* LEA. */> ++ rtx xops[2];> ++ xops[0] = stack_pointer_rtx;> ++ xops[1] = plus_constant (Pmode, stack_pointer_rtx, UNITS_PER_WORD);> ++ output_asm_insn ("lea\t{%E1, %0|%0, %E1}", xops);> ++> ++ if (need_bnd_p)> ++ fputs ("\tbnd ret\n", asm_out_file);> ++ else> ++ fputs ("\tret\n", asm_out_file);> ++}> ++> ++static void> ++output_indirect_thunk_function (bool need_bnd_p)> ++{> ++ char name[32];> ++ tree decl;> ++> ++ indirect_thunk_name (name, need_bnd_p);> ++ decl = build_decl (BUILTINS_LOCATION, FUNCTION_DECL,> ++ get_identifier (name),> ++ build_function_type_list (void_type_node, NULL_TREE));> ++ DECL_RESULT (decl) = build_decl (BUILTINS_LOCATION, RESULT_DECL,> ++ NULL_TREE, void_type_node);> ++ TREE_PUBLIC (decl) = 1;> ++ TREE_STATIC (decl) = 1;> ++ DECL_IGNORED_P (decl) = 1;> ++> ++#if TARGET_MACHO> ++ if (TARGET_MACHO)> ++ {> ++ switch_to_section (darwin_sections[picbase_thunk_section]);> ++ fputs ("\t.weak_definition\t", asm_out_file);> ++ assemble_name (asm_out_file, name);> ++ fputs ("\n\t.private_extern\t", asm_out_file);> ++ assemble_name (asm_out_file, name);> ++ putc ('\n', asm_out_file);> ++ ASM_OUTPUT_LABEL (asm_out_file, name);> ++ DECL_WEAK (decl) = 1;> ++ }> ++ else> ++#endif> ++ if (USE_HIDDEN_LINKONCE)> ++ {> ++ cgraph_node::create (decl)->set_comdat_group (DECL_ASSEMBLER_NAME (decl));> ++> ++ targetm.asm_out.unique_section (decl, 0);> ++ switch_to_section (get_named_section (decl, NULL, 0));> ++> ++ targetm.asm_out.globalize_label (asm_out_file, name);> ++ fputs ("\t.hidden\t", asm_out_file);> ++ assemble_name (asm_out_file, name);> ++ putc ('\n', asm_out_file);> ++ ASM_DECLARE_FUNCTION_NAME (asm_out_file, name, decl);> ++ }> ++ else> ++ {> ++ switch_to_section (text_section);> ++ ASM_OUTPUT_LABEL (asm_out_file, name);> ++ }> ++> ++ DECL_INITIAL (decl) = make_node (BLOCK);> ++ current_function_decl = decl;> ++ allocate_struct_function (decl, false);> ++ init_function_start (decl);> ++ /* We're about to hide the function body from callees of final_* by> ++ emitting it directly; tell them we're a thunk, if they care. */> ++ cfun->is_thunk = true;> ++ first_function_block_is_cold = false;> ++ /* Make sure unwind info is emitted for the thunk if needed. */> ++ final_start_function (emit_barrier (), asm_out_file, 1);> ++> ++ output_indirect_thunk (need_bnd_p);> ++> ++ final_end_function ();> ++ init_insn_lengths ();> ++ free_after_compilation (cfun);> ++ set_cfun (NULL);> ++ current_function_decl = NULL;> ++}> ++> + static int pic_labels_used;> + > + /* Fills in the label name that should be used for a pc thunk for> +@@ -11935,6 +12074,11 @@ ix86_code_end (void)> + rtx xops[2];> + int regno;> + > ++ if (indirect_thunk_needed)> ++ output_indirect_thunk_function (false);> ++ if (indirect_thunk_bnd_needed)> ++ output_indirect_thunk_function (true);> ++> + for (regno = AX_REG; regno <= SP_REG; regno++)> + {> + char name[32];> +@@ -28452,12 +28596,132 @@ ix86_nopic_noplt_attribute_p (rtx call_op)> + return false;> + }> + > ++static void> ++ix86_output_indirect_branch (rtx call_op, const char *xasm,> ++ bool sibcall_p)> ++{> ++ char thunk_name[32];> ++ char push_buf[64];> ++ bool need_bnd_p = ix86_bnd_prefixed_insn_p (current_output_insn);> ++> ++ bool need_thunk = ix86_indirect_branch == indirect_branch_thunk;> ++ if (need_bnd_p)> ++ indirect_thunk_bnd_needed |= need_thunk;> ++ else> ++ indirect_thunk_needed |= need_thunk;> ++ indirect_thunk_name (thunk_name, need_bnd_p);> ++> ++ snprintf (push_buf, sizeof (push_buf), "push{%c}\t%s",> ++ TARGET_64BIT ? 'q' : 'l', xasm);> ++> ++ if (sibcall_p)> ++ {> ++ output_asm_insn (push_buf, &call_op);> ++ if (thunk_name != NULL)> ++ {> ++ if (need_bnd_p)> ++ fprintf (asm_out_file, "\tbnd jmp\t%s\n", thunk_name);> ++ else> ++ fprintf (asm_out_file, "\tjmp\t%s\n", thunk_name);> ++ }> ++ else> ++ output_indirect_thunk (need_bnd_p);> ++ }> ++ else> ++ {> ++ char indirectlabel1[32];> ++ char indirectlabel2[32];> ++> ++ ASM_GENERATE_INTERNAL_LABEL (indirectlabel1,> ++ INDIRECT_LABEL,> ++ indirectlabelno++);> ++ ASM_GENERATE_INTERNAL_LABEL (indirectlabel2,> ++ INDIRECT_LABEL,> ++ indirectlabelno++);> ++> ++ /* Jump. */> ++ if (need_bnd_p)> ++ fputs ("\tbnd jmp\t", asm_out_file);> ++ else> ++ fputs ("\tjmp\t", asm_out_file);> ++ assemble_name_raw (asm_out_file, indirectlabel2);> ++ fputc ('\n', asm_out_file);> ++> ++ ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, indirectlabel1);> ++> ++ if (MEM_P (call_op))> ++ {> ++ struct ix86_address parts;> ++ rtx addr = XEXP (call_op, 0);> ++ if (ix86_decompose_address (addr, &parts)> ++ && parts.base == stack_pointer_rtx)> ++ {> ++ /* Since call will adjust stack by -UNITS_PER_WORD,> ++ we must convert "disp(stack, index, scale)" to> ++ "disp+UNITS_PER_WORD(stack, index, scale)". */> ++ if (parts.index)> ++ {> ++ addr = gen_rtx_MULT (Pmode, parts.index,> ++ GEN_INT (parts.scale));> ++ addr = gen_rtx_PLUS (Pmode, stack_pointer_rtx,> ++ addr);> ++ }> ++ else> ++ addr = stack_pointer_rtx;> ++> ++ rtx disp;> ++ if (parts.disp != NULL_RTX)> ++ disp = plus_constant (Pmode, parts.disp,> ++ UNITS_PER_WORD);> ++ else> ++ disp = GEN_INT (UNITS_PER_WORD);> ++> ++ addr = gen_rtx_PLUS (Pmode, addr, disp);> ++ call_op = gen_rtx_MEM (GET_MODE (call_op), addr);> ++ }> ++ }> ++> ++ output_asm_insn (push_buf, &call_op);> ++> ++ if (need_bnd_p)> ++ fprintf (asm_out_file, "\tbnd jmp\t%s\n", thunk_name);> ++ else> ++ fprintf (asm_out_file, "\tjmp\t%s\n", thunk_name);> ++> ++ ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, indirectlabel2);> ++> ++ /* Call. */> ++ if (need_bnd_p)> ++ fputs ("\tbnd call\t", asm_out_file);> ++ else> ++ fputs ("\tcall\t", asm_out_file);> ++ assemble_name_raw (asm_out_file, indirectlabel1);> ++ fputc ('\n', asm_out_file);> ++ }> ++}> ++> ++const char *> ++ix86_output_indirect_jmp (rtx call_op)> ++{> ++ if (ix86_red_zone_size == 0> ++ && ix86_indirect_branch != indirect_branch_keep)> ++ {> ++ ix86_output_indirect_branch (call_op, "%0", true);> ++ return "";> ++ }> ++ else> ++ return "%!jmp\t%A0";> ++}> ++> + /* Output the assembly for a call instruction. */> + > + const char *> + ix86_output_call_insn (rtx_insn *insn, rtx call_op)> + {> + bool direct_p = constant_call_address_operand (call_op, VOIDmode);> ++ bool output_indirect_p> ++ = (!TARGET_SEH> ++ && ix86_indirect_branch != indirect_branch_keep);> + bool seh_nop_p = false;> + const char *xasm;> + > +@@ -28467,10 +28731,21 @@ ix86_output_call_insn (rtx_insn *insn, rtx call_op)> + {> + if (ix86_nopic_noplt_attribute_p (call_op))> + {> ++ direct_p = false;> + if (TARGET_64BIT)> +- xasm = "%!jmp\t{*%p0@GOTPCREL(%%rip)|[QWORD PTR %p0@GOTPCREL[rip]]}";> ++ {> ++ if (output_indirect_p)> ++ xasm = "{%p0@GOTPCREL(%%rip)|[QWORD PTR %p0@GOTPCREL[rip]]}";> ++ else> ++ xasm = "%!jmp\t{*%p0@GOTPCREL(%%rip)|[QWORD PTR %p0@GOTPCREL[rip]]}";> ++ }> + else> +- xasm = "%!jmp\t{*%p0@GOT|[DWORD PTR %p0@GOT]}";> ++ {> ++ if (output_indirect_p)> ++ xasm = "{%p0@GOT|[DWORD PTR %p0@GOT]}";> ++ else> ++ xasm = "%!jmp\t{*%p0@GOT|[DWORD PTR %p0@GOT]}";> ++ }> + }> + else> + xasm = "%!jmp\t%P0";> +@@ -28480,9 +28755,17 @@ ix86_output_call_insn (rtx_insn *insn, rtx call_op)> + else if (TARGET_SEH)> + xasm = "%!rex.W jmp\t%A0";> + else> +- xasm = "%!jmp\t%A0";> ++ {> ++ if (output_indirect_p)> ++ xasm = "%0";> ++ else> ++ xasm = "%!jmp\t%A0";> ++ }> + > +- output_asm_insn (xasm, &call_op);> ++ if (output_indirect_p && !direct_p)> ++ ix86_output_indirect_branch (call_op, xasm, true);> ++ else> ++ output_asm_insn (xasm, &call_op);> + return "";> + }> + > +@@ -28520,18 +28803,37 @@ ix86_output_call_insn (rtx_insn *insn, rtx call_op)> + {> + if (ix86_nopic_noplt_attribute_p (call_op))> + {> ++ direct_p = false;> + if (TARGET_64BIT)> +- xasm = "%!call\t{*%p0@GOTPCREL(%%rip)|[QWORD PTR %p0@GOTPCREL[rip]]}";> ++ {> ++ if (output_indirect_p)> ++ xasm = "{%p0@GOTPCREL(%%rip)|[QWORD PTR %p0@GOTPCREL[rip]]}";> ++ else> ++ xasm = "%!call\t{*%p0@GOTPCREL(%%rip)|[QWORD PTR %p0@GOTPCREL[rip]]}";> ++ }> + else> +- xasm = "%!call\t{*%p0@GOT|[DWORD PTR %p0@GOT]}";> ++ {> ++ if (output_indirect_p)> ++ xasm = "{%p0@GOT|[DWORD PTR %p0@GOT]}";> ++ else> ++ xasm = "%!call\t{*%p0@GOT|[DWORD PTR %p0@GOT]}";> ++ }> + }> + else> + xasm = "%!call\t%P0";> + }> + else> +- xasm = "%!call\t%A0";> ++ {> ++ if (output_indirect_p)> ++ xasm = "%0";> ++ else> ++ xasm = "%!call\t%A0";> ++ }> + > +- output_asm_insn (xasm, &call_op);> ++ if (output_indirect_p && !direct_p)> ++ ix86_output_indirect_branch (call_op, xasm, false);> ++ else> ++ output_asm_insn (xasm, &call_op);> + > + if (seh_nop_p)> + return "nop";> +diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md> +index 81cfba57afc..01b7b2039e6 100644> +--- a/gcc/config/i386/i386.md> ++++ b/gcc/config/i386/i386.md> +@@ -11615,7 +11615,7 @@> + (define_insn "*indirect_jump"> + [(set (pc) (match_operand:W 0 "indirect_branch_operand" "rBw"))]> + ""> +- "%!jmp\t%A0"> ++ "* return ix86_output_indirect_jmp (operands[0]);"> + [(set_attr "type" "ibr")> + (set_attr "length_immediate" "0")> + (set_attr "maybe_prefix_bnd" "1")])> +@@ -11665,7 +11665,7 @@> + [(set (pc) (match_operand:W 0 "indirect_branch_operand" "rBw"))> + (use (label_ref (match_operand 1)))]> + ""> +- "%!jmp\t%A0"> ++ "* return ix86_output_indirect_jmp (operands[0]);"> + [(set_attr "type" "ibr")> + (set_attr "length_immediate" "0")> + (set_attr "maybe_prefix_bnd" "1")])> +@@ -12337,7 +12337,7 @@> + [(simple_return)> + (use (match_operand:SI 0 "register_operand" "r"))]> + "reload_completed"> +- "%!jmp\t%A0"> ++ "* return ix86_output_indirect_jmp (operands[0]);"> + [(set_attr "type" "ibr")> + (set_attr "length_immediate" "0")> + (set_attr "maybe_prefix_bnd" "1")])> +diff --git a/gcc/config/i386/i386.opt b/gcc/config/i386/i386.opt> +index 9384e29b1de..1773e5614cf 100644> +--- a/gcc/config/i386/i386.opt> ++++ b/gcc/config/i386/i386.opt> +@@ -927,3 +927,17 @@ Attempt to avoid generating instruction sequences containing ret bytes.> + mgeneral-regs-only> + Target Report RejectNegative Mask(GENERAL_REGS_ONLY) Var(ix86_target_flags) Save> + Generate code which uses only the general registers.> ++> ++mindirect-branch=> ++Target Report RejectNegative Joined Enum(indirect_branch) Var(ix86_indirect_branch) Init(indirect_branch_keep)> ++Update indirect call and jump.> ++> ++Enum> ++Name(indirect_branch) Type(enum indirect_branch)> ++Known indirect branch choices (for use with the -mindirect-branch= option):> ++> ++EnumValue> ++Enum(indirect_branch) String(keep) Value(indirect_branch_keep)> ++> ++EnumValue> ++Enum(indirect_branch) String(thunk) Value(indirect_branch_thunk)> +diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi> +index a0fb09eb9e1..fafda2926bd 100644> +--- a/gcc/doc/invoke.texi> ++++ b/gcc/doc/invoke.texi> +@@ -1210,7 +1210,7 @@ See RS/6000 and PowerPC Options.> + -msse2avx -mfentry -mrecord-mcount -mnop-mcount -m8bit-idiv @gol> + -mavx256-split-unaligned-load -mavx256-split-unaligned-store @gol> + -malign-data=@var{type} -mstack-protector-guard=@var{guard} @gol> +--mmitigate-rop -mgeneral-regs-only}> ++-mmitigate-rop -mgeneral-regs-only -mindirect-branch=@var{choice}}> + > + @emph{x86 Windows Options}> + @gccoptlist{-mconsole -mcygwin -mno-cygwin -mdll @gol> +@@ -25648,6 +25648,13 @@ Generate code that uses only the general-purpose registers. This> + prevents the compiler from using floating-point, vector, mask and bound> + registers.> + > ++@item -mindirect-branch=@var{choice}> ++@opindex -mindirect-branch> ++Update indirect call and jump with @var{choice}. The default is> ++@samp{keep}, which keeps indirect call and jump unmodified.> ++@samp{thunk} converts indirect call and jump to push and> ++PC-relative call thunk.> ++> + @end table> + > + These @samp{-m} switches are supported in addition to the above> +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-1.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-1.c> +new file mode 100644> +index 00000000000..d8b6f5a06a5> +--- /dev/null> ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-1.c> +@@ -0,0 +1,19 @@> ++/* { dg-do compile } */> ++/* { dg-options "-O2 -mindirect-branch=thunk -fno-pic" } */> ++> ++typedef void (*dispatch_t)(long offset);> ++> ++dispatch_t dispatch;> ++> ++void> ++male_indirect_jump (long offset)> ++{> ++ dispatch(offset);> ++}> ++> ++/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { ! x32 } } } } */> ++/* { dg-final { scan-assembler "pushq\[ \t\]%rax" { target x32 } } } */> ++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" } } */> ++/* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */> ++/* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */> ++/* { dg-final { scan-assembler {\tlfence} } } */> +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-2.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-2.c> +new file mode 100644> +index 00000000000..f7d5cb315a8> +--- /dev/null> ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-2.c> +@@ -0,0 +1,19 @@> ++/* { dg-do compile } */> ++/* { dg-options "-O2 -mindirect-branch=thunk -fno-pic" } */> ++> ++typedef void (*dispatch_t)(long offset);> ++> ++dispatch_t dispatch[256];> ++> ++void> ++male_indirect_jump (long offset)> ++{> ++ dispatch[offset](offset);> ++}> ++> ++/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { ! x32 } } } } */> ++/* { dg-final { scan-assembler "pushq\[ \t\]%rax" { target x32 } } } */> ++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" } } */> ++/* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */> ++/* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */> ++/* { dg-final { scan-assembler {\tlfence} } } */> +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-3.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-3.c> +new file mode 100644> +index 00000000000..736d7cda058> +--- /dev/null> ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-3.c> +@@ -0,0 +1,20 @@> ++/* { dg-do compile } */> ++/* { dg-options "-O2 -mindirect-branch=thunk -fno-pic" } */> ++> ++typedef void (*dispatch_t)(long offset);> ++> ++dispatch_t dispatch;> ++> ++int> ++male_indirect_jump (long offset)> ++{> ++ dispatch(offset);> ++ return 0;> ++}> ++> ++/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { ! x32 } } } } */> ++/* { dg-final { scan-assembler "pushq\[ \t\]%rax" { target x32 } } } */> ++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" } } */> ++/* { dg-final { scan-assembler-times "jmp\[ \t\]*\.LIND" 2 } } */> ++/* { dg-final { scan-assembler-times "call\[ \t\]*\.LIND" 2 } } */> ++/* { dg-final { scan-assembler {\tlfence} } } */> +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-4.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-4.c> +new file mode 100644> +index 00000000000..cef9b10513e> +--- /dev/null> ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-4.c> +@@ -0,0 +1,20 @@> ++/* { dg-do compile } */> ++/* { dg-options "-O2 -mindirect-branch=thunk -fno-pic" } */> ++> ++typedef void (*dispatch_t)(long offset);> ++> ++dispatch_t dispatch[256];> ++> ++int> ++male_indirect_jump (long offset)> ++{> ++ dispatch[offset](offset);> ++ return 0;> ++}> ++> ++/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { ! x32 } } } } */> ++/* { dg-final { scan-assembler "pushq\[ \t\]%rax" { target x32 } } } */> ++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" } } */> ++/* { dg-final { scan-assembler-times "jmp\[ \t\]*\.LIND" 2 } } */> ++/* { dg-final { scan-assembler-times "call\[ \t\]*\.LIND" 2 } } */> ++/* { dg-final { scan-assembler {\tlfence} } } */> +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-5.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-5.c> +new file mode 100644> +index 00000000000..1a9bb0e431e> +--- /dev/null> ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-5.c> +@@ -0,0 +1,16 @@> ++/* { dg-do compile { target *-*-linux* } } */> ++/* { dg-options "-O2 -fpic -fno-plt -mindirect-branch=thunk" } */> ++> ++extern void bar (void);> ++> ++void> ++foo (void)> ++{> ++ bar ();> ++}> ++> ++/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*bar@GOT" } } */> ++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" } } */> ++/* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */> ++/* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */> ++/* { dg-final { scan-assembler {\tlfence} } } */> +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-6.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-6.c> +new file mode 100644> +index 00000000000..bc7d20ec6ad> +--- /dev/null> ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-6.c> +@@ -0,0 +1,17 @@> ++/* { dg-do compile { target *-*-linux* } } */> ++/* { dg-options "-O2 -fpic -fno-plt -mindirect-branch=thunk" } */> ++> ++extern void bar (void);> ++> ++int> ++foo (void)> ++{> ++ bar ();> ++ return 0;> ++}> ++> ++/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*bar@GOT" } } */> ++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" } } */> ++/* { dg-final { scan-assembler-times "jmp\[ \t\]*\.LIND" 2 } } */> ++/* { dg-final { scan-assembler-times "call\[ \t\]*\.LIND" 2 } } */> ++/* { dg-final { scan-assembler {\tlfence} } } */> +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-7.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-7.c> +new file mode 100644> +index 00000000000..ea0fa312f64> +--- /dev/null> ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-7.c> +@@ -0,0 +1,43 @@> ++/* { dg-do compile } */> ++/* { dg-options "-O2 -mindirect-branch=thunk -fno-pic" } */> ++> ++void func0 (void);> ++void func1 (void);> ++void func2 (void);> ++void func3 (void);> ++void func4 (void);> ++void func4 (void);> ++void func5 (void);> ++> ++void> ++bar (int i)> ++{> ++ switch (i)> ++ {> ++ default:> ++ func0 ();> ++ break;> ++ case 1:> ++ func1 ();> ++ break;> ++ case 2:> ++ func2 ();> ++ break;> ++ case 3:> ++ func3 ();> ++ break;> ++ case 4:> ++ func4 ();> ++ break;> ++ case 5:> ++ func5 ();> ++ break;> ++ }> ++}> ++> ++/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*\.L\[0-9\]+\\(,%" { target { ! x32 } } } } */> ++/* { dg-final { scan-assembler "pushq\[ \t\]%rax" { target x32 } } } */> ++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" } } */> ++/* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */> ++/* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */> ++/* { dg-final { scan-assembler {\tlfence} } } */> +-- > +2.15.1> +> diff --git a/gnu/packages/patches/gcc-retpoline-Add-mno-indirect-branch-register-to-indirect-branch-.patch b/gnu/packages/patches/gcc-retpoline-Add-mno-indirect-branch-register-to-indirect-branch-.patch> new file mode 100644> index 000000000..2b4ac1b81> --- /dev/null> +++ b/gnu/packages/patches/gcc-retpoline-Add-mno-indirect-branch-register-to-indirect-branch-.patch> @@ -0,0 +1,554 @@> +'Retpoline' mitigation technique for Spectre (branch target injection)> +[CVE-2017-5715]:> +> +https://security.googleblog.com/2018/01/more-details-about-mitigations-for-cpu_4.html> +https://support.google.com/faqs/answer/7625886> +https://spectreattack.com/> +https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2017-5715> +> +Patch copied from the 'retpoline-20180107' branch of upstream source repository> +(please add new / update existing patches when new 'retpoline-xxxxxxxx' branch> +appears):> +> +http://git.infradead.org/users/dwmw2/gcc-retpoline.git> +> +From 2c14ecf03978ce6c60e021a2b0d72778a5fe0982 Mon Sep 17 00:00:00 2001> +From: "H.J. Lu" <hjl.tools@gmail.com>> +Date: Tue, 12 Dec 2017 12:34:26 -0800> +Subject: [PATCH 14/17] Add -mno-indirect-branch-register to indirect branch> + tests> +> +---> + gcc/testsuite/gcc.target/i386/indirect-thunk-1.c | 2 +-> + gcc/testsuite/gcc.target/i386/indirect-thunk-2.c | 2 +-> + gcc/testsuite/gcc.target/i386/indirect-thunk-3.c | 2 +-> + gcc/testsuite/gcc.target/i386/indirect-thunk-4.c | 2 +-> + gcc/testsuite/gcc.target/i386/indirect-thunk-5.c | 2 +-> + gcc/testsuite/gcc.target/i386/indirect-thunk-6.c | 2 +-> + gcc/testsuite/gcc.target/i386/indirect-thunk-7.c | 2 +-> + gcc/testsuite/gcc.target/i386/indirect-thunk-attr-1.c | 2 +-> + gcc/testsuite/gcc.target/i386/indirect-thunk-attr-2.c | 2 +-> + gcc/testsuite/gcc.target/i386/indirect-thunk-attr-3.c | 2 +-> + gcc/testsuite/gcc.target/i386/indirect-thunk-attr-4.c | 2 +-> + gcc/testsuite/gcc.target/i386/indirect-thunk-attr-5.c | 2 +-> + gcc/testsuite/gcc.target/i386/indirect-thunk-attr-6.c | 2 +-> + gcc/testsuite/gcc.target/i386/indirect-thunk-attr-7.c | 2 +-> + gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-1.c | 2 +-> + gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-2.c | 2 +-> + gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-3.c | 2 +-> + gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-4.c | 2 +-> + gcc/testsuite/gcc.target/i386/indirect-thunk-extern-1.c | 2 +-> + gcc/testsuite/gcc.target/i386/indirect-thunk-extern-2.c | 2 +-> + gcc/testsuite/gcc.target/i386/indirect-thunk-extern-3.c | 2 +-> + gcc/testsuite/gcc.target/i386/indirect-thunk-extern-4.c | 2 +-> + gcc/testsuite/gcc.target/i386/indirect-thunk-extern-5.c | 2 +-> + gcc/testsuite/gcc.target/i386/indirect-thunk-extern-6.c | 2 +-> + gcc/testsuite/gcc.target/i386/indirect-thunk-extern-7.c | 2 +-> + gcc/testsuite/gcc.target/i386/indirect-thunk-inline-1.c | 2 +-> + gcc/testsuite/gcc.target/i386/indirect-thunk-inline-2.c | 2 +-> + gcc/testsuite/gcc.target/i386/indirect-thunk-inline-3.c | 2 +-> + gcc/testsuite/gcc.target/i386/indirect-thunk-inline-4.c | 2 +-> + gcc/testsuite/gcc.target/i386/indirect-thunk-inline-5.c | 2 +-> + gcc/testsuite/gcc.target/i386/indirect-thunk-inline-6.c | 2 +-> + gcc/testsuite/gcc.target/i386/indirect-thunk-inline-7.c | 2 +-> + gcc/testsuite/gcc.target/i386/indirect-thunk-loop-1.c | 2 +-> + gcc/testsuite/gcc.target/i386/indirect-thunk-loop-2.c | 2 +-> + gcc/testsuite/gcc.target/i386/indirect-thunk-loop-3.c | 2 +-> + gcc/testsuite/gcc.target/i386/indirect-thunk-loop-4.c | 2 +-> + gcc/testsuite/gcc.target/i386/indirect-thunk-loop-5.c | 2 +-> + gcc/testsuite/gcc.target/i386/ret-thunk-10.c | 2 +-> + gcc/testsuite/gcc.target/i386/ret-thunk-11.c | 2 +-> + gcc/testsuite/gcc.target/i386/ret-thunk-12.c | 2 +-> + gcc/testsuite/gcc.target/i386/ret-thunk-13.c | 2 +-> + gcc/testsuite/gcc.target/i386/ret-thunk-14.c | 2 +-> + gcc/testsuite/gcc.target/i386/ret-thunk-15.c | 2 +-> + gcc/testsuite/gcc.target/i386/ret-thunk-9.c | 2 +-> + 44 files changed, 44 insertions(+), 44 deletions(-)> +> +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-1.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-1.c> +index 318db1e7f5c..b0625207b92 100644> +--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-1.c> ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-1.c> +@@ -1,5 +1,5 @@> + /* { dg-do compile } */> +-/* { dg-options "-O2 -mfunction-return=keep -mindirect-branch=thunk -fno-pic" } */> ++/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=keep -mindirect-branch=thunk -fno-pic" } */> + > + typedef void (*dispatch_t)(long offset);> + > +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-2.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-2.c> +index f2700dd36cf..0b289685e6b 100644> +--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-2.c> ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-2.c> +@@ -1,5 +1,5 @@> + /* { dg-do compile } */> +-/* { dg-options "-O2 -mfunction-return=keep -mindirect-branch=thunk -fno-pic" } */> ++/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=keep -mindirect-branch=thunk -fno-pic" } */> + > + typedef void (*dispatch_t)(long offset);> + > +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-3.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-3.c> +index 46685d9a674..79a9f76285f 100644> +--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-3.c> ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-3.c> +@@ -1,5 +1,5 @@> + /* { dg-do compile } */> +-/* { dg-options "-O2 -mfunction-return=keep -mindirect-branch=thunk -fno-pic" } */> ++/* { dg-options "-O2 -mno-indirect-branch-register -mno-indirect-branch-register -mno-indirect-branch-register -mfunction-return=keep -mindirect-branch=thunk -fno-pic" } */> + > + typedef void (*dispatch_t)(long offset);> + > +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-4.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-4.c> +index 8f701775cea..901d94213bd 100644> +--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-4.c> ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-4.c> +@@ -1,5 +1,5 @@> + /* { dg-do compile } */> +-/* { dg-options "-O2 -mfunction-return=keep -mindirect-branch=thunk -fno-pic" } */> ++/* { dg-options "-O2 -mno-indirect-branch-register -mno-indirect-branch-register -mno-indirect-branch-register -mfunction-return=keep -mindirect-branch=thunk -fno-pic" } */> + > + typedef void (*dispatch_t)(long offset);> + > +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-5.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-5.c> +index f88ac31d07a..d2c9bd9d7ca 100644> +--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-5.c> ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-5.c> +@@ -1,5 +1,5 @@> + /* { dg-do compile { target *-*-linux* } } */> +-/* { dg-options "-O2 -mfunction-return=keep -fpic -fno-plt -mindirect-branch=thunk" } */> ++/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=keep -fpic -fno-plt -mindirect-branch=thunk" } */> + > + extern void bar (void);> + > +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-6.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-6.c> +index d745116d321..f8b028db7a2 100644> +--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-6.c> ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-6.c> +@@ -1,5 +1,5 @@> + /* { dg-do compile { target *-*-linux* } } */> +-/* { dg-options "-O2 -mfunction-return=keep -fpic -fno-plt -mindirect-branch=thunk" } */> ++/* { dg-options "-O2 -mno-indirect-branch-register -mno-indirect-branch-register -mno-indirect-branch-register -mfunction-return=keep -fpic -fno-plt -mindirect-branch=thunk" } */> + > + extern void bar (void);> + > +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-7.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-7.c> +index 969cb8c6ddc..465775407ec 100644> +--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-7.c> ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-7.c> +@@ -1,5 +1,5 @@> + /* { dg-do compile } */> +-/* { dg-options "-O2 -mfunction-return=keep -mindirect-branch=thunk -fno-pic" } */> ++/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=keep -mindirect-branch=thunk -fno-pic" } */> + > + void func0 (void);> + void func1 (void);> +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-1.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-1.c> +index 12a61c3bbc7..5309d5a3eaa 100644> +--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-1.c> ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-1.c> +@@ -1,5 +1,5 @@> + /* { dg-do compile } */> +-/* { dg-options "-O2 -mfunction-return=keep -fno-pic" } */> ++/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=keep -fno-pic" } */> + > + typedef void (*dispatch_t)(long offset);> + > +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-2.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-2.c> +index a06907933a2..dd1efca49fd 100644> +--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-2.c> ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-2.c> +@@ -1,5 +1,5 @@> + /* { dg-do compile } */> +-/* { dg-options "-O2 -mfunction-return=keep -fno-pic" } */> ++/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=keep -fno-pic" } */> + > + typedef void (*dispatch_t)(long offset);> + > +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-3.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-3.c> +index 7f56725e6b6..e97ca636020 100644> +--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-3.c> ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-3.c> +@@ -1,5 +1,5 @@> + /* { dg-do compile } */> +-/* { dg-options "-O2 -mfunction-return=keep -fno-pic" } */> ++/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=keep -fno-pic" } */> + > + typedef void (*dispatch_t)(long offset);> + > +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-4.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-4.c> +index fd4ab1dbaa0..b547cbbf255 100644> +--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-4.c> ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-4.c> +@@ -1,5 +1,5 @@> + /* { dg-do compile } */> +-/* { dg-options "-O2 -mfunction-return=keep -fno-pic" } */> ++/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=keep -fno-pic" } */> + > + typedef void (*dispatch_t)(long offset);> + > +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-5.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-5.c> +index 1ffbf3b1181..353689dc415 100644> +--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-5.c> ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-5.c> +@@ -1,5 +1,5 @@> + /* { dg-do compile } */> +-/* { dg-options "-O2 -mfunction-return=keep -fno-pic" } */> ++/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=keep -fno-pic" } */> + > + typedef void (*dispatch_t)(long offset);> + > +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-6.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-6.c> +index 1559072919a..1edef7208f4 100644> +--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-6.c> ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-6.c> +@@ -1,5 +1,5 @@> + /* { dg-do compile } */> +-/* { dg-options "-O2 -mfunction-return=keep -fno-pic" } */> ++/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=keep -fno-pic" } */> + > + typedef void (*dispatch_t)(long offset);> + > +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-7.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-7.c> +index 1717e7bb436..c2e816cdfc6 100644> +--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-7.c> ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-7.c> +@@ -1,5 +1,5 @@> + /* { dg-do compile } */> +-/* { dg-options "-O2 -mfunction-return=keep -fno-pic" } */> ++/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=keep -fno-pic" } */> + > + void func0 (void);> + void func1 (void);> +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-1.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-1.c> +index 20903b0f79d..5c10de47b7c 100644> +--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-1.c> ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-1.c> +@@ -1,5 +1,5 @@> + /* { dg-do compile { target { ! x32 } } } */> +-/* { dg-options "-O2 -mfunction-return=keep -mindirect-branch=thunk -fcheck-pointer-bounds -mmpx -fno-pic" } */> ++/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=keep -mindirect-branch=thunk -fcheck-pointer-bounds -mmpx -fno-pic" } */> + > + void (*dispatch) (char *);> + char buf[10];> +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-2.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-2.c> +index aef4bd144f4..9eedd9a5a82 100644> +--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-2.c> ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-2.c> +@@ -1,5 +1,5 @@> + /* { dg-do compile { target { ! x32 } } } */> +-/* { dg-options "-O2 -mfunction-return=keep -mindirect-branch=thunk -fcheck-pointer-bounds -mmpx -fno-pic" } */> ++/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=keep -mindirect-branch=thunk -fcheck-pointer-bounds -mmpx -fno-pic" } */> + > + void (*dispatch) (char *);> + char buf[10];> +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-3.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-3.c> +index 2cc0343f828..b2b8587eac7 100644> +--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-3.c> ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-3.c> +@@ -1,5 +1,5 @@> + /* { dg-do compile { target { *-*-linux* && { ! x32 } } } } */> +-/* { dg-options "-O2 -mfunction-return=keep -mindirect-branch=thunk -fcheck-pointer-bounds -mmpx -fpic -fno-plt" } */> ++/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=keep -mindirect-branch=thunk -fcheck-pointer-bounds -mmpx -fpic -fno-plt" } */> + > + void bar (char *);> + char buf[10];> +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-4.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-4.c> +index 91560fef661..9459a2417f4 100644> +--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-4.c> ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-4.c> +@@ -1,5 +1,5 @@> + /* { dg-do compile { target { *-*-linux* && { ! x32 } } } } */> +-/* { dg-options "-O2 -mfunction-return=keep -mindirect-branch=thunk -fcheck-pointer-bounds -mmpx -fpic -fno-plt" } */> ++/* { dg-options "-O2 -mno-indirect-branch-register -mno-indirect-branch-register -mfunction-return=keep -mindirect-branch=thunk -fcheck-pointer-bounds -mmpx -fpic -fno-plt" } */> + > + void bar (char *);> + char buf[10];> +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-1.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-1.c> +index dc6bd10af4c..b0aa3811e65 100644> +--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-1.c> ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-1.c> +@@ -1,5 +1,5 @@> + /* { dg-do compile } */> +-/* { dg-options "-O2 -mfunction-return=keep -mindirect-branch=thunk-extern -fno-pic" } */> ++/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=keep -mindirect-branch=thunk-extern -fno-pic" } */> + > + typedef void (*dispatch_t)(long offset);> + > +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-2.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-2.c> +index 955aa256529..75fabcd988c 100644> +--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-2.c> ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-2.c> +@@ -1,5 +1,5 @@> + /* { dg-do compile } */> +-/* { dg-options "-O2 -mfunction-return=keep -mindirect-branch=thunk-extern -fno-pic" } */> ++/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=keep -mindirect-branch=thunk-extern -fno-pic" } */> + > + typedef void (*dispatch_t)(long offset);> + > +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-3.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-3.c> +index 1537239416f..1d9dff2e834 100644> +--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-3.c> ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-3.c> +@@ -1,5 +1,5 @@> + /* { dg-do compile } */> +-/* { dg-options "-O2 -mfunction-return=keep -mindirect-branch=thunk-extern -fno-pic" } */> ++/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=keep -mindirect-branch=thunk-extern -fno-pic" } */> + > + typedef void (*dispatch_t)(long offset);> + > +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-4.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-4.c> +index c82e53068fe..5b464155e38 100644> +--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-4.c> ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-4.c> +@@ -1,5 +1,5 @@> + /* { dg-do compile } */> +-/* { dg-options "-O2 -mfunction-return=keep -mindirect-branch=thunk-extern -fno-pic" } */> ++/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=keep -mindirect-branch=thunk-extern -fno-pic" } */> + > + typedef void (*dispatch_t)(long offset);> + > +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-5.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-5.c> +index 23548d85f78..55ce91c73ec 100644> +--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-5.c> ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-5.c> +@@ -1,5 +1,5 @@> + /* { dg-do compile { target *-*-linux* } } */> +-/* { dg-options "-O2 -mfunction-return=keep -fpic -fno-plt -mindirect-branch=thunk-extern" } */> ++/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=keep -fpic -fno-plt -mindirect-branch=thunk-extern" } */> + > + extern void bar (void);> + > +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-6.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-6.c> +index 56c2fe92f25..06180e7bee9 100644> +--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-6.c> ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-6.c> +@@ -1,5 +1,5 @@> + /* { dg-do compile { target *-*-linux* } } */> +-/* { dg-options "-O2 -mfunction-return=keep -fpic -fno-plt -mindirect-branch=thunk-extern" } */> ++/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=keep -fpic -fno-plt -mindirect-branch=thunk-extern" } */> + > + extern void bar (void);> + > +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-7.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-7.c> +index e12b88593fe..790a05cec3e 100644> +--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-7.c> ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-7.c> +@@ -1,5 +1,5 @@> + /* { dg-do compile } */> +-/* { dg-options "-O2 -mfunction-return=keep -mindirect-branch=thunk-extern -fno-pic" } */> ++/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=keep -mindirect-branch=thunk-extern -fno-pic" } */> + > + void func0 (void);> + void func1 (void);> +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-1.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-1.c> +index 87b5429702f..1ce8ca5aff1 100644> +--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-1.c> ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-1.c> +@@ -1,5 +1,5 @@> + /* { dg-do compile } */> +-/* { dg-options "-O2 -mfunction-return=keep -mindirect-branch=thunk-inline -fno-pic" } */> ++/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=keep -mindirect-branch=thunk-inline -fno-pic" } */> + > + typedef void (*dispatch_t)(long offset);> + > +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-2.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-2.c> +index a496a41a918..f6b71e868bd 100644> +--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-2.c> ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-2.c> +@@ -1,5 +1,5 @@> + /* { dg-do compile } */> +-/* { dg-options "-O2 -mfunction-return=keep -mindirect-branch=thunk-inline -fno-pic" } */> ++/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=keep -mindirect-branch=thunk-inline -fno-pic" } */> + > + typedef void (*dispatch_t)(long offset);> + > +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-3.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-3.c> +index 6fe5ce71abf..84a09d4d0d6 100644> +--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-3.c> ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-3.c> +@@ -1,5 +1,5 @@> + /* { dg-do compile } */> +-/* { dg-options "-O2 -mfunction-return=keep -mindirect-branch=thunk-inline -fno-pic" } */> ++/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=keep -mindirect-branch=thunk-inline -fno-pic" } */> + > + typedef void (*dispatch_t)(long offset);> + > +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-4.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-4.c> +index 65cd997a33f..cfe3aefa0bf 100644> +--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-4.c> ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-4.c> +@@ -1,5 +1,5 @@> + /* { dg-do compile } */> +-/* { dg-options "-O2 -mfunction-return=keep -mindirect-branch=thunk-inline -fno-pic" } */> ++/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=keep -mindirect-branch=thunk-inline -fno-pic" } */> + > + typedef void (*dispatch_t)(long offset);> + > +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-5.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-5.c> +index 7321d015c02..6411454243f 100644> +--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-5.c> ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-5.c> +@@ -1,5 +1,5 @@> + /* { dg-do compile { target *-*-linux* } } */> +-/* { dg-options "-O2 -mfunction-return=keep -fpic -fno-plt -mindirect-branch=thunk-inline" } */> ++/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=keep -fpic -fno-plt -mindirect-branch=thunk-inline" } */> + > + extern void bar (void);> + > +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-6.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-6.c> +index 6ec2e5621ab..d4297fe21c4 100644> +--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-6.c> ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-6.c> +@@ -1,5 +1,5 @@> + /* { dg-do compile { target *-*-linux* } } */> +-/* { dg-options "-O2 -mfunction-return=keep -fpic -fno-plt -mindirect-branch=thunk-inline" } */> ++/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=keep -fpic -fno-plt -mindirect-branch=thunk-inline" } */> + > + extern void bar (void);> + > +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-7.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-7.c> +index a3d1a13cded..eb318efdf4d 100644> +--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-7.c> ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-7.c> +@@ -1,5 +1,5 @@> + /* { dg-do compile } */> +-/* { dg-options "-O2 -mfunction-return=keep -mindirect-branch=thunk-inline -fno-pic" } */> ++/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=keep -mindirect-branch=thunk-inline -fno-pic" } */> + > + void func0 (void);> + void func1 (void);> +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-loop-1.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-loop-1.c> +index f0e8f4949c8..605e32bb584 100644> +--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-loop-1.c> ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-loop-1.c> +@@ -1,5 +1,5 @@> + /* { dg-do compile } */> +-/* { dg-options "-O2 -mindirect-branch=thunk -mindirect-branch-loop=pause -fno-pic" } */> ++/* { dg-options "-O2 -mno-indirect-branch-register -mindirect-branch=thunk -mindirect-branch-loop=pause -fno-pic" } */> + > + typedef void (*dispatch_t)(long offset);> + > +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-loop-2.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-loop-2.c> +index a577ac2568a..dd7a7b60621 100644> +--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-loop-2.c> ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-loop-2.c> +@@ -1,5 +1,5 @@> + /* { dg-do compile } */> +-/* { dg-options "-O2 -mindirect-branch=thunk -mindirect-branch-loop=nop -fno-pic" } */> ++/* { dg-options "-O2 -mno-indirect-branch-register -mindirect-branch=thunk -mindirect-branch-loop=nop -fno-pic" } */> + > + typedef void (*dispatch_t)(long offset);> + > +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-loop-3.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-loop-3.c> +index c8dcb9639c4..338f22c373c 100644> +--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-loop-3.c> ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-loop-3.c> +@@ -1,5 +1,5 @@> + /* { dg-do compile } */> +-/* { dg-options "-O2 -mindirect-branch=thunk -mindirect-branch-loop=lfence -fno-pic" } */> ++/* { dg-options "-O2 -mno-indirect-branch-register -mindirect-branch=thunk -mindirect-branch-loop=lfence -fno-pic" } */> + > + typedef void (*dispatch_t)(long offset);> + > +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-loop-4.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-loop-4.c> +index 8569dfc92c3..3b083ee30a8 100644> +--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-loop-4.c> ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-loop-4.c> +@@ -1,5 +1,5 @@> + /* { dg-do compile } */> +-/* { dg-options "-O2 -mindirect-branch=thunk-inline -mindirect-branch-loop=pause -fno-pic" } */> ++/* { dg-options "-O2 -mno-indirect-branch-register -mindirect-branch=thunk-inline -mindirect-branch-loop=pause -fno-pic" } */> + > + typedef void (*dispatch_t)(long offset);> + > +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-loop-5.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-loop-5.c> +index bcf19c9ede1..31a9a81a911 100644> +--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-loop-5.c> ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-loop-5.c> +@@ -1,5 +1,5 @@> + /* { dg-do compile } */> +-/* { dg-options "-O2 -mindirect-branch=thunk-extern -mindirect-branch-loop=pause -fno-pic" } */> ++/* { dg-options "-O2 -mno-indirect-branch-register -mindirect-branch=thunk-extern -mindirect-branch-loop=pause -fno-pic" } */> + > + typedef void (*dispatch_t)(long offset);> + > +diff --git a/gcc/testsuite/gcc.target/i386/ret-thunk-10.c b/gcc/testsuite/gcc.target/i386/ret-thunk-10.c> +index aecea4224f9..74f37ee9a62 100644> +--- a/gcc/testsuite/gcc.target/i386/ret-thunk-10.c> ++++ b/gcc/testsuite/gcc.target/i386/ret-thunk-10.c> +@@ -1,5 +1,5 @@> + /* { dg-do compile } */> +-/* { dg-options "-O2 -mfunction-return=thunk-inline -mindirect-branch=thunk -fno-pic" } */> ++/* { dg-options "-O2 -mno-indirect-branch-register -mno-indirect-branch-register -mfunction-return=thunk-inline -mindirect-branch=thunk -fno-pic" } */> + > + extern void (*bar) (void);> + > +diff --git a/gcc/testsuite/gcc.target/i386/ret-thunk-11.c b/gcc/testsuite/gcc.target/i386/ret-thunk-11.c> +index 3bacfb54dfd..0a52318e86b 100644> +--- a/gcc/testsuite/gcc.target/i386/ret-thunk-11.c> ++++ b/gcc/testsuite/gcc.target/i386/ret-thunk-11.c> +@@ -1,5 +1,5 @@> + /* { dg-do compile } */> +-/* { dg-options "-O2 -mfunction-return=thunk-extern -mindirect-branch=thunk -fno-pic" } */> ++/* { 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" } */> + > + extern void (*bar) (void);> + > +diff --git a/gcc/testsuite/gcc.target/i386/ret-thunk-12.c b/gcc/testsuite/gcc.target/i386/ret-thunk-12.c> +index 851115ac507..d2f775490ea 100644> +--- a/gcc/testsuite/gcc.target/i386/ret-thunk-12.c> ++++ b/gcc/testsuite/gcc.target/i386/ret-thunk-12.c> +@@ -1,5 +1,5 @@> + /* { dg-do compile } */> +-/* { dg-options "-O2 -mfunction-return=keep -mindirect-branch=thunk -fno-pic" } */> ++/* { 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" } */> + > + extern void (*bar) (void);> + > +diff --git a/gcc/testsuite/gcc.target/i386/ret-thunk-13.c b/gcc/testsuite/gcc.target/i386/ret-thunk-13.c> +index 7acb6fa5eae..82d46165f3e 100644> +--- a/gcc/testsuite/gcc.target/i386/ret-thunk-13.c> ++++ b/gcc/testsuite/gcc.target/i386/ret-thunk-13.c> +@@ -1,5 +1,5 @@> + /* { dg-do compile } */> +-/* { dg-options "-O2 -mfunction-return=keep -mindirect-branch=thunk-inline -fno-pic" } */> ++/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=keep -mindirect-branch=thunk-inline -fno-pic" } */> + > + extern void (*bar) (void);> + extern int foo (void) __attribute__ ((function_return("thunk")));> +diff --git a/gcc/testsuite/gcc.target/i386/ret-thunk-14.c b/gcc/testsuite/gcc.target/i386/ret-thunk-14.c> +index bf340fac7c6..6711eb27fa8 100644> +--- a/gcc/testsuite/gcc.target/i386/ret-thunk-14.c> ++++ b/gcc/testsuite/gcc.target/i386/ret-thunk-14.c> +@@ -1,5 +1,5 @@> + /* { dg-do compile } */> +-/* { dg-options "-O2 -mfunction-return=keep -mindirect-branch=thunk-extern -fno-pic" } */> ++/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=keep -mindirect-branch=thunk-extern -fno-pic" } */> + > + extern void (*bar) (void);> + > +diff --git a/gcc/testsuite/gcc.target/i386/ret-thunk-15.c b/gcc/testsuite/gcc.target/i386/ret-thunk-15.c> +index 735f8648c96..37758c33371 100644> +--- a/gcc/testsuite/gcc.target/i386/ret-thunk-15.c> ++++ b/gcc/testsuite/gcc.target/i386/ret-thunk-15.c> +@@ -1,5 +1,5 @@> + /* { dg-do compile } */> +-/* { dg-options "-O2 -mfunction-return=keep -mindirect-branch=keep -fno-pic" } */> ++/* { 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" } */> + > + extern void (*bar) (void);> + > +diff --git a/gcc/testsuite/gcc.target/i386/ret-thunk-9.c b/gcc/testsuite/gcc.target/i386/ret-thunk-9.c> +index 569e5f47973..70771ea35d7 100644> +--- a/gcc/testsuite/gcc.target/i386/ret-thunk-9.c> ++++ b/gcc/testsuite/gcc.target/i386/ret-thunk-9.c> +@@ -1,5 +1,5 @@> + /* { dg-do compile } */> +-/* { dg-options "-O2 -mfunction-return=thunk -mindirect-branch=thunk -fno-pic" } */> ++/* { dg-options "-O2 -mno-indirect-branch-register -mno-indirect-branch-register -mfunction-return=thunk -mindirect-branch=thunk -fno-pic" } */> + > + extern void (*bar) (void);> + > +-- > +2.15.1> +> diff --git a/gnu/packages/patches/gcc-retpoline-Add-tests-for-mindirect-branch-thunk-fcheck-pointer-.patch b/gnu/packages/patches/gcc-retpoline-Add-tests-for-mindirect-branch-thunk-fcheck-pointer-.patch> new file mode 100644> index 000000000..e21bb5039> --- /dev/null> +++ b/gnu/packages/patches/gcc-retpoline-Add-tests-for-mindirect-branch-thunk-fcheck-pointer-.patch> @@ -0,0 +1,134 @@> +'Retpoline' mitigation technique for Spectre (branch target injection)> +[CVE-2017-5715]:> +> +https://security.googleblog.com/2018/01/more-details-about-mitigations-for-cpu_4.html> +https://support.google.com/faqs/answer/7625886> +https://spectreattack.com/> +https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2017-5715> +> +Patch copied from the 'retpoline-20180107' branch of upstream source repository> +(please add new / update existing patches when new 'retpoline-xxxxxxxx' branch> +appears):> +> +http://git.infradead.org/users/dwmw2/gcc-retpoline.git> +> +From ece041bc3083aabd00fab9de5ba409fbd7dcad8c Mon Sep 17 00:00:00 2001> +From: "H.J. Lu" <hjl.tools@gmail.com>> +Date: Mon, 4 Dec 2017 12:58:20 -0800> +Subject: [PATCH 05/17] Add tests for -mindirect-branch=thunk> + -fcheck-pointer-bounds -mmpx> +> +---> + gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-1.c | 19 +++++++++++++++++++> + gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-2.c | 20 ++++++++++++++++++++> + gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-3.c | 18 ++++++++++++++++++> + gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-4.c | 19 +++++++++++++++++++> + 4 files changed, 76 insertions(+)> + create mode 100644 gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-1.c> + create mode 100644 gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-2.c> + create mode 100644 gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-3.c> + create mode 100644 gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-4.c> +> +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-1.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-1.c> +new file mode 100644> +index 00000000000..a5b1d38e061> +--- /dev/null> ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-1.c> +@@ -0,0 +1,19 @@> ++/* { dg-do compile { target { ! x32 } } } */> ++/* { dg-options "-O2 -mindirect-branch=thunk -fcheck-pointer-bounds -mmpx -fno-pic" } */> ++> ++void (*dispatch) (char *);> ++char buf[10];> ++> ++void> ++foo (void)> ++{> ++ dispatch (buf);> ++}> ++> ++/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { ! x32 } } } } */> ++/* { dg-final { scan-assembler "pushq\[ \t\]%rax" { target x32 } } } */> ++/* { dg-final { scan-assembler "bnd jmp\[ \t\]*__x86.indirect_thunk_bnd" } } */> ++/* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */> ++/* { dg-final { scan-assembler "bnd call\[ \t\]*\.LIND" } } */> ++/* { dg-final { scan-assembler "bnd ret" } } */> ++/* { dg-final { scan-assembler {\tlfence} } } */> +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-2.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-2.c> +new file mode 100644> +index 00000000000..a42add209e2> +--- /dev/null> ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-2.c> +@@ -0,0 +1,20 @@> ++/* { dg-do compile { target { ! x32 } } } */> ++/* { dg-options "-O2 -mindirect-branch=thunk -fcheck-pointer-bounds -mmpx -fno-pic" } */> ++> ++void (*dispatch) (char *);> ++char buf[10];> ++> ++int> ++foo (void)> ++{> ++ dispatch (buf);> ++ return 0;> ++}> ++> ++/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { ! x32 } } } } */> ++/* { dg-final { scan-assembler "pushq\[ \t\]%rax" { target x32 } } } */> ++/* { dg-final { scan-assembler "bnd jmp\[ \t\]*__x86.indirect_thunk_bnd" } } */> ++/* { dg-final { scan-assembler "bnd jmp\[ \t\]*\.LIND" } } */> ++/* { dg-final { scan-assembler "bnd call\[ \t\]*\.LIND" } } */> ++/* { dg-final { scan-assembler "bnd ret" } } */> ++/* { dg-final { scan-assembler {\tlfence} } } */> +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-3.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-3.c> +new file mode 100644> +index 00000000000..265e010a0fe> +--- /dev/null> ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-3.c> +@@ -0,0 +1,18 @@> ++/* { dg-do compile { target { *-*-linux* && { ! x32 } } } } */> ++/* { dg-options "-O2 -mindirect-branch=thunk -fcheck-pointer-bounds -mmpx -fpic -fno-plt" } */> ++> ++void bar (char *);> ++char buf[10];> ++> ++void> ++foo (void)> ++{> ++ bar (buf);> ++}> ++> ++/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*bar@GOT" } } */> ++/* { dg-final { scan-assembler "bnd jmp\[ \t\]*__x86.indirect_thunk_bnd" } } */> ++/* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */> ++/* { dg-final { scan-assembler "bnd call\[ \t\]*\.LIND" } } */> ++/* { dg-final { scan-assembler "bnd ret" } } */> ++/* { dg-final { scan-assembler {\tlfence} } } */> +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-4.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-4.c> +new file mode 100644> +index 00000000000..1c01bcb7fc6> +--- /dev/null> ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-4.c> +@@ -0,0 +1,19 @@> ++/* { dg-do compile { target { *-*-linux* && { ! x32 } } } } */> ++/* { dg-options "-O2 -mindirect-branch=thunk -fcheck-pointer-bounds -mmpx -fpic -fno-plt" } */> ++> ++void bar (char *);> ++char buf[10];> ++> ++int> ++foo (void)> ++{> ++ bar (buf);> ++ return 0;> ++}> ++> ++/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*bar@GOT" } } */> ++/* { dg-final { scan-assembler "bnd jmp\[ \t\]*__x86.indirect_thunk" } } */> ++/* { dg-final { scan-assembler "bnd jmp\[ \t\]*\.LIND" } } */> ++/* { dg-final { scan-assembler-times "bnd call\[ \t\]*\.LIND" 2 } } */> ++/* { dg-final { scan-assembler "bnd ret" } } */> ++/* { dg-final { scan-assembler {\tlfence} } } */> +-- > +2.15.1> +> diff --git a/gnu/packages/patches/gcc-retpoline-Disable-red-zone-with-local-indirect-jump.patch b/gnu/packages/patches/gcc-retpoline-Disable-red-zone-with-local-indirect-jump.patch> new file mode 100644> index 000000000..b22e364af> --- /dev/null> +++ b/gnu/packages/patches/gcc-retpoline-Disable-red-zone-with-local-indirect-jump.patch> @@ -0,0 +1,147 @@> +'Retpoline' mitigation technique for Spectre (branch target injection)> +[CVE-2017-5715]:> +> +https://security.googleblog.com/2018/01/more-details-about-mitigations-for-cpu_4.html> +https://support.google.com/faqs/answer/7625886> +https://spectreattack.com/> +https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2017-5715> +> +Patch copied from the 'retpoline-20180107' branch of upstream source repository> +(please add new / update existing patches when new 'retpoline-xxxxxxxx' branch> +appears):> +> +http://git.infradead.org/users/dwmw2/gcc-retpoline.git> +> +From f96e28553b0f2253184441f22852d76976e19968 Mon Sep 17 00:00:00 2001> +From: "H.J. Lu" <hjl.tools@gmail.com>> +Date: Tue, 12 Dec 2017 19:15:25 -0800> +Subject: [PATCH 15/17] Disable red zone with local indirect jump> +> +---> + gcc/config/i386/i386-protos.h | 2 +-> + gcc/config/i386/i386.c | 22 +++++++++++++++++-----> + gcc/config/i386/i386.h | 4 ++++> + gcc/config/i386/i386.md | 8 +++++---> + 4 files changed, 27 insertions(+), 9 deletions(-)> +> +diff --git a/gcc/config/i386/i386-protos.h b/gcc/config/i386/i386-protos.h> +index 213663811de..a78bfa00427 100644> +--- a/gcc/config/i386/i386-protos.h> ++++ b/gcc/config/i386/i386-protos.h> +@@ -315,7 +315,7 @@ extern enum attr_cpu ix86_schedule;> + #endif> + > + extern const char * ix86_output_call_insn (rtx_insn *insn, rtx call_op);> +-extern const char * ix86_output_indirect_jmp (rtx call_op);> ++extern const char * ix86_output_indirect_jmp (rtx call_op, bool ret_p);> + extern const char * ix86_output_function_return (bool long_p);> + extern bool ix86_operands_ok_for_move_multiple (rtx *operands, bool load,> + enum machine_mode mode);> +diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c> +index 7ae3523095c..344cafe3dac 100644> +--- a/gcc/config/i386/i386.c> ++++ b/gcc/config/i386/i386.c> +@@ -4209,12 +4209,19 @@ make_pass_stv (gcc::context *ctxt)> + return new pass_stv (ctxt);> + }> + > +-/* Return true if a red-zone is in use. */> ++/* Return true if a red-zone is in use. We can't use red-zone when> ++ there are local indirect jumps, like "indirect_jump" or "tablejump",> ++ which jumps to another place in the function, since "call" in the> ++ indirect thunk pushes the return address onto stack, destroying> ++ red-zone. */> + > + bool> + ix86_using_red_zone (void)> + {> +- return TARGET_RED_ZONE && !TARGET_64BIT_MS_ABI;> ++ return (TARGET_RED_ZONE> ++ && !TARGET_64BIT_MS_ABI> ++ && (!cfun->machine->has_local_indirect_jump> ++ || cfun->machine->indirect_branch_type == indirect_branch_keep));> + }> + > + /* Return a string that documents the current -m options. The caller is> +@@ -28919,11 +28926,16 @@ ix86_output_indirect_branch (rtx call_op, const char *xasm,> + }> + > + const char *> +-ix86_output_indirect_jmp (rtx call_op)> ++ix86_output_indirect_jmp (rtx call_op, bool ret_p)> + {> +- if (ix86_red_zone_size == 0> +- && cfun->machine->indirect_branch_type != indirect_branch_keep)> ++ if (cfun->machine->indirect_branch_type != indirect_branch_keep)> + {> ++ /* We can't have red-zone if this isn't a function return since> ++ "call" in the indirect thunk pushes the return address onto> ++ stack, destroying red-zone. */> ++ if (!ret_p && ix86_red_zone_size != 0)> ++ gcc_unreachable ();> ++> + ix86_output_indirect_branch (call_op, "%0", true);> + return "";> + }> +diff --git a/gcc/config/i386/i386.h b/gcc/config/i386/i386.h> +index f248f3ba2f5..5f30d3f8d19 100644> +--- a/gcc/config/i386/i386.h> ++++ b/gcc/config/i386/i386.h> +@@ -2607,6 +2607,10 @@ struct GTY(()) machine_function {> + /* How to generate indirec branch. */> + ENUM_BITFIELD(indirect_branch) indirect_branch_type : 3;> + > ++ /* If true, the current function has local indirect jumps, like> ++ "indirect_jump" or "tablejump". */> ++ BOOL_BITFIELD has_local_indirect_jump : 1;> ++> + /* How to generate function return. */> + ENUM_BITFIELD(indirect_branch) function_return_type : 3;> + > +diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md> +index 473fa5c089b..ea95aad7540 100644> +--- a/gcc/config/i386/i386.md> ++++ b/gcc/config/i386/i386.md> +@@ -11610,12 +11610,13 @@> + {> + if (TARGET_X32 || ix86_indirect_branch_thunk_register)> + operands[0] = convert_memory_address (word_mode, operands[0]);> ++ cfun->machine->has_local_indirect_jump = true;> + })> + > + (define_insn "*indirect_jump"> + [(set (pc) (match_operand:W 0 "indirect_branch_operand" "rBw"))]> + ""> +- "* return ix86_output_indirect_jmp (operands[0]);"> ++ "* return ix86_output_indirect_jmp (operands[0], false);"> + [(set_attr "type" "ibr")> + (set_attr "length_immediate" "0")> + (set_attr "maybe_prefix_bnd" "1")])> +@@ -11659,13 +11660,14 @@> + > + if (TARGET_X32 || ix86_indirect_branch_thunk_register)> + operands[0] = convert_memory_address (word_mode, operands[0]);> ++ cfun->machine->has_local_indirect_jump = true;> + })> + > + (define_insn "*tablejump_1"> + [(set (pc) (match_operand:W 0 "indirect_branch_operand" "rBw"))> + (use (label_ref (match_operand 1)))]> + ""> +- "* return ix86_output_indirect_jmp (operands[0]);"> ++ "* return ix86_output_indirect_jmp (operands[0], false);"> + [(set_attr "type" "ibr")> + (set_attr "length_immediate" "0")> + (set_attr "maybe_prefix_bnd" "1")])> +@@ -12342,7 +12344,7 @@> + [(simple_return)> + (use (match_operand:SI 0 "register_operand" "r"))]> + "reload_completed"> +- "* return ix86_output_indirect_jmp (operands[0]);"> ++ "* return ix86_output_indirect_jmp (operands[0], true);"> + [(set_attr "type" "ibr")> + (set_attr "length_immediate" "0")> + (set_attr "maybe_prefix_bnd" "1")])> +-- > +2.15.1> +> diff --git a/gnu/packages/patches/gcc-retpoline-Rename-thunks-to-__x86_indirect_thunk_rax-etc.-to-re.patch b/gnu/packages/patches/gcc-retpoline-Rename-thunks-to-__x86_indirect_thunk_rax-etc.-to-re.patch> new file mode 100644> index 000000000..6379270df> --- /dev/null> +++ b/gnu/packages/patches/gcc-retpoline-Rename-thunks-to-__x86_indirect_thunk_rax-etc.-to-re.patch> @@ -0,0 +1,926 @@> +'Retpoline' mitigation technique for Spectre (branch target injection)> +[CVE-2017-5715]:> +> +https://security.googleblog.com/2018/01/more-details-about-mitigations-for-cpu_4.html> +https://support.google.com/faqs/answer/7625886> +https://spectreattack.com/> +https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2017-5715> +> +Patch copied from the 'retpoline-20180107' branch of upstream source repository> +(please add new / update existing patches when new 'retpoline-xxxxxxxx' branch> +appears):> +> +http://git.infradead.org/users/dwmw2/gcc-retpoline.git> +> +From a072725899c551d9f3f06f3595e2a49748ab0187 Mon Sep 17 00:00:00 2001> +From: David Woodhouse <dwmw2@infradead.org>> +Date: Sun, 7 Jan 2018 17:27:09 +0000> +Subject: [PATCH 17/17] Rename thunks to __x86_indirect_thunk_rax etc. to> + remove dots> +> +---> + gcc/config/i386/i386.c | 8 ++++----> + gcc/testsuite/gcc.target/i386/indirect-thunk-1.c | 4 ++--> + gcc/testsuite/gcc.target/i386/indirect-thunk-2.c | 4 ++--> + gcc/testsuite/gcc.target/i386/indirect-thunk-3.c | 4 ++--> + gcc/testsuite/gcc.target/i386/indirect-thunk-4.c | 4 ++--> + gcc/testsuite/gcc.target/i386/indirect-thunk-5.c | 2 +-> + gcc/testsuite/gcc.target/i386/indirect-thunk-6.c | 2 +-> + gcc/testsuite/gcc.target/i386/indirect-thunk-7.c | 4 ++--> + gcc/testsuite/gcc.target/i386/indirect-thunk-attr-1.c | 4 ++--> + gcc/testsuite/gcc.target/i386/indirect-thunk-attr-2.c | 4 ++--> + gcc/testsuite/gcc.target/i386/indirect-thunk-attr-3.c | 2 +-> + gcc/testsuite/gcc.target/i386/indirect-thunk-attr-4.c | 2 +-> + gcc/testsuite/gcc.target/i386/indirect-thunk-attr-5.c | 4 ++--> + gcc/testsuite/gcc.target/i386/indirect-thunk-attr-6.c | 4 ++--> + gcc/testsuite/gcc.target/i386/indirect-thunk-attr-7.c | 4 ++--> + gcc/testsuite/gcc.target/i386/indirect-thunk-attr-8.c | 2 +-> + gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-1.c | 2 +-> + gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-2.c | 2 +-> + gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-3.c | 2 +-> + gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-4.c | 2 +-> + gcc/testsuite/gcc.target/i386/indirect-thunk-extern-1.c | 4 ++--> + gcc/testsuite/gcc.target/i386/indirect-thunk-extern-2.c | 4 ++--> + gcc/testsuite/gcc.target/i386/indirect-thunk-extern-3.c | 4 ++--> + gcc/testsuite/gcc.target/i386/indirect-thunk-extern-4.c | 4 ++--> + gcc/testsuite/gcc.target/i386/indirect-thunk-extern-5.c | 2 +-> + gcc/testsuite/gcc.target/i386/indirect-thunk-extern-6.c | 2 +-> + gcc/testsuite/gcc.target/i386/indirect-thunk-extern-7.c | 4 ++--> + gcc/testsuite/gcc.target/i386/indirect-thunk-inline-1.c | 2 +-> + gcc/testsuite/gcc.target/i386/indirect-thunk-inline-2.c | 2 +-> + gcc/testsuite/gcc.target/i386/indirect-thunk-inline-3.c | 2 +-> + gcc/testsuite/gcc.target/i386/indirect-thunk-inline-4.c | 2 +-> + gcc/testsuite/gcc.target/i386/indirect-thunk-inline-5.c | 2 +-> + gcc/testsuite/gcc.target/i386/indirect-thunk-inline-6.c | 2 +-> + gcc/testsuite/gcc.target/i386/indirect-thunk-inline-7.c | 2 +-> + gcc/testsuite/gcc.target/i386/indirect-thunk-loop-1.c | 4 ++--> + gcc/testsuite/gcc.target/i386/indirect-thunk-loop-2.c | 4 ++--> + gcc/testsuite/gcc.target/i386/indirect-thunk-loop-3.c | 4 ++--> + gcc/testsuite/gcc.target/i386/indirect-thunk-loop-4.c | 2 +-> + gcc/testsuite/gcc.target/i386/indirect-thunk-loop-5.c | 4 ++--> + gcc/testsuite/gcc.target/i386/indirect-thunk-register-1.c | 6 +++---> + gcc/testsuite/gcc.target/i386/indirect-thunk-register-2.c | 2 +-> + gcc/testsuite/gcc.target/i386/indirect-thunk-register-3.c | 2 +-> + gcc/testsuite/gcc.target/i386/ret-thunk-1.c | 2 +-> + gcc/testsuite/gcc.target/i386/ret-thunk-10.c | 10 +++++-----> + gcc/testsuite/gcc.target/i386/ret-thunk-11.c | 10 +++++-----> + gcc/testsuite/gcc.target/i386/ret-thunk-12.c | 10 +++++-----> + gcc/testsuite/gcc.target/i386/ret-thunk-13.c | 6 +++---> + gcc/testsuite/gcc.target/i386/ret-thunk-14.c | 6 +++---> + gcc/testsuite/gcc.target/i386/ret-thunk-15.c | 6 +++---> + gcc/testsuite/gcc.target/i386/ret-thunk-16.c | 4 ++--> + gcc/testsuite/gcc.target/i386/ret-thunk-2.c | 2 +-> + gcc/testsuite/gcc.target/i386/ret-thunk-3.c | 2 +-> + gcc/testsuite/gcc.target/i386/ret-thunk-4.c | 2 +-> + gcc/testsuite/gcc.target/i386/ret-thunk-5.c | 2 +-> + gcc/testsuite/gcc.target/i386/ret-thunk-6.c | 2 +-> + gcc/testsuite/gcc.target/i386/ret-thunk-7.c | 2 +-> + gcc/testsuite/gcc.target/i386/ret-thunk-8.c | 2 +-> + gcc/testsuite/gcc.target/i386/ret-thunk-9.c | 10 +++++-----> + 58 files changed, 105 insertions(+), 105 deletions(-)> +> +diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c> +index 6cb0681233a..9e6c9bdb514 100644> +--- a/gcc/config/i386/i386.c> ++++ b/gcc/config/i386/i386.c> +@@ -12006,13 +12006,13 @@ indirect_thunk_name (char name[32], int regno, bool need_bnd_p,> + reg_prefix = TARGET_64BIT ? "r" : "e";> + else> + reg_prefix = "";> +- sprintf (name, "__x86.indirect_thunk%s.%s%s",> ++ sprintf (name, "__x86_indirect_thunk%s_%s%s",> + bnd, reg_prefix, reg_names[regno]);> + }> + else> + {> + const char *ret = ret_p ? "return" : "indirect";> +- sprintf (name, "__x86.%s_thunk%s", ret, bnd);> ++ sprintf (name, "__x86_%s_thunk%s", ret, bnd);> + }> + }> + else> +@@ -12119,7 +12119,7 @@ output_indirect_thunk_function (bool need_bnd_p, int regno)> + char name[32];> + tree decl;> + > +- /* Create __x86.indirect_thunk/__x86.indirect_thunk_bnd. */> ++ /* Create __x86_indirect_thunk/__x86_indirect_thunk_bnd. */> + indirect_thunk_name (name, regno, need_bnd_p, false);> + decl = build_decl (BUILTINS_LOCATION, FUNCTION_DECL,> + get_identifier (name),> +@@ -12165,7 +12165,7 @@ output_indirect_thunk_function (bool need_bnd_p, int regno)> + > + if (regno < 0)> + {> +- /* Create alias for __x86.return_thunk/__x86.return_thunk_bnd. */> ++ /* Create alias for __x86_return_thunk/__x86_return_thunk_bnd. */> + char alias[32];> + > + indirect_thunk_name (alias, regno, need_bnd_p, true);> +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-1.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-1.c> +index b0625207b92..f4f2b7debe0 100644> +--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-1.c> ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-1.c> +@@ -12,8 +12,8 @@ male_indirect_jump (long offset)> + }> + > + /* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { ! x32 } } } } */> +-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" { target { ! x32 } } } } */> +-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk\.(r|e)ax" { target x32 } } } */> ++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" { target { ! x32 } } } } */> ++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk_(r|e)ax" { target x32 } } } */> + /* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */> + /* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */> + /* { dg-final { scan-assembler {\tlfence} } } */> +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-2.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-2.c> +index 0b289685e6b..d4e5dadd966 100644> +--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-2.c> ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-2.c> +@@ -12,8 +12,8 @@ male_indirect_jump (long offset)> + }> + > + /* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { ! x32 } } } } */> +-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" { target { ! x32 } } } } */> +-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk\.(r|e)ax" { target x32 } } } */> ++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" { target { ! x32 } } } } */> ++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk_(r|e)ax" { target x32 } } } */> + /* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */> + /* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */> + /* { dg-final { scan-assembler {\tlfence} } } */> +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-3.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-3.c> +index 79a9f76285f..9802fae5d04 100644> +--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-3.c> ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-3.c> +@@ -13,8 +13,8 @@ male_indirect_jump (long offset)> + }> + > + /* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { ! x32 } } } } */> +-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" { target { ! x32 } } } } */> +-/* { dg-final { scan-assembler "call\[ \t\]*__x86.indirect_thunk\.(r|e)ax" { target x32 } } } */> ++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" { target { ! x32 } } } } */> ++/* { dg-final { scan-assembler "call\[ \t\]*__x86_indirect_thunk_(r|e)ax" { target x32 } } } */> + /* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */> + /* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */> + /* { dg-final { scan-assembler {\tlfence} } } */> +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-4.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-4.c> +index 901d94213bd..fad3105b50d 100644> +--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-4.c> ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-4.c> +@@ -13,8 +13,8 @@ male_indirect_jump (long offset)> + }> + > + /* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { ! x32 } } } } */> +-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" { target { ! x32 } } } } */> +-/* { dg-final { scan-assembler "call\[ \t\]*__x86.indirect_thunk\.(r|e)ax" { target x32 } } } */> ++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" { target { ! x32 } } } } */> ++/* { dg-final { scan-assembler "call\[ \t\]*__x86_indirect_thunk_(r|e)ax" { target x32 } } } */> + /* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */> + /* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */> + /* { dg-final { scan-assembler {\tlfence} } } */> +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-5.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-5.c> +index d2c9bd9d7ca..e44f2ff5682 100644> +--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-5.c> ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-5.c> +@@ -10,7 +10,7 @@ foo (void)> + }> + > + /* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*bar@GOT" } } */> +-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" } } */> ++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" } } */> + /* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */> + /* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */> + /* { dg-final { scan-assembler {\tlfence} } } */> +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-6.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-6.c> +index f8b028db7a2..f1e03a30854 100644> +--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-6.c> ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-6.c> +@@ -11,7 +11,7 @@ foo (void)> + }> + > + /* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*bar@GOT" } } */> +-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" } } */> ++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" } } */> + /* { dg-final { scan-assembler-times "jmp\[ \t\]*\.LIND" 2 } } */> + /* { dg-final { scan-assembler-times "call\[ \t\]*\.LIND" 2 } } */> + /* { dg-final { scan-assembler {\tlfence} } } */> +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-7.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-7.c> +index 465775407ec..fc91a334459 100644> +--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-7.c> ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-7.c> +@@ -36,8 +36,8 @@ bar (int i)> + }> + > + /* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*\.L\[0-9\]+\\(,%" { target { ! x32 } } } } */> +-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" { target { ! x32 } } } } */> +-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk\.(r|e)ax" { target x32 } } } */> ++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" { target { ! x32 } } } } */> ++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk_(r|e)ax" { target x32 } } } */> + /* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */> + /* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */> + /* { dg-final { scan-assembler {\tlfence} } } */> +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-1.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-1.c> +index 5309d5a3eaa..a8ab95b6451 100644> +--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-1.c> ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-1.c> +@@ -15,8 +15,8 @@ male_indirect_jump (long offset)> + }> + > + /* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { ! x32 } } } } */> +-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" { target { ! x32 } } } } */> +-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk\.(r|e)ax" { target x32 } } } */> ++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" { target { ! x32 } } } } */> ++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk_(r|e)ax" { target x32 } } } */> + /* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */> + /* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */> + /* { dg-final { scan-assembler {\tlfence} } } */> +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-2.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-2.c> +index dd1efca49fd..467d62324d5 100644> +--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-2.c> ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-2.c> +@@ -13,8 +13,8 @@ male_indirect_jump (long offset)> + }> + > + /* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { ! x32 } } } } */> +-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" { target { ! x32 } } } } */> +-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk\.(r|e)ax" { target x32 } } } */> ++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" { target { ! x32 } } } } */> ++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk_(r|e)ax" { target x32 } } } */> + /* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */> + /* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */> + /* { dg-final { scan-assembler {\tlfence} } } */> +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-3.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-3.c> +index e97ca636020..02223f8d0f4 100644> +--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-3.c> ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-3.c> +@@ -17,5 +17,5 @@ male_indirect_jump (long offset)> + /* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { ! x32 } } } } */> + /* { dg-final { scan-assembler-times "jmp\[ \t\]*\.LIND" 2 } } */> + /* { dg-final { scan-assembler-times "call\[ \t\]*\.LIND" 2 } } */> +-/* { dg-final { scan-assembler-not "__x86.indirect_thunk" } } */> ++/* { dg-final { scan-assembler-not "__x86_indirect_thunk" } } */> + /* { dg-final { scan-assembler-not "pushq\[ \t\]%rax" { target x32 } } } */> +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-4.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-4.c> +index b547cbbf255..a80b46af934 100644> +--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-4.c> ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-4.c> +@@ -16,5 +16,5 @@ male_indirect_jump (long offset)> + /* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { ! x32 } } } } */> + /* { dg-final { scan-assembler-times "jmp\[ \t\]*\.LIND" 2 } } */> + /* { dg-final { scan-assembler-times "call\[ \t\]*\.LIND" 2 } } */> +-/* { dg-final { scan-assembler-not "__x86.indirect_thunk" } } */> ++/* { dg-final { scan-assembler-not "__x86_indirect_thunk" } } */> + /* { dg-final { scan-assembler-not "pushq\[ \t\]%rax" { target x32 } } } */> +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-5.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-5.c> +index 353689dc415..4bb1c5f9220 100644> +--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-5.c> ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-5.c> +@@ -17,6 +17,6 @@ male_indirect_jump (long offset)> + /* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { ! x32 } } } } */> + /* { dg-final { scan-assembler-times "jmp\[ \t\]*\.LIND" 1 { target { ! x32 } } } } */> + /* { dg-final { scan-assembler-times "call\[ \t\]*\.LIND" 1 { target { ! x32 } } } } */> +-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" { target { ! x32 } } } } */> +-/* { dg-final { scan-assembler "call\[ \t\]*__x86.indirect_thunk\.(r|e)ax" { target x32 } } } */> ++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" { target { ! x32 } } } } */> ++/* { dg-final { scan-assembler "call\[ \t\]*__x86_indirect_thunk_(r|e)ax" { target x32 } } } */> + /* { dg-final { scan-assembler-not {\t(lfence|pause)} } } */> +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-6.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-6.c> +index 1edef7208f4..4e33a638862 100644> +--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-6.c> ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-6.c> +@@ -16,6 +16,6 @@ male_indirect_jump (long offset)> + /* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { ! x32 } } } } */> + /* { dg-final { scan-assembler-times "jmp\[ \t\]*\.LIND" 1 { target { ! x32 } } } } */> + /* { dg-final { scan-assembler-times "call\[ \t\]*\.LIND" 1 { target { ! x32 } } } } */> +-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" { target { ! x32 } } } } */> +-/* { dg-final { scan-assembler "call\[ \t\]*__x86.indirect_thunk\.(r|e)ax" { target x32 } } } */> ++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" { target { ! x32 } } } } */> ++/* { dg-final { scan-assembler "call\[ \t\]*__x86_indirect_thunk_(r|e)ax" { target x32 } } } */> + /* { dg-final { scan-assembler-not {\t(lfence|pause)} } } */> +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-7.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-7.c> +index c2e816cdfc6..427ba3ddbb4 100644> +--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-7.c> ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-7.c> +@@ -37,8 +37,8 @@ bar (int i)> + }> + > + /* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*\.L\[0-9\]+\\(,%" { target { ! x32 } } } } */> +-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk\.(r|e)ax" { target x32 } } } */> +-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" } } */> ++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk_(r|e)ax" { target x32 } } } */> ++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" } } */> + /* { dg-final { scan-assembler-not {\t(lfence|pause)} } } */> + /* { dg-final { scan-assembler-not "jmp\[ \t\]*\.LIND" } } */> + /* { dg-final { scan-assembler-not "call\[ \t\]*\.LIND" } } */> +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-8.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-8.c> +index af1bb125a22..c246f974610 100644> +--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-8.c> ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-8.c> +@@ -36,6 +36,6 @@ bar (int i)> + }> + }> + > +-/* { dg-final { scan-assembler-not "__x86.indirect_thunk" } } */> ++/* { dg-final { scan-assembler-not "__x86_indirect_thunk" } } */> + /* { dg-final { scan-assembler-not "jmp\[ \t\]*\.LIND" } } */> + /* { dg-final { scan-assembler-not "call\[ \t\]*\.LIND" } } */> +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-1.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-1.c> +index 5c10de47b7c..3399ad56a7f 100644> +--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-1.c> ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-1.c> +@@ -12,7 +12,7 @@ foo (void)> + > + /* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { ! x32 } } } } */> + /* { dg-final { scan-assembler "pushq\[ \t\]%rax" { target x32 } } } */> +-/* { dg-final { scan-assembler "bnd jmp\[ \t\]*__x86.indirect_thunk_bnd" } } */> ++/* { dg-final { scan-assembler "bnd jmp\[ \t\]*__x86_indirect_thunk_bnd" } } */> + /* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */> + /* { dg-final { scan-assembler "bnd call\[ \t\]*\.LIND" } } */> + /* { dg-final { scan-assembler "bnd ret" } } */> +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-2.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-2.c> +index 9eedd9a5a82..daa9528f7bd 100644> +--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-2.c> ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-2.c> +@@ -13,7 +13,7 @@ foo (void)> + > + /* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { ! x32 } } } } */> + /* { dg-final { scan-assembler "pushq\[ \t\]%rax" { target x32 } } } */> +-/* { dg-final { scan-assembler "bnd jmp\[ \t\]*__x86.indirect_thunk_bnd" } } */> ++/* { dg-final { scan-assembler "bnd jmp\[ \t\]*__x86_indirect_thunk_bnd" } } */> + /* { dg-final { scan-assembler "bnd jmp\[ \t\]*\.LIND" } } */> + /* { dg-final { scan-assembler "bnd call\[ \t\]*\.LIND" } } */> + /* { dg-final { scan-assembler "bnd ret" } } */> +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-3.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-3.c> +index b2b8587eac7..647ec5a4ade 100644> +--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-3.c> ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-3.c> +@@ -11,7 +11,7 @@ foo (void)> + }> + > + /* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*bar@GOT" } } */> +-/* { dg-final { scan-assembler "bnd jmp\[ \t\]*__x86.indirect_thunk_bnd" } } */> ++/* { dg-final { scan-assembler "bnd jmp\[ \t\]*__x86_indirect_thunk_bnd" } } */> + /* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */> + /* { dg-final { scan-assembler "bnd call\[ \t\]*\.LIND" } } */> + /* { dg-final { scan-assembler "bnd ret" } } */> +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-4.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-4.c> +index 9459a2417f4..3a7a1cea8bc 100644> +--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-4.c> ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-4.c> +@@ -12,7 +12,7 @@ foo (void)> + }> + > + /* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*bar@GOT" } } */> +-/* { dg-final { scan-assembler "bnd jmp\[ \t\]*__x86.indirect_thunk" } } */> ++/* { dg-final { scan-assembler "bnd jmp\[ \t\]*__x86_indirect_thunk" } } */> + /* { dg-final { scan-assembler "bnd jmp\[ \t\]*\.LIND" } } */> + /* { dg-final { scan-assembler-times "bnd call\[ \t\]*\.LIND" 2 } } */> + /* { dg-final { scan-assembler "bnd ret" } } */> +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-1.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-1.c> +index b0aa3811e65..5c20a35ecec 100644> +--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-1.c> ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-1.c> +@@ -12,8 +12,8 @@ male_indirect_jump (long offset)> + }> + > + /* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { ! x32 } } } } */> +-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" { target { ! x32 } } } } */> +-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk\.(r|e)ax" { target x32 } } } */> ++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" { target { ! x32 } } } } */> ++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk_(r|e)ax" { target x32 } } } */> + /* { dg-final { scan-assembler-not {\t(lfence|pause)} } } */> + /* { dg-final { scan-assembler-not "jmp\[ \t\]*\.LIND" } } */> + /* { dg-final { scan-assembler-not "call\[ \t\]*\.LIND" } } */> +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-2.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-2.c> +index 75fabcd988c..b2fb6e1bcd2 100644> +--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-2.c> ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-2.c> +@@ -12,8 +12,8 @@ male_indirect_jump (long offset)> + }> + > + /* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { ! x32 } } } } */> +-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" { target { ! x32 } } } } */> +-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk\.(r|e)ax" { target x32 } } } */> ++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" { target { ! x32 } } } } */> ++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk_(r|e)ax" { target x32 } } } */> + /* { dg-final { scan-assembler-not {\t(lfence|pause)} } } */> + /* { dg-final { scan-assembler-not "jmp\[ \t\]*\.LIND" } } */> + /* { dg-final { scan-assembler-not "call\[ \t\]*\.LIND" } } */> +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-3.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-3.c> +index 1d9dff2e834..9c84547cd7c 100644> +--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-3.c> ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-3.c> +@@ -13,8 +13,8 @@ male_indirect_jump (long offset)> + }> + > + /* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { ! x32 } } } } */> +-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" { target { ! x32 } } } } */> ++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" { target { ! x32 } } } } */> + /* { dg-final { scan-assembler-times "jmp\[ \t\]*\.LIND" 1 { target { ! x32 } } } } */> + /* { dg-final { scan-assembler-times "call\[ \t\]*\.LIND" 1 { target { ! x32 } } } } */> +-/* { dg-final { scan-assembler "call\[ \t\]*__x86.indirect_thunk\.(r|e)ax" { target x32 } } } */> ++/* { dg-final { scan-assembler "call\[ \t\]*__x86_indirect_thunk_(r|e)ax" { target x32 } } } */> + /* { dg-final { scan-assembler-not {\t(lfence|pause)} } } */> +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-4.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-4.c> +index 5b464155e38..457849564bb 100644> +--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-4.c> ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-4.c> +@@ -13,8 +13,8 @@ male_indirect_jump (long offset)> + }> + > + /* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { ! x32 } } } } */> +-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" { target { ! x32 } } } } */> ++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" { target { ! x32 } } } } */> + /* { dg-final { scan-assembler-times "jmp\[ \t\]*\.LIND" 1 { target { ! x32 } } } } */> + /* { dg-final { scan-assembler-times "call\[ \t\]*\.LIND" 1 { target { ! x32 } } } } */> +-/* { dg-final { scan-assembler "call\[ \t\]*__x86.indirect_thunk\.(r|e)ax" { target x32 } } } */> ++/* { dg-final { scan-assembler "call\[ \t\]*__x86_indirect_thunk_(r|e)ax" { target x32 } } } */> + /* { dg-final { scan-assembler-not {\t(lfence|pause)} } } */> +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-5.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-5.c> +index 55ce91c73ec..5c07e02df6a 100644> +--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-5.c> ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-5.c> +@@ -10,7 +10,7 @@ foo (void)> + }> + > + /* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*bar@GOT" } } */> +-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" } } */> ++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" } } */> + /* { dg-final { scan-assembler-not {\t(lfence|pause)} } } */> + /* { dg-final { scan-assembler-not "jmp\[ \t\]*\.LIND" } } */> + /* { dg-final { scan-assembler-not "call\[ \t\]*\.LIND" } } */> +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-6.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-6.c> +index 06180e7bee9..3eb440693a0 100644> +--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-6.c> ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-6.c> +@@ -13,5 +13,5 @@ foo (void)> + /* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*bar@GOT" } } */> + /* { dg-final { scan-assembler-times "jmp\[ \t\]*\.LIND" 1 } } */> + /* { dg-final { scan-assembler-times "call\[ \t\]*\.LIND" 1 } } */> +-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" } } */> ++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" } } */> + /* { dg-final { scan-assembler-not {\t(lfence|pause)} } } */> +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-7.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-7.c> +index 790a05cec3e..d4747ea0764 100644> +--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-7.c> ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-7.c> +@@ -36,8 +36,8 @@ bar (int i)> + }> + > + /* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*\.L\[0-9\]+\\(,%" { target { ! x32 } } } } */> +-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" { target { ! x32 } } } } */> +-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk\.(r|e)ax" { target x32 } } } */> ++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" { target { ! x32 } } } } */> ++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk_(r|e)ax" { target x32 } } } */> + /* { dg-final { scan-assembler-not {\t(lfence|pause)} } } */> + /* { dg-final { scan-assembler-not "jmp\[ \t\]*\.LIND" } } */> + /* { dg-final { scan-assembler-not "call\[ \t\]*\.LIND" } } */> +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-1.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-1.c> +index 1ce8ca5aff1..f7fad345ca4 100644> +--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-1.c> ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-1.c> +@@ -14,5 +14,5 @@ male_indirect_jump (long offset)> + /* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { ! x32 } } } } */> + /* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */> + /* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */> +-/* { dg-final { scan-assembler-not "__x86.indirect_thunk" } } */> ++/* { dg-final { scan-assembler-not "__x86_indirect_thunk" } } */> + /* { dg-final { scan-assembler-not "pushq\[ \t\]%rax" { target x32 } } } */> +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-2.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-2.c> +index f6b71e868bd..91388544a20 100644> +--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-2.c> ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-2.c> +@@ -14,5 +14,5 @@ male_indirect_jump (long offset)> + /* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { ! x32 } } } } */> + /* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */> + /* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */> +-/* { dg-final { scan-assembler-not "__x86.indirect_thunk" } } */> ++/* { dg-final { scan-assembler-not "__x86_indirect_thunk" } } */> + /* { dg-final { scan-assembler-not "pushq\[ \t\]%rax" { target x32 } } } */> +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-3.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-3.c> +index 84a09d4d0d6..69f03e6472e 100644> +--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-3.c> ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-3.c> +@@ -15,5 +15,5 @@ male_indirect_jump (long offset)> + /* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { ! x32 } } } } */> + /* { dg-final { scan-assembler-times "jmp\[ \t\]*\.LIND" 2 } } */> + /* { dg-final { scan-assembler-times "call\[ \t\]*\.LIND" 2 } } */> +-/* { dg-final { scan-assembler-not "__x86.indirect_thunk" } } */> ++/* { dg-final { scan-assembler-not "__x86_indirect_thunk" } } */> + /* { dg-final { scan-assembler-not "pushq\[ \t\]%rax" { target x32 } } } */> +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-4.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-4.c> +index cfe3aefa0bf..226b776abcf 100644> +--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-4.c> ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-4.c> +@@ -15,5 +15,5 @@ male_indirect_jump (long offset)> + /* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { ! x32 } } } } */> + /* { dg-final { scan-assembler-times "jmp\[ \t\]*\.LIND" 2 } } */> + /* { dg-final { scan-assembler-times "call\[ \t\]*\.LIND" 2 } } */> +-/* { dg-final { scan-assembler-not "__x86.indirect_thunk" } } */> ++/* { dg-final { scan-assembler-not "__x86_indirect_thunk" } } */> + /* { dg-final { scan-assembler-not "pushq\[ \t\]%rax" { target x32 } } } */> +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-5.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-5.c> +index 6411454243f..b9120017c10 100644> +--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-5.c> ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-5.c> +@@ -12,4 +12,4 @@ foo (void)> + /* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*bar@GOT" } } */> + /* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */> + /* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */> +-/* { dg-final { scan-assembler-not "__x86.indirect_thunk" } } */> ++/* { dg-final { scan-assembler-not "__x86_indirect_thunk" } } */> +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-6.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-6.c> +index d4297fe21c4..fbd6f9ec457 100644> +--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-6.c> ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-6.c> +@@ -13,4 +13,4 @@ foo (void)> + /* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*bar@GOT" } } */> + /* { dg-final { scan-assembler-times "jmp\[ \t\]*\.LIND" 2 } } */> + /* { dg-final { scan-assembler-times "call\[ \t\]*\.LIND" 2 } } */> +-/* { dg-final { scan-assembler-not "__x86.indirect_thunk" } } */> ++/* { dg-final { scan-assembler-not "__x86_indirect_thunk" } } */> +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-7.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-7.c> +index eb318efdf4d..2553c56f97f 100644> +--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-7.c> ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-7.c> +@@ -39,4 +39,4 @@ bar (int i)> + /* { dg-final { scan-assembler-not "pushq\[ \t\]%rax" { target x32 } } } */> + /* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */> + /* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */> +-/* { dg-final { scan-assembler-not "__x86.indirect_thunk" } } */> ++/* { dg-final { scan-assembler-not "__x86_indirect_thunk" } } */> +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-loop-1.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-loop-1.c> +index 605e32bb584..c266ca6f2da 100644> +--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-loop-1.c> ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-loop-1.c> +@@ -12,8 +12,8 @@ male_indirect_jump (long offset)> + }> + > + /* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { ! x32 } } } } */> +-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" { target { ! x32 } } } } */> +-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk\.(r|e)ax" { target x32 } } } */> ++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" { target { ! x32 } } } } */> ++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk_(r|e)ax" { target x32 } } } */> + /* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */> + /* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */> + /* { dg-final { scan-assembler {\tpause} } } */> +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-loop-2.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-loop-2.c> +index dd7a7b60621..f7c1cf6c45a 100644> +--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-loop-2.c> ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-loop-2.c> +@@ -12,8 +12,8 @@ male_indirect_jump (long offset)> + }> + > + /* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { ! x32 } } } } */> +-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" { target { ! x32 } } } } */> +-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk\.(r|e)ax" { target x32 } } } */> ++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" { target { ! x32 } } } } */> ++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk_(r|e)ax" { target x32 } } } */> + /* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */> + /* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */> + /* { dg-final { scan-assembler {\tnop} } } */> +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-loop-3.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-loop-3.c> +index 338f22c373c..ef5c4b84312 100644> +--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-loop-3.c> ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-loop-3.c> +@@ -12,8 +12,8 @@ male_indirect_jump (long offset)> + }> + > + /* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { ! x32 } } } } */> +-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" { target { ! x32 } } } } */> +-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk\.(r|e)ax" { target x32 } } } */> ++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" { target { ! x32 } } } } */> ++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk_(r|e)ax" { target x32 } } } */> + /* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */> + /* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */> + /* { dg-final { scan-assembler {\tlfence} } } */> +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-loop-4.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-loop-4.c> +index 3b083ee30a8..941fcdaffb1 100644> +--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-loop-4.c> ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-loop-4.c> +@@ -15,5 +15,5 @@ male_indirect_jump (long offset)> + /* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */> + /* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */> + /* { dg-final { scan-assembler {\tpause} } } */> +-/* { dg-final { scan-assembler-not "__x86.indirect_thunk" } } */> ++/* { dg-final { scan-assembler-not "__x86_indirect_thunk" } } */> + /* { dg-final { scan-assembler-not "pushq\[ \t\]%rax" { target x32 } } } */> +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-loop-5.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-loop-5.c> +index 31a9a81a911..0c5ace58358 100644> +--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-loop-5.c> ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-loop-5.c> +@@ -12,8 +12,8 @@ male_indirect_jump (long offset)> + }> + > + /* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { ! x32 } } } } */> +-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" { target { ! x32 } } } } */> +-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk\.(r|e)ax" { target x32 } } } */> ++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" { target { ! x32 } } } } */> ++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk_(r|e)ax" { target x32 } } } */> + /* { dg-final { scan-assembler-not {\t(lfence|pause|nop)} } } */> + /* { dg-final { scan-assembler-not "jmp\[ \t\]*\.LIND" } } */> + /* { dg-final { scan-assembler-not "call\[ \t\]*\.LIND" } } */> +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-register-1.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-register-1.c> +index ef493a05bbf..1a28abb4604 100644> +--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-register-1.c> ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-register-1.c> +@@ -11,12 +11,12 @@ male_indirect_jump (long offset)> + dispatch(offset);> + }> + > +-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk\.(r|e)ax" } } */> ++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk_(r|e)ax" } } */> + /* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */> + /* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */> + /* { dg-final { scan-assembler "mov\[ \t\](%eax|%rax), \\((%esp|%rsp)\\)" } } */> + /* { dg-final { scan-assembler {\tlfence} } } */> + /* { dg-final { scan-assembler-not "push(?:l|q)\[ \t\]*_?dispatch" } } */> + /* { dg-final { scan-assembler-not "pushq\[ \t\]%rax" } } */> +-/* { dg-final { scan-assembler-not "__x86.indirect_thunk\n" } } */> +-/* { dg-final { scan-assembler-not "__x86.indirect_thunk_bnd\n" } } */> ++/* { dg-final { scan-assembler-not "__x86_indirect_thunk_" } } */> ++/* { dg-final { scan-assembler-not "__x86_indirect_thunk_bnd\n" } } */> +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-register-2.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-register-2.c> +index 89fc8e6e6c4..428d6f9e986 100644> +--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-register-2.c> ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-register-2.c> +@@ -17,4 +17,4 @@ male_indirect_jump (long offset)> + /* { dg-final { scan-assembler {\tlfence} } } */> + /* { dg-final { scan-assembler-not "push(?:l|q)\[ \t\]*_?dispatch" } } */> + /* { dg-final { scan-assembler-not "pushq\[ \t\]%rax" } } */> +-/* { dg-final { scan-assembler-not "__x86.indirect_thunk" } } */> ++/* { dg-final { scan-assembler-not "__x86_indirect_thunk" } } */> +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-register-3.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-register-3.c> +index 31af7ac05b8..28dcdcf2855 100644> +--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-register-3.c> ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-register-3.c> +@@ -11,7 +11,7 @@ male_indirect_jump (long offset)> + dispatch(offset);> + }> + > +-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk\.(r|e)ax" } } */> ++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk_(r|e)ax" } } */> + /* { dg-final { scan-assembler-not "push(?:l|q)\[ \t\]*_?dispatch" } } */> + /* { dg-final { scan-assembler-not "pushq\[ \t\]%rax" } } */> + /* { dg-final { scan-assembler-not {\t(lfence|pause|nop)} } } */> +diff --git a/gcc/testsuite/gcc.target/i386/ret-thunk-1.c b/gcc/testsuite/gcc.target/i386/ret-thunk-1.c> +index 406956f48e5..07f382c21b2 100644> +--- a/gcc/testsuite/gcc.target/i386/ret-thunk-1.c> ++++ b/gcc/testsuite/gcc.target/i386/ret-thunk-1.c> +@@ -6,7 +6,7 @@ foo (void)> + {> + }> + > +-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.return_thunk" } } */> ++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_return_thunk" } } */> + /* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */> + /* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */> + /* { dg-final { scan-assembler {\tlfence} } } */> +diff --git a/gcc/testsuite/gcc.target/i386/ret-thunk-10.c b/gcc/testsuite/gcc.target/i386/ret-thunk-10.c> +index 74f37ee9a62..da8029bad49 100644> +--- a/gcc/testsuite/gcc.target/i386/ret-thunk-10.c> ++++ b/gcc/testsuite/gcc.target/i386/ret-thunk-10.c> +@@ -12,11 +12,11 @@ foo (void)> + > + /* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */> + /* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */> +-/* { dg-final { scan-assembler-not "jmp\[ \t\]*__x86.return_thunk" } } */> ++/* { dg-final { scan-assembler-not "jmp\[ \t\]*__x86_return_thunk" } } */> + /* { dg-final { scan-assembler-times {\tlfence} 2 } } */> + /* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?bar" { target { ! x32 } } } } */> +-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" { target { ! x32 } } } } */> +-/* { dg-final { scan-assembler "__x86.indirect_thunk:" { target { ! x32 } } } } */> +-/* { dg-final { scan-assembler "call\[ \t\]*__x86.indirect_thunk\.(r|e)ax" { target { x32 } } } } */> +-/* { dg-final { scan-assembler "__x86.indirect_thunk\.(r|e)ax:" { target { x32 } } } } */> ++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" { target { ! x32 } } } } */> ++/* { dg-final { scan-assembler "__x86_indirect_thunk:" { target { ! x32 } } } } */> ++/* { dg-final { scan-assembler "call\[ \t\]*__x86_indirect_thunk_(r|e)ax" { target { x32 } } } } */> ++/* { dg-final { scan-assembler "__x86_indirect_thunk_(r|e)ax:" { target { x32 } } } } */> + /* { dg-final { scan-assembler-not "pushq\[ \t\]%rax" { target x32 } } } */> +diff --git a/gcc/testsuite/gcc.target/i386/ret-thunk-11.c b/gcc/testsuite/gcc.target/i386/ret-thunk-11.c> +index 0a52318e86b..6964997871d 100644> +--- a/gcc/testsuite/gcc.target/i386/ret-thunk-11.c> ++++ b/gcc/testsuite/gcc.target/i386/ret-thunk-11.c> +@@ -10,13 +10,13 @@ foo (void)> + return 0;> + }> + > +-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.return_thunk" } } */> ++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_return_thunk" } } */> + /* { dg-final { scan-assembler-times {\tlfence} 1 } } */> + /* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */> + /* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */> + /* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?bar" { target { ! x32 } } } } */> +-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" { target { ! x32 } } } } */> +-/* { dg-final { scan-assembler "__x86.indirect_thunk:" { target { ! x32 } } } } */> +-/* { dg-final { scan-assembler "call\[ \t\]*__x86.indirect_thunk\.(r|e)ax" { target { x32 } } } } */> +-/* { dg-final { scan-assembler "__x86.indirect_thunk\.(r|e)ax:" { target { x32 } } } } */> ++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" { target { ! x32 } } } } */> ++/* { dg-final { scan-assembler "__x86_indirect_thunk:" { target { ! x32 } } } } */> ++/* { dg-final { scan-assembler "call\[ \t\]*__x86_indirect_thunk_(r|e)ax" { target { x32 } } } } */> ++/* { dg-final { scan-assembler "__x86_indirect_thunk_(r|e)ax:" { target { x32 } } } } */> + /* { dg-final { scan-assembler-not "pushq\[ \t\]%rax" { target x32 } } } */> +diff --git a/gcc/testsuite/gcc.target/i386/ret-thunk-12.c b/gcc/testsuite/gcc.target/i386/ret-thunk-12.c> +index d2f775490ea..ff0234bd17d 100644> +--- a/gcc/testsuite/gcc.target/i386/ret-thunk-12.c> ++++ b/gcc/testsuite/gcc.target/i386/ret-thunk-12.c> +@@ -10,12 +10,12 @@ foo (void)> + return 0;> + }> + > +-/* { dg-final { scan-assembler-not "jmp\[ \t\]*__x86.return_thunk" } } */> ++/* { dg-final { scan-assembler-not "jmp\[ \t\]*__x86_return_thunk" } } */> + /* { dg-final { scan-assembler-times {\tlfence} 1 } } */> + /* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */> + /* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */> +-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" { target { ! x32 } } } } */> +-/* { dg-final { scan-assembler "__x86.indirect_thunk:" { target { ! x32 } } } } */> +-/* { dg-final { scan-assembler "call\[ \t\]*__x86.indirect_thunk\.(r|e)ax" { target { x32 } } } } */> +-/* { dg-final { scan-assembler "__x86.indirect_thunk\.(r|e)ax:" { target { x32 } } } } */> ++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" { target { ! x32 } } } } */> ++/* { dg-final { scan-assembler "__x86_indirect_thunk:" { target { ! x32 } } } } */> ++/* { dg-final { scan-assembler "call\[ \t\]*__x86_indirect_thunk_(r|e)ax" { target { x32 } } } } */> ++/* { dg-final { scan-assembler "__x86_indirect_thunk_(r|e)ax:" { target { x32 } } } } */> + /* { dg-final { scan-assembler-not "pushq\[ \t\]%rax" { target x32 } } } */> +diff --git a/gcc/testsuite/gcc.target/i386/ret-thunk-13.c b/gcc/testsuite/gcc.target/i386/ret-thunk-13.c> +index 82d46165f3e..a5b16472051 100644> +--- a/gcc/testsuite/gcc.target/i386/ret-thunk-13.c> ++++ b/gcc/testsuite/gcc.target/i386/ret-thunk-13.c> +@@ -11,11 +11,11 @@ foo (void)> + return 0;> + }> + > +-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.return_thunk" } } */> ++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_return_thunk" } } */> + /* { dg-final { scan-assembler-times {\tlfence} 2 } } */> + /* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?bar" { target { ! x32 } } } } */> + /* { dg-final { scan-assembler-times "jmp\[ \t\]*\.LIND" 3 } } */> + /* { dg-final { scan-assembler-times "call\[ \t\]*\.LIND" 3 } } */> +-/* { dg-final { scan-assembler-not "jmp\[ \t\]*__x86.indirect_thunk" } } */> +-/* { dg-final { scan-assembler-not "call\[ \t\]*__x86.indirect_thunk\.(r|e)ax" { target { x32 } } } } */> ++/* { dg-final { scan-assembler-not "jmp\[ \t\]*__x86_indirect_thunk" } } */> ++/* { dg-final { scan-assembler-not "call\[ \t\]*__x86_indirect_thunk_(r|e)ax" { target { x32 } } } } */> + /* { dg-final { scan-assembler-not "pushq\[ \t\]%rax" { target x32 } } } */> +diff --git a/gcc/testsuite/gcc.target/i386/ret-thunk-14.c b/gcc/testsuite/gcc.target/i386/ret-thunk-14.c> +index 6711eb27fa8..219d71548bf 100644> +--- a/gcc/testsuite/gcc.target/i386/ret-thunk-14.c> ++++ b/gcc/testsuite/gcc.target/i386/ret-thunk-14.c> +@@ -12,10 +12,10 @@ foo (void)> + }> + > + /* { dg-final { scan-assembler-times {\tlfence} 1 } } */> +-/* { dg-final { scan-assembler-not "jmp\[ \t\]*__x86.return_thunk" } } */> ++/* { dg-final { scan-assembler-not "jmp\[ \t\]*__x86_return_thunk" } } */> + /* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */> + /* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */> + /* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?bar" { target { ! x32 } } } } */> +-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" { target { ! x32 } } } } */> +-/* { dg-final { scan-assembler "call\[ \t\]*__x86.indirect_thunk\.(r|e)ax" { target { x32 } } } } */> ++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" { target { ! x32 } } } } */> ++/* { dg-final { scan-assembler "call\[ \t\]*__x86_indirect_thunk_(r|e)ax" { target { x32 } } } } */> + /* { dg-final { scan-assembler-not "pushq\[ \t\]%rax" { target x32 } } } */> +diff --git a/gcc/testsuite/gcc.target/i386/ret-thunk-15.c b/gcc/testsuite/gcc.target/i386/ret-thunk-15.c> +index 37758c33371..bad6b16820d 100644> +--- a/gcc/testsuite/gcc.target/i386/ret-thunk-15.c> ++++ b/gcc/testsuite/gcc.target/i386/ret-thunk-15.c> +@@ -11,11 +11,11 @@ foo (void)> + return 0;> + }> + > +-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.return_thunk" } } */> ++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_return_thunk" } } */> + /* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */> + /* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */> + /* { dg-final { scan-assembler-times {\tlfence} 1 } } */> + /* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?bar" { target { ! x32 } } } } */> +-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" { target { ! x32 } } } } */> +-/* { dg-final { scan-assembler "call\[ \t\]*__x86.indirect_thunk\.(r|e)ax" { target x32 } } } */> ++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" { target { ! x32 } } } } */> ++/* { dg-final { scan-assembler "call\[ \t\]*__x86_indirect_thunk_(r|e)ax" { target x32 } } } */> + /* { dg-final { scan-assembler-not "pushq\[ \t\]%rax" { target x32 } } } */> +diff --git a/gcc/testsuite/gcc.target/i386/ret-thunk-16.c b/gcc/testsuite/gcc.target/i386/ret-thunk-16.c> +index cf3920563e0..173fe243d7b 100644> +--- a/gcc/testsuite/gcc.target/i386/ret-thunk-16.c> ++++ b/gcc/testsuite/gcc.target/i386/ret-thunk-16.c> +@@ -11,8 +11,8 @@ foo (void)> + return 0;> + }> + > +-/* { dg-final { scan-assembler-not "__x86.indirect_thunk" } } */> +-/* { dg-final { scan-assembler-not "__x86.return_thunk" } } */> ++/* { dg-final { scan-assembler-not "__x86_indirect_thunk" } } */> ++/* { dg-final { scan-assembler-not "__x86_return_thunk" } } */> + /* { dg-final { scan-assembler-not {\tlfence} } } */> + /* { dg-final { scan-assembler-not "jmp\[ \t\]*\.LIND" } } */> + /* { dg-final { scan-assembler-not "call\[ \t\]*\.LIND" } } */> +diff --git a/gcc/testsuite/gcc.target/i386/ret-thunk-2.c b/gcc/testsuite/gcc.target/i386/ret-thunk-2.c> +index 190947cc2ca..5516813a290 100644> +--- a/gcc/testsuite/gcc.target/i386/ret-thunk-2.c> ++++ b/gcc/testsuite/gcc.target/i386/ret-thunk-2.c> +@@ -9,4 +9,4 @@ foo (void)> + /* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */> + /* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */> + /* { dg-final { scan-assembler {\tlfence} } } */> +-/* { dg-final { scan-assembler-not "jmp\[ \t\]*__x86.return_thunk" } } */> ++/* { dg-final { scan-assembler-not "jmp\[ \t\]*__x86_return_thunk" } } */> +diff --git a/gcc/testsuite/gcc.target/i386/ret-thunk-3.c b/gcc/testsuite/gcc.target/i386/ret-thunk-3.c> +index d71de3ac520..9f1ade857ef 100644> +--- a/gcc/testsuite/gcc.target/i386/ret-thunk-3.c> ++++ b/gcc/testsuite/gcc.target/i386/ret-thunk-3.c> +@@ -6,7 +6,7 @@ foo (void)> + {> + }> + > +-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.return_thunk" } } */> ++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_return_thunk" } } */> + /* { dg-final { scan-assembler-not {\tlfence} } } */> + /* { dg-final { scan-assembler-not "jmp\[ \t\]*\.LIND" } } */> + /* { dg-final { scan-assembler-not "call\[ \t\]*\.LIND" } } */> +diff --git a/gcc/testsuite/gcc.target/i386/ret-thunk-4.c b/gcc/testsuite/gcc.target/i386/ret-thunk-4.c> +index 68c22122f0d..abecde0a550 100644> +--- a/gcc/testsuite/gcc.target/i386/ret-thunk-4.c> ++++ b/gcc/testsuite/gcc.target/i386/ret-thunk-4.c> +@@ -6,7 +6,7 @@ foo (void)> + {> + }> + > +-/* { dg-final { scan-assembler-not "jmp\[ \t\]*__x86.return_thunk" } } */> ++/* { dg-final { scan-assembler-not "jmp\[ \t\]*__x86_return_thunk" } } */> + /* { dg-final { scan-assembler-not {\tlfence} } } */> + /* { dg-final { scan-assembler-not "jmp\[ \t\]*\.LIND" } } */> + /* { dg-final { scan-assembler-not "call\[ \t\]*\.LIND" } } */> +diff --git a/gcc/testsuite/gcc.target/i386/ret-thunk-5.c b/gcc/testsuite/gcc.target/i386/ret-thunk-5.c> +index 28c576e2267..3b51a9931db 100644> +--- a/gcc/testsuite/gcc.target/i386/ret-thunk-5.c> ++++ b/gcc/testsuite/gcc.target/i386/ret-thunk-5.c> +@@ -8,7 +8,7 @@ foo (void)> + {> + }> + > +-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.return_thunk" } } */> ++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_return_thunk" } } */> + /* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */> + /* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */> + /* { dg-final { scan-assembler {\tlfence} } } */> +diff --git a/gcc/testsuite/gcc.target/i386/ret-thunk-6.c b/gcc/testsuite/gcc.target/i386/ret-thunk-6.c> +index 10ad40b9c26..52160e0ee77 100644> +--- a/gcc/testsuite/gcc.target/i386/ret-thunk-6.c> ++++ b/gcc/testsuite/gcc.target/i386/ret-thunk-6.c> +@@ -10,4 +10,4 @@ foo (void)> + /* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */> + /* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */> + /* { dg-final { scan-assembler {\tlfence} } } */> +-/* { dg-final { scan-assembler-not "jmp\[ \t\]*__x86.return_thunk" } } */> ++/* { dg-final { scan-assembler-not "jmp\[ \t\]*__x86_return_thunk" } } */> +diff --git a/gcc/testsuite/gcc.target/i386/ret-thunk-7.c b/gcc/testsuite/gcc.target/i386/ret-thunk-7.c> +index 7ac0beaa73e..65819c2ab76 100644> +--- a/gcc/testsuite/gcc.target/i386/ret-thunk-7.c> ++++ b/gcc/testsuite/gcc.target/i386/ret-thunk-7.c> +@@ -7,7 +7,7 @@ foo (void)> + {> + }> + > +-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.return_thunk" } } */> ++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_return_thunk" } } */> + /* { dg-final { scan-assembler-not {\tlfence} } } */> + /* { dg-final { scan-assembler-not "jmp\[ \t\]*\.LIND" } } */> + /* { dg-final { scan-assembler-not "call\[ \t\]*\.LIND" } } */> +diff --git a/gcc/testsuite/gcc.target/i386/ret-thunk-8.c b/gcc/testsuite/gcc.target/i386/ret-thunk-8.c> +index 777ab7c8088..a6a1bbc054b 100644> +--- a/gcc/testsuite/gcc.target/i386/ret-thunk-8.c> ++++ b/gcc/testsuite/gcc.target/i386/ret-thunk-8.c> +@@ -8,7 +8,7 @@ foo (void)> + {> + }> + > +-/* { dg-final { scan-assembler-not "jmp\[ \t\]*__x86.return_thunk" } } */> ++/* { dg-final { scan-assembler-not "jmp\[ \t\]*__x86_return_thunk" } } */> + /* { dg-final { scan-assembler-not {\tlfence} } } */> + /* { dg-final { scan-assembler-not "jmp\[ \t\]*\.LIND" } } */> + /* { dg-final { scan-assembler-not "call\[ \t\]*\.LIND" } } */> +diff --git a/gcc/testsuite/gcc.target/i386/ret-thunk-9.c b/gcc/testsuite/gcc.target/i386/ret-thunk-9.c> +index 70771ea35d7..21a0e6bde3d 100644> +--- a/gcc/testsuite/gcc.target/i386/ret-thunk-9.c> ++++ b/gcc/testsuite/gcc.target/i386/ret-thunk-9.c> +@@ -10,14 +10,14 @@ foo (void)> + return 0;> + }> + > +-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.return_thunk" } } */> +-/* { dg-final { scan-assembler-not "__x86.return_thunk:" } } */> ++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_return_thunk" } } */> ++/* { dg-final { scan-assembler-not "__x86_return_thunk:" } } */> + /* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */> + /* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */> +-/* { dg-final { scan-assembler "__x86.indirect_thunk:" } } */> ++/* { dg-final { scan-assembler "__x86_indirect_thunk:" } } */> + /* { dg-final { scan-assembler-times {\tlfence} 1 { target { ! x32 } } } } */> + /* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?bar" { target { ! x32 } } } } */> +-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" { target { ! x32 } } } } */> ++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" { target { ! x32 } } } } */> + /* { dg-final { scan-assembler-times {\tlfence} 2 { target { x32 } } } } */> +-/* { dg-final { scan-assembler "call\[ \t\]*__x86.indirect_thunk\.(r|e)ax" { target { x32 } } } } */> ++/* { dg-final { scan-assembler "call\[ \t\]*__x86_indirect_thunk_(r|e)ax" { target { x32 } } } } */> + /* { dg-final { scan-assembler-not "pushq\[ \t\]%rax" { target x32 } } } */> +-- > +2.15.1> +> diff --git a/gnu/packages/patches/gcc-retpoline-Use-__x86.indirect_thunk.reg-for-indirect-branch-via.patch b/gnu/packages/patches/gcc-retpoline-Use-__x86.indirect_thunk.reg-for-indirect-branch-via.patch> new file mode 100644> index 000000000..bd6797816> --- /dev/null> +++ b/gnu/packages/patches/gcc-retpoline-Use-__x86.indirect_thunk.reg-for-indirect-branch-via.patch> @@ -0,0 +1,623 @@> +'Retpoline' mitigation technique for Spectre (branch target injection)> +[CVE-2017-5715]:> +> +https://security.googleblog.com/2018/01/more-details-about-mitigations-for-cpu_4.html> +https://support.google.com/faqs/answer/7625886> +https://spectreattack.com/> +https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2017-5715> +> +Patch copied from the 'retpoline-20180107' branch of upstream source repository> +(please add new / update existing patches when new 'retpoline-xxxxxxxx' branch> +appears):> +> +http://git.infradead.org/users/dwmw2/gcc-retpoline.git> +> +From e4e33b44a49eaa102806589ce12f021ab6a1e5f1 Mon Sep 17 00:00:00 2001> +From: "H.J. Lu" <hjl.tools@gmail.com>> +Date: Wed, 13 Dec 2017 12:59:50 -0800> +Subject: [PATCH 09/17] Use __x86.indirect_thunk.reg for indirect branch via> + register> +> +---> + gcc/config/i386/i386.c | 137 +++++++++++++++++----> + gcc/testsuite/gcc.target/i386/indirect-thunk-1.c | 4 +-> + gcc/testsuite/gcc.target/i386/indirect-thunk-2.c | 4 +-> + gcc/testsuite/gcc.target/i386/indirect-thunk-3.c | 8 +-> + gcc/testsuite/gcc.target/i386/indirect-thunk-4.c | 8 +-> + gcc/testsuite/gcc.target/i386/indirect-thunk-7.c | 4 +-> + .../gcc.target/i386/indirect-thunk-attr-1.c | 4 +-> + .../gcc.target/i386/indirect-thunk-attr-2.c | 4 +-> + .../gcc.target/i386/indirect-thunk-attr-3.c | 2 +-> + .../gcc.target/i386/indirect-thunk-attr-4.c | 2 +-> + .../gcc.target/i386/indirect-thunk-attr-5.c | 8 +-> + .../gcc.target/i386/indirect-thunk-attr-6.c | 8 +-> + .../gcc.target/i386/indirect-thunk-attr-7.c | 2 +-> + .../gcc.target/i386/indirect-thunk-extern-1.c | 4 +-> + .../gcc.target/i386/indirect-thunk-extern-2.c | 4 +-> + .../gcc.target/i386/indirect-thunk-extern-3.c | 8 +-> + .../gcc.target/i386/indirect-thunk-extern-4.c | 8 +-> + .../gcc.target/i386/indirect-thunk-extern-7.c | 4 +-> + .../gcc.target/i386/indirect-thunk-inline-1.c | 2 +-> + .../gcc.target/i386/indirect-thunk-inline-2.c | 2 +-> + .../gcc.target/i386/indirect-thunk-inline-3.c | 2 +-> + .../gcc.target/i386/indirect-thunk-inline-4.c | 2 +-> + .../gcc.target/i386/indirect-thunk-inline-7.c | 2 +-> + 23 files changed, 158 insertions(+), 75 deletions(-)> +> +diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c> +index 5e66af08066..590729b3f87 100644> +--- a/gcc/config/i386/i386.c> ++++ b/gcc/config/i386/i386.c> +@@ -11948,6 +11948,9 @@ static int indirectlabelno;> + static bool indirect_thunk_needed = false;> + static bool indirect_thunk_bnd_needed = false;> + > ++static int indirect_thunks_used;> ++static int indirect_thunks_bnd_used;> ++> + #ifndef INDIRECT_LABEL> + # define INDIRECT_LABEL "LIND"> + #endif> +@@ -11955,24 +11958,45 @@ static bool indirect_thunk_bnd_needed = false;> + /* Fills in the label name that should be used for the indirect thunk. */> + > + static void> +-indirect_thunk_name (char name[32], bool need_bnd_p)> ++indirect_thunk_name (char name[32], int regno, bool need_bnd_p)> + {> + if (USE_HIDDEN_LINKONCE)> + {> + const char *bnd = need_bnd_p ? "_bnd" : "";> +- sprintf (name, "__x86.indirect_thunk%s", bnd);> ++ if (regno >= 0)> ++ {> ++ const char *reg_prefix;> ++ if (LEGACY_INT_REGNO_P (regno))> ++ reg_prefix = TARGET_64BIT ? "r" : "e";> ++ else> ++ reg_prefix = "";> ++ sprintf (name, "__x86.indirect_thunk%s.%s%s",> ++ bnd, reg_prefix, reg_names[regno]);> ++ }> ++ else> ++ sprintf (name, "__x86.indirect_thunk%s", bnd);> + }> + else> + {> +- if (need_bnd_p)> +- ASM_GENERATE_INTERNAL_LABEL (name, "LITB", 0);> ++ if (regno >= 0)> ++ {> ++ if (need_bnd_p)> ++ ASM_GENERATE_INTERNAL_LABEL (name, "LITBR", regno);> ++ else> ++ ASM_GENERATE_INTERNAL_LABEL (name, "LITR", regno);> ++ }> + else> +- ASM_GENERATE_INTERNAL_LABEL (name, "LIT", 0);> ++ {> ++ if (need_bnd_p)> ++ ASM_GENERATE_INTERNAL_LABEL (name, "LITB", 0);> ++ else> ++ ASM_GENERATE_INTERNAL_LABEL (name, "LIT", 0);> ++ }> + }> + }> + > + static void> +-output_indirect_thunk (bool need_bnd_p)> ++output_indirect_thunk (bool need_bnd_p, int regno)> + {> + char indirectlabel1[32];> + char indirectlabel2[32];> +@@ -12002,11 +12026,22 @@ output_indirect_thunk (bool need_bnd_p)> + > + ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, indirectlabel2);> + > +- /* LEA. */> +- rtx xops[2];> +- xops[0] = stack_pointer_rtx;> +- xops[1] = plus_constant (Pmode, stack_pointer_rtx, UNITS_PER_WORD);> +- output_asm_insn ("lea\t{%E1, %0|%0, %E1}", xops);> ++ if (regno >= 0)> ++ {> ++ /* MOV. */> ++ rtx xops[2];> ++ xops[0] = gen_rtx_MEM (word_mode, stack_pointer_rtx);> ++ xops[1] = gen_rtx_REG (word_mode, regno);> ++ output_asm_insn ("mov\t{%1, %0|%0, %1}", xops);> ++ }> ++ else> ++ {> ++ /* LEA. */> ++ rtx xops[2];> ++ xops[0] = stack_pointer_rtx;> ++ xops[1] = plus_constant (Pmode, stack_pointer_rtx, UNITS_PER_WORD);> ++ output_asm_insn ("lea\t{%E1, %0|%0, %E1}", xops);> ++ }> + > + if (need_bnd_p)> + fputs ("\tbnd ret\n", asm_out_file);> +@@ -12015,12 +12050,13 @@ output_indirect_thunk (bool need_bnd_p)> + }> + > + static void> +-output_indirect_thunk_function (bool need_bnd_p)> ++output_indirect_thunk_function (bool need_bnd_p, int regno)> + {> + char name[32];> + tree decl;> + > +- indirect_thunk_name (name, need_bnd_p);> ++ /* Create __x86.indirect_thunk/__x86.indirect_thunk_bnd. */> ++ indirect_thunk_name (name, regno, need_bnd_p);> + decl = build_decl (BUILTINS_LOCATION, FUNCTION_DECL,> + get_identifier (name),> + build_function_type_list (void_type_node, NULL_TREE));> +@@ -12074,7 +12110,7 @@ output_indirect_thunk_function (bool need_bnd_p)> + /* Make sure unwind info is emitted for the thunk if needed. */> + final_start_function (emit_barrier (), asm_out_file, 1);> + > +- output_indirect_thunk (need_bnd_p);> ++ output_indirect_thunk (need_bnd_p, regno);> + > + final_end_function ();> + init_insn_lengths ();> +@@ -12110,15 +12146,31 @@ ix86_code_end (void)> + int regno;> + > + if (indirect_thunk_needed)> +- output_indirect_thunk_function (false);> ++ output_indirect_thunk_function (false, -1);> + if (indirect_thunk_bnd_needed)> +- output_indirect_thunk_function (true);> ++ output_indirect_thunk_function (true, -1);> ++> ++ for (regno = FIRST_REX_INT_REG; regno <= LAST_REX_INT_REG; regno++)> ++ {> ++ int i = regno - FIRST_REX_INT_REG + LAST_INT_REG + 1;> ++ if ((indirect_thunks_used & (1 << i)))> ++ output_indirect_thunk_function (false, regno);> ++> ++ if ((indirect_thunks_bnd_used & (1 << i)))> ++ output_indirect_thunk_function (true, regno);> ++ }> + > + for (regno = AX_REG; regno <= SP_REG; regno++)> + {> + char name[32];> + tree decl;> + > ++ if ((indirect_thunks_used & (1 << regno)))> ++ output_indirect_thunk_function (false, regno);> ++> ++ if ((indirect_thunks_bnd_used & (1 << regno)))> ++ output_indirect_thunk_function (true, regno);> ++> + if (!(pic_labels_used & (1 << regno)))> + continue;> + > +@@ -28639,17 +28691,37 @@ ix86_output_indirect_branch (rtx call_op, const char *xasm,> + char *thunk_name;> + char push_buf[64];> + bool need_bnd_p = ix86_bnd_prefixed_insn_p (current_output_insn);> ++ int regno;> ++> ++ if (REG_P (call_op))> ++ regno = REGNO (call_op);> ++ else> ++ regno = -1;> + > + if (cfun->machine->indirect_branch_type> + != indirect_branch_thunk_inline)> + {> +- bool need_thunk> +- = cfun->machine->indirect_branch_type == indirect_branch_thunk;> +- if (need_bnd_p)> +- indirect_thunk_bnd_needed |= need_thunk;> +- else> +- indirect_thunk_needed |= need_thunk;> +- indirect_thunk_name (thunk_name_buf, need_bnd_p);> ++ if (cfun->machine->indirect_branch_type == indirect_branch_thunk)> ++ {> ++ if (regno >= 0)> ++ {> ++ int i = regno;> ++ if (i >= FIRST_REX_INT_REG)> ++ i -= (FIRST_REX_INT_REG - LAST_INT_REG - 1);> ++ if (need_bnd_p)> ++ indirect_thunks_bnd_used |= 1 << i;> ++ else> ++ indirect_thunks_used |= 1 << i;> ++ }> ++ else> ++ {> ++ if (need_bnd_p)> ++ indirect_thunk_bnd_needed = true;> ++ else> ++ indirect_thunk_needed = true;> ++ }> ++ }> ++ indirect_thunk_name (thunk_name_buf, regno, need_bnd_p);> + thunk_name = thunk_name_buf;> + }> + else> +@@ -28660,7 +28732,8 @@ ix86_output_indirect_branch (rtx call_op, const char *xasm,> + > + if (sibcall_p)> + {> +- output_asm_insn (push_buf, &call_op);> ++ if (regno < 0)> ++ output_asm_insn (push_buf, &call_op);> + if (thunk_name != NULL)> + {> + if (need_bnd_p)> +@@ -28669,10 +28742,19 @@ ix86_output_indirect_branch (rtx call_op, const char *xasm,> + fprintf (asm_out_file, "\tjmp\t%s\n", thunk_name);> + }> + else> +- output_indirect_thunk (need_bnd_p);> ++ output_indirect_thunk (need_bnd_p, regno);> + }> + else> + {> ++ if (regno >= 0 && thunk_name != NULL)> ++ {> ++ if (need_bnd_p)> ++ fprintf (asm_out_file, "\tbnd call\t%s\n", thunk_name);> ++ else> ++ fprintf (asm_out_file, "\tcall\t%s\n", thunk_name);> ++ return;> ++ }> ++> + char indirectlabel1[32];> + char indirectlabel2[32];> + > +@@ -28725,7 +28807,8 @@ ix86_output_indirect_branch (rtx call_op, const char *xasm,> + }> + }> + > +- output_asm_insn (push_buf, &call_op);> ++ if (regno < 0)> ++ output_asm_insn (push_buf, &call_op);> + > + if (thunk_name != NULL)> + {> +@@ -28735,7 +28818,7 @@ ix86_output_indirect_branch (rtx call_op, const char *xasm,> + fprintf (asm_out_file, "\tjmp\t%s\n", thunk_name);> + }> + else> +- output_indirect_thunk (need_bnd_p);> ++ output_indirect_thunk (need_bnd_p, regno);> + > + ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, indirectlabel2);> + > +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-1.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-1.c> +index d8b6f5a06a5..785e593405f 100644> +--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-1.c> ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-1.c> +@@ -12,8 +12,8 @@ male_indirect_jump (long offset)> + }> + > + /* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { ! x32 } } } } */> +-/* { dg-final { scan-assembler "pushq\[ \t\]%rax" { target x32 } } } */> +-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" } } */> ++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" { target { ! x32 } } } } */> ++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk\.(r|e)ax" { target x32 } } } */> + /* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */> + /* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */> + /* { dg-final { scan-assembler {\tlfence} } } */> +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-2.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-2.c> +index f7d5cb315a8..b69075e6483 100644> +--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-2.c> ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-2.c> +@@ -12,8 +12,8 @@ male_indirect_jump (long offset)> + }> + > + /* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { ! x32 } } } } */> +-/* { dg-final { scan-assembler "pushq\[ \t\]%rax" { target x32 } } } */> +-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" } } */> ++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" { target { ! x32 } } } } */> ++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk\.(r|e)ax" { target x32 } } } */> + /* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */> + /* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */> + /* { dg-final { scan-assembler {\tlfence} } } */> +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-3.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-3.c> +index 736d7cda058..df8109baf55 100644> +--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-3.c> ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-3.c> +@@ -13,8 +13,8 @@ male_indirect_jump (long offset)> + }> + > + /* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { ! x32 } } } } */> +-/* { dg-final { scan-assembler "pushq\[ \t\]%rax" { target x32 } } } */> +-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" } } */> +-/* { dg-final { scan-assembler-times "jmp\[ \t\]*\.LIND" 2 } } */> +-/* { dg-final { scan-assembler-times "call\[ \t\]*\.LIND" 2 } } */> ++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" { target { ! x32 } } } } */> ++/* { dg-final { scan-assembler "call\[ \t\]*__x86.indirect_thunk\.(r|e)ax" { target x32 } } } */> ++/* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */> ++/* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */> + /* { dg-final { scan-assembler {\tlfence} } } */> +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-4.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-4.c> +index cef9b10513e..8f3b9f4d8a5 100644> +--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-4.c> ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-4.c> +@@ -13,8 +13,8 @@ male_indirect_jump (long offset)> + }> + > + /* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { ! x32 } } } } */> +-/* { dg-final { scan-assembler "pushq\[ \t\]%rax" { target x32 } } } */> +-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" } } */> +-/* { dg-final { scan-assembler-times "jmp\[ \t\]*\.LIND" 2 } } */> +-/* { dg-final { scan-assembler-times "call\[ \t\]*\.LIND" 2 } } */> ++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" { target { ! x32 } } } } */> ++/* { dg-final { scan-assembler "call\[ \t\]*__x86.indirect_thunk\.(r|e)ax" { target x32 } } } */> ++/* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */> ++/* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */> + /* { dg-final { scan-assembler {\tlfence} } } */> +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-7.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-7.c> +index ea0fa312f64..f0e1cfe1893 100644> +--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-7.c> ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-7.c> +@@ -36,8 +36,8 @@ bar (int i)> + }> + > + /* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*\.L\[0-9\]+\\(,%" { target { ! x32 } } } } */> +-/* { dg-final { scan-assembler "pushq\[ \t\]%rax" { target x32 } } } */> +-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" } } */> ++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" { target { ! x32 } } } } */> ++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk\.(r|e)ax" { target x32 } } } */> + /* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */> + /* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */> + /* { dg-final { scan-assembler {\tlfence} } } */> +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-1.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-1.c> +index 26550fad4c8..8b88449e625 100644> +--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-1.c> ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-1.c> +@@ -15,8 +15,8 @@ male_indirect_jump (long offset)> + }> + > + /* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { ! x32 } } } } */> +-/* { dg-final { scan-assembler "pushq\[ \t\]%rax" { target x32 } } } */> +-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" } } */> ++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" { target { ! x32 } } } } */> ++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk\.(r|e)ax" { target x32 } } } */> + /* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */> + /* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */> + /* { dg-final { scan-assembler {\tlfence} } } */> +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-2.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-2.c> +index f57bb2a92d6..c69f7bf4f60 100644> +--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-2.c> ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-2.c> +@@ -13,8 +13,8 @@ male_indirect_jump (long offset)> + }> + > + /* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { ! x32 } } } } */> +-/* { dg-final { scan-assembler "pushq\[ \t\]%rax" { target x32 } } } */> +-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" } } */> ++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" { target { ! x32 } } } } */> ++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk\.(r|e)ax" { target x32 } } } */> + /* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */> + /* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */> + /* { dg-final { scan-assembler {\tlfence} } } */> +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-3.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-3.c> +index a3668a6586c..c845099a83e 100644> +--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-3.c> ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-3.c> +@@ -15,7 +15,7 @@ male_indirect_jump (long offset)> + }> + > + /* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { ! x32 } } } } */> +-/* { dg-final { scan-assembler "pushq\[ \t\]%rax" { target x32 } } } */> + /* { dg-final { scan-assembler-times "jmp\[ \t\]*\.LIND" 2 } } */> + /* { dg-final { scan-assembler-times "call\[ \t\]*\.LIND" 2 } } */> + /* { dg-final { scan-assembler-not "__x86.indirect_thunk" } } */> ++/* { dg-final { scan-assembler-not "pushq\[ \t\]%rax" { target x32 } } } */> +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-4.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-4.c> +index a9c4a137dd4..f636f3422fd 100644> +--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-4.c> ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-4.c> +@@ -14,7 +14,7 @@ male_indirect_jump (long offset)> + }> + > + /* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { ! x32 } } } } */> +-/* { dg-final { scan-assembler "pushq\[ \t\]%rax" { target x32 } } } */> + /* { dg-final { scan-assembler-times "jmp\[ \t\]*\.LIND" 2 } } */> + /* { dg-final { scan-assembler-times "call\[ \t\]*\.LIND" 2 } } */> + /* { dg-final { scan-assembler-not "__x86.indirect_thunk" } } */> ++/* { dg-final { scan-assembler-not "pushq\[ \t\]%rax" { target x32 } } } */> +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-5.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-5.c> +index 9582e0c5824..5f1d6a78041 100644> +--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-5.c> ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-5.c> +@@ -15,8 +15,8 @@ male_indirect_jump (long offset)> + }> + > + /* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { ! x32 } } } } */> +-/* { dg-final { scan-assembler "pushq\[ \t\]%rax" { target x32 } } } */> +-/* { dg-final { scan-assembler-times "jmp\[ \t\]*\.LIND" 1 } } */> +-/* { dg-final { scan-assembler-times "call\[ \t\]*\.LIND" 1 } } */> +-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" } } */> ++/* { dg-final { scan-assembler-times "jmp\[ \t\]*\.LIND" 1 { target { ! x32 } } } } */> ++/* { dg-final { scan