From unknown Sun Jun 22 07:57:08 2025 X-Loop: help-debbugs@gnu.org Subject: [bug#30111] gnu: gcc@7: Apply the 'retpoline' mitigation technique. Resent-From: Alex Vong Original-Sender: "Debbugs-submit" Resent-CC: guix-patches@gnu.org Resent-Date: Sun, 14 Jan 2018 13:10:01 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: report 30111 X-GNU-PR-Package: guix-patches X-GNU-PR-Keywords: To: 30111@debbugs.gnu.org X-Debbugs-Original-To: guix-patches@gnu.org Received: via spool by submit@debbugs.gnu.org id=B.15159353432832 (code B ref -1); Sun, 14 Jan 2018 13:10:01 +0000 Received: (at submit) by debbugs.gnu.org; 14 Jan 2018 13:09:03 +0000 Received: from localhost ([127.0.0.1]:55439 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1eai22-0000jb-TA for submit@debbugs.gnu.org; Sun, 14 Jan 2018 08:09:02 -0500 Received: from eggs.gnu.org ([208.118.235.92]:43900) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1eai21-0000j5-5v for submit@debbugs.gnu.org; Sun, 14 Jan 2018 08:09:01 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1eai1V-0005Wh-8E for submit@debbugs.gnu.org; Sun, 14 Jan 2018 08:08:56 -0500 X-Spam-Checker-Version: SpamAssassin 3.3.2 (2011-06-06) on eggs.gnu.org X-Spam-Level: * X-Spam-Status: No, score=1.1 required=5.0 tests=BAYES_50, FREEMAIL_ENVFROM_END_DIGIT,FREEMAIL_FROM,T_DKIM_INVALID autolearn=disabled version=3.3.2 Received: from lists.gnu.org ([2001:4830:134:3::11]:32792) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1eai1U-0005Vc-4w for submit@debbugs.gnu.org; Sun, 14 Jan 2018 08:08:29 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:34754) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eai13-0000ZH-4u for guix-patches@gnu.org; Sun, 14 Jan 2018 08:08:27 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1eai0a-0004mk-VF for guix-patches@gnu.org; Sun, 14 Jan 2018 08:08:01 -0500 Received: from mail-pf0-x22c.google.com ([2607:f8b0:400e:c00::22c]:37772) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1eai0Z-0004lL-6d for guix-patches@gnu.org; Sun, 14 Jan 2018 08:07:32 -0500 Received: by mail-pf0-x22c.google.com with SMTP id p1so6890605pfh.4 for ; Sun, 14 Jan 2018 05:07:30 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:subject:date:message-id:user-agent:mime-version; bh=pl3/n3YyJ/Il7XlsKVujC2Wl66yxNWYNKnIbJnOUoAo=; b=SACf7gB79AN1nv10ieHBWGlClbBMf4Gmi6k6ocqXe1+uTk+dkQvtKuq22lDsqE0OmO p6+4vVOHrj0ODNnvfrOM648ru1o3rs65ESMe9P8/j0ANMwaHJxOWhdToBKUJpKgvPXib Sml3pc4Lm5A6ReS12my+Ygkd3LX7+kGbmHMv9pM4UJZvvrN6e8mqfyLyzz3F6rPt5dwM RMf21fpGreON0z9aRRxi6gheDRbi2HFjzmY+BlL4U3qwUQtt0sjhpYYPdjtQHraNLA8z 3tnxOU0breRSttpWJOt1XnNni2G3iwCC0d33gG+qqiVkg78AGuEH11VAUL6bUDrhXjnT rAIA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:subject:date:message-id:user-agent :mime-version; bh=pl3/n3YyJ/Il7XlsKVujC2Wl66yxNWYNKnIbJnOUoAo=; b=gk6TyhiXew2mU9xXjT4WZ0pF6BnU1Yq3TPX3JoyzlDhfuqTeHA5fG35N4EKevhNE6n C1YmR8cC4ItLJsWO+diosufv/K/6H7JcV+PfM1sM/zDem1fdJFRgtrjCrW22JeCEqK9N o/FuZc1JnEXm/WPYG4Rsw5d0ppHZDiAT4rfx7Qbiu/YjFpFL8UBNyfzEi1qMYh7NOGxo j3gGgi0KgInDRqd1oTpkUBmX9j8s7iC171vWievzCTFydqx9/hpHwNSUPrWj2HKbTupk LQ+e267IByE0tOfiC1mY+jAN0r6LTwYgooeoNol6+dRba4rEehMbkTs7+oIa7hETiEJE jyhQ== X-Gm-Message-State: AKGB3mIcgDn5CfTAfwhFGqUM5kWoQjdWqCs6EmtGpMpOPmDQZK6NIbgz +9Zrw2h0NwfW/40R6y1yHBI= X-Google-Smtp-Source: ACJfBoshrrPicVx45N6RNrwbPDPnLPmMDaqjtAZb2ZCal8ZLGWfjmlIQUaaSoct5ZP5t1h8vPCPBBw== X-Received: by 10.98.204.144 with SMTP id j16mr24208277pfk.101.1515935250179; Sun, 14 Jan 2018 05:07:30 -0800 (PST) Received: from debian (n218103180243.netvigator.com. [218.103.180.243]) by smtp.gmail.com with ESMTPSA id d24sm27329615pfb.30.2018.01.14.05.07.26 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Sun, 14 Jan 2018 05:07:28 -0800 (PST) From: Alex Vong Date: Sun, 14 Jan 2018 21:07:17 +0800 Message-ID: <877esksi62.fsf@gmail.com> User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/25.3 (gnu/linux) MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="=-=-=" X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.6.x X-Received-From: 2001:4830:134:3::11 X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" --=-=-= Content-Type: text/plain 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. --=-=-= Content-Type: text/x-diff; charset=utf-8 Content-Disposition: inline; filename=0001-gnu-gcc-7-Apply-the-retpoline-mitigation-technique.patch Content-Transfer-Encoding: quoted-printable >From 5be54f7ebe9b0ab6dc65ea974584be0850604b14 Mon Sep 17 00:00:00 2001 From: Alex Vong 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 . * 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-tes= ts.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-br= anch-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-indi= rect-branch-.patch, gnu/packages/patches/gcc-retpoline-Add-tests-for-mindirect-branch-thunk-fch= eck-pointer-.patch, gnu/packages/patches/gcc-retpoline-Disable-red-zone-with-local-indirect-jum= p.patch, gnu/packages/patches/gcc-retpoline-Rename-thunks-to-__x86_indirect_thunk_ra= x-etc.-to-re.patch, gnu/packages/patches/gcc-retpoline-Use-__x86.indirect_thunk.reg-for-indirec= t-branch-via.patch, gnu/packages/patches/gcc-retpoline-i386-Add-V-register-operand-modifier.pat= ch, gnu/packages/patches/gcc-retpoline-i386-More-use-reference-of-struct-ix86_f= rame-to-avoi.patch, gnu/packages/patches/gcc-retpoline-i386-Move-struct-ix86_frame-to-machine_f= unction.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-bra= nch-register-to-indirect-branch-.patch create mode 100644 gnu/packages/patches/gcc-retpoline-Add-tests-for-mindir= ect-branch-thunk-fcheck-pointer-.patch create mode 100644 gnu/packages/patches/gcc-retpoline-Disable-red-zone-wit= h-local-indirect-jump.patch create mode 100644 gnu/packages/patches/gcc-retpoline-Rename-thunks-to-__x= 86_indirect_thunk_rax-etc.-to-re.patch create mode 100644 gnu/packages/patches/gcc-retpoline-Use-__x86.indirect_t= hunk.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-refere= nce-of-struct-ix86_frame-to-avoi.patch create mode 100644 gnu/packages/patches/gcc-retpoline-i386-Move-struct-ix8= 6_frame-to-machine_function.patch create mode 100644 gnu/packages/patches/gcc-retpoline-i386-Use-reference-o= f-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 =C2=A9 2016 Adonay "adfeno" Felipe Nogueira # Copyright =C2=A9 2016, 2017 Ricardo Wurmus # Copyright =C2=A9 2016 Ben Woodcroft -# Copyright =C2=A9 2016, 2017 Alex Vong +# Copyright =C2=A9 2016, 2017, 2018 Alex Vong # Copyright =C2=A9 2016, 2017 Efraim Flashner # Copyright =C2=A9 2016, 2017 Jan Nieuwenhuizen # Copyright =C2=A9 2017 Tobias Geerinckx-Rice @@ -652,6 +652,23 @@ dist_patch_DATA =3D \ %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-machin= e_function.patch \ + %D%/packages/patches/gcc-retpoline-i386-Use-reference-of-struct-ix86_fra= me-to-avoid-cop.patch \ + %D%/packages/patches/gcc-retpoline-i386-More-use-reference-of-struct-ix8= 6_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.pat= ch \ + %D%/packages/patches/gcc-retpoline-Add-mindirect-branch-thunk-extern.pat= ch \ + %D%/packages/patches/gcc-retpoline-Add-indirect_branch-attribute-with-te= sts.patch \ + %D%/packages/patches/gcc-retpoline-Use-__x86.indirect_thunk.reg-for-indi= rect-branch-via.patch \ + %D%/packages/patches/gcc-retpoline-Add-mindirect-branch-loop.patch \ + %D%/packages/patches/gcc-retpoline-Add-mfunction-return-and-function_ret= urn-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-tes= ts.patch \ + %D%/packages/patches/gcc-retpoline-Add-mno-indirect-branch-register-to-i= ndirect-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 =C2=A9 2015 Andreas Enge ;;; Copyright =C2=A9 2015, 2016, 2017 Efraim Flashner ;;; Copyright =C2=A9 2016 Carlos S=C3=A1nchez de La Lama +;;; Copyright =C2=A9 2018 ALex Vong ;;; ;;; This file is part of GNU Guix. ;;; @@ -427,7 +428,24 @@ Go. It also includes runtime support libraries for th= ese 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-ix8= 6_frame-to-machine_function.patch" + "gcc-retpoline-i386-Use-reference-o= f-struct-ix86_frame-to-avoid-cop.patch" + "gcc-retpoline-i386-More-use-refere= nce-of-struct-ix86_frame-to-avoi.patch" + "gcc-retpoline-Add-mindirect-branch= -thunk.patch" + "gcc-retpoline-Add-tests-for-mindir= ect-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_t= hunk.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-bra= nch-register-to-indirect-branch-.patch" + "gcc-retpoline-Disable-red-zone-wit= h-local-indirect-jump.patch" + "gcc-retpoline-i386-Add-V-register-= operand-modifier.patch" + "gcc-retpoline-Rename-thunks-to-__x= 86_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-attribu= te-with-tests.patch b/gnu/packages/patches/gcc-retpoline-Add-indirect_branc= h-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=3DCVE-2017-5715 + +Patch copied from the 'retpoline-20180107' branch of upstream source repos= itory +(please add new / update existing patches when new 'retpoline-xxxxxxxx' br= anch +appears): + +http://git.infradead.org/users/dwmw2/gcc-retpoline.git + +From e9794727bb0384be6d27ad1edaefc71c23cc0d86 Mon Sep 17 00:00:00 2001 +From: "H.J. Lu" +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 { + }; +=20 + enum indirect_branch { ++ indirect_branch_unset =3D 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) + } + } +=20 ++/* 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 =3D=3D indirect_branch_unset) ++ { ++ tree attr =3D lookup_attribute ("indirect_branch", ++ DECL_ATTRIBUTES (fndecl)); ++ if (attr !=3D NULL) ++ { ++ tree args =3D TREE_VALUE (attr); ++ if (args =3D=3D NULL) ++ gcc_unreachable (); ++ tree cst =3D TREE_VALUE (args); ++ if (strcmp (TREE_STRING_POINTER (cst), "keep") =3D=3D 0) ++ cfun->machine->indirect_branch_type =3D indirect_branch_keep; ++ else if (strcmp (TREE_STRING_POINTER (cst), "thunk") =3D=3D 0) ++ cfun->machine->indirect_branch_type =3D indirect_branch_thunk; ++ else if (strcmp (TREE_STRING_POINTER (cst), "thunk-inline") =3D=3D 0) ++ cfun->machine->indirect_branch_type =3D indirect_branch_thunk_inline; ++ else if (strcmp (TREE_STRING_POINTER (cst), "thunk-extern") =3D=3D 0) ++ cfun->machine->indirect_branch_type =3D indirect_branch_thunk_extern; ++ else ++ gcc_unreachable (); ++ } ++ else ++ cfun->machine->indirect_branch_type =3D 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 !=3D NULL_TREE) +- ix86_set_func_type (fndecl); ++ { ++ ix86_set_func_type (fndecl); ++ ix86_set_indirect_branch_type (fndecl); ++ } + return; + } +=20 +@@ -7172,6 +7206,7 @@ ix86_set_current_function (tree fndecl) + } +=20 + ix86_set_func_type (fndecl); ++ ix86_set_indirect_branch_type (fndecl); +=20 + tree new_tree =3D DECL_FUNCTION_SPECIFIC_TARGET (fndecl); + if (new_tree =3D=3D NULL_TREE) +@@ -28605,9 +28640,11 @@ ix86_output_indirect_branch (rtx call_op, const c= har *xasm, + char push_buf[64]; + bool need_bnd_p =3D ix86_bnd_prefixed_insn_p (current_output_insn); +=20 +- if (ix86_indirect_branch !=3D indirect_branch_thunk_inline) ++ if (cfun->machine->indirect_branch_type ++ !=3D indirect_branch_thunk_inline) + { +- bool need_thunk =3D ix86_indirect_branch =3D=3D indirect_branch_thu= nk; ++ bool need_thunk ++ =3D cfun->machine->indirect_branch_type =3D=3D indirect_branch_thunk; + if (need_bnd_p) + indirect_thunk_bnd_needed |=3D need_thunk; + else +@@ -28716,7 +28753,7 @@ const char * + ix86_output_indirect_jmp (rtx call_op) + { + if (ix86_red_zone_size =3D=3D 0 +- && ix86_indirect_branch !=3D indirect_branch_keep) ++ && cfun->machine->indirect_branch_type !=3D 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 =3D constant_call_address_operand (call_op, VOIDmode); + bool output_indirect_p + =3D (!TARGET_SEH +- && ix86_indirect_branch !=3D indirect_branch_keep); ++ && cfun->machine->indirect_branch_type !=3D indirect_branch_keep); + bool seh_nop_p =3D false; + const char *xasm; +=20 +@@ -41749,7 +41786,7 @@ ix86_handle_struct_attribute (tree *node, tree nam= e, tree, int, + } +=20 + 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) !=3D FUNCTION_DECL) +@@ -41758,6 +41795,29 @@ ix86_handle_fndecl_attribute (tree *node, tree na= me, tree, int, + name); + *no_add_attrs =3D true; + } ++ ++ if (is_attribute_p ("indirect_branch", name)) ++ { ++ tree cst =3D TREE_VALUE (args); ++ if (TREE_CODE (cst) !=3D STRING_CST) ++ { ++ warning (OPT_Wattributes, ++ "%qE attribute requires a string constant argument", ++ name); ++ *no_add_attrs =3D true; ++ } ++ else if (strcmp (TREE_STRING_POINTER (cst), "keep") !=3D 0 ++ && strcmp (TREE_STRING_POINTER (cst), "thunk") !=3D 0 ++ && strcmp (TREE_STRING_POINTER (cst), "thunk-inline") !=3D 0 ++ && strcmp (TREE_STRING_POINTER (cst), "thunk-extern") !=3D 0) ++ { ++ warning (OPT_Wattributes, ++ "argument to %qE attribute is not " ++ "(keep|thunk|thunk-inline|thunk-extern)", name); ++ *no_add_attrs =3D true; ++ } ++ } ++ + return NULL_TREE; + } +=20 +@@ -46052,6 +46112,8 @@ static const struct attribute_spec ix86_attribute_= table[] =3D + 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 }, +=20 + /* 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; +=20 ++ /* 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/t= estsuite/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/t= estsuite/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/t= estsuite/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/t= estsuite/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/t= estsuite/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/t= estsuite/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/t= estsuite/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\]+\\(,%" { ta= rget { ! 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/t= estsuite/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=3Dthunk -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" } } */ +--=20 +2.15.1 + diff --git a/gnu/packages/patches/gcc-retpoline-Add-mfunction-return-and-fu= nction_return-attribute.patch b/gnu/packages/patches/gcc-retpoline-Add-mfun= ction-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=3DCVE-2017-5715 + +Patch copied from the 'retpoline-20180107' branch of upstream source repos= itory +(please add new / update existing patches when new 'retpoline-xxxxxxxx' br= anch +appears): + +http://git.infradead.org/users/dwmw2/gcc-retpoline.git + +From 29d5a3f23c18c96944dd3230a41380a6edcd25fd Mon Sep 17 00:00:00 2001 +From: "H.J. Lu" +Date: Tue, 5 Dec 2017 13:29:06 -0800 +Subject: [PATCH 11/17] Add -mfunction-return=3D and function_return attrib= ute + +Add -mfunction-return=3D and function_return attribute tests + +-mfunction-return=3Dthunk + Convert function return instruction to PC-relative call thunk. +-mfunction-return=3Dthunk-inline + Convert function return instruction to PC-relative call thunk with + thunk inlined. +-mfunction-return=3Dthunk-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; +=20 + 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); +=20 +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 =3D ix86_indirect_branch; + } ++ ++ if (cfun->machine->function_return_type =3D=3D indirect_branch_unset) ++ { ++ tree attr =3D lookup_attribute ("function_return", ++ DECL_ATTRIBUTES (fndecl)); ++ if (attr !=3D NULL) ++ { ++ tree args =3D TREE_VALUE (attr); ++ if (args =3D=3D NULL) ++ gcc_unreachable (); ++ tree cst =3D TREE_VALUE (args); ++ if (strcmp (TREE_STRING_POINTER (cst), "keep") =3D=3D 0) ++ cfun->machine->function_return_type =3D indirect_branch_keep; ++ else if (strcmp (TREE_STRING_POINTER (cst), "thunk") =3D=3D 0) ++ cfun->machine->function_return_type =3D indirect_branch_thunk; ++ else if (strcmp (TREE_STRING_POINTER (cst), "thunk-inline") =3D=3D 0) ++ cfun->machine->function_return_type =3D indirect_branch_thunk_inline; ++ else if (strcmp (TREE_STRING_POINTER (cst), "thunk-extern") =3D=3D 0) ++ cfun->machine->function_return_type =3D indirect_branch_thunk_extern; ++ else ++ gcc_unreachable (); ++ } ++ else ++ cfun->machine->function_return_type =3D ix86_function_return; ++ } + } +=20 + /* 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. */ +=20 + 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 >=3D 0 && ret_p) ++ gcc_unreachable (); ++ + if (USE_HIDDEN_LINKONCE) + { + const char *bnd =3D need_bnd_p ? "_bnd" : ""; +@@ -11974,7 +12003,10 @@ indirect_thunk_name (char name[32], int regno, bo= ol need_bnd_p) + bnd, reg_prefix, reg_names[regno]); + } + else +- sprintf (name, "__x86.indirect_thunk%s", bnd); ++ { ++ const char *ret =3D 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, b= ool 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, i= nt regno) + tree decl; +=20 + /* 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 =3D 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); + } +=20 ++ 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) =3D make_node (BLOCK); + current_function_decl =3D decl; + allocate_struct_function (decl, false); +@@ -28736,7 +28807,7 @@ ix86_output_indirect_branch (rtx call_op, const ch= ar *xasm, + indirect_thunk_needed =3D true; + } + } +- indirect_thunk_name (thunk_name_buf, regno, need_bnd_p); ++ indirect_thunk_name (thunk_name_buf, regno, need_bnd_p, false); + thunk_name =3D thunk_name_buf; + } + else +@@ -28860,6 +28931,43 @@ ix86_output_indirect_jmp (rtx call_op) + return "%!jmp\t%A0"; + } +=20 ++const char * ++ix86_output_function_return (bool long_p) ++{ ++ if (cfun->machine->function_return_type !=3D indirect_branch_keep) ++ { ++ char thunk_name[32]; ++ bool need_bnd_p =3D ix86_bnd_prefixed_insn_p (current_output_insn); ++ ++ if (cfun->machine->function_return_type ++ !=3D indirect_branch_thunk_inline) ++ { ++ bool need_thunk =3D (cfun->machine->function_return_type ++ =3D=3D indirect_branch_thunk); ++ indirect_thunk_name (thunk_name, -1, need_bnd_p, true); ++ if (need_bnd_p) ++ { ++ indirect_thunk_bnd_needed |=3D need_thunk; ++ fprintf (asm_out_file, "\tbnd jmp\t%s\n", thunk_name); ++ } ++ else ++ { ++ indirect_thunk_needed |=3D 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. */ +=20 + const char * +@@ -41916,6 +42024,28 @@ ix86_handle_fndecl_attribute (tree *node, tree na= me, tree args, int, + } + } +=20 ++ if (is_attribute_p ("function_return", name)) ++ { ++ tree cst =3D TREE_VALUE (args); ++ if (TREE_CODE (cst) !=3D STRING_CST) ++ { ++ warning (OPT_Wattributes, ++ "%qE attribute requires a string constant argument", ++ name); ++ *no_add_attrs =3D true; ++ } ++ else if (strcmp (TREE_STRING_POINTER (cst), "keep") !=3D 0 ++ && strcmp (TREE_STRING_POINTER (cst), "thunk") !=3D 0 ++ && strcmp (TREE_STRING_POINTER (cst), "thunk-inline") !=3D 0 ++ && strcmp (TREE_STRING_POINTER (cst), "thunk-extern") !=3D 0) ++ { ++ warning (OPT_Wattributes, ++ "argument to %qE attribute is not " ++ "(keep|thunk|thunk-inline|thunk-extern)", name); ++ *no_add_attrs =3D true; ++ } ++ } ++ + return NULL_TREE; + } +=20 +@@ -46212,6 +46342,8 @@ static const struct attribute_spec ix86_attribute_= table[] =3D + 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 }, +=20 + /* 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; +=20 ++ /* 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=3D + Target Report RejectNegative Joined Enum(indirect_branch) Var(ix86_indire= ct_branch) Init(indirect_branch_keep) + Update indirect call and jump. +=20 ++mfunction-return=3D ++Target Report RejectNegative Joined Enum(indirect_branch) Var(ix86_functi= on_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=3D opti= on): ++Known indirect branch choices (for use with the -mindirect-branch=3D/-mfu= nction-return=3D options): +=20 + 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/g= cc.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=3Dthunk" } */ ++ ++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=3Dthunk-inline -mindirect-branch= =3Dthunk -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 { ! x3= 2 } } } } */ ++/* { 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=3Dthunk-extern -mindirect-branch= =3Dthunk -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 { ! x3= 2 } } } } */ ++/* { 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=3Dkeep -mindirect-branch=3Dthunk -= 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=3Dkeep -mindirect-branch=3Dthunk-i= nline -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 { ! x3= 2 } } } } */ ++/* { 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=3Dkeep -mindirect-branch=3Dthunk-e= xtern -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 { ! x3= 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-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=3Dkeep -mindirect-branch=3Dkeep -f= no-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 { ! x3= 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-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=3Dthunk-inline -mindirect-branch= =3Dthunk-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/g= cc.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=3Dthunk-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/g= cc.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=3Dthunk-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/g= cc.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=3Dkeep" } */ ++ ++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/g= cc.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=3Dkeep" } */ ++ ++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/g= cc.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=3Dkeep" } */ ++ ++__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/g= cc.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=3Dkeep" } */ ++ ++__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/g= cc.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=3Dthunk-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/g= cc.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=3Dthunk -mindirect-branch=3Dthunk = -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 { ! x3= 2 } } } } */ ++/* { 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 } } } = */ +--=20 +2.15.1 + diff --git a/gnu/packages/patches/gcc-retpoline-Add-mfunction-return-keep-t= o-indirect-branch-tests.patch b/gnu/packages/patches/gcc-retpoline-Add-mfun= ction-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-indir= ect-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=3DCVE-2017-5715 + +Patch copied from the 'retpoline-20180107' branch of upstream source repos= itory +(please add new / update existing patches when new 'retpoline-xxxxxxxx' br= anch +appears): + +http://git.infradead.org/users/dwmw2/gcc-retpoline.git + +From def2b5d75fd6234984ec969f4586fcb8c516a3b9 Mon Sep 17 00:00:00 2001 +From: "H.J. Lu" +Date: Wed, 6 Dec 2017 09:58:42 -0800 +Subject: [PATCH 12/17] Add -mfunction-return=3Dkeep to indirect branch tes= ts + +--- + 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/testsu= ite/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=3Dthunk -fno-pic" } */ ++/* { dg-options "-O2 -mfunction-return=3Dkeep -mindirect-branch=3Dthunk -= fno-pic" } */ +=20 + typedef void (*dispatch_t)(long offset); +=20 +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-2.c b/gcc/testsu= ite/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=3Dthunk -fno-pic" } */ ++/* { dg-options "-O2 -mfunction-return=3Dkeep -mindirect-branch=3Dthunk -= fno-pic" } */ +=20 + typedef void (*dispatch_t)(long offset); +=20 +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-3.c b/gcc/testsu= ite/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=3Dthunk -fno-pic" } */ ++/* { dg-options "-O2 -mfunction-return=3Dkeep -mindirect-branch=3Dthunk -= fno-pic" } */ +=20 + typedef void (*dispatch_t)(long offset); +=20 +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-4.c b/gcc/testsu= ite/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=3Dthunk -fno-pic" } */ ++/* { dg-options "-O2 -mfunction-return=3Dkeep -mindirect-branch=3Dthunk -= fno-pic" } */ +=20 + typedef void (*dispatch_t)(long offset); +=20 +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-5.c b/gcc/testsu= ite/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=3Dthunk" } */ ++/* { dg-options "-O2 -mfunction-return=3Dkeep -fpic -fno-plt -mindirect-b= ranch=3Dthunk" } */ +=20 + extern void bar (void); +=20 +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-6.c b/gcc/testsu= ite/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=3Dthunk" } */ ++/* { dg-options "-O2 -mfunction-return=3Dkeep -fpic -fno-plt -mindirect-b= ranch=3Dthunk" } */ +=20 + extern void bar (void); +=20 +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-7.c b/gcc/testsu= ite/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=3Dthunk -fno-pic" } */ ++/* { dg-options "-O2 -mfunction-return=3Dkeep -mindirect-branch=3Dthunk -= fno-pic" } */ +=20 + void func0 (void); + void func1 (void); +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-1.c b/gcc/t= estsuite/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=3Dkeep -fno-pic" } */ +=20 + typedef void (*dispatch_t)(long offset); +=20 +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-2.c b/gcc/t= estsuite/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=3Dkeep -fno-pic" } */ +=20 + typedef void (*dispatch_t)(long offset); +=20 +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-3.c b/gcc/t= estsuite/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=3Dkeep -fno-pic" } */ +=20 + typedef void (*dispatch_t)(long offset); +=20 +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-4.c b/gcc/t= estsuite/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=3Dkeep -fno-pic" } */ +=20 + typedef void (*dispatch_t)(long offset); +=20 +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-5.c b/gcc/t= estsuite/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=3Dkeep -fno-pic" } */ +=20 + typedef void (*dispatch_t)(long offset); +=20 +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-6.c b/gcc/t= estsuite/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=3Dkeep -fno-pic" } */ +=20 + typedef void (*dispatch_t)(long offset); +=20 +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-7.c b/gcc/t= estsuite/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=3Dkeep -fno-pic" } */ +=20 + void func0 (void); + void func1 (void); +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-8.c b/gcc/t= estsuite/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=3Dthunk -fno-pic" } */ ++/* { dg-options "-O2 -mfunction-return=3Dkeep -mindirect-branch=3Dthunk -= fno-pic" } */ +=20 + void func0 (void); + void func1 (void); +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-1.c b/gcc/te= stsuite/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=3Dthunk -fcheck-pointer-bounds -mm= px -fno-pic" } */ ++/* { dg-options "-O2 -mfunction-return=3Dkeep -mindirect-branch=3Dthunk -= fcheck-pointer-bounds -mmpx -fno-pic" } */ +=20 + void (*dispatch) (char *); + char buf[10]; +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-2.c b/gcc/te= stsuite/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=3Dthunk -fcheck-pointer-bounds -mm= px -fno-pic" } */ ++/* { dg-options "-O2 -mfunction-return=3Dkeep -mindirect-branch=3Dthunk -= fcheck-pointer-bounds -mmpx -fno-pic" } */ +=20 + void (*dispatch) (char *); + char buf[10]; +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-3.c b/gcc/te= stsuite/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=3Dthunk -fcheck-pointer-bounds -mm= px -fpic -fno-plt" } */ ++/* { dg-options "-O2 -mfunction-return=3Dkeep -mindirect-branch=3Dthunk -= fcheck-pointer-bounds -mmpx -fpic -fno-plt" } */ +=20 + void bar (char *); + char buf[10]; +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-4.c b/gcc/te= stsuite/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=3Dthunk -fcheck-pointer-bounds -mm= px -fpic -fno-plt" } */ ++/* { dg-options "-O2 -mfunction-return=3Dkeep -mindirect-branch=3Dthunk -= fcheck-pointer-bounds -mmpx -fpic -fno-plt" } */ +=20 + 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=3Dthunk-extern -fno-pic" } */ ++/* { dg-options "-O2 -mfunction-return=3Dkeep -mindirect-branch=3Dthunk-e= xtern -fno-pic" } */ +=20 + typedef void (*dispatch_t)(long offset); +=20 +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=3Dthunk-extern -fno-pic" } */ ++/* { dg-options "-O2 -mfunction-return=3Dkeep -mindirect-branch=3Dthunk-e= xtern -fno-pic" } */ +=20 + typedef void (*dispatch_t)(long offset); +=20 +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=3Dthunk-extern -fno-pic" } */ ++/* { dg-options "-O2 -mfunction-return=3Dkeep -mindirect-branch=3Dthunk-e= xtern -fno-pic" } */ +=20 + typedef void (*dispatch_t)(long offset); +=20 +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=3Dthunk-extern -fno-pic" } */ ++/* { dg-options "-O2 -mfunction-return=3Dkeep -mindirect-branch=3Dthunk-e= xtern -fno-pic" } */ +=20 + typedef void (*dispatch_t)(long offset); +=20 +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=3Dthunk-extern" } */ ++/* { dg-options "-O2 -mfunction-return=3Dkeep -fpic -fno-plt -mindirect-b= ranch=3Dthunk-extern" } */ +=20 + extern void bar (void); +=20 +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=3Dthunk-extern" } */ ++/* { dg-options "-O2 -mfunction-return=3Dkeep -fpic -fno-plt -mindirect-b= ranch=3Dthunk-extern" } */ +=20 + extern void bar (void); +=20 +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=3Dthunk-extern -fno-pic" } */ ++/* { dg-options "-O2 -mfunction-return=3Dkeep -mindirect-branch=3Dthunk-e= xtern -fno-pic" } */ +=20 + 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=3Dthunk-inline -fno-pic" } */ ++/* { dg-options "-O2 -mfunction-return=3Dkeep -mindirect-branch=3Dthunk-i= nline -fno-pic" } */ +=20 + typedef void (*dispatch_t)(long offset); +=20 +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=3Dthunk-inline -fno-pic" } */ ++/* { dg-options "-O2 -mfunction-return=3Dkeep -mindirect-branch=3Dthunk-i= nline -fno-pic" } */ +=20 + typedef void (*dispatch_t)(long offset); +=20 +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=3Dthunk-inline -fno-pic" } */ ++/* { dg-options "-O2 -mfunction-return=3Dkeep -mindirect-branch=3Dthunk-i= nline -fno-pic" } */ +=20 + typedef void (*dispatch_t)(long offset); +=20 +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=3Dthunk-inline -fno-pic" } */ ++/* { dg-options "-O2 -mfunction-return=3Dkeep -mindirect-branch=3Dthunk-i= nline -fno-pic" } */ +=20 + typedef void (*dispatch_t)(long offset); +=20 +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=3Dthunk-inline" } */ ++/* { dg-options "-O2 -mfunction-return=3Dkeep -fpic -fno-plt -mindirect-b= ranch=3Dthunk-inline" } */ +=20 + extern void bar (void); +=20 +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=3Dthunk-inline" } */ ++/* { dg-options "-O2 -mfunction-return=3Dkeep -fpic -fno-plt -mindirect-b= ranch=3Dthunk-inline" } */ +=20 + extern void bar (void); +=20 +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=3Dthunk-inline -fno-pic" } */ ++/* { dg-options "-O2 -mfunction-return=3Dkeep -mindirect-branch=3Dthunk-i= nline -fno-pic" } */ +=20 + void func0 (void); + void func1 (void); +--=20 +2.15.1 + diff --git a/gnu/packages/patches/gcc-retpoline-Add-mindirect-branch-loop.p= atch 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=3DCVE-2017-5715 + +Patch copied from the 'retpoline-20180107' branch of upstream source repos= itory +(please add new / update existing patches when new 'retpoline-xxxxxxxx' br= anch +appears): + +http://git.infradead.org/users/dwmw2/gcc-retpoline.git + +From d667049b53e3d45de057fba2f1ed0e3f268201c1 Mon Sep 17 00:00:00 2001 +From: "H.J. Lu" +Date: Thu, 16 Nov 2017 14:46:20 -0800 +Subject: [PATCH 10/17] Add -mindirect-branch-loop=3D + +Add -mindirect-branch-loop=3D 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 + }; +=20 ++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) +=20 + ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, indirectlabel1); +=20 +- /* 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 (); ++ } +=20 + /* 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(indi= rect_branch_thunk_inline) +=20 + EnumValue + Enum(indirect_branch) String(thunk-extern) Value(indirect_branch_thunk_ex= tern) ++ ++mindirect-branch-loop=3D ++Target Report RejectNegative Joined Enum(indirect_branch_loop) Var(ix86_i= ndirect_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=3D option): ++ ++EnumValue ++Enum(indirect_branch_loop) String(lfence) Value(indirect_branch_loop_lfen= ce) ++ ++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/t= estsuite/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=3Dthunk -mindirect-branch-loop=3Dp= ause -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/t= estsuite/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=3Dthunk -mindirect-branch-loop=3Dn= op -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/t= estsuite/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=3Dthunk -mindirect-branch-loop=3Dl= fence -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/t= estsuite/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=3Dthunk-inline -mindirect-branch-l= oop=3Dpause -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/t= estsuite/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=3Dthunk-extern -mindirect-branch-l= oop=3Dpause -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" } } */ +--=20 +2.15.1 + diff --git a/gnu/packages/patches/gcc-retpoline-Add-mindirect-branch-regist= er-and-tests.patch b/gnu/packages/patches/gcc-retpoline-Add-mindirect-branc= h-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=3DCVE-2017-5715 + +Patch copied from the 'retpoline-20180107' branch of upstream source repos= itory +(please add new / update existing patches when new 'retpoline-xxxxxxxx' br= anch +appears): + +http://git.infradead.org/users/dwmw2/gcc-retpoline.git + +From fb8875abab630962dbcb08c822b1b960fa5a51d4 Mon Sep 17 00:00:00 2001 +From: "H.J. Lu" +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 @@ +=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 =3D=3D DImode") ++ (and (match_test "TARGET_X32 && Pmode =3D=3D DImode ++ && !ix86_indirect_branch_thunk_register") + (match_operand 0 "GOT_memory_operand")))) +=20 + (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 =3D=3D DImode") ++ (and (match_test "TARGET_X32 && Pmode =3D=3D DImode ++ && !ix86_indirect_branch_thunk_register") + (match_operand 0 "GOT_memory_operand")))) +=20 + (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] =3D convert_memory_address (word_mode, operands[0]); + }) +=20 +@@ -11657,7 +11657,7 @@ + OPTAB_DIRECT); + } +=20 +- if (TARGET_X32) ++ if (TARGET_X32 || ix86_indirect_branch_thunk_register) + operands[0] =3D convert_memory_address (word_mode, operands[0]); + }) +=20 +@@ -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")]) +=20 +@@ -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 @@ + }) +=20 + (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")]) +=20 + (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))]) +=20 + ;; 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")]) +=20 +@@ -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 @@ +=20 + (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(indi= rect_branch_thunk_inline) + EnumValue + Enum(indirect_branch) String(thunk-extern) Value(indirect_branch_thunk_ex= tern) +=20 ++mindirect-branch-register ++Target Report Var(ix86_indirect_branch_thunk_register) Init(0) ++Force indirect call and jump via register. ++ + mindirect-branch-loop=3D + Target Report RejectNegative Joined Enum(indirect_branch_loop) Var(ix86_i= ndirect_branch_loop) Undocumented Init(indirect_branch_loop_lfence) +=20 +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")))) +=20 + ;; Return true if OP is a memory operands that can be used in sibcalls. +@@ -664,7 +665,8 @@ +=20 + ;; 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 =3D XEXP (op, 0); + return (GET_CODE (op) =3D=3D CONST +@@ -678,9 +680,11 @@ + (ior (match_test "constant_call_address_operand + (op, mode =3D=3D 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 =3D=3D DImode") ++ (and (match_test "TARGET_X32 && Pmode =3D=3D DImode ++ && !ix86_indirect_branch_thunk_register") + (match_operand 0 "GOT_memory_operand"))))) +=20 + ;; Similarly, but for tail calls, in which we cannot allow memory referen= ces. +@@ -688,14 +692,17 @@ + (ior (match_test "constant_call_address_operand + (op, mode =3D=3D 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 =3D=3D DImode") ++ (and (match_test "TARGET_X32 && Pmode =3D=3D DImode ++ && !ix86_indirect_branch_thunk_register") + (match_operand 0 "GOT_memory_operand"))))) +=20 + ;; Return true if OP is a 32-bit GOT symbol operand. + (define_predicate "GOT32_symbol_operand" +- (match_test "GET_CODE (op) =3D=3D CONST ++ (match_test "!ix86_indirect_branch_thunk_register ++ && GET_CODE (op) =3D=3D CONST + && GET_CODE (XEXP (op, 0)) =3D=3D UNSPEC + && XINT (XEXP (op, 0), 1) =3D=3D UNSPEC_GOT")) +=20 +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-register-1.c b/g= cc/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=3Dthunk -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/g= cc/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=3Dthunk-inline -mindirect-branch-r= egister -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/g= cc/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=3Dthunk-extern -mindirect-branch-r= egister -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" } } */ +--=20 +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-thun= k-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=3DCVE-2017-5715 + +Patch copied from the 'retpoline-20180107' branch of upstream source repos= itory +(please add new / update existing patches when new 'retpoline-xxxxxxxx' br= anch +appears): + +http://git.infradead.org/users/dwmw2/gcc-retpoline.git + +From 4032162fb6d36e20091885d0558f91daaa0080d3 Mon Sep 17 00:00:00 2001 +From: "H.J. Lu" +Date: Mon, 27 Nov 2017 08:38:41 -0800 +Subject: [PATCH 07/17] Add -mindirect-branch=3Dthunk-extern + +Add -mindirect-branch=3Dthunk-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 + }; +=20 + #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_bra= nch_thunk) +=20 + EnumValue + Enum(indirect_branch) String(thunk-inline) Value(indirect_branch_thunk_in= line) ++ ++EnumValue ++Enum(indirect_branch) String(thunk-extern) Value(indirect_branch_thunk_ex= tern) +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=3Dthunk-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=3Dthunk-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=3Dthunk-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=3Dthunk-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=3Dthunk-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=3Dthunk-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=3Dthunk-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\]+\\(,%" { ta= rget { ! 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" } } */ +--=20 +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-thun= k-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=3DCVE-2017-5715 + +Patch copied from the 'retpoline-20180107' branch of upstream source repos= itory +(please add new / update existing patches when new 'retpoline-xxxxxxxx' br= anch +appears): + +http://git.infradead.org/users/dwmw2/gcc-retpoline.git + +From 7f4f2bf1688c81496107993080e68a29a24de702 Mon Sep 17 00:00:00 2001 +From: "H.J. Lu" +Date: Wed, 15 Nov 2017 11:20:31 -0800 +Subject: [PATCH 06/17] Add -mindirect-branch=3Dthunk-inline + +Add -mindirect-branch=3Dthunk-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 { +=20 + enum indirect_branch { + indirect_branch_keep, +- indirect_branch_thunk ++ indirect_branch_thunk, ++ indirect_branch_thunk_inline + }; +=20 + #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 =3D ix86_bnd_prefixed_insn_p (current_output_insn); +=20 +- bool need_thunk =3D ix86_indirect_branch =3D=3D indirect_branch_thunk; +- if (need_bnd_p) +- indirect_thunk_bnd_needed |=3D need_thunk; ++ if (ix86_indirect_branch !=3D indirect_branch_thunk_inline) ++ { ++ bool need_thunk =3D ix86_indirect_branch =3D=3D indirect_branch_thu= nk; ++ if (need_bnd_p) ++ indirect_thunk_bnd_needed |=3D need_thunk; ++ else ++ indirect_thunk_needed |=3D need_thunk; ++ indirect_thunk_name (thunk_name_buf, need_bnd_p); ++ thunk_name =3D thunk_name_buf; ++ } + else +- indirect_thunk_needed |=3D need_thunk; +- indirect_thunk_name (thunk_name, need_bnd_p); ++ thunk_name =3D NULL; +=20 + 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, +=20 + output_asm_insn (push_buf, &call_op); +=20 +- if (need_bnd_p) +- fprintf (asm_out_file, "\tbnd jmp\t%s\n", thunk_name); ++ if (thunk_name !=3D 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); +=20 + ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, indirectlabel2); +=20 +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_bran= ch_keep) +=20 + EnumValue + Enum(indirect_branch) String(thunk) Value(indirect_branch_thunk) ++ ++EnumValue ++Enum(indirect_branch) String(thunk-inline) Value(indirect_branch_thunk_in= line) +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=3Dthunk-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=3Dthunk-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=3Dthunk-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=3Dthunk-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=3Dthunk-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=3Dthunk-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=3Dthunk-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\]+\\(,%" { ta= rget { ! 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" } } */ +--=20 +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=3DCVE-2017-5715 + +Patch copied from the 'retpoline-20180107' branch of upstream source repos= itory +(please add new / update existing patches when new 'retpoline-xxxxxxxx' br= anch +appears): + +http://git.infradead.org/users/dwmw2/gcc-retpoline.git + +From 63024dad9c00f1613738fd766e2f0afd455b76d1 Mon Sep 17 00:00:00 2001 +From: "H.J. Lu" +Date: Wed, 1 Nov 2017 16:05:50 -0700 +Subject: [PATCH 04/17] Add -mindirect-branch=3Dthunk + +Add tests for -mindirect-branch=3Dthunk +--- + 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 */ + }; +=20 ++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 +=20 + 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); +=20 +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 +=20 ++static int indirectlabelno; ++static bool indirect_thunk_needed =3D false; ++static bool indirect_thunk_bnd_needed =3D 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 =3D 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] =3D stack_pointer_rtx; ++ xops[1] =3D 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 =3D build_decl (BUILTINS_LOCATION, FUNCTION_DECL, ++ get_identifier (name), ++ build_function_type_list (void_type_node, NULL_TREE)); ++ DECL_RESULT (decl) =3D build_decl (BUILTINS_LOCATION, RESULT_DECL, ++ NULL_TREE, void_type_node); ++ TREE_PUBLIC (decl) =3D 1; ++ TREE_STATIC (decl) =3D 1; ++ DECL_IGNORED_P (decl) =3D 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) =3D 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) =3D make_node (BLOCK); ++ current_function_decl =3D 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 =3D true; ++ first_function_block_is_cold =3D 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 =3D NULL; ++} ++ + static int pic_labels_used; +=20 + /* 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; +=20 ++ if (indirect_thunk_needed) ++ output_indirect_thunk_function (false); ++ if (indirect_thunk_bnd_needed) ++ output_indirect_thunk_function (true); ++ + for (regno =3D AX_REG; regno <=3D SP_REG; regno++) + { + char name[32]; +@@ -28452,12 +28596,132 @@ ix86_nopic_noplt_attribute_p (rtx call_op) + return false; + } +=20 ++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 =3D ix86_bnd_prefixed_insn_p (current_output_insn); ++ ++ bool need_thunk =3D ix86_indirect_branch =3D=3D indirect_branch_thunk; ++ if (need_bnd_p) ++ indirect_thunk_bnd_needed |=3D need_thunk; ++ else ++ indirect_thunk_needed |=3D 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 !=3D 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 =3D XEXP (call_op, 0); ++ if (ix86_decompose_address (addr, &parts) ++ && parts.base =3D=3D 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 =3D gen_rtx_MULT (Pmode, parts.index, ++ GEN_INT (parts.scale)); ++ addr =3D gen_rtx_PLUS (Pmode, stack_pointer_rtx, ++ addr); ++ } ++ else ++ addr =3D stack_pointer_rtx; ++ ++ rtx disp; ++ if (parts.disp !=3D NULL_RTX) ++ disp =3D plus_constant (Pmode, parts.disp, ++ UNITS_PER_WORD); ++ else ++ disp =3D GEN_INT (UNITS_PER_WORD); ++ ++ addr =3D gen_rtx_PLUS (Pmode, addr, disp); ++ call_op =3D 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 =3D=3D 0 ++ && ix86_indirect_branch !=3D indirect_branch_keep) ++ { ++ ix86_output_indirect_branch (call_op, "%0", true); ++ return ""; ++ } ++ else ++ return "%!jmp\t%A0"; ++} ++ + /* Output the assembly for a call instruction. */ +=20 + const char * + ix86_output_call_insn (rtx_insn *insn, rtx call_op) + { + bool direct_p =3D constant_call_address_operand (call_op, VOIDmode); ++ bool output_indirect_p ++ =3D (!TARGET_SEH ++ && ix86_indirect_branch !=3D indirect_branch_keep); + bool seh_nop_p =3D false; + const char *xasm; +=20 +@@ -28467,10 +28731,21 @@ ix86_output_call_insn (rtx_insn *insn, rtx call_= op) + { + if (ix86_nopic_noplt_attribute_p (call_op)) + { ++ direct_p =3D false; + if (TARGET_64BIT) +- xasm =3D "%!jmp\t{*%p0@GOTPCREL(%%rip)|[QWORD PTR %p0@GOTPCREL[rip]]}"; ++ { ++ if (output_indirect_p) ++ xasm =3D "{%p0@GOTPCREL(%%rip)|[QWORD PTR %p0@GOTPCREL[rip]]}"; ++ else ++ xasm =3D "%!jmp\t{*%p0@GOTPCREL(%%rip)|[QWORD PTR %p0@GOTPCREL[rip]= ]}"; ++ } + else +- xasm =3D "%!jmp\t{*%p0@GOT|[DWORD PTR %p0@GOT]}"; ++ { ++ if (output_indirect_p) ++ xasm =3D "{%p0@GOT|[DWORD PTR %p0@GOT]}"; ++ else ++ xasm =3D "%!jmp\t{*%p0@GOT|[DWORD PTR %p0@GOT]}"; ++ } + } + else + xasm =3D "%!jmp\t%P0"; +@@ -28480,9 +28755,17 @@ ix86_output_call_insn (rtx_insn *insn, rtx call_o= p) + else if (TARGET_SEH) + xasm =3D "%!rex.W jmp\t%A0"; + else +- xasm =3D "%!jmp\t%A0"; ++ { ++ if (output_indirect_p) ++ xasm =3D "%0"; ++ else ++ xasm =3D "%!jmp\t%A0"; ++ } +=20 +- 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 ""; + } +=20 +@@ -28520,18 +28803,37 @@ ix86_output_call_insn (rtx_insn *insn, rtx call_= op) + { + if (ix86_nopic_noplt_attribute_p (call_op)) + { ++ direct_p =3D false; + if (TARGET_64BIT) +- xasm =3D "%!call\t{*%p0@GOTPCREL(%%rip)|[QWORD PTR %p0@GOTPCREL[rip]= ]}"; ++ { ++ if (output_indirect_p) ++ xasm =3D "{%p0@GOTPCREL(%%rip)|[QWORD PTR %p0@GOTPCREL[rip]]}"; ++ else ++ xasm =3D "%!call\t{*%p0@GOTPCREL(%%rip)|[QWORD PTR %p0@GOTPCREL[rip]]}"; ++ } + else +- xasm =3D "%!call\t{*%p0@GOT|[DWORD PTR %p0@GOT]}"; ++ { ++ if (output_indirect_p) ++ xasm =3D "{%p0@GOT|[DWORD PTR %p0@GOT]}"; ++ else ++ xasm =3D "%!call\t{*%p0@GOT|[DWORD PTR %p0@GOT]}"; ++ } + } + else + xasm =3D "%!call\t%P0"; + } + else +- xasm =3D "%!call\t%A0"; ++ { ++ if (output_indirect_p) ++ xasm =3D "%0"; ++ else ++ xasm =3D "%!call\t%A0"; ++ } +=20 +- 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); +=20 + 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 con= taining ret bytes. + mgeneral-regs-only + Target Report RejectNegative Mask(GENERAL_REGS_ONLY) Var(ix86_target_flag= s) Save + Generate code which uses only the general registers. ++ ++mindirect-branch=3D ++Target Report RejectNegative Joined Enum(indirect_branch) Var(ix86_indire= ct_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=3D opti= on): ++ ++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=3D@var{type} -mstack-protector-guard=3D@var{guard} @gol +--mmitigate-rop -mgeneral-regs-only} ++-mmitigate-rop -mgeneral-regs-only -mindirect-branch=3D@var{choice}} +=20 + @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. +=20 ++@item -mindirect-branch=3D@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 +=20 + 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/testsu= ite/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=3Dthunk -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/testsu= ite/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=3Dthunk -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/testsu= ite/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=3Dthunk -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/testsu= ite/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=3Dthunk -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/testsu= ite/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=3Dthunk" } */ ++ ++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/testsu= ite/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=3Dthunk" } */ ++ ++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/testsu= ite/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=3Dthunk -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\]+\\(,%" { ta= rget { ! 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} } } */ +--=20 +2.15.1 + diff --git a/gnu/packages/patches/gcc-retpoline-Add-mno-indirect-branch-reg= ister-to-indirect-branch-.patch b/gnu/packages/patches/gcc-retpoline-Add-mn= o-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-t= o-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=3DCVE-2017-5715 + +Patch copied from the 'retpoline-20180107' branch of upstream source repos= itory +(please add new / update existing patches when new 'retpoline-xxxxxxxx' br= anch +appears): + +http://git.infradead.org/users/dwmw2/gcc-retpoline.git + +From 2c14ecf03978ce6c60e021a2b0d72778a5fe0982 Mon Sep 17 00:00:00 2001 +From: "H.J. Lu" +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/testsu= ite/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=3Dkeep -mindirect-branch=3Dthunk -= fno-pic" } */ ++/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=3Dke= ep -mindirect-branch=3Dthunk -fno-pic" } */ +=20 + typedef void (*dispatch_t)(long offset); +=20 +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-2.c b/gcc/testsu= ite/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=3Dkeep -mindirect-branch=3Dthunk -= fno-pic" } */ ++/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=3Dke= ep -mindirect-branch=3Dthunk -fno-pic" } */ +=20 + typedef void (*dispatch_t)(long offset); +=20 +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-3.c b/gcc/testsu= ite/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=3Dkeep -mindirect-branch=3Dthunk -= fno-pic" } */ ++/* { dg-options "-O2 -mno-indirect-branch-register -mno-indirect-branch-r= egister -mno-indirect-branch-register -mfunction-return=3Dkeep -mindirect-b= ranch=3Dthunk -fno-pic" } */ +=20 + typedef void (*dispatch_t)(long offset); +=20 +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-4.c b/gcc/testsu= ite/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=3Dkeep -mindirect-branch=3Dthunk -= fno-pic" } */ ++/* { dg-options "-O2 -mno-indirect-branch-register -mno-indirect-branch-r= egister -mno-indirect-branch-register -mfunction-return=3Dkeep -mindirect-b= ranch=3Dthunk -fno-pic" } */ +=20 + typedef void (*dispatch_t)(long offset); +=20 +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-5.c b/gcc/testsu= ite/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=3Dkeep -fpic -fno-plt -mindirect-b= ranch=3Dthunk" } */ ++/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=3Dke= ep -fpic -fno-plt -mindirect-branch=3Dthunk" } */ +=20 + extern void bar (void); +=20 +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-6.c b/gcc/testsu= ite/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=3Dkeep -fpic -fno-plt -mindirect-b= ranch=3Dthunk" } */ ++/* { dg-options "-O2 -mno-indirect-branch-register -mno-indirect-branch-r= egister -mno-indirect-branch-register -mfunction-return=3Dkeep -fpic -fno-p= lt -mindirect-branch=3Dthunk" } */ +=20 + extern void bar (void); +=20 +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-7.c b/gcc/testsu= ite/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=3Dkeep -mindirect-branch=3Dthunk -= fno-pic" } */ ++/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=3Dke= ep -mindirect-branch=3Dthunk -fno-pic" } */ +=20 + void func0 (void); + void func1 (void); +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-1.c b/gcc/t= estsuite/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=3Dkeep -fno-pic" } */ ++/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=3Dke= ep -fno-pic" } */ +=20 + typedef void (*dispatch_t)(long offset); +=20 +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-2.c b/gcc/t= estsuite/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=3Dkeep -fno-pic" } */ ++/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=3Dke= ep -fno-pic" } */ +=20 + typedef void (*dispatch_t)(long offset); +=20 +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-3.c b/gcc/t= estsuite/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=3Dkeep -fno-pic" } */ ++/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=3Dke= ep -fno-pic" } */ +=20 + typedef void (*dispatch_t)(long offset); +=20 +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-4.c b/gcc/t= estsuite/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=3Dkeep -fno-pic" } */ ++/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=3Dke= ep -fno-pic" } */ +=20 + typedef void (*dispatch_t)(long offset); +=20 +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-5.c b/gcc/t= estsuite/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=3Dkeep -fno-pic" } */ ++/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=3Dke= ep -fno-pic" } */ +=20 + typedef void (*dispatch_t)(long offset); +=20 +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-6.c b/gcc/t= estsuite/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=3Dkeep -fno-pic" } */ ++/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=3Dke= ep -fno-pic" } */ +=20 + typedef void (*dispatch_t)(long offset); +=20 +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-7.c b/gcc/t= estsuite/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=3Dkeep -fno-pic" } */ ++/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=3Dke= ep -fno-pic" } */ +=20 + void func0 (void); + void func1 (void); +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-1.c b/gcc/te= stsuite/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=3Dkeep -mindirect-branch=3Dthunk -= fcheck-pointer-bounds -mmpx -fno-pic" } */ ++/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=3Dke= ep -mindirect-branch=3Dthunk -fcheck-pointer-bounds -mmpx -fno-pic" } */ +=20 + void (*dispatch) (char *); + char buf[10]; +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-2.c b/gcc/te= stsuite/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=3Dkeep -mindirect-branch=3Dthunk -= fcheck-pointer-bounds -mmpx -fno-pic" } */ ++/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=3Dke= ep -mindirect-branch=3Dthunk -fcheck-pointer-bounds -mmpx -fno-pic" } */ +=20 + void (*dispatch) (char *); + char buf[10]; +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-3.c b/gcc/te= stsuite/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=3Dkeep -mindirect-branch=3Dthunk -= fcheck-pointer-bounds -mmpx -fpic -fno-plt" } */ ++/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=3Dke= ep -mindirect-branch=3Dthunk -fcheck-pointer-bounds -mmpx -fpic -fno-plt" }= */ +=20 + void bar (char *); + char buf[10]; +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-4.c b/gcc/te= stsuite/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=3Dkeep -mindirect-branch=3Dthunk -= fcheck-pointer-bounds -mmpx -fpic -fno-plt" } */ ++/* { dg-options "-O2 -mno-indirect-branch-register -mno-indirect-branch-r= egister -mfunction-return=3Dkeep -mindirect-branch=3Dthunk -fcheck-pointer-= bounds -mmpx -fpic -fno-plt" } */ +=20 + 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=3Dkeep -mindirect-branch=3Dthunk-e= xtern -fno-pic" } */ ++/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=3Dke= ep -mindirect-branch=3Dthunk-extern -fno-pic" } */ +=20 + typedef void (*dispatch_t)(long offset); +=20 +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=3Dkeep -mindirect-branch=3Dthunk-e= xtern -fno-pic" } */ ++/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=3Dke= ep -mindirect-branch=3Dthunk-extern -fno-pic" } */ +=20 + typedef void (*dispatch_t)(long offset); +=20 +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=3Dkeep -mindirect-branch=3Dthunk-e= xtern -fno-pic" } */ ++/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=3Dke= ep -mindirect-branch=3Dthunk-extern -fno-pic" } */ +=20 + typedef void (*dispatch_t)(long offset); +=20 +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=3Dkeep -mindirect-branch=3Dthunk-e= xtern -fno-pic" } */ ++/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=3Dke= ep -mindirect-branch=3Dthunk-extern -fno-pic" } */ +=20 + typedef void (*dispatch_t)(long offset); +=20 +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=3Dkeep -fpic -fno-plt -mindirect-b= ranch=3Dthunk-extern" } */ ++/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=3Dke= ep -fpic -fno-plt -mindirect-branch=3Dthunk-extern" } */ +=20 + extern void bar (void); +=20 +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=3Dkeep -fpic -fno-plt -mindirect-b= ranch=3Dthunk-extern" } */ ++/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=3Dke= ep -fpic -fno-plt -mindirect-branch=3Dthunk-extern" } */ +=20 + extern void bar (void); +=20 +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=3Dkeep -mindirect-branch=3Dthunk-e= xtern -fno-pic" } */ ++/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=3Dke= ep -mindirect-branch=3Dthunk-extern -fno-pic" } */ +=20 + 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=3Dkeep -mindirect-branch=3Dthunk-i= nline -fno-pic" } */ ++/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=3Dke= ep -mindirect-branch=3Dthunk-inline -fno-pic" } */ +=20 + typedef void (*dispatch_t)(long offset); +=20 +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=3Dkeep -mindirect-branch=3Dthunk-i= nline -fno-pic" } */ ++/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=3Dke= ep -mindirect-branch=3Dthunk-inline -fno-pic" } */ +=20 + typedef void (*dispatch_t)(long offset); +=20 +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=3Dkeep -mindirect-branch=3Dthunk-i= nline -fno-pic" } */ ++/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=3Dke= ep -mindirect-branch=3Dthunk-inline -fno-pic" } */ +=20 + typedef void (*dispatch_t)(long offset); +=20 +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=3Dkeep -mindirect-branch=3Dthunk-i= nline -fno-pic" } */ ++/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=3Dke= ep -mindirect-branch=3Dthunk-inline -fno-pic" } */ +=20 + typedef void (*dispatch_t)(long offset); +=20 +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=3Dkeep -fpic -fno-plt -mindirect-b= ranch=3Dthunk-inline" } */ ++/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=3Dke= ep -fpic -fno-plt -mindirect-branch=3Dthunk-inline" } */ +=20 + extern void bar (void); +=20 +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=3Dkeep -fpic -fno-plt -mindirect-b= ranch=3Dthunk-inline" } */ ++/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=3Dke= ep -fpic -fno-plt -mindirect-branch=3Dthunk-inline" } */ +=20 + extern void bar (void); +=20 +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=3Dkeep -mindirect-branch=3Dthunk-i= nline -fno-pic" } */ ++/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=3Dke= ep -mindirect-branch=3Dthunk-inline -fno-pic" } */ +=20 + void func0 (void); + void func1 (void); +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-loop-1.c b/gcc/t= estsuite/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=3Dthunk -mindirect-branch-loop=3Dp= ause -fno-pic" } */ ++/* { dg-options "-O2 -mno-indirect-branch-register -mindirect-branch=3Dth= unk -mindirect-branch-loop=3Dpause -fno-pic" } */ +=20 + typedef void (*dispatch_t)(long offset); +=20 +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-loop-2.c b/gcc/t= estsuite/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=3Dthunk -mindirect-branch-loop=3Dn= op -fno-pic" } */ ++/* { dg-options "-O2 -mno-indirect-branch-register -mindirect-branch=3Dth= unk -mindirect-branch-loop=3Dnop -fno-pic" } */ +=20 + typedef void (*dispatch_t)(long offset); +=20 +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-loop-3.c b/gcc/t= estsuite/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=3Dthunk -mindirect-branch-loop=3Dl= fence -fno-pic" } */ ++/* { dg-options "-O2 -mno-indirect-branch-register -mindirect-branch=3Dth= unk -mindirect-branch-loop=3Dlfence -fno-pic" } */ +=20 + typedef void (*dispatch_t)(long offset); +=20 +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-loop-4.c b/gcc/t= estsuite/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=3Dthunk-inline -mindirect-branch-l= oop=3Dpause -fno-pic" } */ ++/* { dg-options "-O2 -mno-indirect-branch-register -mindirect-branch=3Dth= unk-inline -mindirect-branch-loop=3Dpause -fno-pic" } */ +=20 + typedef void (*dispatch_t)(long offset); +=20 +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-loop-5.c b/gcc/t= estsuite/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=3Dthunk-extern -mindirect-branch-l= oop=3Dpause -fno-pic" } */ ++/* { dg-options "-O2 -mno-indirect-branch-register -mindirect-branch=3Dth= unk-extern -mindirect-branch-loop=3Dpause -fno-pic" } */ +=20 + typedef void (*dispatch_t)(long offset); +=20 +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=3Dthunk-inline -mindirect-branch= =3Dthunk -fno-pic" } */ ++/* { dg-options "-O2 -mno-indirect-branch-register -mno-indirect-branch-r= egister -mfunction-return=3Dthunk-inline -mindirect-branch=3Dthunk -fno-pic= " } */ +=20 + extern void (*bar) (void); +=20 +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=3Dthunk-extern -mindirect-branch= =3Dthunk -fno-pic" } */ ++/* { dg-options "-O2 -mno-indirect-branch-register -mno-indirect-branch-r= egister -mno-indirect-branch-register -mno-indirect-branch-register -mfunct= ion-return=3Dthunk-extern -mindirect-branch=3Dthunk -fno-pic" } */ +=20 + extern void (*bar) (void); +=20 +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=3Dkeep -mindirect-branch=3Dthunk -= fno-pic" } */ ++/* { dg-options "-O2 -mno-indirect-branch-register -mno-indirect-branch-r= egister -mno-indirect-branch-register -mno-indirect-branch-register -mfunct= ion-return=3Dkeep -mindirect-branch=3Dthunk -fno-pic" } */ +=20 + extern void (*bar) (void); +=20 +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=3Dkeep -mindirect-branch=3Dthunk-i= nline -fno-pic" } */ ++/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=3Dke= ep -mindirect-branch=3Dthunk-inline -fno-pic" } */ +=20 + 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=3Dkeep -mindirect-branch=3Dthunk-e= xtern -fno-pic" } */ ++/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=3Dke= ep -mindirect-branch=3Dthunk-extern -fno-pic" } */ +=20 + extern void (*bar) (void); +=20 +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=3Dkeep -mindirect-branch=3Dkeep -f= no-pic" } */ ++/* { dg-options "-O2 -mno-indirect-branch-register -mno-indirect-branch-r= egister -mno-indirect-branch-register -mno-indirect-branch-register -mfunct= ion-return=3Dkeep -mindirect-branch=3Dkeep -fno-pic" } */ +=20 + extern void (*bar) (void); +=20 +diff --git a/gcc/testsuite/gcc.target/i386/ret-thunk-9.c b/gcc/testsuite/g= cc.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=3Dthunk -mindirect-branch=3Dthunk = -fno-pic" } */ ++/* { dg-options "-O2 -mno-indirect-branch-register -mno-indirect-branch-r= egister -mfunction-return=3Dthunk -mindirect-branch=3Dthunk -fno-pic" } */ +=20 + extern void (*bar) (void); +=20 +--=20 +2.15.1 + diff --git a/gnu/packages/patches/gcc-retpoline-Add-tests-for-mindirect-bra= nch-thunk-fcheck-pointer-.patch b/gnu/packages/patches/gcc-retpoline-Add-te= sts-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-thu= nk-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=3DCVE-2017-5715 + +Patch copied from the 'retpoline-20180107' branch of upstream source repos= itory +(please add new / update existing patches when new 'retpoline-xxxxxxxx' br= anch +appears): + +http://git.infradead.org/users/dwmw2/gcc-retpoline.git + +From ece041bc3083aabd00fab9de5ba409fbd7dcad8c Mon Sep 17 00:00:00 2001 +From: "H.J. Lu" +Date: Mon, 4 Dec 2017 12:58:20 -0800 +Subject: [PATCH 05/17] Add tests for -mindirect-branch=3Dthunk + -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/te= stsuite/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=3Dthunk -fcheck-pointer-bounds -mm= px -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/te= stsuite/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=3Dthunk -fcheck-pointer-bounds -mm= px -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/te= stsuite/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=3Dthunk -fcheck-pointer-bounds -mm= px -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/te= stsuite/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=3Dthunk -fcheck-pointer-bounds -mm= px -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} } } */ +--=20 +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-indire= ct-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=3DCVE-2017-5715 + +Patch copied from the 'retpoline-20180107' branch of upstream source repos= itory +(please add new / update existing patches when new 'retpoline-xxxxxxxx' br= anch +appears): + +http://git.infradead.org/users/dwmw2/gcc-retpoline.git + +From f96e28553b0f2253184441f22852d76976e19968 Mon Sep 17 00:00:00 2001 +From: "H.J. Lu" +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 +=20 + 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); + } +=20 +-/* 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. */ +=20 + 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 =3D=3D 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, + } +=20 + const char * +-ix86_output_indirect_jmp (rtx call_op) ++ix86_output_indirect_jmp (rtx call_op, bool ret_p) + { +- if (ix86_red_zone_size =3D=3D 0 +- && cfun->machine->indirect_branch_type !=3D indirect_branch_keep) ++ if (cfun->machine->indirect_branch_type !=3D 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 !=3D 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; +=20 ++ /* 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; +=20 +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] =3D convert_memory_address (word_mode, operands[0]); ++ cfun->machine->has_local_indirect_jump =3D true; + }) +=20 + (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 @@ +=20 + if (TARGET_X32 || ix86_indirect_branch_thunk_register) + operands[0] =3D convert_memory_address (word_mode, operands[0]); ++ cfun->machine->has_local_indirect_jump =3D true; + }) +=20 + (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")]) +--=20 +2.15.1 + diff --git a/gnu/packages/patches/gcc-retpoline-Rename-thunks-to-__x86_indi= rect_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_th= unk_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=3DCVE-2017-5715 + +Patch copied from the 'retpoline-20180107' branch of upstream source repos= itory +(please add new / update existing patches when new 'retpoline-xxxxxxxx' br= anch +appears): + +http://git.infradead.org/users/dwmw2/gcc-retpoline.git + +From a072725899c551d9f3f06f3595e2a49748ab0187 Mon Sep 17 00:00:00 2001 +From: David Woodhouse +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, b= ool need_bnd_p, + reg_prefix =3D TARGET_64BIT ? "r" : "e"; + else + reg_prefix =3D ""; +- 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 =3D 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, i= nt regno) + char name[32]; + tree decl; +=20 +- /* 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 =3D build_decl (BUILTINS_LOCATION, FUNCTION_DECL, + get_identifier (name), +@@ -12165,7 +12165,7 @@ output_indirect_thunk_function (bool need_bnd_p, i= nt regno) +=20 + 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]; +=20 + indirect_thunk_name (alias, regno, need_bnd_p, true); +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-1.c b/gcc/testsu= ite/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) + } +=20 + /* { 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/testsu= ite/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) + } +=20 + /* { 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/testsu= ite/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) + } +=20 + /* { 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/testsu= ite/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) + } +=20 + /* { 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/testsu= ite/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) + } +=20 + /* { 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/testsu= ite/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) + } +=20 + /* { 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/testsu= ite/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) + } +=20 + /* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*\.L\[0-9\]+\\(,%" { ta= rget { ! 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/t= estsuite/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) + } +=20 + /* { 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/t= estsuite/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) + } +=20 + /* { 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/t= estsuite/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/t= estsuite/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/t= estsuite/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 { ! x= 32 } } } } */ + /* { 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/t= estsuite/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 { ! x= 32 } } } } */ + /* { 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/t= estsuite/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) + } +=20 + /* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*\.L\[0-9\]+\\(,%" { ta= rget { ! 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/t= estsuite/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) + } + } +=20 +-/* { 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/te= stsuite/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) +=20 + /* { 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/te= stsuite/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) +=20 + /* { 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/te= stsuite/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) + } +=20 + /* { 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/te= stsuite/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) + } +=20 + /* { 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) + } +=20 + /* { 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) + } +=20 + /* { 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) + } +=20 + /* { 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 { ! x= 32 } } } } */ + /* { 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) + } +=20 + /* { 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 { ! x= 32 } } } } */ + /* { 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) + } +=20 + /* { 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) + } +=20 + /* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*\.L\[0-9\]+\\(,%" { ta= rget { ! 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/t= estsuite/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) + } +=20 + /* { 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/t= estsuite/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) + } +=20 + /* { 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/t= estsuite/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) + } +=20 + /* { 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/t= estsuite/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/t= estsuite/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) + } +=20 + /* { 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/g= cc/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); + } +=20 +-/* { 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/g= cc/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/g= cc/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); + } +=20 +-/* { 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/g= cc.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) + { + } +=20 +-/* { 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) +=20 + /* { 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 { ! x3= 2 } } } } */ +-/* { 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; + } +=20 +-/* { 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 { ! x3= 2 } } } } */ +-/* { 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; + } +=20 +-/* { 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; + } +=20 +-/* { 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 { ! x3= 2 } } } } */ + /* { 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) + } +=20 + /* { 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 { ! x3= 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\]*__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; + } +=20 +-/* { 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 { ! x3= 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\]*__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; + } +=20 +-/* { 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/g= cc.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/g= cc.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) + { + } +=20 +-/* { 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/g= cc.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) + { + } +=20 +-/* { 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/g= cc.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) + { + } +=20 +-/* { 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/g= cc.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/g= cc.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) + { + } +=20 +-/* { 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/g= cc.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) + { + } +=20 +-/* { 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/g= cc.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; + } +=20 +-/* { 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 { ! x3= 2 } } } } */ +-/* { 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 } } } = */ +--=20 +2.15.1 + diff --git a/gnu/packages/patches/gcc-retpoline-Use-__x86.indirect_thunk.re= g-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-i= ndirect-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=3DCVE-2017-5715 + +Patch copied from the 'retpoline-20180107' branch of upstream source repos= itory +(please add new / update existing patches when new 'retpoline-xxxxxxxx' br= anch +appears): + +http://git.infradead.org/users/dwmw2/gcc-retpoline.git + +From e4e33b44a49eaa102806589ce12f021ab6a1e5f1 Mon Sep 17 00:00:00 2001 +From: "H.J. Lu" +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 =3D false; + static bool indirect_thunk_bnd_needed =3D false; +=20 ++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 =3D false; + /* Fills in the label name that should be used for the indirect thunk. */ +=20 + 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 =3D need_bnd_p ? "_bnd" : ""; +- sprintf (name, "__x86.indirect_thunk%s", bnd); ++ if (regno >=3D 0) ++ { ++ const char *reg_prefix; ++ if (LEGACY_INT_REGNO_P (regno)) ++ reg_prefix =3D TARGET_64BIT ? "r" : "e"; ++ else ++ reg_prefix =3D ""; ++ 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 >=3D 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); ++ } + } + } +=20 + 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) +=20 + ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, indirectlabel2); +=20 +- /* LEA. */ +- rtx xops[2]; +- xops[0] =3D stack_pointer_rtx; +- xops[1] =3D plus_constant (Pmode, stack_pointer_rtx, UNITS_PER_WORD); +- output_asm_insn ("lea\t{%E1, %0|%0, %E1}", xops); ++ if (regno >=3D 0) ++ { ++ /* MOV. */ ++ rtx xops[2]; ++ xops[0] =3D gen_rtx_MEM (word_mode, stack_pointer_rtx); ++ xops[1] =3D gen_rtx_REG (word_mode, regno); ++ output_asm_insn ("mov\t{%1, %0|%0, %1}", xops); ++ } ++ else ++ { ++ /* LEA. */ ++ rtx xops[2]; ++ xops[0] =3D stack_pointer_rtx; ++ xops[1] =3D plus_constant (Pmode, stack_pointer_rtx, UNITS_PER_WORD= ); ++ output_asm_insn ("lea\t{%E1, %0|%0, %E1}", xops); ++ } +=20 + if (need_bnd_p) + fputs ("\tbnd ret\n", asm_out_file); +@@ -12015,12 +12050,13 @@ output_indirect_thunk (bool need_bnd_p) + } +=20 + 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; +=20 +- indirect_thunk_name (name, need_bnd_p); ++ /* Create __x86.indirect_thunk/__x86.indirect_thunk_bnd. */ ++ indirect_thunk_name (name, regno, need_bnd_p); + decl =3D 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); +=20 +- output_indirect_thunk (need_bnd_p); ++ output_indirect_thunk (need_bnd_p, regno); +=20 + final_end_function (); + init_insn_lengths (); +@@ -12110,15 +12146,31 @@ ix86_code_end (void) + int regno; +=20 + 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 =3D FIRST_REX_INT_REG; regno <=3D LAST_REX_INT_REG; regno++) ++ { ++ int i =3D 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); ++ } +=20 + for (regno =3D AX_REG; regno <=3D SP_REG; regno++) + { + char name[32]; + tree decl; +=20 ++ 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; +=20 +@@ -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 =3D ix86_bnd_prefixed_insn_p (current_output_insn); ++ int regno; ++ ++ if (REG_P (call_op)) ++ regno =3D REGNO (call_op); ++ else ++ regno =3D -1; +=20 + if (cfun->machine->indirect_branch_type + !=3D indirect_branch_thunk_inline) + { +- bool need_thunk +- =3D cfun->machine->indirect_branch_type =3D=3D indirect_branch_thunk; +- if (need_bnd_p) +- indirect_thunk_bnd_needed |=3D need_thunk; +- else +- indirect_thunk_needed |=3D need_thunk; +- indirect_thunk_name (thunk_name_buf, need_bnd_p); ++ if (cfun->machine->indirect_branch_type =3D=3D indirect_branch_thun= k) ++ { ++ if (regno >=3D 0) ++ { ++ int i =3D regno; ++ if (i >=3D FIRST_REX_INT_REG) ++ i -=3D (FIRST_REX_INT_REG - LAST_INT_REG - 1); ++ if (need_bnd_p) ++ indirect_thunks_bnd_used |=3D 1 << i; ++ else ++ indirect_thunks_used |=3D 1 << i; ++ } ++ else ++ { ++ if (need_bnd_p) ++ indirect_thunk_bnd_needed =3D true; ++ else ++ indirect_thunk_needed =3D true; ++ } ++ } ++ indirect_thunk_name (thunk_name_buf, regno, need_bnd_p); + thunk_name =3D thunk_name_buf; + } + else +@@ -28660,7 +28732,8 @@ ix86_output_indirect_branch (rtx call_op, const ch= ar *xasm, +=20 + if (sibcall_p) + { +- output_asm_insn (push_buf, &call_op); ++ if (regno < 0) ++ output_asm_insn (push_buf, &call_op); + if (thunk_name !=3D 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 >=3D 0 && thunk_name !=3D 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]; +=20 +@@ -28725,7 +28807,8 @@ ix86_output_indirect_branch (rtx call_op, const ch= ar *xasm, + } + } +=20 +- output_asm_insn (push_buf, &call_op); ++ if (regno < 0) ++ output_asm_insn (push_buf, &call_op); +=20 + if (thunk_name !=3D NULL) + { +@@ -28735,7 +28818,7 @@ ix86_output_indirect_branch (rtx call_op, const ch= ar *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); +=20 + ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, indirectlabel2); +=20 +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-1.c b/gcc/testsu= ite/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) + } +=20 + /* { 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/testsu= ite/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) + } +=20 + /* { 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/testsu= ite/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) + } +=20 + /* { 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/testsu= ite/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) + } +=20 + /* { 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/testsu= ite/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) + } +=20 + /* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*\.L\[0-9\]+\\(,%" { ta= rget { ! 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/t= estsuite/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) + } +=20 + /* { 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/t= estsuite/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) + } +=20 + /* { 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/t= estsuite/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) + } +=20 + /* { 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/t= estsuite/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) + } +=20 + /* { 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/t= estsuite/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) + } +=20 + /* { 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 { ! x= 32 } } } } */ ++/* { 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/t= estsuite/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) + } +=20 + /* { 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 { ! x= 32 } } } } */ ++/* { 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/t= estsuite/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) + } +=20 + /* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*\.L\[0-9\]+\\(,%" { ta= rget { ! 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) + } +=20 + /* { 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) + } +=20 + /* { 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) + } +=20 + /* { 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 { ! x= 32 } } } } */ ++/* { 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) + } +=20 + /* { 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 { ! x= 32 } } } } */ ++/* { 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) + } +=20 + /* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*\.L\[0-9\]+\\(,%" { ta= rget { ! 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) + } +=20 + /* { 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) + } +=20 + /* { 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) + } +=20 + /* { 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) + } +=20 + /* { 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) + } +=20 + /* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*\.L\[0-9\]+\\(,%" { ta= rget { ! 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" } } */ +--=20 +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-op= erand-modifier.patch new file mode 100644 index 000000000..1996a1dfe --- /dev/null +++ b/gnu/packages/patches/gcc-retpoline-i386-Add-V-register-operand-modifi= er.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=3DCVE-2017-5715 + +Patch copied from the 'retpoline-20180107' branch of upstream source repos= itory +(please add new / update existing patches when new 'retpoline-xxxxxxxx' br= anch +appears): + +http://git.infradead.org/users/dwmw2/gcc-retpoline.git + +From f83391fb22471a2f1c330e2e78f64630d64f497d Mon Sep 17 00:00:00 2001 +From: "H.J. Lu" +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_mo= de 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 %. + */ +=20 + void +@@ -17896,7 +17897,7 @@ print_reg (rtx x, int code, FILE *file) + unsigned int regno; + bool duplicated; +=20 +- if (ASSEMBLER_DIALECT =3D=3D ASM_ATT) ++ if (ASSEMBLER_DIALECT =3D=3D ASM_ATT && code !=3D 'V') + putc ('%', file); +=20 + if (x =3D=3D 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; +=20 + case 's': +--=20 +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-M= ore-use-reference-of-struct-ix86_frame-to-avoi.patch new file mode 100644 index 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=3DCVE-2017-5715 + +Patch copied from the 'retpoline-20180107' branch of upstream source repos= itory +(please add new / update existing patches when new 'retpoline-xxxxxxxx' br= anch +appears): + +http://git.infradead.org/users/dwmw2/gcc-retpoline.git + +From d96784e4a7355aaab68dec62f31a97bd10714064 Mon Sep 17 00:00:00 2001 +From: "H.J. Lu" +Date: Tue, 28 Nov 2017 10:26:35 -0800 +Subject: [PATCH 03/17] i386: More use reference of struct ix86_frame to av= oid + 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 =3D 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 =3D true; +=20 + ix86_compute_frame_layout (); +- frame =3D m->frame; ++ struct ix86_frame &frame =3D cfun->machine->frame; +=20 + if (!TARGET_64BIT && ix86_function_ms_hook_prologue (current_function_d= ecl)) + { +@@ -14343,13 +14342,12 @@ ix86_expand_epilogue (int style) + { + struct machine_function *m =3D cfun->machine; + struct machine_frame_state frame_state_save =3D m->fs; +- struct ix86_frame frame; + bool restore_regs_via_mov; + bool using_drap; +=20 + ix86_finalize_stack_realign_flags (); + ix86_compute_frame_layout (); +- frame =3D m->frame; ++ struct ix86_frame &frame =3D cfun->machine->frame; +=20 + m->fs.sp_valid =3D (!frame_pointer_needed + || (crtl->sp_is_unchanging +--=20 +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-s= truct-ix86_frame-to-machine_function.patch new file mode 100644 index 000000000..908e3cd83 --- /dev/null +++ b/gnu/packages/patches/gcc-retpoline-i386-Move-struct-ix86_frame-to-mac= hine_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=3DCVE-2017-5715 + +Patch copied from the 'retpoline-20180107' branch of upstream source repos= itory +(please add new / update existing patches when new 'retpoline-xxxxxxxx' br= anch +appears): + +http://git.infradead.org/users/dwmw2/gcc-retpoline.git + +From 85743811dfa4eb648edbbb637632ac53182b6e05 Mon Sep 17 00:00:00 2001 +From: "H.J. Lu" +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; + }; +=20 +-/* 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] | =3D 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; +=20 +@@ -2579,7 +2532,7 @@ static unsigned int ix86_function_arg_boundary (mach= ine_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 >=3D 32768) + return 0; +=20 +- ix86_compute_frame_layout (&frame); ++ ix86_compute_frame_layout (); ++ frame =3D cfun->machine->frame; + return (frame.stack_pointer_offset =3D=3D UNITS_PER_WORD + && (frame.nregs + frame.nsseregs) =3D=3D 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 =3D cfun->machine->frame; +=20 + if (from =3D=3D ARG_POINTER_REGNUM && to =3D=3D HARD_FRAME_POINTER_REGN= UM) + 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. = */ +=20 + static void +-ix86_compute_frame_layout (struct ix86_frame *frame) ++ix86_compute_frame_layout (void) + { ++ struct ix86_frame *frame =3D &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 =3D INCOMING_FRAME_SP_OFFSET; + m->fs.sp_valid =3D true; +=20 +- ix86_compute_frame_layout (&frame); ++ ix86_compute_frame_layout (); ++ frame =3D m->frame; +=20 + if (!TARGET_64BIT && ix86_function_ms_hook_prologue (current_function_d= ecl)) + { +@@ -14394,7 +14350,8 @@ ix86_expand_epilogue (int style) + bool using_drap; +=20 + ix86_finalize_stack_realign_flags (); +- ix86_compute_frame_layout (&frame); ++ ix86_compute_frame_layout (); ++ frame =3D m->frame; +=20 + m->fs.sp_valid =3D (!frame_pointer_needed + || (crtl->sp_is_unchanging +@@ -14904,7 +14861,8 @@ ix86_expand_split_stack_prologue (void) + gcc_assert (flag_split_stack && reload_completed); +=20 + ix86_finalize_stack_realign_flags (); +- ix86_compute_frame_layout (&frame); ++ ix86_compute_frame_layout (); ++ frame =3D cfun->machine->frame; + allocate =3D frame.stack_pointer_offset - INCOMING_FRAME_SP_OFFSET; +=20 + /* 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] | =3D 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. = */ +=20 +-#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]; +=20 ++ /* 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) +=20 + /* Control behavior of x86_file_start. */ + #define X86_FILE_START_VERSION_DIRECTIVE false +--=20 +2.15.1 + diff --git a/gnu/packages/patches/gcc-retpoline-i386-Use-reference-of-struc= t-ix86_frame-to-avoid-cop.patch b/gnu/packages/patches/gcc-retpoline-i386-U= se-reference-of-struct-ix86_frame-to-avoid-cop.patch new file mode 100644 index 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=3DCVE-2017-5715 + +Patch copied from the 'retpoline-20180107' branch of upstream source repos= itory +(please add new / update existing patches when new 'retpoline-xxxxxxxx' br= anch +appears): + +http://git.infradead.org/users/dwmw2/gcc-retpoline.git + +From 0b1769bdce27304a6a91bec234f47f102a2603d5 Mon Sep 17 00:00:00 2001 +From: hjl +Date: Mon, 6 Nov 2017 23:04:15 +0000 +Subject: [PATCH 02/17] i386: Use reference of struct ix86_frame to avoid c= opy + +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; +=20 + ix86_compute_frame_layout (); +- frame =3D cfun->machine->frame; ++ struct ix86_frame &frame =3D cfun->machine->frame; + return (frame.stack_pointer_offset =3D=3D UNITS_PER_WORD + && (frame.nregs + frame.nsseregs) =3D=3D 0); + } +@@ -12333,7 +12331,7 @@ HOST_WIDE_INT + ix86_initial_elimination_offset (int from, int to) + { + ix86_compute_frame_layout (); +- struct ix86_frame frame =3D cfun->machine->frame; ++ struct ix86_frame &frame =3D cfun->machine->frame; +=20 + if (from =3D=3D ARG_POINTER_REGNUM && to =3D=3D HARD_FRAME_POINTER_REGN= UM) + 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) +=20 + ix86_finalize_stack_realign_flags (); + ix86_compute_frame_layout (); +- frame =3D cfun->machine->frame; ++ struct ix86_frame &frame =3D cfun->machine->frame; + allocate =3D frame.stack_pointer_offset - INCOMING_FRAME_SP_OFFSET; +=20 + /* This is the label we will branch to if we have enough stack +--=20 +2.15.1 + --=20 2.15.1 --=-=-= Content-Type: text/plain Cheers, Alex --=-=-=-- From debbugs-submit-bounces@debbugs.gnu.org Sun Jan 14 11:30:37 2018 Received: (at control) by debbugs.gnu.org; 14 Jan 2018 16:30:37 +0000 Received: from localhost ([127.0.0.1]:56179 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1ealB7-0005Wj-JK for submit@debbugs.gnu.org; Sun, 14 Jan 2018 11:30:37 -0500 Received: from mail-pf0-f172.google.com ([209.85.192.172]:40530) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1ealB3-0005WV-VE for control@debbugs.gnu.org; Sun, 14 Jan 2018 11:30:34 -0500 Received: by mail-pf0-f172.google.com with SMTP id i66so6993596pfd.7 for ; Sun, 14 Jan 2018 08:30:33 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:subject:date:message-id:user-agent:mime-version; bh=qywxP96CoVzdN5r8OYwVf8HHh4zWlsFSPXNfXnYwfYM=; b=iUuTzQ5ghW+ygxAx882SuTCfYM8qbw/4RikVAwTq/yabv4TaeMlTZtq3uv2G4R8kyp JJkzbmPMovZ+0cZp7SWwlHZTSX9f4Gq3mrVawNx7bZeJ2NaquYjRBYw6MnOfVXxCImCw kKcxBIGrtSqu6FAiBZKIeXx1KAt6G2HiLx6uhCwFGwWQ7om/MGjnoBkDzRawh7lcivqr oG4WUlqkdCRRGrxAccm6Tc0BRzgV18wzR802ur418S3znShgqbL325N2O3C5WnwXy6H4 JFN2M+9XTeg3raoZUB66aU2G793nF/I4s17evT35E59b2Ouck3YcWWuuzR5AjYMVeQhA 9N1Q== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:subject:date:message-id:user-agent :mime-version; bh=qywxP96CoVzdN5r8OYwVf8HHh4zWlsFSPXNfXnYwfYM=; b=uHUng2qRfhQFSgIJu4ffh52k4Fm19r3JTBRnD46YSR0SWqdybBxCZRDVF//tgZjsSV MjA7raE9qDEIj9lXg6xJ3w4gbiua1T9A20nG2elezaix1aDQosefK32+5JNnr+UVdyxn Hdk1p2kKbE2Imp+i5nbJixY75QPPmdqTnmDQPtmcUG4btVeD/uplHAAx4UPWpTCIxCX2 /cJB+I9aqaVFt90zkFX3IDV2gE1IQdyEed79AAQRLswIQPFtZZDbKnM1Jd2wTSxektIc elGELImIVxa55H6OPsZqkWHLLP/1W9nsH2MPd/Jua9efXYpbaqn3hCC4fE91EDvhXJE+ mWKQ== X-Gm-Message-State: AKGB3mLYPXtcjgl4QeSEwnxhK0jLfTXfYy0LqBhxUbC7wxfyCcat8Dfy 4CjP6B+h8762vJr57ocpkws= X-Google-Smtp-Source: ACJfBouJHHagh39Os1Hk5vc37RVjm5PPZ7v1STNL61UxjEH6Cu8tgjByqIA/ZMt2ZCSKHQICnoAZ0Q== X-Received: by 10.101.100.144 with SMTP id e16mr24640767pgv.26.1515947428268; Sun, 14 Jan 2018 08:30:28 -0800 (PST) Received: from debian (1-64-83-091.static.netvigator.com. [1.64.83.91]) by smtp.gmail.com with ESMTPSA id x15sm49165509pfh.27.2018.01.14.08.30.26 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Sun, 14 Jan 2018 08:30:27 -0800 (PST) From: Alex Vong To: control@debbugs.gnu.org Subject: Add tags. Date: Mon, 15 Jan 2018 00:30:25 +0800 Message-ID: <87o9lwqu72.fsf@gmail.com> User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/25.3 (gnu/linux) MIME-Version: 1.0 Content-Type: text/plain X-Spam-Score: 0.3 (/) X-Debbugs-Envelope-To: control X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: 0.3 (/) package guix-patches tags 30111 patch security thanks From debbugs-submit-bounces@debbugs.gnu.org Sun Jan 14 11:38:01 2018 Received: (at control) by debbugs.gnu.org; 14 Jan 2018 16:38:01 +0000 Received: from localhost ([127.0.0.1]:56202 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1ealIH-0005hx-0L for submit@debbugs.gnu.org; Sun, 14 Jan 2018 11:38:01 -0500 Received: from mail-pl0-f44.google.com ([209.85.160.44]:45501) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1ealIF-0005hj-0f for control@debbugs.gnu.org; Sun, 14 Jan 2018 11:37:59 -0500 Received: by mail-pl0-f44.google.com with SMTP id p5so2056958plo.12 for ; Sun, 14 Jan 2018 08:37:58 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:subject:date:message-id:user-agent:mime-version; bh=Pv0PB9OP8tuLyK+D5D0ms8PkyLyMd3j1GxS+dUnZE5A=; b=D03niPqZh4yUBoZ/lt/h6WQRhun+NHZU1M3TeipUt1AdyMO/2ttwcOqsGpk4Ocirdy H9g0Nkzxwj8yZvZNY6vatLA6N85ecN6bOC7FR0nvsSBgX9c7pupNvXlpm2wcTQudbygV GPJfRCFOUJGogqrFKVl19CXYAZMUEe+7CAQveCTOdycZGbvj52zIL0W25xBAvvHmPomL P8ER8gAqI+cJ2JEYB+xlwvKaoK7/GkiKEvxkh6WLb4jOvugDpQ5/xpK6nhrDCaUAOolu Fnmfh6Z9cFvQwD7CIs8g4XrQGMX2iauZB9nN5s68XJQDQCL4zDCO0zPKpwgUi6l2B2hi OMzg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:subject:date:message-id:user-agent :mime-version; bh=Pv0PB9OP8tuLyK+D5D0ms8PkyLyMd3j1GxS+dUnZE5A=; b=Lh8GeN/IEWrYvBMwW8iaNB/WJxRmGEdNgwea5PBuQCAulqWGa2JsR+W1wJ0ZPQZ7+K ia7aGt18hZ9CUln9/+LwPugQOS3PeHeigBe/l1D0C1JpWtekVp7z6t8LsgJiM9yklr/J MEqTU/WpLiVoDlwPkV1X6iJWcuoTd7vHw+PfUEE9aLbxLdfPHjfXZUzhovn+bGzC/ykG 7dSSBIgtI2DmsHCtFfaQfyzc3iTUxkHu3mVW8ApfpPh5h/hS9WQywOZxQTcWDESVmhl1 AmbpMmkbcK/GYf9ipJbB7/TGVwe+vMjmY7wkxdrATAcvtNYrgfWe1yFwLMLSc5EGRjmR NA3g== X-Gm-Message-State: AKGB3mJp9rlJBMpe6CCJsnl2dW9kzMicbemevbCmv+0hsY0rgOVvF2pw u9/cU/wJI3EC71BqNeELuec= X-Google-Smtp-Source: ACJfBotXAZ5+4Dbn4NanPPNddgGmg2PGI0hArFOcQRj0J4RgJyeXXRa8nglPTOWCzq/klksF/5Nlqg== X-Received: by 10.159.253.68 with SMTP id b4mr33215741plx.220.1515947873252; Sun, 14 Jan 2018 08:37:53 -0800 (PST) Received: from debian (1-64-83-091.static.netvigator.com. [1.64.83.91]) by smtp.gmail.com with ESMTPSA id b81sm36836696pfm.25.2018.01.14.08.37.52 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Sun, 14 Jan 2018 08:37:52 -0800 (PST) From: Alex Vong To: control@debbugs.gnu.org Subject: Fix title. Date: Mon, 15 Jan 2018 00:37:50 +0800 Message-ID: <87k1wkqtup.fsf@gmail.com> User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/25.3 (gnu/linux) MIME-Version: 1.0 Content-Type: text/plain X-Spam-Score: 0.3 (/) X-Debbugs-Envelope-To: control X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: 0.3 (/) package guix-patches retitle 30111 [PATCH] gnu: gcc@7: Apply the 'retpoline' mitigation technique. thanks From unknown Sun Jun 22 07:57:08 2025 X-Loop: help-debbugs@gnu.org Subject: [bug#30111] gnu: gcc@7: Apply the 'retpoline' mitigation technique. Resent-From: Alex Vong Original-Sender: "Debbugs-submit" Resent-CC: guix-patches@gnu.org Resent-Date: Mon, 15 Jan 2018 14:30:02 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 30111 X-GNU-PR-Package: guix-patches X-GNU-PR-Keywords: security patch To: 30111@debbugs.gnu.org Received: via spool by 30111-submit@debbugs.gnu.org id=B30111.151602657523707 (code B ref 30111); Mon, 15 Jan 2018 14:30:02 +0000 Received: (at 30111) by debbugs.gnu.org; 15 Jan 2018 14:29:35 +0000 Received: from localhost ([127.0.0.1]:56829 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1eb5lX-0006AH-8e for submit@debbugs.gnu.org; Mon, 15 Jan 2018 09:29:35 -0500 Received: from mail-pg0-f51.google.com ([74.125.83.51]:38198) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1eb5lV-0006A1-BJ for 30111@debbugs.gnu.org; Mon, 15 Jan 2018 09:29:33 -0500 Received: by mail-pg0-f51.google.com with SMTP id y27so2052476pgc.5 for <30111@debbugs.gnu.org>; Mon, 15 Jan 2018 06:29:33 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:subject:references:date:in-reply-to:message-id:user-agent :mime-version:content-transfer-encoding; bh=CUP48WvMIt5WLsQZRi5XOtBhXIfAwI1z6/sRK4XwnNc=; b=i1b5R4odkBsdeuKyIxbYlBm2r3pcKSB+gO6o8LOM6QKvRxRSLj5Hm8ZDyoc9MPcp+Y Z++DIEvphpYHkYX+TbRrfPjyPyljBJJQjasoAvucJPPu5i+CDcwJ/ROHoWSfrb2h16xQ D31fR6ZJxynlhPZsGTNFmpDKRAEKHWM6fCmqcMIIvtTW8e45PrTglUGM2ViAjLgeP6bo jWxgAT42BGi3rsnFEG4UL7suulcQs9unofUGIBeE3zFkoZvxgbPsK4ZG3FhbBlBwsV1v QAwH2ROJv/j9yDTcmWbcUqxPpwaXoJLN2Gz1909DKdoWTixFkVenc/akpB8+0Xb5Ik5v 0UqA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:subject:references:date:in-reply-to :message-id:user-agent:mime-version:content-transfer-encoding; bh=CUP48WvMIt5WLsQZRi5XOtBhXIfAwI1z6/sRK4XwnNc=; b=p23Eli2aFkUxuUEBIUINrlDGVlM3OuSbbHe0yatQLe0uJP8f6KQrQ9QE0693xUll0K 6dNuiIWO6YgjMiMgMW0eXGGhje7ma0S5KkUdN9SixbuGkRS3FWO3KDcZlc3ckZSqDHMt n96Jub7iEBPIOKv8IjOruPkEdFzBbBzXm4/3KED06AAYWuSbpOhQUphg5BXAJ26b2FvK oyJEUTnn2Qp+n8qFiAwLHMsgg+cuCZhzW6Ye8ladMWo8LngrIdUQYljaJjUrWss0RoQb uo8S07bw9whfQgSlxh9J7x2KvVlsT3IOl9jYmYBKKaNamy4VAn8vLqpVpORWH4MrvfFb Msgg== X-Gm-Message-State: AKwxyteUBIcnnjWp4VdBFDpa2leI1ZLad32x5lRTn/pOMevUDN/Bg5vo rziJyGdddPrX611xlh8rHxU= X-Google-Smtp-Source: ACJfBotLkPDBPo4N3BwZUaXSRsjmnqAR8IEmD7Rluz0tOXlEE443bcwVleYy5v9Brm2DBhMohaFzVw== X-Received: by 10.98.106.1 with SMTP id f1mr15343263pfc.162.1516026566588; Mon, 15 Jan 2018 06:29:26 -0800 (PST) Received: from debian (n058152179035.netvigator.com. [58.152.179.35]) by smtp.gmail.com with ESMTPSA id l190sm41434827pfc.73.2018.01.15.06.29.20 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Mon, 15 Jan 2018 06:29:25 -0800 (PST) From: Alex Vong References: <877esksi62.fsf@gmail.com> Date: Mon, 15 Jan 2018 22:29:10 +0800 In-Reply-To: <877esksi62.fsf@gmail.com> (Alex Vong's message of "Sun, 14 Jan 2018 21:07:17 +0800") Message-ID: <87d12bgpqh.fsf@gmail.com> User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/25.3 (gnu/linux) MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: quoted-printable X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" Hello, Please do not review the last patch. It seems the author[0] has refactor 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 writes: > 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 > 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 . > > * 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-t= ests.patch, > gnu/packages/patches/gcc-retpoline-Add-mfunction-return-and-function_retu= rn-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-test= s.patch, > gnu/packages/patches/gcc-retpoline-Add-mindirect-branch-thunk-extern.patc= h, > gnu/packages/patches/gcc-retpoline-Add-mindirect-branch-thunk-inline.patc= h, > gnu/packages/patches/gcc-retpoline-Add-mindirect-branch-thunk.patch, > gnu/packages/patches/gcc-retpoline-Add-mno-indirect-branch-register-to-in= direct-branch-.patch, > gnu/packages/patches/gcc-retpoline-Add-tests-for-mindirect-branch-thunk-f= check-pointer-.patch, > gnu/packages/patches/gcc-retpoline-Disable-red-zone-with-local-indirect-j= ump.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-indir= ect-branch-via.patch, > gnu/packages/patches/gcc-retpoline-i386-Add-V-register-operand-modifier.p= atch, > 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_fram= e-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_branc= h-attribute-with-tests.patch > create mode 100644 gnu/packages/patches/gcc-retpoline-Add-mfunction-retu= rn-and-function_return-attribute.patch > create mode 100644 gnu/packages/patches/gcc-retpoline-Add-mfunction-retu= rn-keep-to-indirect-branch-tests.patch > create mode 100644 gnu/packages/patches/gcc-retpoline-Add-mindirect-bran= ch-loop.patch > create mode 100644 gnu/packages/patches/gcc-retpoline-Add-mindirect-bran= ch-register-and-tests.patch > create mode 100644 gnu/packages/patches/gcc-retpoline-Add-mindirect-bran= ch-thunk-extern.patch > create mode 100644 gnu/packages/patches/gcc-retpoline-Add-mindirect-bran= ch-thunk-inline.patch > create mode 100644 gnu/packages/patches/gcc-retpoline-Add-mindirect-bran= ch-thunk.patch > create mode 100644 gnu/packages/patches/gcc-retpoline-Add-mno-indirect-b= ranch-register-to-indirect-branch-.patch > create mode 100644 gnu/packages/patches/gcc-retpoline-Add-tests-for-mind= irect-branch-thunk-fcheck-pointer-.patch > create mode 100644 gnu/packages/patches/gcc-retpoline-Disable-red-zone-w= ith-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-registe= r-operand-modifier.patch > create mode 100644 gnu/packages/patches/gcc-retpoline-i386-More-use-refe= rence-of-struct-ix86_frame-to-avoi.patch > create mode 100644 gnu/packages/patches/gcc-retpoline-i386-Move-struct-i= x86_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 =C2=A9 2016 Adonay "adfeno" Felipe Nogueira > # Copyright =C2=A9 2016, 2017 Ricardo Wurmus > # Copyright =C2=A9 2016 Ben Woodcroft > -# Copyright =C2=A9 2016, 2017 Alex Vong > +# Copyright =C2=A9 2016, 2017, 2018 Alex Vong > # Copyright =C2=A9 2016, 2017 Efraim Flashner > # Copyright =C2=A9 2016, 2017 Jan Nieuwenhuizen > # Copyright =C2=A9 2017 Tobias Geerinckx-Rice > @@ -652,6 +652,23 @@ dist_patch_DATA =3D \ > %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-mach= ine_function.patch \ > + %D%/packages/patches/gcc-retpoline-i386-Use-reference-of-struct-ix86_f= rame-to-avoid-cop.patch \ > + %D%/packages/patches/gcc-retpoline-i386-More-use-reference-of-struct-i= x86_frame-to-avoi.patch \ > + %D%/packages/patches/gcc-retpoline-Add-mindirect-branch-thunk.patch \ > + %D%/packages/patches/gcc-retpoline-Add-tests-for-mindirect-branch-thun= k-fcheck-pointer-.patch \ > + %D%/packages/patches/gcc-retpoline-Add-mindirect-branch-thunk-inline.p= atch \ > + %D%/packages/patches/gcc-retpoline-Add-mindirect-branch-thunk-extern.p= atch \ > + %D%/packages/patches/gcc-retpoline-Add-indirect_branch-attribute-with-= tests.patch \ > + %D%/packages/patches/gcc-retpoline-Use-__x86.indirect_thunk.reg-for-in= direct-branch-via.patch \ > + %D%/packages/patches/gcc-retpoline-Add-mindirect-branch-loop.patch \ > + %D%/packages/patches/gcc-retpoline-Add-mfunction-return-and-function_r= eturn-attribute.patch \ > + %D%/packages/patches/gcc-retpoline-Add-mfunction-return-keep-to-indire= ct-branch-tests.patch \ > + %D%/packages/patches/gcc-retpoline-Add-mindirect-branch-register-and-t= ests.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-indirec= t-jump.patch \ > + %D%/packages/patches/gcc-retpoline-i386-Add-V-register-operand-modifie= r.patch \ > + %D%/packages/patches/gcc-retpoline-Rename-thunks-to-__x86_indirect_thu= nk_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 =C2=A9 2015 Andreas Enge > ;;; Copyright =C2=A9 2015, 2016, 2017 Efraim Flashner > ;;; Copyright =C2=A9 2016 Carlos S=C3=A1nchez de La Lama > +;;; Copyright =C2=A9 2018 ALex Vong > ;;; > ;;; 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.patc= h" > - "gcc-5.0-libvtv-runpath.patch")))) > + "gcc-5.0-libvtv-runpath.patch" > + "gcc-retpoline-i386-Move-struct-i= x86_frame-to-machine_function.patch" > + "gcc-retpoline-i386-Use-reference= -of-struct-ix86_frame-to-avoid-cop.patch" > + "gcc-retpoline-i386-More-use-refe= rence-of-struct-ix86_frame-to-avoi.patch" > + "gcc-retpoline-Add-mindirect-bran= ch-thunk.patch" > + "gcc-retpoline-Add-tests-for-mind= irect-branch-thunk-fcheck-pointer-.patch" > + "gcc-retpoline-Add-mindirect-bran= ch-thunk-inline.patch" > + "gcc-retpoline-Add-mindirect-bran= ch-thunk-extern.patch" > + "gcc-retpoline-Add-indirect_branc= h-attribute-with-tests.patch" > + "gcc-retpoline-Use-__x86.indirect= _thunk.reg-for-indirect-branch-via.patch" > + "gcc-retpoline-Add-mindirect-bran= ch-loop.patch" > + "gcc-retpoline-Add-mfunction-retu= rn-and-function_return-attribute.patch" > + "gcc-retpoline-Add-mfunction-retu= rn-keep-to-indirect-branch-tests.patch" > + "gcc-retpoline-Add-mindirect-bran= ch-register-and-tests.patch" > + "gcc-retpoline-Add-mno-indirect-b= ranch-register-to-indirect-branch-.patch" > + "gcc-retpoline-Disable-red-zone-w= ith-local-indirect-jump.patch" > + "gcc-retpoline-i386-Add-V-registe= r-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-en= ds > for several languages, including C, C++, Objective-C, Fortran, Ada, and = Go. > diff --git a/gnu/packages/patches/gcc-retpoline-Add-indirect_branch-attri= bute-with-tests.patch b/gnu/packages/patches/gcc-retpoline-Add-indirect_bra= nch-attribute-with-tests.patch > new file mode 100644 > index 000000000..5129a8273 > --- /dev/null > +++ b/gnu/packages/patches/gcc-retpoline-Add-indirect_branch-attribute-wi= th-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-f= or-cpu_4.html > +https://support.google.com/faqs/answer/7625886 > +https://spectreattack.com/ > +https://cve.mitre.org/cgi-bin/cvename.cgi?name=3DCVE-2017-5715 > + > +Patch copied from the 'retpoline-20180107' branch of upstream source rep= ository > +(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" > +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 { > + }; > +=20 > + enum indirect_branch { > ++ indirect_branch_unset =3D 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) > + } > + } > +=20 > ++/* 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 =3D=3D indirect_branch_unset) > ++ { > ++ tree attr =3D lookup_attribute ("indirect_branch", > ++ DECL_ATTRIBUTES (fndecl)); > ++ if (attr !=3D NULL) > ++ { > ++ tree args =3D TREE_VALUE (attr); > ++ if (args =3D=3D NULL) > ++ gcc_unreachable (); > ++ tree cst =3D TREE_VALUE (args); > ++ if (strcmp (TREE_STRING_POINTER (cst), "keep") =3D=3D 0) > ++ cfun->machine->indirect_branch_type =3D indirect_branch_keep; > ++ else if (strcmp (TREE_STRING_POINTER (cst), "thunk") =3D=3D 0) > ++ cfun->machine->indirect_branch_type =3D indirect_branch_thunk; > ++ else if (strcmp (TREE_STRING_POINTER (cst), "thunk-inline") =3D=3D 0) > ++ cfun->machine->indirect_branch_type =3D indirect_branch_thunk_inli= ne; > ++ else if (strcmp (TREE_STRING_POINTER (cst), "thunk-extern") =3D=3D 0) > ++ cfun->machine->indirect_branch_type =3D indirect_branch_thunk_exte= rn; > ++ else > ++ gcc_unreachable (); > ++ } > ++ else > ++ cfun->machine->indirect_branch_type =3D 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 !=3D NULL_TREE) > +- ix86_set_func_type (fndecl); > ++ { > ++ ix86_set_func_type (fndecl); > ++ ix86_set_indirect_branch_type (fndecl); > ++ } > + return; > + } > +=20 > +@@ -7172,6 +7206,7 @@ ix86_set_current_function (tree fndecl) > + } > +=20 > + ix86_set_func_type (fndecl); > ++ ix86_set_indirect_branch_type (fndecl); > +=20 > + tree new_tree =3D DECL_FUNCTION_SPECIFIC_TARGET (fndecl); > + if (new_tree =3D=3D NULL_TREE) > +@@ -28605,9 +28640,11 @@ ix86_output_indirect_branch (rtx call_op, const= char *xasm, > + char push_buf[64]; > + bool need_bnd_p =3D ix86_bnd_prefixed_insn_p (current_output_insn); > +=20 > +- if (ix86_indirect_branch !=3D indirect_branch_thunk_inline) > ++ if (cfun->machine->indirect_branch_type > ++ !=3D indirect_branch_thunk_inline) > + { > +- bool need_thunk =3D ix86_indirect_branch =3D=3D indirect_branch_t= hunk; > ++ bool need_thunk > ++ =3D cfun->machine->indirect_branch_type =3D=3D indirect_branch_thunk; > + if (need_bnd_p) > + indirect_thunk_bnd_needed |=3D need_thunk; > + else > +@@ -28716,7 +28753,7 @@ const char * > + ix86_output_indirect_jmp (rtx call_op) > + { > + if (ix86_red_zone_size =3D=3D 0 > +- && ix86_indirect_branch !=3D indirect_branch_keep) > ++ && cfun->machine->indirect_branch_type !=3D 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 =3D constant_call_address_operand (call_op, VOIDmode); > + bool output_indirect_p > + =3D (!TARGET_SEH > +- && ix86_indirect_branch !=3D indirect_branch_keep); > ++ && cfun->machine->indirect_branch_type !=3D indirect_branch_keep= ); > + bool seh_nop_p =3D false; > + const char *xasm; > +=20 > +@@ -41749,7 +41786,7 @@ ix86_handle_struct_attribute (tree *node, tree n= ame, tree, int, > + } > +=20 > + 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) !=3D FUNCTION_DECL) > +@@ -41758,6 +41795,29 @@ ix86_handle_fndecl_attribute (tree *node, tree = name, tree, int, > + name); > + *no_add_attrs =3D true; > + } > ++ > ++ if (is_attribute_p ("indirect_branch", name)) > ++ { > ++ tree cst =3D TREE_VALUE (args); > ++ if (TREE_CODE (cst) !=3D STRING_CST) > ++ { > ++ warning (OPT_Wattributes, > ++ "%qE attribute requires a string constant argument", > ++ name); > ++ *no_add_attrs =3D true; > ++ } > ++ else if (strcmp (TREE_STRING_POINTER (cst), "keep") !=3D 0 > ++ && strcmp (TREE_STRING_POINTER (cst), "thunk") !=3D 0 > ++ && strcmp (TREE_STRING_POINTER (cst), "thunk-inline") !=3D 0 > ++ && strcmp (TREE_STRING_POINTER (cst), "thunk-extern") !=3D 0) > ++ { > ++ warning (OPT_Wattributes, > ++ "argument to %qE attribute is not " > ++ "(keep|thunk|thunk-inline|thunk-extern)", name); > ++ *no_add_attrs =3D true; > ++ } > ++ } > ++ > + return NULL_TREE; > + } > +=20 > +@@ -46052,6 +46112,8 @@ static const struct attribute_spec ix86_attribut= e_table[] =3D > + 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 }, > +=20 > + /* 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; > +=20 > ++ /* 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=3Dthunk -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" } } */ > +--=20 > +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-mf= unction-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-functio= n_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-f= or-cpu_4.html > +https://support.google.com/faqs/answer/7625886 > +https://spectreattack.com/ > +https://cve.mitre.org/cgi-bin/cvename.cgi?name=3DCVE-2017-5715 > + > +Patch copied from the 'retpoline-20180107' branch of upstream source rep= ository > +(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" > +Date: Tue, 5 Dec 2017 13:29:06 -0800 > +Subject: [PATCH 11/17] Add -mfunction-return=3D and function_return attr= ibute > + > +Add -mfunction-return=3D and function_return attribute tests > + > +-mfunction-return=3Dthunk > + Convert function return instruction to PC-relative call thunk. > +-mfunction-return=3Dthunk-inline > + Convert function return instruction to PC-relative call thunk with > + thunk inlined. > +-mfunction-return=3Dthunk-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; > +=20 > + 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 loa= d, > + enum machine_mode mode); > +=20 > +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 =3D ix86_indirect_branch; > + } > ++ > ++ if (cfun->machine->function_return_type =3D=3D indirect_branch_unset) > ++ { > ++ tree attr =3D lookup_attribute ("function_return", > ++ DECL_ATTRIBUTES (fndecl)); > ++ if (attr !=3D NULL) > ++ { > ++ tree args =3D TREE_VALUE (attr); > ++ if (args =3D=3D NULL) > ++ gcc_unreachable (); > ++ tree cst =3D TREE_VALUE (args); > ++ if (strcmp (TREE_STRING_POINTER (cst), "keep") =3D=3D 0) > ++ cfun->machine->function_return_type =3D indirect_branch_keep; > ++ else if (strcmp (TREE_STRING_POINTER (cst), "thunk") =3D=3D 0) > ++ cfun->machine->function_return_type =3D indirect_branch_thunk; > ++ else if (strcmp (TREE_STRING_POINTER (cst), "thunk-inline") =3D=3D 0) > ++ cfun->machine->function_return_type =3D indirect_branch_thunk_inli= ne; > ++ else if (strcmp (TREE_STRING_POINTER (cst), "thunk-extern") =3D=3D 0) > ++ cfun->machine->function_return_type =3D indirect_branch_thunk_exte= rn; > ++ else > ++ gcc_unreachable (); > ++ } > ++ else > ++ cfun->machine->function_return_type =3D ix86_function_return; > ++ } > + } > +=20 > + /* 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. = */ > +=20 > + 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 >=3D 0 && ret_p) > ++ gcc_unreachable (); > ++ > + if (USE_HIDDEN_LINKONCE) > + { > + const char *bnd =3D 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 =3D 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; > +=20 > + /* 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 =3D 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); > + } > +=20 > ++ 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) =3D make_node (BLOCK); > + current_function_decl =3D decl; > + allocate_struct_function (decl, false); > +@@ -28736,7 +28807,7 @@ ix86_output_indirect_branch (rtx call_op, const = char *xasm, > + indirect_thunk_needed =3D true; > + } > + } > +- indirect_thunk_name (thunk_name_buf, regno, need_bnd_p); > ++ indirect_thunk_name (thunk_name_buf, regno, need_bnd_p, false); > + thunk_name =3D thunk_name_buf; > + } > + else > +@@ -28860,6 +28931,43 @@ ix86_output_indirect_jmp (rtx call_op) > + return "%!jmp\t%A0"; > + } > +=20 > ++const char * > ++ix86_output_function_return (bool long_p) > ++{ > ++ if (cfun->machine->function_return_type !=3D indirect_branch_keep) > ++ { > ++ char thunk_name[32]; > ++ bool need_bnd_p =3D ix86_bnd_prefixed_insn_p (current_output_insn= ); > ++ > ++ if (cfun->machine->function_return_type > ++ !=3D indirect_branch_thunk_inline) > ++ { > ++ bool need_thunk =3D (cfun->machine->function_return_type > ++ =3D=3D indirect_branch_thunk); > ++ indirect_thunk_name (thunk_name, -1, need_bnd_p, true); > ++ if (need_bnd_p) > ++ { > ++ indirect_thunk_bnd_needed |=3D need_thunk; > ++ fprintf (asm_out_file, "\tbnd jmp\t%s\n", thunk_name); > ++ } > ++ else > ++ { > ++ indirect_thunk_needed |=3D 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. */ > +=20 > + const char * > +@@ -41916,6 +42024,28 @@ ix86_handle_fndecl_attribute (tree *node, tree = name, tree args, int, > + } > + } > +=20 > ++ if (is_attribute_p ("function_return", name)) > ++ { > ++ tree cst =3D TREE_VALUE (args); > ++ if (TREE_CODE (cst) !=3D STRING_CST) > ++ { > ++ warning (OPT_Wattributes, > ++ "%qE attribute requires a string constant argument", > ++ name); > ++ *no_add_attrs =3D true; > ++ } > ++ else if (strcmp (TREE_STRING_POINTER (cst), "keep") !=3D 0 > ++ && strcmp (TREE_STRING_POINTER (cst), "thunk") !=3D 0 > ++ && strcmp (TREE_STRING_POINTER (cst), "thunk-inline") !=3D 0 > ++ && strcmp (TREE_STRING_POINTER (cst), "thunk-extern") !=3D 0) > ++ { > ++ warning (OPT_Wattributes, > ++ "argument to %qE attribute is not " > ++ "(keep|thunk|thunk-inline|thunk-extern)", name); > ++ *no_add_attrs =3D true; > ++ } > ++ } > ++ > + return NULL_TREE; > + } > +=20 > +@@ -46212,6 +46342,8 @@ static const struct attribute_spec ix86_attribut= e_table[] =3D > + 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 }, > +=20 > + /* 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; > +=20 > ++ /* 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=3D > + Target Report RejectNegative Joined Enum(indirect_branch) Var(ix86_indi= rect_branch) Init(indirect_branch_keep) > + Update indirect call and jump. > +=20 > ++mfunction-return=3D > ++Target Report RejectNegative Joined Enum(indirect_branch) Var(ix86_func= tion_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=3D op= tion): > ++Known indirect branch choices (for use with the -mindirect-branch=3D/-m= function-return=3D options): > +=20 > + 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=3Dthunk" } */ > ++ > ++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/testsuit= e/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=3Dthunk-inline -mindirect-branch= =3Dthunk -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" { targ= et { ! 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:" { targe= t { 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/testsuit= e/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=3Dthunk-extern -mindirect-branch= =3Dthunk -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" { targ= et { ! 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:" { targe= t { 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/testsuit= e/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=3Dkeep -mindirect-branch=3Dthunk= -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" { targ= et { ! 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:" { targe= t { 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/testsuit= e/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=3Dkeep -mindirect-branch=3Dthunk= -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/testsuit= e/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=3Dkeep -mindirect-branch=3Dthunk= -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" { targ= et { ! 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/testsuit= e/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=3Dkeep -mindirect-branch=3Dkeep = -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" { targ= et { ! 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/testsuit= e/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=3Dthunk-inline -mindirect-branch= =3Dthunk-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=3Dthunk-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=3Dthunk-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=3Dkeep" } */ > ++ > ++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=3Dkeep" } */ > ++ > ++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=3Dkeep" } */ > ++ > ++__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=3Dkeep" } */ > ++ > ++__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=3Dthunk-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=3Dthunk -mindirect-branch=3Dthun= k -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" { targ= et { ! 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 } } = } */ > +--=20 > +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-mf= unction-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-ind= irect-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-f= or-cpu_4.html > +https://support.google.com/faqs/answer/7625886 > +https://spectreattack.com/ > +https://cve.mitre.org/cgi-bin/cvename.cgi?name=3DCVE-2017-5715 > + > +Patch copied from the 'retpoline-20180107' branch of upstream source rep= ository > +(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" > +Date: Wed, 6 Dec 2017 09:58:42 -0800 > +Subject: [PATCH 12/17] Add -mfunction-return=3Dkeep to indirect branch t= ests > + > +--- > + 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/test= suite/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=3Dthunk -fno-pic" } */ > ++/* { dg-options "-O2 -mfunction-return=3Dkeep -mindirect-branch=3Dthunk= -fno-pic" } */ > +=20 > + typedef void (*dispatch_t)(long offset); > +=20 > +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-2.c b/gcc/test= suite/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=3Dthunk -fno-pic" } */ > ++/* { dg-options "-O2 -mfunction-return=3Dkeep -mindirect-branch=3Dthunk= -fno-pic" } */ > +=20 > + typedef void (*dispatch_t)(long offset); > +=20 > +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-3.c b/gcc/test= suite/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=3Dthunk -fno-pic" } */ > ++/* { dg-options "-O2 -mfunction-return=3Dkeep -mindirect-branch=3Dthunk= -fno-pic" } */ > +=20 > + typedef void (*dispatch_t)(long offset); > +=20 > +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-4.c b/gcc/test= suite/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=3Dthunk -fno-pic" } */ > ++/* { dg-options "-O2 -mfunction-return=3Dkeep -mindirect-branch=3Dthunk= -fno-pic" } */ > +=20 > + typedef void (*dispatch_t)(long offset); > +=20 > +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-5.c b/gcc/test= suite/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=3Dthunk" } */ > ++/* { dg-options "-O2 -mfunction-return=3Dkeep -fpic -fno-plt -mindirect= -branch=3Dthunk" } */ > +=20 > + extern void bar (void); > +=20 > +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-6.c b/gcc/test= suite/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=3Dthunk" } */ > ++/* { dg-options "-O2 -mfunction-return=3Dkeep -fpic -fno-plt -mindirect= -branch=3Dthunk" } */ > +=20 > + extern void bar (void); > +=20 > +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-7.c b/gcc/test= suite/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=3Dthunk -fno-pic" } */ > ++/* { dg-options "-O2 -mfunction-return=3Dkeep -mindirect-branch=3Dthunk= -fno-pic" } */ > +=20 > + 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=3Dkeep -fno-pic" } */ > +=20 > + typedef void (*dispatch_t)(long offset); > +=20 > +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=3Dkeep -fno-pic" } */ > +=20 > + typedef void (*dispatch_t)(long offset); > +=20 > +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=3Dkeep -fno-pic" } */ > +=20 > + typedef void (*dispatch_t)(long offset); > +=20 > +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=3Dkeep -fno-pic" } */ > +=20 > + typedef void (*dispatch_t)(long offset); > +=20 > +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=3Dkeep -fno-pic" } */ > +=20 > + typedef void (*dispatch_t)(long offset); > +=20 > +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=3Dkeep -fno-pic" } */ > +=20 > + typedef void (*dispatch_t)(long offset); > +=20 > +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=3Dkeep -fno-pic" } */ > +=20 > + 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=3Dthunk -fno-pic" } */ > ++/* { dg-options "-O2 -mfunction-return=3Dkeep -mindirect-branch=3Dthunk= -fno-pic" } */ > +=20 > + 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=3Dthunk -fcheck-pointer-bounds -= mmpx -fno-pic" } */ > ++/* { dg-options "-O2 -mfunction-return=3Dkeep -mindirect-branch=3Dthunk= -fcheck-pointer-bounds -mmpx -fno-pic" } */ > +=20 > + 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=3Dthunk -fcheck-pointer-bounds -= mmpx -fno-pic" } */ > ++/* { dg-options "-O2 -mfunction-return=3Dkeep -mindirect-branch=3Dthunk= -fcheck-pointer-bounds -mmpx -fno-pic" } */ > +=20 > + 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=3Dthunk -fcheck-pointer-bounds -= mmpx -fpic -fno-plt" } */ > ++/* { dg-options "-O2 -mfunction-return=3Dkeep -mindirect-branch=3Dthunk= -fcheck-pointer-bounds -mmpx -fpic -fno-plt" } */ > +=20 > + 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=3Dthunk -fcheck-pointer-bounds -= mmpx -fpic -fno-plt" } */ > ++/* { dg-options "-O2 -mfunction-return=3Dkeep -mindirect-branch=3Dthunk= -fcheck-pointer-bounds -mmpx -fpic -fno-plt" } */ > +=20 > + void bar (char *); > + char buf[10]; > +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-1.c b/g= cc/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=3Dthunk-extern -fno-pic" } */ > ++/* { dg-options "-O2 -mfunction-return=3Dkeep -mindirect-branch=3Dthunk= -extern -fno-pic" } */ > +=20 > + typedef void (*dispatch_t)(long offset); > +=20 > +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-2.c b/g= cc/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=3Dthunk-extern -fno-pic" } */ > ++/* { dg-options "-O2 -mfunction-return=3Dkeep -mindirect-branch=3Dthunk= -extern -fno-pic" } */ > +=20 > + typedef void (*dispatch_t)(long offset); > +=20 > +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-3.c b/g= cc/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=3Dthunk-extern -fno-pic" } */ > ++/* { dg-options "-O2 -mfunction-return=3Dkeep -mindirect-branch=3Dthunk= -extern -fno-pic" } */ > +=20 > + typedef void (*dispatch_t)(long offset); > +=20 > +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-4.c b/g= cc/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=3Dthunk-extern -fno-pic" } */ > ++/* { dg-options "-O2 -mfunction-return=3Dkeep -mindirect-branch=3Dthunk= -extern -fno-pic" } */ > +=20 > + typedef void (*dispatch_t)(long offset); > +=20 > +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-5.c b/g= cc/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=3Dthunk-extern" }= */ > ++/* { dg-options "-O2 -mfunction-return=3Dkeep -fpic -fno-plt -mindirect= -branch=3Dthunk-extern" } */ > +=20 > + extern void bar (void); > +=20 > +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-6.c b/g= cc/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=3Dthunk-extern" }= */ > ++/* { dg-options "-O2 -mfunction-return=3Dkeep -fpic -fno-plt -mindirect= -branch=3Dthunk-extern" } */ > +=20 > + extern void bar (void); > +=20 > +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-7.c b/g= cc/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=3Dthunk-extern -fno-pic" } */ > ++/* { dg-options "-O2 -mfunction-return=3Dkeep -mindirect-branch=3Dthunk= -extern -fno-pic" } */ > +=20 > + void func0 (void); > + void func1 (void); > +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-1.c b/g= cc/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=3Dthunk-inline -fno-pic" } */ > ++/* { dg-options "-O2 -mfunction-return=3Dkeep -mindirect-branch=3Dthunk= -inline -fno-pic" } */ > +=20 > + typedef void (*dispatch_t)(long offset); > +=20 > +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-2.c b/g= cc/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=3Dthunk-inline -fno-pic" } */ > ++/* { dg-options "-O2 -mfunction-return=3Dkeep -mindirect-branch=3Dthunk= -inline -fno-pic" } */ > +=20 > + typedef void (*dispatch_t)(long offset); > +=20 > +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-3.c b/g= cc/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=3Dthunk-inline -fno-pic" } */ > ++/* { dg-options "-O2 -mfunction-return=3Dkeep -mindirect-branch=3Dthunk= -inline -fno-pic" } */ > +=20 > + typedef void (*dispatch_t)(long offset); > +=20 > +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-4.c b/g= cc/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=3Dthunk-inline -fno-pic" } */ > ++/* { dg-options "-O2 -mfunction-return=3Dkeep -mindirect-branch=3Dthunk= -inline -fno-pic" } */ > +=20 > + typedef void (*dispatch_t)(long offset); > +=20 > +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-5.c b/g= cc/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=3Dthunk-inline" }= */ > ++/* { dg-options "-O2 -mfunction-return=3Dkeep -fpic -fno-plt -mindirect= -branch=3Dthunk-inline" } */ > +=20 > + extern void bar (void); > +=20 > +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-6.c b/g= cc/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=3Dthunk-inline" }= */ > ++/* { dg-options "-O2 -mfunction-return=3Dkeep -fpic -fno-plt -mindirect= -branch=3Dthunk-inline" } */ > +=20 > + extern void bar (void); > +=20 > +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-7.c b/g= cc/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=3Dthunk-inline -fno-pic" } */ > ++/* { dg-options "-O2 -mfunction-return=3Dkeep -mindirect-branch=3Dthunk= -inline -fno-pic" } */ > +=20 > + void func0 (void); > + void func1 (void); > +--=20 > +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-f= or-cpu_4.html > +https://support.google.com/faqs/answer/7625886 > +https://spectreattack.com/ > +https://cve.mitre.org/cgi-bin/cvename.cgi?name=3DCVE-2017-5715 > + > +Patch copied from the 'retpoline-20180107' branch of upstream source rep= ository > +(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" > +Date: Thu, 16 Nov 2017 14:46:20 -0800 > +Subject: [PATCH 10/17] Add -mindirect-branch-loop=3D > + > +Add -mindirect-branch-loop=3D 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 > + }; > +=20 > ++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 reg= no) > +=20 > + ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, indirectlabel1); > +=20 > +- /* 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 (); > ++ } > +=20 > + /* 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(in= direct_branch_thunk_inline) > +=20 > + EnumValue > + Enum(indirect_branch) String(thunk-extern) Value(indirect_branch_thunk_= extern) > ++ > ++mindirect-branch-loop=3D > ++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=3D option): > ++ > ++EnumValue > ++Enum(indirect_branch_loop) String(lfence) Value(indirect_branch_loop_lf= ence) > ++ > ++EnumValue > ++Enum(indirect_branch_loop) String(pause) Value(indirect_branch_loop_pau= se) > ++ > ++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=3Dthunk -mindirect-branch-loop= =3Dpause -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" { targ= et { ! x32 } } } } */ > ++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk\.(r|e)a= x" { 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=3Dthunk -mindirect-branch-loop= =3Dnop -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" { targ= et { ! x32 } } } } */ > ++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk\.(r|e)a= x" { 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=3Dthunk -mindirect-branch-loop= =3Dlfence -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" { targ= et { ! x32 } } } } */ > ++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk\.(r|e)a= x" { 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=3Dthunk-inline -mindirect-branch= -loop=3Dpause -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=3Dthunk-extern -mindirect-branch= -loop=3Dpause -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" { targ= et { ! x32 } } } } */ > ++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk\.(r|e)a= x" { 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" } } */ > +--=20 > +2.15.1 > + > diff --git a/gnu/packages/patches/gcc-retpoline-Add-mindirect-branch-regi= ster-and-tests.patch b/gnu/packages/patches/gcc-retpoline-Add-mindirect-bra= nch-register-and-tests.patch > new file mode 100644 > index 000000000..de9e373fd > --- /dev/null > +++ b/gnu/packages/patches/gcc-retpoline-Add-mindirect-branch-register-an= d-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-f= or-cpu_4.html > +https://support.google.com/faqs/answer/7625886 > +https://spectreattack.com/ > +https://cve.mitre.org/cgi-bin/cvename.cgi?name=3DCVE-2017-5715 > + > +Patch copied from the 'retpoline-20180107' branch of upstream source rep= ository > +(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" > +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-registe= r-1.c > + create mode 100644 gcc/testsuite/gcc.target/i386/indirect-thunk-registe= r-2.c > + create mode 100644 gcc/testsuite/gcc.target/i386/indirect-thunk-registe= r-3.c > + > +diff --git a/gcc/config/i386/constraints.md b/gcc/config/i386/constraint= s.md > +index 38d604fdace..697caf704dd 100644 > +--- a/gcc/config/i386/constraints.md > ++++ b/gcc/config/i386/constraints.md > +@@ -198,16 +198,20 @@ > +=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 =3D=3D DImode") > ++ (and (match_test "TARGET_X32 && Pmode =3D=3D DImode > ++ && !ix86_indirect_branch_thunk_register") > + (match_operand 0 "GOT_memory_operand")))) > +=20 > + (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 =3D=3D DImode") > ++ (and (match_test "TARGET_X32 && Pmode =3D=3D DImode > ++ && !ix86_indirect_branch_thunk_register") > + (match_operand 0 "GOT_memory_operand")))) > +=20 > + (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] =3D convert_memory_address (word_mode, operands[0]); > + }) > +=20 > +@@ -11657,7 +11657,7 @@ > + OPTAB_DIRECT); > + } > +=20 > +- if (TARGET_X32) > ++ if (TARGET_X32 || ix86_indirect_branch_thunk_register) > + operands[0] =3D convert_memory_address (word_mode, operands[0]); > + }) > +=20 > +@@ -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")]) > +=20 > +@@ -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 @@ > + }) > +=20 > + (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")]) > +=20 > + (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))]) > +=20 > + ;; 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")]) > +=20 > +@@ -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 @@ > +=20 > + (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(in= direct_branch_thunk_inline) > + EnumValue > + Enum(indirect_branch) String(thunk-extern) Value(indirect_branch_thunk_= extern) > +=20 > ++mindirect-branch-register > ++Target Report Var(ix86_indirect_branch_thunk_register) Init(0) > ++Force indirect call and jump via register. > ++ > + mindirect-branch-loop=3D > + Target Report RejectNegative Joined Enum(indirect_branch_loop) Var(ix86= _indirect_branch_loop) Undocumented Init(indirect_branch_loop_lfence) > +=20 > +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")))) > +=20 > + ;; Return true if OP is a memory operands that can be used in sibcalls. > +@@ -664,7 +665,8 @@ > +=20 > + ;; 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 =3D XEXP (op, 0); > + return (GET_CODE (op) =3D=3D CONST > +@@ -678,9 +680,11 @@ > + (ior (match_test "constant_call_address_operand > + (op, mode =3D=3D 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 =3D=3D DImode") > ++ (and (match_test "TARGET_X32 && Pmode =3D=3D DImode > ++ && !ix86_indirect_branch_thunk_register") > + (match_operand 0 "GOT_memory_operand"))))) > +=20 > + ;; Similarly, but for tail calls, in which we cannot allow memory refer= ences. > +@@ -688,14 +692,17 @@ > + (ior (match_test "constant_call_address_operand > + (op, mode =3D=3D 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 =3D=3D DImode") > ++ (and (match_test "TARGET_X32 && Pmode =3D=3D DImode > ++ && !ix86_indirect_branch_thunk_register") > + (match_operand 0 "GOT_memory_operand"))))) > +=20 > + ;; Return true if OP is a 32-bit GOT symbol operand. > + (define_predicate "GOT32_symbol_operand" > +- (match_test "GET_CODE (op) =3D=3D CONST > ++ (match_test "!ix86_indirect_branch_thunk_register > ++ && GET_CODE (op) =3D=3D CONST > + && GET_CODE (XEXP (op, 0)) =3D=3D UNSPEC > + && XINT (XEXP (op, 0), 1) =3D=3D UNSPEC_GOT")) > +=20 > +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=3Dthunk -mindirect-branch-regist= er -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)a= x" } } */ > ++/* { 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=3Dthunk-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=3Dthunk-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)a= x" } } */ > ++/* { 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" } } */ > +--=20 > +2.15.1 > + > diff --git a/gnu/packages/patches/gcc-retpoline-Add-mindirect-branch-thun= k-extern.patch b/gnu/packages/patches/gcc-retpoline-Add-mindirect-branch-th= unk-extern.patch > new file mode 100644 > index 000000000..18b2dfaea > --- /dev/null > +++ b/gnu/packages/patches/gcc-retpoline-Add-mindirect-branch-thunk-exter= n.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-f= or-cpu_4.html > +https://support.google.com/faqs/answer/7625886 > +https://spectreattack.com/ > +https://cve.mitre.org/cgi-bin/cvename.cgi?name=3DCVE-2017-5715 > + > +Patch copied from the 'retpoline-20180107' branch of upstream source rep= ository > +(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" > +Date: Mon, 27 Nov 2017 08:38:41 -0800 > +Subject: [PATCH 07/17] Add -mindirect-branch=3Dthunk-extern > + > +Add -mindirect-branch=3Dthunk-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 > + }; > +=20 > + #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_b= ranch_thunk) > +=20 > + 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/g= cc/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=3Dthunk-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/g= cc/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=3Dthunk-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/g= cc/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=3Dthunk-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/g= cc/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=3Dthunk-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/g= cc/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=3Dthunk-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/g= cc/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=3Dthunk-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/g= cc/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=3Dthunk-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" } } */ > +--=20 > +2.15.1 > + > diff --git a/gnu/packages/patches/gcc-retpoline-Add-mindirect-branch-thun= k-inline.patch b/gnu/packages/patches/gcc-retpoline-Add-mindirect-branch-th= unk-inline.patch > new file mode 100644 > index 000000000..bb12c0e95 > --- /dev/null > +++ b/gnu/packages/patches/gcc-retpoline-Add-mindirect-branch-thunk-inlin= e.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-f= or-cpu_4.html > +https://support.google.com/faqs/answer/7625886 > +https://spectreattack.com/ > +https://cve.mitre.org/cgi-bin/cvename.cgi?name=3DCVE-2017-5715 > + > +Patch copied from the 'retpoline-20180107' branch of upstream source rep= ository > +(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" > +Date: Wed, 15 Nov 2017 11:20:31 -0800 > +Subject: [PATCH 06/17] Add -mindirect-branch=3Dthunk-inline > + > +Add -mindirect-branch=3Dthunk-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 { > +=20 > + enum indirect_branch { > + indirect_branch_keep, > +- indirect_branch_thunk > ++ indirect_branch_thunk, > ++ indirect_branch_thunk_inline > + }; > +=20 > + #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 =3D ix86_bnd_prefixed_insn_p (current_output_insn); > +=20 > +- bool need_thunk =3D ix86_indirect_branch =3D=3D indirect_branch_thunk; > +- if (need_bnd_p) > +- indirect_thunk_bnd_needed |=3D need_thunk; > ++ if (ix86_indirect_branch !=3D indirect_branch_thunk_inline) > ++ { > ++ bool need_thunk =3D ix86_indirect_branch =3D=3D indirect_branch_t= hunk; > ++ if (need_bnd_p) > ++ indirect_thunk_bnd_needed |=3D need_thunk; > ++ else > ++ indirect_thunk_needed |=3D need_thunk; > ++ indirect_thunk_name (thunk_name_buf, need_bnd_p); > ++ thunk_name =3D thunk_name_buf; > ++ } > + else > +- indirect_thunk_needed |=3D need_thunk; > +- indirect_thunk_name (thunk_name, need_bnd_p); > ++ thunk_name =3D NULL; > +=20 > + 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, cons= t char *xasm, > +=20 > + output_asm_insn (push_buf, &call_op); > +=20 > +- if (need_bnd_p) > +- fprintf (asm_out_file, "\tbnd jmp\t%s\n", thunk_name); > ++ if (thunk_name !=3D 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); > +=20 > + ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, indirectlabel2); > +=20 > +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_br= anch_keep) > +=20 > + 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/g= cc/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=3Dthunk-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/g= cc/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=3Dthunk-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/g= cc/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=3Dthunk-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/g= cc/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=3Dthunk-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/g= cc/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=3Dthunk-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/g= cc/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=3Dthunk-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/g= cc/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=3Dthunk-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" } } */ > +--=20 > +2.15.1 > + > diff --git a/gnu/packages/patches/gcc-retpoline-Add-mindirect-branch-thun= k.patch b/gnu/packages/patches/gcc-retpoline-Add-mindirect-branch-thunk.pat= ch > 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-f= or-cpu_4.html > +https://support.google.com/faqs/answer/7625886 > +https://spectreattack.com/ > +https://cve.mitre.org/cgi-bin/cvename.cgi?name=3DCVE-2017-5715 > + > +Patch copied from the 'retpoline-20180107' branch of upstream source rep= ository > +(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" > +Date: Wed, 1 Nov 2017 16:05:50 -0700 > +Subject: [PATCH 04/17] Add -mindirect-branch=3Dthunk > + > +Add tests for -mindirect-branch=3Dthunk > +--- > + 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 */ > + }; > +=20 > ++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 > +=20 > + 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 loa= d, > + enum machine_mode mode); > +=20 > +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 > +=20 > ++static int indirectlabelno; > ++static bool indirect_thunk_needed =3D false; > ++static bool indirect_thunk_bnd_needed =3D 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 =3D 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] =3D stack_pointer_rtx; > ++ xops[1] =3D 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 =3D build_decl (BUILTINS_LOCATION, FUNCTION_DECL, > ++ get_identifier (name), > ++ build_function_type_list (void_type_node, NULL_TREE)); > ++ DECL_RESULT (decl) =3D build_decl (BUILTINS_LOCATION, RESULT_DECL, > ++ NULL_TREE, void_type_node); > ++ TREE_PUBLIC (decl) =3D 1; > ++ TREE_STATIC (decl) =3D 1; > ++ DECL_IGNORED_P (decl) =3D 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) =3D 1; > ++ } > ++ else > ++#endif > ++ if (USE_HIDDEN_LINKONCE) > ++ { > ++ cgraph_node::create (decl)->set_comdat_group (DECL_ASSEMBLER_NAME (dec= l)); > ++ > ++ 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) =3D make_node (BLOCK); > ++ current_function_decl =3D 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 =3D true; > ++ first_function_block_is_cold =3D 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 =3D NULL; > ++} > ++ > + static int pic_labels_used; > +=20 > + /* 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; > +=20 > ++ if (indirect_thunk_needed) > ++ output_indirect_thunk_function (false); > ++ if (indirect_thunk_bnd_needed) > ++ output_indirect_thunk_function (true); > ++ > + for (regno =3D AX_REG; regno <=3D SP_REG; regno++) > + { > + char name[32]; > +@@ -28452,12 +28596,132 @@ ix86_nopic_noplt_attribute_p (rtx call_op) > + return false; > + } > +=20 > ++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 =3D ix86_bnd_prefixed_insn_p (current_output_insn); > ++ > ++ bool need_thunk =3D ix86_indirect_branch =3D=3D indirect_branch_thunk; > ++ if (need_bnd_p) > ++ indirect_thunk_bnd_needed |=3D need_thunk; > ++ else > ++ indirect_thunk_needed |=3D 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 !=3D 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 =3D XEXP (call_op, 0); > ++ if (ix86_decompose_address (addr, &parts) > ++ && parts.base =3D=3D 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 =3D gen_rtx_MULT (Pmode, parts.index, > ++ GEN_INT (parts.scale)); > ++ addr =3D gen_rtx_PLUS (Pmode, stack_pointer_rtx, > ++ addr); > ++ } > ++ else > ++ addr =3D stack_pointer_rtx; > ++ > ++ rtx disp; > ++ if (parts.disp !=3D NULL_RTX) > ++ disp =3D plus_constant (Pmode, parts.disp, > ++ UNITS_PER_WORD); > ++ else > ++ disp =3D GEN_INT (UNITS_PER_WORD); > ++ > ++ addr =3D gen_rtx_PLUS (Pmode, addr, disp); > ++ call_op =3D 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 =3D=3D 0 > ++ && ix86_indirect_branch !=3D indirect_branch_keep) > ++ { > ++ ix86_output_indirect_branch (call_op, "%0", true); > ++ return ""; > ++ } > ++ else > ++ return "%!jmp\t%A0"; > ++} > ++ > + /* Output the assembly for a call instruction. */ > +=20 > + const char * > + ix86_output_call_insn (rtx_insn *insn, rtx call_op) > + { > + bool direct_p =3D constant_call_address_operand (call_op, VOIDmode); > ++ bool output_indirect_p > ++ =3D (!TARGET_SEH > ++ && ix86_indirect_branch !=3D indirect_branch_keep); > + bool seh_nop_p =3D false; > + const char *xasm; > +=20 > +@@ -28467,10 +28731,21 @@ ix86_output_call_insn (rtx_insn *insn, rtx cal= l_op) > + { > + if (ix86_nopic_noplt_attribute_p (call_op)) > + { > ++ direct_p =3D false; > + if (TARGET_64BIT) > +- xasm =3D "%!jmp\t{*%p0@GOTPCREL(%%rip)|[QWORD PTR %p0@GOTPCREL[rip]]}= "; > ++ { > ++ if (output_indirect_p) > ++ xasm =3D "{%p0@GOTPCREL(%%rip)|[QWORD PTR %p0@GOTPCREL[rip]]}"; > ++ else > ++ xasm =3D "%!jmp\t{*%p0@GOTPCREL(%%rip)|[QWORD PTR %p0@GOTPCREL[ri= p]]}"; > ++ } > + else > +- xasm =3D "%!jmp\t{*%p0@GOT|[DWORD PTR %p0@GOT]}"; > ++ { > ++ if (output_indirect_p) > ++ xasm =3D "{%p0@GOT|[DWORD PTR %p0@GOT]}"; > ++ else > ++ xasm =3D "%!jmp\t{*%p0@GOT|[DWORD PTR %p0@GOT]}"; > ++ } > + } > + else > + xasm =3D "%!jmp\t%P0"; > +@@ -28480,9 +28755,17 @@ ix86_output_call_insn (rtx_insn *insn, rtx call= _op) > + else if (TARGET_SEH) > + xasm =3D "%!rex.W jmp\t%A0"; > + else > +- xasm =3D "%!jmp\t%A0"; > ++ { > ++ if (output_indirect_p) > ++ xasm =3D "%0"; > ++ else > ++ xasm =3D "%!jmp\t%A0"; > ++ } > +=20 > +- 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 ""; > + } > +=20 > +@@ -28520,18 +28803,37 @@ ix86_output_call_insn (rtx_insn *insn, rtx cal= l_op) > + { > + if (ix86_nopic_noplt_attribute_p (call_op)) > + { > ++ direct_p =3D false; > + if (TARGET_64BIT) > +- xasm =3D "%!call\t{*%p0@GOTPCREL(%%rip)|[QWORD PTR %p0@GOTPCREL[ri= p]]}"; > ++ { > ++ if (output_indirect_p) > ++ xasm =3D "{%p0@GOTPCREL(%%rip)|[QWORD PTR %p0@GOTPCREL[rip]]}"; > ++ else > ++ xasm =3D "%!call\t{*%p0@GOTPCREL(%%rip)|[QWORD PTR %p0@GOTPCREL[rip]]= }"; > ++ } > + else > +- xasm =3D "%!call\t{*%p0@GOT|[DWORD PTR %p0@GOT]}"; > ++ { > ++ if (output_indirect_p) > ++ xasm =3D "{%p0@GOT|[DWORD PTR %p0@GOT]}"; > ++ else > ++ xasm =3D "%!call\t{*%p0@GOT|[DWORD PTR %p0@GOT]}"; > ++ } > + } > + else > + xasm =3D "%!call\t%P0"; > + } > + else > +- xasm =3D "%!call\t%A0"; > ++ { > ++ if (output_indirect_p) > ++ xasm =3D "%0"; > ++ else > ++ xasm =3D "%!call\t%A0"; > ++ } > +=20 > +- 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); > +=20 > + 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 c= ontaining ret bytes. > + mgeneral-regs-only > + Target Report RejectNegative Mask(GENERAL_REGS_ONLY) Var(ix86_target_fl= ags) Save > + Generate code which uses only the general registers. > ++ > ++mindirect-branch=3D > ++Target Report RejectNegative Joined Enum(indirect_branch) Var(ix86_indi= rect_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=3D op= tion): > ++ > ++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=3D@var{type} -mstack-protector-guard=3D@var{guard} @gol > +--mmitigate-rop -mgeneral-regs-only} > ++-mmitigate-rop -mgeneral-regs-only -mindirect-branch=3D@var{choice}} > +=20 > + @emph{x86 Windows Options} > + @gccoptlist{-mconsole -mcygwin -mno-cygwin -mdll @gol > +@@ -25648,6 +25648,13 @@ Generate code that uses only the general-purpos= e registers. This > + prevents the compiler from using floating-point, vector, mask and bound > + registers. > +=20 > ++@item -mindirect-branch=3D@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 > +=20 > + 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/test= suite/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=3Dthunk -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/test= suite/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=3Dthunk -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/test= suite/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=3Dthunk -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/test= suite/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=3Dthunk -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/test= suite/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=3Dthunk" } */ > ++ > ++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/test= suite/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=3Dthunk" } */ > ++ > ++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/test= suite/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=3Dthunk -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} } } */ > +--=20 > +2.15.1 > + > diff --git a/gnu/packages/patches/gcc-retpoline-Add-mno-indirect-branch-r= egister-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-f= or-cpu_4.html > +https://support.google.com/faqs/answer/7625886 > +https://spectreattack.com/ > +https://cve.mitre.org/cgi-bin/cvename.cgi?name=3DCVE-2017-5715 > + > +Patch copied from the 'retpoline-20180107' branch of upstream source rep= ository > +(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" > +Date: Tue, 12 Dec 2017 12:34:26 -0800 > +Subject: [PATCH 14/17] Add -mno-indirect-branch-register to indirect bra= nch > + 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/test= suite/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=3Dkeep -mindirect-branch=3Dthunk= -fno-pic" } */ > ++/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=3D= keep -mindirect-branch=3Dthunk -fno-pic" } */ > +=20 > + typedef void (*dispatch_t)(long offset); > +=20 > +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-2.c b/gcc/test= suite/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=3Dkeep -mindirect-branch=3Dthunk= -fno-pic" } */ > ++/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=3D= keep -mindirect-branch=3Dthunk -fno-pic" } */ > +=20 > + typedef void (*dispatch_t)(long offset); > +=20 > +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-3.c b/gcc/test= suite/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=3Dkeep -mindirect-branch=3Dthunk= -fno-pic" } */ > ++/* { dg-options "-O2 -mno-indirect-branch-register -mno-indirect-branch= -register -mno-indirect-branch-register -mfunction-return=3Dkeep -mindirect= -branch=3Dthunk -fno-pic" } */ > +=20 > + typedef void (*dispatch_t)(long offset); > +=20 > +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-4.c b/gcc/test= suite/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=3Dkeep -mindirect-branch=3Dthunk= -fno-pic" } */ > ++/* { dg-options "-O2 -mno-indirect-branch-register -mno-indirect-branch= -register -mno-indirect-branch-register -mfunction-return=3Dkeep -mindirect= -branch=3Dthunk -fno-pic" } */ > +=20 > + typedef void (*dispatch_t)(long offset); > +=20 > +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-5.c b/gcc/test= suite/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=3Dkeep -fpic -fno-plt -mindirect= -branch=3Dthunk" } */ > ++/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=3D= keep -fpic -fno-plt -mindirect-branch=3Dthunk" } */ > +=20 > + extern void bar (void); > +=20 > +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-6.c b/gcc/test= suite/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=3Dkeep -fpic -fno-plt -mindirect= -branch=3Dthunk" } */ > ++/* { dg-options "-O2 -mno-indirect-branch-register -mno-indirect-branch= -register -mno-indirect-branch-register -mfunction-return=3Dkeep -fpic -fno= -plt -mindirect-branch=3Dthunk" } */ > +=20 > + extern void bar (void); > +=20 > +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-7.c b/gcc/test= suite/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=3Dkeep -mindirect-branch=3Dthunk= -fno-pic" } */ > ++/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=3D= keep -mindirect-branch=3Dthunk -fno-pic" } */ > +=20 > + 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=3Dkeep -fno-pic" } */ > ++/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=3D= keep -fno-pic" } */ > +=20 > + typedef void (*dispatch_t)(long offset); > +=20 > +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=3Dkeep -fno-pic" } */ > ++/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=3D= keep -fno-pic" } */ > +=20 > + typedef void (*dispatch_t)(long offset); > +=20 > +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=3Dkeep -fno-pic" } */ > ++/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=3D= keep -fno-pic" } */ > +=20 > + typedef void (*dispatch_t)(long offset); > +=20 > +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=3Dkeep -fno-pic" } */ > ++/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=3D= keep -fno-pic" } */ > +=20 > + typedef void (*dispatch_t)(long offset); > +=20 > +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=3Dkeep -fno-pic" } */ > ++/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=3D= keep -fno-pic" } */ > +=20 > + typedef void (*dispatch_t)(long offset); > +=20 > +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=3Dkeep -fno-pic" } */ > ++/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=3D= keep -fno-pic" } */ > +=20 > + typedef void (*dispatch_t)(long offset); > +=20 > +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=3Dkeep -fno-pic" } */ > ++/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=3D= keep -fno-pic" } */ > +=20 > + 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=3Dkeep -mindirect-branch=3Dthunk= -fcheck-pointer-bounds -mmpx -fno-pic" } */ > ++/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=3D= keep -mindirect-branch=3Dthunk -fcheck-pointer-bounds -mmpx -fno-pic" } */ > +=20 > + 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=3Dkeep -mindirect-branch=3Dthunk= -fcheck-pointer-bounds -mmpx -fno-pic" } */ > ++/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=3D= keep -mindirect-branch=3Dthunk -fcheck-pointer-bounds -mmpx -fno-pic" } */ > +=20 > + 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=3Dkeep -mindirect-branch=3Dthunk= -fcheck-pointer-bounds -mmpx -fpic -fno-plt" } */ > ++/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=3D= keep -mindirect-branch=3Dthunk -fcheck-pointer-bounds -mmpx -fpic -fno-plt"= } */ > +=20 > + 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=3Dkeep -mindirect-branch=3Dthunk= -fcheck-pointer-bounds -mmpx -fpic -fno-plt" } */ > ++/* { dg-options "-O2 -mno-indirect-branch-register -mno-indirect-branch= -register -mfunction-return=3Dkeep -mindirect-branch=3Dthunk -fcheck-pointe= r-bounds -mmpx -fpic -fno-plt" } */ > +=20 > + void bar (char *); > + char buf[10]; > +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-1.c b/g= cc/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=3Dkeep -mindirect-branch=3Dthunk= -extern -fno-pic" } */ > ++/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=3D= keep -mindirect-branch=3Dthunk-extern -fno-pic" } */ > +=20 > + typedef void (*dispatch_t)(long offset); > +=20 > +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-2.c b/g= cc/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=3Dkeep -mindirect-branch=3Dthunk= -extern -fno-pic" } */ > ++/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=3D= keep -mindirect-branch=3Dthunk-extern -fno-pic" } */ > +=20 > + typedef void (*dispatch_t)(long offset); > +=20 > +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-3.c b/g= cc/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=3Dkeep -mindirect-branch=3Dthunk= -extern -fno-pic" } */ > ++/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=3D= keep -mindirect-branch=3Dthunk-extern -fno-pic" } */ > +=20 > + typedef void (*dispatch_t)(long offset); > +=20 > +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-4.c b/g= cc/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=3Dkeep -mindirect-branch=3Dthunk= -extern -fno-pic" } */ > ++/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=3D= keep -mindirect-branch=3Dthunk-extern -fno-pic" } */ > +=20 > + typedef void (*dispatch_t)(long offset); > +=20 > +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-5.c b/g= cc/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=3Dkeep -fpic -fno-plt -mindirect= -branch=3Dthunk-extern" } */ > ++/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=3D= keep -fpic -fno-plt -mindirect-branch=3Dthunk-extern" } */ > +=20 > + extern void bar (void); > +=20 > +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-6.c b/g= cc/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=3Dkeep -fpic -fno-plt -mindirect= -branch=3Dthunk-extern" } */ > ++/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=3D= keep -fpic -fno-plt -mindirect-branch=3Dthunk-extern" } */ > +=20 > + extern void bar (void); > +=20 > +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-7.c b/g= cc/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=3Dkeep -mindirect-branch=3Dthunk= -extern -fno-pic" } */ > ++/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=3D= keep -mindirect-branch=3Dthunk-extern -fno-pic" } */ > +=20 > + void func0 (void); > + void func1 (void); > +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-1.c b/g= cc/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=3Dkeep -mindirect-branch=3Dthunk= -inline -fno-pic" } */ > ++/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=3D= keep -mindirect-branch=3Dthunk-inline -fno-pic" } */ > +=20 > + typedef void (*dispatch_t)(long offset); > +=20 > +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-2.c b/g= cc/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=3Dkeep -mindirect-branch=3Dthunk= -inline -fno-pic" } */ > ++/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=3D= keep -mindirect-branch=3Dthunk-inline -fno-pic" } */ > +=20 > + typedef void (*dispatch_t)(long offset); > +=20 > +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-3.c b/g= cc/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=3Dkeep -mindirect-branch=3Dthunk= -inline -fno-pic" } */ > ++/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=3D= keep -mindirect-branch=3Dthunk-inline -fno-pic" } */ > +=20 > + typedef void (*dispatch_t)(long offset); > +=20 > +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-4.c b/g= cc/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=3Dkeep -mindirect-branch=3Dthunk= -inline -fno-pic" } */ > ++/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=3D= keep -mindirect-branch=3Dthunk-inline -fno-pic" } */ > +=20 > + typedef void (*dispatch_t)(long offset); > +=20 > +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-5.c b/g= cc/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=3Dkeep -fpic -fno-plt -mindirect= -branch=3Dthunk-inline" } */ > ++/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=3D= keep -fpic -fno-plt -mindirect-branch=3Dthunk-inline" } */ > +=20 > + extern void bar (void); > +=20 > +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-6.c b/g= cc/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=3Dkeep -fpic -fno-plt -mindirect= -branch=3Dthunk-inline" } */ > ++/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=3D= keep -fpic -fno-plt -mindirect-branch=3Dthunk-inline" } */ > +=20 > + extern void bar (void); > +=20 > +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-7.c b/g= cc/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=3Dkeep -mindirect-branch=3Dthunk= -inline -fno-pic" } */ > ++/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=3D= keep -mindirect-branch=3Dthunk-inline -fno-pic" } */ > +=20 > + 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=3Dthunk -mindirect-branch-loop= =3Dpause -fno-pic" } */ > ++/* { dg-options "-O2 -mno-indirect-branch-register -mindirect-branch=3D= thunk -mindirect-branch-loop=3Dpause -fno-pic" } */ > +=20 > + typedef void (*dispatch_t)(long offset); > +=20 > +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=3Dthunk -mindirect-branch-loop= =3Dnop -fno-pic" } */ > ++/* { dg-options "-O2 -mno-indirect-branch-register -mindirect-branch=3D= thunk -mindirect-branch-loop=3Dnop -fno-pic" } */ > +=20 > + typedef void (*dispatch_t)(long offset); > +=20 > +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=3Dthunk -mindirect-branch-loop= =3Dlfence -fno-pic" } */ > ++/* { dg-options "-O2 -mno-indirect-branch-register -mindirect-branch=3D= thunk -mindirect-branch-loop=3Dlfence -fno-pic" } */ > +=20 > + typedef void (*dispatch_t)(long offset); > +=20 > +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=3Dthunk-inline -mindirect-branch= -loop=3Dpause -fno-pic" } */ > ++/* { dg-options "-O2 -mno-indirect-branch-register -mindirect-branch=3D= thunk-inline -mindirect-branch-loop=3Dpause -fno-pic" } */ > +=20 > + typedef void (*dispatch_t)(long offset); > +=20 > +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=3Dthunk-extern -mindirect-branch= -loop=3Dpause -fno-pic" } */ > ++/* { dg-options "-O2 -mno-indirect-branch-register -mindirect-branch=3D= thunk-extern -mindirect-branch-loop=3Dpause -fno-pic" } */ > +=20 > + typedef void (*dispatch_t)(long offset); > +=20 > +diff --git a/gcc/testsuite/gcc.target/i386/ret-thunk-10.c b/gcc/testsuit= e/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=3Dthunk-inline -mindirect-branch= =3Dthunk -fno-pic" } */ > ++/* { dg-options "-O2 -mno-indirect-branch-register -mno-indirect-branch= -register -mfunction-return=3Dthunk-inline -mindirect-branch=3Dthunk -fno-p= ic" } */ > +=20 > + extern void (*bar) (void); > +=20 > +diff --git a/gcc/testsuite/gcc.target/i386/ret-thunk-11.c b/gcc/testsuit= e/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=3Dthunk-extern -mindirect-branch= =3Dthunk -fno-pic" } */ > ++/* { dg-options "-O2 -mno-indirect-branch-register -mno-indirect-branch= -register -mno-indirect-branch-register -mno-indirect-branch-register -mfun= ction-return=3Dthunk-extern -mindirect-branch=3Dthunk -fno-pic" } */ > +=20 > + extern void (*bar) (void); > +=20 > +diff --git a/gcc/testsuite/gcc.target/i386/ret-thunk-12.c b/gcc/testsuit= e/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=3Dkeep -mindirect-branch=3Dthunk= -fno-pic" } */ > ++/* { dg-options "-O2 -mno-indirect-branch-register -mno-indirect-branch= -register -mno-indirect-branch-register -mno-indirect-branch-register -mfun= ction-return=3Dkeep -mindirect-branch=3Dthunk -fno-pic" } */ > +=20 > + extern void (*bar) (void); > +=20 > +diff --git a/gcc/testsuite/gcc.target/i386/ret-thunk-13.c b/gcc/testsuit= e/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=3Dkeep -mindirect-branch=3Dthunk= -inline -fno-pic" } */ > ++/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=3D= keep -mindirect-branch=3Dthunk-inline -fno-pic" } */ > +=20 > + 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/testsuit= e/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=3Dkeep -mindirect-branch=3Dthunk= -extern -fno-pic" } */ > ++/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=3D= keep -mindirect-branch=3Dthunk-extern -fno-pic" } */ > +=20 > + extern void (*bar) (void); > +=20 > +diff --git a/gcc/testsuite/gcc.target/i386/ret-thunk-15.c b/gcc/testsuit= e/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=3Dkeep -mindirect-branch=3Dkeep = -fno-pic" } */ > ++/* { dg-options "-O2 -mno-indirect-branch-register -mno-indirect-branch= -register -mno-indirect-branch-register -mno-indirect-branch-register -mfun= ction-return=3Dkeep -mindirect-branch=3Dkeep -fno-pic" } */ > +=20 > + extern void (*bar) (void); > +=20 > +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=3Dthunk -mindirect-branch=3Dthun= k -fno-pic" } */ > ++/* { dg-options "-O2 -mno-indirect-branch-register -mno-indirect-branch= -register -mfunction-return=3Dthunk -mindirect-branch=3Dthunk -fno-pic" } */ > +=20 > + extern void (*bar) (void); > +=20 > +--=20 > +2.15.1 > + > diff --git a/gnu/packages/patches/gcc-retpoline-Add-tests-for-mindirect-b= ranch-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-t= hunk-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-f= or-cpu_4.html > +https://support.google.com/faqs/answer/7625886 > +https://spectreattack.com/ > +https://cve.mitre.org/cgi-bin/cvename.cgi?name=3DCVE-2017-5715 > + > +Patch copied from the 'retpoline-20180107' branch of upstream source rep= ository > +(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" > +Date: Mon, 4 Dec 2017 12:58:20 -0800 > +Subject: [PATCH 05/17] Add tests for -mindirect-branch=3Dthunk > + -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=3Dthunk -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=3Dthunk -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=3Dthunk -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=3Dthunk -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} } } */ > +--=20 > +2.15.1 > + > diff --git a/gnu/packages/patches/gcc-retpoline-Disable-red-zone-with-loc= al-indirect-jump.patch b/gnu/packages/patches/gcc-retpoline-Disable-red-zon= e-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-indi= rect-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-f= or-cpu_4.html > +https://support.google.com/faqs/answer/7625886 > +https://spectreattack.com/ > +https://cve.mitre.org/cgi-bin/cvename.cgi?name=3DCVE-2017-5715 > + > +Patch copied from the 'retpoline-20180107' branch of upstream source rep= ository > +(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" > +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 > +=20 > + 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 loa= d, > + 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); > + } > +=20 > +-/* 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. */ > +=20 > + 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 =3D=3D indirect_branch_ke= ep)); > + } > + > + /* Return a string that documents the current -m options. The caller is > +@@ -28919,11 +28926,16 @@ ix86_output_indirect_branch (rtx call_op, cons= t char *xasm, > + } > +=20 > + const char * > +-ix86_output_indirect_jmp (rtx call_op) > ++ix86_output_indirect_jmp (rtx call_op, bool ret_p) > + { > +- if (ix86_red_zone_size =3D=3D 0 > +- && cfun->machine->indirect_branch_type !=3D indirect_branch_keep) > ++ if (cfun->machine->indirect_branch_type !=3D 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 !=3D 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; > +=20 > ++ /* 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; > +=20 > +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] =3D convert_memory_address (word_mode, operands[0]); > ++ cfun->machine->has_local_indirect_jump =3D true; > + }) > +=20 > + (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 @@ > +=20 > + if (TARGET_X32 || ix86_indirect_branch_thunk_register) > + operands[0] =3D convert_memory_address (word_mode, operands[0]); > ++ cfun->machine->has_local_indirect_jump =3D true; > + }) > +=20 > + (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")]) > +--=20 > +2.15.1 > + > diff --git a/gnu/packages/patches/gcc-retpoline-Rename-thunks-to-__x86_in= direct_thunk_rax-etc.-to-re.patch b/gnu/packages/patches/gcc-retpoline-Rena= me-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-f= or-cpu_4.html > +https://support.google.com/faqs/answer/7625886 > +https://spectreattack.com/ > +https://cve.mitre.org/cgi-bin/cvename.cgi?name=3DCVE-2017-5715 > + > +Patch copied from the 'retpoline-20180107' branch of upstream source rep= ository > +(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 > +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 =3D TARGET_64BIT ? "r" : "e"; > + else > + reg_prefix =3D ""; > +- 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 =3D 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; > +=20 > +- /* 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 =3D build_decl (BUILTINS_LOCATION, FUNCTION_DECL, > + get_identifier (name), > +@@ -12165,7 +12165,7 @@ output_indirect_thunk_function (bool need_bnd_p,= int regno) > +=20 > + 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]; > +=20 > + indirect_thunk_name (alias, regno, need_bnd_p, true); > +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-1.c b/gcc/test= suite/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) > + } > +=20 > + /* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target= { ! x32 } } } } */ > +-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" { targ= et { ! x32 } } } } */ > +-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk\.(r|e)a= x" { target x32 } } } */ > ++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" { targ= et { ! 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/test= suite/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) > + } > +=20 > + /* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target= { ! x32 } } } } */ > +-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" { targ= et { ! x32 } } } } */ > +-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk\.(r|e)a= x" { target x32 } } } */ > ++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" { targ= et { ! 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/test= suite/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) > + } > +=20 > + /* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target= { ! x32 } } } } */ > +-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" { targ= et { ! x32 } } } } */ > +-/* { dg-final { scan-assembler "call\[ \t\]*__x86.indirect_thunk\.(r|e)= ax" { target x32 } } } */ > ++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" { targ= et { ! x32 } } } } */ > ++/* { dg-final { scan-assembler "call\[ \t\]*__x86_indirect_thunk_(r|e)a= x" { 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/test= suite/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) > + } > +=20 > + /* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target= { ! x32 } } } } */ > +-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" { targ= et { ! x32 } } } } */ > +-/* { dg-final { scan-assembler "call\[ \t\]*__x86.indirect_thunk\.(r|e)= ax" { target x32 } } } */ > ++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" { targ= et { ! x32 } } } } */ > ++/* { dg-final { scan-assembler "call\[ \t\]*__x86_indirect_thunk_(r|e)a= x" { 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/test= suite/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) > + } > +=20 > + /* { 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/test= suite/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) > + } > +=20 > + /* { 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/test= suite/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) > + } > +=20 > + /* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*\.L\[0-9\]+\\(,%" { = target { ! x32 } } } } */ > +-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" { targ= et { ! x32 } } } } */ > +-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk\.(r|e)a= x" { target x32 } } } */ > ++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" { targ= et { ! 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) > + } > +=20 > + /* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target= { ! x32 } } } } */ > +-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" { targ= et { ! x32 } } } } */ > +-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk\.(r|e)a= x" { target x32 } } } */ > ++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" { targ= et { ! 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) > + } > +=20 > + /* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target= { ! x32 } } } } */ > +-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" { targ= et { ! x32 } } } } */ > +-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk\.(r|e)a= x" { target x32 } } } */ > ++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" { targ= et { ! 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" { targ= et { ! x32 } } } } */ > +-/* { dg-final { scan-assembler "call\[ \t\]*__x86.indirect_thunk\.(r|e)= ax" { target x32 } } } */ > ++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" { targ= et { ! x32 } } } } */ > ++/* { dg-final { scan-assembler "call\[ \t\]*__x86_indirect_thunk_(r|e)a= x" { 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" { targ= et { ! x32 } } } } */ > +-/* { dg-final { scan-assembler "call\[ \t\]*__x86.indirect_thunk\.(r|e)= ax" { target x32 } } } */ > ++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" { targ= et { ! x32 } } } } */ > ++/* { dg-final { scan-assembler "call\[ \t\]*__x86_indirect_thunk_(r|e)a= x" { 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) > + } > +=20 > + /* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*\.L\[0-9\]+\\(,%" { = target { ! x32 } } } } */ > +-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk\.(r|e)a= x" { 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) > + } > + } > +=20 > +-/* { 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) > +=20 > + /* { 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) > +=20 > + /* { 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) > + } > +=20 > + /* { 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) > + } > +=20 > + /* { 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/g= cc/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) > + } > +=20 > + /* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target= { ! x32 } } } } */ > +-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" { targ= et { ! x32 } } } } */ > +-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk\.(r|e)a= x" { target x32 } } } */ > ++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" { targ= et { ! 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/g= cc/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) > + } > +=20 > + /* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target= { ! x32 } } } } */ > +-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" { targ= et { ! x32 } } } } */ > +-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk\.(r|e)a= x" { target x32 } } } */ > ++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" { targ= et { ! 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/g= cc/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) > + } > +=20 > + /* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target= { ! x32 } } } } */ > +-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" { targ= et { ! x32 } } } } */ > ++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" { targ= et { ! 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)a= x" { target x32 } } } */ > + /* { dg-final { scan-assembler-not {\t(lfence|pause)} } } */ > +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-4.c b/g= cc/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) > + } > +=20 > + /* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target= { ! x32 } } } } */ > +-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" { targ= et { ! x32 } } } } */ > ++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" { targ= et { ! 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)a= x" { target x32 } } } */ > + /* { dg-final { scan-assembler-not {\t(lfence|pause)} } } */ > +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-5.c b/g= cc/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) > + } > +=20 > + /* { 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/g= cc/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/g= cc/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) > + } > +=20 > + /* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*\.L\[0-9\]+\\(,%" { = target { ! x32 } } } } */ > +-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" { targ= et { ! x32 } } } } */ > +-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk\.(r|e)a= x" { target x32 } } } */ > ++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" { targ= et { ! 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/g= cc/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/g= cc/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/g= cc/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/g= cc/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/g= cc/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/g= cc/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/g= cc/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) > + } > +=20 > + /* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target= { ! x32 } } } } */ > +-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" { targ= et { ! x32 } } } } */ > +-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk\.(r|e)a= x" { target x32 } } } */ > ++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" { targ= et { ! 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) > + } > +=20 > + /* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target= { ! x32 } } } } */ > +-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" { targ= et { ! x32 } } } } */ > +-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk\.(r|e)a= x" { target x32 } } } */ > ++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" { targ= et { ! 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) > + } > +=20 > + /* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target= { ! x32 } } } } */ > +-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" { targ= et { ! x32 } } } } */ > +-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk\.(r|e)a= x" { target x32 } } } */ > ++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" { targ= et { ! 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) > + } > +=20 > + /* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target= { ! x32 } } } } */ > +-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" { targ= et { ! x32 } } } } */ > +-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk\.(r|e)a= x" { target x32 } } } */ > ++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" { targ= et { ! 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); > + } > +=20 > +-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk\.(r|e)a= x" } } */ > ++/* { 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); > + } > +=20 > +-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk\.(r|e)a= x" } } */ > ++/* { 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) > + { > + } > +=20 > +-/* { 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/testsuit= e/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) > +=20 > + /* { 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" { targ= et { ! 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:" { targe= t { x32 } } } } */ > ++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" { targ= et { ! x32 } } } } */ > ++/* { dg-final { scan-assembler "__x86_indirect_thunk:" { target { ! x32= } } } } */ > ++/* { dg-final { scan-assembler "call\[ \t\]*__x86_indirect_thunk_(r|e)a= x" { 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/testsuit= e/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; > + } > +=20 > +-/* { 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" { targ= et { ! 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:" { targe= t { x32 } } } } */ > ++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" { targ= et { ! x32 } } } } */ > ++/* { dg-final { scan-assembler "__x86_indirect_thunk:" { target { ! x32= } } } } */ > ++/* { dg-final { scan-assembler "call\[ \t\]*__x86_indirect_thunk_(r|e)a= x" { 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/testsuit= e/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; > + } > +=20 > +-/* { 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" { targ= et { ! 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:" { targe= t { x32 } } } } */ > ++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" { targ= et { ! x32 } } } } */ > ++/* { dg-final { scan-assembler "__x86_indirect_thunk:" { target { ! x32= } } } } */ > ++/* { dg-final { scan-assembler "call\[ \t\]*__x86_indirect_thunk_(r|e)a= x" { 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/testsuit= e/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; > + } > +=20 > +-/* { 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/testsuit= e/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) > + } > +=20 > + /* { 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" { targ= et { ! x32 } } } } */ > +-/* { dg-final { scan-assembler "call\[ \t\]*__x86.indirect_thunk\.(r|e)= ax" { target { x32 } } } } */ > ++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" { targ= et { ! x32 } } } } */ > ++/* { dg-final { scan-assembler "call\[ \t\]*__x86_indirect_thunk_(r|e)a= x" { 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/testsuit= e/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; > + } > +=20 > +-/* { 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" { targ= et { ! x32 } } } } */ > +-/* { dg-final { scan-assembler "call\[ \t\]*__x86.indirect_thunk\.(r|e)= ax" { target x32 } } } */ > ++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" { targ= et { ! x32 } } } } */ > ++/* { dg-final { scan-assembler "call\[ \t\]*__x86_indirect_thunk_(r|e)a= x" { 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/testsuit= e/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; > + } > +=20 > +-/* { 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) > + { > + } > +=20 > +-/* { 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) > + { > + } > +=20 > +-/* { 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) > + { > + } > +=20 > +-/* { 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) > + { > + } > +=20 > +-/* { 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) > + { > + } > +=20 > +-/* { 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; > + } > +=20 > +-/* { 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" { targ= et { ! x32 } } } } */ > ++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" { targ= et { ! 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)a= x" { target { x32 } } } } */ > + /* { dg-final { scan-assembler-not "pushq\[ \t\]%rax" { target x32 } } = } */ > +--=20 > +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-f= or-cpu_4.html > +https://support.google.com/faqs/answer/7625886 > +https://spectreattack.com/ > +https://cve.mitre.org/cgi-bin/cvename.cgi?name=3DCVE-2017-5715 > + > +Patch copied from the 'retpoline-20180107' branch of upstream source rep= ository > +(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" > +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 =3D false; > + static bool indirect_thunk_bnd_needed =3D false; > +=20 > ++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 =3D fals= e; > + /* Fills in the label name that should be used for the indirect thunk. = */ > +=20 > + 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 =3D need_bnd_p ? "_bnd" : ""; > +- sprintf (name, "__x86.indirect_thunk%s", bnd); > ++ if (regno >=3D 0) > ++ { > ++ const char *reg_prefix; > ++ if (LEGACY_INT_REGNO_P (regno)) > ++ reg_prefix =3D TARGET_64BIT ? "r" : "e"; > ++ else > ++ reg_prefix =3D ""; > ++ 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 >=3D 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); > ++ } > + } > + } > +=20 > + 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) > +=20 > + ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, indirectlabel2); > +=20 > +- /* LEA. */ > +- rtx xops[2]; > +- xops[0] =3D stack_pointer_rtx; > +- xops[1] =3D plus_constant (Pmode, stack_pointer_rtx, UNITS_PER_WORD); > +- output_asm_insn ("lea\t{%E1, %0|%0, %E1}", xops); > ++ if (regno >=3D 0) > ++ { > ++ /* MOV. */ > ++ rtx xops[2]; > ++ xops[0] =3D gen_rtx_MEM (word_mode, stack_pointer_rtx); > ++ xops[1] =3D gen_rtx_REG (word_mode, regno); > ++ output_asm_insn ("mov\t{%1, %0|%0, %1}", xops); > ++ } > ++ else > ++ { > ++ /* LEA. */ > ++ rtx xops[2]; > ++ xops[0] =3D stack_pointer_rtx; > ++ xops[1] =3D plus_constant (Pmode, stack_pointer_rtx, UNITS_PER_WO= RD); > ++ output_asm_insn ("lea\t{%E1, %0|%0, %E1}", xops); > ++ } > +=20 > + if (need_bnd_p) > + fputs ("\tbnd ret\n", asm_out_file); > +@@ -12015,12 +12050,13 @@ output_indirect_thunk (bool need_bnd_p) > + } > +=20 > + 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; > +=20 > +- indirect_thunk_name (name, need_bnd_p); > ++ /* Create __x86.indirect_thunk/__x86.indirect_thunk_bnd. */ > ++ indirect_thunk_name (name, regno, need_bnd_p); > + decl =3D 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); > +=20 > +- output_indirect_thunk (need_bnd_p); > ++ output_indirect_thunk (need_bnd_p, regno); > +=20 > + final_end_function (); > + init_insn_lengths (); > +@@ -12110,15 +12146,31 @@ ix86_code_end (void) > + int regno; > +=20 > + 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 =3D FIRST_REX_INT_REG; regno <=3D LAST_REX_INT_REG; regno+= +) > ++ { > ++ int i =3D 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); > ++ } > +=20 > + for (regno =3D AX_REG; regno <=3D SP_REG; regno++) > + { > + char name[32]; > + tree decl; > +=20 > ++ 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; > +=20 > +@@ -28639,17 +28691,37 @@ ix86_output_indirect_branch (rtx call_op, cons= t char *xasm, > + char *thunk_name; > + char push_buf[64]; > + bool need_bnd_p =3D ix86_bnd_prefixed_insn_p (current_output_insn); > ++ int regno; > ++ > ++ if (REG_P (call_op)) > ++ regno =3D REGNO (call_op); > ++ else > ++ regno =3D -1; > +=20 > + if (cfun->machine->indirect_branch_type > + !=3D indirect_branch_thunk_inline) > + { > +- bool need_thunk > +- =3D cfun->machine->indirect_branch_type =3D=3D indirect_branch_thunk; > +- if (need_bnd_p) > +- indirect_thunk_bnd_needed |=3D need_thunk; > +- else > +- indirect_thunk_needed |=3D need_thunk; > +- indirect_thunk_name (thunk_name_buf, need_bnd_p); > ++ if (cfun->machine->indirect_branch_type =3D=3D indirect_branch_th= unk) > ++ { > ++ if (regno >=3D 0) > ++ { > ++ int i =3D regno; > ++ if (i >=3D FIRST_REX_INT_REG) > ++ i -=3D (FIRST_REX_INT_REG - LAST_INT_REG - 1); > ++ if (need_bnd_p) > ++ indirect_thunks_bnd_used |=3D 1 << i; > ++ else > ++ indirect_thunks_used |=3D 1 << i; > ++ } > ++ else > ++ { > ++ if (need_bnd_p) > ++ indirect_thunk_bnd_needed =3D true; > ++ else > ++ indirect_thunk_needed =3D true; > ++ } > ++ } > ++ indirect_thunk_name (thunk_name_buf, regno, need_bnd_p); > + thunk_name =3D thunk_name_buf; > + } > + else > +@@ -28660,7 +28732,8 @@ ix86_output_indirect_branch (rtx call_op, const = char *xasm, > +=20 > + if (sibcall_p) > + { > +- output_asm_insn (push_buf, &call_op); > ++ if (regno < 0) > ++ output_asm_insn (push_buf, &call_op); > + if (thunk_name !=3D NULL) > + { > + if (need_bnd_p) > +@@ -28669,10 +28742,19 @@ ix86_output_indirect_branch (rtx call_op, cons= t 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 >=3D 0 && thunk_name !=3D 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]; > +=20 > +@@ -28725,7 +28807,8 @@ ix86_output_indirect_branch (rtx call_op, const = char *xasm, > + } > + } > +=20 > +- output_asm_insn (push_buf, &call_op); > ++ if (regno < 0) > ++ output_asm_insn (push_buf, &call_op); > +=20 > + if (thunk_name !=3D 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); > +=20 > + ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, indirectlabel2); > +=20 > +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-1.c b/gcc/test= suite/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) > + } > +=20 > + /* { 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" { targ= et { ! x32 } } } } */ > ++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk\.(r|e)a= x" { 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/test= suite/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) > + } > +=20 > + /* { 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" { targ= et { ! x32 } } } } */ > ++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk\.(r|e)a= x" { 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/test= suite/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) > + } > +=20 > + /* { 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" { targ= et { ! 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/test= suite/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) > + } > +=20 > + /* { 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" { targ= et { ! 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/test= suite/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) > + } > +=20 > + /* { 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" { targ= et { ! x32 } } } } */ > ++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk\.(r|e)a= x" { 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) > + } > +=20 > + /* { 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" { targ= et { ! x32 } } } } */ > ++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk\.(r|e)a= x" { 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) > + } > +=20 > + /* { 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" { targ= et { ! x32 } } } } */ > ++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk\.(r|e)a= x" { 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) > + } > +=20 > + /* { 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) > + } > +=20 > + /* { 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) > + } > +=20 > + /* { 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" { targ= et { ! 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) > + } > +=20 > + /* { 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" { targ= et { ! 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) > + } > +=20 > + /* { 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)a= x" { 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/g= cc/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) > + } > +=20 > + /* { 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" { targ= et { ! x32 } } } } */ > ++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk\.(r|e)a= x" { 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/g= cc/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) > + } > +=20 > + /* { 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" { targ= et { ! x32 } } } } */ > ++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk\.(r|e)a= x" { 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/g= cc/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) > + } > +=20 > + /* { 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" { targ= et { ! 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/g= cc/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) > + } > +=20 > + /* { 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" { targ= et { ! 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/g= cc/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) > + } > +=20 > + /* { 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" { targ= et { ! x32 } } } } */ > ++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk\.(r|e)a= x" { 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/g= cc/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) > + } > +=20 > + /* { 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/g= cc/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) > + } > +=20 > + /* { 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/g= cc/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) > + } > +=20 > + /* { 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/g= cc/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) > + } > +=20 > + /* { 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/g= cc/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) > + } > +=20 > + /* { 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" } } */ > +--=20 > +2.15.1 > + > diff --git a/gnu/packages/patches/gcc-retpoline-i386-Add-V-register-opera= nd-modifier.patch b/gnu/packages/patches/gcc-retpoline-i386-Add-V-register-= operand-modifier.patch > new file mode 100644 > index 000000000..1996a1dfe > --- /dev/null > +++ b/gnu/packages/patches/gcc-retpoline-i386-Add-V-register-operand-modi= fier.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-f= or-cpu_4.html > +https://support.google.com/faqs/answer/7625886 > +https://spectreattack.com/ > +https://cve.mitre.org/cgi-bin/cvename.cgi?name=3DCVE-2017-5715 > + > +Patch copied from the 'retpoline-20180107' branch of upstream source rep= ository > +(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" > +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 o= p. > + If CODE is 'd', duplicate the operand for AVX instruction. > ++ If CODE is 'V', print naked register name without %. > + */ > +=20 > + void > +@@ -17896,7 +17897,7 @@ print_reg (rtx x, int code, FILE *file) > + unsigned int regno; > + bool duplicated; > +=20 > +- if (ASSEMBLER_DIALECT =3D=3D ASM_ATT) > ++ if (ASSEMBLER_DIALECT =3D=3D ASM_ATT && code !=3D 'V') > + putc ('%', file); > +=20 > + if (x =3D=3D 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; > +=20 > + case 's': > +--=20 > +2.15.1 > + > diff --git a/gnu/packages/patches/gcc-retpoline-i386-More-use-reference-o= f-struct-ix86_frame-to-avoi.patch b/gnu/packages/patches/gcc-retpoline-i386= -More-use-reference-of-struct-ix86_frame-to-avoi.patch > new file mode 100644 > index 000000000..3c42dd802 > --- /dev/null > +++ b/gnu/packages/patches/gcc-retpoline-i386-More-use-reference-of-struc= t-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-f= or-cpu_4.html > +https://support.google.com/faqs/answer/7625886 > +https://spectreattack.com/ > +https://cve.mitre.org/cgi-bin/cvename.cgi?name=3DCVE-2017-5715 > + > +Patch copied from the 'retpoline-20180107' branch of upstream source rep= ository > +(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" > +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 =3D 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 =3D true; > +=20 > + ix86_compute_frame_layout (); > +- frame =3D m->frame; > ++ struct ix86_frame &frame =3D cfun->machine->frame; > +=20 > + if (!TARGET_64BIT && ix86_function_ms_hook_prologue (current_function= _decl)) > + { > +@@ -14343,13 +14342,12 @@ ix86_expand_epilogue (int style) > + { > + struct machine_function *m =3D cfun->machine; > + struct machine_frame_state frame_state_save =3D m->fs; > +- struct ix86_frame frame; > + bool restore_regs_via_mov; > + bool using_drap; > +=20 > + ix86_finalize_stack_realign_flags (); > + ix86_compute_frame_layout (); > +- frame =3D m->frame; > ++ struct ix86_frame &frame =3D cfun->machine->frame; > +=20 > + m->fs.sp_valid =3D (!frame_pointer_needed > + || (crtl->sp_is_unchanging > +--=20 > +2.15.1 > + > diff --git a/gnu/packages/patches/gcc-retpoline-i386-Move-struct-ix86_fra= me-to-machine_function.patch b/gnu/packages/patches/gcc-retpoline-i386-Move= -struct-ix86_frame-to-machine_function.patch > new file mode 100644 > index 000000000..908e3cd83 > --- /dev/null > +++ b/gnu/packages/patches/gcc-retpoline-i386-Move-struct-ix86_frame-to-m= achine_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-f= or-cpu_4.html > +https://support.google.com/faqs/answer/7625886 > +https://spectreattack.com/ > +https://cve.mitre.org/cgi-bin/cvename.cgi?name=3DCVE-2017-5715 > + > +Patch copied from the 'retpoline-20180107' branch of upstream source rep= ository > +(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" > +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; > + }; > +=20 > +-/* 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] | =3D 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; > +=20 > +@@ -2579,7 +2532,7 @@ static unsigned int ix86_function_arg_boundary (ma= chine_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 >=3D 32768) > + return 0; > +=20 > +- ix86_compute_frame_layout (&frame); > ++ ix86_compute_frame_layout (); > ++ frame =3D cfun->machine->frame; > + return (frame.stack_pointer_offset =3D=3D UNITS_PER_WORD > + && (frame.nregs + frame.nsseregs) =3D=3D 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 =3D cfun->machine->frame; > +=20 > + if (from =3D=3D ARG_POINTER_REGNUM && to =3D=3D HARD_FRAME_POINTER_RE= GNUM) > + 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= . */ > +=20 > + static void > +-ix86_compute_frame_layout (struct ix86_frame *frame) > ++ix86_compute_frame_layout (void) > + { > ++ struct ix86_frame *frame =3D &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 =3D INCOMING_FRAME_SP_OFFSET; > + m->fs.sp_valid =3D true; > +=20 > +- ix86_compute_frame_layout (&frame); > ++ ix86_compute_frame_layout (); > ++ frame =3D m->frame; > +=20 > + if (!TARGET_64BIT && ix86_function_ms_hook_prologue (current_function= _decl)) > + { > +@@ -14394,7 +14350,8 @@ ix86_expand_epilogue (int style) > + bool using_drap; > +=20 > + ix86_finalize_stack_realign_flags (); > +- ix86_compute_frame_layout (&frame); > ++ ix86_compute_frame_layout (); > ++ frame =3D m->frame; > +=20 > + m->fs.sp_valid =3D (!frame_pointer_needed > + || (crtl->sp_is_unchanging > +@@ -14904,7 +14861,8 @@ ix86_expand_split_stack_prologue (void) > + gcc_assert (flag_split_stack && reload_completed); > +=20 > + ix86_finalize_stack_realign_flags (); > +- ix86_compute_frame_layout (&frame); > ++ ix86_compute_frame_layout (); > ++ frame =3D cfun->machine->frame; > + allocate =3D frame.stack_pointer_offset - INCOMING_FRAME_SP_OFFSET; > +=20 > + /* 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] | =3D 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.= */ > +=20 > +-#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]; > +=20 > ++ /* 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 (S= P_REG)) > + #define ix86_static_chain_on_stack (cfun->machine->static_chain_on_stac= k) > ++#define ix86_red_zone_size (cfun->machine->frame.red_zone_size) > +=20 > + /* Control behavior of x86_file_start. */ > + #define X86_FILE_START_VERSION_DIRECTIVE false > +--=20 > +2.15.1 > + > diff --git a/gnu/packages/patches/gcc-retpoline-i386-Use-reference-of-str= uct-ix86_frame-to-avoid-cop.patch b/gnu/packages/patches/gcc-retpoline-i386= -Use-reference-of-struct-ix86_frame-to-avoid-cop.patch > new file mode 100644 > index 000000000..623ce5094 > --- /dev/null > +++ b/gnu/packages/patches/gcc-retpoline-i386-Use-reference-of-struct-ix8= 6_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-f= or-cpu_4.html > +https://support.google.com/faqs/answer/7625886 > +https://spectreattack.com/ > +https://cve.mitre.org/cgi-bin/cvename.cgi?name=3DCVE-2017-5715 > + > +Patch copied from the 'retpoline-20180107' branch of upstream source rep= ository > +(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 > +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-041= 0-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; > +=20 > + ix86_compute_frame_layout (); > +- frame =3D cfun->machine->frame; > ++ struct ix86_frame &frame =3D cfun->machine->frame; > + return (frame.stack_pointer_offset =3D=3D UNITS_PER_WORD > + && (frame.nregs + frame.nsseregs) =3D=3D 0); > + } > +@@ -12333,7 +12331,7 @@ HOST_WIDE_INT > + ix86_initial_elimination_offset (int from, int to) > + { > + ix86_compute_frame_layout (); > +- struct ix86_frame frame =3D cfun->machine->frame; > ++ struct ix86_frame &frame =3D cfun->machine->frame; > +=20 > + if (from =3D=3D ARG_POINTER_REGNUM && to =3D=3D HARD_FRAME_POINTER_RE= GNUM) > + 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) > +=20 > + ix86_finalize_stack_realign_flags (); > + ix86_compute_frame_layout (); > +- frame =3D cfun->machine->frame; > ++ struct ix86_frame &frame =3D cfun->machine->frame; > + allocate =3D frame.stack_pointer_offset - INCOMING_FRAME_SP_OFFSET; > +=20 > + /* This is the label we will branch to if we have enough stack > +--=20 > +2.15.1 > + From unknown Sun Jun 22 07:57:08 2025 X-Loop: help-debbugs@gnu.org Subject: [bug#30111] gnu: gcc@7: Apply the 'retpoline' mitigation technique. Resent-From: Alex Vong Original-Sender: "Debbugs-submit" Resent-CC: guix-patches@gnu.org Resent-Date: Tue, 16 Jan 2018 13:16:01 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 30111 X-GNU-PR-Package: guix-patches X-GNU-PR-Keywords: security patch To: 30111@debbugs.gnu.org Received: via spool by 30111-submit@debbugs.gnu.org id=B30111.151610851928953 (code B ref 30111); Tue, 16 Jan 2018 13:16:01 +0000 Received: (at 30111) by debbugs.gnu.org; 16 Jan 2018 13:15:19 +0000 Received: from localhost ([127.0.0.1]:58175 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1ebR5D-0007Wv-AU for submit@debbugs.gnu.org; Tue, 16 Jan 2018 08:15:19 -0500 Received: from mail-pf0-f169.google.com ([209.85.192.169]:34098) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1ebR5C-0007Wj-0W for 30111@debbugs.gnu.org; Tue, 16 Jan 2018 08:15:18 -0500 Received: by mail-pf0-f169.google.com with SMTP id e76so9658410pfk.1 for <30111@debbugs.gnu.org>; Tue, 16 Jan 2018 05:15:17 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:subject:references:date:in-reply-to:message-id:user-agent :mime-version; bh=6nQ9aAckMMlFfgpjR38uza66YRiUOQhZ70cb27Jdn2g=; b=gk9BCi+C1/HPneCcNdfZouUgFhO0OqfsBz7XqYarKG4z31Ri4y6buGW4eRR/1aDbrN VUaGkF2jqwyO/n3SunyKWpfzQuV9rUC0v+oomgib7x13zArM4U9/CoxMfp+p8Fe+2XYU ZmB2HTsnZBk2xUgPy7Ko+N2e8vJdjokFUSHYdQcNL5WhaSXk2XcXw0HlQ7q3MwLuZe9/ Vz+u3h7eX/eVjc6gCzZo5vqBHMBi3XvX7eHyRdFFJCYiSGtj3B/Lz5WfQnPewLtgmUW5 K0mSmBSDr7etreSCs+xVWrIVlB48hbpvUIsL0otaddg/fR4H7ylQ1x4bCU4COBuesb+9 hl4A== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:subject:references:date:in-reply-to :message-id:user-agent:mime-version; bh=6nQ9aAckMMlFfgpjR38uza66YRiUOQhZ70cb27Jdn2g=; b=Q0V34CDKFkfVhROjs01+QCr5WPo22ksVrlfZBXGyObVhO0JN0CtR5/p+1tgEW1mEkE 1qn6myJJGjpy030P8SSiCOW63PQbWIK+KVN7YjNLnWZppVd91FtwbOS7inl5tht914OA 7jxissRNMnihi5F0ehgqvc/j97QAhSxy/jedsW8QMCWIET6dKkVVGdhM84uUnyEVSTwt 0qVAn6edRyhpJLDqyUFQZOx05PgpNBhcb00VpohhqXY9pxXEiPIt9zomT/sZlQQakNqw cK0+dceUW1XJEiaSy791vcsuR4uqoRwhC5hPnlGaxSkj6tq4KYbup468atSAIwjPvgEw xdIg== X-Gm-Message-State: AKGB3mIfylLtkCY7pK5XkZLr+KKpzplCaKhOX+CwaaG8FvWMOib0rSKi 0L/jhk+VvfK1q8HxT41c6jk= X-Google-Smtp-Source: ACJfBoupBAUJbcGMPWlgVbPKYSYWTwPRzegCtRv5bVNXaZBxZNoKH6/tvchshzqGnXAupwvNwVowFA== X-Received: by 10.98.98.5 with SMTP id w5mr34296309pfb.233.1516108512160; Tue, 16 Jan 2018 05:15:12 -0800 (PST) Received: from debian (n218250002129.netvigator.com. [218.250.2.129]) by smtp.gmail.com with ESMTPSA id u195sm3733537pgb.64.2018.01.16.05.15.08 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Tue, 16 Jan 2018 05:15:11 -0800 (PST) From: Alex Vong References: <877esksi62.fsf@gmail.com> <87d12bgpqh.fsf@gmail.com> Date: Tue, 16 Jan 2018 21:14:54 +0800 In-Reply-To: <87d12bgpqh.fsf@gmail.com> (Alex Vong's message of "Mon, 15 Jan 2018 22:29:10 +0800") Message-ID: <87a7xet06p.fsf@gmail.com> User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/25.3 (gnu/linux) MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="=-=-=" X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" --=-=-= Content-Type: text/plain Hello, This is the new patch. Similar to last time, I haven't test it yet, but I will report if it doesn't build. --=-=-= Content-Type: text/x-diff; charset=utf-8 Content-Disposition: inline; filename=0001-gnu-gcc-7-Apply-the-retpoline-mitigation-technique.patch Content-Transfer-Encoding: quoted-printable >From aea3d11f59e260111bdb8bcac458c97a946fa900 Mon Sep 17 00:00:00 2001 From: Alex Vong Date: Tue, 16 Jan 2018 20:32:32 +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 . * gnu/local.mk (dist_patch_DATA): Add them. * gnu/packages/gcc.scm (gcc@7): Use them. * gnu/packages/patches/gcc-retpoline-Change-V-to-bare-reg-names.patch, gnu/packages/patches/gcc-retpoline-i386-More-use-reference-of-struct-ix86_f= rame-to-avoi.patch, gnu/packages/patches/gcc-retpoline-i386-Move-struct-ix86_frame-to-machine_f= unction.patch, gnu/packages/patches/gcc-retpoline-i386-Use-reference-of-struct-ix86_frame-= to-avoid-cop.patch, gnu/packages/patches/gcc-retpoline-indirect-thunk-reg-names.patch, gnu/packages/patches/gcc-retpoline-x86-Add-V-register-operand-modifier.patc= h, gnu/packages/patches/gcc-retpoline-x86-Add-mfunction-return.patch, gnu/packages/patches/gcc-retpoline-x86-Add-mindirect-branch-register.patch, gnu/packages/patches/gcc-retpoline-x86-Add-mindirect-branch.patch, gnu/packages/patches/gcc-retpoline-x86-Disallow-mindirect-branch-mfunction-= return-with-.patch: New files. --- gnu/local.mk | 12 +- gnu/packages/gcc.scm | 13 +- .../gcc-retpoline-Change-V-to-bare-reg-names.patch | 51 + ...se-reference-of-struct-ix86_frame-to-avoi.patch | 69 + ...ove-struct-ix86_frame-to-machine_function.patch | 252 +++ ...ference-of-struct-ix86_frame-to-avoid-cop.patch | 83 + .../gcc-retpoline-indirect-thunk-reg-names.patch | 365 ++++ ...oline-x86-Add-V-register-operand-modifier.patch | 143 ++ .../gcc-retpoline-x86-Add-mfunction-return.patch | 1303 ++++++++++++ ...tpoline-x86-Add-mindirect-branch-register.patch | 907 ++++++++ .../gcc-retpoline-x86-Add-mindirect-branch.patch | 2171 ++++++++++++++++= ++++ ...w-mindirect-branch-mfunction-return-with-.patch | 308 +++ 12 files changed, 5675 insertions(+), 2 deletions(-) create mode 100644 gnu/packages/patches/gcc-retpoline-Change-V-to-bare-reg= -names.patch create mode 100644 gnu/packages/patches/gcc-retpoline-i386-More-use-refere= nce-of-struct-ix86_frame-to-avoi.patch create mode 100644 gnu/packages/patches/gcc-retpoline-i386-Move-struct-ix8= 6_frame-to-machine_function.patch create mode 100644 gnu/packages/patches/gcc-retpoline-i386-Use-reference-o= f-struct-ix86_frame-to-avoid-cop.patch create mode 100644 gnu/packages/patches/gcc-retpoline-indirect-thunk-reg-n= ames.patch create mode 100644 gnu/packages/patches/gcc-retpoline-x86-Add-V-register-o= perand-modifier.patch create mode 100644 gnu/packages/patches/gcc-retpoline-x86-Add-mfunction-re= turn.patch create mode 100644 gnu/packages/patches/gcc-retpoline-x86-Add-mindirect-br= anch-register.patch create mode 100644 gnu/packages/patches/gcc-retpoline-x86-Add-mindirect-br= anch.patch create mode 100644 gnu/packages/patches/gcc-retpoline-x86-Disallow-mindire= ct-branch-mfunction-return-with-.patch diff --git a/gnu/local.mk b/gnu/local.mk index fb4babfdb..b84d0b545 100644 --- a/gnu/local.mk +++ b/gnu/local.mk @@ -9,7 +9,7 @@ # Copyright =C2=A9 2016 Adonay "adfeno" Felipe Nogueira # Copyright =C2=A9 2016, 2017 Ricardo Wurmus # Copyright =C2=A9 2016 Ben Woodcroft -# Copyright =C2=A9 2016, 2017 Alex Vong +# Copyright =C2=A9 2016, 2017, 2018 Alex Vong # Copyright =C2=A9 2016, 2017 Efraim Flashner # Copyright =C2=A9 2016, 2017 Jan Nieuwenhuizen # Copyright =C2=A9 2017 Tobias Geerinckx-Rice @@ -654,6 +654,16 @@ dist_patch_DATA =3D \ %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-machin= e_function.patch \ + %D%/packages/patches/gcc-retpoline-i386-Use-reference-of-struct-ix86_fra= me-to-avoid-cop.patch \ + %D%/packages/patches/gcc-retpoline-i386-More-use-reference-of-struct-ix8= 6_frame-to-avoi.patch \ + %D%/packages/patches/gcc-retpoline-x86-Add-mindirect-branch.patch \ + %D%/packages/patches/gcc-retpoline-x86-Add-mfunction-return.patch \ + %D%/packages/patches/gcc-retpoline-x86-Add-mindirect-branch-register.pat= ch \ + %D%/packages/patches/gcc-retpoline-x86-Add-V-register-operand-modifier.p= atch \ + %D%/packages/patches/gcc-retpoline-x86-Disallow-mindirect-branch-mfuncti= on-return-with-.patch \ + %D%/packages/patches/gcc-retpoline-Change-V-to-bare-reg-names.patch \ + %D%/packages/patches/gcc-retpoline-indirect-thunk-reg-names.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..89d2ab7fd 100644 --- a/gnu/packages/gcc.scm +++ b/gnu/packages/gcc.scm @@ -5,6 +5,7 @@ ;;; Copyright =C2=A9 2015 Andreas Enge ;;; Copyright =C2=A9 2015, 2016, 2017 Efraim Flashner ;;; Copyright =C2=A9 2016 Carlos S=C3=A1nchez de La Lama +;;; Copyright =C2=A9 2018 ALex Vong ;;; ;;; This file is part of GNU Guix. ;;; @@ -427,7 +428,17 @@ Go. It also includes runtime support libraries for th= ese 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-ix8= 6_frame-to-machine_function.patch" + "gcc-retpoline-i386-Use-reference-o= f-struct-ix86_frame-to-avoid-cop.patch" + "gcc-retpoline-i386-More-use-refere= nce-of-struct-ix86_frame-to-avoi.patch" + "gcc-retpoline-x86-Add-mindirect-br= anch.patch" + "gcc-retpoline-x86-Add-mfunction-re= turn.patch" + "gcc-retpoline-x86-Add-mindirect-br= anch-register.patch" + "gcc-retpoline-x86-Add-V-register-o= perand-modifier.patch" + "gcc-retpoline-x86-Disallow-mindire= ct-branch-mfunction-return-with-.patch" + "gcc-retpoline-Change-V-to-bare-reg= -names.patch" + "gcc-retpoline-indirect-thunk-reg-n= ames.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-Change-V-to-bare-reg-names.= patch b/gnu/packages/patches/gcc-retpoline-Change-V-to-bare-reg-names.patch new file mode 100644 index 000000000..1d893a621 --- /dev/null +++ b/gnu/packages/patches/gcc-retpoline-Change-V-to-bare-reg-names.patch @@ -0,0 +1,51 @@ +'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=3DCVE-2017-5715 + +Patch copied from the 'retpoline-regnames' branch of upstream source repos= itory +(please keep an eye for new branches or updates for existing branches): + +http://git.infradead.org/users/dwmw2/gcc-retpoline.git + +From c26d2b96599ebc9ff24c685a2dc3b01709aa3cce Mon Sep 17 00:00:00 2001 +From: David Woodhouse +Date: Sun, 14 Jan 2018 21:27:35 +0000 +Subject: [PATCH 09/10] Change %V to bare reg names + +--- + gcc/config/i386/i386.c | 2 +- + gcc/testsuite/gcc.target/i386/indirect-thunk-register-4.c | 4 ++-- + 2 files changed, 3 insertions(+), 3 deletions(-) + +diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c +index 318a71840c9..6d345031a82 100644 +--- a/gcc/config/i386/i386.c ++++ b/gcc/config/i386/i386.c +@@ -18029,7 +18029,7 @@ print_reg (rtx x, int code, FILE *file) + warning (0, "unsupported size for integer register"); + /* FALLTHRU */ + case 4: +- if (LEGACY_INT_REGNO_P (regno)) ++ if (LEGACY_INT_REGNO_P (regno) && code !=3D 'V') + putc (msize > 4 && TARGET_64BIT ? 'r' : 'e', file); + /* FALLTHRU */ + case 2: +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-register-4.c b/g= cc/testsuite/gcc.target/i386/indirect-thunk-register-4.c +index f0cd9b75be8..6791890944c 100644 +--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-register-4.c ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-register-4.c +@@ -9,5 +9,5 @@ foo (void) + asm("call __x86_indirect_thunk_%V0" : : "a" (func_p)); + } +=20 +-/* { dg-final { scan-assembler "call\[ \t\]*__x86_indirect_thunk_eax" { t= arget ia32 } } } */ +-/* { dg-final { scan-assembler "call\[ \t\]*__x86_indirect_thunk_rax" { t= arget { ! ia32 } } } } */ ++/* { dg-final { scan-assembler "call\[ \t\]*__x86_indirect_thunk_ax" { ta= rget ia32 } } } */ ++/* { dg-final { scan-assembler "call\[ \t\]*__x86_indirect_thunk_ax" { ta= rget { ! ia32 } } } } */ +--=20 +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-M= ore-use-reference-of-struct-ix86_frame-to-avoi.patch new file mode 100644 index 000000000..e115e3f6c --- /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=3DCVE-2017-5715 + +Patch copied from the 'retpoline-regnames' branch of upstream source repos= itory +(please keep an eye for new branches or updates for existing branches): + +http://git.infradead.org/users/dwmw2/gcc-retpoline.git + +From ec4a7ca4051bb5cbefe03a2e1fb690b9738b8c6d Mon Sep 17 00:00:00 2001 +From: "H.J. Lu" +Date: Tue, 28 Nov 2017 10:26:35 -0800 +Subject: [PATCH 03/10] i386: More use reference of struct ix86_frame to av= oid + copy + +When there is no need to make a copy of ix86_frame, we can use reference +of struct ix86_frame to avoid copy. + + Backport from mainline + * 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 397ef7cac26..986e6d79584 100644 +--- a/gcc/config/i386/i386.c ++++ b/gcc/config/i386/i386.c +@@ -13667,7 +13667,6 @@ ix86_expand_prologue (void) + { + struct machine_function *m =3D cfun->machine; + rtx insn, t; +- struct ix86_frame frame; + HOST_WIDE_INT allocate; + bool int_registers_saved; + bool sse_registers_saved; +@@ -13691,7 +13690,7 @@ ix86_expand_prologue (void) + m->fs.sp_valid =3D true; +=20 + ix86_compute_frame_layout (); +- frame =3D m->frame; ++ struct ix86_frame &frame =3D cfun->machine->frame; +=20 + if (!TARGET_64BIT && ix86_function_ms_hook_prologue (current_function_d= ecl)) + { +@@ -14354,13 +14353,12 @@ ix86_expand_epilogue (int style) + { + struct machine_function *m =3D cfun->machine; + struct machine_frame_state frame_state_save =3D m->fs; +- struct ix86_frame frame; + bool restore_regs_via_mov; + bool using_drap; +=20 + ix86_finalize_stack_realign_flags (); + ix86_compute_frame_layout (); +- frame =3D m->frame; ++ struct ix86_frame &frame =3D cfun->machine->frame; +=20 + m->fs.sp_valid =3D (!frame_pointer_needed + || (crtl->sp_is_unchanging +--=20 +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-s= truct-ix86_frame-to-machine_function.patch new file mode 100644 index 000000000..b55ee3407 --- /dev/null +++ b/gnu/packages/patches/gcc-retpoline-i386-Move-struct-ix86_frame-to-mac= hine_function.patch @@ -0,0 +1,252 @@ +'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=3DCVE-2017-5715 + +Patch copied from the 'retpoline-regnames' branch of upstream source repos= itory +(please keep an eye for new branches or updates for existing branches): + +http://git.infradead.org/users/dwmw2/gcc-retpoline.git + +From f23f45109139911714e2164191c0228500ebef92 Mon Sep 17 00:00:00 2001 +From: "H.J. Lu" +Date: Mon, 6 Nov 2017 09:11:08 -0800 +Subject: [PATCH 01/10] i386: Move struct ix86_frame to machine_function + +Make ix86_frame available to i386 code generation. This is needed to +backport the patch set of -mindirect-branch=3D to mitigate variant #2 of +the speculative execution vulnerabilities on x86 processors identified +by CVE-2017-5715, aka Spectre. + + Backport from mainline + * 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 8a3782c0298..813337242d8 100644 +--- a/gcc/config/i386/i386.c ++++ b/gcc/config/i386/i386.c +@@ -2444,53 +2444,6 @@ struct GTY(()) stack_local_entry { + struct stack_local_entry *next; + }; +=20 +-/* 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] | =3D 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; +=20 +@@ -2582,7 +2535,7 @@ static unsigned int ix86_function_arg_boundary (mach= ine_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); +@@ -11903,7 +11856,8 @@ ix86_can_use_return_insn_p (void) + if (crtl->args.pops_args && crtl->args.size >=3D 32768) + return 0; +=20 +- ix86_compute_frame_layout (&frame); ++ ix86_compute_frame_layout (); ++ frame =3D cfun->machine->frame; + return (frame.stack_pointer_offset =3D=3D UNITS_PER_WORD + && (frame.nregs + frame.nsseregs) =3D=3D 0); + } +@@ -12389,8 +12343,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 =3D cfun->machine->frame; +=20 + if (from =3D=3D ARG_POINTER_REGNUM && to =3D=3D HARD_FRAME_POINTER_REGN= UM) + return frame.hard_frame_pointer_offset; +@@ -12429,8 +12383,9 @@ ix86_builtin_setjmp_frame_value (void) + /* Fill structure ix86_frame about frame of currently computed function. = */ +=20 + static void +-ix86_compute_frame_layout (struct ix86_frame *frame) ++ix86_compute_frame_layout (void) + { ++ struct ix86_frame *frame =3D &cfun->machine->frame; + unsigned HOST_WIDE_INT stack_alignment_needed; + HOST_WIDE_INT offset; + unsigned HOST_WIDE_INT preferred_alignment; +@@ -13737,7 +13692,8 @@ ix86_expand_prologue (void) + m->fs.sp_offset =3D INCOMING_FRAME_SP_OFFSET; + m->fs.sp_valid =3D true; +=20 +- ix86_compute_frame_layout (&frame); ++ ix86_compute_frame_layout (); ++ frame =3D m->frame; +=20 + if (!TARGET_64BIT && ix86_function_ms_hook_prologue (current_function_d= ecl)) + { +@@ -14405,7 +14361,8 @@ ix86_expand_epilogue (int style) + bool using_drap; +=20 + ix86_finalize_stack_realign_flags (); +- ix86_compute_frame_layout (&frame); ++ ix86_compute_frame_layout (); ++ frame =3D m->frame; +=20 + m->fs.sp_valid =3D (!frame_pointer_needed + || (crtl->sp_is_unchanging +@@ -14915,7 +14872,8 @@ ix86_expand_split_stack_prologue (void) + gcc_assert (flag_split_stack && reload_completed); +=20 + ix86_finalize_stack_realign_flags (); +- ix86_compute_frame_layout (&frame); ++ ix86_compute_frame_layout (); ++ frame =3D cfun->machine->frame; + allocate =3D frame.stack_pointer_offset - INCOMING_FRAME_SP_OFFSET; +=20 + /* 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 9c776dc5172..f9b91286a01 100644 +--- a/gcc/config/i386/i386.h ++++ b/gcc/config/i386/i386.h +@@ -2451,9 +2451,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] | =3D 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. = */ +=20 +-#ifndef USED_FOR_TARGET + struct GTY(()) machine_frame_state + { + /* This pair tracks the currently active CFA as reg+offset. When reg +@@ -2512,6 +2559,9 @@ struct GTY(()) machine_function { + int varargs_fpr_size; + int optimize_mode_switching[MAX_386_ENTITIES]; +=20 ++ /* 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; +@@ -2594,6 +2644,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) +=20 + /* Control behavior of x86_file_start. */ + #define X86_FILE_START_VERSION_DIRECTIVE false +--=20 +2.15.1 + diff --git a/gnu/packages/patches/gcc-retpoline-i386-Use-reference-of-struc= t-ix86_frame-to-avoid-cop.patch b/gnu/packages/patches/gcc-retpoline-i386-U= se-reference-of-struct-ix86_frame-to-avoid-cop.patch new file mode 100644 index 000000000..30eca1a43 --- /dev/null +++ b/gnu/packages/patches/gcc-retpoline-i386-Use-reference-of-struct-ix86_= frame-to-avoid-cop.patch @@ -0,0 +1,83 @@ +'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=3DCVE-2017-5715 + +Patch copied from the 'retpoline-regnames' branch of upstream source repos= itory +(please keep an eye for new branches or updates for existing branches): + +http://git.infradead.org/users/dwmw2/gcc-retpoline.git + +From ca658cd57c02a81327ec09474e24f0688ac1a190 Mon Sep 17 00:00:00 2001 +From: hjl +Date: Mon, 6 Nov 2017 23:04:15 +0000 +Subject: [PATCH 02/10] i386: Use reference of struct ix86_frame to avoid c= opy + +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. + + Backport from mainline + * 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. +--- + 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 813337242d8..397ef7cac26 100644 +--- a/gcc/config/i386/i386.c ++++ b/gcc/config/i386/i386.c +@@ -11843,8 +11843,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 +@@ -11857,7 +11855,7 @@ ix86_can_use_return_insn_p (void) + return 0; +=20 + ix86_compute_frame_layout (); +- frame =3D cfun->machine->frame; ++ struct ix86_frame &frame =3D cfun->machine->frame; + return (frame.stack_pointer_offset =3D=3D UNITS_PER_WORD + && (frame.nregs + frame.nsseregs) =3D=3D 0); + } +@@ -12344,7 +12342,7 @@ HOST_WIDE_INT + ix86_initial_elimination_offset (int from, int to) + { + ix86_compute_frame_layout (); +- struct ix86_frame frame =3D cfun->machine->frame; ++ struct ix86_frame &frame =3D cfun->machine->frame; +=20 + if (from =3D=3D ARG_POINTER_REGNUM && to =3D=3D HARD_FRAME_POINTER_REGN= UM) + return frame.hard_frame_pointer_offset; +@@ -14860,7 +14858,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; +@@ -14873,7 +14870,7 @@ ix86_expand_split_stack_prologue (void) +=20 + ix86_finalize_stack_realign_flags (); + ix86_compute_frame_layout (); +- frame =3D cfun->machine->frame; ++ struct ix86_frame &frame =3D cfun->machine->frame; + allocate =3D frame.stack_pointer_offset - INCOMING_FRAME_SP_OFFSET; +=20 + /* This is the label we will branch to if we have enough stack +--=20 +2.15.1 + diff --git a/gnu/packages/patches/gcc-retpoline-indirect-thunk-reg-names.pa= tch b/gnu/packages/patches/gcc-retpoline-indirect-thunk-reg-names.patch new file mode 100644 index 000000000..6da7b48c3 --- /dev/null +++ b/gnu/packages/patches/gcc-retpoline-indirect-thunk-reg-names.patch @@ -0,0 +1,365 @@ +'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=3DCVE-2017-5715 + +Patch copied from the 'retpoline-regnames' branch of upstream source repos= itory +(please keep an eye for new branches or updates for existing branches): + +http://git.infradead.org/users/dwmw2/gcc-retpoline.git + +From f6d256da9cefa1409598fa5ffe632647a30ad6f9 Mon Sep 17 00:00:00 2001 +From: David Woodhouse +Date: Sun, 14 Jan 2018 21:36:59 +0000 +Subject: [PATCH 10/10] indirect thunk reg names + +--- + gcc/config/i386/i386.c | 9 ++------- + 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-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-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-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-7.c | 2 +- + gcc/testsuite/gcc.target/i386/indirect-thunk-register-1.c | 2 +- + gcc/testsuite/gcc.target/i386/indirect-thunk-register-3.c | 2 +- + gcc/testsuite/gcc.target/i386/ret-thunk-10.c | 4 ++-- + gcc/testsuite/gcc.target/i386/ret-thunk-11.c | 4 ++-- + gcc/testsuite/gcc.target/i386/ret-thunk-12.c | 4 ++-- + 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 +- + 25 files changed, 29 insertions(+), 34 deletions(-) + +diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c +index 6d345031a82..89eb68032a2 100644 +--- a/gcc/config/i386/i386.c ++++ b/gcc/config/i386/i386.c +@@ -12052,13 +12052,8 @@ indirect_thunk_name (char name[32], int regno, bo= ol need_bnd_p, + const char *bnd =3D need_bnd_p ? "_bnd" : ""; + if (regno >=3D 0) + { +- const char *reg_prefix; +- if (LEGACY_INT_REGNO_P (regno)) +- reg_prefix =3D TARGET_64BIT ? "r" : "e"; +- else +- reg_prefix =3D ""; +- sprintf (name, "__x86_indirect_thunk%s_%s%s", +- bnd, reg_prefix, reg_names[regno]); ++ sprintf (name, "__x86_indirect_thunk%s_%s", ++ bnd, reg_names[regno]); + } + else + { +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-1.c b/gcc/testsu= ite/gcc.target/i386/indirect-thunk-1.c +index 9eb9b273ade..fb56b2db3b6 100644 +--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-1.c ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-1.c +@@ -13,7 +13,7 @@ male_indirect_jump (long offset) +=20 + /* { 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_ax" { tar= get 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-2.c b/gcc/testsu= ite/gcc.target/i386/indirect-thunk-2.c +index c63795e4127..337f455aa44 100644 +--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-2.c ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-2.c +@@ -13,7 +13,7 @@ male_indirect_jump (long offset) +=20 + /* { 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_ax" { tar= get 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-3.c b/gcc/testsu= ite/gcc.target/i386/indirect-thunk-3.c +index 82973cda771..2e40ec71609 100644 +--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-3.c ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-3.c +@@ -14,7 +14,7 @@ male_indirect_jump (long offset) +=20 + /* { 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 "call\[ \t\]*__x86_indirect_thunk_ax" { ta= rget 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-4.c b/gcc/testsu= ite/gcc.target/i386/indirect-thunk-4.c +index a5f3d1cbed8..309d1f6c10b 100644 +--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-4.c ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-4.c +@@ -14,7 +14,7 @@ male_indirect_jump (long offset) +=20 + /* { 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 "call\[ \t\]*__x86_indirect_thunk_ax" { ta= rget 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-7.c b/gcc/testsu= ite/gcc.target/i386/indirect-thunk-7.c +index ebfb8aab937..47674395309 100644 +--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-7.c ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-7.c +@@ -37,7 +37,7 @@ bar (int i) +=20 + /* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*\.L\[0-9\]+\\(,%" { ta= rget { ! 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_ax" { tar= get 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-attr-1.c b/gcc/t= estsuite/gcc.target/i386/indirect-thunk-attr-1.c +index a08022db8e4..e8cdc4fa05d 100644 +--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-1.c ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-1.c +@@ -16,7 +16,7 @@ male_indirect_jump (long offset) +=20 + /* { 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_ax" { tar= get 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-attr-2.c b/gcc/t= estsuite/gcc.target/i386/indirect-thunk-attr-2.c +index b257c695ad1..5f333d86e18 100644 +--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-2.c ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-2.c +@@ -14,7 +14,7 @@ male_indirect_jump (long offset) +=20 + /* { 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_ax" { tar= get 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-attr-5.c b/gcc/t= estsuite/gcc.target/i386/indirect-thunk-attr-5.c +index 4bb1c5f9220..fa067b0acc8 100644 +--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-5.c ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-5.c +@@ -18,5 +18,5 @@ male_indirect_jump (long offset) + /* { dg-final { scan-assembler-times "jmp\[ \t\]*\.LIND" 1 { target { ! x= 32 } } } } */ + /* { 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 "call\[ \t\]*__x86_indirect_thunk_ax" { ta= rget x32 } } } */ + /* { dg-final { scan-assembler-not {\t(lfence|pause)} } } */ +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-6.c b/gcc/t= estsuite/gcc.target/i386/indirect-thunk-attr-6.c +index 4e33a638862..442f97c123c 100644 +--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-6.c ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-6.c +@@ -17,5 +17,5 @@ male_indirect_jump (long offset) + /* { dg-final { scan-assembler-times "jmp\[ \t\]*\.LIND" 1 { target { ! x= 32 } } } } */ + /* { 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 "call\[ \t\]*__x86_indirect_thunk_ax" { ta= rget x32 } } } */ + /* { dg-final { scan-assembler-not {\t(lfence|pause)} } } */ +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-7.c b/gcc/t= estsuite/gcc.target/i386/indirect-thunk-attr-7.c +index 427ba3ddbb4..64b85fc7b96 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) + } +=20 + /* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*\.L\[0-9\]+\\(,%" { ta= rget { ! x32 } } } } */ +-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk_(r|e)ax" = { target x32 } } } */ ++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk_ax" { tar= get 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 5c20a35ecec..cb95a09ea34 100644 +--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-1.c ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-1.c +@@ -13,7 +13,7 @@ male_indirect_jump (long offset) +=20 + /* { 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_ax" { tar= get 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 b2fb6e1bcd2..b2af9e96b7e 100644 +--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-2.c ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-2.c +@@ -13,7 +13,7 @@ male_indirect_jump (long offset) +=20 + /* { 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_ax" { tar= get 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 9c84547cd7c..a9a1a8bc177 100644 +--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-3.c ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-3.c +@@ -16,5 +16,5 @@ male_indirect_jump (long offset) + /* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" { target= { ! x32 } } } } */ + /* { dg-final { scan-assembler-times "jmp\[ \t\]*\.LIND" 1 { target { ! x= 32 } } } } */ + /* { 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_ax" { ta= rget 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 457849564bb..bbf3dd24f37 100644 +--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-4.c ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-4.c +@@ -16,5 +16,5 @@ male_indirect_jump (long offset) + /* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" { target= { ! x32 } } } } */ + /* { dg-final { scan-assembler-times "jmp\[ \t\]*\.LIND" 1 { target { ! x= 32 } } } } */ + /* { 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_ax" { ta= rget 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 d4747ea0764..39acad399d3 100644 +--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-7.c ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-7.c +@@ -37,7 +37,7 @@ bar (int i) +=20 + /* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*\.L\[0-9\]+\\(,%" { ta= rget { ! 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_ax" { tar= get 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-register-1.c b/g= cc/testsuite/gcc.target/i386/indirect-thunk-register-1.c +index 7d396a31953..0660feeed73 100644 +--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-register-1.c ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-register-1.c +@@ -11,7 +11,7 @@ male_indirect_jump (long offset) + dispatch(offset); + } +=20 +-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk_(r|e)ax" = } } */ ++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk_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)\\)"= } } */ +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-register-3.c b/g= cc/testsuite/gcc.target/i386/indirect-thunk-register-3.c +index 5320e923be2..d39e387586e 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); + } +=20 +-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk_(r|e)ax" = } } */ ++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk_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(pause|pause|nop)} } } */ +diff --git a/gcc/testsuite/gcc.target/i386/ret-thunk-10.c b/gcc/testsuite/= gcc.target/i386/ret-thunk-10.c +index b4f9d48065d..2f373c362d0 100644 +--- a/gcc/testsuite/gcc.target/i386/ret-thunk-10.c ++++ b/gcc/testsuite/gcc.target/i386/ret-thunk-10.c +@@ -18,6 +18,6 @@ foo (void) + /* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?bar" { target { ! x3= 2 } } } } */ + /* { 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 "call\[ \t\]*__x86_indirect_thunk_ax" { ta= rget { x32 } } } } */ ++/* { dg-final { scan-assembler "__x86_indirect_thunk_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 0312577a043..11e041fda7e 100644 +--- a/gcc/testsuite/gcc.target/i386/ret-thunk-11.c ++++ b/gcc/testsuite/gcc.target/i386/ret-thunk-11.c +@@ -18,6 +18,6 @@ foo (void) + /* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?bar" { target { ! x3= 2 } } } } */ + /* { 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 "call\[ \t\]*__x86_indirect_thunk_ax" { ta= rget { x32 } } } } */ ++/* { dg-final { scan-assembler "__x86_indirect_thunk_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 fa3181303c9..f16c1a5d0c6 100644 +--- a/gcc/testsuite/gcc.target/i386/ret-thunk-12.c ++++ b/gcc/testsuite/gcc.target/i386/ret-thunk-12.c +@@ -17,6 +17,6 @@ foo (void) + /* { 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 "call\[ \t\]*__x86_indirect_thunk_ax" { ta= rget { x32 } } } } */ ++/* { dg-final { scan-assembler "__x86_indirect_thunk_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 7a08e71c76b..b4553216f99 100644 +--- a/gcc/testsuite/gcc.target/i386/ret-thunk-13.c ++++ b/gcc/testsuite/gcc.target/i386/ret-thunk-13.c +@@ -18,5 +18,5 @@ foo (void) + /* { 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 "call\[ \t\]*__x86_indirect_thunk_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 dacf0c769fc..28e5434a004 100644 +--- a/gcc/testsuite/gcc.target/i386/ret-thunk-14.c ++++ b/gcc/testsuite/gcc.target/i386/ret-thunk-14.c +@@ -18,5 +18,5 @@ foo (void) + /* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */ + /* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?bar" { target { ! x3= 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 "call\[ \t\]*__x86_indirect_thunk_ax" { ta= rget { 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 cf06a5f35c7..20fad48b790 100644 +--- a/gcc/testsuite/gcc.target/i386/ret-thunk-15.c ++++ b/gcc/testsuite/gcc.target/i386/ret-thunk-15.c +@@ -18,5 +18,5 @@ foo (void) + /* { dg-final { scan-assembler-times {\tlfence} 1 } } */ + /* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?bar" { target { ! x3= 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 "call\[ \t\]*__x86_indirect_thunk_ax" { ta= rget x32 } } } */ + /* { dg-final { scan-assembler-not "pushq\[ \t\]%rax" { target x32 } } } = */ +diff --git a/gcc/testsuite/gcc.target/i386/ret-thunk-9.c b/gcc/testsuite/g= cc.target/i386/ret-thunk-9.c +index 6da5ab97081..8f0375b5def 100644 +--- a/gcc/testsuite/gcc.target/i386/ret-thunk-9.c ++++ b/gcc/testsuite/gcc.target/i386/ret-thunk-9.c +@@ -21,5 +21,5 @@ foo (void) + /* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" { target= { ! x32 } } } } */ + /* { dg-final { scan-assembler-times {\tpause} 2 { 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_ax" { ta= rget { x32 } } } } */ + /* { dg-final { scan-assembler-not "pushq\[ \t\]%rax" { target x32 } } } = */ +--=20 +2.15.1 + diff --git a/gnu/packages/patches/gcc-retpoline-x86-Add-V-register-operand-= modifier.patch b/gnu/packages/patches/gcc-retpoline-x86-Add-V-register-oper= and-modifier.patch new file mode 100644 index 000000000..d47f23942 --- /dev/null +++ b/gnu/packages/patches/gcc-retpoline-x86-Add-V-register-operand-modifie= r.patch @@ -0,0 +1,143 @@ +'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=3DCVE-2017-5715 + +Patch copied from the 'retpoline-regnames' branch of upstream source repos= itory +(please keep an eye for new branches or updates for existing branches): + +http://git.infradead.org/users/dwmw2/gcc-retpoline.git + +From 5e977dfedb93e764dc480c0e0674500590ef5604 Mon Sep 17 00:00:00 2001 +From: "H.J. Lu" +Date: Sat, 6 Jan 2018 22:29:56 -0800 +Subject: [PATCH 07/10] x86: Add 'V' register operand modifier + +Add 'V', a special modifier which prints the name of the full integer +register without '%'. For + +extern void (*func_p) (void); + +void +foo (void) +{ + asm ("call __x86_indirect_thunk_%V0" : : "a" (func_p)); +} + +it generates: + +foo: + movq func_p(%rip), %rax + call __x86_indirect_thunk_rax + ret + +gcc/ + + Backport from mainline + * config/i386/i386.c (print_reg): Print the name of the full + integer register without '%'. + (ix86_print_operand): Handle 'V'. + * doc/extend.texi: Document 'V' modifier. + +gcc/testsuite/ + + Backport from mainline + * gcc.target/i386/indirect-thunk-register-4.c: New test. +--- + gcc/config/i386/i386.c | 13 ++++++++++= ++- + gcc/doc/extend.texi | 3 +++ + gcc/testsuite/gcc.target/i386/indirect-thunk-register-4.c | 13 ++++++++++= +++ + 3 files changed, 28 insertions(+), 1 deletion(-) + create mode 100644 gcc/testsuite/gcc.target/i386/indirect-thunk-register-= 4.c + +diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c +index 4bfe2fa8c1d..e32de13688a 100644 +--- a/gcc/config/i386/i386.c ++++ b/gcc/config/i386/i386.c +@@ -17925,6 +17925,7 @@ put_condition_code (enum rtx_code code, machine_mo= de 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 full integer register name without %. + */ +=20 + void +@@ -17935,7 +17936,7 @@ print_reg (rtx x, int code, FILE *file) + unsigned int regno; + bool duplicated; +=20 +- if (ASSEMBLER_DIALECT =3D=3D ASM_ATT) ++ if (ASSEMBLER_DIALECT =3D=3D ASM_ATT && code !=3D 'V') + putc ('%', file); +=20 + if (x =3D=3D pc_rtx) +@@ -17983,6 +17984,14 @@ print_reg (rtx x, int code, FILE *file) + return; + } +=20 ++ if (code =3D=3D 'V') ++ { ++ if (GENERAL_REGNO_P (regno)) ++ msize =3D GET_MODE_SIZE (word_mode); ++ else ++ error ("'V' modifier on non-integer register"); ++ } ++ + duplicated =3D code =3D=3D 'd' && TARGET_AVX; +=20 + switch (msize) +@@ -18102,6 +18111,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 full integer 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. +@@ -18326,6 +18336,7 @@ ix86_print_operand (FILE *file, rtx x, int code) + case 'X': + case 'P': + case 'p': ++ case 'V': + break; +=20 + case 's': +diff --git a/gcc/doc/extend.texi b/gcc/doc/extend.texi +index 46e0a3623a6..9db9e0e27e9 100644 +--- a/gcc/doc/extend.texi ++++ b/gcc/doc/extend.texi +@@ -8778,6 +8778,9 @@ The table below shows the list of supported modifier= s and their effects. + @tab @code{2} + @end multitable +=20 ++@code{V} is a special modifier which prints the name of the full integer ++register without @code{%}. ++ + @anchor{x86floatingpointasmoperands} + @subsubsection x86 Floating-Point @code{asm} Operands +=20 +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-register-4.c b/g= cc/testsuite/gcc.target/i386/indirect-thunk-register-4.c +new file mode 100644 +index 00000000000..f0cd9b75be8 +--- /dev/null ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-register-4.c +@@ -0,0 +1,13 @@ ++/* { dg-do compile } */ ++/* { dg-options "-O2 -mindirect-branch=3Dkeep -fno-pic" } */ ++ ++extern void (*func_p) (void); ++ ++void ++foo (void) ++{ ++ asm("call __x86_indirect_thunk_%V0" : : "a" (func_p)); ++} ++ ++/* { dg-final { scan-assembler "call\[ \t\]*__x86_indirect_thunk_eax" { t= arget ia32 } } } */ ++/* { dg-final { scan-assembler "call\[ \t\]*__x86_indirect_thunk_rax" { t= arget { ! ia32 } } } } */ +--=20 +2.15.1 + diff --git a/gnu/packages/patches/gcc-retpoline-x86-Add-mfunction-return.pa= tch b/gnu/packages/patches/gcc-retpoline-x86-Add-mfunction-return.patch new file mode 100644 index 000000000..bfd154eaa --- /dev/null +++ b/gnu/packages/patches/gcc-retpoline-x86-Add-mfunction-return.patch @@ -0,0 +1,1303 @@ +'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=3DCVE-2017-5715 + +Patch copied from the 'retpoline-regnames' branch of upstream source repos= itory +(please keep an eye for new branches or updates for existing branches): + +http://git.infradead.org/users/dwmw2/gcc-retpoline.git + +From dfa5f37da1fed9d9439e396fdf49847f4d9184d4 Mon Sep 17 00:00:00 2001 +From: "H.J. Lu" +Date: Sat, 6 Jan 2018 22:29:56 -0800 +Subject: [PATCH 05/10] x86: Add -mfunction-return=3D + +Add -mfunction-return=3D option to convert function return to call and +return thunks. The default is 'keep', which keeps function return +unmodified. 'thunk' converts function return to call and return thunk. +'thunk-inline' converts function return to inlined call and return thunk. +'thunk-extern' converts function return to external call and return +thunk provided in a separate object file. You can control this behavior +for a specific function by using the function attribute function_return. + +Function return thunk is the same as memory thunk for -mindirect-branch=3D +where the return address is at the top of the stack: + +__x86_return_thunk: + call L2 +L1: + pause + lfence + jmp L1 +L2: + lea 8(%rsp), %rsp|lea 4(%esp), %esp + ret + +and function return becomes + + jmp __x86_return_thunk + +-mindirect-branch=3D tests are updated with -mfunction-return=3Dkeep to +avoid false test failures when -mfunction-return=3Dthunk is added to +RUNTESTFLAGS for "make check". + +gcc/ + + Backport from mainline + * config/i386/i386-protos.h (ix86_output_function_return): New. + * config/i386/i386.c (ix86_set_indirect_branch_type): Also + set function_return_type. + (indirect_thunk_name): Add ret_p to indicate thunk for function + return. + (output_indirect_thunk_function): Pass false to + indirect_thunk_name. + (ix86_output_indirect_branch): Likewise. + (output_indirect_thunk_function): Create alias for function + return thunk if regno < 0. + (ix86_output_function_return): New function. + (ix86_handle_fndecl_attribute): Handle function_return. + (ix86_attribute_table): Add function_return. + * config/i386/i386.h (machine_function): Add + function_return_type. + * config/i386/i386.md (simple_return_internal): Use + ix86_output_function_return. + (simple_return_internal_long): Likewise. + * config/i386/i386.opt (mfunction-return=3D): New option. + (indirect_branch): Mention -mfunction-return=3D. + * doc/extend.texi: Document function_return function attribute. + * doc/invoke.texi: Document -mfunction-return=3D option. + +gcc/testsuite/ + + Backport from mainline + * gcc.target/i386/indirect-thunk-1.c (dg-options): Add + -mfunction-return=3Dkeep. + * gcc.target/i386/indirect-thunk-2.c: Likewise. + * gcc.target/i386/indirect-thunk-3.c: Likewise. + * gcc.target/i386/indirect-thunk-4.c: Likewise. + * gcc.target/i386/indirect-thunk-5.c: Likewise. + * gcc.target/i386/indirect-thunk-6.c: Likewise. + * gcc.target/i386/indirect-thunk-7.c: Likewise. + * gcc.target/i386/indirect-thunk-attr-1.c: Likewise. + * gcc.target/i386/indirect-thunk-attr-2.c: Likewise. + * gcc.target/i386/indirect-thunk-attr-3.c: Likewise. + * gcc.target/i386/indirect-thunk-attr-4.c: Likewise. + * gcc.target/i386/indirect-thunk-attr-5.c: Likewise. + * gcc.target/i386/indirect-thunk-attr-6.c: Likewise. + * gcc.target/i386/indirect-thunk-attr-7.c: Likewise. + * gcc.target/i386/indirect-thunk-attr-8.c: Likewise. + * gcc.target/i386/indirect-thunk-bnd-1.c: Likewise. + * gcc.target/i386/indirect-thunk-bnd-2.c: Likewise. + * gcc.target/i386/indirect-thunk-bnd-3.c: Likewise. + * gcc.target/i386/indirect-thunk-bnd-4.c: Likewise. + * gcc.target/i386/indirect-thunk-extern-1.c: Likewise. + * gcc.target/i386/indirect-thunk-extern-2.c: Likewise. + * gcc.target/i386/indirect-thunk-extern-3.c: Likewise. + * gcc.target/i386/indirect-thunk-extern-4.c: Likewise. + * gcc.target/i386/indirect-thunk-extern-5.c: Likewise. + * gcc.target/i386/indirect-thunk-extern-6.c: Likewise. + * gcc.target/i386/indirect-thunk-extern-7.c: Likewise. + * gcc.target/i386/indirect-thunk-inline-1.c: Likewise. + * gcc.target/i386/indirect-thunk-inline-2.c: Likewise. + * gcc.target/i386/indirect-thunk-inline-3.c: Likewise. + * gcc.target/i386/indirect-thunk-inline-4.c: Likewise. + * gcc.target/i386/indirect-thunk-inline-5.c: Likewise. + * gcc.target/i386/indirect-thunk-inline-6.c: Likewise. + * gcc.target/i386/indirect-thunk-inline-7.c: Likewise. + * gcc.target/i386/ret-thunk-1.c: New test. + * gcc.target/i386/ret-thunk-10.c: Likewise. + * gcc.target/i386/ret-thunk-11.c: Likewise. + * gcc.target/i386/ret-thunk-12.c: Likewise. + * gcc.target/i386/ret-thunk-13.c: Likewise. + * gcc.target/i386/ret-thunk-14.c: Likewise. + * gcc.target/i386/ret-thunk-15.c: Likewise. + * gcc.target/i386/ret-thunk-16.c: Likewise. + * gcc.target/i386/ret-thunk-2.c: Likewise. + * gcc.target/i386/ret-thunk-3.c: Likewise. + * gcc.target/i386/ret-thunk-4.c: Likewise. + * gcc.target/i386/ret-thunk-5.c: Likewise. + * gcc.target/i386/ret-thunk-6.c: Likewise. + * gcc.target/i386/ret-thunk-7.c: Likewise. + * gcc.target/i386/ret-thunk-8.c: Likewise. + * gcc.target/i386/ret-thunk-9.c: Likewise. +--- + gcc/config/i386/i386-protos.h | 1 + + gcc/config/i386/i386.c | 151 ++++++++++++++++= +++-- + gcc/config/i386/i386.h | 3 + + gcc/config/i386/i386.md | 9 +- + gcc/config/i386/i386.opt | 6 +- + gcc/doc/extend.texi | 9 ++ + gcc/doc/invoke.texi | 13 +- + 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.target/i386/indirect-thunk-attr-1.c | 2 +- + .../gcc.target/i386/indirect-thunk-attr-2.c | 2 +- + .../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 | 2 +- + .../gcc.target/i386/indirect-thunk-attr-6.c | 2 +- + .../gcc.target/i386/indirect-thunk-attr-7.c | 2 +- + .../gcc.target/i386/indirect-thunk-attr-8.c | 2 +- + .../gcc.target/i386/indirect-thunk-bnd-1.c | 2 +- + .../gcc.target/i386/indirect-thunk-bnd-2.c | 2 +- + .../gcc.target/i386/indirect-thunk-bnd-3.c | 2 +- + .../gcc.target/i386/indirect-thunk-bnd-4.c | 2 +- + .../gcc.target/i386/indirect-thunk-extern-1.c | 2 +- + .../gcc.target/i386/indirect-thunk-extern-2.c | 2 +- + .../gcc.target/i386/indirect-thunk-extern-3.c | 2 +- + .../gcc.target/i386/indirect-thunk-extern-4.c | 2 +- + .../gcc.target/i386/indirect-thunk-extern-5.c | 2 +- + .../gcc.target/i386/indirect-thunk-extern-6.c | 2 +- + .../gcc.target/i386/indirect-thunk-extern-7.c | 2 +- + .../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-5.c | 2 +- + .../gcc.target/i386/indirect-thunk-inline-6.c | 2 +- + .../gcc.target/i386/indirect-thunk-inline-7.c | 2 +- + gcc/testsuite/gcc.target/i386/ret-thunk-1.c | 13 ++ + gcc/testsuite/gcc.target/i386/ret-thunk-10.c | 23 ++++ + gcc/testsuite/gcc.target/i386/ret-thunk-11.c | 23 ++++ + gcc/testsuite/gcc.target/i386/ret-thunk-12.c | 22 +++ + gcc/testsuite/gcc.target/i386/ret-thunk-13.c | 22 +++ + gcc/testsuite/gcc.target/i386/ret-thunk-14.c | 22 +++ + gcc/testsuite/gcc.target/i386/ret-thunk-15.c | 22 +++ + gcc/testsuite/gcc.target/i386/ret-thunk-16.c | 18 +++ + gcc/testsuite/gcc.target/i386/ret-thunk-2.c | 13 ++ + 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 | 15 ++ + gcc/testsuite/gcc.target/i386/ret-thunk-6.c | 14 ++ + 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 | 25 ++++ + 56 files changed, 491 insertions(+), 50 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 bcdd9872db9..42eece35766 100644 +--- a/gcc/config/i386/i386-protos.h ++++ b/gcc/config/i386/i386-protos.h +@@ -314,6 +314,7 @@ extern enum attr_cpu ix86_schedule; +=20 + extern const char * ix86_output_call_insn (rtx_insn *insn, 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); +=20 +diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c +index f1c58faa035..4bfe2fa8c1d 100644 +--- a/gcc/config/i386/i386.c ++++ b/gcc/config/i386/i386.c +@@ -7188,6 +7188,31 @@ ix86_set_indirect_branch_type (tree fndecl) + else + cfun->machine->indirect_branch_type =3D ix86_indirect_branch; + } ++ ++ if (cfun->machine->function_return_type =3D=3D indirect_branch_unset) ++ { ++ tree attr =3D lookup_attribute ("function_return", ++ DECL_ATTRIBUTES (fndecl)); ++ if (attr !=3D NULL) ++ { ++ tree args =3D TREE_VALUE (attr); ++ if (args =3D=3D NULL) ++ gcc_unreachable (); ++ tree cst =3D TREE_VALUE (args); ++ if (strcmp (TREE_STRING_POINTER (cst), "keep") =3D=3D 0) ++ cfun->machine->function_return_type =3D indirect_branch_keep; ++ else if (strcmp (TREE_STRING_POINTER (cst), "thunk") =3D=3D 0) ++ cfun->machine->function_return_type =3D indirect_branch_thunk; ++ else if (strcmp (TREE_STRING_POINTER (cst), "thunk-inline") =3D=3D 0) ++ cfun->machine->function_return_type =3D indirect_branch_thunk_inline; ++ else if (strcmp (TREE_STRING_POINTER (cst), "thunk-extern") =3D=3D 0) ++ cfun->machine->function_return_type =3D indirect_branch_thunk_extern; ++ else ++ gcc_unreachable (); ++ } ++ else ++ cfun->machine->function_return_type =3D ix86_function_return; ++ } + } +=20 + /* Establish appropriate back-end context for processing the function +@@ -11990,8 +12015,12 @@ static int indirect_thunks_bnd_used; + /* Fills in the label name that should be used for the indirect thunk. */ +=20 + 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 >=3D 0 && ret_p) ++ gcc_unreachable (); ++ + if (USE_HIDDEN_LINKONCE) + { + const char *bnd =3D need_bnd_p ? "_bnd" : ""; +@@ -12006,7 +12035,10 @@ indirect_thunk_name (char name[32], int regno, bo= ol need_bnd_p) + bnd, reg_prefix, reg_names[regno]); + } + else +- sprintf (name, "__x86_indirect_thunk%s", bnd); ++ { ++ const char *ret =3D ret_p ? "return" : "indirect"; ++ sprintf (name, "__x86_%s_thunk%s", ret, bnd); ++ } + } + else + { +@@ -12019,10 +12051,20 @@ indirect_thunk_name (char name[32], int regno, b= ool 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); ++ } + } + } + } +@@ -12117,7 +12159,7 @@ output_indirect_thunk_function (bool need_bnd_p, i= nt regno) + tree decl; +=20 + /* 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 =3D build_decl (BUILTINS_LOCATION, FUNCTION_DECL, + get_identifier (name), + build_function_type_list (void_type_node, NULL_TREE)); +@@ -12160,6 +12202,35 @@ output_indirect_thunk_function (bool need_bnd_p, = int regno) + ASM_OUTPUT_LABEL (asm_out_file, name); + } +=20 ++ 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) =3D make_node (BLOCK); + current_function_decl =3D decl; + allocate_struct_function (decl, false); +@@ -28760,7 +28831,7 @@ ix86_output_indirect_branch_via_reg (rtx call_op, = bool sibcall_p) + else + indirect_thunks_used |=3D 1 << i; + } +- indirect_thunk_name (thunk_name_buf, regno, need_bnd_p); ++ indirect_thunk_name (thunk_name_buf, regno, need_bnd_p, false); + thunk_name =3D thunk_name_buf; + } + else +@@ -28869,7 +28940,7 @@ ix86_output_indirect_branch_via_push (rtx call_op,= const char *xasm, + else + indirect_thunk_needed =3D true; + } +- indirect_thunk_name (thunk_name_buf, regno, need_bnd_p); ++ indirect_thunk_name (thunk_name_buf, regno, need_bnd_p, false); + thunk_name =3D thunk_name_buf; + } + else +@@ -29004,6 +29075,46 @@ ix86_output_indirect_jmp (rtx call_op, bool ret_p) + return "%!jmp\t%A0"; + } +=20 ++/* Output function return. CALL_OP is the jump target. Add a REP ++ prefix to RET if LONG_P is true and function return is kept. */ ++ ++const char * ++ix86_output_function_return (bool long_p) ++{ ++ if (cfun->machine->function_return_type !=3D indirect_branch_keep) ++ { ++ char thunk_name[32]; ++ bool need_bnd_p =3D ix86_bnd_prefixed_insn_p (current_output_insn); ++ ++ if (cfun->machine->function_return_type ++ !=3D indirect_branch_thunk_inline) ++ { ++ bool need_thunk =3D (cfun->machine->function_return_type ++ =3D=3D indirect_branch_thunk); ++ indirect_thunk_name (thunk_name, -1, need_bnd_p, true); ++ if (need_bnd_p) ++ { ++ indirect_thunk_bnd_needed |=3D need_thunk; ++ fprintf (asm_out_file, "\tbnd jmp\t%s\n", thunk_name); ++ } ++ else ++ { ++ indirect_thunk_needed |=3D 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. */ +=20 + const char * +@@ -42075,6 +42186,28 @@ ix86_handle_fndecl_attribute (tree *node, tree na= me, tree args, int, + } + } +=20 ++ if (is_attribute_p ("function_return", name)) ++ { ++ tree cst =3D TREE_VALUE (args); ++ if (TREE_CODE (cst) !=3D STRING_CST) ++ { ++ warning (OPT_Wattributes, ++ "%qE attribute requires a string constant argument", ++ name); ++ *no_add_attrs =3D true; ++ } ++ else if (strcmp (TREE_STRING_POINTER (cst), "keep") !=3D 0 ++ && strcmp (TREE_STRING_POINTER (cst), "thunk") !=3D 0 ++ && strcmp (TREE_STRING_POINTER (cst), "thunk-inline") !=3D 0 ++ && strcmp (TREE_STRING_POINTER (cst), "thunk-extern") !=3D 0) ++ { ++ warning (OPT_Wattributes, ++ "argument to %qE attribute is not " ++ "(keep|thunk|thunk-inline|thunk-extern)", name); ++ *no_add_attrs =3D true; ++ } ++ } ++ + return NULL_TREE; + } +=20 +@@ -46385,6 +46518,8 @@ static const struct attribute_spec ix86_attribute_= table[] =3D + 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 }, +=20 + /* 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 9d2209e605b..45593068905 100644 +--- a/gcc/config/i386/i386.h ++++ b/gcc/config/i386/i386.h +@@ -2616,6 +2616,9 @@ struct GTY(()) machine_function { + "indirect_jump" or "tablejump". */ + BOOL_BITFIELD has_local_indirect_jump : 1; +=20 ++ /* 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 cd2e73cf9d3..d112bdb8552 100644 +--- a/gcc/config/i386/i386.md ++++ b/gcc/config/i386/i386.md +@@ -12315,7 +12315,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") +@@ -12337,12 +12337,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 c076d9c70ab..b07388d95a9 100644 +--- a/gcc/config/i386/i386.opt ++++ b/gcc/config/i386/i386.opt +@@ -932,9 +932,13 @@ mindirect-branch=3D + Target Report RejectNegative Joined Enum(indirect_branch) Var(ix86_indire= ct_branch) Init(indirect_branch_keep) + Convert indirect call and jump to call and return thunks. +=20 ++mfunction-return=3D ++Target Report RejectNegative Joined Enum(indirect_branch) Var(ix86_functi= on_return) Init(indirect_branch_keep) ++Convert function return to call and return thunk. ++ + Enum + Name(indirect_branch) Type(enum indirect_branch) +-Known indirect branch choices (for use with the -mindirect-branch=3D opti= on): ++Known indirect branch choices (for use with the -mindirect-branch=3D/-mfu= nction-return=3D options): +=20 + EnumValue + Enum(indirect_branch) String(keep) Value(indirect_branch_keep) +diff --git a/gcc/doc/extend.texi b/gcc/doc/extend.texi +index 935381da6fa..46e0a3623a6 100644 +--- a/gcc/doc/extend.texi ++++ b/gcc/doc/extend.texi +@@ -5550,6 +5550,15 @@ call and jump to call and return thunk. @samp{thun= k-inline} converts + indirect call and jump to inlined call and return thunk. + @samp{thunk-extern} converts indirect call and jump to external call + and return thunk provided in a separate object file. ++ ++@item function_return("@var{choice}") ++@cindex @code{function_return} function attribute, x86 ++On x86 targets, the @code{function_return} attribute causes the compiler ++to convert function return with @var{choice}. @samp{keep} keeps function ++return unmodified. @samp{thunk} converts function return to call and ++return thunk. @samp{thunk-inline} converts function return to inlined ++call and return thunk. @samp{thunk-extern} converts function return to ++external call and return thunk provided in a separate object file. + @end table +=20 + On the x86, the inliner does not inline a +diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi +index 4979c8c939d..f3eb54b1668 100644 +--- a/gcc/doc/invoke.texi ++++ b/gcc/doc/invoke.texi +@@ -1211,7 +1211,7 @@ See RS/6000 and PowerPC Options. + -mavx256-split-unaligned-load -mavx256-split-unaligned-store @gol + -malign-data=3D@var{type} -mstack-protector-guard=3D@var{guard} @gol + -mmitigate-rop -mgeneral-regs-only @gol +--mindirect-branch=3D@var{choice}} ++-mindirect-branch=3D@var{choice} -mfunction-return=3D=3D@var{choice}} +=20 + @emph{x86 Windows Options} + @gccoptlist{-mconsole -mcygwin -mno-cygwin -mdll @gol +@@ -25698,6 +25698,17 @@ to external call and return thunk provided in a s= eparate object file. + You can control this behavior for a specific function by using the + function attribute @code{indirect_branch}. @xref{Function Attributes}. +=20 ++@item -mfunction-return=3D@var{choice} ++@opindex -mfunction-return ++Convert function return with @var{choice}. The default is @samp{keep}, ++which keeps function return unmodified. @samp{thunk} converts function ++return to call and return thunk. @samp{thunk-inline} converts function ++return to inlined call and return thunk. @samp{thunk-extern} converts ++function return to external call and return thunk provided in a separate ++object file. You can control this behavior for a specific function by ++using the function attribute @code{function_return}. ++@xref{Function Attributes}. ++ + @end table +=20 + 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/testsu= ite/gcc.target/i386/indirect-thunk-1.c +index d983e1c3e26..f076155c91a 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=3Dthunk -fno-pic" } */ ++/* { dg-options "-O2 -mfunction-return=3Dkeep -mindirect-branch=3Dthunk -= fno-pic" } */ +=20 + typedef void (*dispatch_t)(long offset); +=20 +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-2.c b/gcc/testsu= ite/gcc.target/i386/indirect-thunk-2.c +index 58f09b42d8a..d7984f592fe 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=3Dthunk -fno-pic" } */ ++/* { dg-options "-O2 -mfunction-return=3Dkeep -mindirect-branch=3Dthunk -= fno-pic" } */ +=20 + typedef void (*dispatch_t)(long offset); +=20 +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-3.c b/gcc/testsu= ite/gcc.target/i386/indirect-thunk-3.c +index f20d35c19b6..3257d0a2e16 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=3Dthunk -fno-pic" } */ ++/* { dg-options "-O2 -mfunction-return=3Dkeep -mindirect-branch=3Dthunk -= fno-pic" } */ +=20 + typedef void (*dispatch_t)(long offset); +=20 +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-4.c b/gcc/testsu= ite/gcc.target/i386/indirect-thunk-4.c +index 0eff8fb658a..7cab2df6474 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=3Dthunk -fno-pic" } */ ++/* { dg-options "-O2 -mfunction-return=3Dkeep -mindirect-branch=3Dthunk -= fno-pic" } */ +=20 + typedef void (*dispatch_t)(long offset); +=20 +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-5.c b/gcc/testsu= ite/gcc.target/i386/indirect-thunk-5.c +index a25b20dd808..b4836c38d6c 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=3Dthunk" } */ ++/* { dg-options "-O2 -mfunction-return=3Dkeep -fpic -fno-plt -mindirect-b= ranch=3Dthunk" } */ +=20 + extern void bar (void); +=20 +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-6.c b/gcc/testsu= ite/gcc.target/i386/indirect-thunk-6.c +index cff114a6c29..1f06bd1af74 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=3Dthunk" } */ ++/* { dg-options "-O2 -mfunction-return=3Dkeep -fpic -fno-plt -mindirect-b= ranch=3Dthunk" } */ +=20 + extern void bar (void); +=20 +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-7.c b/gcc/testsu= ite/gcc.target/i386/indirect-thunk-7.c +index afdb6007986..0b3fef86a20 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=3Dthunk -fno-pic" } */ ++/* { dg-options "-O2 -mfunction-return=3Dkeep -mindirect-branch=3Dthunk -= fno-pic" } */ +=20 + void func0 (void); + void func1 (void); +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-1.c b/gcc/t= estsuite/gcc.target/i386/indirect-thunk-attr-1.c +index d64d978b699..5f6cfc17b56 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=3Dkeep -fno-pic" } */ +=20 + typedef void (*dispatch_t)(long offset); +=20 +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-2.c b/gcc/t= estsuite/gcc.target/i386/indirect-thunk-attr-2.c +index 93067454d3d..b256160ec80 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=3Dkeep -fno-pic" } */ +=20 + typedef void (*dispatch_t)(long offset); +=20 +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-3.c b/gcc/t= estsuite/gcc.target/i386/indirect-thunk-attr-3.c +index 97744d65729..567c95051d6 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=3Dkeep -fno-pic" } */ +=20 + typedef void (*dispatch_t)(long offset); +=20 +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-4.c b/gcc/t= estsuite/gcc.target/i386/indirect-thunk-attr-4.c +index bfce3ea5cb2..3b662af7d5d 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=3Dkeep -fno-pic" } */ +=20 + typedef void (*dispatch_t)(long offset); +=20 +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-5.c b/gcc/t= estsuite/gcc.target/i386/indirect-thunk-attr-5.c +index 0833606046b..98785a38248 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=3Dkeep -fno-pic" } */ +=20 + typedef void (*dispatch_t)(long offset); +=20 +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-6.c b/gcc/t= estsuite/gcc.target/i386/indirect-thunk-attr-6.c +index 2eba0fbd9b2..a498a39e404 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=3Dkeep -fno-pic" } */ +=20 + typedef void (*dispatch_t)(long offset); +=20 +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-7.c b/gcc/t= estsuite/gcc.target/i386/indirect-thunk-attr-7.c +index f58427eae11..66f295d1eb6 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=3Dkeep -fno-pic" } */ +=20 + void func0 (void); + void func1 (void); +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-8.c b/gcc/t= estsuite/gcc.target/i386/indirect-thunk-attr-8.c +index 564ed39547c..d730d31bda1 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=3Dthunk -fno-pic" } */ ++/* { dg-options "-O2 -mfunction-return=3Dkeep -mindirect-branch=3Dthunk -= fno-pic" } */ +=20 + void func0 (void); + void func1 (void); +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-1.c b/gcc/te= stsuite/gcc.target/i386/indirect-thunk-bnd-1.c +index 50fbee20a5a..aacb814d737 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=3Dthunk -fcheck-pointer-bounds -mm= px -fno-pic" } */ ++/* { dg-options "-O2 -mfunction-return=3Dkeep -mindirect-branch=3Dthunk -= fcheck-pointer-bounds -mmpx -fno-pic" } */ +=20 + void (*dispatch) (char *); + char buf[10]; +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-2.c b/gcc/te= stsuite/gcc.target/i386/indirect-thunk-bnd-2.c +index 2976e67adce..7b44dda23df 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=3Dthunk -fcheck-pointer-bounds -mm= px -fno-pic" } */ ++/* { dg-options "-O2 -mfunction-return=3Dkeep -mindirect-branch=3Dthunk -= fcheck-pointer-bounds -mmpx -fno-pic" } */ +=20 + void (*dispatch) (char *); + char buf[10]; +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-3.c b/gcc/te= stsuite/gcc.target/i386/indirect-thunk-bnd-3.c +index da4bc98ef23..70b4fb36eea 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=3Dthunk -fcheck-pointer-bounds -mm= px -fpic -fno-plt" } */ ++/* { dg-options "-O2 -mfunction-return=3Dkeep -mindirect-branch=3Dthunk -= fcheck-pointer-bounds -mmpx -fpic -fno-plt" } */ +=20 + void bar (char *); + char buf[10]; +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-4.c b/gcc/te= stsuite/gcc.target/i386/indirect-thunk-bnd-4.c +index c64d12ef989..3baf03ee77c 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=3Dthunk -fcheck-pointer-bounds -mm= px -fpic -fno-plt" } */ ++/* { dg-options "-O2 -mfunction-return=3Dkeep -mindirect-branch=3Dthunk -= fcheck-pointer-bounds -mmpx -fpic -fno-plt" } */ +=20 + 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 49f27b49465..637fc3d3f4e 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=3Dthunk-extern -fno-pic" } */ ++/* { dg-options "-O2 -mfunction-return=3Dkeep -mindirect-branch=3Dthunk-e= xtern -fno-pic" } */ +=20 + typedef void (*dispatch_t)(long offset); +=20 +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 a1e3eb6fc74..ff9efe03fe6 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=3Dthunk-extern -fno-pic" } */ ++/* { dg-options "-O2 -mfunction-return=3Dkeep -mindirect-branch=3Dthunk-e= xtern -fno-pic" } */ +=20 + typedef void (*dispatch_t)(long offset); +=20 +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 395634e7e5c..2686a5f2db4 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=3Dthunk-extern -fno-pic" } */ ++/* { dg-options "-O2 -mfunction-return=3Dkeep -mindirect-branch=3Dthunk-e= xtern -fno-pic" } */ +=20 + typedef void (*dispatch_t)(long offset); +=20 +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 fd3f63379a1..f07f6b214ad 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=3Dthunk-extern -fno-pic" } */ ++/* { dg-options "-O2 -mfunction-return=3Dkeep -mindirect-branch=3Dthunk-e= xtern -fno-pic" } */ +=20 + typedef void (*dispatch_t)(long offset); +=20 +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 ba2f92b6f34..21740ac5b7f 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=3Dthunk-extern" } */ ++/* { dg-options "-O2 -mfunction-return=3Dkeep -fpic -fno-plt -mindirect-b= ranch=3Dthunk-extern" } */ +=20 + extern void bar (void); +=20 +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 0c5a2d472c6..a77c1f470b8 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=3Dthunk-extern" } */ ++/* { dg-options "-O2 -mfunction-return=3Dkeep -fpic -fno-plt -mindirect-b= ranch=3Dthunk-extern" } */ +=20 + extern void bar (void); +=20 +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 665252327aa..e64910fd4aa 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=3Dthunk-extern -fno-pic" } */ ++/* { dg-options "-O2 -mfunction-return=3Dkeep -mindirect-branch=3Dthunk-e= xtern -fno-pic" } */ +=20 + 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 68c0ff713b3..365cf2ee226 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=3Dthunk-inline -fno-pic" } */ ++/* { dg-options "-O2 -mfunction-return=3Dkeep -mindirect-branch=3Dthunk-i= nline -fno-pic" } */ +=20 + typedef void (*dispatch_t)(long offset); +=20 +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 e2da1fcb683..72646a4960b 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=3Dthunk-inline -fno-pic" } */ ++/* { dg-options "-O2 -mfunction-return=3Dkeep -mindirect-branch=3Dthunk-i= nline -fno-pic" } */ +=20 + typedef void (*dispatch_t)(long offset); +=20 +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 244fec708d6..f48945e3dfc 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=3Dthunk-inline -fno-pic" } */ ++/* { dg-options "-O2 -mfunction-return=3Dkeep -mindirect-branch=3Dthunk-i= nline -fno-pic" } */ +=20 + typedef void (*dispatch_t)(long offset); +=20 +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 107ebe32f54..4b1d558fc4e 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=3Dthunk-inline -fno-pic" } */ ++/* { dg-options "-O2 -mfunction-return=3Dkeep -mindirect-branch=3Dthunk-i= nline -fno-pic" } */ +=20 + typedef void (*dispatch_t)(long offset); +=20 +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 17b04ef2229..0f687c3b027 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=3Dthunk-inline" } */ ++/* { dg-options "-O2 -mfunction-return=3Dkeep -fpic -fno-plt -mindirect-b= ranch=3Dthunk-inline" } */ +=20 + extern void bar (void); +=20 +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 d9eb11285aa..b27c6fc96a2 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=3Dthunk-inline" } */ ++/* { dg-options "-O2 -mfunction-return=3Dkeep -fpic -fno-plt -mindirect-b= ranch=3Dthunk-inline" } */ +=20 + extern void bar (void); +=20 +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 d02b1dcb1b9..2c496492eaa 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=3Dthunk-inline -fno-pic" } */ ++/* { dg-options "-O2 -mfunction-return=3Dkeep -mindirect-branch=3Dthunk-i= nline -fno-pic" } */ +=20 + void func0 (void); + void func1 (void); +diff --git a/gcc/testsuite/gcc.target/i386/ret-thunk-1.c b/gcc/testsuite/g= cc.target/i386/ret-thunk-1.c +new file mode 100644 +index 00000000000..7223f67ba5e +--- /dev/null ++++ b/gcc/testsuite/gcc.target/i386/ret-thunk-1.c +@@ -0,0 +1,13 @@ ++/* { dg-do compile } */ ++/* { dg-options "-O2 -mfunction-return=3Dthunk" } */ ++ ++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 {\tpause} } } */ ++/* { 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..1630e2fa2b5 +--- /dev/null ++++ b/gcc/testsuite/gcc.target/i386/ret-thunk-10.c +@@ -0,0 +1,23 @@ ++/* { dg-do compile } */ ++/* { dg-options "-O2 -mfunction-return=3Dthunk-inline -mindirect-branch= =3Dthunk -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 {\tpause} 2 } } */ ++/* { dg-final { scan-assembler-times {\tlfence} 2 } } */ ++/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?bar" { target { ! x3= 2 } } } } */ ++/* { 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..876159cf783 +--- /dev/null ++++ b/gcc/testsuite/gcc.target/i386/ret-thunk-11.c +@@ -0,0 +1,23 @@ ++/* { dg-do compile } */ ++/* { dg-options "-O2 -mfunction-return=3Dthunk-extern -mindirect-branch= =3Dthunk -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 {\tpause} 1 } } */ ++/* { 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 { ! x3= 2 } } } } */ ++/* { 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..01b0a02f80b +--- /dev/null ++++ b/gcc/testsuite/gcc.target/i386/ret-thunk-12.c +@@ -0,0 +1,22 @@ ++/* { dg-do compile } */ ++/* { dg-options "-O2 -mfunction-return=3Dkeep -mindirect-branch=3Dthunk -= 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 {\tpause} 1 } } */ ++/* { 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..e028c2b6a99 +--- /dev/null ++++ b/gcc/testsuite/gcc.target/i386/ret-thunk-13.c +@@ -0,0 +1,22 @@ ++/* { dg-do compile } */ ++/* { dg-options "-O2 -mfunction-return=3Dkeep -mindirect-branch=3Dthunk-i= nline -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 {\tpause} 2 } } */ ++/* { dg-final { scan-assembler-times {\tlfence} 2 } } */ ++/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?bar" { target { ! x3= 2 } } } } */ ++/* { 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..c14ee3ae4c0 +--- /dev/null ++++ b/gcc/testsuite/gcc.target/i386/ret-thunk-14.c +@@ -0,0 +1,22 @@ ++/* { dg-do compile } */ ++/* { dg-options "-O2 -mfunction-return=3Dkeep -mindirect-branch=3Dthunk-e= xtern -fno-pic" } */ ++ ++extern void (*bar) (void); ++ ++__attribute__ ((function_return("thunk-inline"))) ++int ++foo (void) ++{ ++ bar (); ++ return 0; ++} ++ ++/* { dg-final { scan-assembler-times {\tpause} 1 } } */ ++/* { 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 { ! x3= 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-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..2f21e138ec2 +--- /dev/null ++++ b/gcc/testsuite/gcc.target/i386/ret-thunk-15.c +@@ -0,0 +1,22 @@ ++/* { dg-do compile } */ ++/* { dg-options "-O2 -mfunction-return=3Dkeep -mindirect-branch=3Dkeep -f= no-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 {\tpause} 1 } } */ ++/* { dg-final { scan-assembler-times {\tlfence} 1 } } */ ++/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?bar" { target { ! x3= 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-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..a16cad16aaa +--- /dev/null ++++ b/gcc/testsuite/gcc.target/i386/ret-thunk-16.c +@@ -0,0 +1,18 @@ ++/* { dg-do compile } */ ++/* { dg-options "-O2 -mfunction-return=3Dthunk-inline -mindirect-branch= =3Dthunk-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 {\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/ret-thunk-2.c b/gcc/testsuite/g= cc.target/i386/ret-thunk-2.c +new file mode 100644 +index 00000000000..c6659e3ad09 +--- /dev/null ++++ b/gcc/testsuite/gcc.target/i386/ret-thunk-2.c +@@ -0,0 +1,13 @@ ++/* { dg-do compile } */ ++/* { dg-options "-O2 -mfunction-return=3Dthunk-inline" } */ ++ ++void ++foo (void) ++{ ++} ++ ++/* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */ ++/* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */ ++/* { dg-final { scan-assembler {\tpause} } } */ ++/* { 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/g= cc.target/i386/ret-thunk-3.c +new file mode 100644 +index 00000000000..0f7f388f459 +--- /dev/null ++++ b/gcc/testsuite/gcc.target/i386/ret-thunk-3.c +@@ -0,0 +1,12 @@ ++/* { dg-do compile } */ ++/* { dg-options "-O2 -mfunction-return=3Dthunk-extern" } */ ++ ++void ++foo (void) ++{ ++} ++ ++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_return_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/ret-thunk-4.c b/gcc/testsuite/g= cc.target/i386/ret-thunk-4.c +new file mode 100644 +index 00000000000..9ae37e835a0 +--- /dev/null ++++ b/gcc/testsuite/gcc.target/i386/ret-thunk-4.c +@@ -0,0 +1,12 @@ ++/* { dg-do compile } */ ++/* { dg-options "-O2 -mfunction-return=3Dkeep" } */ ++ ++void ++foo (void) ++{ ++} ++ ++/* { dg-final { scan-assembler-not "jmp\[ \t\]*__x86_return_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/ret-thunk-5.c b/gcc/testsuite/g= cc.target/i386/ret-thunk-5.c +new file mode 100644 +index 00000000000..4bd0d2a27bc +--- /dev/null ++++ b/gcc/testsuite/gcc.target/i386/ret-thunk-5.c +@@ -0,0 +1,15 @@ ++/* { dg-do compile } */ ++/* { dg-options "-O2 -mfunction-return=3Dkeep" } */ ++ ++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 {\tpause} } } */ ++/* { dg-final { scan-assembler {\tlfence} } } */ +diff --git a/gcc/testsuite/gcc.target/i386/ret-thunk-6.c b/gcc/testsuite/g= cc.target/i386/ret-thunk-6.c +new file mode 100644 +index 00000000000..053841f6f7d +--- /dev/null ++++ b/gcc/testsuite/gcc.target/i386/ret-thunk-6.c +@@ -0,0 +1,14 @@ ++/* { dg-do compile } */ ++/* { dg-options "-O2 -mfunction-return=3Dkeep" } */ ++ ++__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 {\tpause} } } */ ++/* { 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/g= cc.target/i386/ret-thunk-7.c +new file mode 100644 +index 00000000000..262e6780112 +--- /dev/null ++++ b/gcc/testsuite/gcc.target/i386/ret-thunk-7.c +@@ -0,0 +1,13 @@ ++/* { dg-do compile } */ ++/* { dg-options "-O2 -mfunction-return=3Dkeep" } */ ++ ++__attribute__ ((function_return("thunk-extern"))) ++void ++foo (void) ++{ ++} ++ ++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_return_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/ret-thunk-8.c b/gcc/testsuite/g= cc.target/i386/ret-thunk-8.c +new file mode 100644 +index 00000000000..c1658e96673 +--- /dev/null ++++ b/gcc/testsuite/gcc.target/i386/ret-thunk-8.c +@@ -0,0 +1,14 @@ ++/* { dg-do compile } */ ++/* { dg-options "-O2 -mfunction-return=3Dthunk-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 {\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/ret-thunk-9.c b/gcc/testsuite/g= cc.target/i386/ret-thunk-9.c +new file mode 100644 +index 00000000000..f6ccad98da7 +--- /dev/null ++++ b/gcc/testsuite/gcc.target/i386/ret-thunk-9.c +@@ -0,0 +1,25 @@ ++/* { dg-do compile } */ ++/* { dg-options "-O2 -mfunction-return=3Dthunk -mindirect-branch=3Dthunk = -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 {\tpause} 1 { target { ! x32 } } } }= */ ++/* { dg-final { scan-assembler-times {\tlfence} 1 { target { ! x32 } } } = } */ ++/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?bar" { target { ! x3= 2 } } } } */ ++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" { target= { ! x32 } } } } */ ++/* { dg-final { scan-assembler-times {\tpause} 2 { 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 } } } = */ +--=20 +2.15.1 + diff --git a/gnu/packages/patches/gcc-retpoline-x86-Add-mindirect-branch-re= gister.patch b/gnu/packages/patches/gcc-retpoline-x86-Add-mindirect-branch-= register.patch new file mode 100644 index 000000000..5fbced669 --- /dev/null +++ b/gnu/packages/patches/gcc-retpoline-x86-Add-mindirect-branch-register.= patch @@ -0,0 +1,907 @@ +'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=3DCVE-2017-5715 + +Patch copied from the 'retpoline-regnames' branch of upstream source repos= itory +(please keep an eye for new branches or updates for existing branches): + +http://git.infradead.org/users/dwmw2/gcc-retpoline.git + +From 139dd2c61a11430263f91030910e2b63a73a11e7 Mon Sep 17 00:00:00 2001 +From: "H.J. Lu" +Date: Sat, 6 Jan 2018 22:29:56 -0800 +Subject: [PATCH 06/10] x86: Add -mindirect-branch-register + +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. + +-mindirect-branch=3D and -mfunction-return=3D tests are updated with +-mno-indirect-branch-register to avoid false test failures when +-mindirect-branch-register is added to RUNTESTFLAGS for "make check". + +gcc/ + + Backport from mainline + * 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. + * config/i386/i386.opt (mindirect-branch-register): New option. + * doc/invoke.texi: Document -mindirect-branch-register option. + +gcc/testsuite/ + + Backport from mainline + * gcc.target/i386/indirect-thunk-1.c (dg-options): Add + -mno-indirect-branch-register. + * gcc.target/i386/indirect-thunk-2.c: Likewise. + * gcc.target/i386/indirect-thunk-3.c: Likewise. + * gcc.target/i386/indirect-thunk-4.c: Likewise. + * gcc.target/i386/indirect-thunk-5.c: Likewise. + * gcc.target/i386/indirect-thunk-6.c: Likewise. + * gcc.target/i386/indirect-thunk-7.c: Likewise. + * gcc.target/i386/indirect-thunk-attr-1.c: Likewise. + * gcc.target/i386/indirect-thunk-attr-2.c: Likewise. + * gcc.target/i386/indirect-thunk-attr-3.c: Likewise. + * gcc.target/i386/indirect-thunk-attr-4.c: Likewise. + * gcc.target/i386/indirect-thunk-attr-5.c: Likewise. + * gcc.target/i386/indirect-thunk-attr-6.c: Likewise. + * gcc.target/i386/indirect-thunk-attr-7.c: Likewise. + * gcc.target/i386/indirect-thunk-bnd-1.c: Likewise. + * gcc.target/i386/indirect-thunk-bnd-2.c: Likewise. + * gcc.target/i386/indirect-thunk-bnd-3.c: Likewise. + * gcc.target/i386/indirect-thunk-bnd-4.c: Likewise. + * gcc.target/i386/indirect-thunk-extern-1.c: Likewise. + * gcc.target/i386/indirect-thunk-extern-2.c: Likewise. + * gcc.target/i386/indirect-thunk-extern-3.c: Likewise. + * gcc.target/i386/indirect-thunk-extern-4.c: Likewise. + * gcc.target/i386/indirect-thunk-extern-5.c: Likewise. + * gcc.target/i386/indirect-thunk-extern-6.c: Likewise. + * gcc.target/i386/indirect-thunk-extern-7.c: Likewise. + * gcc.target/i386/indirect-thunk-inline-1.c: Likewise. + * gcc.target/i386/indirect-thunk-inline-2.c: Likewise. + * gcc.target/i386/indirect-thunk-inline-3.c: Likewise. + * gcc.target/i386/indirect-thunk-inline-4.c: Likewise. + * gcc.target/i386/indirect-thunk-inline-5.c: Likewise. + * gcc.target/i386/indirect-thunk-inline-6.c: Likewise. + * gcc.target/i386/indirect-thunk-inline-7.c: Likewise. + * gcc.target/i386/ret-thunk-10.c: Likewise. + * gcc.target/i386/ret-thunk-11.c: Likewise. + * gcc.target/i386/ret-thunk-12.c: Likewise. + * gcc.target/i386/ret-thunk-13.c: Likewise. + * gcc.target/i386/ret-thunk-14.c: Likewise. + * gcc.target/i386/ret-thunk-15.c: Likewise. + * gcc.target/i386/ret-thunk-9.c: Likewise. + * gcc.target/i386/indirect-thunk-register-1.c: New test. + * gcc.target/i386/indirect-thunk-register-2.c: Likewise. + * gcc.target/i386/indirect-thunk-register-3.c: Likewise. +--- + 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/doc/invoke.texi | 7 ++++- + 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.target/i386/indirect-thunk-attr-1.c | 2 +- + .../gcc.target/i386/indirect-thunk-attr-2.c | 2 +- + .../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 | 2 +- + .../gcc.target/i386/indirect-thunk-attr-6.c | 2 +- + .../gcc.target/i386/indirect-thunk-attr-7.c | 2 +- + .../gcc.target/i386/indirect-thunk-bnd-1.c | 2 +- + .../gcc.target/i386/indirect-thunk-bnd-2.c | 2 +- + .../gcc.target/i386/indirect-thunk-bnd-3.c | 2 +- + .../gcc.target/i386/indirect-thunk-bnd-4.c | 2 +- + .../gcc.target/i386/indirect-thunk-extern-1.c | 2 +- + .../gcc.target/i386/indirect-thunk-extern-2.c | 2 +- + .../gcc.target/i386/indirect-thunk-extern-3.c | 2 +- + .../gcc.target/i386/indirect-thunk-extern-4.c | 2 +- + .../gcc.target/i386/indirect-thunk-extern-5.c | 2 +- + .../gcc.target/i386/indirect-thunk-extern-6.c | 2 +- + .../gcc.target/i386/indirect-thunk-extern-7.c | 2 +- + .../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-5.c | 2 +- + .../gcc.target/i386/indirect-thunk-inline-6.c | 2 +- + .../gcc.target/i386/indirect-thunk-inline-7.c | 2 +- + .../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 ++++++++++++ + 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 +- + 47 files changed, 154 insertions(+), 63 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 @@ +=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 =3D=3D DImode") ++ (and (match_test "TARGET_X32 && Pmode =3D=3D DImode ++ && !ix86_indirect_branch_thunk_register") + (match_operand 0 "GOT_memory_operand")))) +=20 + (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 =3D=3D DImode") ++ (and (match_test "TARGET_X32 && Pmode =3D=3D DImode ++ && !ix86_indirect_branch_thunk_register") + (match_operand 0 "GOT_memory_operand")))) +=20 + (define_constraint "Bz" +diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md +index d112bdb8552..96941e8c5c4 100644 +--- a/gcc/config/i386/i386.md ++++ b/gcc/config/i386/i386.md +@@ -11625,7 +11625,7 @@ + [(set (pc) (match_operand 0 "indirect_branch_operand"))] + "" + { +- if (TARGET_X32) ++ if (TARGET_X32 || ix86_indirect_branch_thunk_register) + operands[0] =3D convert_memory_address (word_mode, operands[0]); + cfun->machine->has_local_indirect_jump =3D true; + }) +@@ -11679,7 +11679,7 @@ + OPTAB_DIRECT); + } +=20 +- if (TARGET_X32) ++ if (TARGET_X32 || ix86_indirect_branch_thunk_register) + operands[0] =3D convert_memory_address (word_mode, operands[0]); + cfun->machine->has_local_indirect_jump =3D true; + }) +@@ -11871,7 +11871,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")]) +=20 +@@ -11880,7 +11880,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)) +@@ -11893,7 +11895,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) +@@ -11915,7 +11919,7 @@ + }) +=20 + (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) +@@ -11935,7 +11939,7 @@ + [(set_attr "type" "call")]) +=20 + (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) +@@ -11989,7 +11993,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))]) +=20 + ;; Call subroutine, returning value in operand 0 +@@ -12070,7 +12076,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")]) +=20 +@@ -12080,7 +12086,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) +@@ -12095,7 +12103,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) +@@ -12120,7 +12130,7 @@ +=20 + (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 b07388d95a9..852033cbb67 100644 +--- a/gcc/config/i386/i386.opt ++++ b/gcc/config/i386/i386.opt +@@ -951,3 +951,7 @@ Enum(indirect_branch) String(thunk-inline) Value(indir= ect_branch_thunk_inline) +=20 + EnumValue + Enum(indirect_branch) String(thunk-extern) Value(indirect_branch_thunk_ex= tern) ++ ++mindirect-branch-register ++Target Report Var(ix86_indirect_branch_thunk_register) Init(0) ++Force indirect call and jump via register. +diff --git a/gcc/config/i386/predicates.md b/gcc/config/i386/predicates.md +index 2fc2c60f6ac..a88b1d860ca 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")))) +=20 + ;; Return true if OP is a memory operands that can be used in sibcalls. +@@ -664,7 +665,8 @@ +=20 + ;; 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 =3D XEXP (op, 0); + return (GET_CODE (op) =3D=3D CONST +@@ -678,9 +680,11 @@ + (ior (match_test "constant_call_address_operand + (op, mode =3D=3D 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 =3D=3D DImode") ++ (and (match_test "TARGET_X32 && Pmode =3D=3D DImode ++ && !ix86_indirect_branch_thunk_register") + (match_operand 0 "GOT_memory_operand"))))) +=20 + ;; Similarly, but for tail calls, in which we cannot allow memory referen= ces. +@@ -688,14 +692,17 @@ + (ior (match_test "constant_call_address_operand + (op, mode =3D=3D 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 =3D=3D DImode") ++ (and (match_test "TARGET_X32 && Pmode =3D=3D DImode ++ && !ix86_indirect_branch_thunk_register") + (match_operand 0 "GOT_memory_operand"))))) +=20 + ;; Return true if OP is a 32-bit GOT symbol operand. + (define_predicate "GOT32_symbol_operand" +- (match_test "GET_CODE (op) =3D=3D CONST ++ (match_test "!ix86_indirect_branch_thunk_register ++ && GET_CODE (op) =3D=3D CONST + && GET_CODE (XEXP (op, 0)) =3D=3D UNSPEC + && XINT (XEXP (op, 0), 1) =3D=3D UNSPEC_GOT")) +=20 +diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi +index f3eb54b1668..1e572b1f9a2 100644 +--- a/gcc/doc/invoke.texi ++++ b/gcc/doc/invoke.texi +@@ -1211,7 +1211,8 @@ See RS/6000 and PowerPC Options. + -mavx256-split-unaligned-load -mavx256-split-unaligned-store @gol + -malign-data=3D@var{type} -mstack-protector-guard=3D@var{guard} @gol + -mmitigate-rop -mgeneral-regs-only @gol +--mindirect-branch=3D@var{choice} -mfunction-return=3D=3D@var{choice}} ++-mindirect-branch=3D@var{choice} -mfunction-return=3D=3D@var{choice} @gol ++-mindirect-branch-register} +=20 + @emph{x86 Windows Options} + @gccoptlist{-mconsole -mcygwin -mno-cygwin -mdll @gol +@@ -25709,6 +25710,10 @@ object file. You can control this behavior for a= specific function by + using the function attribute @code{function_return}. + @xref{Function Attributes}. +=20 ++@item -mindirect-branch-register ++@opindex -mindirect-branch-register ++Force indirect call and jump via register. ++ + @end table +=20 + 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/testsu= ite/gcc.target/i386/indirect-thunk-1.c +index f076155c91a..9eb9b273ade 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=3Dkeep -mindirect-branch=3Dthunk -= fno-pic" } */ ++/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=3Dke= ep -mindirect-branch=3Dthunk -fno-pic" } */ +=20 + typedef void (*dispatch_t)(long offset); +=20 +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-2.c b/gcc/testsu= ite/gcc.target/i386/indirect-thunk-2.c +index d7984f592fe..c63795e4127 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=3Dkeep -mindirect-branch=3Dthunk -= fno-pic" } */ ++/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=3Dke= ep -mindirect-branch=3Dthunk -fno-pic" } */ +=20 + typedef void (*dispatch_t)(long offset); +=20 +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-3.c b/gcc/testsu= ite/gcc.target/i386/indirect-thunk-3.c +index 3257d0a2e16..82973cda771 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=3Dkeep -mindirect-branch=3Dthunk -= fno-pic" } */ ++/* { dg-options "-O2 -mno-indirect-branch-register -mno-indirect-branch-r= egister -mno-indirect-branch-register -mfunction-return=3Dkeep -mindirect-b= ranch=3Dthunk -fno-pic" } */ +=20 + typedef void (*dispatch_t)(long offset); +=20 +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-4.c b/gcc/testsu= ite/gcc.target/i386/indirect-thunk-4.c +index 7cab2df6474..a5f3d1cbed8 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=3Dkeep -mindirect-branch=3Dthunk -= fno-pic" } */ ++/* { dg-options "-O2 -mno-indirect-branch-register -mno-indirect-branch-r= egister -mno-indirect-branch-register -mfunction-return=3Dkeep -mindirect-b= ranch=3Dthunk -fno-pic" } */ +=20 + typedef void (*dispatch_t)(long offset); +=20 +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-5.c b/gcc/testsu= ite/gcc.target/i386/indirect-thunk-5.c +index b4836c38d6c..fcaa18d10b7 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=3Dkeep -fpic -fno-plt -mindirect-b= ranch=3Dthunk" } */ ++/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=3Dke= ep -fpic -fno-plt -mindirect-branch=3Dthunk" } */ +=20 + extern void bar (void); +=20 +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-6.c b/gcc/testsu= ite/gcc.target/i386/indirect-thunk-6.c +index 1f06bd1af74..e4649283d10 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=3Dkeep -fpic -fno-plt -mindirect-b= ranch=3Dthunk" } */ ++/* { dg-options "-O2 -mno-indirect-branch-register -mno-indirect-branch-r= egister -mno-indirect-branch-register -mfunction-return=3Dkeep -fpic -fno-p= lt -mindirect-branch=3Dthunk" } */ +=20 + extern void bar (void); +=20 +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-7.c b/gcc/testsu= ite/gcc.target/i386/indirect-thunk-7.c +index 0b3fef86a20..ebfb8aab937 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=3Dkeep -mindirect-branch=3Dthunk -= fno-pic" } */ ++/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=3Dke= ep -mindirect-branch=3Dthunk -fno-pic" } */ +=20 + void func0 (void); + void func1 (void); +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-1.c b/gcc/t= estsuite/gcc.target/i386/indirect-thunk-attr-1.c +index 5f6cfc17b56..a08022db8e4 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=3Dkeep -fno-pic" } */ ++/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=3Dke= ep -fno-pic" } */ +=20 + typedef void (*dispatch_t)(long offset); +=20 +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-2.c b/gcc/t= estsuite/gcc.target/i386/indirect-thunk-attr-2.c +index b256160ec80..b257c695ad1 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=3Dkeep -fno-pic" } */ ++/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=3Dke= ep -fno-pic" } */ +=20 + typedef void (*dispatch_t)(long offset); +=20 +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-3.c b/gcc/t= estsuite/gcc.target/i386/indirect-thunk-attr-3.c +index 567c95051d6..dfb1370d23d 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=3Dkeep -fno-pic" } */ ++/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=3Dke= ep -fno-pic" } */ +=20 + typedef void (*dispatch_t)(long offset); +=20 +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-4.c b/gcc/t= estsuite/gcc.target/i386/indirect-thunk-attr-4.c +index 3b662af7d5d..a6e3f6f9f2b 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=3Dkeep -fno-pic" } */ ++/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=3Dke= ep -fno-pic" } */ +=20 + typedef void (*dispatch_t)(long offset); +=20 +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-5.c b/gcc/t= estsuite/gcc.target/i386/indirect-thunk-attr-5.c +index 98785a38248..4bb1c5f9220 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=3Dkeep -fno-pic" } */ ++/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=3Dke= ep -fno-pic" } */ +=20 + typedef void (*dispatch_t)(long offset); +=20 +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-6.c b/gcc/t= estsuite/gcc.target/i386/indirect-thunk-attr-6.c +index a498a39e404..4e33a638862 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=3Dkeep -fno-pic" } */ ++/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=3Dke= ep -fno-pic" } */ +=20 + typedef void (*dispatch_t)(long offset); +=20 +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-7.c b/gcc/t= estsuite/gcc.target/i386/indirect-thunk-attr-7.c +index 66f295d1eb6..427ba3ddbb4 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=3Dkeep -fno-pic" } */ ++/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=3Dke= ep -fno-pic" } */ +=20 + void func0 (void); + void func1 (void); +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-1.c b/gcc/te= stsuite/gcc.target/i386/indirect-thunk-bnd-1.c +index aacb814d737..dc7143414fb 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=3Dkeep -mindirect-branch=3Dthunk -= fcheck-pointer-bounds -mmpx -fno-pic" } */ ++/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=3Dke= ep -mindirect-branch=3Dthunk -fcheck-pointer-bounds -mmpx -fno-pic" } */ +=20 + void (*dispatch) (char *); + char buf[10]; +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-2.c b/gcc/te= stsuite/gcc.target/i386/indirect-thunk-bnd-2.c +index 7b44dda23df..737c60946f6 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=3Dkeep -mindirect-branch=3Dthunk -= fcheck-pointer-bounds -mmpx -fno-pic" } */ ++/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=3Dke= ep -mindirect-branch=3Dthunk -fcheck-pointer-bounds -mmpx -fno-pic" } */ +=20 + void (*dispatch) (char *); + char buf[10]; +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-3.c b/gcc/te= stsuite/gcc.target/i386/indirect-thunk-bnd-3.c +index 70b4fb36eea..d34485a0010 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=3Dkeep -mindirect-branch=3Dthunk -= fcheck-pointer-bounds -mmpx -fpic -fno-plt" } */ ++/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=3Dke= ep -mindirect-branch=3Dthunk -fcheck-pointer-bounds -mmpx -fpic -fno-plt" }= */ +=20 + void bar (char *); + char buf[10]; +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-4.c b/gcc/te= stsuite/gcc.target/i386/indirect-thunk-bnd-4.c +index 3baf03ee77c..0e19830de4d 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=3Dkeep -mindirect-branch=3Dthunk -= fcheck-pointer-bounds -mmpx -fpic -fno-plt" } */ ++/* { dg-options "-O2 -mno-indirect-branch-register -mno-indirect-branch-r= egister -mfunction-return=3Dkeep -mindirect-branch=3Dthunk -fcheck-pointer-= bounds -mmpx -fpic -fno-plt" } */ +=20 + 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 637fc3d3f4e..5c20a35ecec 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=3Dkeep -mindirect-branch=3Dthunk-e= xtern -fno-pic" } */ ++/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=3Dke= ep -mindirect-branch=3Dthunk-extern -fno-pic" } */ +=20 + typedef void (*dispatch_t)(long offset); +=20 +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 ff9efe03fe6..b2fb6e1bcd2 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=3Dkeep -mindirect-branch=3Dthunk-e= xtern -fno-pic" } */ ++/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=3Dke= ep -mindirect-branch=3Dthunk-extern -fno-pic" } */ +=20 + typedef void (*dispatch_t)(long offset); +=20 +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 2686a5f2db4..9c84547cd7c 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=3Dkeep -mindirect-branch=3Dthunk-e= xtern -fno-pic" } */ ++/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=3Dke= ep -mindirect-branch=3Dthunk-extern -fno-pic" } */ +=20 + typedef void (*dispatch_t)(long offset); +=20 +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 f07f6b214ad..457849564bb 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=3Dkeep -mindirect-branch=3Dthunk-e= xtern -fno-pic" } */ ++/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=3Dke= ep -mindirect-branch=3Dthunk-extern -fno-pic" } */ +=20 + typedef void (*dispatch_t)(long offset); +=20 +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 21740ac5b7f..5c07e02df6a 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=3Dkeep -fpic -fno-plt -mindirect-b= ranch=3Dthunk-extern" } */ ++/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=3Dke= ep -fpic -fno-plt -mindirect-branch=3Dthunk-extern" } */ +=20 + extern void bar (void); +=20 +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 a77c1f470b8..3eb440693a0 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=3Dkeep -fpic -fno-plt -mindirect-b= ranch=3Dthunk-extern" } */ ++/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=3Dke= ep -fpic -fno-plt -mindirect-branch=3Dthunk-extern" } */ +=20 + extern void bar (void); +=20 +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 e64910fd4aa..d4747ea0764 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=3Dkeep -mindirect-branch=3Dthunk-e= xtern -fno-pic" } */ ++/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=3Dke= ep -mindirect-branch=3Dthunk-extern -fno-pic" } */ +=20 + 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 365cf2ee226..536abfa74e4 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=3Dkeep -mindirect-branch=3Dthunk-i= nline -fno-pic" } */ ++/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=3Dke= ep -mindirect-branch=3Dthunk-inline -fno-pic" } */ +=20 + typedef void (*dispatch_t)(long offset); +=20 +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 72646a4960b..bd2b6246aa1 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=3Dkeep -mindirect-branch=3Dthunk-i= nline -fno-pic" } */ ++/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=3Dke= ep -mindirect-branch=3Dthunk-inline -fno-pic" } */ +=20 + typedef void (*dispatch_t)(long offset); +=20 +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 f48945e3dfc..9885eebbcff 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=3Dkeep -mindirect-branch=3Dthunk-i= nline -fno-pic" } */ ++/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=3Dke= ep -mindirect-branch=3Dthunk-inline -fno-pic" } */ +=20 + typedef void (*dispatch_t)(long offset); +=20 +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 4b1d558fc4e..7b3983949d2 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=3Dkeep -mindirect-branch=3Dthunk-i= nline -fno-pic" } */ ++/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=3Dke= ep -mindirect-branch=3Dthunk-inline -fno-pic" } */ +=20 + typedef void (*dispatch_t)(long offset); +=20 +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 0f687c3b027..c6d77e10352 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=3Dkeep -fpic -fno-plt -mindirect-b= ranch=3Dthunk-inline" } */ ++/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=3Dke= ep -fpic -fno-plt -mindirect-branch=3Dthunk-inline" } */ +=20 + extern void bar (void); +=20 +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 b27c6fc96a2..6454827b780 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=3Dkeep -fpic -fno-plt -mindirect-b= ranch=3Dthunk-inline" } */ ++/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=3Dke= ep -fpic -fno-plt -mindirect-branch=3Dthunk-inline" } */ +=20 + extern void bar (void); +=20 +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 2c496492eaa..cc592f89aba 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=3Dkeep -mindirect-branch=3Dthunk-i= nline -fno-pic" } */ ++/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=3Dke= ep -mindirect-branch=3Dthunk-inline -fno-pic" } */ +=20 + void func0 (void); + void func1 (void); +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-register-1.c b/g= cc/testsuite/gcc.target/i386/indirect-thunk-register-1.c +new file mode 100644 +index 00000000000..7d396a31953 +--- /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=3Dthunk -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 {\tpause} } } */ ++/* { 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/g= cc/testsuite/gcc.target/i386/indirect-thunk-register-2.c +new file mode 100644 +index 00000000000..e7e616bb271 +--- /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=3Dthunk-inline -mindirect-branch-r= egister -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 {\tpause} } } */ ++/* { 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/g= cc/testsuite/gcc.target/i386/indirect-thunk-register-3.c +new file mode 100644 +index 00000000000..5320e923be2 +--- /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=3Dthunk-extern -mindirect-branch-r= egister -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(pause|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/ret-thunk-10.c b/gcc/testsuite/= gcc.target/i386/ret-thunk-10.c +index 1630e2fa2b5..b4f9d48065d 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=3Dthunk-inline -mindirect-branch= =3Dthunk -fno-pic" } */ ++/* { dg-options "-O2 -mno-indirect-branch-register -mno-indirect-branch-r= egister -mfunction-return=3Dthunk-inline -mindirect-branch=3Dthunk -fno-pic= " } */ +=20 + extern void (*bar) (void); +=20 +diff --git a/gcc/testsuite/gcc.target/i386/ret-thunk-11.c b/gcc/testsuite/= gcc.target/i386/ret-thunk-11.c +index 876159cf783..0312577a043 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=3Dthunk-extern -mindirect-branch= =3Dthunk -fno-pic" } */ ++/* { dg-options "-O2 -mno-indirect-branch-register -mno-indirect-branch-r= egister -mno-indirect-branch-register -mno-indirect-branch-register -mfunct= ion-return=3Dthunk-extern -mindirect-branch=3Dthunk -fno-pic" } */ +=20 + extern void (*bar) (void); +=20 +diff --git a/gcc/testsuite/gcc.target/i386/ret-thunk-12.c b/gcc/testsuite/= gcc.target/i386/ret-thunk-12.c +index 01b0a02f80b..fa3181303c9 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=3Dkeep -mindirect-branch=3Dthunk -= fno-pic" } */ ++/* { dg-options "-O2 -mno-indirect-branch-register -mno-indirect-branch-r= egister -mno-indirect-branch-register -mno-indirect-branch-register -mfunct= ion-return=3Dkeep -mindirect-branch=3Dthunk -fno-pic" } */ +=20 + extern void (*bar) (void); +=20 +diff --git a/gcc/testsuite/gcc.target/i386/ret-thunk-13.c b/gcc/testsuite/= gcc.target/i386/ret-thunk-13.c +index e028c2b6a99..7a08e71c76b 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=3Dkeep -mindirect-branch=3Dthunk-i= nline -fno-pic" } */ ++/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=3Dke= ep -mindirect-branch=3Dthunk-inline -fno-pic" } */ +=20 + 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 c14ee3ae4c0..dacf0c769fc 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=3Dkeep -mindirect-branch=3Dthunk-e= xtern -fno-pic" } */ ++/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=3Dke= ep -mindirect-branch=3Dthunk-extern -fno-pic" } */ +=20 + extern void (*bar) (void); +=20 +diff --git a/gcc/testsuite/gcc.target/i386/ret-thunk-15.c b/gcc/testsuite/= gcc.target/i386/ret-thunk-15.c +index 2f21e138ec2..cf06a5f35c7 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=3Dkeep -mindirect-branch=3Dkeep -f= no-pic" } */ ++/* { dg-options "-O2 -mno-indirect-branch-register -mno-indirect-branch-r= egister -mno-indirect-branch-register -mno-indirect-branch-register -mfunct= ion-return=3Dkeep -mindirect-branch=3Dkeep -fno-pic" } */ +=20 + extern void (*bar) (void); +=20 +diff --git a/gcc/testsuite/gcc.target/i386/ret-thunk-9.c b/gcc/testsuite/g= cc.target/i386/ret-thunk-9.c +index f6ccad98da7..6da5ab97081 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=3Dthunk -mindirect-branch=3Dthunk = -fno-pic" } */ ++/* { dg-options "-O2 -mno-indirect-branch-register -mno-indirect-branch-r= egister -mfunction-return=3Dthunk -mindirect-branch=3Dthunk -fno-pic" } */ +=20 + extern void (*bar) (void); +=20 +--=20 +2.15.1 + diff --git a/gnu/packages/patches/gcc-retpoline-x86-Add-mindirect-branch.pa= tch b/gnu/packages/patches/gcc-retpoline-x86-Add-mindirect-branch.patch new file mode 100644 index 000000000..e622601ea --- /dev/null +++ b/gnu/packages/patches/gcc-retpoline-x86-Add-mindirect-branch.patch @@ -0,0 +1,2171 @@ +'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=3DCVE-2017-5715 + +Patch copied from the 'retpoline-regnames' branch of upstream source repos= itory +(please keep an eye for new branches or updates for existing branches): + +http://git.infradead.org/users/dwmw2/gcc-retpoline.git + +From 09f7c546376f7ed6770fc64f24aed77229f95f67 Mon Sep 17 00:00:00 2001 +From: "H.J. Lu" +Date: Sat, 6 Jan 2018 22:29:55 -0800 +Subject: [PATCH 04/10] x86: Add -mindirect-branch=3D + +Add -mindirect-branch=3D option to convert indirect call and jump to call +and return thunks. The default is 'keep', which keeps indirect call and +jump unmodified. 'thunk' converts indirect call and jump to call and +return thunk. 'thunk-inline' converts indirect call and jump to inlined +call and return thunk. 'thunk-extern' converts indirect call and jump to +external call and return thunk provided in a separate object file. You +can control this behavior for a specific function by using the function +attribute indirect_branch. + +2 kinds of thunks are geneated. Memory thunk where the function address +is at the top of the stack: + +__x86_indirect_thunk: + call L2 +L1: + pause + lfence + jmp L1 +L2: + lea 8(%rsp), %rsp|lea 4(%esp), %esp + ret + +Indirect jmp via memory, "jmp mem", is converted to + + push memory + jmp __x86_indirect_thunk + +Indirect call via memory, "call mem", is converted to + + jmp L2 +L1: + push [mem] + jmp __x86_indirect_thunk +L2: + call L1 + +Register thunk where the function address is in a register, reg: + +__x86_indirect_thunk_reg: + call L2 +L1: + pause + lfence + jmp L1 +L2: + movq %reg, (%rsp)|movl %reg, (%esp) + ret + +where reg is one of (r|e)ax, (r|e)dx, (r|e)cx, (r|e)bx, (r|e)si, (r|e)di, +(r|e)bp, r8, r9, r10, r11, r12, r13, r14 and r15. + +Indirect jmp via register, "jmp reg", is converted to + + jmp __x86_indirect_thunk_reg + +Indirect call via register, "call reg", is converted to + + call __x86_indirect_thunk_reg + +gcc/ + + Backport from mainline + * config/i386/i386-opts.h (indirect_branch): New. + * config/i386/i386-protos.h (ix86_output_indirect_jmp): Likewise. + * config/i386/i386.c (ix86_using_red_zone): Disallow red-zone + with local indirect jump when converting indirect call and jump. + (ix86_set_indirect_branch_type): New. + (ix86_set_current_function): Call ix86_set_indirect_branch_type. + (indirectlabelno): New. + (indirect_thunk_needed): Likewise. + (indirect_thunk_bnd_needed): Likewise. + (indirect_thunks_used): Likewise. + (indirect_thunks_bnd_used): Likewise. + (INDIRECT_LABEL): Likewise. + (indirect_thunk_name): Likewise. + (output_indirect_thunk): Likewise. + (output_indirect_thunk_function): Likewise. + (ix86_output_indirect_branch): Likewise. + (ix86_output_indirect_jmp): Likewise. + (ix86_code_end): Call output_indirect_thunk_function if needed. + (ix86_output_call_insn): Call ix86_output_indirect_branch if + needed. + (ix86_handle_fndecl_attribute): Handle indirect_branch. + (ix86_attribute_table): Add indirect_branch. + * config/i386/i386.h (machine_function): Add indirect_branch_type + and has_local_indirect_jump. + * config/i386/i386.md (indirect_jump): Set has_local_indirect_jump + to true. + (tablejump): Likewise. + (*indirect_jump): Use ix86_output_indirect_jmp. + (*tablejump_1): Likewise. + (simple_return_indirect_internal): Likewise. + * config/i386/i386.opt (mindirect-branch=3D): New option. + (indirect_branch): New. + (keep): Likewise. + (thunk): Likewise. + (thunk-inline): Likewise. + (thunk-extern): Likewise. + * doc/extend.texi: Document indirect_branch function attribute. + * doc/invoke.texi: Document -mindirect-branch=3D option. + +gcc/testsuite/ + + Backport from mainline + * gcc.target/i386/indirect-thunk-1.c: New test. + * gcc.target/i386/indirect-thunk-2.c: Likewise. + * gcc.target/i386/indirect-thunk-3.c: Likewise. + * gcc.target/i386/indirect-thunk-4.c: Likewise. + * gcc.target/i386/indirect-thunk-5.c: Likewise. + * gcc.target/i386/indirect-thunk-6.c: Likewise. + * gcc.target/i386/indirect-thunk-7.c: Likewise. + * gcc.target/i386/indirect-thunk-attr-1.c: Likewise. + * gcc.target/i386/indirect-thunk-attr-2.c: Likewise. + * gcc.target/i386/indirect-thunk-attr-3.c: Likewise. + * gcc.target/i386/indirect-thunk-attr-4.c: Likewise. + * gcc.target/i386/indirect-thunk-attr-5.c: Likewise. + * gcc.target/i386/indirect-thunk-attr-6.c: Likewise. + * gcc.target/i386/indirect-thunk-attr-7.c: Likewise. + * gcc.target/i386/indirect-thunk-attr-8.c: Likewise. + * gcc.target/i386/indirect-thunk-bnd-1.c: Likewise. + * gcc.target/i386/indirect-thunk-bnd-2.c: Likewise. + * gcc.target/i386/indirect-thunk-bnd-3.c: Likewise. + * gcc.target/i386/indirect-thunk-bnd-4.c: Likewise. + * gcc.target/i386/indirect-thunk-extern-1.c: Likewise. + * gcc.target/i386/indirect-thunk-extern-2.c: Likewise. + * gcc.target/i386/indirect-thunk-extern-3.c: Likewise. + * gcc.target/i386/indirect-thunk-extern-4.c: Likewise. + * gcc.target/i386/indirect-thunk-extern-5.c: Likewise. + * gcc.target/i386/indirect-thunk-extern-6.c: Likewise. + * gcc.target/i386/indirect-thunk-extern-7.c: Likewise. + * gcc.target/i386/indirect-thunk-inline-1.c: Likewise. + * gcc.target/i386/indirect-thunk-inline-2.c: Likewise. + * gcc.target/i386/indirect-thunk-inline-3.c: Likewise. + * gcc.target/i386/indirect-thunk-inline-4.c: Likewise. + * gcc.target/i386/indirect-thunk-inline-5.c: Likewise. + * gcc.target/i386/indirect-thunk-inline-6.c: Likewise. + * gcc.target/i386/indirect-thunk-inline-7.c: Likewise. +--- + gcc/config/i386/i386-opts.h | 13 + + gcc/config/i386/i386-protos.h | 1 + + gcc/config/i386/i386.c | 648 ++++++++++++++++= ++++- + gcc/config/i386/i386.h | 7 + + gcc/config/i386/i386.md | 26 +- + gcc/config/i386/i386.opt | 20 + + gcc/doc/extend.texi | 10 + + gcc/doc/invoke.texi | 14 +- + gcc/testsuite/gcc.target/i386/indirect-thunk-1.c | 20 + + gcc/testsuite/gcc.target/i386/indirect-thunk-2.c | 20 + + gcc/testsuite/gcc.target/i386/indirect-thunk-3.c | 21 + + gcc/testsuite/gcc.target/i386/indirect-thunk-4.c | 21 + + gcc/testsuite/gcc.target/i386/indirect-thunk-5.c | 17 + + gcc/testsuite/gcc.target/i386/indirect-thunk-6.c | 18 + + gcc/testsuite/gcc.target/i386/indirect-thunk-7.c | 44 ++ + .../gcc.target/i386/indirect-thunk-attr-1.c | 23 + + .../gcc.target/i386/indirect-thunk-attr-2.c | 21 + + .../gcc.target/i386/indirect-thunk-attr-3.c | 23 + + .../gcc.target/i386/indirect-thunk-attr-4.c | 22 + + .../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 | 42 ++ + .../gcc.target/i386/indirect-thunk-bnd-1.c | 20 + + .../gcc.target/i386/indirect-thunk-bnd-2.c | 21 + + .../gcc.target/i386/indirect-thunk-bnd-3.c | 19 + + .../gcc.target/i386/indirect-thunk-bnd-4.c | 20 + + .../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 ++ + .../gcc.target/i386/indirect-thunk-inline-1.c | 20 + + .../gcc.target/i386/indirect-thunk-inline-2.c | 20 + + .../gcc.target/i386/indirect-thunk-inline-3.c | 21 + + .../gcc.target/i386/indirect-thunk-inline-4.c | 21 + + .../gcc.target/i386/indirect-thunk-inline-5.c | 17 + + .../gcc.target/i386/indirect-thunk-inline-6.c | 18 + + .../gcc.target/i386/indirect-thunk-inline-7.c | 44 ++ + 41 files changed, 1494 insertions(+), 19 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 + 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 + 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 + 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 + 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 542cd0f3d67..efcdc3b1a14 100644 +--- a/gcc/config/i386/i386-opts.h ++++ b/gcc/config/i386/i386-opts.h +@@ -99,4 +99,17 @@ enum stack_protector_guard { + SSP_GLOBAL /* global canary */ + }; +=20 ++/* This is used to mitigate variant #2 of the speculative execution ++ vulnerabilities on x86 processors identified by CVE-2017-5715, aka ++ Spectre. They convert indirect branches and function returns to ++ call and return thunks to avoid speculative execution via indirect ++ call, jmp and ret. */ ++enum indirect_branch { ++ indirect_branch_unset =3D 0, ++ indirect_branch_keep, ++ indirect_branch_thunk, ++ indirect_branch_thunk_inline, ++ indirect_branch_thunk_extern ++}; ++ + #endif +diff --git a/gcc/config/i386/i386-protos.h b/gcc/config/i386/i386-protos.h +index d2cccf14735..bcdd9872db9 100644 +--- a/gcc/config/i386/i386-protos.h ++++ b/gcc/config/i386/i386-protos.h +@@ -313,6 +313,7 @@ extern enum attr_cpu ix86_schedule; + #endif +=20 + extern const char * ix86_output_call_insn (rtx_insn *insn, rtx call_op); ++extern const char * ix86_output_indirect_jmp (rtx call_op, bool ret_p); + extern bool ix86_operands_ok_for_move_multiple (rtx *operands, bool load, + enum machine_mode mode); +=20 +diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c +index 986e6d79584..f1c58faa035 100644 +--- a/gcc/config/i386/i386.c ++++ b/gcc/config/i386/i386.c +@@ -4212,12 +4212,23 @@ make_pass_stv (gcc::context *ctxt) + return new pass_stv (ctxt); + } +=20 +-/* 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. ++ ++ TODO: If we can reserve the first 2 WORDs, for PUSH and, another ++ for CALL, in red-zone, we can allow local indirect jumps with ++ indirect thunk. */ +=20 + 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 =3D=3D indirect_branch_keep= )); + } + + /* Return a string that documents the current -m options. The caller is +@@ -7148,6 +7159,37 @@ ix86_set_func_type (tree fndecl) + } + } +=20 ++/* 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 =3D=3D indirect_branch_unset) ++ { ++ tree attr =3D lookup_attribute ("indirect_branch", ++ DECL_ATTRIBUTES (fndecl)); ++ if (attr !=3D NULL) ++ { ++ tree args =3D TREE_VALUE (attr); ++ if (args =3D=3D NULL) ++ gcc_unreachable (); ++ tree cst =3D TREE_VALUE (args); ++ if (strcmp (TREE_STRING_POINTER (cst), "keep") =3D=3D 0) ++ cfun->machine->indirect_branch_type =3D indirect_branch_keep; ++ else if (strcmp (TREE_STRING_POINTER (cst), "thunk") =3D=3D 0) ++ cfun->machine->indirect_branch_type =3D indirect_branch_thunk; ++ else if (strcmp (TREE_STRING_POINTER (cst), "thunk-inline") =3D=3D 0) ++ cfun->machine->indirect_branch_type =3D indirect_branch_thunk_inline; ++ else if (strcmp (TREE_STRING_POINTER (cst), "thunk-extern") =3D=3D 0) ++ cfun->machine->indirect_branch_type =3D indirect_branch_thunk_extern; ++ else ++ gcc_unreachable (); ++ } ++ else ++ cfun->machine->indirect_branch_type =3D 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. */ +@@ -7163,7 +7205,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 !=3D NULL_TREE) +- ix86_set_func_type (fndecl); ++ { ++ ix86_set_func_type (fndecl); ++ ix86_set_indirect_branch_type (fndecl); ++ } + return; + } +=20 +@@ -7183,6 +7228,7 @@ ix86_set_current_function (tree fndecl) + } +=20 + ix86_set_func_type (fndecl); ++ ix86_set_indirect_branch_type (fndecl); +=20 + tree new_tree =3D DECL_FUNCTION_SPECIFIC_TARGET (fndecl); + if (new_tree =3D=3D NULL_TREE) +@@ -11920,6 +11966,220 @@ ix86_setup_frame_addresses (void) + # endif + #endif +=20 ++/* Label count for call and return thunks. It is used to make unique ++ labels in call and return thunks. */ ++static int indirectlabelno; ++ ++/* True if call and return thunk functions are needed. */ ++static bool indirect_thunk_needed =3D false; ++/* True if call and return thunk functions with the BND prefix are ++ needed. */ ++static bool indirect_thunk_bnd_needed =3D false; ++ ++/* Bit masks of integer registers, which contain branch target, used ++ by call and return thunks functions. */ ++static int indirect_thunks_used; ++/* Bit masks of integer registers, which contain branch target, used ++ by call and return thunks functions with the BND prefix. */ ++static int indirect_thunks_bnd_used; ++ ++#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], int regno, bool need_bnd_p) ++{ ++ if (USE_HIDDEN_LINKONCE) ++ { ++ const char *bnd =3D need_bnd_p ? "_bnd" : ""; ++ if (regno >=3D 0) ++ { ++ const char *reg_prefix; ++ if (LEGACY_INT_REGNO_P (regno)) ++ reg_prefix =3D TARGET_64BIT ? "r" : "e"; ++ else ++ reg_prefix =3D ""; ++ sprintf (name, "__x86_indirect_thunk%s_%s%s", ++ bnd, reg_prefix, reg_names[regno]); ++ } ++ else ++ sprintf (name, "__x86_indirect_thunk%s", bnd); ++ } ++ else ++ { ++ if (regno >=3D 0) ++ { ++ if (need_bnd_p) ++ ASM_GENERATE_INTERNAL_LABEL (name, "LITBR", regno); ++ else ++ ASM_GENERATE_INTERNAL_LABEL (name, "LITR", regno); ++ } ++ else ++ { ++ if (need_bnd_p) ++ ASM_GENERATE_INTERNAL_LABEL (name, "LITB", 0); ++ else ++ ASM_GENERATE_INTERNAL_LABEL (name, "LIT", 0); ++ } ++ } ++} ++ ++/* Output a call and return thunk for indirect branch. If BND_P is ++ true, the BND prefix is needed. If REGNO !=3D -1, the function ++ address is in REGNO and the call and return thunk looks like: ++ ++ call L2 ++ L1: ++ pause ++ jmp L1 ++ L2: ++ mov %REG, (%sp) ++ ret ++ ++ Otherwise, the function address is on the top of stack and the ++ call and return thunk looks like: ++ ++ call L2 ++ L1: ++ pause ++ jmp L1 ++ L2: ++ lea WORD_SIZE(%sp), %sp ++ ret ++ */ ++ ++static void ++output_indirect_thunk (bool need_bnd_p, int regno) ++{ ++ 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); ++ ++ /* Pause + lfence. */ ++ fprintf (asm_out_file, "\tpause\n\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); ++ ++ if (regno >=3D 0) ++ { ++ /* MOV. */ ++ rtx xops[2]; ++ xops[0] =3D gen_rtx_MEM (word_mode, stack_pointer_rtx); ++ xops[1] =3D gen_rtx_REG (word_mode, regno); ++ output_asm_insn ("mov\t{%1, %0|%0, %1}", xops); ++ } ++ else ++ { ++ /* LEA. */ ++ rtx xops[2]; ++ xops[0] =3D stack_pointer_rtx; ++ xops[1] =3D 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); ++} ++ ++/* Output a funtion with a call and return thunk for indirect branch. ++ If BND_P is true, the BND prefix is needed. If REGNO !=3D -1, the ++ function address is in REGNO. Otherwise, the function address is ++ on the top of stack. */ ++ ++static void ++output_indirect_thunk_function (bool need_bnd_p, int regno) ++{ ++ char name[32]; ++ tree decl; ++ ++ /* Create __x86_indirect_thunk/__x86_indirect_thunk_bnd. */ ++ indirect_thunk_name (name, regno, need_bnd_p); ++ decl =3D build_decl (BUILTINS_LOCATION, FUNCTION_DECL, ++ get_identifier (name), ++ build_function_type_list (void_type_node, NULL_TREE)); ++ DECL_RESULT (decl) =3D build_decl (BUILTINS_LOCATION, RESULT_DECL, ++ NULL_TREE, void_type_node); ++ TREE_PUBLIC (decl) =3D 1; ++ TREE_STATIC (decl) =3D 1; ++ DECL_IGNORED_P (decl) =3D 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) =3D 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) =3D make_node (BLOCK); ++ current_function_decl =3D 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 =3D true; ++ first_function_block_is_cold =3D 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, regno); ++ ++ final_end_function (); ++ init_insn_lengths (); ++ free_after_compilation (cfun); ++ set_cfun (NULL); ++ current_function_decl =3D NULL; ++} ++ + static int pic_labels_used; +=20 + /* Fills in the label name that should be used for a pc thunk for +@@ -11946,11 +12206,32 @@ ix86_code_end (void) + rtx xops[2]; + int regno; +=20 ++ if (indirect_thunk_needed) ++ output_indirect_thunk_function (false, -1); ++ if (indirect_thunk_bnd_needed) ++ output_indirect_thunk_function (true, -1); ++ ++ for (regno =3D FIRST_REX_INT_REG; regno <=3D LAST_REX_INT_REG; regno++) ++ { ++ int i =3D 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 =3D AX_REG; regno <=3D SP_REG; regno++) + { + char name[32]; + tree decl; +=20 ++ 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; +=20 +@@ -28446,12 +28727,292 @@ ix86_nopic_noplt_attribute_p (rtx call_op) + return false; + } +=20 ++/* Output indirect branch via a call and return thunk. CALL_OP is a ++ register which contains the branch target. XASM is the assembly ++ template for CALL_OP. Branch is a tail call if SIBCALL_P is true. ++ A normal call is converted to: ++ ++ call __x86_indirect_thunk_reg ++ ++ and a tail call is converted to: ++ ++ jmp __x86_indirect_thunk_reg ++ */ ++ ++static void ++ix86_output_indirect_branch_via_reg (rtx call_op, bool sibcall_p) ++{ ++ char thunk_name_buf[32]; ++ char *thunk_name; ++ bool need_bnd_p =3D ix86_bnd_prefixed_insn_p (current_output_insn); ++ int regno =3D REGNO (call_op); ++ ++ if (cfun->machine->indirect_branch_type ++ !=3D indirect_branch_thunk_inline) ++ { ++ if (cfun->machine->indirect_branch_type =3D=3D indirect_branch_thun= k) ++ { ++ int i =3D regno; ++ if (i >=3D FIRST_REX_INT_REG) ++ i -=3D (FIRST_REX_INT_REG - LAST_INT_REG - 1); ++ if (need_bnd_p) ++ indirect_thunks_bnd_used |=3D 1 << i; ++ else ++ indirect_thunks_used |=3D 1 << i; ++ } ++ indirect_thunk_name (thunk_name_buf, regno, need_bnd_p); ++ thunk_name =3D thunk_name_buf; ++ } ++ else ++ thunk_name =3D NULL; ++ ++ if (sibcall_p) ++ { ++ if (thunk_name !=3D 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, regno); ++ } ++ else ++ { ++ if (thunk_name !=3D 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]; ++ ++ 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 (thunk_name !=3D 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, regno); ++ ++ 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); ++ } ++} ++ ++/* Output indirect branch via a call and return thunk. CALL_OP is ++ the branch target. XASM is the assembly template for CALL_OP. ++ Branch is a tail call if SIBCALL_P is true. A normal call is ++ converted to: ++ ++ jmp L2 ++ L1: ++ push CALL_OP ++ jmp __x86_indirect_thunk ++ L2: ++ call L1 ++ ++ and a tail call is converted to: ++ ++ push CALL_OP ++ jmp __x86_indirect_thunk ++ */ ++ ++static void ++ix86_output_indirect_branch_via_push (rtx call_op, const char *xasm, ++ bool sibcall_p) ++{ ++ char thunk_name_buf[32]; ++ char *thunk_name; ++ char push_buf[64]; ++ bool need_bnd_p =3D ix86_bnd_prefixed_insn_p (current_output_insn); ++ int regno =3D -1; ++ ++ if (cfun->machine->indirect_branch_type ++ !=3D indirect_branch_thunk_inline) ++ { ++ if (cfun->machine->indirect_branch_type =3D=3D indirect_branch_thun= k) ++ { ++ if (need_bnd_p) ++ indirect_thunk_bnd_needed =3D true; ++ else ++ indirect_thunk_needed =3D true; ++ } ++ indirect_thunk_name (thunk_name_buf, regno, need_bnd_p); ++ thunk_name =3D thunk_name_buf; ++ } ++ else ++ thunk_name =3D NULL; ++ ++ 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 !=3D 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, regno); ++ } ++ 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); ++ ++ /* An external function may be called via GOT, instead of PLT. */ ++ if (MEM_P (call_op)) ++ { ++ struct ix86_address parts; ++ rtx addr =3D XEXP (call_op, 0); ++ if (ix86_decompose_address (addr, &parts) ++ && parts.base =3D=3D 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 =3D gen_rtx_MULT (Pmode, parts.index, ++ GEN_INT (parts.scale)); ++ addr =3D gen_rtx_PLUS (Pmode, stack_pointer_rtx, ++ addr); ++ } ++ else ++ addr =3D stack_pointer_rtx; ++ ++ rtx disp; ++ if (parts.disp !=3D NULL_RTX) ++ disp =3D plus_constant (Pmode, parts.disp, ++ UNITS_PER_WORD); ++ else ++ disp =3D GEN_INT (UNITS_PER_WORD); ++ ++ addr =3D gen_rtx_PLUS (Pmode, addr, disp); ++ call_op =3D gen_rtx_MEM (GET_MODE (call_op), addr); ++ } ++ } ++ ++ output_asm_insn (push_buf, &call_op); ++ ++ if (thunk_name !=3D 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, regno); ++ ++ 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); ++ } ++} ++ ++/* Output indirect branch via a call and return thunk. CALL_OP is ++ the branch target. XASM is the assembly template for CALL_OP. ++ Branch is a tail call if SIBCALL_P is true. */ ++ ++static void ++ix86_output_indirect_branch (rtx call_op, const char *xasm, ++ bool sibcall_p) ++{ ++ if (REG_P (call_op)) ++ ix86_output_indirect_branch_via_reg (call_op, sibcall_p); ++ else ++ ix86_output_indirect_branch_via_push (call_op, xasm, sibcall_p); ++} ++/* Output indirect jump. CALL_OP is the jump target. Jump is a ++ function return if RET_P is true. */ ++ ++const char * ++ix86_output_indirect_jmp (rtx call_op, bool ret_p) ++{ ++ if (cfun->machine->indirect_branch_type !=3D 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 !=3D 0) ++ gcc_unreachable (); ++ ++ ix86_output_indirect_branch (call_op, "%0", true); ++ return ""; ++ } ++ else ++ return "%!jmp\t%A0"; ++} ++ + /* Output the assembly for a call instruction. */ +=20 + const char * + ix86_output_call_insn (rtx_insn *insn, rtx call_op) + { + bool direct_p =3D constant_call_address_operand (call_op, VOIDmode); ++ bool output_indirect_p ++ =3D (!TARGET_SEH ++ && cfun->machine->indirect_branch_type !=3D indirect_branch_keep); + bool seh_nop_p =3D false; + const char *xasm; +=20 +@@ -28461,10 +29022,21 @@ ix86_output_call_insn (rtx_insn *insn, rtx call_= op) + { + if (ix86_nopic_noplt_attribute_p (call_op)) + { ++ direct_p =3D false; + if (TARGET_64BIT) +- xasm =3D "%!jmp\t{*%p0@GOTPCREL(%%rip)|[QWORD PTR %p0@GOTPCREL[rip]]}"; ++ { ++ if (output_indirect_p) ++ xasm =3D "{%p0@GOTPCREL(%%rip)|[QWORD PTR %p0@GOTPCREL[rip]]}"; ++ else ++ xasm =3D "%!jmp\t{*%p0@GOTPCREL(%%rip)|[QWORD PTR %p0@GOTPCREL[rip]= ]}"; ++ } + else +- xasm =3D "%!jmp\t{*%p0@GOT|[DWORD PTR %p0@GOT]}"; ++ { ++ if (output_indirect_p) ++ xasm =3D "{%p0@GOT|[DWORD PTR %p0@GOT]}"; ++ else ++ xasm =3D "%!jmp\t{*%p0@GOT|[DWORD PTR %p0@GOT]}"; ++ } + } + else + xasm =3D "%!jmp\t%P0"; +@@ -28474,9 +29046,17 @@ ix86_output_call_insn (rtx_insn *insn, rtx call_o= p) + else if (TARGET_SEH) + xasm =3D "%!rex.W jmp\t%A0"; + else +- xasm =3D "%!jmp\t%A0"; ++ { ++ if (output_indirect_p) ++ xasm =3D "%0"; ++ else ++ xasm =3D "%!jmp\t%A0"; ++ } +=20 +- 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 ""; + } +=20 +@@ -28514,18 +29094,37 @@ ix86_output_call_insn (rtx_insn *insn, rtx call_= op) + { + if (ix86_nopic_noplt_attribute_p (call_op)) + { ++ direct_p =3D false; + if (TARGET_64BIT) +- xasm =3D "%!call\t{*%p0@GOTPCREL(%%rip)|[QWORD PTR %p0@GOTPCREL[rip]= ]}"; ++ { ++ if (output_indirect_p) ++ xasm =3D "{%p0@GOTPCREL(%%rip)|[QWORD PTR %p0@GOTPCREL[rip]]}"; ++ else ++ xasm =3D "%!call\t{*%p0@GOTPCREL(%%rip)|[QWORD PTR %p0@GOTPCREL[rip]]}"; ++ } + else +- xasm =3D "%!call\t{*%p0@GOT|[DWORD PTR %p0@GOT]}"; ++ { ++ if (output_indirect_p) ++ xasm =3D "{%p0@GOT|[DWORD PTR %p0@GOT]}"; ++ else ++ xasm =3D "%!call\t{*%p0@GOT|[DWORD PTR %p0@GOT]}"; ++ } + } + else + xasm =3D "%!call\t%P0"; + } + else +- xasm =3D "%!call\t%A0"; ++ { ++ if (output_indirect_p) ++ xasm =3D "%0"; ++ else ++ xasm =3D "%!call\t%A0"; ++ } +=20 +- 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); +=20 + if (seh_nop_p) + return "nop"; +@@ -41444,7 +42043,7 @@ ix86_handle_struct_attribute (tree *node, tree nam= e, tree, int, + } +=20 + 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) !=3D FUNCTION_DECL) +@@ -41453,6 +42052,29 @@ ix86_handle_fndecl_attribute (tree *node, tree na= me, tree, int, + name); + *no_add_attrs =3D true; + } ++ ++ if (is_attribute_p ("indirect_branch", name)) ++ { ++ tree cst =3D TREE_VALUE (args); ++ if (TREE_CODE (cst) !=3D STRING_CST) ++ { ++ warning (OPT_Wattributes, ++ "%qE attribute requires a string constant argument", ++ name); ++ *no_add_attrs =3D true; ++ } ++ else if (strcmp (TREE_STRING_POINTER (cst), "keep") !=3D 0 ++ && strcmp (TREE_STRING_POINTER (cst), "thunk") !=3D 0 ++ && strcmp (TREE_STRING_POINTER (cst), "thunk-inline") !=3D 0 ++ && strcmp (TREE_STRING_POINTER (cst), "thunk-extern") !=3D 0) ++ { ++ warning (OPT_Wattributes, ++ "argument to %qE attribute is not " ++ "(keep|thunk|thunk-inline|thunk-extern)", name); ++ *no_add_attrs =3D true; ++ } ++ } ++ + return NULL_TREE; + } +=20 +@@ -45761,6 +46383,8 @@ static const struct attribute_spec ix86_attribute_= table[] =3D + 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 }, +=20 + /* 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 f9b91286a01..9d2209e605b 100644 +--- a/gcc/config/i386/i386.h ++++ b/gcc/config/i386/i386.h +@@ -2609,6 +2609,13 @@ struct GTY(()) machine_function { + /* Function type. */ + ENUM_BITFIELD(function_type) func_type : 2; +=20 ++ /* 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; ++ + /* 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 dbe88f40c8f..cd2e73cf9d3 100644 +--- a/gcc/config/i386/i386.md ++++ b/gcc/config/i386/i386.md +@@ -11627,13 +11627,18 @@ + { + if (TARGET_X32) + operands[0] =3D convert_memory_address (word_mode, operands[0]); ++ cfun->machine->has_local_indirect_jump =3D true; + }) +=20 + (define_insn "*indirect_jump" + [(set (pc) (match_operand:W 0 "indirect_branch_operand" "rBw"))] + "" +- "%!jmp\t%A0" +- [(set_attr "type" "ibr") ++ "* return ix86_output_indirect_jmp (operands[0], false);" ++ [(set (attr "type") ++ (if_then_else (match_test "(cfun->machine->indirect_branch_type ++ !=3D indirect_branch_keep)") ++ (const_string "multi") ++ (const_string "ibr"))) + (set_attr "length_immediate" "0") + (set_attr "maybe_prefix_bnd" "1")]) +=20 +@@ -11676,14 +11681,19 @@ +=20 + if (TARGET_X32) + operands[0] =3D convert_memory_address (word_mode, operands[0]); ++ cfun->machine->has_local_indirect_jump =3D true; + }) +=20 + (define_insn "*tablejump_1" + [(set (pc) (match_operand:W 0 "indirect_branch_operand" "rBw")) + (use (label_ref (match_operand 1)))] + "" +- "%!jmp\t%A0" +- [(set_attr "type" "ibr") ++ "* return ix86_output_indirect_jmp (operands[0], false);" ++ [(set (attr "type") ++ (if_then_else (match_test "(cfun->machine->indirect_branch_type ++ !=3D indirect_branch_keep)") ++ (const_string "multi") ++ (const_string "ibr"))) + (set_attr "length_immediate" "0") + (set_attr "maybe_prefix_bnd" "1")]) + +@@ -12354,8 +12364,12 @@ + [(simple_return) + (use (match_operand:SI 0 "register_operand" "r"))] + "reload_completed" +- "%!jmp\t%A0" +- [(set_attr "type" "ibr") ++ "* return ix86_output_indirect_jmp (operands[0], true);" ++ [(set (attr "type") ++ (if_then_else (match_test "(cfun->machine->indirect_branch_type ++ !=3D indirect_branch_keep)") ++ (const_string "multi") ++ (const_string "ibr"))) + (set_attr "length_immediate" "0") + (set_attr "maybe_prefix_bnd" "1")]) +=20 +diff --git a/gcc/config/i386/i386.opt b/gcc/config/i386/i386.opt +index 9384e29b1de..c076d9c70ab 100644 +--- a/gcc/config/i386/i386.opt ++++ b/gcc/config/i386/i386.opt +@@ -927,3 +927,23 @@ Attempt to avoid generating instruction sequences con= taining ret bytes. + mgeneral-regs-only + Target Report RejectNegative Mask(GENERAL_REGS_ONLY) Var(ix86_target_flag= s) Save + Generate code which uses only the general registers. ++ ++mindirect-branch=3D ++Target Report RejectNegative Joined Enum(indirect_branch) Var(ix86_indire= ct_branch) Init(indirect_branch_keep) ++Convert indirect call and jump to call and return thunks. ++ ++Enum ++Name(indirect_branch) Type(enum indirect_branch) ++Known indirect branch choices (for use with the -mindirect-branch=3D opti= on): ++ ++EnumValue ++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_in= line) ++ ++EnumValue ++Enum(indirect_branch) String(thunk-extern) Value(indirect_branch_thunk_ex= tern) +diff --git a/gcc/doc/extend.texi b/gcc/doc/extend.texi +index ba309d01a9b..935381da6fa 100644 +--- a/gcc/doc/extend.texi ++++ b/gcc/doc/extend.texi +@@ -5540,6 +5540,16 @@ Specify which floating-point unit to use. You must= specify the + @code{target("fpmath=3Dsse,387")} option as + @code{target("fpmath=3Dsse+387")} because the comma would separate + different options. ++ ++@item indirect_branch("@var{choice}") ++@cindex @code{indirect_branch} function attribute, x86 ++On x86 targets, the @code{indirect_branch} attribute causes the compiler ++to convert indirect call and jump with @var{choice}. @samp{keep} ++keeps indirect call and jump unmodified. @samp{thunk} converts indirect ++call and jump to call and return thunk. @samp{thunk-inline} converts ++indirect call and jump to inlined call and return thunk. ++@samp{thunk-extern} converts indirect call and jump to external call ++and return thunk provided in a separate object file. + @end table +=20 + On the x86, the inliner does not inline a +diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi +index 7311c10a754..4979c8c939d 100644 +--- a/gcc/doc/invoke.texi ++++ b/gcc/doc/invoke.texi +@@ -1210,7 +1210,8 @@ 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=3D@var{type} -mstack-protector-guard=3D@var{guard} @gol +--mmitigate-rop -mgeneral-regs-only} ++-mmitigate-rop -mgeneral-regs-only @gol ++-mindirect-branch=3D@var{choice}} +=20 + @emph{x86 Windows Options} + @gccoptlist{-mconsole -mcygwin -mno-cygwin -mdll @gol +@@ -25686,6 +25687,17 @@ Generate code that uses only the general-purpose = registers. This + prevents the compiler from using floating-point, vector, mask and bound + registers. +=20 ++@item -mindirect-branch=3D@var{choice} ++@opindex -mindirect-branch ++Convert 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 call and return thunk. ++@samp{thunk-inline} converts indirect call and jump to inlined call ++and return thunk. @samp{thunk-extern} converts indirect call and jump ++to external call and return thunk provided in a separate object file. ++You can control this behavior for a specific function by using the ++function attribute @code{indirect_branch}. @xref{Function Attributes}. ++ + @end table +=20 + 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/testsu= ite/gcc.target/i386/indirect-thunk-1.c +new file mode 100644 +index 00000000000..d983e1c3e26 +--- /dev/null ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-1.c +@@ -0,0 +1,20 @@ ++/* { dg-do compile } */ ++/* { dg-options "-O2 -mindirect-branch=3Dthunk -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} } } */ ++/* { dg-final { scan-assembler {\tlfence} } } */ +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-2.c b/gcc/testsu= ite/gcc.target/i386/indirect-thunk-2.c +new file mode 100644 +index 00000000000..58f09b42d8a +--- /dev/null ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-2.c +@@ -0,0 +1,20 @@ ++/* { dg-do compile } */ ++/* { dg-options "-O2 -mindirect-branch=3Dthunk -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 {\tpause} } } */ ++/* { dg-final { scan-assembler {\tlfence} } } */ +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-3.c b/gcc/testsu= ite/gcc.target/i386/indirect-thunk-3.c +new file mode 100644 +index 00000000000..f20d35c19b6 +--- /dev/null ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-3.c +@@ -0,0 +1,21 @@ ++/* { dg-do compile } */ ++/* { dg-options "-O2 -mindirect-branch=3Dthunk -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 "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 {\tpause} } } */ ++/* { dg-final { scan-assembler {\tlfence} } } */ +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-4.c b/gcc/testsu= ite/gcc.target/i386/indirect-thunk-4.c +new file mode 100644 +index 00000000000..0eff8fb658a +--- /dev/null ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-4.c +@@ -0,0 +1,21 @@ ++/* { dg-do compile } */ ++/* { dg-options "-O2 -mindirect-branch=3Dthunk -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 "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 {\tpause} } } */ ++/* { dg-final { scan-assembler {\tlfence} } } */ +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-5.c b/gcc/testsu= ite/gcc.target/i386/indirect-thunk-5.c +new file mode 100644 +index 00000000000..a25b20dd808 +--- /dev/null ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-5.c +@@ -0,0 +1,17 @@ ++/* { dg-do compile { target *-*-linux* } } */ ++/* { dg-options "-O2 -fpic -fno-plt -mindirect-branch=3Dthunk" } */ ++ ++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 {\tpause} } } */ ++/* { dg-final { scan-assembler {\tlfence} } } */ +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-6.c b/gcc/testsu= ite/gcc.target/i386/indirect-thunk-6.c +new file mode 100644 +index 00000000000..cff114a6c29 +--- /dev/null ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-6.c +@@ -0,0 +1,18 @@ ++/* { dg-do compile { target *-*-linux* } } */ ++/* { dg-options "-O2 -fpic -fno-plt -mindirect-branch=3Dthunk" } */ ++ ++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 {\tpause} } } */ ++/* { dg-final { scan-assembler {\tlfence} } } */ +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-7.c b/gcc/testsu= ite/gcc.target/i386/indirect-thunk-7.c +new file mode 100644 +index 00000000000..afdb6007986 +--- /dev/null ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-7.c +@@ -0,0 +1,44 @@ ++/* { dg-do compile } */ ++/* { dg-options "-O2 -mindirect-branch=3Dthunk -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\]+\\(,%" { ta= rget { ! 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} } } */ ++/* { dg-final { scan-assembler {\tlfence} } } */ +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-1.c b/gcc/t= estsuite/gcc.target/i386/indirect-thunk-attr-1.c +new file mode 100644 +index 00000000000..d64d978b699 +--- /dev/null ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-1.c +@@ -0,0 +1,23 @@ ++/* { 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 "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} } } */ ++/* { dg-final { scan-assembler {\tlfence} } } */ +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-2.c b/gcc/t= estsuite/gcc.target/i386/indirect-thunk-attr-2.c +new file mode 100644 +index 00000000000..93067454d3d +--- /dev/null ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-2.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"))) ++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 {\tpause} } } */ ++/* { dg-final { scan-assembler {\tlfence} } } */ +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-3.c b/gcc/t= estsuite/gcc.target/i386/indirect-thunk-attr-3.c +new file mode 100644 +index 00000000000..97744d65729 +--- /dev/null ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-3.c +@@ -0,0 +1,23 @@ ++/* { 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-times "jmp\[ \t\]*\.LIND" 2 } } */ ++/* { dg-final { scan-assembler-times "call\[ \t\]*\.LIND" 2 } } */ ++/* { dg-final { scan-assembler {\tpause} } } */ ++/* { dg-final { scan-assembler {\tlfence} } } */ ++/* { 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/t= estsuite/gcc.target/i386/indirect-thunk-attr-4.c +new file mode 100644 +index 00000000000..bfce3ea5cb2 +--- /dev/null ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-4.c +@@ -0,0 +1,22 @@ ++/* { 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-times "jmp\[ \t\]*\.LIND" 2 } } */ ++/* { dg-final { scan-assembler-times "call\[ \t\]*\.LIND" 2 } } */ ++/* { dg-final { scan-assembler {\tpause} } } */ ++/* { dg-final { scan-assembler {\tlfence} } } */ ++/* { 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/t= estsuite/gcc.target/i386/indirect-thunk-attr-5.c +new file mode 100644 +index 00000000000..0833606046b +--- /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-times "jmp\[ \t\]*\.LIND" 1 { target { ! x= 32 } } } } */ ++/* { 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/t= estsuite/gcc.target/i386/indirect-thunk-attr-6.c +new file mode 100644 +index 00000000000..2eba0fbd9b2 +--- /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-times "jmp\[ \t\]*\.LIND" 1 { target { ! x= 32 } } } } */ ++/* { 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/t= estsuite/gcc.target/i386/indirect-thunk-attr-7.c +new file mode 100644 +index 00000000000..f58427eae11 +--- /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\]+\\(,%" { ta= rget { ! 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" } } */ ++/* { dg-final { scan-assembler-not "call\[ \t\]*\.LIND" } } */ +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-8.c b/gcc/t= estsuite/gcc.target/i386/indirect-thunk-attr-8.c +new file mode 100644 +index 00000000000..564ed39547c +--- /dev/null ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-8.c +@@ -0,0 +1,42 @@ ++/* { dg-do compile } */ ++/* { dg-options "-O2 -mindirect-branch=3Dthunk -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 {\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-bnd-1.c b/gcc/te= stsuite/gcc.target/i386/indirect-thunk-bnd-1.c +new file mode 100644 +index 00000000000..50fbee20a5a +--- /dev/null ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-1.c +@@ -0,0 +1,20 @@ ++/* { dg-do compile { target { ! x32 } } } */ ++/* { dg-options "-O2 -mindirect-branch=3Dthunk -fcheck-pointer-bounds -mm= px -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 {\tpause} } } */ ++/* { dg-final { scan-assembler {\tlfence} } } */ +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-2.c b/gcc/te= stsuite/gcc.target/i386/indirect-thunk-bnd-2.c +new file mode 100644 +index 00000000000..2976e67adce +--- /dev/null ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-2.c +@@ -0,0 +1,21 @@ ++/* { dg-do compile { target { ! x32 } } } */ ++/* { dg-options "-O2 -mindirect-branch=3Dthunk -fcheck-pointer-bounds -mm= px -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 {\tpause} } } */ ++/* { dg-final { scan-assembler {\tlfence} } } */ +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-3.c b/gcc/te= stsuite/gcc.target/i386/indirect-thunk-bnd-3.c +new file mode 100644 +index 00000000000..da4bc98ef23 +--- /dev/null ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-3.c +@@ -0,0 +1,19 @@ ++/* { dg-do compile { target { *-*-linux* && { ! x32 } } } } */ ++/* { dg-options "-O2 -mindirect-branch=3Dthunk -fcheck-pointer-bounds -mm= px -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 {\tpause} } } */ ++/* { dg-final { scan-assembler {\tlfence} } } */ +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-4.c b/gcc/te= stsuite/gcc.target/i386/indirect-thunk-bnd-4.c +new file mode 100644 +index 00000000000..c64d12ef989 +--- /dev/null ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-4.c +@@ -0,0 +1,20 @@ ++/* { dg-do compile { target { *-*-linux* && { ! x32 } } } } */ ++/* { dg-options "-O2 -mindirect-branch=3Dthunk -fcheck-pointer-bounds -mm= px -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 {\tpause} } } */ ++/* { dg-final { scan-assembler {\tlfence} } } */ +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..49f27b49465 +--- /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=3Dthunk-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 "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 +new file mode 100644 +index 00000000000..a1e3eb6fc74 +--- /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=3Dthunk-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 "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 +new file mode 100644 +index 00000000000..395634e7e5c +--- /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=3Dthunk-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 "jmp\[ \t\]*__x86_indirect_thunk" { target= { ! x32 } } } } */ ++/* { dg-final { scan-assembler-times "jmp\[ \t\]*\.LIND" 1 { target { ! x= 32 } } } } */ ++/* { 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 +new file mode 100644 +index 00000000000..fd3f63379a1 +--- /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=3Dthunk-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 "jmp\[ \t\]*__x86_indirect_thunk" { target= { ! x32 } } } } */ ++/* { dg-final { scan-assembler-times "jmp\[ \t\]*\.LIND" 1 { target { ! x= 32 } } } } */ ++/* { 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-5.c b/gcc= /testsuite/gcc.target/i386/indirect-thunk-extern-5.c +new file mode 100644 +index 00000000000..ba2f92b6f34 +--- /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=3Dthunk-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..0c5a2d472c6 +--- /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=3Dthunk-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..665252327aa +--- /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=3Dthunk-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\]+\\(,%" { ta= rget { ! 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 +new file mode 100644 +index 00000000000..68c0ff713b3 +--- /dev/null ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-1.c +@@ -0,0 +1,20 @@ ++/* { dg-do compile } */ ++/* { dg-options "-O2 -mindirect-branch=3Dthunk-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 "jmp\[ \t\]*\.LIND" } } */ ++/* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */ ++/* { dg-final { scan-assembler {\tpause} } } */ ++/* { dg-final { scan-assembler {\tlfence} } } */ ++/* { 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 +new file mode 100644 +index 00000000000..e2da1fcb683 +--- /dev/null ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-2.c +@@ -0,0 +1,20 @@ ++/* { dg-do compile } */ ++/* { dg-options "-O2 -mindirect-branch=3Dthunk-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 "jmp\[ \t\]*\.LIND" } } */ ++/* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */ ++/* { dg-final { scan-assembler {\tpause} } } */ ++/* { dg-final { scan-assembler {\tlfence} } } */ ++/* { 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 +new file mode 100644 +index 00000000000..244fec708d6 +--- /dev/null ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-3.c +@@ -0,0 +1,21 @@ ++/* { dg-do compile } */ ++/* { dg-options "-O2 -mindirect-branch=3Dthunk-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-times "jmp\[ \t\]*\.LIND" 2 } } */ ++/* { dg-final { scan-assembler-times "call\[ \t\]*\.LIND" 2 } } */ ++/* { dg-final { scan-assembler-times {\tpause} 1 } } */ ++/* { dg-final { scan-assembler-times {\tlfence} 1 } } */ ++/* { 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 +new file mode 100644 +index 00000000000..107ebe32f54 +--- /dev/null ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-4.c +@@ -0,0 +1,21 @@ ++/* { dg-do compile } */ ++/* { dg-options "-O2 -mindirect-branch=3Dthunk-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-times "jmp\[ \t\]*\.LIND" 2 } } */ ++/* { dg-final { scan-assembler-times "call\[ \t\]*\.LIND" 2 } } */ ++/* { dg-final { scan-assembler-times {\tpause} 1 } } */ ++/* { dg-final { scan-assembler-times {\tlfence} 1 } } */ ++/* { 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 +new file mode 100644 +index 00000000000..17b04ef2229 +--- /dev/null ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-5.c +@@ -0,0 +1,17 @@ ++/* { dg-do compile { target *-*-linux* } } */ ++/* { dg-options "-O2 -fpic -fno-plt -mindirect-branch=3Dthunk-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 {\tpause} } } */ ++/* { dg-final { scan-assembler {\tlfence} } } */ ++/* { 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..d9eb11285aa +--- /dev/null ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-6.c +@@ -0,0 +1,18 @@ ++/* { dg-do compile { target *-*-linux* } } */ ++/* { dg-options "-O2 -fpic -fno-plt -mindirect-branch=3Dthunk-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-times {\tpause} 1 } } */ ++/* { dg-final { scan-assembler-times {\tlfence} 1 } } */ ++/* { 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..d02b1dcb1b9 +--- /dev/null ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-7.c +@@ -0,0 +1,44 @@ ++/* { dg-do compile } */ ++/* { dg-options "-O2 -mindirect-branch=3Dthunk-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\]+\\(,%" { ta= rget { ! 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 {\tpause} } } */ ++/* { dg-final { scan-assembler {\tlfence} } } */ ++/* { dg-final { scan-assembler-not "__x86_indirect_thunk" } } */ +--=20 +2.15.1 + diff --git a/gnu/packages/patches/gcc-retpoline-x86-Disallow-mindirect-bran= ch-mfunction-return-with-.patch b/gnu/packages/patches/gcc-retpoline-x86-Di= sallow-mindirect-branch-mfunction-return-with-.patch new file mode 100644 index 000000000..1dae0b493 --- /dev/null +++ b/gnu/packages/patches/gcc-retpoline-x86-Disallow-mindirect-branch-mfun= ction-return-with-.patch @@ -0,0 +1,308 @@ +'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=3DCVE-2017-5715 + +Patch copied from the 'retpoline-regnames' branch of upstream source repos= itory +(please keep an eye for new branches or updates for existing branches): + +http://git.infradead.org/users/dwmw2/gcc-retpoline.git + +From 13dce7cceef28026c4fc2e505d724526141fe4c1 Mon Sep 17 00:00:00 2001 +From: "H.J. Lu" +Date: Sat, 13 Jan 2018 18:01:54 -0800 +Subject: [PATCH 08/10] x86: Disallow -mindirect-branch=3D/-mfunction-retur= n=3D + with -mcmodel=3Dlarge + +Since the thunk function may not be reachable in large code model, +-mcmodel=3Dlarge is incompatible with -mindirect-branch=3Dthunk, +-mindirect-branch=3Dthunk-extern, -mfunction-return=3Dthunk and +-mfunction-return=3Dthunk-extern. Issue an error when they are used with +-mcmodel=3Dlarge. + +gcc/ + + Backport from mainline + * config/i386/i386.c (ix86_set_indirect_branch_type): Disallow + -mcmodel=3Dlarge with -mindirect-branch=3Dthunk, + -mindirect-branch=3Dthunk-extern, -mfunction-return=3Dthunk and + -mfunction-return=3Dthunk-extern. + * doc/invoke.texi: Document -mcmodel=3Dlarge is incompatible with + -mindirect-branch=3Dthunk, -mindirect-branch=3Dthunk-extern, + -mfunction-return=3Dthunk and -mfunction-return=3Dthunk-extern. + +gcc/testsuite/ + + Backport from mainline + * gcc.target/i386/indirect-thunk-10.c: New test. + * gcc.target/i386/indirect-thunk-8.c: Likewise. + * gcc.target/i386/indirect-thunk-9.c: Likewise. + * gcc.target/i386/indirect-thunk-attr-10.c: Likewise. + * gcc.target/i386/indirect-thunk-attr-11.c: Likewise. + * gcc.target/i386/indirect-thunk-attr-9.c: Likewise. + * gcc.target/i386/ret-thunk-17.c: Likewise. + * gcc.target/i386/ret-thunk-18.c: Likewise. + * gcc.target/i386/ret-thunk-19.c: Likewise. + * gcc.target/i386/ret-thunk-20.c: Likewise. + * gcc.target/i386/ret-thunk-21.c: Likewise. +--- + gcc/config/i386/i386.c | 26 +++++++++++++++++= +++++ + gcc/doc/invoke.texi | 11 +++++++++ + gcc/testsuite/gcc.target/i386/indirect-thunk-10.c | 7 ++++++ + gcc/testsuite/gcc.target/i386/indirect-thunk-8.c | 7 ++++++ + gcc/testsuite/gcc.target/i386/indirect-thunk-9.c | 7 ++++++ + .../gcc.target/i386/indirect-thunk-attr-10.c | 9 ++++++++ + .../gcc.target/i386/indirect-thunk-attr-11.c | 9 ++++++++ + .../gcc.target/i386/indirect-thunk-attr-9.c | 9 ++++++++ + gcc/testsuite/gcc.target/i386/ret-thunk-17.c | 7 ++++++ + gcc/testsuite/gcc.target/i386/ret-thunk-18.c | 8 +++++++ + gcc/testsuite/gcc.target/i386/ret-thunk-19.c | 8 +++++++ + gcc/testsuite/gcc.target/i386/ret-thunk-20.c | 9 ++++++++ + gcc/testsuite/gcc.target/i386/ret-thunk-21.c | 9 ++++++++ + 13 files changed, 126 insertions(+) + create mode 100644 gcc/testsuite/gcc.target/i386/indirect-thunk-10.c + create mode 100644 gcc/testsuite/gcc.target/i386/indirect-thunk-8.c + create mode 100644 gcc/testsuite/gcc.target/i386/indirect-thunk-9.c + create mode 100644 gcc/testsuite/gcc.target/i386/indirect-thunk-attr-10.c + create mode 100644 gcc/testsuite/gcc.target/i386/indirect-thunk-attr-11.c + create mode 100644 gcc/testsuite/gcc.target/i386/indirect-thunk-attr-9.c + create mode 100644 gcc/testsuite/gcc.target/i386/ret-thunk-17.c + create mode 100644 gcc/testsuite/gcc.target/i386/ret-thunk-18.c + create mode 100644 gcc/testsuite/gcc.target/i386/ret-thunk-19.c + create mode 100644 gcc/testsuite/gcc.target/i386/ret-thunk-20.c + create mode 100644 gcc/testsuite/gcc.target/i386/ret-thunk-21.c + +diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c +index e32de13688a..318a71840c9 100644 +--- a/gcc/config/i386/i386.c ++++ b/gcc/config/i386/i386.c +@@ -7187,6 +7187,19 @@ ix86_set_indirect_branch_type (tree fndecl) + } + else + cfun->machine->indirect_branch_type =3D ix86_indirect_branch; ++ ++ /* -mcmodel=3Dlarge is not compatible with -mindirect-branch=3Dthunk ++ nor -mindirect-branch=3Dthunk-extern. */ ++ if ((ix86_cmodel =3D=3D CM_LARGE || ix86_cmodel =3D=3D CM_LARGE_PIC) ++ && ((cfun->machine->indirect_branch_type ++ =3D=3D indirect_branch_thunk_extern) ++ || (cfun->machine->indirect_branch_type ++ =3D=3D indirect_branch_thunk))) ++ error ("%<-mindirect-branch=3D%s%> and %<-mcmodel=3Dlarge%> are not " ++ "compatible", ++ ((cfun->machine->indirect_branch_type ++ =3D=3D indirect_branch_thunk_extern) ++ ? "thunk-extern" : "thunk")); + } +=20 + if (cfun->machine->function_return_type =3D=3D indirect_branch_unset) +@@ -7212,6 +7225,19 @@ ix86_set_indirect_branch_type (tree fndecl) + } + else + cfun->machine->function_return_type =3D ix86_function_return; ++ ++ /* -mcmodel=3Dlarge is not compatible with -mfunction-return=3Dthunk ++ nor -mfunction-return=3Dthunk-extern. */ ++ if ((ix86_cmodel =3D=3D CM_LARGE || ix86_cmodel =3D=3D CM_LARGE_PIC) ++ && ((cfun->machine->function_return_type ++ =3D=3D indirect_branch_thunk_extern) ++ || (cfun->machine->function_return_type ++ =3D=3D indirect_branch_thunk))) ++ error ("%<-mfunction-return=3D%s%> and %<-mcmodel=3Dlarge%> are not " ++ "compatible", ++ ((cfun->machine->function_return_type ++ =3D=3D indirect_branch_thunk_extern) ++ ? "thunk-extern" : "thunk")); + } + } +=20 +diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi +index 1e572b1f9a2..6f3c344476c 100644 +--- a/gcc/doc/invoke.texi ++++ b/gcc/doc/invoke.texi +@@ -25699,6 +25699,11 @@ to external call and return thunk provided in a s= eparate object file. + You can control this behavior for a specific function by using the + function attribute @code{indirect_branch}. @xref{Function Attributes}. +=20 ++Note that @option{-mcmodel=3Dlarge} is incompatible with ++@option{-mindirect-branch=3Dthunk} nor ++@option{-mindirect-branch=3Dthunk-extern} since the thunk function may ++not be reachable in large code model. ++ + @item -mfunction-return=3D@var{choice} + @opindex -mfunction-return + Convert function return with @var{choice}. The default is @samp{keep}, +@@ -25710,6 +25715,12 @@ object file. You can control this behavior for a= specific function by + using the function attribute @code{function_return}. + @xref{Function Attributes}. +=20 ++Note that @option{-mcmodel=3Dlarge} is incompatible with ++@option{-mfunction-return=3Dthunk} nor ++@option{-mfunction-return=3Dthunk-extern} since the thunk function may ++not be reachable in large code model. ++ ++ + @item -mindirect-branch-register + @opindex -mindirect-branch-register + Force indirect call and jump via register. +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-10.c b/gcc/tests= uite/gcc.target/i386/indirect-thunk-10.c +new file mode 100644 +index 00000000000..a0674bd2363 +--- /dev/null ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-10.c +@@ -0,0 +1,7 @@ ++/* { dg-do compile { target { lp64 } } } */ ++/* { dg-options "-O2 -mindirect-branch=3Dthunk-inline -mfunction-return= =3Dkeep -mcmodel=3Dlarge" } */ ++ ++void ++bar (void) ++{ ++} +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-8.c b/gcc/testsu= ite/gcc.target/i386/indirect-thunk-8.c +new file mode 100644 +index 00000000000..7a80a8986e8 +--- /dev/null ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-8.c +@@ -0,0 +1,7 @@ ++/* { dg-do compile { target { lp64 } } } */ ++/* { dg-options "-O2 -mindirect-branch=3Dthunk -mfunction-return=3Dkeep -= mcmodel=3Dlarge" } */ ++ ++void ++bar (void) ++{ /* { dg-error "'-mindirect-branch=3Dthunk' and '-mcmodel=3Dlarge' are n= ot compatible" } */ ++} +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-9.c b/gcc/testsu= ite/gcc.target/i386/indirect-thunk-9.c +new file mode 100644 +index 00000000000..d4d45c5114d +--- /dev/null ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-9.c +@@ -0,0 +1,7 @@ ++/* { dg-do compile { target { lp64 } } } */ ++/* { dg-options "-O2 -mindirect-branch=3Dthunk-extern -mfunction-return= =3Dkeep -mcmodel=3Dlarge" } */ ++ ++void ++bar (void) ++{ /* { dg-error "'-mindirect-branch=3Dthunk-extern' and '-mcmodel=3Dlarge= ' are not compatible" } */ ++} +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-10.c b/gcc/= testsuite/gcc.target/i386/indirect-thunk-attr-10.c +new file mode 100644 +index 00000000000..3a2aeaddbc5 +--- /dev/null ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-10.c +@@ -0,0 +1,9 @@ ++/* { dg-do compile { target { lp64 } } } */ ++/* { dg-options "-O2 -mindirect-branch=3Dkeep -mfunction-return=3Dkeep -m= cmodel=3Dlarge" } */ ++/* { dg-additional-options "-fPIC" { target fpic } } */ ++ ++__attribute__ ((indirect_branch("thunk-extern"))) ++void ++bar (void) ++{ /* { dg-error "'-mindirect-branch=3Dthunk-extern' and '-mcmodel=3Dlarge= ' are not compatible" } */ ++} +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-11.c b/gcc/= testsuite/gcc.target/i386/indirect-thunk-attr-11.c +new file mode 100644 +index 00000000000..8e52f032b6c +--- /dev/null ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-11.c +@@ -0,0 +1,9 @@ ++/* { dg-do compile { target { lp64 } } } */ ++/* { dg-options "-O2 -mindirect-branch=3Dkeep -mfunction-return=3Dkeep -m= cmodel=3Dlarge" } */ ++/* { dg-additional-options "-fPIC" { target fpic } } */ ++ ++__attribute__ ((indirect_branch("thunk-inline"))) ++void ++bar (void) ++{ ++} +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-9.c b/gcc/t= estsuite/gcc.target/i386/indirect-thunk-attr-9.c +new file mode 100644 +index 00000000000..bdaa4f6911b +--- /dev/null ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-9.c +@@ -0,0 +1,9 @@ ++/* { dg-do compile { target { lp64 } } } */ ++/* { dg-options "-O2 -mindirect-branch=3Dkeep -mfunction-return=3Dkeep -m= cmodel=3Dlarge" } */ ++/* { dg-additional-options "-fPIC" { target fpic } } */ ++ ++__attribute__ ((indirect_branch("thunk"))) ++void ++bar (void) ++{ /* { dg-error "'-mindirect-branch=3Dthunk' and '-mcmodel=3Dlarge' are n= ot compatible" } */ ++} +diff --git a/gcc/testsuite/gcc.target/i386/ret-thunk-17.c b/gcc/testsuite/= gcc.target/i386/ret-thunk-17.c +new file mode 100644 +index 00000000000..0605e2c6542 +--- /dev/null ++++ b/gcc/testsuite/gcc.target/i386/ret-thunk-17.c +@@ -0,0 +1,7 @@ ++/* { dg-do compile { target { lp64 } } } */ ++/* { dg-options "-O2 -mfunction-return=3Dthunk -mindirect-branch=3Dkeep -= mcmodel=3Dlarge" } */ ++ ++void ++bar (void) ++{ /* { dg-error "'-mfunction-return=3Dthunk' and '-mcmodel=3Dlarge' are n= ot compatible" } */ ++} +diff --git a/gcc/testsuite/gcc.target/i386/ret-thunk-18.c b/gcc/testsuite/= gcc.target/i386/ret-thunk-18.c +new file mode 100644 +index 00000000000..307019dc242 +--- /dev/null ++++ b/gcc/testsuite/gcc.target/i386/ret-thunk-18.c +@@ -0,0 +1,8 @@ ++/* { dg-do compile { target { lp64 } } } */ ++/* { dg-options "-O2 -mfunction-return=3Dthunk-extern -mindirect-branch= =3Dkeep -mcmodel=3Dlarge" } */ ++/* { dg-additional-options "-fPIC" { target fpic } } */ ++ ++void ++bar (void) ++{ /* { dg-error "'-mfunction-return=3Dthunk-extern' and '-mcmodel=3Dlarge= ' are not compatible" } */ ++} +diff --git a/gcc/testsuite/gcc.target/i386/ret-thunk-19.c b/gcc/testsuite/= gcc.target/i386/ret-thunk-19.c +new file mode 100644 +index 00000000000..772617f4010 +--- /dev/null ++++ b/gcc/testsuite/gcc.target/i386/ret-thunk-19.c +@@ -0,0 +1,8 @@ ++/* { dg-do compile { target { lp64 } } } */ ++/* { dg-options "-O2 -mfunction-return=3Dkeep -mindirect-branch=3Dkeep -m= cmodel=3Dlarge" } */ ++ ++__attribute__ ((function_return("thunk"))) ++void ++bar (void) ++{ /* { dg-error "'-mfunction-return=3Dthunk' and '-mcmodel=3Dlarge' are n= ot compatible" } */ ++} +diff --git a/gcc/testsuite/gcc.target/i386/ret-thunk-20.c b/gcc/testsuite/= gcc.target/i386/ret-thunk-20.c +new file mode 100644 +index 00000000000..1e9f9bd5a66 +--- /dev/null ++++ b/gcc/testsuite/gcc.target/i386/ret-thunk-20.c +@@ -0,0 +1,9 @@ ++/* { dg-do compile { target { lp64 } } } */ ++/* { dg-options "-O2 -mfunction-return=3Dkeep -mindirect-branch=3Dkeep -m= cmodel=3Dlarge" } */ ++/* { dg-additional-options "-fPIC" { target fpic } } */ ++ ++__attribute__ ((function_return("thunk-extern"))) ++void ++bar (void) ++{ /* { dg-error "'-mfunction-return=3Dthunk-extern' and '-mcmodel=3Dlarge= ' are not compatible" } */ ++} +diff --git a/gcc/testsuite/gcc.target/i386/ret-thunk-21.c b/gcc/testsuite/= gcc.target/i386/ret-thunk-21.c +new file mode 100644 +index 00000000000..eea07f7abe1 +--- /dev/null ++++ b/gcc/testsuite/gcc.target/i386/ret-thunk-21.c +@@ -0,0 +1,9 @@ ++/* { dg-do compile { target { lp64 } } } */ ++/* { dg-options "-O2 -mfunction-return=3Dkeep -mindirect-branch=3Dkeep -m= cmodel=3Dlarge" } */ ++/* { dg-additional-options "-fPIC" { target fpic } } */ ++ ++__attribute__ ((function_return("thunk-inline"))) ++void ++bar (void) ++{ ++} +--=20 +2.15.1 + --=20 2.15.1 --=-=-= Content-Type: text/plain Cheers, Alex --=-=-=-- From unknown Sun Jun 22 07:57:08 2025 X-Loop: help-debbugs@gnu.org Subject: [bug#30111] gnu: gcc@7: Apply the 'retpoline' mitigation technique. Resent-From: ludo@gnu.org (Ludovic =?UTF-8?Q?Court=C3=A8s?=) Original-Sender: "Debbugs-submit" Resent-CC: guix-patches@gnu.org Resent-Date: Tue, 16 Jan 2018 14:35:01 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 30111 X-GNU-PR-Package: guix-patches X-GNU-PR-Keywords: security patch To: Alex Vong Cc: 30111@debbugs.gnu.org Received: via spool by 30111-submit@debbugs.gnu.org id=B30111.15161132433749 (code B ref 30111); Tue, 16 Jan 2018 14:35:01 +0000 Received: (at 30111) by debbugs.gnu.org; 16 Jan 2018 14:34:03 +0000 Received: from localhost ([127.0.0.1]:58217 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1ebSJP-0000yP-AL for submit@debbugs.gnu.org; Tue, 16 Jan 2018 09:34:03 -0500 Received: from hera.aquilenet.fr ([185.233.100.1]:54298) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1ebSJL-0000xy-4G for 30111@debbugs.gnu.org; Tue, 16 Jan 2018 09:34:01 -0500 Received: from localhost (localhost [127.0.0.1]) by hera.aquilenet.fr (Postfix) with ESMTP id 9CDF410DA4; Tue, 16 Jan 2018 15:33:58 +0100 (CET) X-Virus-Scanned: Debian amavisd-new at aquilenet.fr Received: from hera.aquilenet.fr ([127.0.0.1]) by localhost (hera.aquilenet.fr [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id avDAZtBmLA3A; Tue, 16 Jan 2018 15:33:57 +0100 (CET) Received: from ribbon (unknown [193.50.110.60]) by hera.aquilenet.fr (Postfix) with ESMTPSA id C63F810D30; Tue, 16 Jan 2018 15:33:57 +0100 (CET) From: ludo@gnu.org (Ludovic =?UTF-8?Q?Court=C3=A8s?=) References: <877esksi62.fsf@gmail.com> <87d12bgpqh.fsf@gmail.com> <87a7xet06p.fsf@gmail.com> X-URL: http://www.fdn.fr/~lcourtes/ X-Revolutionary-Date: 27 =?UTF-8?Q?Niv=C3=B4se?= an 226 de la =?UTF-8?Q?R=C3=A9volution?= X-PGP-Key-ID: 0x090B11993D9AEBB5 X-PGP-Key: http://www.fdn.fr/~lcourtes/ludovic.asc X-PGP-Fingerprint: 3CE4 6455 8A84 FDC6 9DB4 0CFB 090B 1199 3D9A EBB5 X-OS: x86_64-pc-linux-gnu Date: Tue, 16 Jan 2018 15:33:57 +0100 In-Reply-To: <87a7xet06p.fsf@gmail.com> (Alex Vong's message of "Tue, 16 Jan 2018 21:14:54 +0800") Message-ID: <87a7xd6ffu.fsf@gnu.org> User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/25.3 (gnu/linux) MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: quoted-printable X-Spam-Score: 1.0 (+) X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: 1.0 (+) Hi Alex, Alex Vong skribis: > From aea3d11f59e260111bdb8bcac458c97a946fa900 Mon Sep 17 00:00:00 2001 > From: Alex Vong > Date: Tue, 16 Jan 2018 20:32:32 +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 . > > * gnu/local.mk (dist_patch_DATA): Add them. > * gnu/packages/gcc.scm (gcc@7): Use them. > * gnu/packages/patches/gcc-retpoline-Change-V-to-bare-reg-names.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_fram= e-to-avoid-cop.patch, > gnu/packages/patches/gcc-retpoline-indirect-thunk-reg-names.patch, > gnu/packages/patches/gcc-retpoline-x86-Add-V-register-operand-modifier.pa= tch, > gnu/packages/patches/gcc-retpoline-x86-Add-mfunction-return.patch, > gnu/packages/patches/gcc-retpoline-x86-Add-mindirect-branch-register.patc= h, > gnu/packages/patches/gcc-retpoline-x86-Add-mindirect-branch.patch, > gnu/packages/patches/gcc-retpoline-x86-Disallow-mindirect-branch-mfunctio= n-return-with-.patch: > New files. I=E2=80=99d suggest removing the test suite changes from the patches (curre= ntly we don=E2=80=99t run GCC=E2=80=99s test suite.) Also, =E2=80=98guix lint= =E2=80=99 may suggest using shorter file names. Do you know if a new 7.x including retpoline support is scheduled for release soon? Thanks, Ludo=E2=80=99. From unknown Sun Jun 22 07:57:08 2025 X-Loop: help-debbugs@gnu.org Subject: [bug#30111] gnu: gcc@7: Apply the 'retpoline' mitigation technique. Resent-From: Alex Vong Original-Sender: "Debbugs-submit" Resent-CC: guix-patches@gnu.org Resent-Date: Tue, 16 Jan 2018 15:25:01 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 30111 X-GNU-PR-Package: guix-patches X-GNU-PR-Keywords: security patch To: ludo@gnu.org (Ludovic =?UTF-8?Q?Court=C3=A8s?=) Cc: 30111@debbugs.gnu.org Received: via spool by 30111-submit@debbugs.gnu.org id=B30111.15161162989171 (code B ref 30111); Tue, 16 Jan 2018 15:25:01 +0000 Received: (at 30111) by debbugs.gnu.org; 16 Jan 2018 15:24:58 +0000 Received: from localhost ([127.0.0.1]:58873 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1ebT6e-0002No-63 for submit@debbugs.gnu.org; Tue, 16 Jan 2018 10:24:58 -0500 Received: from mail-pg0-f44.google.com ([74.125.83.44]:43631) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1ebT6a-0002NY-Fw for 30111@debbugs.gnu.org; Tue, 16 Jan 2018 10:24:54 -0500 Received: by mail-pg0-f44.google.com with SMTP id n17so2082252pgf.10 for <30111@debbugs.gnu.org>; Tue, 16 Jan 2018 07:24:52 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:references:date:in-reply-to:message-id :user-agent:mime-version:content-transfer-encoding; bh=5b6vnPJ0W2h8O+yK/TV56KKrXrnrHYmKlpTAZrWxTIY=; b=Z0mXk6vDNHSrrLPW6H4R6QV2kqcccVf/ClaMyGt9evfqyS1HoSqMH6cv2asiy14Up0 2rmPXRDlRyjHiwxb9fTk5YENZakp9JmDq6dK/tMRQ+AQL8vcY4dmxGxY870JCpKg/xmy yTjyZiinnyxXYXJrWefCBwBESFXpPaPYtaEf5AxFHWuii5NOKLlHO1kni0rFRY3Ny7Vw t6HgBtyu/uIFR7mCTkIfkRvUuJGWZnnrnW7yTKhPUDtrwO/dC2Pnpx/FIMhkZiTbF2Vy qukyXO5ROqBBoOWCFT+jT7m58nl26HBlf9EXogwFgl1b3UhlM0wyE4uzULTkHdechQQx ZBIA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:references:date:in-reply-to :message-id:user-agent:mime-version:content-transfer-encoding; bh=5b6vnPJ0W2h8O+yK/TV56KKrXrnrHYmKlpTAZrWxTIY=; b=g3A2YGc/1QPcsRT330AXqc2qQulO0lMJ/0g5MtFRpVQ+DuVY12pGGmofic9T2ZXYOO rDHNWpU+xe79D99JzVlBGF4YzowlY8kQkos6XYNFly5cjqNvmTOb1B1NSbOoi1p+A9Mf xi+Eczw9k7QoTfg96awBWBEn8qOWdDD7TvxbLE/9Wcm5DPMajNQc9fY7zxaOLr9yqpqa AUi1nZp3vFdLQhyN6j5Rs5bxJn2AFcJ5nBV2+znZvFN+I+pbNc4sX9SF18tJnpm1w4ff cSGETmw5wAfyz4JAoV3imHBoQ13uAwE4T1+KxNDg+qp6EsDn6Cg23I8FAX5GSsyy7PKh pzrQ== X-Gm-Message-State: AKGB3mIU/XyrFcHs8wX9U7M9aoHg7BmWsa5NQVFCh6iPUqTyE54BOdjx 6Jda8DgVgbB+EqZw1jOZkGU= X-Google-Smtp-Source: ACJfBov5wsbQc9EIK2Tn9mikLh29SAenSDe9K8rLYzF6mzueR4s1BZarEjwGor0YtSwZ2n928Qn1Hg== X-Received: by 10.99.189.81 with SMTP id d17mr30987233pgp.370.1516116286716; Tue, 16 Jan 2018 07:24:46 -0800 (PST) Received: from debian (n218250002129.netvigator.com. [218.250.2.129]) by smtp.gmail.com with ESMTPSA id l8sm3791326pgc.58.2018.01.16.07.24.45 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Tue, 16 Jan 2018 07:24:46 -0800 (PST) From: Alex Vong References: <877esksi62.fsf@gmail.com> <87d12bgpqh.fsf@gmail.com> <87a7xet06p.fsf@gmail.com> <87a7xd6ffu.fsf@gnu.org> Date: Tue, 16 Jan 2018 23:24:35 +0800 In-Reply-To: <87a7xd6ffu.fsf@gnu.org> ("Ludovic \=\?utf-8\?Q\?Court\=C3\=A8s\=22'\?\= \=\?utf-8\?Q\?s\?\= message of "Tue, 16 Jan 2018 15:33:57 +0100") Message-ID: <876081u8r0.fsf@gmail.com> User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/25.3 (gnu/linux) MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: quoted-printable X-Spam-Score: 0.3 (/) X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: 0.3 (/) ludo@gnu.org (Ludovic Court=C3=A8s) writes: > Hi Alex, > > Alex Vong skribis: > >> From aea3d11f59e260111bdb8bcac458c97a946fa900 Mon Sep 17 00:00:00 2001 >> From: Alex Vong >> Date: Tue, 16 Jan 2018 20:32:32 +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 . >> >> * gnu/local.mk (dist_patch_DATA): Add them. >> * gnu/packages/gcc.scm (gcc@7): Use them. >> * gnu/packages/patches/gcc-retpoline-Change-V-to-bare-reg-names.patch, >> gnu/packages/patches/gcc-retpoline-i386-More-use-reference-of-struct-ix8= 6_frame-to-avoi.patch, >> gnu/packages/patches/gcc-retpoline-i386-Move-struct-ix86_frame-to-machin= e_function.patch, >> gnu/packages/patches/gcc-retpoline-i386-Use-reference-of-struct-ix86_fra= me-to-avoid-cop.patch, >> gnu/packages/patches/gcc-retpoline-indirect-thunk-reg-names.patch, >> gnu/packages/patches/gcc-retpoline-x86-Add-V-register-operand-modifier.p= atch, >> gnu/packages/patches/gcc-retpoline-x86-Add-mfunction-return.patch, >> gnu/packages/patches/gcc-retpoline-x86-Add-mindirect-branch-register.pat= ch, >> gnu/packages/patches/gcc-retpoline-x86-Add-mindirect-branch.patch, >> gnu/packages/patches/gcc-retpoline-x86-Disallow-mindirect-branch-mfuncti= on-return-with-.patch: >> New files. > > I=E2=80=99d suggest removing the test suite changes from the patches (cur= rently > we don=E2=80=99t run GCC=E2=80=99s test suite.) Also, =E2=80=98guix lint= =E2=80=99 may suggest using > shorter file names. > OK, no problem. > Do you know if a new 7.x including retpoline support is scheduled for > release soon? > Yes, I think they will appear in 7.3 according to [0]. Also, some changes appear to be in gcc-7-branch already[1]. Do you think we should wait for it instead? [0]: https://gcc.gnu.org/ml/gcc-patches/2018-01/msg01400.html [1]: https://gcc.gnu.org/git/?p=3Dgcc.git;a=3Dshortlog;h=3Drefs/heads/gcc-7= -branch > Thanks, > Ludo=E2=80=99. From unknown Sun Jun 22 07:57:08 2025 X-Loop: help-debbugs@gnu.org Subject: [bug#30111] gnu: gcc@7: Apply the 'retpoline' mitigation technique. Resent-From: ludo@gnu.org (Ludovic =?UTF-8?Q?Court=C3=A8s?=) Original-Sender: "Debbugs-submit" Resent-CC: guix-patches@gnu.org Resent-Date: Wed, 17 Jan 2018 13:12:01 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 30111 X-GNU-PR-Package: guix-patches X-GNU-PR-Keywords: security patch To: Alex Vong Cc: 30111@debbugs.gnu.org Received: via spool by 30111-submit@debbugs.gnu.org id=B30111.15161946802369 (code B ref 30111); Wed, 17 Jan 2018 13:12:01 +0000 Received: (at 30111) by debbugs.gnu.org; 17 Jan 2018 13:11:20 +0000 Received: from localhost ([127.0.0.1]:59543 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1ebnUt-0000c9-Ro for submit@debbugs.gnu.org; Wed, 17 Jan 2018 08:11:20 -0500 Received: from hera.aquilenet.fr ([185.233.100.1]:42520) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1ebnUr-0000c0-Dt for 30111@debbugs.gnu.org; Wed, 17 Jan 2018 08:11:17 -0500 Received: from localhost (localhost [127.0.0.1]) by hera.aquilenet.fr (Postfix) with ESMTP id 8BC9910E8C; Wed, 17 Jan 2018 14:11:16 +0100 (CET) X-Virus-Scanned: Debian amavisd-new at aquilenet.fr Received: from hera.aquilenet.fr ([127.0.0.1]) by localhost (hera.aquilenet.fr [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id H1wTEF0ONUVD; Wed, 17 Jan 2018 14:11:15 +0100 (CET) Received: from ribbon (unknown [IPv6:2a01:e0a:1d:7270:af76:b9b:ca24:c465]) by hera.aquilenet.fr (Postfix) with ESMTPSA id 8D36010C9E; Wed, 17 Jan 2018 14:11:15 +0100 (CET) From: ludo@gnu.org (Ludovic =?UTF-8?Q?Court=C3=A8s?=) References: <877esksi62.fsf@gmail.com> <87d12bgpqh.fsf@gmail.com> <87a7xet06p.fsf@gmail.com> <87a7xd6ffu.fsf@gnu.org> <876081u8r0.fsf@gmail.com> X-URL: http://www.fdn.fr/~lcourtes/ X-Revolutionary-Date: 28 =?UTF-8?Q?Niv=C3=B4se?= an 226 de la =?UTF-8?Q?R=C3=A9volution?= X-PGP-Key-ID: 0x090B11993D9AEBB5 X-PGP-Key: http://www.fdn.fr/~lcourtes/ludovic.asc X-PGP-Fingerprint: 3CE4 6455 8A84 FDC6 9DB4 0CFB 090B 1199 3D9A EBB5 X-OS: x86_64-pc-linux-gnu Date: Wed, 17 Jan 2018 14:11:14 +0100 In-Reply-To: <876081u8r0.fsf@gmail.com> (Alex Vong's message of "Tue, 16 Jan 2018 23:24:35 +0800") Message-ID: <87shb46365.fsf@gnu.org> User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/25.3 (gnu/linux) MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: quoted-printable X-Spam-Score: 1.0 (+) X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: 1.0 (+) Hi Alex, Alex Vong skribis: > ludo@gnu.org (Ludovic Court=C3=A8s) writes: [...] >> Do you know if a new 7.x including retpoline support is scheduled for >> release soon? >> > Yes, I think they will appear in 7.3 according to [0]. Also, some > changes appear to be in gcc-7-branch already[1]. Do you think we should > wait for it instead? Yes, perhaps we should wait for that release. What do people think? Ludo=E2=80=99. From unknown Sun Jun 22 07:57:08 2025 X-Loop: help-debbugs@gnu.org Subject: [bug#30111] gnu: gcc@7: Apply the 'retpoline' mitigation technique. Resent-From: Leo Famulari Original-Sender: "Debbugs-submit" Resent-CC: guix-patches@gnu.org Resent-Date: Wed, 17 Jan 2018 23:32:02 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 30111 X-GNU-PR-Package: guix-patches X-GNU-PR-Keywords: security patch To: Ludovic =?UTF-8?Q?Court=C3=A8s?= Cc: 30111@debbugs.gnu.org, Alex Vong Received: via spool by 30111-submit@debbugs.gnu.org id=B30111.15162319157549 (code B ref 30111); Wed, 17 Jan 2018 23:32:02 +0000 Received: (at 30111) by debbugs.gnu.org; 17 Jan 2018 23:31:55 +0000 Received: from localhost ([127.0.0.1]:60708 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1ebxBS-0001xh-OY for submit@debbugs.gnu.org; Wed, 17 Jan 2018 18:31:54 -0500 Received: from out1-smtp.messagingengine.com ([66.111.4.25]:43767) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1ebxBQ-0001xZ-T9 for 30111@debbugs.gnu.org; Wed, 17 Jan 2018 18:31:53 -0500 Received: from compute4.internal (compute4.nyi.internal [10.202.2.44]) by mailout.nyi.internal (Postfix) with ESMTP id C2A2120E40; Wed, 17 Jan 2018 18:31:52 -0500 (EST) Received: from frontend1 ([10.202.2.160]) by compute4.internal (MEProxy); Wed, 17 Jan 2018 18:31:52 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=famulari.name; h=cc:content-type:date:from:in-reply-to:message-id:mime-version :references:subject:to:x-me-sender:x-me-sender:x-sasl-enc; s= mesmtp; bh=EntO3VHd8eUJevVAP7AecWsIhA0Wd/THbIp3h6U7xZQ=; b=AZpZW UQrFp3RnwpIQ72iqrVLIxmBY2C2ICVqRYVoiFYg09tSLZF0K/2KMJQ2SZUoJS0J4 MY7wRrrtn9LP6kIXKsBN0KE1GwiZqp9Ir6nLgEgLvPr/PrGcfa5+OhX8Ja1SqNsG /R9hS/oUCG8mBb1LsxyFhrg1ip01m1+oDeWB7E= DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d= messagingengine.com; h=cc:content-type:date:from:in-reply-to :message-id:mime-version:references:subject:to:x-me-sender :x-me-sender:x-sasl-enc; s=fm1; bh=EntO3VHd8eUJevVAP7AecWsIhA0Wd /THbIp3h6U7xZQ=; b=KvmLj4n+/jdQG1nv7u4CMLXJf8RVWY8577vm/ydNkVNG9 4tf3KsMZY45hQ+pPUl3FGJi6Vdo3WwY+YoTyLpWEyjCG2XLMtzbB4MCvtbHByXi6 Eke5avvZIDQx0ekedEmGzlC41jsOYSX3/laICdS0uss3JYXN/7X3LuBY94eEjShj aNPHdb8AidkASW/DoBwe38HU5PNpi0AVE9ZAr3kop0zcQ2lKfopFsCQobypWqzju lIDdogvFoAIvyCoPV943DZzputgsciHOEM0Mae7Oy1F5avScV3zvRlOHPOXqXWcW GcAMKZ2ZoK6cm09iLnHCSppQZfp3DPhDlgJs7PK/A== X-ME-Sender: Received: from localhost (71-93-196-183.dhcp.nrwl.ca.charter.com [71.93.196.183]) by mail.messagingengine.com (Postfix) with ESMTPA id 661157E5CA; Wed, 17 Jan 2018 18:31:52 -0500 (EST) Date: Wed, 17 Jan 2018 15:31:51 -0800 From: Leo Famulari Message-ID: <20180117233151.GC17805@jasmine.lan> References: <877esksi62.fsf@gmail.com> <87d12bgpqh.fsf@gmail.com> <87a7xet06p.fsf@gmail.com> <87a7xd6ffu.fsf@gnu.org> <876081u8r0.fsf@gmail.com> <87shb46365.fsf@gnu.org> MIME-Version: 1.0 Content-Type: multipart/signed; micalg=pgp-sha256; protocol="application/pgp-signature"; boundary="XWOWbaMNXpFDWE00" Content-Disposition: inline In-Reply-To: <87shb46365.fsf@gnu.org> User-Agent: Mutt/1.9.2 (2017-12-15) X-Spam-Score: -0.7 (/) X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -0.7 (/) --XWOWbaMNXpFDWE00 Content-Type: text/plain; charset=iso-8859-1 Content-Disposition: inline Content-Transfer-Encoding: quoted-printable On Wed, Jan 17, 2018 at 02:11:14PM +0100, Ludovic Court=E8s wrote: > Hi Alex, >=20 > Alex Vong skribis: >=20 > > ludo@gnu.org (Ludovic Court=E8s) writes: >=20 > [...] >=20 > >> Do you know if a new 7.x including retpoline support is scheduled for > >> release soon? > >> > > Yes, I think they will appear in 7.3 according to [0]. Also, some > > changes appear to be in gcc-7-branch already[1]. Do you think we should > > wait for it instead? >=20 > Yes, perhaps we should wait for that release. >=20 > What do people think? It depends on whether or not the GCC team is confident in the implementation yet. If they are still working out the kinks then I suggest waiting. --XWOWbaMNXpFDWE00 Content-Type: application/pgp-signature; name="signature.asc" -----BEGIN PGP SIGNATURE----- iQIzBAABCAAdFiEEsFFZSPHn08G5gDigJkb6MLrKfwgFAlpf3OcACgkQJkb6MLrK fwjJNQ//UuC6aSoDJvXJ0lVIARfuDBn06L0RknkTKqdagEVZOdnmtG7tiHAVUKup HxXPdm6tKflOO7EABb/av2QjcNaDm7JsUhc/NKTNWO0imcFMdODnmX4XF2DcpRgJ heAOhawSYLFIa5mHxj0Z6kCMKKKGz2/uDnx1tAWR5StR96ICStX++WnuSKELPG9b 5vcjbYh6NU8uFKai++lcfZPEVa8+0/d0XdUVxjDLySStsI4MCXwtDVTOEweCxFw9 AbAEMGDY2w/6cvPONn0WXApSynAIYFtTX74oJGtozbGRkfW4eu39Tm/DaDpvxB94 zxI5saZeXToFw7RLhNS2t7Z6n5QjZU4CDVZOl1AG1fR3QNfnDOVegGwC7bWE7Z4/ 65WhnN0AcMHG9V/bQ7uEYR21U5nj9W98WnTddCHAkew0frDfYA1x7LS316FTpDFf KTsUWHl3lSLjrQn7O/tY0r4KnEn5j8nw30BukwsCWFaed0UZwLWHQ5GZktOvvNEy azaM/yTsk9zyBlLAdEsU5gzWf8aCQacxeyYcmgXM0A5KQL5+/FcI+XdHIZN5qTE/ vLgqidBkorWSH2MnW8cf5COx7wBTMrf4p0BjIo9gWRrBf4hK/lrrdlzyhUIMZzui J8kqcoNnuhmRyhSlrcmhrOi/oT4YFl8hTxI0g00G2sRL6MIkyak= =S5+D -----END PGP SIGNATURE----- --XWOWbaMNXpFDWE00-- From debbugs-submit-bounces@debbugs.gnu.org Fri Jan 26 22:07:01 2018 Received: (at control) by debbugs.gnu.org; 27 Jan 2018 03:07:01 +0000 Received: from localhost ([127.0.0.1]:44209 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1efGpZ-0006bK-1n for submit@debbugs.gnu.org; Fri, 26 Jan 2018 22:07:01 -0500 Received: from mail-pl0-f44.google.com ([209.85.160.44]:37098) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1efGpX-0006b7-IJ for control@debbugs.gnu.org; Fri, 26 Jan 2018 22:06:59 -0500 Received: by mail-pl0-f44.google.com with SMTP id ay8so151900plb.4 for ; Fri, 26 Jan 2018 19:06:59 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:subject:date:message-id:user-agent:mime-version; bh=vdzGLC/wYNwvi3XP5UENwk9KNhXJo8YOvB4H6qoEGl0=; b=VFJa/n7psjbRyDRtHC7rRgze/L+67cKiPEzI8zMQX6bimIsObLVwr+WlvIxhRqdLzA y52J2VUiFmDLlLnvQoW+K2XHFDvcqmgWTdLLw/6cUoaE7Deo0DQ5wvQunAfss3WdeZLd pLN/DGiBWBmdgEJT1plFLLJv9ncK6EFYiigsTI+X4dN81yoM1zn8JZrOeBJYBqlWjHLA novcVEbSyEsSPmQjhypIv0NTlR0sI1T/tCgkoIbybRUx71Mn7bWtl5eJohHOxkrN/19n noUuXBPRlb/aALXo9fXru8uIKfIiwYfuO4ejIjyJ+XD9oPoKZNKUjW3ac1rtYlW1hmVQ yT2A== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:subject:date:message-id:user-agent :mime-version; bh=vdzGLC/wYNwvi3XP5UENwk9KNhXJo8YOvB4H6qoEGl0=; b=QrQ6T8hT2LkfkIqr/jyPl2MJFUAY35VQ1tmohGr6DiOW/TBqQNtnWhRG6Z5SQqJWiG SpHTAJesMfZuWnldO0kt1X716CHjA0J3XAfgpKXvNwsNkB4U1rPjs+VCwFZ89E3a4rd/ XylqhHN6E2L4Od5hMFrnF3QStubt8bkfAOMIfpEOruZKHtEgCo/ofapvNq3rZN0pNPXT KzQD0QIiUxQiAw5snaQT7wpO3qcZJqPiSZoHzbrYAljp71BYbx/FuA7Yy1+xb2N7AR3+ TYIK01Y/zZAhlNI7DqhIr0S5nqUqUgC58/cyz1ZA2kSXDxE/tR3OAkBeoRx0T2zLrVY1 A6ew== X-Gm-Message-State: AKwxytcQJFrFYSaQJ6og+PdFFezqu8RIcLqq+Hk2IaqtFnHXhPpsIKB6 +/+oSG4k5dZkajDLvE+Am5U= X-Google-Smtp-Source: AH8x22449URD9s2xhEDs5//SElgzp7s4/yVGy8svUJ5tObHGo+Yj0wdWSjWESZU4lAUj+pJEsYJdJw== X-Received: by 2002:a17:902:7046:: with SMTP id h6-v6mr15211521plt.157.1517022413773; Fri, 26 Jan 2018 19:06:53 -0800 (PST) Received: from debian (n218250043136.netvigator.com. [218.250.43.136]) by smtp.gmail.com with ESMTPSA id e67sm21864308pfd.23.2018.01.26.19.06.52 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Fri, 26 Jan 2018 19:06:53 -0800 (PST) From: Alex Vong To: control@debbugs.gnu.org Subject: Change Title. Date: Sat, 27 Jan 2018 11:06:41 +0800 Message-ID: <87po5wt2ym.fsf@gmail.com> User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/25.3 (gnu/linux) MIME-Version: 1.0 Content-Type: text/plain X-Spam-Score: 0.3 (/) X-Debbugs-Envelope-To: control X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: 0.3 (/) package guix-patches retitle 30111 [PATCH] gnu: gcc@7: Use retpoline options when building itself. thanks From unknown Sun Jun 22 07:57:08 2025 X-Loop: help-debbugs@gnu.org Subject: [bug#30111] [PATCH] gnu: gcc@7: Use retpoline options when building itself. References: <877esksi62.fsf@gmail.com> In-Reply-To: <877esksi62.fsf@gmail.com> Resent-From: Alex Vong Original-Sender: "Debbugs-submit" Resent-CC: guix-patches@gnu.org Resent-Date: Sat, 27 Jan 2018 03:21:01 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 30111 X-GNU-PR-Package: guix-patches X-GNU-PR-Keywords: security patch To: 30111@debbugs.gnu.org Received: via spool by 30111-submit@debbugs.gnu.org id=B30111.15170232081487 (code B ref 30111); Sat, 27 Jan 2018 03:21:01 +0000 Received: (at 30111) by debbugs.gnu.org; 27 Jan 2018 03:20:08 +0000 Received: from localhost ([127.0.0.1]:44226 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1efH2G-0000Nu-0q for submit@debbugs.gnu.org; Fri, 26 Jan 2018 22:20:08 -0500 Received: from mail-pl0-f42.google.com ([209.85.160.42]:46249) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1efH2E-0000NL-DV for 30111@debbugs.gnu.org; Fri, 26 Jan 2018 22:20:06 -0500 Received: by mail-pl0-f42.google.com with SMTP id 36so162832ple.13 for <30111@debbugs.gnu.org>; Fri, 26 Jan 2018 19:20:06 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:subject:date:message-id:user-agent:mime-version; bh=INWO0vgcdUguooZek3yjvLD1lqq8Du1YPt/20t8bm40=; b=UzFim0L1DrcK1OcUIKjxIRrwn0tnTDRBsIy5r+nAqiWjBDHXBnL3e1liR2fbHOkeqs 9QZg77Pndjy+2LEbDliPAjablPIWtkP3Nn6xnTj7wfn15v/lk0RH91oir4UJuypjMJSS enfJ8LUbasKKuAAdYG2h6ePCZhgPo5xv20z4M3qyAIUTJx6sMHDk9+p3wL9r+a7M5RS4 fNeZnaTNZ34fZzFWMcucfnqBcFDkL8zxg/DaRPlBS+V7yh64KplNTdf3r/WjAELZxBG+ VViW799SML4G2DDMrnB7pYYBGui8Ea1ll2G/XnBxHrddhzev5xMtMZExIFx88EZU0g/u gxLg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:subject:date:message-id:user-agent :mime-version; bh=INWO0vgcdUguooZek3yjvLD1lqq8Du1YPt/20t8bm40=; b=EAcHvg1TVSgldoDLKwTwzD9Zt9HINAll2ttApWeU+LwSvVQPN6f4O+h0xSa9d9lg50 NACmPZVxwVIj5fUT5rh9jrOg+Q57/3Nur/Dk01VQ7QHVVBJ/T9AjrsWkRcACpuJjc2Bw 3k4hs5B3PQOUg1+g6xdt31EwQWoERhJ9XFPzlxKhj6OOzaZdq5YKP9VIpT+m40mvTOYw ScCjKXg5y7P+gths1FtuuLGuZwh1C/Q6DgnOQx2nDMpTtcrVDHywiz/TldsPGMSbAfrp dm/BF+uKKutQXbNuVDGfnStT3vHiLb3tQOuV9kRNR4jHNc1jYpkCEpROilU2P6Vie7U2 //IQ== X-Gm-Message-State: AKwxyteJQgXbpT6k3np1SqmTRMyF/Iwg7p65ivU4ZP93ZrRGi4jCnfbG pIRHl/TzOB3zGkwJ2L+xAuk= X-Google-Smtp-Source: AH8x226Jm9Tf/0lanefPvD0Rpe7I4x8+dh8sZD2DQ8S7Zrh1/LVItIdtfgEKS7Q/4Xbyg8aueifp1w== X-Received: by 2002:a17:902:7c97:: with SMTP id y23-v6mr15975284pll.439.1517023200767; Fri, 26 Jan 2018 19:20:00 -0800 (PST) Received: from debian (n218250043136.netvigator.com. [218.250.43.136]) by smtp.gmail.com with ESMTPSA id t8sm9504584pgr.21.2018.01.26.19.19.59 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Fri, 26 Jan 2018 19:20:00 -0800 (PST) From: Alex Vong Date: Sat, 27 Jan 2018 11:19:55 +0800 Message-ID: <87lggkt2ck.fsf@gmail.com> User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/25.3 (gnu/linux) MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="=-=-=" X-Spam-Score: 0.2 (/) X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: 0.2 (/) --=-=-= Content-Type: text/plain Hello, This patch makes gcc use retpoline options when building itself. My last attempt to build it was successful. But after that I have changed something, I hope it wouldn't make it fail to build. (It shouldn't, since the options passed aren't changed.) Are we going to add these options to other natively compiled programs as well? --=-=-= Content-Type: text/x-diff; charset=utf-8 Content-Disposition: attachment; filename=0001-gnu-gcc-7-Use-retpoline-options-when-building-itself.patch Content-Transfer-Encoding: quoted-printable >From f6b9caae6e13936be65550c871208a3425fe4ce4 Mon Sep 17 00:00:00 2001 From: Alex Vong Date: Thu, 25 Jan 2018 23:24:24 +0800 Subject: [PATCH] gnu: gcc@7: Use retpoline options when building itself. * gnu/packages/gcc.scm (gcc@7)[arguments]: Add retpoline options to #:make-flags. --- gnu/packages/gcc.scm | 40 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) diff --git a/gnu/packages/gcc.scm b/gnu/packages/gcc.scm index 48e7b8ee3..6344ce734 100644 --- a/gnu/packages/gcc.scm +++ b/gnu/packages/gcc.scm @@ -5,6 +5,7 @@ ;;; Copyright =C2=A9 2015 Andreas Enge ;;; Copyright =C2=A9 2015, 2016, 2017 Efraim Flashner ;;; Copyright =C2=A9 2016 Carlos S=C3=A1nchez de La Lama +;;; Copyright =C2=A9 2018 Alex Vong ;;; ;;; This file is part of GNU Guix. ;;; @@ -428,6 +429,45 @@ Go. It also includes runtime support libraries for th= ese languages.") "0p71bij6bfhzyrs8676a8jmpjsfz392s2rg862sdnsk30jpacb43")) (patches (search-patches "gcc-strmov-store-file-names.patch" "gcc-5.0-libvtv-runpath.patch")))) + (arguments + (substitute-keyword-arguments `(#:modules ((guix build gnu-build-syst= em) + (guix build utils) + (ice-9 regex) + (srfi srfi-1) + (srfi srfi-26)) + ,@(package-arguments gcc-6)) + ;; Use retpoline options when building itself. + ((#:make-flags flags) + `(let* ((cross-compiling? ,(%current-target-system)) + (system (if cross-compiling? + ,(%current-target-system) + ,(%current-system))) + (retpoline-opts '("-mindirect-branch=3Dthunk" + "-mfunction-return=3Dthunk" + "-mindirect-branch-register")) + (append-flag + (lambda (flag) + (if (string-match "^((BOOT_)?CFLAGS|C(XX)?FLAGS_FOR_TAR= GET)=3D" + flag) + (string-join (cons flag retpoline-opts)) + flag))) + (add-flag + (lambda (prefix flags) + (if (any (cut string-prefix? prefix <>) flags) + flags + (cons (string-append prefix + (string-join retpoline-opts)) + flags)))) + (add-gcc-flag (cut add-flag + (if cross-compiling? "CFLAGS=3D" "BOOT_CFL= AGS=3D") + <>)) + (add-c-lib-flag (cut add-flag "CFLAGS_FOR_TARGET=3D" <>)) + (add-c++-lib-flag (cut add-flag "CXXFLAGS_FOR_TARGET=3D" <= >))) + ;; Right now, the retpoline options are x86-specific. + (if (any (cut string-prefix? <> system) '("x86_64" "i686")) + (add-gcc-flag (add-c-lib-flag (add-c++-lib-flag (map append= -flag + ,flags= )))) + ,flags))))) (description "GCC is the GNU Compiler Collection. It provides compiler front-ends for several languages, including C, C++, Objective-C, Fortran, Ada, and Go. --=20 2.15.1 --=-=-= Content-Type: text/plain Cheers, Alex --=-=-=-- From unknown Sun Jun 22 07:57:08 2025 X-Loop: help-debbugs@gnu.org Subject: [bug#30111] [PATCH] gnu: gcc@7: Use retpoline options when building itself. Resent-From: ludo@gnu.org (Ludovic =?UTF-8?Q?Court=C3=A8s?=) Original-Sender: "Debbugs-submit" Resent-CC: guix-patches@gnu.org Resent-Date: Tue, 27 Feb 2018 09:38:02 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 30111 X-GNU-PR-Package: guix-patches X-GNU-PR-Keywords: security patch To: Alex Vong Cc: 30111@debbugs.gnu.org Received: via spool by 30111-submit@debbugs.gnu.org id=B30111.15197242363084 (code B ref 30111); Tue, 27 Feb 2018 09:38:02 +0000 Received: (at 30111) by debbugs.gnu.org; 27 Feb 2018 09:37:16 +0000 Received: from localhost ([127.0.0.1]:34326 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1eqbhC-0000ne-Eb for submit@debbugs.gnu.org; Tue, 27 Feb 2018 04:37:16 -0500 Received: from hera.aquilenet.fr ([185.233.100.1]:50778) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1eqbhA-0000nU-Jj for 30111@debbugs.gnu.org; Tue, 27 Feb 2018 04:37:13 -0500 Received: from localhost (localhost [127.0.0.1]) by hera.aquilenet.fr (Postfix) with ESMTP id F14A310CD3; Tue, 27 Feb 2018 10:37:11 +0100 (CET) X-Virus-Scanned: Debian amavisd-new at aquilenet.fr Received: from hera.aquilenet.fr ([127.0.0.1]) by localhost (hera.aquilenet.fr [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id 3dVscEN-_2qH; Tue, 27 Feb 2018 10:37:11 +0100 (CET) Received: from ribbon (unknown [193.50.110.216]) by hera.aquilenet.fr (Postfix) with ESMTPSA id EFD641069E; Tue, 27 Feb 2018 10:37:10 +0100 (CET) From: ludo@gnu.org (Ludovic =?UTF-8?Q?Court=C3=A8s?=) References: <877esksi62.fsf@gmail.com> <87lggkt2ck.fsf@gmail.com> Date: Tue, 27 Feb 2018 10:37:10 +0100 In-Reply-To: <87lggkt2ck.fsf@gmail.com> (Alex Vong's message of "Sat, 27 Jan 2018 11:19:55 +0800") Message-ID: <87r2p64vuh.fsf@gnu.org> User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/25.3 (gnu/linux) MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: quoted-printable X-Spam-Score: 1.0 (+) X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: 1.0 (+) Hi Alex, Sorry for the delay. Alex Vong skribis: > This patch makes gcc use retpoline options when building itself. My last > attempt to build it was successful. But after that I have changed > something, I hope it wouldn't make it fail to build. (It shouldn't, > since the options passed aren't changed.) Any idea what upstream thinks of compiling GCC itself with these options? Do they offer a configure flag or something to help with that? > Are we going to add these options to other natively compiled programs as > well? I don=E2=80=99t have a good answer. Clearly we=E2=80=99ll want that in key= packages, but then where do we draw the line, and also how do we make sure we don=E2=80=99t repeat ourselves? Thoughts? >>>From f6b9caae6e13936be65550c871208a3425fe4ce4 Mon Sep 17 00:00:00 2001 > From: Alex Vong > Date: Thu, 25 Jan 2018 23:24:24 +0800 > Subject: [PATCH] gnu: gcc@7: Use retpoline options when building itself. > > * gnu/packages/gcc.scm (gcc@7)[arguments]: Add retpoline options > to #:make-flags. [...] > + (arguments > + (substitute-keyword-arguments `(#:modules ((guix build gnu-build-sy= stem) > + (guix build utils) > + (ice-9 regex) > + (srfi srfi-1) > + (srfi srfi-26)) > + ,@(package-arguments gcc-6)) > + ;; Use retpoline options when building itself. > + ((#:make-flags flags) > + `(let* ((cross-compiling? ,(%current-target-system)) > + (system (if cross-compiling? > + ,(%current-target-system) > + ,(%current-system))) > + (retpoline-opts '("-mindirect-branch=3Dthunk" > + "-mfunction-return=3Dthunk" > + "-mindirect-branch-register")) > + (append-flag > + (lambda (flag) > + (if (string-match "^((BOOT_)?CFLAGS|C(XX)?FLAGS_FOR_T= ARGET)=3D" > + flag) > + (string-join (cons flag retpoline-opts)) > + flag))) > + (add-flag > + (lambda (prefix flags) > + (if (any (cut string-prefix? prefix <>) flags) > + flags > + (cons (string-append prefix > + (string-join retpoline-opts)) > + flags)))) > + (add-gcc-flag (cut add-flag > + (if cross-compiling? "CFLAGS=3D" "BOOT_C= FLAGS=3D") > + <>)) > + (add-c-lib-flag (cut add-flag "CFLAGS_FOR_TARGET=3D" <>)) > + (add-c++-lib-flag (cut add-flag "CXXFLAGS_FOR_TARGET=3D"= <>))) > + ;; Right now, the retpoline options are x86-specific. > + (if (any (cut string-prefix? <> system) '("x86_64" "i686")) > + (add-gcc-flag (add-c-lib-flag (add-c++-lib-flag (map appe= nd-flag > + ,fla= gs)))) > + ,flags))))) I=E2=80=99m a bit concerned by the apparent complexity and the extra mainte= nance burden it may entail. I don=E2=80=99t have any concrete suggestions though= . I suppose we should somehow abstract GCC compilation to make it easier to pass new flags? Thanks, Ludo=E2=80=99. From unknown Sun Jun 22 07:57:08 2025 X-Loop: help-debbugs@gnu.org Subject: [bug#30111] gnu: gcc@7: Use retpoline options when building itself. Previous Next References: <877esksi62.fsf@gmail.com> In-Reply-To: <877esksi62.fsf@gmail.com> Resent-From: =?UTF-8?Q?G=C3=A1bor?= Boskovits Original-Sender: "Debbugs-submit" Resent-CC: guix-patches@gnu.org Resent-Date: Fri, 22 Jun 2018 20:08:02 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 30111 X-GNU-PR-Package: guix-patches X-GNU-PR-Keywords: security patch To: 30111@debbugs.gnu.org Received: via spool by 30111-submit@debbugs.gnu.org id=B30111.15296980458651 (code B ref 30111); Fri, 22 Jun 2018 20:08:02 +0000 Received: (at 30111) by debbugs.gnu.org; 22 Jun 2018 20:07:25 +0000 Received: from localhost ([127.0.0.1]:60612 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1fWSL7-0002FT-60 for submit@debbugs.gnu.org; Fri, 22 Jun 2018 16:07:25 -0400 Received: from mail-it0-f46.google.com ([209.85.214.46]:55785) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1fWSL5-0002FF-Hl for 30111@debbugs.gnu.org; Fri, 22 Jun 2018 16:07:24 -0400 Received: by mail-it0-f46.google.com with SMTP id 16-v6so4463265itl.5 for <30111@debbugs.gnu.org>; Fri, 22 Jun 2018 13:07:23 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=mime-version:from:date:message-id:subject:to; bh=Gqxz65tP7HnwtzSmSov87DJH4L5BzXrSmFXzyeGSYns=; b=raZlMkjE1sPfog+vAhmGvewWFEbeFEmZSsb+GBNPoodsEkEe0WfNZo+cSveRaw4U1K L/D9+Uw+Vcu2yKvxUQRTn4VCPOGkzye+2+Ag2EQkWY7LlED/kma6rf9Q2B7bdH9Dqes5 2f3ewbZptnDh294VVfuHbAcLdega/x/ZX2j+655yumw6SODO/tePctNRRAUc9TzVTR/r jgVLAA+/gilnyhod8t3l8WNoNvRYgw8o/p6SSVP4jqNZfJceejjMCXXTB2hc9h1rA3PR gRTddIHXRJ24UBrF7PxTlLpklSFBUz7+HZQ/gZ628GcN4uBclHYOy2+aZC40vmgVml/t yZ/g== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:mime-version:from:date:message-id:subject:to; bh=Gqxz65tP7HnwtzSmSov87DJH4L5BzXrSmFXzyeGSYns=; b=EMIXYCLQ2HH0qCbIvG9bcbmAPQydHHwWbqFuoKftxjBmRmBQkK/m0VT/Pij/Zve/zx Vqc2L5KKGz+rTtie2PsWW4k5V+3tBfXSk8OfUhThtbXHzd8/K0DerkWvGvnWl6Anp+4k h0WCW0X/xvbG5R0v6RB09yNRUixvkekiCkccuIIG6YcMH9nVQvANppovvoBSgIu/xZtP wBrry6fUtl1QBULUGg+MkNlSNIpZVB6Br16dNmeLpVQLDuT4+K8Vusnzz1kVTDzSH41y Azr0Q3izr5GIhO/CGoN9T1ToOhD6f01VKNeivS6GLKtgpLjaoUvkWgwl77IYjauXwpIN RazA== X-Gm-Message-State: APt69E0noy9t6OO/xV8pU+RyClzGNjtkSsAbH9R7mM9NLBlOBJ8ijq38 bprhtn8P7wDrWLWZ3tj2Wi3gKpBNhucdr9oXVYTD X-Google-Smtp-Source: ADUXVKIwlRjdL6o4jF2TSfZW8J2rLOMUvC9VArpKtMIAiAth4psNZ4KUCsEMWe1UT0uq5CupYtZHTFQP08OMzra2tLg= X-Received: by 2002:a24:2e43:: with SMTP id i64-v6mr2767662ita.0.1529698037836; Fri, 22 Jun 2018 13:07:17 -0700 (PDT) MIME-Version: 1.0 From: =?UTF-8?Q?G=C3=A1bor?= Boskovits Date: Fri, 22 Jun 2018 22:07:06 +0200 Message-ID: Content-Type: multipart/alternative; boundary="00000000000028b053056f4094a0" X-Spam-Score: -0.0 (/) X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -1.0 (-) --00000000000028b053056f4094a0 Content-Type: text/plain; charset="UTF-8" We already have gcc 7.3, what is the status of this? --00000000000028b053056f4094a0 Content-Type: text/html; charset="UTF-8"
We already have gcc 7.3, what is the status of this?
--00000000000028b053056f4094a0-- From unknown Sun Jun 22 07:57:08 2025 X-Loop: help-debbugs@gnu.org Subject: [bug#30111] gnu: gcc@7: Apply the 'retpoline' mitigation technique. Resent-From: zimoun Original-Sender: "Debbugs-submit" Resent-CC: guix-patches@gnu.org Resent-Date: Fri, 18 Dec 2020 23:32:01 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 30111 X-GNU-PR-Package: guix-patches X-GNU-PR-Keywords: security patch To: Alex Vong , Ludovic =?UTF-8?Q?Court=C3=A8s?= , Leo Famulari , =?UTF-8?Q?G=C3=A1bor?= Boskovits Cc: 30111@debbugs.gnu.org Received: via spool by 30111-submit@debbugs.gnu.org id=B30111.160833431216678 (code B ref 30111); Fri, 18 Dec 2020 23:32:01 +0000 Received: (at 30111) by debbugs.gnu.org; 18 Dec 2020 23:31:52 +0000 Received: from localhost ([127.0.0.1]:40484 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1kqPE0-0004Kw-2B for submit@debbugs.gnu.org; Fri, 18 Dec 2020 18:31:52 -0500 Received: from mail-wr1-f49.google.com ([209.85.221.49]:43446) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1kqPDx-0004Kf-S6 for 30111@debbugs.gnu.org; Fri, 18 Dec 2020 18:31:50 -0500 Received: by mail-wr1-f49.google.com with SMTP id y17so4148434wrr.10 for <30111@debbugs.gnu.org>; Fri, 18 Dec 2020 15:31:49 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:references:date:in-reply-to:message-id :user-agent:mime-version; bh=uOUqvVQ4BLT9huvHvWfz21cnOJxA1tlGNYqSuIeFimk=; b=hAA5WRHmri5qo32hIbEGLRfuyL4dB5aBBOBSywbyiMTzI3B4j8tUUdsZbm3MJlKxSd CtKIWlUJZhVfr0Elif00wxue/gOBABnIUvlzZxPcdZAJiCXHnGkMcFihbSMkiNVbQPit Uk/w+OlerK0MCum4vBeJEtW1kkRO+hh9rSnXZt0XHxQx4GgK5v9RW/rlHW2jvz368Ud6 9vWq+xBjH/Aw5c/0fA7pW6rnh3rFvezo41KgFsXk0U2X6TOZKDWkawtOBE9w7cAUR3vx QZBmDVrWBs9jO/AqNmCY802VuHrqhol3V/1HyVIsugeZTevt90Ed3ryavqj6B+6p3Ops dvGQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:references:date:in-reply-to :message-id:user-agent:mime-version; bh=uOUqvVQ4BLT9huvHvWfz21cnOJxA1tlGNYqSuIeFimk=; b=oMTV/8WnBi69zuO71JudII5Fxn/OFUs/x7TJ29VKT32oakJliQ8/wCU32ASSvzc6n8 t6jqSOMNEXvcAEGtXOqeAXHkqn5f66uGeiZki5VyCb2vMdLlwjro0usrj68zvI9CvIld pm6npXWI2j1aryq2vouP5E4GmWrENeRg7uwjNwPgFq59n/NoJTre4eKTH5+RijSwZEku PdtGPIB2J6gO8fzafqu1j7y20zRPexGudtWONwnr5QH97sit0AHeehS5jb8rvmYvm9l4 8I6sTUnW61VSGx+V7lcqWdr9T9EM0rOfBOJU7Bo7EaH78ttxH2v/jIU6FQ9tFuimSXgP F8Lw== X-Gm-Message-State: AOAM530LsDc2Ottm8UO526TXin9K6R0Qqcu4q4upJi7GKP7OpRxprA0K K9TnZyuM/HjIYR8MxiXkvj5l2HV6NMG6kg== X-Google-Smtp-Source: ABdhPJz63N9SMBp0Jlx1G6KaJJYQYpPNKAT8pf+hTSp71MQSyAygZvz1VzR8KIe33TwcUnXkqx/uCw== X-Received: by 2002:a5d:4e86:: with SMTP id e6mr6926979wru.33.1608334303937; Fri, 18 Dec 2020 15:31:43 -0800 (PST) Received: from lili ([2a01:e0a:59b:9120:65d2:2476:f637:db1e]) by smtp.gmail.com with ESMTPSA id u10sm12643619wmd.43.2020.12.18.15.31.43 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 18 Dec 2020 15:31:43 -0800 (PST) From: zimoun References: <877esksi62.fsf@gmail.com> Date: Sat, 19 Dec 2020 00:22:07 +0100 In-Reply-To: <877esksi62.fsf@gmail.com> (Alex Vong's message of "Sun, 14 Jan 2018 21:07:17 +0800") Message-ID: <86czz6u2cg.fsf@gmail.com> User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/27.1 (gnu/linux) MIME-Version: 1.0 Content-Type: text/plain X-Spam-Score: 0.0 (/) X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -1.0 (-) Hi, On Sun, 14 Jan 2018 at 21:07, Alex Vong wrote: > 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. As asked here: , since gcc 7.3 is in, and now even more recent, I am inclined to close this submission since it appears to me no more relevant. WDYT? All the best, simon From unknown Sun Jun 22 07:57:08 2025 X-Loop: help-debbugs@gnu.org Subject: [bug#30111] gnu: gcc@7: Apply the 'retpoline' mitigation technique. Resent-From: zimoun Original-Sender: "Debbugs-submit" Resent-CC: guix-patches@gnu.org Resent-Date: Mon, 11 Jan 2021 15:49:04 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 30111 X-GNU-PR-Package: guix-patches X-GNU-PR-Keywords: security patch To: Alex Vong Cc: Ludovic =?UTF-8?Q?Court=C3=A8s?= , 30111@debbugs.gnu.org, =?UTF-8?Q?G=C3=A1bor?= Boskovits , Leo Famulari Received: via spool by 30111-submit@debbugs.gnu.org id=B30111.16103801426564 (code B ref 30111); Mon, 11 Jan 2021 15:49:04 +0000 Received: (at 30111) by debbugs.gnu.org; 11 Jan 2021 15:49:02 +0000 Received: from localhost ([127.0.0.1]:57933 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1kyzRF-0001hh-G0 for submit@debbugs.gnu.org; Mon, 11 Jan 2021 10:49:01 -0500 Received: from mail-wm1-f46.google.com ([209.85.128.46]:53607) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1kyzRD-0001gw-M9 for 30111@debbugs.gnu.org; Mon, 11 Jan 2021 10:49:00 -0500 Received: by mail-wm1-f46.google.com with SMTP id k10so240894wmi.3 for <30111@debbugs.gnu.org>; Mon, 11 Jan 2021 07:48:59 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:references:date:in-reply-to:message-id :user-agent:mime-version; bh=kyN/Z+KY2kiFlRPnzOdJdQ50rTeOlrp1D0u4a7Vr2c0=; b=LYDjo1i9mfpF+Diuv0cgr244+xd/8Q1Cr2KhHXeTLhBzoqxPemD4r0QR1cEn91DFY2 42YTXQ7ORsokZyQsofOcy7WXIQyPxAcTb5rDFpFqdJfOYXrAlRTVTV7Ts5weI9Aiq/fj KEP7GqNt+DkIFX5+DsK2inxfhJMsiwlR3qeLhiP87bfd4eYQUrh32Gzk5oOwJ7zoRLgF +4lQeQF120Jr/IG3ygPR/5SLuLnPcIRqCRHfOWOkaouazSoBdLZdVdzyjAtBwk/l9Ykj NJgGk+C5VWEMwDORqLaV74eN17LUCoAIR3OyEznjUoz9hNHW3q038V7J8gI2JlYUxaN+ gp1A== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:references:date:in-reply-to :message-id:user-agent:mime-version; bh=kyN/Z+KY2kiFlRPnzOdJdQ50rTeOlrp1D0u4a7Vr2c0=; b=bdMa1GUvZwcaa1Iomghm2IqtPoauHLkudVfmPBr1VI35xLvOQQa840pYZuH05BFDQY C//d6/wcprLj8qCb4ehBNh4YGvP5B1YduOUJmutuGjQ54pxBSSwdvvHUXQ3om8UQe2Hp 4fnLwlCPOUUKDkYMtjSimUKLPEAU4xKnT468X3n7m4BybYVYCAkDFD5e/vECXVStD3BR eegE8LS4piGLul7ULZSu+RddvN5psv2ZmIwsykxFZFk2IdRm/K3loCaegD09ZojLkAXk 1wUxJBxERMtQhF70FOwT+MAlma5oWKiDUbEuXEKmwwt03vq50nE/6Sioyk4EnpoDiGIk KzWQ== X-Gm-Message-State: AOAM530/CO+byIdH7PR6ZpharVD+JlXjdM5jY3/UnwpGg3p98yIKnSgB jEoscKtlrc81mEyaoWx57TL0hA7iW0TG+Q== X-Google-Smtp-Source: ABdhPJyYt/nTJYv5538KEQlRfZVtRjDuvkgjRHkgOfMVEb8cXeWCOgxDakuZQqIMVMC8Z9zSCU6INw== X-Received: by 2002:a7b:c406:: with SMTP id k6mr308358wmi.90.1610380134088; Mon, 11 Jan 2021 07:48:54 -0800 (PST) Received: from lili ([2a01:e0a:59b:9120:65d2:2476:f637:db1e]) by smtp.gmail.com with ESMTPSA id x25sm230213wmc.3.2021.01.11.07.48.52 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 11 Jan 2021 07:48:53 -0800 (PST) From: zimoun References: <877esksi62.fsf@gmail.com> <86czz6u2cg.fsf@gmail.com> Date: Mon, 11 Jan 2021 16:43:41 +0100 In-Reply-To: <86czz6u2cg.fsf@gmail.com> (zimoun's message of "Sat, 19 Dec 2020 00:22:07 +0100") Message-ID: <86y2gzqy1e.fsf@gmail.com> User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/27.1 (gnu/linux) MIME-Version: 1.0 Content-Type: text/plain X-Spam-Score: 0.0 (/) X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -1.0 (-) Hi, On Sat, 19 Dec 2020 at 00:22, zimoun wrote: > Hi, > > On Sun, 14 Jan 2018 at 21:07, Alex Vong wrote: > >> 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. > > As asked here: , since gcc > 7.3 is in, and now even more recent, I am inclined to close this > submission since it appears to me no more relevant. If no objection, I will close this in the coming days. All the best, simon From unknown Sun Jun 22 07:57:08 2025 X-Loop: help-debbugs@gnu.org Subject: [bug#30111] gnu: gcc@7: Apply the 'retpoline' mitigation technique. Resent-From: Efraim Flashner Original-Sender: "Debbugs-submit" Resent-CC: guix-patches@gnu.org Resent-Date: Mon, 11 Jan 2021 20:04:01 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 30111 X-GNU-PR-Package: guix-patches X-GNU-PR-Keywords: security patch To: zimoun Cc: 30111@debbugs.gnu.org, Alex Vong Received: via spool by 30111-submit@debbugs.gnu.org id=B30111.161039542615486 (code B ref 30111); Mon, 11 Jan 2021 20:04:01 +0000 Received: (at 30111) by debbugs.gnu.org; 11 Jan 2021 20:03:46 +0000 Received: from localhost ([127.0.0.1]:58343 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1kz3Pm-00041g-91 for submit@debbugs.gnu.org; Mon, 11 Jan 2021 15:03:46 -0500 Received: from flashner.co.il ([178.62.234.194]:53748) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1kz3Pk-00041U-0n for 30111@debbugs.gnu.org; Mon, 11 Jan 2021 15:03:44 -0500 Received: from localhost (unknown [5.102.238.249]) by flashner.co.il (Postfix) with ESMTPSA id 3E777401FA; Mon, 11 Jan 2021 20:03:38 +0000 (UTC) Date: Mon, 11 Jan 2021 22:03:06 +0200 From: Efraim Flashner Message-ID: References: <877esksi62.fsf@gmail.com> <86czz6u2cg.fsf@gmail.com> <86y2gzqy1e.fsf@gmail.com> MIME-Version: 1.0 Content-Type: multipart/signed; micalg=pgp-sha512; protocol="application/pgp-signature"; boundary="7qPMl5Cve/+gTVUS" Content-Disposition: inline In-Reply-To: <86y2gzqy1e.fsf@gmail.com> X-PGP-Key-ID: 0x41AAE7DCCA3D8351 X-PGP-Key: https://flashner.co.il/~efraim/efraim_flashner.asc X-PGP-Fingerprint: A28B F40C 3E55 1372 662D 14F7 41AA E7DC CA3D 8351 X-Spam-Score: -0.0 (/) X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -1.0 (-) --7qPMl5Cve/+gTVUS Content-Type: text/plain; charset=utf-8 Content-Disposition: inline Content-Transfer-Encoding: quoted-printable On Mon, Jan 11, 2021 at 04:43:41PM +0100, zimoun wrote: > Hi, >=20 > On Sat, 19 Dec 2020 at 00:22, zimoun wrote: > > Hi, > > > > On Sun, 14 Jan 2018 at 21:07, Alex Vong wrote: > > > >> This patch adds the repoline patches (totally 17 of them) taken from t= he > >> 'retpoline-20180107' branch at > >> ``http://git.infradead.org/users/dwmw2/gcc-retpoline.git'' to gcc@7. > > > > As asked here: , since gcc > > 7.3 is in, and now even more recent, I am inclined to close this > > submission since it appears to me no more relevant. >=20 > If no objection, I will close this in the coming days. >=20 I believe we're good (ins)efraim@3900XT ~$ lscpu | grep retpoline Vulnerability Spectre v2: Mitigation; Full AMD retpoline, IBPB condi= tional, STIBP conditional, RSB filling (ins)efraim@3900XT ~$ uname -a Linux 3900XT 5.10.6-gnu #1 SMP 1 x86_64 GNU/Linux --=20 Efraim Flashner =D7=90=D7=A4=D7=A8=D7=99=D7=9D = =D7=A4=D7=9C=D7=A9=D7=A0=D7=A8 GPG key =3D A28B F40C 3E55 1372 662D 14F7 41AA E7DC CA3D 8351 Confidentiality cannot be guaranteed on emails sent or received unencrypted --7qPMl5Cve/+gTVUS Content-Type: application/pgp-signature; name="signature.asc" -----BEGIN PGP SIGNATURE----- iQIzBAABCgAdFiEEoov0DD5VE3JmLRT3Qarn3Mo9g1EFAl/8rvkACgkQQarn3Mo9 g1H+8RAAiJt0NL5oo+/Xy+XZr3e2WV/Zmw5AiLua2siPF/U2j2vDYbsapZpjkVKF RmCZwT8N+OkkfUMd/i1hUY1Um9SVn8XSAGwkop+NP5FsyuHmF/XWfDY1YNvRYCk3 IBhD3yTjV1mXghuDFpN6J2KkDanfRGoujbV+94o8NSDbm2kqTLuJfex3UIUHWaKw a/mHyvUD4ah+gBUjDmNmXc1kgFDGjm/HA3eg3QeS+urJ/+t1S8t+Xan81b9Id561 Mo3/D1IEd7yc/ysFpoab9QVdS4dJFR4i7cCMN2b3fFyG74MIpl1RnGIPzaYtZGvC B5GQCQF2h2eMWvDxaH8V9B+tWkrUj4jJ+Dx4vgfiEdz9Hz45fvf/zn7NquJEPkM4 dov5OJsz+XEqccpiu2wA/hcZIG5yXMonglv6ziarQmQzgv2b4GCcwG0QTAgK138c b5W3p0r7bVCbF3d/ZtVtQxchn8eJ4BTCA4VaW009ZMrxKSFFujp9SCNmm7WdVb8m +3CVtV7/qN2e/oLi4seiwfqP73ky3PH1+JKcoQ5/CZqgBZmpRt8iGz8cGNhGQNyb aXkOGX4Vz6dI/er0ZLwDIZArEFav3Sx/P2AstiyDJgv4bnxIeGKdRYsqJeUSCelA tIFz4QzBGaR3JbXRVOYTIjDwPDN6ksF+1RRAC+UDLC3vWRtGXn4= =+8L7 -----END PGP SIGNATURE----- --7qPMl5Cve/+gTVUS-- From unknown Sun Jun 22 07:57:08 2025 MIME-Version: 1.0 X-Mailer: MIME-tools 5.505 (Entity 5.505) X-Loop: help-debbugs@gnu.org From: help-debbugs@gnu.org (GNU bug Tracking System) To: Alex Vong Subject: bug#30111: closed (Re: [bug#30111] gnu: gcc@7: Apply the 'retpoline' mitigation technique.) Message-ID: References: <86sg66jbfz.fsf@gmail.com> <877esksi62.fsf@gmail.com> X-Gnu-PR-Message: they-closed 30111 X-Gnu-PR-Package: guix-patches X-Gnu-PR-Keywords: security patch Reply-To: 30111@debbugs.gnu.org Date: Tue, 09 Feb 2021 01:10:02 +0000 Content-Type: multipart/mixed; boundary="----------=_1612833002-30114-1" This is a multi-part message in MIME format... ------------=_1612833002-30114-1 Content-Disposition: inline Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Your bug report #30111: [PATCH] gnu: gcc@7: Use retpoline options when building itself. which was filed against the guix-patches package, has been closed. The explanation is attached below, along with your original report. If you require more details, please reply to 30111@debbugs.gnu.org. --=20 30111: http://debbugs.gnu.org/cgi/bugreport.cgi?bug=3D30111 GNU Bug Tracking System Contact help-debbugs@gnu.org with problems ------------=_1612833002-30114-1 Content-Type: message/rfc822 Content-Disposition: inline Content-Transfer-Encoding: 7bit Received: (at 30111-done) by debbugs.gnu.org; 9 Feb 2021 01:10:00 +0000 Received: from localhost ([127.0.0.1]:52196 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1l9HXT-0007pJ-I7 for submit@debbugs.gnu.org; Mon, 08 Feb 2021 20:09:59 -0500 Received: from mail-wr1-f47.google.com ([209.85.221.47]:43946) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1l9HXP-0007oV-JY for 30111-done@debbugs.gnu.org; Mon, 08 Feb 2021 20:09:56 -0500 Received: by mail-wr1-f47.google.com with SMTP id z6so19526879wrq.10 for <30111-done@debbugs.gnu.org>; Mon, 08 Feb 2021 17:09:55 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:references:date:in-reply-to:message-id :user-agent:mime-version; bh=PD8EhnpuU9Q95ushAVNHXPdMhyFH7LCNmL2xfKiPgjc=; b=qohIpBpBBts3vXoNyGkxvBfzoxtMrkGo5s2pvVTsjKigFIcZxj59Vs1ZKfEwu9FAXb 2cEPkU1WUchUpsc2tOJid6FpLThQK7AeBnmDUms2VA+S87xfz8A56NnxuyiirkNr5UyX mqV2r5wZttg+CTzuAp1EVl1GMcJjJI02dGqQiftfFjqGgLYU+9OZUfY0lf5xtTiwk7Gp Qs+w6m9ZL5tHNqA9yzFfszqXm5ua3lXlQIjC4PUipa9uS1EVHu6uvvQY/mm4dBUdNfMS 5m1O6u5ZPBm4iLiDD76Eg6CBEX9RhjzX5wtEHYteytaIEDvj9YOe6GeMXDV1k8TZb04y Wyhw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:references:date:in-reply-to :message-id:user-agent:mime-version; bh=PD8EhnpuU9Q95ushAVNHXPdMhyFH7LCNmL2xfKiPgjc=; b=MHUsuwu/txEXIXbGCHIz+P/ybDg3s7xKgoBDst0/4t6RkXNE22f9vVf/IRt1eDx5Td vzYditMKgo6uCiYzi3xZSXGFDNR/nu4PvwJo5N1+L15K0/lb1wO5OLEzjnhq3CA9HMD/ hn52YIaqFE6GMEhAHeg08bU3NJOBQuCcu+4BkpsEJYWP7uMm2ecdlKSXl/rBL2KArFT7 3HbVxhenps+bZkcWGyQDW0Znck6c9clpQIbdBmRdbanv8tK1cYDs3opliS2/zV2aN5bY 6rkrJ85u77Idt4mZm88dxm0vMD6MoOayXgePz/sqsV5uhmOAMfOWd7KSuJUxx8ItTHod 1E5A== X-Gm-Message-State: AOAM53366h6wQw4csNuNjS4re8Fm2y1hvkpa/EQhsduTUs7Yu59MSYNP X/59jiseBf7j/3RFjmj/Ftw= X-Google-Smtp-Source: ABdhPJzXou2grbwo/86FtXf1s44lluQtxXvbh5pA6ocneKHu2G1e0rx+NUTFgUswpc2V7GzKG8MCdg== X-Received: by 2002:a5d:4ccb:: with SMTP id c11mr21752440wrt.324.1612832990137; Mon, 08 Feb 2021 17:09:50 -0800 (PST) Received: from lili ([2a01:e0a:59b:9120:65d2:2476:f637:db1e]) by smtp.gmail.com with ESMTPSA id g15sm13686362wrx.1.2021.02.08.17.09.49 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 08 Feb 2021 17:09:49 -0800 (PST) From: zimoun To: Efraim Flashner Subject: Re: [bug#30111] gnu: gcc@7: Apply the 'retpoline' mitigation technique. References: <877esksi62.fsf@gmail.com> <86czz6u2cg.fsf@gmail.com> <86y2gzqy1e.fsf@gmail.com> Date: Tue, 09 Feb 2021 02:07:28 +0100 In-Reply-To: (Efraim Flashner's message of "Mon, 11 Jan 2021 22:03:06 +0200") Message-ID: <86sg66jbfz.fsf@gmail.com> User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/27.1 (gnu/linux) MIME-Version: 1.0 Content-Type: text/plain X-Spam-Score: 0.0 (/) X-Debbugs-Envelope-To: 30111-done Cc: 30111-done@debbugs.gnu.org, Alex Vong X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -1.0 (-) Hi, On Mon, 11 Jan 2021 at 22:03, Efraim Flashner wrote: > On Mon, Jan 11, 2021 at 04:43:41PM +0100, zimoun wrote: >> On Sat, 19 Dec 2020 at 00:22, zimoun wrote: >> > On Sun, 14 Jan 2018 at 21:07, Alex Vong wrote: >> > >> >> 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. >> > >> > As asked here: , since gcc >> > 7.3 is in, and now even more recent, I am inclined to close this >> > submission since it appears to me no more relevant. >> >> If no objection, I will close this in the coming days. > > I believe we're good > > (ins)efraim@3900XT ~$ lscpu | grep retpoline > Vulnerability Spectre v2: Mitigation; Full AMD retpoline, IBPB conditional, STIBP conditional, RSB filling > (ins)efraim@3900XT ~$ uname -a > Linux 3900XT 5.10.6-gnu #1 SMP 1 x86_64 GNU/Linux Thanks Efraim. If I miss something, please reopen it. Cheers, simon ------------=_1612833002-30114-1 Content-Type: message/rfc822 Content-Disposition: inline Content-Transfer-Encoding: 7bit Received: (at submit) by debbugs.gnu.org; 14 Jan 2018 13:09:03 +0000 Received: from localhost ([127.0.0.1]:55439 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1eai22-0000jb-TA for submit@debbugs.gnu.org; Sun, 14 Jan 2018 08:09:02 -0500 Received: from eggs.gnu.org ([208.118.235.92]:43900) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1eai21-0000j5-5v for submit@debbugs.gnu.org; Sun, 14 Jan 2018 08:09:01 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1eai1V-0005Wh-8E for submit@debbugs.gnu.org; Sun, 14 Jan 2018 08:08:56 -0500 X-Spam-Checker-Version: SpamAssassin 3.3.2 (2011-06-06) on eggs.gnu.org X-Spam-Level: * X-Spam-Status: No, score=1.1 required=5.0 tests=BAYES_50, FREEMAIL_ENVFROM_END_DIGIT,FREEMAIL_FROM,T_DKIM_INVALID autolearn=disabled version=3.3.2 Received: from lists.gnu.org ([2001:4830:134:3::11]:32792) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1eai1U-0005Vc-4w for submit@debbugs.gnu.org; Sun, 14 Jan 2018 08:08:29 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:34754) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eai13-0000ZH-4u for guix-patches@gnu.org; Sun, 14 Jan 2018 08:08:27 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1eai0a-0004mk-VF for guix-patches@gnu.org; Sun, 14 Jan 2018 08:08:01 -0500 Received: from mail-pf0-x22c.google.com ([2607:f8b0:400e:c00::22c]:37772) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1eai0Z-0004lL-6d for guix-patches@gnu.org; Sun, 14 Jan 2018 08:07:32 -0500 Received: by mail-pf0-x22c.google.com with SMTP id p1so6890605pfh.4 for ; Sun, 14 Jan 2018 05:07:30 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:subject:date:message-id:user-agent:mime-version; bh=pl3/n3YyJ/Il7XlsKVujC2Wl66yxNWYNKnIbJnOUoAo=; b=SACf7gB79AN1nv10ieHBWGlClbBMf4Gmi6k6ocqXe1+uTk+dkQvtKuq22lDsqE0OmO p6+4vVOHrj0ODNnvfrOM648ru1o3rs65ESMe9P8/j0ANMwaHJxOWhdToBKUJpKgvPXib Sml3pc4Lm5A6ReS12my+Ygkd3LX7+kGbmHMv9pM4UJZvvrN6e8mqfyLyzz3F6rPt5dwM RMf21fpGreON0z9aRRxi6gheDRbi2HFjzmY+BlL4U3qwUQtt0sjhpYYPdjtQHraNLA8z 3tnxOU0breRSttpWJOt1XnNni2G3iwCC0d33gG+qqiVkg78AGuEH11VAUL6bUDrhXjnT rAIA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:subject:date:message-id:user-agent :mime-version; bh=pl3/n3YyJ/Il7XlsKVujC2Wl66yxNWYNKnIbJnOUoAo=; b=gk6TyhiXew2mU9xXjT4WZ0pF6BnU1Yq3TPX3JoyzlDhfuqTeHA5fG35N4EKevhNE6n C1YmR8cC4ItLJsWO+diosufv/K/6H7JcV+PfM1sM/zDem1fdJFRgtrjCrW22JeCEqK9N o/FuZc1JnEXm/WPYG4Rsw5d0ppHZDiAT4rfx7Qbiu/YjFpFL8UBNyfzEi1qMYh7NOGxo j3gGgi0KgInDRqd1oTpkUBmX9j8s7iC171vWievzCTFydqx9/hpHwNSUPrWj2HKbTupk LQ+e267IByE0tOfiC1mY+jAN0r6LTwYgooeoNol6+dRba4rEehMbkTs7+oIa7hETiEJE jyhQ== X-Gm-Message-State: AKGB3mIcgDn5CfTAfwhFGqUM5kWoQjdWqCs6EmtGpMpOPmDQZK6NIbgz +9Zrw2h0NwfW/40R6y1yHBI= X-Google-Smtp-Source: ACJfBoshrrPicVx45N6RNrwbPDPnLPmMDaqjtAZb2ZCal8ZLGWfjmlIQUaaSoct5ZP5t1h8vPCPBBw== X-Received: by 10.98.204.144 with SMTP id j16mr24208277pfk.101.1515935250179; Sun, 14 Jan 2018 05:07:30 -0800 (PST) Received: from debian (n218103180243.netvigator.com. [218.103.180.243]) by smtp.gmail.com with ESMTPSA id d24sm27329615pfb.30.2018.01.14.05.07.26 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Sun, 14 Jan 2018 05:07:28 -0800 (PST) From: Alex Vong To: guix-patches@gnu.org Subject: gnu: gcc@7: Apply the 'retpoline' mitigation technique. Date: Sun, 14 Jan 2018 21:07:17 +0800 Message-ID: <877esksi62.fsf@gmail.com> User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/25.3 (gnu/linux) MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="=-=-=" X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.6.x X-Received-From: 2001:4830:134:3::11 X-Debbugs-Envelope-To: submit X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" --=-=-= Content-Type: text/plain 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. --=-=-= Content-Type: text/x-diff; charset=utf-8 Content-Disposition: inline; filename=0001-gnu-gcc-7-Apply-the-retpoline-mitigation-technique.patch Content-Transfer-Encoding: quoted-printable >From 5be54f7ebe9b0ab6dc65ea974584be0850604b14 Mon Sep 17 00:00:00 2001 From: Alex Vong 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 . * 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-tes= ts.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-br= anch-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-indi= rect-branch-.patch, gnu/packages/patches/gcc-retpoline-Add-tests-for-mindirect-branch-thunk-fch= eck-pointer-.patch, gnu/packages/patches/gcc-retpoline-Disable-red-zone-with-local-indirect-jum= p.patch, gnu/packages/patches/gcc-retpoline-Rename-thunks-to-__x86_indirect_thunk_ra= x-etc.-to-re.patch, gnu/packages/patches/gcc-retpoline-Use-__x86.indirect_thunk.reg-for-indirec= t-branch-via.patch, gnu/packages/patches/gcc-retpoline-i386-Add-V-register-operand-modifier.pat= ch, gnu/packages/patches/gcc-retpoline-i386-More-use-reference-of-struct-ix86_f= rame-to-avoi.patch, gnu/packages/patches/gcc-retpoline-i386-Move-struct-ix86_frame-to-machine_f= unction.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-bra= nch-register-to-indirect-branch-.patch create mode 100644 gnu/packages/patches/gcc-retpoline-Add-tests-for-mindir= ect-branch-thunk-fcheck-pointer-.patch create mode 100644 gnu/packages/patches/gcc-retpoline-Disable-red-zone-wit= h-local-indirect-jump.patch create mode 100644 gnu/packages/patches/gcc-retpoline-Rename-thunks-to-__x= 86_indirect_thunk_rax-etc.-to-re.patch create mode 100644 gnu/packages/patches/gcc-retpoline-Use-__x86.indirect_t= hunk.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-refere= nce-of-struct-ix86_frame-to-avoi.patch create mode 100644 gnu/packages/patches/gcc-retpoline-i386-Move-struct-ix8= 6_frame-to-machine_function.patch create mode 100644 gnu/packages/patches/gcc-retpoline-i386-Use-reference-o= f-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 =C2=A9 2016 Adonay "adfeno" Felipe Nogueira # Copyright =C2=A9 2016, 2017 Ricardo Wurmus # Copyright =C2=A9 2016 Ben Woodcroft -# Copyright =C2=A9 2016, 2017 Alex Vong +# Copyright =C2=A9 2016, 2017, 2018 Alex Vong # Copyright =C2=A9 2016, 2017 Efraim Flashner # Copyright =C2=A9 2016, 2017 Jan Nieuwenhuizen # Copyright =C2=A9 2017 Tobias Geerinckx-Rice @@ -652,6 +652,23 @@ dist_patch_DATA =3D \ %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-machin= e_function.patch \ + %D%/packages/patches/gcc-retpoline-i386-Use-reference-of-struct-ix86_fra= me-to-avoid-cop.patch \ + %D%/packages/patches/gcc-retpoline-i386-More-use-reference-of-struct-ix8= 6_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.pat= ch \ + %D%/packages/patches/gcc-retpoline-Add-mindirect-branch-thunk-extern.pat= ch \ + %D%/packages/patches/gcc-retpoline-Add-indirect_branch-attribute-with-te= sts.patch \ + %D%/packages/patches/gcc-retpoline-Use-__x86.indirect_thunk.reg-for-indi= rect-branch-via.patch \ + %D%/packages/patches/gcc-retpoline-Add-mindirect-branch-loop.patch \ + %D%/packages/patches/gcc-retpoline-Add-mfunction-return-and-function_ret= urn-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-tes= ts.patch \ + %D%/packages/patches/gcc-retpoline-Add-mno-indirect-branch-register-to-i= ndirect-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 =C2=A9 2015 Andreas Enge ;;; Copyright =C2=A9 2015, 2016, 2017 Efraim Flashner ;;; Copyright =C2=A9 2016 Carlos S=C3=A1nchez de La Lama +;;; Copyright =C2=A9 2018 ALex Vong ;;; ;;; This file is part of GNU Guix. ;;; @@ -427,7 +428,24 @@ Go. It also includes runtime support libraries for th= ese 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-ix8= 6_frame-to-machine_function.patch" + "gcc-retpoline-i386-Use-reference-o= f-struct-ix86_frame-to-avoid-cop.patch" + "gcc-retpoline-i386-More-use-refere= nce-of-struct-ix86_frame-to-avoi.patch" + "gcc-retpoline-Add-mindirect-branch= -thunk.patch" + "gcc-retpoline-Add-tests-for-mindir= ect-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_t= hunk.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-bra= nch-register-to-indirect-branch-.patch" + "gcc-retpoline-Disable-red-zone-wit= h-local-indirect-jump.patch" + "gcc-retpoline-i386-Add-V-register-= operand-modifier.patch" + "gcc-retpoline-Rename-thunks-to-__x= 86_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-attribu= te-with-tests.patch b/gnu/packages/patches/gcc-retpoline-Add-indirect_branc= h-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=3DCVE-2017-5715 + +Patch copied from the 'retpoline-20180107' branch of upstream source repos= itory +(please add new / update existing patches when new 'retpoline-xxxxxxxx' br= anch +appears): + +http://git.infradead.org/users/dwmw2/gcc-retpoline.git + +From e9794727bb0384be6d27ad1edaefc71c23cc0d86 Mon Sep 17 00:00:00 2001 +From: "H.J. Lu" +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 { + }; +=20 + enum indirect_branch { ++ indirect_branch_unset =3D 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) + } + } +=20 ++/* 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 =3D=3D indirect_branch_unset) ++ { ++ tree attr =3D lookup_attribute ("indirect_branch", ++ DECL_ATTRIBUTES (fndecl)); ++ if (attr !=3D NULL) ++ { ++ tree args =3D TREE_VALUE (attr); ++ if (args =3D=3D NULL) ++ gcc_unreachable (); ++ tree cst =3D TREE_VALUE (args); ++ if (strcmp (TREE_STRING_POINTER (cst), "keep") =3D=3D 0) ++ cfun->machine->indirect_branch_type =3D indirect_branch_keep; ++ else if (strcmp (TREE_STRING_POINTER (cst), "thunk") =3D=3D 0) ++ cfun->machine->indirect_branch_type =3D indirect_branch_thunk; ++ else if (strcmp (TREE_STRING_POINTER (cst), "thunk-inline") =3D=3D 0) ++ cfun->machine->indirect_branch_type =3D indirect_branch_thunk_inline; ++ else if (strcmp (TREE_STRING_POINTER (cst), "thunk-extern") =3D=3D 0) ++ cfun->machine->indirect_branch_type =3D indirect_branch_thunk_extern; ++ else ++ gcc_unreachable (); ++ } ++ else ++ cfun->machine->indirect_branch_type =3D 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 !=3D NULL_TREE) +- ix86_set_func_type (fndecl); ++ { ++ ix86_set_func_type (fndecl); ++ ix86_set_indirect_branch_type (fndecl); ++ } + return; + } +=20 +@@ -7172,6 +7206,7 @@ ix86_set_current_function (tree fndecl) + } +=20 + ix86_set_func_type (fndecl); ++ ix86_set_indirect_branch_type (fndecl); +=20 + tree new_tree =3D DECL_FUNCTION_SPECIFIC_TARGET (fndecl); + if (new_tree =3D=3D NULL_TREE) +@@ -28605,9 +28640,11 @@ ix86_output_indirect_branch (rtx call_op, const c= har *xasm, + char push_buf[64]; + bool need_bnd_p =3D ix86_bnd_prefixed_insn_p (current_output_insn); +=20 +- if (ix86_indirect_branch !=3D indirect_branch_thunk_inline) ++ if (cfun->machine->indirect_branch_type ++ !=3D indirect_branch_thunk_inline) + { +- bool need_thunk =3D ix86_indirect_branch =3D=3D indirect_branch_thu= nk; ++ bool need_thunk ++ =3D cfun->machine->indirect_branch_type =3D=3D indirect_branch_thunk; + if (need_bnd_p) + indirect_thunk_bnd_needed |=3D need_thunk; + else +@@ -28716,7 +28753,7 @@ const char * + ix86_output_indirect_jmp (rtx call_op) + { + if (ix86_red_zone_size =3D=3D 0 +- && ix86_indirect_branch !=3D indirect_branch_keep) ++ && cfun->machine->indirect_branch_type !=3D 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 =3D constant_call_address_operand (call_op, VOIDmode); + bool output_indirect_p + =3D (!TARGET_SEH +- && ix86_indirect_branch !=3D indirect_branch_keep); ++ && cfun->machine->indirect_branch_type !=3D indirect_branch_keep); + bool seh_nop_p =3D false; + const char *xasm; +=20 +@@ -41749,7 +41786,7 @@ ix86_handle_struct_attribute (tree *node, tree nam= e, tree, int, + } +=20 + 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) !=3D FUNCTION_DECL) +@@ -41758,6 +41795,29 @@ ix86_handle_fndecl_attribute (tree *node, tree na= me, tree, int, + name); + *no_add_attrs =3D true; + } ++ ++ if (is_attribute_p ("indirect_branch", name)) ++ { ++ tree cst =3D TREE_VALUE (args); ++ if (TREE_CODE (cst) !=3D STRING_CST) ++ { ++ warning (OPT_Wattributes, ++ "%qE attribute requires a string constant argument", ++ name); ++ *no_add_attrs =3D true; ++ } ++ else if (strcmp (TREE_STRING_POINTER (cst), "keep") !=3D 0 ++ && strcmp (TREE_STRING_POINTER (cst), "thunk") !=3D 0 ++ && strcmp (TREE_STRING_POINTER (cst), "thunk-inline") !=3D 0 ++ && strcmp (TREE_STRING_POINTER (cst), "thunk-extern") !=3D 0) ++ { ++ warning (OPT_Wattributes, ++ "argument to %qE attribute is not " ++ "(keep|thunk|thunk-inline|thunk-extern)", name); ++ *no_add_attrs =3D true; ++ } ++ } ++ + return NULL_TREE; + } +=20 +@@ -46052,6 +46112,8 @@ static const struct attribute_spec ix86_attribute_= table[] =3D + 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 }, +=20 + /* 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; +=20 ++ /* 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/t= estsuite/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/t= estsuite/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/t= estsuite/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/t= estsuite/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/t= estsuite/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/t= estsuite/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/t= estsuite/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\]+\\(,%" { ta= rget { ! 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/t= estsuite/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=3Dthunk -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" } } */ +--=20 +2.15.1 + diff --git a/gnu/packages/patches/gcc-retpoline-Add-mfunction-return-and-fu= nction_return-attribute.patch b/gnu/packages/patches/gcc-retpoline-Add-mfun= ction-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=3DCVE-2017-5715 + +Patch copied from the 'retpoline-20180107' branch of upstream source repos= itory +(please add new / update existing patches when new 'retpoline-xxxxxxxx' br= anch +appears): + +http://git.infradead.org/users/dwmw2/gcc-retpoline.git + +From 29d5a3f23c18c96944dd3230a41380a6edcd25fd Mon Sep 17 00:00:00 2001 +From: "H.J. Lu" +Date: Tue, 5 Dec 2017 13:29:06 -0800 +Subject: [PATCH 11/17] Add -mfunction-return=3D and function_return attrib= ute + +Add -mfunction-return=3D and function_return attribute tests + +-mfunction-return=3Dthunk + Convert function return instruction to PC-relative call thunk. +-mfunction-return=3Dthunk-inline + Convert function return instruction to PC-relative call thunk with + thunk inlined. +-mfunction-return=3Dthunk-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; +=20 + 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); +=20 +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 =3D ix86_indirect_branch; + } ++ ++ if (cfun->machine->function_return_type =3D=3D indirect_branch_unset) ++ { ++ tree attr =3D lookup_attribute ("function_return", ++ DECL_ATTRIBUTES (fndecl)); ++ if (attr !=3D NULL) ++ { ++ tree args =3D TREE_VALUE (attr); ++ if (args =3D=3D NULL) ++ gcc_unreachable (); ++ tree cst =3D TREE_VALUE (args); ++ if (strcmp (TREE_STRING_POINTER (cst), "keep") =3D=3D 0) ++ cfun->machine->function_return_type =3D indirect_branch_keep; ++ else if (strcmp (TREE_STRING_POINTER (cst), "thunk") =3D=3D 0) ++ cfun->machine->function_return_type =3D indirect_branch_thunk; ++ else if (strcmp (TREE_STRING_POINTER (cst), "thunk-inline") =3D=3D 0) ++ cfun->machine->function_return_type =3D indirect_branch_thunk_inline; ++ else if (strcmp (TREE_STRING_POINTER (cst), "thunk-extern") =3D=3D 0) ++ cfun->machine->function_return_type =3D indirect_branch_thunk_extern; ++ else ++ gcc_unreachable (); ++ } ++ else ++ cfun->machine->function_return_type =3D ix86_function_return; ++ } + } +=20 + /* 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. */ +=20 + 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 >=3D 0 && ret_p) ++ gcc_unreachable (); ++ + if (USE_HIDDEN_LINKONCE) + { + const char *bnd =3D need_bnd_p ? "_bnd" : ""; +@@ -11974,7 +12003,10 @@ indirect_thunk_name (char name[32], int regno, bo= ol need_bnd_p) + bnd, reg_prefix, reg_names[regno]); + } + else +- sprintf (name, "__x86.indirect_thunk%s", bnd); ++ { ++ const char *ret =3D 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, b= ool 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, i= nt regno) + tree decl; +=20 + /* 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 =3D 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); + } +=20 ++ 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) =3D make_node (BLOCK); + current_function_decl =3D decl; + allocate_struct_function (decl, false); +@@ -28736,7 +28807,7 @@ ix86_output_indirect_branch (rtx call_op, const ch= ar *xasm, + indirect_thunk_needed =3D true; + } + } +- indirect_thunk_name (thunk_name_buf, regno, need_bnd_p); ++ indirect_thunk_name (thunk_name_buf, regno, need_bnd_p, false); + thunk_name =3D thunk_name_buf; + } + else +@@ -28860,6 +28931,43 @@ ix86_output_indirect_jmp (rtx call_op) + return "%!jmp\t%A0"; + } +=20 ++const char * ++ix86_output_function_return (bool long_p) ++{ ++ if (cfun->machine->function_return_type !=3D indirect_branch_keep) ++ { ++ char thunk_name[32]; ++ bool need_bnd_p =3D ix86_bnd_prefixed_insn_p (current_output_insn); ++ ++ if (cfun->machine->function_return_type ++ !=3D indirect_branch_thunk_inline) ++ { ++ bool need_thunk =3D (cfun->machine->function_return_type ++ =3D=3D indirect_branch_thunk); ++ indirect_thunk_name (thunk_name, -1, need_bnd_p, true); ++ if (need_bnd_p) ++ { ++ indirect_thunk_bnd_needed |=3D need_thunk; ++ fprintf (asm_out_file, "\tbnd jmp\t%s\n", thunk_name); ++ } ++ else ++ { ++ indirect_thunk_needed |=3D 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. */ +=20 + const char * +@@ -41916,6 +42024,28 @@ ix86_handle_fndecl_attribute (tree *node, tree na= me, tree args, int, + } + } +=20 ++ if (is_attribute_p ("function_return", name)) ++ { ++ tree cst =3D TREE_VALUE (args); ++ if (TREE_CODE (cst) !=3D STRING_CST) ++ { ++ warning (OPT_Wattributes, ++ "%qE attribute requires a string constant argument", ++ name); ++ *no_add_attrs =3D true; ++ } ++ else if (strcmp (TREE_STRING_POINTER (cst), "keep") !=3D 0 ++ && strcmp (TREE_STRING_POINTER (cst), "thunk") !=3D 0 ++ && strcmp (TREE_STRING_POINTER (cst), "thunk-inline") !=3D 0 ++ && strcmp (TREE_STRING_POINTER (cst), "thunk-extern") !=3D 0) ++ { ++ warning (OPT_Wattributes, ++ "argument to %qE attribute is not " ++ "(keep|thunk|thunk-inline|thunk-extern)", name); ++ *no_add_attrs =3D true; ++ } ++ } ++ + return NULL_TREE; + } +=20 +@@ -46212,6 +46342,8 @@ static const struct attribute_spec ix86_attribute_= table[] =3D + 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 }, +=20 + /* 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; +=20 ++ /* 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=3D + Target Report RejectNegative Joined Enum(indirect_branch) Var(ix86_indire= ct_branch) Init(indirect_branch_keep) + Update indirect call and jump. +=20 ++mfunction-return=3D ++Target Report RejectNegative Joined Enum(indirect_branch) Var(ix86_functi= on_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=3D opti= on): ++Known indirect branch choices (for use with the -mindirect-branch=3D/-mfu= nction-return=3D options): +=20 + 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/g= cc.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=3Dthunk" } */ ++ ++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=3Dthunk-inline -mindirect-branch= =3Dthunk -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 { ! x3= 2 } } } } */ ++/* { 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=3Dthunk-extern -mindirect-branch= =3Dthunk -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 { ! x3= 2 } } } } */ ++/* { 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=3Dkeep -mindirect-branch=3Dthunk -= 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=3Dkeep -mindirect-branch=3Dthunk-i= nline -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 { ! x3= 2 } } } } */ ++/* { 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=3Dkeep -mindirect-branch=3Dthunk-e= xtern -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 { ! x3= 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-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=3Dkeep -mindirect-branch=3Dkeep -f= no-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 { ! x3= 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-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=3Dthunk-inline -mindirect-branch= =3Dthunk-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/g= cc.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=3Dthunk-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/g= cc.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=3Dthunk-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/g= cc.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=3Dkeep" } */ ++ ++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/g= cc.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=3Dkeep" } */ ++ ++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/g= cc.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=3Dkeep" } */ ++ ++__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/g= cc.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=3Dkeep" } */ ++ ++__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/g= cc.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=3Dthunk-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/g= cc.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=3Dthunk -mindirect-branch=3Dthunk = -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 { ! x3= 2 } } } } */ ++/* { 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 } } } = */ +--=20 +2.15.1 + diff --git a/gnu/packages/patches/gcc-retpoline-Add-mfunction-return-keep-t= o-indirect-branch-tests.patch b/gnu/packages/patches/gcc-retpoline-Add-mfun= ction-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-indir= ect-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=3DCVE-2017-5715 + +Patch copied from the 'retpoline-20180107' branch of upstream source repos= itory +(please add new / update existing patches when new 'retpoline-xxxxxxxx' br= anch +appears): + +http://git.infradead.org/users/dwmw2/gcc-retpoline.git + +From def2b5d75fd6234984ec969f4586fcb8c516a3b9 Mon Sep 17 00:00:00 2001 +From: "H.J. Lu" +Date: Wed, 6 Dec 2017 09:58:42 -0800 +Subject: [PATCH 12/17] Add -mfunction-return=3Dkeep to indirect branch tes= ts + +--- + 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/testsu= ite/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=3Dthunk -fno-pic" } */ ++/* { dg-options "-O2 -mfunction-return=3Dkeep -mindirect-branch=3Dthunk -= fno-pic" } */ +=20 + typedef void (*dispatch_t)(long offset); +=20 +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-2.c b/gcc/testsu= ite/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=3Dthunk -fno-pic" } */ ++/* { dg-options "-O2 -mfunction-return=3Dkeep -mindirect-branch=3Dthunk -= fno-pic" } */ +=20 + typedef void (*dispatch_t)(long offset); +=20 +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-3.c b/gcc/testsu= ite/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=3Dthunk -fno-pic" } */ ++/* { dg-options "-O2 -mfunction-return=3Dkeep -mindirect-branch=3Dthunk -= fno-pic" } */ +=20 + typedef void (*dispatch_t)(long offset); +=20 +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-4.c b/gcc/testsu= ite/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=3Dthunk -fno-pic" } */ ++/* { dg-options "-O2 -mfunction-return=3Dkeep -mindirect-branch=3Dthunk -= fno-pic" } */ +=20 + typedef void (*dispatch_t)(long offset); +=20 +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-5.c b/gcc/testsu= ite/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=3Dthunk" } */ ++/* { dg-options "-O2 -mfunction-return=3Dkeep -fpic -fno-plt -mindirect-b= ranch=3Dthunk" } */ +=20 + extern void bar (void); +=20 +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-6.c b/gcc/testsu= ite/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=3Dthunk" } */ ++/* { dg-options "-O2 -mfunction-return=3Dkeep -fpic -fno-plt -mindirect-b= ranch=3Dthunk" } */ +=20 + extern void bar (void); +=20 +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-7.c b/gcc/testsu= ite/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=3Dthunk -fno-pic" } */ ++/* { dg-options "-O2 -mfunction-return=3Dkeep -mindirect-branch=3Dthunk -= fno-pic" } */ +=20 + void func0 (void); + void func1 (void); +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-1.c b/gcc/t= estsuite/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=3Dkeep -fno-pic" } */ +=20 + typedef void (*dispatch_t)(long offset); +=20 +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-2.c b/gcc/t= estsuite/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=3Dkeep -fno-pic" } */ +=20 + typedef void (*dispatch_t)(long offset); +=20 +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-3.c b/gcc/t= estsuite/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=3Dkeep -fno-pic" } */ +=20 + typedef void (*dispatch_t)(long offset); +=20 +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-4.c b/gcc/t= estsuite/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=3Dkeep -fno-pic" } */ +=20 + typedef void (*dispatch_t)(long offset); +=20 +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-5.c b/gcc/t= estsuite/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=3Dkeep -fno-pic" } */ +=20 + typedef void (*dispatch_t)(long offset); +=20 +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-6.c b/gcc/t= estsuite/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=3Dkeep -fno-pic" } */ +=20 + typedef void (*dispatch_t)(long offset); +=20 +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-7.c b/gcc/t= estsuite/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=3Dkeep -fno-pic" } */ +=20 + void func0 (void); + void func1 (void); +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-8.c b/gcc/t= estsuite/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=3Dthunk -fno-pic" } */ ++/* { dg-options "-O2 -mfunction-return=3Dkeep -mindirect-branch=3Dthunk -= fno-pic" } */ +=20 + void func0 (void); + void func1 (void); +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-1.c b/gcc/te= stsuite/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=3Dthunk -fcheck-pointer-bounds -mm= px -fno-pic" } */ ++/* { dg-options "-O2 -mfunction-return=3Dkeep -mindirect-branch=3Dthunk -= fcheck-pointer-bounds -mmpx -fno-pic" } */ +=20 + void (*dispatch) (char *); + char buf[10]; +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-2.c b/gcc/te= stsuite/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=3Dthunk -fcheck-pointer-bounds -mm= px -fno-pic" } */ ++/* { dg-options "-O2 -mfunction-return=3Dkeep -mindirect-branch=3Dthunk -= fcheck-pointer-bounds -mmpx -fno-pic" } */ +=20 + void (*dispatch) (char *); + char buf[10]; +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-3.c b/gcc/te= stsuite/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=3Dthunk -fcheck-pointer-bounds -mm= px -fpic -fno-plt" } */ ++/* { dg-options "-O2 -mfunction-return=3Dkeep -mindirect-branch=3Dthunk -= fcheck-pointer-bounds -mmpx -fpic -fno-plt" } */ +=20 + void bar (char *); + char buf[10]; +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-4.c b/gcc/te= stsuite/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=3Dthunk -fcheck-pointer-bounds -mm= px -fpic -fno-plt" } */ ++/* { dg-options "-O2 -mfunction-return=3Dkeep -mindirect-branch=3Dthunk -= fcheck-pointer-bounds -mmpx -fpic -fno-plt" } */ +=20 + 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=3Dthunk-extern -fno-pic" } */ ++/* { dg-options "-O2 -mfunction-return=3Dkeep -mindirect-branch=3Dthunk-e= xtern -fno-pic" } */ +=20 + typedef void (*dispatch_t)(long offset); +=20 +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=3Dthunk-extern -fno-pic" } */ ++/* { dg-options "-O2 -mfunction-return=3Dkeep -mindirect-branch=3Dthunk-e= xtern -fno-pic" } */ +=20 + typedef void (*dispatch_t)(long offset); +=20 +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=3Dthunk-extern -fno-pic" } */ ++/* { dg-options "-O2 -mfunction-return=3Dkeep -mindirect-branch=3Dthunk-e= xtern -fno-pic" } */ +=20 + typedef void (*dispatch_t)(long offset); +=20 +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=3Dthunk-extern -fno-pic" } */ ++/* { dg-options "-O2 -mfunction-return=3Dkeep -mindirect-branch=3Dthunk-e= xtern -fno-pic" } */ +=20 + typedef void (*dispatch_t)(long offset); +=20 +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=3Dthunk-extern" } */ ++/* { dg-options "-O2 -mfunction-return=3Dkeep -fpic -fno-plt -mindirect-b= ranch=3Dthunk-extern" } */ +=20 + extern void bar (void); +=20 +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=3Dthunk-extern" } */ ++/* { dg-options "-O2 -mfunction-return=3Dkeep -fpic -fno-plt -mindirect-b= ranch=3Dthunk-extern" } */ +=20 + extern void bar (void); +=20 +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=3Dthunk-extern -fno-pic" } */ ++/* { dg-options "-O2 -mfunction-return=3Dkeep -mindirect-branch=3Dthunk-e= xtern -fno-pic" } */ +=20 + 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=3Dthunk-inline -fno-pic" } */ ++/* { dg-options "-O2 -mfunction-return=3Dkeep -mindirect-branch=3Dthunk-i= nline -fno-pic" } */ +=20 + typedef void (*dispatch_t)(long offset); +=20 +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=3Dthunk-inline -fno-pic" } */ ++/* { dg-options "-O2 -mfunction-return=3Dkeep -mindirect-branch=3Dthunk-i= nline -fno-pic" } */ +=20 + typedef void (*dispatch_t)(long offset); +=20 +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=3Dthunk-inline -fno-pic" } */ ++/* { dg-options "-O2 -mfunction-return=3Dkeep -mindirect-branch=3Dthunk-i= nline -fno-pic" } */ +=20 + typedef void (*dispatch_t)(long offset); +=20 +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=3Dthunk-inline -fno-pic" } */ ++/* { dg-options "-O2 -mfunction-return=3Dkeep -mindirect-branch=3Dthunk-i= nline -fno-pic" } */ +=20 + typedef void (*dispatch_t)(long offset); +=20 +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=3Dthunk-inline" } */ ++/* { dg-options "-O2 -mfunction-return=3Dkeep -fpic -fno-plt -mindirect-b= ranch=3Dthunk-inline" } */ +=20 + extern void bar (void); +=20 +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=3Dthunk-inline" } */ ++/* { dg-options "-O2 -mfunction-return=3Dkeep -fpic -fno-plt -mindirect-b= ranch=3Dthunk-inline" } */ +=20 + extern void bar (void); +=20 +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=3Dthunk-inline -fno-pic" } */ ++/* { dg-options "-O2 -mfunction-return=3Dkeep -mindirect-branch=3Dthunk-i= nline -fno-pic" } */ +=20 + void func0 (void); + void func1 (void); +--=20 +2.15.1 + diff --git a/gnu/packages/patches/gcc-retpoline-Add-mindirect-branch-loop.p= atch 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=3DCVE-2017-5715 + +Patch copied from the 'retpoline-20180107' branch of upstream source repos= itory +(please add new / update existing patches when new 'retpoline-xxxxxxxx' br= anch +appears): + +http://git.infradead.org/users/dwmw2/gcc-retpoline.git + +From d667049b53e3d45de057fba2f1ed0e3f268201c1 Mon Sep 17 00:00:00 2001 +From: "H.J. Lu" +Date: Thu, 16 Nov 2017 14:46:20 -0800 +Subject: [PATCH 10/17] Add -mindirect-branch-loop=3D + +Add -mindirect-branch-loop=3D 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 + }; +=20 ++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) +=20 + ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, indirectlabel1); +=20 +- /* 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 (); ++ } +=20 + /* 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(indi= rect_branch_thunk_inline) +=20 + EnumValue + Enum(indirect_branch) String(thunk-extern) Value(indirect_branch_thunk_ex= tern) ++ ++mindirect-branch-loop=3D ++Target Report RejectNegative Joined Enum(indirect_branch_loop) Var(ix86_i= ndirect_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=3D option): ++ ++EnumValue ++Enum(indirect_branch_loop) String(lfence) Value(indirect_branch_loop_lfen= ce) ++ ++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/t= estsuite/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=3Dthunk -mindirect-branch-loop=3Dp= ause -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/t= estsuite/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=3Dthunk -mindirect-branch-loop=3Dn= op -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/t= estsuite/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=3Dthunk -mindirect-branch-loop=3Dl= fence -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/t= estsuite/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=3Dthunk-inline -mindirect-branch-l= oop=3Dpause -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/t= estsuite/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=3Dthunk-extern -mindirect-branch-l= oop=3Dpause -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" } } */ +--=20 +2.15.1 + diff --git a/gnu/packages/patches/gcc-retpoline-Add-mindirect-branch-regist= er-and-tests.patch b/gnu/packages/patches/gcc-retpoline-Add-mindirect-branc= h-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=3DCVE-2017-5715 + +Patch copied from the 'retpoline-20180107' branch of upstream source repos= itory +(please add new / update existing patches when new 'retpoline-xxxxxxxx' br= anch +appears): + +http://git.infradead.org/users/dwmw2/gcc-retpoline.git + +From fb8875abab630962dbcb08c822b1b960fa5a51d4 Mon Sep 17 00:00:00 2001 +From: "H.J. Lu" +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 @@ +=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 =3D=3D DImode") ++ (and (match_test "TARGET_X32 && Pmode =3D=3D DImode ++ && !ix86_indirect_branch_thunk_register") + (match_operand 0 "GOT_memory_operand")))) +=20 + (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 =3D=3D DImode") ++ (and (match_test "TARGET_X32 && Pmode =3D=3D DImode ++ && !ix86_indirect_branch_thunk_register") + (match_operand 0 "GOT_memory_operand")))) +=20 + (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] =3D convert_memory_address (word_mode, operands[0]); + }) +=20 +@@ -11657,7 +11657,7 @@ + OPTAB_DIRECT); + } +=20 +- if (TARGET_X32) ++ if (TARGET_X32 || ix86_indirect_branch_thunk_register) + operands[0] =3D convert_memory_address (word_mode, operands[0]); + }) +=20 +@@ -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")]) +=20 +@@ -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 @@ + }) +=20 + (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")]) +=20 + (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))]) +=20 + ;; 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")]) +=20 +@@ -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 @@ +=20 + (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(indi= rect_branch_thunk_inline) + EnumValue + Enum(indirect_branch) String(thunk-extern) Value(indirect_branch_thunk_ex= tern) +=20 ++mindirect-branch-register ++Target Report Var(ix86_indirect_branch_thunk_register) Init(0) ++Force indirect call and jump via register. ++ + mindirect-branch-loop=3D + Target Report RejectNegative Joined Enum(indirect_branch_loop) Var(ix86_i= ndirect_branch_loop) Undocumented Init(indirect_branch_loop_lfence) +=20 +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")))) +=20 + ;; Return true if OP is a memory operands that can be used in sibcalls. +@@ -664,7 +665,8 @@ +=20 + ;; 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 =3D XEXP (op, 0); + return (GET_CODE (op) =3D=3D CONST +@@ -678,9 +680,11 @@ + (ior (match_test "constant_call_address_operand + (op, mode =3D=3D 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 =3D=3D DImode") ++ (and (match_test "TARGET_X32 && Pmode =3D=3D DImode ++ && !ix86_indirect_branch_thunk_register") + (match_operand 0 "GOT_memory_operand"))))) +=20 + ;; Similarly, but for tail calls, in which we cannot allow memory referen= ces. +@@ -688,14 +692,17 @@ + (ior (match_test "constant_call_address_operand + (op, mode =3D=3D 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 =3D=3D DImode") ++ (and (match_test "TARGET_X32 && Pmode =3D=3D DImode ++ && !ix86_indirect_branch_thunk_register") + (match_operand 0 "GOT_memory_operand"))))) +=20 + ;; Return true if OP is a 32-bit GOT symbol operand. + (define_predicate "GOT32_symbol_operand" +- (match_test "GET_CODE (op) =3D=3D CONST ++ (match_test "!ix86_indirect_branch_thunk_register ++ && GET_CODE (op) =3D=3D CONST + && GET_CODE (XEXP (op, 0)) =3D=3D UNSPEC + && XINT (XEXP (op, 0), 1) =3D=3D UNSPEC_GOT")) +=20 +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-register-1.c b/g= cc/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=3Dthunk -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/g= cc/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=3Dthunk-inline -mindirect-branch-r= egister -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/g= cc/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=3Dthunk-extern -mindirect-branch-r= egister -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" } } */ +--=20 +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-thun= k-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=3DCVE-2017-5715 + +Patch copied from the 'retpoline-20180107' branch of upstream source repos= itory +(please add new / update existing patches when new 'retpoline-xxxxxxxx' br= anch +appears): + +http://git.infradead.org/users/dwmw2/gcc-retpoline.git + +From 4032162fb6d36e20091885d0558f91daaa0080d3 Mon Sep 17 00:00:00 2001 +From: "H.J. Lu" +Date: Mon, 27 Nov 2017 08:38:41 -0800 +Subject: [PATCH 07/17] Add -mindirect-branch=3Dthunk-extern + +Add -mindirect-branch=3Dthunk-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 + }; +=20 + #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_bra= nch_thunk) +=20 + EnumValue + Enum(indirect_branch) String(thunk-inline) Value(indirect_branch_thunk_in= line) ++ ++EnumValue ++Enum(indirect_branch) String(thunk-extern) Value(indirect_branch_thunk_ex= tern) +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=3Dthunk-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=3Dthunk-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=3Dthunk-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=3Dthunk-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=3Dthunk-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=3Dthunk-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=3Dthunk-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\]+\\(,%" { ta= rget { ! 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" } } */ +--=20 +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-thun= k-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=3DCVE-2017-5715 + +Patch copied from the 'retpoline-20180107' branch of upstream source repos= itory +(please add new / update existing patches when new 'retpoline-xxxxxxxx' br= anch +appears): + +http://git.infradead.org/users/dwmw2/gcc-retpoline.git + +From 7f4f2bf1688c81496107993080e68a29a24de702 Mon Sep 17 00:00:00 2001 +From: "H.J. Lu" +Date: Wed, 15 Nov 2017 11:20:31 -0800 +Subject: [PATCH 06/17] Add -mindirect-branch=3Dthunk-inline + +Add -mindirect-branch=3Dthunk-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 { +=20 + enum indirect_branch { + indirect_branch_keep, +- indirect_branch_thunk ++ indirect_branch_thunk, ++ indirect_branch_thunk_inline + }; +=20 + #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 =3D ix86_bnd_prefixed_insn_p (current_output_insn); +=20 +- bool need_thunk =3D ix86_indirect_branch =3D=3D indirect_branch_thunk; +- if (need_bnd_p) +- indirect_thunk_bnd_needed |=3D need_thunk; ++ if (ix86_indirect_branch !=3D indirect_branch_thunk_inline) ++ { ++ bool need_thunk =3D ix86_indirect_branch =3D=3D indirect_branch_thu= nk; ++ if (need_bnd_p) ++ indirect_thunk_bnd_needed |=3D need_thunk; ++ else ++ indirect_thunk_needed |=3D need_thunk; ++ indirect_thunk_name (thunk_name_buf, need_bnd_p); ++ thunk_name =3D thunk_name_buf; ++ } + else +- indirect_thunk_needed |=3D need_thunk; +- indirect_thunk_name (thunk_name, need_bnd_p); ++ thunk_name =3D NULL; +=20 + 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, +=20 + output_asm_insn (push_buf, &call_op); +=20 +- if (need_bnd_p) +- fprintf (asm_out_file, "\tbnd jmp\t%s\n", thunk_name); ++ if (thunk_name !=3D 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); +=20 + ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, indirectlabel2); +=20 +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_bran= ch_keep) +=20 + EnumValue + Enum(indirect_branch) String(thunk) Value(indirect_branch_thunk) ++ ++EnumValue ++Enum(indirect_branch) String(thunk-inline) Value(indirect_branch_thunk_in= line) +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=3Dthunk-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=3Dthunk-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=3Dthunk-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=3Dthunk-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=3Dthunk-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=3Dthunk-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=3Dthunk-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\]+\\(,%" { ta= rget { ! 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" } } */ +--=20 +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=3DCVE-2017-5715 + +Patch copied from the 'retpoline-20180107' branch of upstream source repos= itory +(please add new / update existing patches when new 'retpoline-xxxxxxxx' br= anch +appears): + +http://git.infradead.org/users/dwmw2/gcc-retpoline.git + +From 63024dad9c00f1613738fd766e2f0afd455b76d1 Mon Sep 17 00:00:00 2001 +From: "H.J. Lu" +Date: Wed, 1 Nov 2017 16:05:50 -0700 +Subject: [PATCH 04/17] Add -mindirect-branch=3Dthunk + +Add tests for -mindirect-branch=3Dthunk +--- + 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 */ + }; +=20 ++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 +=20 + 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); +=20 +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 +=20 ++static int indirectlabelno; ++static bool indirect_thunk_needed =3D false; ++static bool indirect_thunk_bnd_needed =3D 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 =3D 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] =3D stack_pointer_rtx; ++ xops[1] =3D 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 =3D build_decl (BUILTINS_LOCATION, FUNCTION_DECL, ++ get_identifier (name), ++ build_function_type_list (void_type_node, NULL_TREE)); ++ DECL_RESULT (decl) =3D build_decl (BUILTINS_LOCATION, RESULT_DECL, ++ NULL_TREE, void_type_node); ++ TREE_PUBLIC (decl) =3D 1; ++ TREE_STATIC (decl) =3D 1; ++ DECL_IGNORED_P (decl) =3D 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) =3D 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) =3D make_node (BLOCK); ++ current_function_decl =3D 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 =3D true; ++ first_function_block_is_cold =3D 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 =3D NULL; ++} ++ + static int pic_labels_used; +=20 + /* 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; +=20 ++ if (indirect_thunk_needed) ++ output_indirect_thunk_function (false); ++ if (indirect_thunk_bnd_needed) ++ output_indirect_thunk_function (true); ++ + for (regno =3D AX_REG; regno <=3D SP_REG; regno++) + { + char name[32]; +@@ -28452,12 +28596,132 @@ ix86_nopic_noplt_attribute_p (rtx call_op) + return false; + } +=20 ++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 =3D ix86_bnd_prefixed_insn_p (current_output_insn); ++ ++ bool need_thunk =3D ix86_indirect_branch =3D=3D indirect_branch_thunk; ++ if (need_bnd_p) ++ indirect_thunk_bnd_needed |=3D need_thunk; ++ else ++ indirect_thunk_needed |=3D 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 !=3D 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 =3D XEXP (call_op, 0); ++ if (ix86_decompose_address (addr, &parts) ++ && parts.base =3D=3D 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 =3D gen_rtx_MULT (Pmode, parts.index, ++ GEN_INT (parts.scale)); ++ addr =3D gen_rtx_PLUS (Pmode, stack_pointer_rtx, ++ addr); ++ } ++ else ++ addr =3D stack_pointer_rtx; ++ ++ rtx disp; ++ if (parts.disp !=3D NULL_RTX) ++ disp =3D plus_constant (Pmode, parts.disp, ++ UNITS_PER_WORD); ++ else ++ disp =3D GEN_INT (UNITS_PER_WORD); ++ ++ addr =3D gen_rtx_PLUS (Pmode, addr, disp); ++ call_op =3D 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 =3D=3D 0 ++ && ix86_indirect_branch !=3D indirect_branch_keep) ++ { ++ ix86_output_indirect_branch (call_op, "%0", true); ++ return ""; ++ } ++ else ++ return "%!jmp\t%A0"; ++} ++ + /* Output the assembly for a call instruction. */ +=20 + const char * + ix86_output_call_insn (rtx_insn *insn, rtx call_op) + { + bool direct_p =3D constant_call_address_operand (call_op, VOIDmode); ++ bool output_indirect_p ++ =3D (!TARGET_SEH ++ && ix86_indirect_branch !=3D indirect_branch_keep); + bool seh_nop_p =3D false; + const char *xasm; +=20 +@@ -28467,10 +28731,21 @@ ix86_output_call_insn (rtx_insn *insn, rtx call_= op) + { + if (ix86_nopic_noplt_attribute_p (call_op)) + { ++ direct_p =3D false; + if (TARGET_64BIT) +- xasm =3D "%!jmp\t{*%p0@GOTPCREL(%%rip)|[QWORD PTR %p0@GOTPCREL[rip]]}"; ++ { ++ if (output_indirect_p) ++ xasm =3D "{%p0@GOTPCREL(%%rip)|[QWORD PTR %p0@GOTPCREL[rip]]}"; ++ else ++ xasm =3D "%!jmp\t{*%p0@GOTPCREL(%%rip)|[QWORD PTR %p0@GOTPCREL[rip]= ]}"; ++ } + else +- xasm =3D "%!jmp\t{*%p0@GOT|[DWORD PTR %p0@GOT]}"; ++ { ++ if (output_indirect_p) ++ xasm =3D "{%p0@GOT|[DWORD PTR %p0@GOT]}"; ++ else ++ xasm =3D "%!jmp\t{*%p0@GOT|[DWORD PTR %p0@GOT]}"; ++ } + } + else + xasm =3D "%!jmp\t%P0"; +@@ -28480,9 +28755,17 @@ ix86_output_call_insn (rtx_insn *insn, rtx call_o= p) + else if (TARGET_SEH) + xasm =3D "%!rex.W jmp\t%A0"; + else +- xasm =3D "%!jmp\t%A0"; ++ { ++ if (output_indirect_p) ++ xasm =3D "%0"; ++ else ++ xasm =3D "%!jmp\t%A0"; ++ } +=20 +- 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 ""; + } +=20 +@@ -28520,18 +28803,37 @@ ix86_output_call_insn (rtx_insn *insn, rtx call_= op) + { + if (ix86_nopic_noplt_attribute_p (call_op)) + { ++ direct_p =3D false; + if (TARGET_64BIT) +- xasm =3D "%!call\t{*%p0@GOTPCREL(%%rip)|[QWORD PTR %p0@GOTPCREL[rip]= ]}"; ++ { ++ if (output_indirect_p) ++ xasm =3D "{%p0@GOTPCREL(%%rip)|[QWORD PTR %p0@GOTPCREL[rip]]}"; ++ else ++ xasm =3D "%!call\t{*%p0@GOTPCREL(%%rip)|[QWORD PTR %p0@GOTPCREL[rip]]}"; ++ } + else +- xasm =3D "%!call\t{*%p0@GOT|[DWORD PTR %p0@GOT]}"; ++ { ++ if (output_indirect_p) ++ xasm =3D "{%p0@GOT|[DWORD PTR %p0@GOT]}"; ++ else ++ xasm =3D "%!call\t{*%p0@GOT|[DWORD PTR %p0@GOT]}"; ++ } + } + else + xasm =3D "%!call\t%P0"; + } + else +- xasm =3D "%!call\t%A0"; ++ { ++ if (output_indirect_p) ++ xasm =3D "%0"; ++ else ++ xasm =3D "%!call\t%A0"; ++ } +=20 +- 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); +=20 + 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 con= taining ret bytes. + mgeneral-regs-only + Target Report RejectNegative Mask(GENERAL_REGS_ONLY) Var(ix86_target_flag= s) Save + Generate code which uses only the general registers. ++ ++mindirect-branch=3D ++Target Report RejectNegative Joined Enum(indirect_branch) Var(ix86_indire= ct_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=3D opti= on): ++ ++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=3D@var{type} -mstack-protector-guard=3D@var{guard} @gol +--mmitigate-rop -mgeneral-regs-only} ++-mmitigate-rop -mgeneral-regs-only -mindirect-branch=3D@var{choice}} +=20 + @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. +=20 ++@item -mindirect-branch=3D@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 +=20 + 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/testsu= ite/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=3Dthunk -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/testsu= ite/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=3Dthunk -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/testsu= ite/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=3Dthunk -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/testsu= ite/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=3Dthunk -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/testsu= ite/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=3Dthunk" } */ ++ ++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/testsu= ite/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=3Dthunk" } */ ++ ++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/testsu= ite/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=3Dthunk -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\]+\\(,%" { ta= rget { ! 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} } } */ +--=20 +2.15.1 + diff --git a/gnu/packages/patches/gcc-retpoline-Add-mno-indirect-branch-reg= ister-to-indirect-branch-.patch b/gnu/packages/patches/gcc-retpoline-Add-mn= o-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-t= o-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=3DCVE-2017-5715 + +Patch copied from the 'retpoline-20180107' branch of upstream source repos= itory +(please add new / update existing patches when new 'retpoline-xxxxxxxx' br= anch +appears): + +http://git.infradead.org/users/dwmw2/gcc-retpoline.git + +From 2c14ecf03978ce6c60e021a2b0d72778a5fe0982 Mon Sep 17 00:00:00 2001 +From: "H.J. Lu" +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/testsu= ite/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=3Dkeep -mindirect-branch=3Dthunk -= fno-pic" } */ ++/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=3Dke= ep -mindirect-branch=3Dthunk -fno-pic" } */ +=20 + typedef void (*dispatch_t)(long offset); +=20 +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-2.c b/gcc/testsu= ite/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=3Dkeep -mindirect-branch=3Dthunk -= fno-pic" } */ ++/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=3Dke= ep -mindirect-branch=3Dthunk -fno-pic" } */ +=20 + typedef void (*dispatch_t)(long offset); +=20 +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-3.c b/gcc/testsu= ite/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=3Dkeep -mindirect-branch=3Dthunk -= fno-pic" } */ ++/* { dg-options "-O2 -mno-indirect-branch-register -mno-indirect-branch-r= egister -mno-indirect-branch-register -mfunction-return=3Dkeep -mindirect-b= ranch=3Dthunk -fno-pic" } */ +=20 + typedef void (*dispatch_t)(long offset); +=20 +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-4.c b/gcc/testsu= ite/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=3Dkeep -mindirect-branch=3Dthunk -= fno-pic" } */ ++/* { dg-options "-O2 -mno-indirect-branch-register -mno-indirect-branch-r= egister -mno-indirect-branch-register -mfunction-return=3Dkeep -mindirect-b= ranch=3Dthunk -fno-pic" } */ +=20 + typedef void (*dispatch_t)(long offset); +=20 +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-5.c b/gcc/testsu= ite/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=3Dkeep -fpic -fno-plt -mindirect-b= ranch=3Dthunk" } */ ++/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=3Dke= ep -fpic -fno-plt -mindirect-branch=3Dthunk" } */ +=20 + extern void bar (void); +=20 +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-6.c b/gcc/testsu= ite/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=3Dkeep -fpic -fno-plt -mindirect-b= ranch=3Dthunk" } */ ++/* { dg-options "-O2 -mno-indirect-branch-register -mno-indirect-branch-r= egister -mno-indirect-branch-register -mfunction-return=3Dkeep -fpic -fno-p= lt -mindirect-branch=3Dthunk" } */ +=20 + extern void bar (void); +=20 +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-7.c b/gcc/testsu= ite/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=3Dkeep -mindirect-branch=3Dthunk -= fno-pic" } */ ++/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=3Dke= ep -mindirect-branch=3Dthunk -fno-pic" } */ +=20 + void func0 (void); + void func1 (void); +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-1.c b/gcc/t= estsuite/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=3Dkeep -fno-pic" } */ ++/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=3Dke= ep -fno-pic" } */ +=20 + typedef void (*dispatch_t)(long offset); +=20 +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-2.c b/gcc/t= estsuite/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=3Dkeep -fno-pic" } */ ++/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=3Dke= ep -fno-pic" } */ +=20 + typedef void (*dispatch_t)(long offset); +=20 +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-3.c b/gcc/t= estsuite/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=3Dkeep -fno-pic" } */ ++/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=3Dke= ep -fno-pic" } */ +=20 + typedef void (*dispatch_t)(long offset); +=20 +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-4.c b/gcc/t= estsuite/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=3Dkeep -fno-pic" } */ ++/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=3Dke= ep -fno-pic" } */ +=20 + typedef void (*dispatch_t)(long offset); +=20 +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-5.c b/gcc/t= estsuite/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=3Dkeep -fno-pic" } */ ++/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=3Dke= ep -fno-pic" } */ +=20 + typedef void (*dispatch_t)(long offset); +=20 +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-6.c b/gcc/t= estsuite/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=3Dkeep -fno-pic" } */ ++/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=3Dke= ep -fno-pic" } */ +=20 + typedef void (*dispatch_t)(long offset); +=20 +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-7.c b/gcc/t= estsuite/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=3Dkeep -fno-pic" } */ ++/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=3Dke= ep -fno-pic" } */ +=20 + void func0 (void); + void func1 (void); +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-1.c b/gcc/te= stsuite/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=3Dkeep -mindirect-branch=3Dthunk -= fcheck-pointer-bounds -mmpx -fno-pic" } */ ++/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=3Dke= ep -mindirect-branch=3Dthunk -fcheck-pointer-bounds -mmpx -fno-pic" } */ +=20 + void (*dispatch) (char *); + char buf[10]; +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-2.c b/gcc/te= stsuite/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=3Dkeep -mindirect-branch=3Dthunk -= fcheck-pointer-bounds -mmpx -fno-pic" } */ ++/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=3Dke= ep -mindirect-branch=3Dthunk -fcheck-pointer-bounds -mmpx -fno-pic" } */ +=20 + void (*dispatch) (char *); + char buf[10]; +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-3.c b/gcc/te= stsuite/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=3Dkeep -mindirect-branch=3Dthunk -= fcheck-pointer-bounds -mmpx -fpic -fno-plt" } */ ++/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=3Dke= ep -mindirect-branch=3Dthunk -fcheck-pointer-bounds -mmpx -fpic -fno-plt" }= */ +=20 + void bar (char *); + char buf[10]; +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-4.c b/gcc/te= stsuite/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=3Dkeep -mindirect-branch=3Dthunk -= fcheck-pointer-bounds -mmpx -fpic -fno-plt" } */ ++/* { dg-options "-O2 -mno-indirect-branch-register -mno-indirect-branch-r= egister -mfunction-return=3Dkeep -mindirect-branch=3Dthunk -fcheck-pointer-= bounds -mmpx -fpic -fno-plt" } */ +=20 + 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=3Dkeep -mindirect-branch=3Dthunk-e= xtern -fno-pic" } */ ++/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=3Dke= ep -mindirect-branch=3Dthunk-extern -fno-pic" } */ +=20 + typedef void (*dispatch_t)(long offset); +=20 +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=3Dkeep -mindirect-branch=3Dthunk-e= xtern -fno-pic" } */ ++/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=3Dke= ep -mindirect-branch=3Dthunk-extern -fno-pic" } */ +=20 + typedef void (*dispatch_t)(long offset); +=20 +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=3Dkeep -mindirect-branch=3Dthunk-e= xtern -fno-pic" } */ ++/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=3Dke= ep -mindirect-branch=3Dthunk-extern -fno-pic" } */ +=20 + typedef void (*dispatch_t)(long offset); +=20 +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=3Dkeep -mindirect-branch=3Dthunk-e= xtern -fno-pic" } */ ++/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=3Dke= ep -mindirect-branch=3Dthunk-extern -fno-pic" } */ +=20 + typedef void (*dispatch_t)(long offset); +=20 +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=3Dkeep -fpic -fno-plt -mindirect-b= ranch=3Dthunk-extern" } */ ++/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=3Dke= ep -fpic -fno-plt -mindirect-branch=3Dthunk-extern" } */ +=20 + extern void bar (void); +=20 +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=3Dkeep -fpic -fno-plt -mindirect-b= ranch=3Dthunk-extern" } */ ++/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=3Dke= ep -fpic -fno-plt -mindirect-branch=3Dthunk-extern" } */ +=20 + extern void bar (void); +=20 +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=3Dkeep -mindirect-branch=3Dthunk-e= xtern -fno-pic" } */ ++/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=3Dke= ep -mindirect-branch=3Dthunk-extern -fno-pic" } */ +=20 + 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=3Dkeep -mindirect-branch=3Dthunk-i= nline -fno-pic" } */ ++/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=3Dke= ep -mindirect-branch=3Dthunk-inline -fno-pic" } */ +=20 + typedef void (*dispatch_t)(long offset); +=20 +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=3Dkeep -mindirect-branch=3Dthunk-i= nline -fno-pic" } */ ++/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=3Dke= ep -mindirect-branch=3Dthunk-inline -fno-pic" } */ +=20 + typedef void (*dispatch_t)(long offset); +=20 +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=3Dkeep -mindirect-branch=3Dthunk-i= nline -fno-pic" } */ ++/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=3Dke= ep -mindirect-branch=3Dthunk-inline -fno-pic" } */ +=20 + typedef void (*dispatch_t)(long offset); +=20 +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=3Dkeep -mindirect-branch=3Dthunk-i= nline -fno-pic" } */ ++/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=3Dke= ep -mindirect-branch=3Dthunk-inline -fno-pic" } */ +=20 + typedef void (*dispatch_t)(long offset); +=20 +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=3Dkeep -fpic -fno-plt -mindirect-b= ranch=3Dthunk-inline" } */ ++/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=3Dke= ep -fpic -fno-plt -mindirect-branch=3Dthunk-inline" } */ +=20 + extern void bar (void); +=20 +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=3Dkeep -fpic -fno-plt -mindirect-b= ranch=3Dthunk-inline" } */ ++/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=3Dke= ep -fpic -fno-plt -mindirect-branch=3Dthunk-inline" } */ +=20 + extern void bar (void); +=20 +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=3Dkeep -mindirect-branch=3Dthunk-i= nline -fno-pic" } */ ++/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=3Dke= ep -mindirect-branch=3Dthunk-inline -fno-pic" } */ +=20 + void func0 (void); + void func1 (void); +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-loop-1.c b/gcc/t= estsuite/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=3Dthunk -mindirect-branch-loop=3Dp= ause -fno-pic" } */ ++/* { dg-options "-O2 -mno-indirect-branch-register -mindirect-branch=3Dth= unk -mindirect-branch-loop=3Dpause -fno-pic" } */ +=20 + typedef void (*dispatch_t)(long offset); +=20 +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-loop-2.c b/gcc/t= estsuite/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=3Dthunk -mindirect-branch-loop=3Dn= op -fno-pic" } */ ++/* { dg-options "-O2 -mno-indirect-branch-register -mindirect-branch=3Dth= unk -mindirect-branch-loop=3Dnop -fno-pic" } */ +=20 + typedef void (*dispatch_t)(long offset); +=20 +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-loop-3.c b/gcc/t= estsuite/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=3Dthunk -mindirect-branch-loop=3Dl= fence -fno-pic" } */ ++/* { dg-options "-O2 -mno-indirect-branch-register -mindirect-branch=3Dth= unk -mindirect-branch-loop=3Dlfence -fno-pic" } */ +=20 + typedef void (*dispatch_t)(long offset); +=20 +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-loop-4.c b/gcc/t= estsuite/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=3Dthunk-inline -mindirect-branch-l= oop=3Dpause -fno-pic" } */ ++/* { dg-options "-O2 -mno-indirect-branch-register -mindirect-branch=3Dth= unk-inline -mindirect-branch-loop=3Dpause -fno-pic" } */ +=20 + typedef void (*dispatch_t)(long offset); +=20 +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-loop-5.c b/gcc/t= estsuite/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=3Dthunk-extern -mindirect-branch-l= oop=3Dpause -fno-pic" } */ ++/* { dg-options "-O2 -mno-indirect-branch-register -mindirect-branch=3Dth= unk-extern -mindirect-branch-loop=3Dpause -fno-pic" } */ +=20 + typedef void (*dispatch_t)(long offset); +=20 +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=3Dthunk-inline -mindirect-branch= =3Dthunk -fno-pic" } */ ++/* { dg-options "-O2 -mno-indirect-branch-register -mno-indirect-branch-r= egister -mfunction-return=3Dthunk-inline -mindirect-branch=3Dthunk -fno-pic= " } */ +=20 + extern void (*bar) (void); +=20 +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=3Dthunk-extern -mindirect-branch= =3Dthunk -fno-pic" } */ ++/* { dg-options "-O2 -mno-indirect-branch-register -mno-indirect-branch-r= egister -mno-indirect-branch-register -mno-indirect-branch-register -mfunct= ion-return=3Dthunk-extern -mindirect-branch=3Dthunk -fno-pic" } */ +=20 + extern void (*bar) (void); +=20 +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=3Dkeep -mindirect-branch=3Dthunk -= fno-pic" } */ ++/* { dg-options "-O2 -mno-indirect-branch-register -mno-indirect-branch-r= egister -mno-indirect-branch-register -mno-indirect-branch-register -mfunct= ion-return=3Dkeep -mindirect-branch=3Dthunk -fno-pic" } */ +=20 + extern void (*bar) (void); +=20 +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=3Dkeep -mindirect-branch=3Dthunk-i= nline -fno-pic" } */ ++/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=3Dke= ep -mindirect-branch=3Dthunk-inline -fno-pic" } */ +=20 + 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=3Dkeep -mindirect-branch=3Dthunk-e= xtern -fno-pic" } */ ++/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=3Dke= ep -mindirect-branch=3Dthunk-extern -fno-pic" } */ +=20 + extern void (*bar) (void); +=20 +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=3Dkeep -mindirect-branch=3Dkeep -f= no-pic" } */ ++/* { dg-options "-O2 -mno-indirect-branch-register -mno-indirect-branch-r= egister -mno-indirect-branch-register -mno-indirect-branch-register -mfunct= ion-return=3Dkeep -mindirect-branch=3Dkeep -fno-pic" } */ +=20 + extern void (*bar) (void); +=20 +diff --git a/gcc/testsuite/gcc.target/i386/ret-thunk-9.c b/gcc/testsuite/g= cc.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=3Dthunk -mindirect-branch=3Dthunk = -fno-pic" } */ ++/* { dg-options "-O2 -mno-indirect-branch-register -mno-indirect-branch-r= egister -mfunction-return=3Dthunk -mindirect-branch=3Dthunk -fno-pic" } */ +=20 + extern void (*bar) (void); +=20 +--=20 +2.15.1 + diff --git a/gnu/packages/patches/gcc-retpoline-Add-tests-for-mindirect-bra= nch-thunk-fcheck-pointer-.patch b/gnu/packages/patches/gcc-retpoline-Add-te= sts-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-thu= nk-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=3DCVE-2017-5715 + +Patch copied from the 'retpoline-20180107' branch of upstream source repos= itory +(please add new / update existing patches when new 'retpoline-xxxxxxxx' br= anch +appears): + +http://git.infradead.org/users/dwmw2/gcc-retpoline.git + +From ece041bc3083aabd00fab9de5ba409fbd7dcad8c Mon Sep 17 00:00:00 2001 +From: "H.J. Lu" +Date: Mon, 4 Dec 2017 12:58:20 -0800 +Subject: [PATCH 05/17] Add tests for -mindirect-branch=3Dthunk + -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/te= stsuite/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=3Dthunk -fcheck-pointer-bounds -mm= px -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/te= stsuite/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=3Dthunk -fcheck-pointer-bounds -mm= px -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/te= stsuite/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=3Dthunk -fcheck-pointer-bounds -mm= px -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/te= stsuite/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=3Dthunk -fcheck-pointer-bounds -mm= px -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} } } */ +--=20 +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-indire= ct-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=3DCVE-2017-5715 + +Patch copied from the 'retpoline-20180107' branch of upstream source repos= itory +(please add new / update existing patches when new 'retpoline-xxxxxxxx' br= anch +appears): + +http://git.infradead.org/users/dwmw2/gcc-retpoline.git + +From f96e28553b0f2253184441f22852d76976e19968 Mon Sep 17 00:00:00 2001 +From: "H.J. Lu" +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 +=20 + 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); + } +=20 +-/* 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. */ +=20 + 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 =3D=3D 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, + } +=20 + const char * +-ix86_output_indirect_jmp (rtx call_op) ++ix86_output_indirect_jmp (rtx call_op, bool ret_p) + { +- if (ix86_red_zone_size =3D=3D 0 +- && cfun->machine->indirect_branch_type !=3D indirect_branch_keep) ++ if (cfun->machine->indirect_branch_type !=3D 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 !=3D 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; +=20 ++ /* 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; +=20 +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] =3D convert_memory_address (word_mode, operands[0]); ++ cfun->machine->has_local_indirect_jump =3D true; + }) +=20 + (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 @@ +=20 + if (TARGET_X32 || ix86_indirect_branch_thunk_register) + operands[0] =3D convert_memory_address (word_mode, operands[0]); ++ cfun->machine->has_local_indirect_jump =3D true; + }) +=20 + (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")]) +--=20 +2.15.1 + diff --git a/gnu/packages/patches/gcc-retpoline-Rename-thunks-to-__x86_indi= rect_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_th= unk_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=3DCVE-2017-5715 + +Patch copied from the 'retpoline-20180107' branch of upstream source repos= itory +(please add new / update existing patches when new 'retpoline-xxxxxxxx' br= anch +appears): + +http://git.infradead.org/users/dwmw2/gcc-retpoline.git + +From a072725899c551d9f3f06f3595e2a49748ab0187 Mon Sep 17 00:00:00 2001 +From: David Woodhouse +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, b= ool need_bnd_p, + reg_prefix =3D TARGET_64BIT ? "r" : "e"; + else + reg_prefix =3D ""; +- 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 =3D 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, i= nt regno) + char name[32]; + tree decl; +=20 +- /* 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 =3D build_decl (BUILTINS_LOCATION, FUNCTION_DECL, + get_identifier (name), +@@ -12165,7 +12165,7 @@ output_indirect_thunk_function (bool need_bnd_p, i= nt regno) +=20 + 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]; +=20 + indirect_thunk_name (alias, regno, need_bnd_p, true); +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-1.c b/gcc/testsu= ite/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) + } +=20 + /* { 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/testsu= ite/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) + } +=20 + /* { 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/testsu= ite/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) + } +=20 + /* { 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/testsu= ite/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) + } +=20 + /* { 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/testsu= ite/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) + } +=20 + /* { 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/testsu= ite/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) + } +=20 + /* { 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/testsu= ite/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) + } +=20 + /* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*\.L\[0-9\]+\\(,%" { ta= rget { ! 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/t= estsuite/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) + } +=20 + /* { 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/t= estsuite/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) + } +=20 + /* { 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/t= estsuite/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/t= estsuite/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/t= estsuite/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 { ! x= 32 } } } } */ + /* { 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/t= estsuite/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 { ! x= 32 } } } } */ + /* { 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/t= estsuite/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) + } +=20 + /* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*\.L\[0-9\]+\\(,%" { ta= rget { ! 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/t= estsuite/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) + } + } +=20 +-/* { 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/te= stsuite/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) +=20 + /* { 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/te= stsuite/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) +=20 + /* { 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/te= stsuite/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) + } +=20 + /* { 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/te= stsuite/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) + } +=20 + /* { 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) + } +=20 + /* { 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) + } +=20 + /* { 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) + } +=20 + /* { 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 { ! x= 32 } } } } */ + /* { 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) + } +=20 + /* { 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 { ! x= 32 } } } } */ + /* { 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) + } +=20 + /* { 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) + } +=20 + /* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*\.L\[0-9\]+\\(,%" { ta= rget { ! 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/t= estsuite/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) + } +=20 + /* { 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/t= estsuite/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) + } +=20 + /* { 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/t= estsuite/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) + } +=20 + /* { 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/t= estsuite/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/t= estsuite/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) + } +=20 + /* { 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/g= cc/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); + } +=20 +-/* { 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/g= cc/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/g= cc/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); + } +=20 +-/* { 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/g= cc.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) + { + } +=20 +-/* { 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) +=20 + /* { 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 { ! x3= 2 } } } } */ +-/* { 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; + } +=20 +-/* { 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 { ! x3= 2 } } } } */ +-/* { 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; + } +=20 +-/* { 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; + } +=20 +-/* { 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 { ! x3= 2 } } } } */ + /* { 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) + } +=20 + /* { 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 { ! x3= 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\]*__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; + } +=20 +-/* { 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 { ! x3= 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\]*__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; + } +=20 +-/* { 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/g= cc.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/g= cc.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) + { + } +=20 +-/* { 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/g= cc.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) + { + } +=20 +-/* { 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/g= cc.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) + { + } +=20 +-/* { 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/g= cc.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/g= cc.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) + { + } +=20 +-/* { 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/g= cc.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) + { + } +=20 +-/* { 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/g= cc.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; + } +=20 +-/* { 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 { ! x3= 2 } } } } */ +-/* { 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 } } } = */ +--=20 +2.15.1 + diff --git a/gnu/packages/patches/gcc-retpoline-Use-__x86.indirect_thunk.re= g-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-i= ndirect-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=3DCVE-2017-5715 + +Patch copied from the 'retpoline-20180107' branch of upstream source repos= itory +(please add new / update existing patches when new 'retpoline-xxxxxxxx' br= anch +appears): + +http://git.infradead.org/users/dwmw2/gcc-retpoline.git + +From e4e33b44a49eaa102806589ce12f021ab6a1e5f1 Mon Sep 17 00:00:00 2001 +From: "H.J. Lu" +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 =3D false; + static bool indirect_thunk_bnd_needed =3D false; +=20 ++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 =3D false; + /* Fills in the label name that should be used for the indirect thunk. */ +=20 + 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 =3D need_bnd_p ? "_bnd" : ""; +- sprintf (name, "__x86.indirect_thunk%s", bnd); ++ if (regno >=3D 0) ++ { ++ const char *reg_prefix; ++ if (LEGACY_INT_REGNO_P (regno)) ++ reg_prefix =3D TARGET_64BIT ? "r" : "e"; ++ else ++ reg_prefix =3D ""; ++ 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 >=3D 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); ++ } + } + } +=20 + 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) +=20 + ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, indirectlabel2); +=20 +- /* LEA. */ +- rtx xops[2]; +- xops[0] =3D stack_pointer_rtx; +- xops[1] =3D plus_constant (Pmode, stack_pointer_rtx, UNITS_PER_WORD); +- output_asm_insn ("lea\t{%E1, %0|%0, %E1}", xops); ++ if (regno >=3D 0) ++ { ++ /* MOV. */ ++ rtx xops[2]; ++ xops[0] =3D gen_rtx_MEM (word_mode, stack_pointer_rtx); ++ xops[1] =3D gen_rtx_REG (word_mode, regno); ++ output_asm_insn ("mov\t{%1, %0|%0, %1}", xops); ++ } ++ else ++ { ++ /* LEA. */ ++ rtx xops[2]; ++ xops[0] =3D stack_pointer_rtx; ++ xops[1] =3D plus_constant (Pmode, stack_pointer_rtx, UNITS_PER_WORD= ); ++ output_asm_insn ("lea\t{%E1, %0|%0, %E1}", xops); ++ } +=20 + if (need_bnd_p) + fputs ("\tbnd ret\n", asm_out_file); +@@ -12015,12 +12050,13 @@ output_indirect_thunk (bool need_bnd_p) + } +=20 + 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; +=20 +- indirect_thunk_name (name, need_bnd_p); ++ /* Create __x86.indirect_thunk/__x86.indirect_thunk_bnd. */ ++ indirect_thunk_name (name, regno, need_bnd_p); + decl =3D 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); +=20 +- output_indirect_thunk (need_bnd_p); ++ output_indirect_thunk (need_bnd_p, regno); +=20 + final_end_function (); + init_insn_lengths (); +@@ -12110,15 +12146,31 @@ ix86_code_end (void) + int regno; +=20 + 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 =3D FIRST_REX_INT_REG; regno <=3D LAST_REX_INT_REG; regno++) ++ { ++ int i =3D 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); ++ } +=20 + for (regno =3D AX_REG; regno <=3D SP_REG; regno++) + { + char name[32]; + tree decl; +=20 ++ 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; +=20 +@@ -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 =3D ix86_bnd_prefixed_insn_p (current_output_insn); ++ int regno; ++ ++ if (REG_P (call_op)) ++ regno =3D REGNO (call_op); ++ else ++ regno =3D -1; +=20 + if (cfun->machine->indirect_branch_type + !=3D indirect_branch_thunk_inline) + { +- bool need_thunk +- =3D cfun->machine->indirect_branch_type =3D=3D indirect_branch_thunk; +- if (need_bnd_p) +- indirect_thunk_bnd_needed |=3D need_thunk; +- else +- indirect_thunk_needed |=3D need_thunk; +- indirect_thunk_name (thunk_name_buf, need_bnd_p); ++ if (cfun->machine->indirect_branch_type =3D=3D indirect_branch_thun= k) ++ { ++ if (regno >=3D 0) ++ { ++ int i =3D regno; ++ if (i >=3D FIRST_REX_INT_REG) ++ i -=3D (FIRST_REX_INT_REG - LAST_INT_REG - 1); ++ if (need_bnd_p) ++ indirect_thunks_bnd_used |=3D 1 << i; ++ else ++ indirect_thunks_used |=3D 1 << i; ++ } ++ else ++ { ++ if (need_bnd_p) ++ indirect_thunk_bnd_needed =3D true; ++ else ++ indirect_thunk_needed =3D true; ++ } ++ } ++ indirect_thunk_name (thunk_name_buf, regno, need_bnd_p); + thunk_name =3D thunk_name_buf; + } + else +@@ -28660,7 +28732,8 @@ ix86_output_indirect_branch (rtx call_op, const ch= ar *xasm, +=20 + if (sibcall_p) + { +- output_asm_insn (push_buf, &call_op); ++ if (regno < 0) ++ output_asm_insn (push_buf, &call_op); + if (thunk_name !=3D 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 >=3D 0 && thunk_name !=3D 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]; +=20 +@@ -28725,7 +28807,8 @@ ix86_output_indirect_branch (rtx call_op, const ch= ar *xasm, + } + } +=20 +- output_asm_insn (push_buf, &call_op); ++ if (regno < 0) ++ output_asm_insn (push_buf, &call_op); +=20 + if (thunk_name !=3D NULL) + { +@@ -28735,7 +28818,7 @@ ix86_output_indirect_branch (rtx call_op, const ch= ar *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); +=20 + ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, indirectlabel2); +=20 +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-1.c b/gcc/testsu= ite/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) + } +=20 + /* { 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/testsu= ite/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) + } +=20 + /* { 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/testsu= ite/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) + } +=20 + /* { 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/testsu= ite/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) + } +=20 + /* { 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/testsu= ite/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) + } +=20 + /* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*\.L\[0-9\]+\\(,%" { ta= rget { ! 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/t= estsuite/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) + } +=20 + /* { 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/t= estsuite/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) + } +=20 + /* { 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/t= estsuite/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) + } +=20 + /* { 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/t= estsuite/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) + } +=20 + /* { 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/t= estsuite/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) + } +=20 + /* { 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 { ! x= 32 } } } } */ ++/* { 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/t= estsuite/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) + } +=20 + /* { 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 { ! x= 32 } } } } */ ++/* { 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/t= estsuite/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) + } +=20 + /* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*\.L\[0-9\]+\\(,%" { ta= rget { ! 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) + } +=20 + /* { 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) + } +=20 + /* { 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) + } +=20 + /* { 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 { ! x= 32 } } } } */ ++/* { 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) + } +=20 + /* { 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 { ! x= 32 } } } } */ ++/* { 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) + } +=20 + /* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*\.L\[0-9\]+\\(,%" { ta= rget { ! 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) + } +=20 + /* { 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) + } +=20 + /* { 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) + } +=20 + /* { 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) + } +=20 + /* { 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) + } +=20 + /* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*\.L\[0-9\]+\\(,%" { ta= rget { ! 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" } } */ +--=20 +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-op= erand-modifier.patch new file mode 100644 index 000000000..1996a1dfe --- /dev/null +++ b/gnu/packages/patches/gcc-retpoline-i386-Add-V-register-operand-modifi= er.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=3DCVE-2017-5715 + +Patch copied from the 'retpoline-20180107' branch of upstream source repos= itory +(please add new / update existing patches when new 'retpoline-xxxxxxxx' br= anch +appears): + +http://git.infradead.org/users/dwmw2/gcc-retpoline.git + +From f83391fb22471a2f1c330e2e78f64630d64f497d Mon Sep 17 00:00:00 2001 +From: "H.J. Lu" +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_mo= de 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 %. + */ +=20 + void +@@ -17896,7 +17897,7 @@ print_reg (rtx x, int code, FILE *file) + unsigned int regno; + bool duplicated; +=20 +- if (ASSEMBLER_DIALECT =3D=3D ASM_ATT) ++ if (ASSEMBLER_DIALECT =3D=3D ASM_ATT && code !=3D 'V') + putc ('%', file); +=20 + if (x =3D=3D 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; +=20 + case 's': +--=20 +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-M= ore-use-reference-of-struct-ix86_frame-to-avoi.patch new file mode 100644 index 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=3DCVE-2017-5715 + +Patch copied from the 'retpoline-20180107' branch of upstream source repos= itory +(please add new / update existing patches when new 'retpoline-xxxxxxxx' br= anch +appears): + +http://git.infradead.org/users/dwmw2/gcc-retpoline.git + +From d96784e4a7355aaab68dec62f31a97bd10714064 Mon Sep 17 00:00:00 2001 +From: "H.J. Lu" +Date: Tue, 28 Nov 2017 10:26:35 -0800 +Subject: [PATCH 03/17] i386: More use reference of struct ix86_frame to av= oid + 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 =3D 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 =3D true; +=20 + ix86_compute_frame_layout (); +- frame =3D m->frame; ++ struct ix86_frame &frame =3D cfun->machine->frame; +=20 + if (!TARGET_64BIT && ix86_function_ms_hook_prologue (current_function_d= ecl)) + { +@@ -14343,13 +14342,12 @@ ix86_expand_epilogue (int style) + { + struct machine_function *m =3D cfun->machine; + struct machine_frame_state frame_state_save =3D m->fs; +- struct ix86_frame frame; + bool restore_regs_via_mov; + bool using_drap; +=20 + ix86_finalize_stack_realign_flags (); + ix86_compute_frame_layout (); +- frame =3D m->frame; ++ struct ix86_frame &frame =3D cfun->machine->frame; +=20 + m->fs.sp_valid =3D (!frame_pointer_needed + || (crtl->sp_is_unchanging +--=20 +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-s= truct-ix86_frame-to-machine_function.patch new file mode 100644 index 000000000..908e3cd83 --- /dev/null +++ b/gnu/packages/patches/gcc-retpoline-i386-Move-struct-ix86_frame-to-mac= hine_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=3DCVE-2017-5715 + +Patch copied from the 'retpoline-20180107' branch of upstream source repos= itory +(please add new / update existing patches when new 'retpoline-xxxxxxxx' br= anch +appears): + +http://git.infradead.org/users/dwmw2/gcc-retpoline.git + +From 85743811dfa4eb648edbbb637632ac53182b6e05 Mon Sep 17 00:00:00 2001 +From: "H.J. Lu" +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; + }; +=20 +-/* 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] | =3D 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; +=20 +@@ -2579,7 +2532,7 @@ static unsigned int ix86_function_arg_boundary (mach= ine_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 >=3D 32768) + return 0; +=20 +- ix86_compute_frame_layout (&frame); ++ ix86_compute_frame_layout (); ++ frame =3D cfun->machine->frame; + return (frame.stack_pointer_offset =3D=3D UNITS_PER_WORD + && (frame.nregs + frame.nsseregs) =3D=3D 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 =3D cfun->machine->frame; +=20 + if (from =3D=3D ARG_POINTER_REGNUM && to =3D=3D HARD_FRAME_POINTER_REGN= UM) + 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. = */ +=20 + static void +-ix86_compute_frame_layout (struct ix86_frame *frame) ++ix86_compute_frame_layout (void) + { ++ struct ix86_frame *frame =3D &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 =3D INCOMING_FRAME_SP_OFFSET; + m->fs.sp_valid =3D true; +=20 +- ix86_compute_frame_layout (&frame); ++ ix86_compute_frame_layout (); ++ frame =3D m->frame; +=20 + if (!TARGET_64BIT && ix86_function_ms_hook_prologue (current_function_d= ecl)) + { +@@ -14394,7 +14350,8 @@ ix86_expand_epilogue (int style) + bool using_drap; +=20 + ix86_finalize_stack_realign_flags (); +- ix86_compute_frame_layout (&frame); ++ ix86_compute_frame_layout (); ++ frame =3D m->frame; +=20 + m->fs.sp_valid =3D (!frame_pointer_needed + || (crtl->sp_is_unchanging +@@ -14904,7 +14861,8 @@ ix86_expand_split_stack_prologue (void) + gcc_assert (flag_split_stack && reload_completed); +=20 + ix86_finalize_stack_realign_flags (); +- ix86_compute_frame_layout (&frame); ++ ix86_compute_frame_layout (); ++ frame =3D cfun->machine->frame; + allocate =3D frame.stack_pointer_offset - INCOMING_FRAME_SP_OFFSET; +=20 + /* 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] | =3D 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. = */ +=20 +-#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]; +=20 ++ /* 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) +=20 + /* Control behavior of x86_file_start. */ + #define X86_FILE_START_VERSION_DIRECTIVE false +--=20 +2.15.1 + diff --git a/gnu/packages/patches/gcc-retpoline-i386-Use-reference-of-struc= t-ix86_frame-to-avoid-cop.patch b/gnu/packages/patches/gcc-retpoline-i386-U= se-reference-of-struct-ix86_frame-to-avoid-cop.patch new file mode 100644 index 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=3DCVE-2017-5715 + +Patch copied from the 'retpoline-20180107' branch of upstream source repos= itory +(please add new / update existing patches when new 'retpoline-xxxxxxxx' br= anch +appears): + +http://git.infradead.org/users/dwmw2/gcc-retpoline.git + +From 0b1769bdce27304a6a91bec234f47f102a2603d5 Mon Sep 17 00:00:00 2001 +From: hjl +Date: Mon, 6 Nov 2017 23:04:15 +0000 +Subject: [PATCH 02/17] i386: Use reference of struct ix86_frame to avoid c= opy + +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; +=20 + ix86_compute_frame_layout (); +- frame =3D cfun->machine->frame; ++ struct ix86_frame &frame =3D cfun->machine->frame; + return (frame.stack_pointer_offset =3D=3D UNITS_PER_WORD + && (frame.nregs + frame.nsseregs) =3D=3D 0); + } +@@ -12333,7 +12331,7 @@ HOST_WIDE_INT + ix86_initial_elimination_offset (int from, int to) + { + ix86_compute_frame_layout (); +- struct ix86_frame frame =3D cfun->machine->frame; ++ struct ix86_frame &frame =3D cfun->machine->frame; +=20 + if (from =3D=3D ARG_POINTER_REGNUM && to =3D=3D HARD_FRAME_POINTER_REGN= UM) + 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) +=20 + ix86_finalize_stack_realign_flags (); + ix86_compute_frame_layout (); +- frame =3D cfun->machine->frame; ++ struct ix86_frame &frame =3D cfun->machine->frame; + allocate =3D frame.stack_pointer_offset - INCOMING_FRAME_SP_OFFSET; +=20 + /* This is the label we will branch to if we have enough stack +--=20 +2.15.1 + --=20 2.15.1 --=-=-= Content-Type: text/plain Cheers, Alex --=-=-=-- ------------=_1612833002-30114-1--