Package | Source(s) | Maintainer(s) | |
---|---|---|---|
guix-patches | PTS Buildd Popcon |
Message #12 received at 30111@debbugs.gnu.org (full text, mbox, reply):
Received: (at 30111) by debbugs.gnu.org; 15 Jan 2018 14:29:35 +0000 From debbugs-submit-bounces@debbugs.gnu.org Mon Jan 15 09:29:35 2018 Received: from localhost ([127.0.0.1]:56829 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from <debbugs-submit-bounces@debbugs.gnu.org>) 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 <alexvong1995@gmail.com>) 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 <alexvong1995@gmail.com> To: 30111@debbugs.gnu.org Subject: Re: gnu: gcc@7: Apply the 'retpoline' mitigation technique. 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-Debbugs-Envelope-To: 30111 X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: <debbugs-submit.debbugs.gnu.org> List-Unsubscribe: <https://debbugs.gnu.org/cgi-bin/mailman/options/debbugs-submit>, <mailto:debbugs-submit-request@debbugs.gnu.org?subject=unsubscribe> List-Archive: <https://debbugs.gnu.org/cgi-bin/mailman/private/debbugs-submit/> List-Post: <mailto:debbugs-submit@debbugs.gnu.org> List-Help: <mailto:debbugs-submit-request@debbugs.gnu.org?subject=help> List-Subscribe: <https://debbugs.gnu.org/cgi-bin/mailman/listinfo/debbugs-submit>, <mailto:debbugs-submit-request@debbugs.gnu.org?subject=subscribe> Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" <debbugs-submit-bounces@debbugs.gnu.org>
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 <alexvong1995@gmail.com> 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 <alexvong1995@gmail.com> > Date: Sun, 14 Jan 2018 20:12:19 +0800 > Subject: [PATCH] gnu: gcc@7: Apply the 'retpoline' mitigation technique. > > This is part of Spectre (branch target injection) [CVE-2017-5715] > mitigation. Suggested by Mark H Weaver <mhw@netris.org>. > > * gnu/local.mk (dist_patch_DATA): Add them. > * gnu/packages/gcc.scm (gcc@7): Use them. > * gnu/packages/patches/gcc-retpoline-Add-indirect_branch-attribute-with-tests.patch, > gnu/packages/patches/gcc-retpoline-Add-mfunction-return-and-function_return-attribute.patch, > gnu/packages/patches/gcc-retpoline-Add-mfunction-return-keep-to-indirect-branch-tests.patch, > gnu/packages/patches/gcc-retpoline-Add-mindirect-branch-loop.patch, > gnu/packages/patches/gcc-retpoline-Add-mindirect-branch-register-and-tests.patch, > gnu/packages/patches/gcc-retpoline-Add-mindirect-branch-thunk-extern.patch, > gnu/packages/patches/gcc-retpoline-Add-mindirect-branch-thunk-inline.patch, > gnu/packages/patches/gcc-retpoline-Add-mindirect-branch-thunk.patch, > gnu/packages/patches/gcc-retpoline-Add-mno-indirect-branch-register-to-indirect-branch-.patch, > gnu/packages/patches/gcc-retpoline-Add-tests-for-mindirect-branch-thunk-fcheck-pointer-.patch, > gnu/packages/patches/gcc-retpoline-Disable-red-zone-with-local-indirect-jump.patch, > gnu/packages/patches/gcc-retpoline-Rename-thunks-to-__x86_indirect_thunk_rax-etc.-to-re.patch, > gnu/packages/patches/gcc-retpoline-Use-__x86.indirect_thunk.reg-for-indirect-branch-via.patch, > gnu/packages/patches/gcc-retpoline-i386-Add-V-register-operand-modifier.patch, > gnu/packages/patches/gcc-retpoline-i386-More-use-reference-of-struct-ix86_frame-to-avoi.patch, > gnu/packages/patches/gcc-retpoline-i386-Move-struct-ix86_frame-to-machine_function.patch, > gnu/packages/patches/gcc-retpoline-i386-Use-reference-of-struct-ix86_frame-to-avoid-cop.patch: > New files. > --- > gnu/local.mk | 19 +- > gnu/packages/gcc.scm | 20 +- > ...-Add-indirect_branch-attribute-with-tests.patch | 475 +++++++++++ > ...tion-return-and-function_return-attribute.patch | 740 ++++++++++++++++ > ...tion-return-keep-to-indirect-branch-tests.patch | 421 ++++++++++ > .../gcc-retpoline-Add-mindirect-branch-loop.patch | 233 ++++++ > ...e-Add-mindirect-branch-register-and-tests.patch | 403 +++++++++ > ...tpoline-Add-mindirect-branch-thunk-extern.patch | 263 ++++++ > ...tpoline-Add-mindirect-branch-thunk-inline.patch | 310 +++++++ > .../gcc-retpoline-Add-mindirect-branch-thunk.patch | 729 ++++++++++++++++ > ...irect-branch-register-to-indirect-branch-.patch | 554 ++++++++++++ > ...or-mindirect-branch-thunk-fcheck-pointer-.patch | 134 +++ > ...Disable-red-zone-with-local-indirect-jump.patch | 147 ++++ > ...ks-to-__x86_indirect_thunk_rax-etc.-to-re.patch | 926 +++++++++++++++++++++ > ...ndirect_thunk.reg-for-indirect-branch-via.patch | 623 ++++++++++++++ > ...line-i386-Add-V-register-operand-modifier.patch | 76 ++ > ...se-reference-of-struct-ix86_frame-to-avoi.patch | 69 ++ > ...ove-struct-ix86_frame-to-machine_function.patch | 249 ++++++ > ...ference-of-struct-ix86_frame-to-avoid-cop.patch | 85 ++ > 19 files changed, 6474 insertions(+), 2 deletions(-) > create mode 100644 gnu/packages/patches/gcc-retpoline-Add-indirect_branch-attribute-with-tests.patch > create mode 100644 gnu/packages/patches/gcc-retpoline-Add-mfunction-return-and-function_return-attribute.patch > create mode 100644 gnu/packages/patches/gcc-retpoline-Add-mfunction-return-keep-to-indirect-branch-tests.patch > create mode 100644 gnu/packages/patches/gcc-retpoline-Add-mindirect-branch-loop.patch > create mode 100644 gnu/packages/patches/gcc-retpoline-Add-mindirect-branch-register-and-tests.patch > create mode 100644 gnu/packages/patches/gcc-retpoline-Add-mindirect-branch-thunk-extern.patch > create mode 100644 gnu/packages/patches/gcc-retpoline-Add-mindirect-branch-thunk-inline.patch > create mode 100644 gnu/packages/patches/gcc-retpoline-Add-mindirect-branch-thunk.patch > create mode 100644 gnu/packages/patches/gcc-retpoline-Add-mno-indirect-branch-register-to-indirect-branch-.patch > create mode 100644 gnu/packages/patches/gcc-retpoline-Add-tests-for-mindirect-branch-thunk-fcheck-pointer-.patch > create mode 100644 gnu/packages/patches/gcc-retpoline-Disable-red-zone-with-local-indirect-jump.patch > create mode 100644 gnu/packages/patches/gcc-retpoline-Rename-thunks-to-__x86_indirect_thunk_rax-etc.-to-re.patch > create mode 100644 gnu/packages/patches/gcc-retpoline-Use-__x86.indirect_thunk.reg-for-indirect-branch-via.patch > create mode 100644 gnu/packages/patches/gcc-retpoline-i386-Add-V-register-operand-modifier.patch > create mode 100644 gnu/packages/patches/gcc-retpoline-i386-More-use-reference-of-struct-ix86_frame-to-avoi.patch > create mode 100644 gnu/packages/patches/gcc-retpoline-i386-Move-struct-ix86_frame-to-machine_function.patch > create mode 100644 gnu/packages/patches/gcc-retpoline-i386-Use-reference-of-struct-ix86_frame-to-avoid-cop.patch > > diff --git a/gnu/local.mk b/gnu/local.mk > index 6af8bfc4b..122e8ef0c 100644 > --- a/gnu/local.mk > +++ b/gnu/local.mk > @@ -9,7 +9,7 @@ > # Copyright © 2016 Adonay "adfeno" Felipe Nogueira <https://libreplanet.org/wiki/User:Adfeno> <adfeno@openmailbox.org> > # Copyright © 2016, 2017 Ricardo Wurmus <rekado@elephly.net> > # Copyright © 2016 Ben Woodcroft <donttrustben@gmail.com> > -# Copyright © 2016, 2017 Alex Vong <alexvong1995@gmail.com> > +# Copyright © 2016, 2017, 2018 Alex Vong <alexvong1995@gmail.com> > # Copyright © 2016, 2017 Efraim Flashner <efraim@flashner.co.il> > # Copyright © 2016, 2017 Jan Nieuwenhuizen <janneke@gnu.org> > # Copyright © 2017 Tobias Geerinckx-Rice <me@tobias.gr> > @@ -652,6 +652,23 @@ dist_patch_DATA = \ > %D%/packages/patches/gcc-asan-powerpc-missing-include.patch \ > %D%/packages/patches/gcc-cross-environment-variables.patch \ > %D%/packages/patches/gcc-libvtv-runpath.patch \ > + %D%/packages/patches/gcc-retpoline-i386-Move-struct-ix86_frame-to-machine_function.patch \ > + %D%/packages/patches/gcc-retpoline-i386-Use-reference-of-struct-ix86_frame-to-avoid-cop.patch \ > + %D%/packages/patches/gcc-retpoline-i386-More-use-reference-of-struct-ix86_frame-to-avoi.patch \ > + %D%/packages/patches/gcc-retpoline-Add-mindirect-branch-thunk.patch \ > + %D%/packages/patches/gcc-retpoline-Add-tests-for-mindirect-branch-thunk-fcheck-pointer-.patch \ > + %D%/packages/patches/gcc-retpoline-Add-mindirect-branch-thunk-inline.patch \ > + %D%/packages/patches/gcc-retpoline-Add-mindirect-branch-thunk-extern.patch \ > + %D%/packages/patches/gcc-retpoline-Add-indirect_branch-attribute-with-tests.patch \ > + %D%/packages/patches/gcc-retpoline-Use-__x86.indirect_thunk.reg-for-indirect-branch-via.patch \ > + %D%/packages/patches/gcc-retpoline-Add-mindirect-branch-loop.patch \ > + %D%/packages/patches/gcc-retpoline-Add-mfunction-return-and-function_return-attribute.patch \ > + %D%/packages/patches/gcc-retpoline-Add-mfunction-return-keep-to-indirect-branch-tests.patch \ > + %D%/packages/patches/gcc-retpoline-Add-mindirect-branch-register-and-tests.patch \ > + %D%/packages/patches/gcc-retpoline-Add-mno-indirect-branch-register-to-indirect-branch-.patch \ > + %D%/packages/patches/gcc-retpoline-Disable-red-zone-with-local-indirect-jump.patch \ > + %D%/packages/patches/gcc-retpoline-i386-Add-V-register-operand-modifier.patch \ > + %D%/packages/patches/gcc-retpoline-Rename-thunks-to-__x86_indirect_thunk_rax-etc.-to-re.patch \ > %D%/packages/patches/gcc-strmov-store-file-names.patch \ > %D%/packages/patches/gcc-4-compile-with-gcc-5.patch \ > %D%/packages/patches/gcc-4.6-gnu-inline.patch \ > diff --git a/gnu/packages/gcc.scm b/gnu/packages/gcc.scm > index ad8992289..6b913aff9 100644 > --- a/gnu/packages/gcc.scm > +++ b/gnu/packages/gcc.scm > @@ -5,6 +5,7 @@ > ;;; Copyright © 2015 Andreas Enge <andreas@enge.fr> > ;;; Copyright © 2015, 2016, 2017 Efraim Flashner <efraim@flashner.co.il> > ;;; Copyright © 2016 Carlos Sánchez de La Lama <csanchezdll@gmail.com> > +;;; Copyright © 2018 ALex Vong <alexvong1995@gmail.com> > ;;; > ;;; This file is part of GNU Guix. > ;;; > @@ -427,7 +428,24 @@ Go. It also includes runtime support libraries for these languages.") > (base32 > "16j7i0888j2f1yp9l0nhji6cq65dy6y4nwy8868a8njbzzwavxqw")) > (patches (search-patches "gcc-strmov-store-file-names.patch" > - "gcc-5.0-libvtv-runpath.patch")))) > + "gcc-5.0-libvtv-runpath.patch" > + "gcc-retpoline-i386-Move-struct-ix86_frame-to-machine_function.patch" > + "gcc-retpoline-i386-Use-reference-of-struct-ix86_frame-to-avoid-cop.patch" > + "gcc-retpoline-i386-More-use-reference-of-struct-ix86_frame-to-avoi.patch" > + "gcc-retpoline-Add-mindirect-branch-thunk.patch" > + "gcc-retpoline-Add-tests-for-mindirect-branch-thunk-fcheck-pointer-.patch" > + "gcc-retpoline-Add-mindirect-branch-thunk-inline.patch" > + "gcc-retpoline-Add-mindirect-branch-thunk-extern.patch" > + "gcc-retpoline-Add-indirect_branch-attribute-with-tests.patch" > + "gcc-retpoline-Use-__x86.indirect_thunk.reg-for-indirect-branch-via.patch" > + "gcc-retpoline-Add-mindirect-branch-loop.patch" > + "gcc-retpoline-Add-mfunction-return-and-function_return-attribute.patch" > + "gcc-retpoline-Add-mfunction-return-keep-to-indirect-branch-tests.patch" > + "gcc-retpoline-Add-mindirect-branch-register-and-tests.patch" > + "gcc-retpoline-Add-mno-indirect-branch-register-to-indirect-branch-.patch" > + "gcc-retpoline-Disable-red-zone-with-local-indirect-jump.patch" > + "gcc-retpoline-i386-Add-V-register-operand-modifier.patch" > + "gcc-retpoline-Rename-thunks-to-__x86_indirect_thunk_rax-etc.-to-re.patch")))) > (description > "GCC is the GNU Compiler Collection. It provides compiler front-ends > for several languages, including C, C++, Objective-C, Fortran, Ada, and Go. > diff --git a/gnu/packages/patches/gcc-retpoline-Add-indirect_branch-attribute-with-tests.patch b/gnu/packages/patches/gcc-retpoline-Add-indirect_branch-attribute-with-tests.patch > new file mode 100644 > index 000000000..5129a8273 > --- /dev/null > +++ b/gnu/packages/patches/gcc-retpoline-Add-indirect_branch-attribute-with-tests.patch > @@ -0,0 +1,475 @@ > +'Retpoline' mitigation technique for Spectre (branch target injection) > +[CVE-2017-5715]: > + > +https://security.googleblog.com/2018/01/more-details-about-mitigations-for-cpu_4.html > +https://support.google.com/faqs/answer/7625886 > +https://spectreattack.com/ > +https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2017-5715 > + > +Patch copied from the 'retpoline-20180107' branch of upstream source repository > +(please add new / update existing patches when new 'retpoline-xxxxxxxx' branch > +appears): > + > +http://git.infradead.org/users/dwmw2/gcc-retpoline.git > + > +From e9794727bb0384be6d27ad1edaefc71c23cc0d86 Mon Sep 17 00:00:00 2001 > +From: "H.J. Lu" <hjl.tools@gmail.com> > +Date: Tue, 28 Nov 2017 06:10:39 -0800 > +Subject: [PATCH 08/17] Add indirect_branch attribute with tests > + > +__attribute__ ((indirect_branch("thunk"))) > +__attribute__ ((indirect_branch("thunk-inline"))) > +__attribute__ ((indirect_branch("thunk-extern"))) > +__attribute__ ((indirect_branch("keep"))) > +--- > + gcc/config/i386/i386-opts.h | 1 + > + gcc/config/i386/i386.c | 74 ++++++++++++++++++++-- > + gcc/config/i386/i386.h | 3 + > + .../gcc.target/i386/indirect-thunk-attr-1.c | 22 +++++++ > + .../gcc.target/i386/indirect-thunk-attr-2.c | 20 ++++++ > + .../gcc.target/i386/indirect-thunk-attr-3.c | 21 ++++++ > + .../gcc.target/i386/indirect-thunk-attr-4.c | 20 ++++++ > + .../gcc.target/i386/indirect-thunk-attr-5.c | 22 +++++++ > + .../gcc.target/i386/indirect-thunk-attr-6.c | 21 ++++++ > + .../gcc.target/i386/indirect-thunk-attr-7.c | 44 +++++++++++++ > + .../gcc.target/i386/indirect-thunk-attr-8.c | 41 ++++++++++++ > + 11 files changed, 283 insertions(+), 6 deletions(-) > + create mode 100644 gcc/testsuite/gcc.target/i386/indirect-thunk-attr-1.c > + create mode 100644 gcc/testsuite/gcc.target/i386/indirect-thunk-attr-2.c > + create mode 100644 gcc/testsuite/gcc.target/i386/indirect-thunk-attr-3.c > + create mode 100644 gcc/testsuite/gcc.target/i386/indirect-thunk-attr-4.c > + create mode 100644 gcc/testsuite/gcc.target/i386/indirect-thunk-attr-5.c > + create mode 100644 gcc/testsuite/gcc.target/i386/indirect-thunk-attr-6.c > + create mode 100644 gcc/testsuite/gcc.target/i386/indirect-thunk-attr-7.c > + create mode 100644 gcc/testsuite/gcc.target/i386/indirect-thunk-attr-8.c > + > +diff --git a/gcc/config/i386/i386-opts.h b/gcc/config/i386/i386-opts.h > +index f8d80ba7ec6..9e56d7f2d12 100644 > +--- a/gcc/config/i386/i386-opts.h > ++++ b/gcc/config/i386/i386-opts.h > +@@ -100,6 +100,7 @@ enum stack_protector_guard { > + }; > + > + enum indirect_branch { > ++ indirect_branch_unset = 0, > + indirect_branch_keep, > + indirect_branch_thunk, > + indirect_branch_thunk_inline, > +diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c > +index ac542f79846..5e66af08066 100644 > +--- a/gcc/config/i386/i386.c > ++++ b/gcc/config/i386/i386.c > +@@ -7137,6 +7137,37 @@ ix86_set_func_type (tree fndecl) > + } > + } > + > ++/* Set the indirect_branch_type field from the function FNDECL. */ > ++ > ++static void > ++ix86_set_indirect_branch_type (tree fndecl) > ++{ > ++ if (cfun->machine->indirect_branch_type == indirect_branch_unset) > ++ { > ++ tree attr = lookup_attribute ("indirect_branch", > ++ DECL_ATTRIBUTES (fndecl)); > ++ if (attr != NULL) > ++ { > ++ tree args = TREE_VALUE (attr); > ++ if (args == NULL) > ++ gcc_unreachable (); > ++ tree cst = TREE_VALUE (args); > ++ if (strcmp (TREE_STRING_POINTER (cst), "keep") == 0) > ++ cfun->machine->indirect_branch_type = indirect_branch_keep; > ++ else if (strcmp (TREE_STRING_POINTER (cst), "thunk") == 0) > ++ cfun->machine->indirect_branch_type = indirect_branch_thunk; > ++ else if (strcmp (TREE_STRING_POINTER (cst), "thunk-inline") == 0) > ++ cfun->machine->indirect_branch_type = indirect_branch_thunk_inline; > ++ else if (strcmp (TREE_STRING_POINTER (cst), "thunk-extern") == 0) > ++ cfun->machine->indirect_branch_type = indirect_branch_thunk_extern; > ++ else > ++ gcc_unreachable (); > ++ } > ++ else > ++ cfun->machine->indirect_branch_type = ix86_indirect_branch; > ++ } > ++} > ++ > + /* Establish appropriate back-end context for processing the function > + FNDECL. The argument might be NULL to indicate processing at top > + level, outside of any function scope. */ > +@@ -7152,7 +7183,10 @@ ix86_set_current_function (tree fndecl) > + one is extern inline and one isn't. Call ix86_set_func_type > + to set the func_type field. */ > + if (fndecl != NULL_TREE) > +- ix86_set_func_type (fndecl); > ++ { > ++ ix86_set_func_type (fndecl); > ++ ix86_set_indirect_branch_type (fndecl); > ++ } > + return; > + } > + > +@@ -7172,6 +7206,7 @@ ix86_set_current_function (tree fndecl) > + } > + > + ix86_set_func_type (fndecl); > ++ ix86_set_indirect_branch_type (fndecl); > + > + tree new_tree = DECL_FUNCTION_SPECIFIC_TARGET (fndecl); > + if (new_tree == NULL_TREE) > +@@ -28605,9 +28640,11 @@ ix86_output_indirect_branch (rtx call_op, const char *xasm, > + char push_buf[64]; > + bool need_bnd_p = ix86_bnd_prefixed_insn_p (current_output_insn); > + > +- if (ix86_indirect_branch != indirect_branch_thunk_inline) > ++ if (cfun->machine->indirect_branch_type > ++ != indirect_branch_thunk_inline) > + { > +- bool need_thunk = ix86_indirect_branch == indirect_branch_thunk; > ++ bool need_thunk > ++ = cfun->machine->indirect_branch_type == indirect_branch_thunk; > + if (need_bnd_p) > + indirect_thunk_bnd_needed |= need_thunk; > + else > +@@ -28716,7 +28753,7 @@ const char * > + ix86_output_indirect_jmp (rtx call_op) > + { > + if (ix86_red_zone_size == 0 > +- && ix86_indirect_branch != indirect_branch_keep) > ++ && cfun->machine->indirect_branch_type != indirect_branch_keep) > + { > + ix86_output_indirect_branch (call_op, "%0", true); > + return ""; > +@@ -28733,7 +28770,7 @@ ix86_output_call_insn (rtx_insn *insn, rtx call_op) > + bool direct_p = constant_call_address_operand (call_op, VOIDmode); > + bool output_indirect_p > + = (!TARGET_SEH > +- && ix86_indirect_branch != indirect_branch_keep); > ++ && cfun->machine->indirect_branch_type != indirect_branch_keep); > + bool seh_nop_p = false; > + const char *xasm; > + > +@@ -41749,7 +41786,7 @@ ix86_handle_struct_attribute (tree *node, tree name, tree, int, > + } > + > + static tree > +-ix86_handle_fndecl_attribute (tree *node, tree name, tree, int, > ++ix86_handle_fndecl_attribute (tree *node, tree name, tree args, int, > + bool *no_add_attrs) > + { > + if (TREE_CODE (*node) != FUNCTION_DECL) > +@@ -41758,6 +41795,29 @@ ix86_handle_fndecl_attribute (tree *node, tree name, tree, int, > + name); > + *no_add_attrs = true; > + } > ++ > ++ if (is_attribute_p ("indirect_branch", name)) > ++ { > ++ tree cst = TREE_VALUE (args); > ++ if (TREE_CODE (cst) != STRING_CST) > ++ { > ++ warning (OPT_Wattributes, > ++ "%qE attribute requires a string constant argument", > ++ name); > ++ *no_add_attrs = true; > ++ } > ++ else if (strcmp (TREE_STRING_POINTER (cst), "keep") != 0 > ++ && strcmp (TREE_STRING_POINTER (cst), "thunk") != 0 > ++ && strcmp (TREE_STRING_POINTER (cst), "thunk-inline") != 0 > ++ && strcmp (TREE_STRING_POINTER (cst), "thunk-extern") != 0) > ++ { > ++ warning (OPT_Wattributes, > ++ "argument to %qE attribute is not " > ++ "(keep|thunk|thunk-inline|thunk-extern)", name); > ++ *no_add_attrs = true; > ++ } > ++ } > ++ > + return NULL_TREE; > + } > + > +@@ -46052,6 +46112,8 @@ static const struct attribute_spec ix86_attribute_table[] = > + ix86_handle_interrupt_attribute, false }, > + { "no_caller_saved_registers", 0, 0, false, true, true, > + ix86_handle_no_caller_saved_registers_attribute, false }, > ++ { "indirect_branch", 1, 1, true, false, false, > ++ ix86_handle_fndecl_attribute, false }, > + > + /* End element. */ > + { NULL, 0, 0, false, false, false, NULL, false } > +diff --git a/gcc/config/i386/i386.h b/gcc/config/i386/i386.h > +index 7d9f9020fb3..a9c199a107c 100644 > +--- a/gcc/config/i386/i386.h > ++++ b/gcc/config/i386/i386.h > +@@ -2604,6 +2604,9 @@ struct GTY(()) machine_function { > + /* Function type. */ > + ENUM_BITFIELD(function_type) func_type : 2; > + > ++ /* How to generate indirec branch. */ > ++ ENUM_BITFIELD(indirect_branch) indirect_branch_type : 3; > ++ > + /* If true, the current function is a function specified with > + the "interrupt" or "no_caller_saved_registers" attribute. */ > + BOOL_BITFIELD no_caller_saved_registers : 1; > +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-1.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-1.c > +new file mode 100644 > +index 00000000000..26550fad4c8 > +--- /dev/null > ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-1.c > +@@ -0,0 +1,22 @@ > ++/* { dg-do compile } */ > ++/* { dg-options "-O2 -fno-pic" } */ > ++ > ++typedef void (*dispatch_t)(long offset); > ++ > ++dispatch_t dispatch; > ++ > ++extern void male_indirect_jump (long) > ++ __attribute__ ((indirect_branch("thunk"))); > ++ > ++void > ++male_indirect_jump (long offset) > ++{ > ++ dispatch(offset); > ++} > ++ > ++/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { ! x32 } } } } */ > ++/* { dg-final { scan-assembler "pushq\[ \t\]%rax" { target x32 } } } */ > ++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" } } */ > ++/* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */ > ++/* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */ > ++/* { dg-final { scan-assembler {\tlfence} } } */ > +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-2.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-2.c > +new file mode 100644 > +index 00000000000..f57bb2a92d6 > +--- /dev/null > ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-2.c > +@@ -0,0 +1,20 @@ > ++/* { dg-do compile } */ > ++/* { dg-options "-O2 -fno-pic" } */ > ++ > ++typedef void (*dispatch_t)(long offset); > ++ > ++dispatch_t dispatch[256]; > ++ > ++__attribute__ ((indirect_branch("thunk"))) > ++void > ++male_indirect_jump (long offset) > ++{ > ++ dispatch[offset](offset); > ++} > ++ > ++/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { ! x32 } } } } */ > ++/* { dg-final { scan-assembler "pushq\[ \t\]%rax" { target x32 } } } */ > ++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" } } */ > ++/* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */ > ++/* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */ > ++/* { dg-final { scan-assembler {\tlfence} } } */ > +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-3.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-3.c > +new file mode 100644 > +index 00000000000..a3668a6586c > +--- /dev/null > ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-3.c > +@@ -0,0 +1,21 @@ > ++/* { dg-do compile } */ > ++/* { dg-options "-O2 -fno-pic" } */ > ++ > ++typedef void (*dispatch_t)(long offset); > ++ > ++dispatch_t dispatch; > ++extern int male_indirect_jump (long) > ++ __attribute__ ((indirect_branch("thunk-inline"))); > ++ > ++int > ++male_indirect_jump (long offset) > ++{ > ++ dispatch(offset); > ++ return 0; > ++} > ++ > ++/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { ! x32 } } } } */ > ++/* { dg-final { scan-assembler "pushq\[ \t\]%rax" { target x32 } } } */ > ++/* { dg-final { scan-assembler-times "jmp\[ \t\]*\.LIND" 2 } } */ > ++/* { dg-final { scan-assembler-times "call\[ \t\]*\.LIND" 2 } } */ > ++/* { dg-final { scan-assembler-not "__x86.indirect_thunk" } } */ > +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-4.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-4.c > +new file mode 100644 > +index 00000000000..a9c4a137dd4 > +--- /dev/null > ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-4.c > +@@ -0,0 +1,20 @@ > ++/* { dg-do compile } */ > ++/* { dg-options "-O2 -fno-pic" } */ > ++ > ++typedef void (*dispatch_t)(long offset); > ++ > ++dispatch_t dispatch[256]; > ++ > ++__attribute__ ((indirect_branch("thunk-inline"))) > ++int > ++male_indirect_jump (long offset) > ++{ > ++ dispatch[offset](offset); > ++ return 0; > ++} > ++ > ++/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { ! x32 } } } } */ > ++/* { dg-final { scan-assembler "pushq\[ \t\]%rax" { target x32 } } } */ > ++/* { dg-final { scan-assembler-times "jmp\[ \t\]*\.LIND" 2 } } */ > ++/* { dg-final { scan-assembler-times "call\[ \t\]*\.LIND" 2 } } */ > ++/* { dg-final { scan-assembler-not "__x86.indirect_thunk" } } */ > +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-5.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-5.c > +new file mode 100644 > +index 00000000000..9582e0c5824 > +--- /dev/null > ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-5.c > +@@ -0,0 +1,22 @@ > ++/* { dg-do compile } */ > ++/* { dg-options "-O2 -fno-pic" } */ > ++ > ++typedef void (*dispatch_t)(long offset); > ++ > ++dispatch_t dispatch; > ++extern int male_indirect_jump (long) > ++ __attribute__ ((indirect_branch("thunk-extern"))); > ++ > ++int > ++male_indirect_jump (long offset) > ++{ > ++ dispatch(offset); > ++ return 0; > ++} > ++ > ++/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { ! x32 } } } } */ > ++/* { dg-final { scan-assembler "pushq\[ \t\]%rax" { target x32 } } } */ > ++/* { dg-final { scan-assembler-times "jmp\[ \t\]*\.LIND" 1 } } */ > ++/* { dg-final { scan-assembler-times "call\[ \t\]*\.LIND" 1 } } */ > ++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" } } */ > ++/* { dg-final { scan-assembler-not {\t(lfence|pause)} } } */ > +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-6.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-6.c > +new file mode 100644 > +index 00000000000..66442cacfe8 > +--- /dev/null > ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-6.c > +@@ -0,0 +1,21 @@ > ++/* { dg-do compile } */ > ++/* { dg-options "-O2 -fno-pic" } */ > ++ > ++typedef void (*dispatch_t)(long offset); > ++ > ++dispatch_t dispatch[256]; > ++ > ++__attribute__ ((indirect_branch("thunk-extern"))) > ++int > ++male_indirect_jump (long offset) > ++{ > ++ dispatch[offset](offset); > ++ return 0; > ++} > ++ > ++/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { ! x32 } } } } */ > ++/* { dg-final { scan-assembler "pushq\[ \t\]%rax" { target x32 } } } */ > ++/* { dg-final { scan-assembler-times "jmp\[ \t\]*\.LIND" 1 } } */ > ++/* { dg-final { scan-assembler-times "call\[ \t\]*\.LIND" 1 } } */ > ++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" } } */ > ++/* { dg-final { scan-assembler-not {\t(lfence|pause)} } } */ > +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-7.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-7.c > +new file mode 100644 > +index 00000000000..2a19b54cd2e > +--- /dev/null > ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-7.c > +@@ -0,0 +1,44 @@ > ++/* { dg-do compile } */ > ++/* { dg-options "-O2 -fno-pic" } */ > ++ > ++void func0 (void); > ++void func1 (void); > ++void func2 (void); > ++void func3 (void); > ++void func4 (void); > ++void func4 (void); > ++void func5 (void); > ++ > ++__attribute__ ((indirect_branch("thunk-extern"))) > ++void > ++bar (int i) > ++{ > ++ switch (i) > ++ { > ++ default: > ++ func0 (); > ++ break; > ++ case 1: > ++ func1 (); > ++ break; > ++ case 2: > ++ func2 (); > ++ break; > ++ case 3: > ++ func3 (); > ++ break; > ++ case 4: > ++ func4 (); > ++ break; > ++ case 5: > ++ func5 (); > ++ break; > ++ } > ++} > ++ > ++/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*\.L\[0-9\]+\\(,%" { target { ! x32 } } } } */ > ++/* { dg-final { scan-assembler "pushq\[ \t\]%rax" { target x32 } } } */ > ++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" } } */ > ++/* { dg-final { scan-assembler-not {\t(lfence|pause)} } } */ > ++/* { dg-final { scan-assembler-not "jmp\[ \t\]*\.LIND" } } */ > ++/* { dg-final { scan-assembler-not "call\[ \t\]*\.LIND" } } */ > +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-8.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-8.c > +new file mode 100644 > +index 00000000000..9f6d12d74a1 > +--- /dev/null > ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-8.c > +@@ -0,0 +1,41 @@ > ++/* { dg-do compile } */ > ++/* { dg-options "-O2 -mindirect-branch=thunk -fno-pic" } */ > ++ > ++void func0 (void); > ++void func1 (void); > ++void func2 (void); > ++void func3 (void); > ++void func4 (void); > ++void func4 (void); > ++void func5 (void); > ++ > ++__attribute__ ((indirect_branch("keep"))) > ++void > ++bar (int i) > ++{ > ++ switch (i) > ++ { > ++ default: > ++ func0 (); > ++ break; > ++ case 1: > ++ func1 (); > ++ break; > ++ case 2: > ++ func2 (); > ++ break; > ++ case 3: > ++ func3 (); > ++ break; > ++ case 4: > ++ func4 (); > ++ break; > ++ case 5: > ++ func5 (); > ++ break; > ++ } > ++} > ++ > ++/* { dg-final { scan-assembler-not "__x86.indirect_thunk" } } */ > ++/* { dg-final { scan-assembler-not "jmp\[ \t\]*\.LIND" } } */ > ++/* { dg-final { scan-assembler-not "call\[ \t\]*\.LIND" } } */ > +-- > +2.15.1 > + > diff --git a/gnu/packages/patches/gcc-retpoline-Add-mfunction-return-and-function_return-attribute.patch b/gnu/packages/patches/gcc-retpoline-Add-mfunction-return-and-function_return-attribute.patch > new file mode 100644 > index 000000000..0845de4b2 > --- /dev/null > +++ b/gnu/packages/patches/gcc-retpoline-Add-mfunction-return-and-function_return-attribute.patch > @@ -0,0 +1,740 @@ > +'Retpoline' mitigation technique for Spectre (branch target injection) > +[CVE-2017-5715]: > + > +https://security.googleblog.com/2018/01/more-details-about-mitigations-for-cpu_4.html > +https://support.google.com/faqs/answer/7625886 > +https://spectreattack.com/ > +https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2017-5715 > + > +Patch copied from the 'retpoline-20180107' branch of upstream source repository > +(please add new / update existing patches when new 'retpoline-xxxxxxxx' branch > +appears): > + > +http://git.infradead.org/users/dwmw2/gcc-retpoline.git > + > +From 29d5a3f23c18c96944dd3230a41380a6edcd25fd Mon Sep 17 00:00:00 2001 > +From: "H.J. Lu" <hjl.tools@gmail.com> > +Date: Tue, 5 Dec 2017 13:29:06 -0800 > +Subject: [PATCH 11/17] Add -mfunction-return= and function_return attribute > + > +Add -mfunction-return= and function_return attribute tests > + > +-mfunction-return=thunk > + Convert function return instruction to PC-relative call thunk. > +-mfunction-return=thunk-inline > + Convert function return instruction to PC-relative call thunk with > + thunk inlined. > +-mfunction-return=thunk-extern > + Convert function return instruction to PC-relative call to external > + thunk. > + > +Add function_return attribute to function declaration > + > +__attribute__ ((function_return("thunk"))) > +__attribute__ ((function_return("thunk-inline"))) > +__attribute__ ((function_return("thunk-extern"))) > +__attribute__ ((function_return("keep"))) > +--- > + gcc/config/i386/i386-protos.h | 1 + > + gcc/config/i386/i386.c | 146 +++++++++++++++++++++++++-- > + gcc/config/i386/i386.h | 3 + > + gcc/config/i386/i386.md | 9 +- > + gcc/config/i386/i386.opt | 6 +- > + gcc/testsuite/gcc.target/i386/ret-thunk-1.c | 12 +++ > + gcc/testsuite/gcc.target/i386/ret-thunk-10.c | 22 ++++ > + gcc/testsuite/gcc.target/i386/ret-thunk-11.c | 22 ++++ > + gcc/testsuite/gcc.target/i386/ret-thunk-12.c | 21 ++++ > + gcc/testsuite/gcc.target/i386/ret-thunk-13.c | 21 ++++ > + gcc/testsuite/gcc.target/i386/ret-thunk-14.c | 21 ++++ > + gcc/testsuite/gcc.target/i386/ret-thunk-15.c | 21 ++++ > + gcc/testsuite/gcc.target/i386/ret-thunk-16.c | 18 ++++ > + gcc/testsuite/gcc.target/i386/ret-thunk-2.c | 12 +++ > + gcc/testsuite/gcc.target/i386/ret-thunk-3.c | 12 +++ > + gcc/testsuite/gcc.target/i386/ret-thunk-4.c | 12 +++ > + gcc/testsuite/gcc.target/i386/ret-thunk-5.c | 14 +++ > + gcc/testsuite/gcc.target/i386/ret-thunk-6.c | 13 +++ > + gcc/testsuite/gcc.target/i386/ret-thunk-7.c | 13 +++ > + gcc/testsuite/gcc.target/i386/ret-thunk-8.c | 14 +++ > + gcc/testsuite/gcc.target/i386/ret-thunk-9.c | 23 +++++ > + 21 files changed, 421 insertions(+), 15 deletions(-) > + create mode 100644 gcc/testsuite/gcc.target/i386/ret-thunk-1.c > + create mode 100644 gcc/testsuite/gcc.target/i386/ret-thunk-10.c > + create mode 100644 gcc/testsuite/gcc.target/i386/ret-thunk-11.c > + create mode 100644 gcc/testsuite/gcc.target/i386/ret-thunk-12.c > + create mode 100644 gcc/testsuite/gcc.target/i386/ret-thunk-13.c > + create mode 100644 gcc/testsuite/gcc.target/i386/ret-thunk-14.c > + create mode 100644 gcc/testsuite/gcc.target/i386/ret-thunk-15.c > + create mode 100644 gcc/testsuite/gcc.target/i386/ret-thunk-16.c > + create mode 100644 gcc/testsuite/gcc.target/i386/ret-thunk-2.c > + create mode 100644 gcc/testsuite/gcc.target/i386/ret-thunk-3.c > + create mode 100644 gcc/testsuite/gcc.target/i386/ret-thunk-4.c > + create mode 100644 gcc/testsuite/gcc.target/i386/ret-thunk-5.c > + create mode 100644 gcc/testsuite/gcc.target/i386/ret-thunk-6.c > + create mode 100644 gcc/testsuite/gcc.target/i386/ret-thunk-7.c > + create mode 100644 gcc/testsuite/gcc.target/i386/ret-thunk-8.c > + create mode 100644 gcc/testsuite/gcc.target/i386/ret-thunk-9.c > + > +diff --git a/gcc/config/i386/i386-protos.h b/gcc/config/i386/i386-protos.h > +index b746429f420..213663811de 100644 > +--- a/gcc/config/i386/i386-protos.h > ++++ b/gcc/config/i386/i386-protos.h > +@@ -316,6 +316,7 @@ extern enum attr_cpu ix86_schedule; > + > + extern const char * ix86_output_call_insn (rtx_insn *insn, rtx call_op); > + extern const char * ix86_output_indirect_jmp (rtx call_op); > ++extern const char * ix86_output_function_return (bool long_p); > + extern bool ix86_operands_ok_for_move_multiple (rtx *operands, bool load, > + enum machine_mode mode); > + > +diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c > +index be1ff4752a9..7ae3523095c 100644 > +--- a/gcc/config/i386/i386.c > ++++ b/gcc/config/i386/i386.c > +@@ -7166,6 +7166,31 @@ ix86_set_indirect_branch_type (tree fndecl) > + else > + cfun->machine->indirect_branch_type = ix86_indirect_branch; > + } > ++ > ++ if (cfun->machine->function_return_type == indirect_branch_unset) > ++ { > ++ tree attr = lookup_attribute ("function_return", > ++ DECL_ATTRIBUTES (fndecl)); > ++ if (attr != NULL) > ++ { > ++ tree args = TREE_VALUE (attr); > ++ if (args == NULL) > ++ gcc_unreachable (); > ++ tree cst = TREE_VALUE (args); > ++ if (strcmp (TREE_STRING_POINTER (cst), "keep") == 0) > ++ cfun->machine->function_return_type = indirect_branch_keep; > ++ else if (strcmp (TREE_STRING_POINTER (cst), "thunk") == 0) > ++ cfun->machine->function_return_type = indirect_branch_thunk; > ++ else if (strcmp (TREE_STRING_POINTER (cst), "thunk-inline") == 0) > ++ cfun->machine->function_return_type = indirect_branch_thunk_inline; > ++ else if (strcmp (TREE_STRING_POINTER (cst), "thunk-extern") == 0) > ++ cfun->machine->function_return_type = indirect_branch_thunk_extern; > ++ else > ++ gcc_unreachable (); > ++ } > ++ else > ++ cfun->machine->function_return_type = ix86_function_return; > ++ } > + } > + > + /* Establish appropriate back-end context for processing the function > +@@ -11958,8 +11983,12 @@ static int indirect_thunks_bnd_used; > + /* Fills in the label name that should be used for the indirect thunk. */ > + > + static void > +-indirect_thunk_name (char name[32], int regno, bool need_bnd_p) > ++indirect_thunk_name (char name[32], int regno, bool need_bnd_p, > ++ bool ret_p) > + { > ++ if (regno >= 0 && ret_p) > ++ gcc_unreachable (); > ++ > + if (USE_HIDDEN_LINKONCE) > + { > + const char *bnd = need_bnd_p ? "_bnd" : ""; > +@@ -11974,7 +12003,10 @@ indirect_thunk_name (char name[32], int regno, bool need_bnd_p) > + bnd, reg_prefix, reg_names[regno]); > + } > + else > +- sprintf (name, "__x86.indirect_thunk%s", bnd); > ++ { > ++ const char *ret = ret_p ? "return" : "indirect"; > ++ sprintf (name, "__x86.%s_thunk%s", ret, bnd); > ++ } > + } > + else > + { > +@@ -11987,10 +12019,20 @@ indirect_thunk_name (char name[32], int regno, bool need_bnd_p) > + } > + else > + { > +- if (need_bnd_p) > +- ASM_GENERATE_INTERNAL_LABEL (name, "LITB", 0); > ++ if (ret_p) > ++ { > ++ if (need_bnd_p) > ++ ASM_GENERATE_INTERNAL_LABEL (name, "LRTB", 0); > ++ else > ++ ASM_GENERATE_INTERNAL_LABEL (name, "LRT", 0); > ++ } > + else > +- ASM_GENERATE_INTERNAL_LABEL (name, "LIT", 0); > ++ { > ++ if (need_bnd_p) > ++ ASM_GENERATE_INTERNAL_LABEL (name, "LITB", 0); > ++ else > ++ ASM_GENERATE_INTERNAL_LABEL (name, "LIT", 0); > ++ } > + } > + } > + } > +@@ -12071,7 +12113,7 @@ output_indirect_thunk_function (bool need_bnd_p, int regno) > + tree decl; > + > + /* Create __x86.indirect_thunk/__x86.indirect_thunk_bnd. */ > +- indirect_thunk_name (name, regno, need_bnd_p); > ++ indirect_thunk_name (name, regno, need_bnd_p, false); > + decl = build_decl (BUILTINS_LOCATION, FUNCTION_DECL, > + get_identifier (name), > + build_function_type_list (void_type_node, NULL_TREE)); > +@@ -12114,6 +12156,35 @@ output_indirect_thunk_function (bool need_bnd_p, int regno) > + ASM_OUTPUT_LABEL (asm_out_file, name); > + } > + > ++ if (regno < 0) > ++ { > ++ /* Create alias for __x86.return_thunk/__x86.return_thunk_bnd. */ > ++ char alias[32]; > ++ > ++ indirect_thunk_name (alias, regno, need_bnd_p, true); > ++ ASM_OUTPUT_DEF (asm_out_file, alias, name); > ++#if TARGET_MACHO > ++ if (TARGET_MACHO) > ++ { > ++ fputs ("\t.weak_definition\t", asm_out_file); > ++ assemble_name (asm_out_file, alias); > ++ fputs ("\n\t.private_extern\t", asm_out_file); > ++ assemble_name (asm_out_file, alias); > ++ putc ('\n', asm_out_file); > ++ } > ++#else > ++ if (USE_HIDDEN_LINKONCE) > ++ { > ++ fputs ("\t.globl\t", asm_out_file); > ++ assemble_name (asm_out_file, alias); > ++ putc ('\n', asm_out_file); > ++ fputs ("\t.hidden\t", asm_out_file); > ++ assemble_name (asm_out_file, alias); > ++ putc ('\n', asm_out_file); > ++ } > ++#endif > ++ } > ++ > + DECL_INITIAL (decl) = make_node (BLOCK); > + current_function_decl = decl; > + allocate_struct_function (decl, false); > +@@ -28736,7 +28807,7 @@ ix86_output_indirect_branch (rtx call_op, const char *xasm, > + indirect_thunk_needed = true; > + } > + } > +- indirect_thunk_name (thunk_name_buf, regno, need_bnd_p); > ++ indirect_thunk_name (thunk_name_buf, regno, need_bnd_p, false); > + thunk_name = thunk_name_buf; > + } > + else > +@@ -28860,6 +28931,43 @@ ix86_output_indirect_jmp (rtx call_op) > + return "%!jmp\t%A0"; > + } > + > ++const char * > ++ix86_output_function_return (bool long_p) > ++{ > ++ if (cfun->machine->function_return_type != indirect_branch_keep) > ++ { > ++ char thunk_name[32]; > ++ bool need_bnd_p = ix86_bnd_prefixed_insn_p (current_output_insn); > ++ > ++ if (cfun->machine->function_return_type > ++ != indirect_branch_thunk_inline) > ++ { > ++ bool need_thunk = (cfun->machine->function_return_type > ++ == indirect_branch_thunk); > ++ indirect_thunk_name (thunk_name, -1, need_bnd_p, true); > ++ if (need_bnd_p) > ++ { > ++ indirect_thunk_bnd_needed |= need_thunk; > ++ fprintf (asm_out_file, "\tbnd jmp\t%s\n", thunk_name); > ++ } > ++ else > ++ { > ++ indirect_thunk_needed |= need_thunk; > ++ fprintf (asm_out_file, "\tjmp\t%s\n", thunk_name); > ++ } > ++ } > ++ else > ++ output_indirect_thunk (need_bnd_p, -1); > ++ > ++ return ""; > ++ } > ++ > ++ if (!long_p || ix86_bnd_prefixed_insn_p (current_output_insn)) > ++ return "%!ret"; > ++ > ++ return "rep%; ret"; > ++} > ++ > + /* Output the assembly for a call instruction. */ > + > + const char * > +@@ -41916,6 +42024,28 @@ ix86_handle_fndecl_attribute (tree *node, tree name, tree args, int, > + } > + } > + > ++ if (is_attribute_p ("function_return", name)) > ++ { > ++ tree cst = TREE_VALUE (args); > ++ if (TREE_CODE (cst) != STRING_CST) > ++ { > ++ warning (OPT_Wattributes, > ++ "%qE attribute requires a string constant argument", > ++ name); > ++ *no_add_attrs = true; > ++ } > ++ else if (strcmp (TREE_STRING_POINTER (cst), "keep") != 0 > ++ && strcmp (TREE_STRING_POINTER (cst), "thunk") != 0 > ++ && strcmp (TREE_STRING_POINTER (cst), "thunk-inline") != 0 > ++ && strcmp (TREE_STRING_POINTER (cst), "thunk-extern") != 0) > ++ { > ++ warning (OPT_Wattributes, > ++ "argument to %qE attribute is not " > ++ "(keep|thunk|thunk-inline|thunk-extern)", name); > ++ *no_add_attrs = true; > ++ } > ++ } > ++ > + return NULL_TREE; > + } > + > +@@ -46212,6 +46342,8 @@ static const struct attribute_spec ix86_attribute_table[] = > + ix86_handle_no_caller_saved_registers_attribute, false }, > + { "indirect_branch", 1, 1, true, false, false, > + ix86_handle_fndecl_attribute, false }, > ++ { "function_return", 1, 1, true, false, false, > ++ ix86_handle_fndecl_attribute, false }, > + > + /* End element. */ > + { NULL, 0, 0, false, false, false, NULL, false } > +diff --git a/gcc/config/i386/i386.h b/gcc/config/i386/i386.h > +index a9c199a107c..f248f3ba2f5 100644 > +--- a/gcc/config/i386/i386.h > ++++ b/gcc/config/i386/i386.h > +@@ -2607,6 +2607,9 @@ struct GTY(()) machine_function { > + /* How to generate indirec branch. */ > + ENUM_BITFIELD(indirect_branch) indirect_branch_type : 3; > + > ++ /* How to generate function return. */ > ++ ENUM_BITFIELD(indirect_branch) function_return_type : 3; > ++ > + /* If true, the current function is a function specified with > + the "interrupt" or "no_caller_saved_registers" attribute. */ > + BOOL_BITFIELD no_caller_saved_registers : 1; > +diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md > +index 01b7b2039e6..00a9afef225 100644 > +--- a/gcc/config/i386/i386.md > ++++ b/gcc/config/i386/i386.md > +@@ -12288,7 +12288,7 @@ > + (define_insn "simple_return_internal" > + [(simple_return)] > + "reload_completed" > +- "%!ret" > ++ "* return ix86_output_function_return (false);" > + [(set_attr "length" "1") > + (set_attr "atom_unit" "jeu") > + (set_attr "length_immediate" "0") > +@@ -12310,12 +12310,7 @@ > + [(simple_return) > + (unspec [(const_int 0)] UNSPEC_REP)] > + "reload_completed" > +-{ > +- if (ix86_bnd_prefixed_insn_p (insn)) > +- return "%!ret"; > +- > +- return "rep%; ret"; > +-} > ++ "* return ix86_output_function_return (true);" > + [(set_attr "length" "2") > + (set_attr "atom_unit" "jeu") > + (set_attr "length_immediate" "0") > +diff --git a/gcc/config/i386/i386.opt b/gcc/config/i386/i386.opt > +index bc81e6bea86..fc2c81c3fb5 100644 > +--- a/gcc/config/i386/i386.opt > ++++ b/gcc/config/i386/i386.opt > +@@ -932,9 +932,13 @@ mindirect-branch= > + Target Report RejectNegative Joined Enum(indirect_branch) Var(ix86_indirect_branch) Init(indirect_branch_keep) > + Update indirect call and jump. > + > ++mfunction-return= > ++Target Report RejectNegative Joined Enum(indirect_branch) Var(ix86_function_return) Init(indirect_branch_keep) > ++Update function return. > ++ > + Enum > + Name(indirect_branch) Type(enum indirect_branch) > +-Known indirect branch choices (for use with the -mindirect-branch= option): > ++Known indirect branch choices (for use with the -mindirect-branch=/-mfunction-return= options): > + > + EnumValue > + Enum(indirect_branch) String(keep) Value(indirect_branch_keep) > +diff --git a/gcc/testsuite/gcc.target/i386/ret-thunk-1.c b/gcc/testsuite/gcc.target/i386/ret-thunk-1.c > +new file mode 100644 > +index 00000000000..406956f48e5 > +--- /dev/null > ++++ b/gcc/testsuite/gcc.target/i386/ret-thunk-1.c > +@@ -0,0 +1,12 @@ > ++/* { dg-do compile } */ > ++/* { dg-options "-O2 -mfunction-return=thunk" } */ > ++ > ++void > ++foo (void) > ++{ > ++} > ++ > ++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.return_thunk" } } */ > ++/* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */ > ++/* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */ > ++/* { dg-final { scan-assembler {\tlfence} } } */ > +diff --git a/gcc/testsuite/gcc.target/i386/ret-thunk-10.c b/gcc/testsuite/gcc.target/i386/ret-thunk-10.c > +new file mode 100644 > +index 00000000000..aecea4224f9 > +--- /dev/null > ++++ b/gcc/testsuite/gcc.target/i386/ret-thunk-10.c > +@@ -0,0 +1,22 @@ > ++/* { dg-do compile } */ > ++/* { dg-options "-O2 -mfunction-return=thunk-inline -mindirect-branch=thunk -fno-pic" } */ > ++ > ++extern void (*bar) (void); > ++ > ++int > ++foo (void) > ++{ > ++ bar (); > ++ return 0; > ++} > ++ > ++/* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */ > ++/* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */ > ++/* { dg-final { scan-assembler-not "jmp\[ \t\]*__x86.return_thunk" } } */ > ++/* { dg-final { scan-assembler-times {\tlfence} 2 } } */ > ++/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?bar" { target { ! x32 } } } } */ > ++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" { target { ! x32 } } } } */ > ++/* { dg-final { scan-assembler "__x86.indirect_thunk:" { target { ! x32 } } } } */ > ++/* { dg-final { scan-assembler "call\[ \t\]*__x86.indirect_thunk\.(r|e)ax" { target { x32 } } } } */ > ++/* { dg-final { scan-assembler "__x86.indirect_thunk\.(r|e)ax:" { target { x32 } } } } */ > ++/* { dg-final { scan-assembler-not "pushq\[ \t\]%rax" { target x32 } } } */ > +diff --git a/gcc/testsuite/gcc.target/i386/ret-thunk-11.c b/gcc/testsuite/gcc.target/i386/ret-thunk-11.c > +new file mode 100644 > +index 00000000000..3bacfb54dfd > +--- /dev/null > ++++ b/gcc/testsuite/gcc.target/i386/ret-thunk-11.c > +@@ -0,0 +1,22 @@ > ++/* { dg-do compile } */ > ++/* { dg-options "-O2 -mfunction-return=thunk-extern -mindirect-branch=thunk -fno-pic" } */ > ++ > ++extern void (*bar) (void); > ++ > ++int > ++foo (void) > ++{ > ++ bar (); > ++ return 0; > ++} > ++ > ++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.return_thunk" } } */ > ++/* { dg-final { scan-assembler-times {\tlfence} 1 } } */ > ++/* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */ > ++/* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */ > ++/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?bar" { target { ! x32 } } } } */ > ++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" { target { ! x32 } } } } */ > ++/* { dg-final { scan-assembler "__x86.indirect_thunk:" { target { ! x32 } } } } */ > ++/* { dg-final { scan-assembler "call\[ \t\]*__x86.indirect_thunk\.(r|e)ax" { target { x32 } } } } */ > ++/* { dg-final { scan-assembler "__x86.indirect_thunk\.(r|e)ax:" { target { x32 } } } } */ > ++/* { dg-final { scan-assembler-not "pushq\[ \t\]%rax" { target x32 } } } */ > +diff --git a/gcc/testsuite/gcc.target/i386/ret-thunk-12.c b/gcc/testsuite/gcc.target/i386/ret-thunk-12.c > +new file mode 100644 > +index 00000000000..851115ac507 > +--- /dev/null > ++++ b/gcc/testsuite/gcc.target/i386/ret-thunk-12.c > +@@ -0,0 +1,21 @@ > ++/* { dg-do compile } */ > ++/* { dg-options "-O2 -mfunction-return=keep -mindirect-branch=thunk -fno-pic" } */ > ++ > ++extern void (*bar) (void); > ++ > ++int > ++foo (void) > ++{ > ++ bar (); > ++ return 0; > ++} > ++ > ++/* { dg-final { scan-assembler-not "jmp\[ \t\]*__x86.return_thunk" } } */ > ++/* { dg-final { scan-assembler-times {\tlfence} 1 } } */ > ++/* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */ > ++/* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */ > ++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" { target { ! x32 } } } } */ > ++/* { dg-final { scan-assembler "__x86.indirect_thunk:" { target { ! x32 } } } } */ > ++/* { dg-final { scan-assembler "call\[ \t\]*__x86.indirect_thunk\.(r|e)ax" { target { x32 } } } } */ > ++/* { dg-final { scan-assembler "__x86.indirect_thunk\.(r|e)ax:" { target { x32 } } } } */ > ++/* { dg-final { scan-assembler-not "pushq\[ \t\]%rax" { target x32 } } } */ > +diff --git a/gcc/testsuite/gcc.target/i386/ret-thunk-13.c b/gcc/testsuite/gcc.target/i386/ret-thunk-13.c > +new file mode 100644 > +index 00000000000..7acb6fa5eae > +--- /dev/null > ++++ b/gcc/testsuite/gcc.target/i386/ret-thunk-13.c > +@@ -0,0 +1,21 @@ > ++/* { dg-do compile } */ > ++/* { dg-options "-O2 -mfunction-return=keep -mindirect-branch=thunk-inline -fno-pic" } */ > ++ > ++extern void (*bar) (void); > ++extern int foo (void) __attribute__ ((function_return("thunk"))); > ++ > ++int > ++foo (void) > ++{ > ++ bar (); > ++ return 0; > ++} > ++ > ++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.return_thunk" } } */ > ++/* { dg-final { scan-assembler-times {\tlfence} 2 } } */ > ++/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?bar" { target { ! x32 } } } } */ > ++/* { dg-final { scan-assembler-times "jmp\[ \t\]*\.LIND" 3 } } */ > ++/* { dg-final { scan-assembler-times "call\[ \t\]*\.LIND" 3 } } */ > ++/* { dg-final { scan-assembler-not "jmp\[ \t\]*__x86.indirect_thunk" } } */ > ++/* { dg-final { scan-assembler-not "call\[ \t\]*__x86.indirect_thunk\.(r|e)ax" { target { x32 } } } } */ > ++/* { dg-final { scan-assembler-not "pushq\[ \t\]%rax" { target x32 } } } */ > +diff --git a/gcc/testsuite/gcc.target/i386/ret-thunk-14.c b/gcc/testsuite/gcc.target/i386/ret-thunk-14.c > +new file mode 100644 > +index 00000000000..bf340fac7c6 > +--- /dev/null > ++++ b/gcc/testsuite/gcc.target/i386/ret-thunk-14.c > +@@ -0,0 +1,21 @@ > ++/* { dg-do compile } */ > ++/* { dg-options "-O2 -mfunction-return=keep -mindirect-branch=thunk-extern -fno-pic" } */ > ++ > ++extern void (*bar) (void); > ++ > ++__attribute__ ((function_return("thunk-inline"))) > ++int > ++foo (void) > ++{ > ++ bar (); > ++ return 0; > ++} > ++ > ++/* { dg-final { scan-assembler-times {\tlfence} 1 } } */ > ++/* { dg-final { scan-assembler-not "jmp\[ \t\]*__x86.return_thunk" } } */ > ++/* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */ > ++/* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */ > ++/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?bar" { target { ! x32 } } } } */ > ++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" { target { ! x32 } } } } */ > ++/* { dg-final { scan-assembler "call\[ \t\]*__x86.indirect_thunk\.(r|e)ax" { target { x32 } } } } */ > ++/* { dg-final { scan-assembler-not "pushq\[ \t\]%rax" { target x32 } } } */ > +diff --git a/gcc/testsuite/gcc.target/i386/ret-thunk-15.c b/gcc/testsuite/gcc.target/i386/ret-thunk-15.c > +new file mode 100644 > +index 00000000000..735f8648c96 > +--- /dev/null > ++++ b/gcc/testsuite/gcc.target/i386/ret-thunk-15.c > +@@ -0,0 +1,21 @@ > ++/* { dg-do compile } */ > ++/* { dg-options "-O2 -mfunction-return=keep -mindirect-branch=keep -fno-pic" } */ > ++ > ++extern void (*bar) (void); > ++ > ++__attribute__ ((function_return("thunk-extern"), indirect_branch("thunk"))) > ++int > ++foo (void) > ++{ > ++ bar (); > ++ return 0; > ++} > ++ > ++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.return_thunk" } } */ > ++/* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */ > ++/* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */ > ++/* { dg-final { scan-assembler-times {\tlfence} 1 } } */ > ++/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?bar" { target { ! x32 } } } } */ > ++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" { target { ! x32 } } } } */ > ++/* { dg-final { scan-assembler "call\[ \t\]*__x86.indirect_thunk\.(r|e)ax" { target x32 } } } */ > ++/* { dg-final { scan-assembler-not "pushq\[ \t\]%rax" { target x32 } } } */ > +diff --git a/gcc/testsuite/gcc.target/i386/ret-thunk-16.c b/gcc/testsuite/gcc.target/i386/ret-thunk-16.c > +new file mode 100644 > +index 00000000000..cf3920563e0 > +--- /dev/null > ++++ b/gcc/testsuite/gcc.target/i386/ret-thunk-16.c > +@@ -0,0 +1,18 @@ > ++/* { dg-do compile } */ > ++/* { dg-options "-O2 -mfunction-return=thunk-inline -mindirect-branch=thunk-extern -fno-pic" } */ > ++ > ++extern void (*bar) (void); > ++ > ++__attribute__ ((function_return("keep"), indirect_branch("keep"))) > ++int > ++foo (void) > ++{ > ++ bar (); > ++ return 0; > ++} > ++ > ++/* { dg-final { scan-assembler-not "__x86.indirect_thunk" } } */ > ++/* { dg-final { scan-assembler-not "__x86.return_thunk" } } */ > ++/* { dg-final { scan-assembler-not {\tlfence} } } */ > ++/* { dg-final { scan-assembler-not "jmp\[ \t\]*\.LIND" } } */ > ++/* { dg-final { scan-assembler-not "call\[ \t\]*\.LIND" } } */ > +diff --git a/gcc/testsuite/gcc.target/i386/ret-thunk-2.c b/gcc/testsuite/gcc.target/i386/ret-thunk-2.c > +new file mode 100644 > +index 00000000000..190947cc2ca > +--- /dev/null > ++++ b/gcc/testsuite/gcc.target/i386/ret-thunk-2.c > +@@ -0,0 +1,12 @@ > ++/* { dg-do compile } */ > ++/* { dg-options "-O2 -mfunction-return=thunk-inline" } */ > ++ > ++void > ++foo (void) > ++{ > ++} > ++ > ++/* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */ > ++/* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */ > ++/* { dg-final { scan-assembler {\tlfence} } } */ > ++/* { dg-final { scan-assembler-not "jmp\[ \t\]*__x86.return_thunk" } } */ > +diff --git a/gcc/testsuite/gcc.target/i386/ret-thunk-3.c b/gcc/testsuite/gcc.target/i386/ret-thunk-3.c > +new file mode 100644 > +index 00000000000..d71de3ac520 > +--- /dev/null > ++++ b/gcc/testsuite/gcc.target/i386/ret-thunk-3.c > +@@ -0,0 +1,12 @@ > ++/* { dg-do compile } */ > ++/* { dg-options "-O2 -mfunction-return=thunk-extern" } */ > ++ > ++void > ++foo (void) > ++{ > ++} > ++ > ++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.return_thunk" } } */ > ++/* { dg-final { scan-assembler-not {\tlfence} } } */ > ++/* { dg-final { scan-assembler-not "jmp\[ \t\]*\.LIND" } } */ > ++/* { dg-final { scan-assembler-not "call\[ \t\]*\.LIND" } } */ > +diff --git a/gcc/testsuite/gcc.target/i386/ret-thunk-4.c b/gcc/testsuite/gcc.target/i386/ret-thunk-4.c > +new file mode 100644 > +index 00000000000..68c22122f0d > +--- /dev/null > ++++ b/gcc/testsuite/gcc.target/i386/ret-thunk-4.c > +@@ -0,0 +1,12 @@ > ++/* { dg-do compile } */ > ++/* { dg-options "-O2 -mfunction-return=keep" } */ > ++ > ++void > ++foo (void) > ++{ > ++} > ++ > ++/* { dg-final { scan-assembler-not "jmp\[ \t\]*__x86.return_thunk" } } */ > ++/* { dg-final { scan-assembler-not {\tlfence} } } */ > ++/* { dg-final { scan-assembler-not "jmp\[ \t\]*\.LIND" } } */ > ++/* { dg-final { scan-assembler-not "call\[ \t\]*\.LIND" } } */ > +diff --git a/gcc/testsuite/gcc.target/i386/ret-thunk-5.c b/gcc/testsuite/gcc.target/i386/ret-thunk-5.c > +new file mode 100644 > +index 00000000000..28c576e2267 > +--- /dev/null > ++++ b/gcc/testsuite/gcc.target/i386/ret-thunk-5.c > +@@ -0,0 +1,14 @@ > ++/* { dg-do compile } */ > ++/* { dg-options "-O2 -mfunction-return=keep" } */ > ++ > ++extern void foo (void) __attribute__ ((function_return("thunk"))); > ++ > ++void > ++foo (void) > ++{ > ++} > ++ > ++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.return_thunk" } } */ > ++/* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */ > ++/* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */ > ++/* { dg-final { scan-assembler {\tlfence} } } */ > +diff --git a/gcc/testsuite/gcc.target/i386/ret-thunk-6.c b/gcc/testsuite/gcc.target/i386/ret-thunk-6.c > +new file mode 100644 > +index 00000000000..10ad40b9c26 > +--- /dev/null > ++++ b/gcc/testsuite/gcc.target/i386/ret-thunk-6.c > +@@ -0,0 +1,13 @@ > ++/* { dg-do compile } */ > ++/* { dg-options "-O2 -mfunction-return=keep" } */ > ++ > ++__attribute__ ((function_return("thunk-inline"))) > ++void > ++foo (void) > ++{ > ++} > ++ > ++/* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */ > ++/* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */ > ++/* { dg-final { scan-assembler {\tlfence} } } */ > ++/* { dg-final { scan-assembler-not "jmp\[ \t\]*__x86.return_thunk" } } */ > +diff --git a/gcc/testsuite/gcc.target/i386/ret-thunk-7.c b/gcc/testsuite/gcc.target/i386/ret-thunk-7.c > +new file mode 100644 > +index 00000000000..7ac0beaa73e > +--- /dev/null > ++++ b/gcc/testsuite/gcc.target/i386/ret-thunk-7.c > +@@ -0,0 +1,13 @@ > ++/* { dg-do compile } */ > ++/* { dg-options "-O2 -mfunction-return=keep" } */ > ++ > ++__attribute__ ((function_return("thunk-extern"))) > ++void > ++foo (void) > ++{ > ++} > ++ > ++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.return_thunk" } } */ > ++/* { dg-final { scan-assembler-not {\tlfence} } } */ > ++/* { dg-final { scan-assembler-not "jmp\[ \t\]*\.LIND" } } */ > ++/* { dg-final { scan-assembler-not "call\[ \t\]*\.LIND" } } */ > +diff --git a/gcc/testsuite/gcc.target/i386/ret-thunk-8.c b/gcc/testsuite/gcc.target/i386/ret-thunk-8.c > +new file mode 100644 > +index 00000000000..777ab7c8088 > +--- /dev/null > ++++ b/gcc/testsuite/gcc.target/i386/ret-thunk-8.c > +@@ -0,0 +1,14 @@ > ++/* { dg-do compile } */ > ++/* { dg-options "-O2 -mfunction-return=thunk-inline" } */ > ++ > ++extern void foo (void) __attribute__ ((function_return("keep"))); > ++ > ++void > ++foo (void) > ++{ > ++} > ++ > ++/* { dg-final { scan-assembler-not "jmp\[ \t\]*__x86.return_thunk" } } */ > ++/* { dg-final { scan-assembler-not {\tlfence} } } */ > ++/* { dg-final { scan-assembler-not "jmp\[ \t\]*\.LIND" } } */ > ++/* { dg-final { scan-assembler-not "call\[ \t\]*\.LIND" } } */ > +diff --git a/gcc/testsuite/gcc.target/i386/ret-thunk-9.c b/gcc/testsuite/gcc.target/i386/ret-thunk-9.c > +new file mode 100644 > +index 00000000000..569e5f47973 > +--- /dev/null > ++++ b/gcc/testsuite/gcc.target/i386/ret-thunk-9.c > +@@ -0,0 +1,23 @@ > ++/* { dg-do compile } */ > ++/* { dg-options "-O2 -mfunction-return=thunk -mindirect-branch=thunk -fno-pic" } */ > ++ > ++extern void (*bar) (void); > ++ > ++int > ++foo (void) > ++{ > ++ bar (); > ++ return 0; > ++} > ++ > ++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.return_thunk" } } */ > ++/* { dg-final { scan-assembler-not "__x86.return_thunk:" } } */ > ++/* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */ > ++/* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */ > ++/* { dg-final { scan-assembler "__x86.indirect_thunk:" } } */ > ++/* { dg-final { scan-assembler-times {\tlfence} 1 { target { ! x32 } } } } */ > ++/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?bar" { target { ! x32 } } } } */ > ++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" { target { ! x32 } } } } */ > ++/* { dg-final { scan-assembler-times {\tlfence} 2 { target { x32 } } } } */ > ++/* { dg-final { scan-assembler "call\[ \t\]*__x86.indirect_thunk\.(r|e)ax" { target { x32 } } } } */ > ++/* { dg-final { scan-assembler-not "pushq\[ \t\]%rax" { target x32 } } } */ > +-- > +2.15.1 > + > diff --git a/gnu/packages/patches/gcc-retpoline-Add-mfunction-return-keep-to-indirect-branch-tests.patch b/gnu/packages/patches/gcc-retpoline-Add-mfunction-return-keep-to-indirect-branch-tests.patch > new file mode 100644 > index 000000000..ac900bab0 > --- /dev/null > +++ b/gnu/packages/patches/gcc-retpoline-Add-mfunction-return-keep-to-indirect-branch-tests.patch > @@ -0,0 +1,421 @@ > +'Retpoline' mitigation technique for Spectre (branch target injection) > +[CVE-2017-5715]: > + > +https://security.googleblog.com/2018/01/more-details-about-mitigations-for-cpu_4.html > +https://support.google.com/faqs/answer/7625886 > +https://spectreattack.com/ > +https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2017-5715 > + > +Patch copied from the 'retpoline-20180107' branch of upstream source repository > +(please add new / update existing patches when new 'retpoline-xxxxxxxx' branch > +appears): > + > +http://git.infradead.org/users/dwmw2/gcc-retpoline.git > + > +From def2b5d75fd6234984ec969f4586fcb8c516a3b9 Mon Sep 17 00:00:00 2001 > +From: "H.J. Lu" <hjl.tools@gmail.com> > +Date: Wed, 6 Dec 2017 09:58:42 -0800 > +Subject: [PATCH 12/17] Add -mfunction-return=keep to indirect branch tests > + > +--- > + gcc/testsuite/gcc.target/i386/indirect-thunk-1.c | 2 +- > + gcc/testsuite/gcc.target/i386/indirect-thunk-2.c | 2 +- > + gcc/testsuite/gcc.target/i386/indirect-thunk-3.c | 2 +- > + gcc/testsuite/gcc.target/i386/indirect-thunk-4.c | 2 +- > + gcc/testsuite/gcc.target/i386/indirect-thunk-5.c | 2 +- > + gcc/testsuite/gcc.target/i386/indirect-thunk-6.c | 2 +- > + gcc/testsuite/gcc.target/i386/indirect-thunk-7.c | 2 +- > + gcc/testsuite/gcc.target/i386/indirect-thunk-attr-1.c | 2 +- > + gcc/testsuite/gcc.target/i386/indirect-thunk-attr-2.c | 2 +- > + gcc/testsuite/gcc.target/i386/indirect-thunk-attr-3.c | 2 +- > + gcc/testsuite/gcc.target/i386/indirect-thunk-attr-4.c | 2 +- > + gcc/testsuite/gcc.target/i386/indirect-thunk-attr-5.c | 2 +- > + gcc/testsuite/gcc.target/i386/indirect-thunk-attr-6.c | 2 +- > + gcc/testsuite/gcc.target/i386/indirect-thunk-attr-7.c | 2 +- > + gcc/testsuite/gcc.target/i386/indirect-thunk-attr-8.c | 2 +- > + gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-1.c | 2 +- > + gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-2.c | 2 +- > + gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-3.c | 2 +- > + gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-4.c | 2 +- > + gcc/testsuite/gcc.target/i386/indirect-thunk-extern-1.c | 2 +- > + gcc/testsuite/gcc.target/i386/indirect-thunk-extern-2.c | 2 +- > + gcc/testsuite/gcc.target/i386/indirect-thunk-extern-3.c | 2 +- > + gcc/testsuite/gcc.target/i386/indirect-thunk-extern-4.c | 2 +- > + gcc/testsuite/gcc.target/i386/indirect-thunk-extern-5.c | 2 +- > + gcc/testsuite/gcc.target/i386/indirect-thunk-extern-6.c | 2 +- > + gcc/testsuite/gcc.target/i386/indirect-thunk-extern-7.c | 2 +- > + gcc/testsuite/gcc.target/i386/indirect-thunk-inline-1.c | 2 +- > + gcc/testsuite/gcc.target/i386/indirect-thunk-inline-2.c | 2 +- > + gcc/testsuite/gcc.target/i386/indirect-thunk-inline-3.c | 2 +- > + gcc/testsuite/gcc.target/i386/indirect-thunk-inline-4.c | 2 +- > + gcc/testsuite/gcc.target/i386/indirect-thunk-inline-5.c | 2 +- > + gcc/testsuite/gcc.target/i386/indirect-thunk-inline-6.c | 2 +- > + gcc/testsuite/gcc.target/i386/indirect-thunk-inline-7.c | 2 +- > + 33 files changed, 33 insertions(+), 33 deletions(-) > + > +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-1.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-1.c > +index 785e593405f..318db1e7f5c 100644 > +--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-1.c > ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-1.c > +@@ -1,5 +1,5 @@ > + /* { dg-do compile } */ > +-/* { dg-options "-O2 -mindirect-branch=thunk -fno-pic" } */ > ++/* { dg-options "-O2 -mfunction-return=keep -mindirect-branch=thunk -fno-pic" } */ > + > + typedef void (*dispatch_t)(long offset); > + > +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-2.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-2.c > +index b69075e6483..f2700dd36cf 100644 > +--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-2.c > ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-2.c > +@@ -1,5 +1,5 @@ > + /* { dg-do compile } */ > +-/* { dg-options "-O2 -mindirect-branch=thunk -fno-pic" } */ > ++/* { dg-options "-O2 -mfunction-return=keep -mindirect-branch=thunk -fno-pic" } */ > + > + typedef void (*dispatch_t)(long offset); > + > +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-3.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-3.c > +index df8109baf55..46685d9a674 100644 > +--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-3.c > ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-3.c > +@@ -1,5 +1,5 @@ > + /* { dg-do compile } */ > +-/* { dg-options "-O2 -mindirect-branch=thunk -fno-pic" } */ > ++/* { dg-options "-O2 -mfunction-return=keep -mindirect-branch=thunk -fno-pic" } */ > + > + typedef void (*dispatch_t)(long offset); > + > +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-4.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-4.c > +index 8f3b9f4d8a5..8f701775cea 100644 > +--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-4.c > ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-4.c > +@@ -1,5 +1,5 @@ > + /* { dg-do compile } */ > +-/* { dg-options "-O2 -mindirect-branch=thunk -fno-pic" } */ > ++/* { dg-options "-O2 -mfunction-return=keep -mindirect-branch=thunk -fno-pic" } */ > + > + typedef void (*dispatch_t)(long offset); > + > +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-5.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-5.c > +index 1a9bb0e431e..f88ac31d07a 100644 > +--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-5.c > ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-5.c > +@@ -1,5 +1,5 @@ > + /* { dg-do compile { target *-*-linux* } } */ > +-/* { dg-options "-O2 -fpic -fno-plt -mindirect-branch=thunk" } */ > ++/* { dg-options "-O2 -mfunction-return=keep -fpic -fno-plt -mindirect-branch=thunk" } */ > + > + extern void bar (void); > + > +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-6.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-6.c > +index bc7d20ec6ad..d745116d321 100644 > +--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-6.c > ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-6.c > +@@ -1,5 +1,5 @@ > + /* { dg-do compile { target *-*-linux* } } */ > +-/* { dg-options "-O2 -fpic -fno-plt -mindirect-branch=thunk" } */ > ++/* { dg-options "-O2 -mfunction-return=keep -fpic -fno-plt -mindirect-branch=thunk" } */ > + > + extern void bar (void); > + > +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-7.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-7.c > +index f0e1cfe1893..969cb8c6ddc 100644 > +--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-7.c > ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-7.c > +@@ -1,5 +1,5 @@ > + /* { dg-do compile } */ > +-/* { dg-options "-O2 -mindirect-branch=thunk -fno-pic" } */ > ++/* { dg-options "-O2 -mfunction-return=keep -mindirect-branch=thunk -fno-pic" } */ > + > + void func0 (void); > + void func1 (void); > +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-1.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-1.c > +index 8b88449e625..12a61c3bbc7 100644 > +--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-1.c > ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-1.c > +@@ -1,5 +1,5 @@ > + /* { dg-do compile } */ > +-/* { dg-options "-O2 -fno-pic" } */ > ++/* { dg-options "-O2 -mfunction-return=keep -fno-pic" } */ > + > + typedef void (*dispatch_t)(long offset); > + > +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-2.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-2.c > +index c69f7bf4f60..a06907933a2 100644 > +--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-2.c > ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-2.c > +@@ -1,5 +1,5 @@ > + /* { dg-do compile } */ > +-/* { dg-options "-O2 -fno-pic" } */ > ++/* { dg-options "-O2 -mfunction-return=keep -fno-pic" } */ > + > + typedef void (*dispatch_t)(long offset); > + > +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-3.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-3.c > +index c845099a83e..7f56725e6b6 100644 > +--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-3.c > ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-3.c > +@@ -1,5 +1,5 @@ > + /* { dg-do compile } */ > +-/* { dg-options "-O2 -fno-pic" } */ > ++/* { dg-options "-O2 -mfunction-return=keep -fno-pic" } */ > + > + typedef void (*dispatch_t)(long offset); > + > +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-4.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-4.c > +index f636f3422fd..fd4ab1dbaa0 100644 > +--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-4.c > ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-4.c > +@@ -1,5 +1,5 @@ > + /* { dg-do compile } */ > +-/* { dg-options "-O2 -fno-pic" } */ > ++/* { dg-options "-O2 -mfunction-return=keep -fno-pic" } */ > + > + typedef void (*dispatch_t)(long offset); > + > +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-5.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-5.c > +index 5f1d6a78041..1ffbf3b1181 100644 > +--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-5.c > ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-5.c > +@@ -1,5 +1,5 @@ > + /* { dg-do compile } */ > +-/* { dg-options "-O2 -fno-pic" } */ > ++/* { dg-options "-O2 -mfunction-return=keep -fno-pic" } */ > + > + typedef void (*dispatch_t)(long offset); > + > +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-6.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-6.c > +index 56c92da9812..1559072919a 100644 > +--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-6.c > ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-6.c > +@@ -1,5 +1,5 @@ > + /* { dg-do compile } */ > +-/* { dg-options "-O2 -fno-pic" } */ > ++/* { dg-options "-O2 -mfunction-return=keep -fno-pic" } */ > + > + typedef void (*dispatch_t)(long offset); > + > +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-7.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-7.c > +index cfb6f5b234b..1717e7bb436 100644 > +--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-7.c > ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-7.c > +@@ -1,5 +1,5 @@ > + /* { dg-do compile } */ > +-/* { dg-options "-O2 -fno-pic" } */ > ++/* { dg-options "-O2 -mfunction-return=keep -fno-pic" } */ > + > + void func0 (void); > + void func1 (void); > +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-8.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-8.c > +index 9f6d12d74a1..af1bb125a22 100644 > +--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-8.c > ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-8.c > +@@ -1,5 +1,5 @@ > + /* { dg-do compile } */ > +-/* { dg-options "-O2 -mindirect-branch=thunk -fno-pic" } */ > ++/* { dg-options "-O2 -mfunction-return=keep -mindirect-branch=thunk -fno-pic" } */ > + > + void func0 (void); > + void func1 (void); > +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-1.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-1.c > +index a5b1d38e061..20903b0f79d 100644 > +--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-1.c > ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-1.c > +@@ -1,5 +1,5 @@ > + /* { dg-do compile { target { ! x32 } } } */ > +-/* { dg-options "-O2 -mindirect-branch=thunk -fcheck-pointer-bounds -mmpx -fno-pic" } */ > ++/* { dg-options "-O2 -mfunction-return=keep -mindirect-branch=thunk -fcheck-pointer-bounds -mmpx -fno-pic" } */ > + > + void (*dispatch) (char *); > + char buf[10]; > +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-2.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-2.c > +index a42add209e2..aef4bd144f4 100644 > +--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-2.c > ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-2.c > +@@ -1,5 +1,5 @@ > + /* { dg-do compile { target { ! x32 } } } */ > +-/* { dg-options "-O2 -mindirect-branch=thunk -fcheck-pointer-bounds -mmpx -fno-pic" } */ > ++/* { dg-options "-O2 -mfunction-return=keep -mindirect-branch=thunk -fcheck-pointer-bounds -mmpx -fno-pic" } */ > + > + void (*dispatch) (char *); > + char buf[10]; > +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-3.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-3.c > +index 265e010a0fe..2cc0343f828 100644 > +--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-3.c > ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-3.c > +@@ -1,5 +1,5 @@ > + /* { dg-do compile { target { *-*-linux* && { ! x32 } } } } */ > +-/* { dg-options "-O2 -mindirect-branch=thunk -fcheck-pointer-bounds -mmpx -fpic -fno-plt" } */ > ++/* { dg-options "-O2 -mfunction-return=keep -mindirect-branch=thunk -fcheck-pointer-bounds -mmpx -fpic -fno-plt" } */ > + > + void bar (char *); > + char buf[10]; > +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-4.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-4.c > +index 1c01bcb7fc6..91560fef661 100644 > +--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-4.c > ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-4.c > +@@ -1,5 +1,5 @@ > + /* { dg-do compile { target { *-*-linux* && { ! x32 } } } } */ > +-/* { dg-options "-O2 -mindirect-branch=thunk -fcheck-pointer-bounds -mmpx -fpic -fno-plt" } */ > ++/* { dg-options "-O2 -mfunction-return=keep -mindirect-branch=thunk -fcheck-pointer-bounds -mmpx -fpic -fno-plt" } */ > + > + void bar (char *); > + char buf[10]; > +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-1.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-1.c > +index f1fa0a11922..dc6bd10af4c 100644 > +--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-1.c > ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-1.c > +@@ -1,5 +1,5 @@ > + /* { dg-do compile } */ > +-/* { dg-options "-O2 -mindirect-branch=thunk-extern -fno-pic" } */ > ++/* { dg-options "-O2 -mfunction-return=keep -mindirect-branch=thunk-extern -fno-pic" } */ > + > + typedef void (*dispatch_t)(long offset); > + > +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-2.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-2.c > +index d6e078d594b..955aa256529 100644 > +--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-2.c > ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-2.c > +@@ -1,5 +1,5 @@ > + /* { dg-do compile } */ > +-/* { dg-options "-O2 -mindirect-branch=thunk-extern -fno-pic" } */ > ++/* { dg-options "-O2 -mfunction-return=keep -mindirect-branch=thunk-extern -fno-pic" } */ > + > + typedef void (*dispatch_t)(long offset); > + > +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-3.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-3.c > +index 3bbe2646955..1537239416f 100644 > +--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-3.c > ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-3.c > +@@ -1,5 +1,5 @@ > + /* { dg-do compile } */ > +-/* { dg-options "-O2 -mindirect-branch=thunk-extern -fno-pic" } */ > ++/* { dg-options "-O2 -mfunction-return=keep -mindirect-branch=thunk-extern -fno-pic" } */ > + > + typedef void (*dispatch_t)(long offset); > + > +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-4.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-4.c > +index 596fac599f6..c82e53068fe 100644 > +--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-4.c > ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-4.c > +@@ -1,5 +1,5 @@ > + /* { dg-do compile } */ > +-/* { dg-options "-O2 -mindirect-branch=thunk-extern -fno-pic" } */ > ++/* { dg-options "-O2 -mfunction-return=keep -mindirect-branch=thunk-extern -fno-pic" } */ > + > + typedef void (*dispatch_t)(long offset); > + > +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-5.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-5.c > +index ad54aaeac4c..23548d85f78 100644 > +--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-5.c > ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-5.c > +@@ -1,5 +1,5 @@ > + /* { dg-do compile { target *-*-linux* } } */ > +-/* { dg-options "-O2 -fpic -fno-plt -mindirect-branch=thunk-extern" } */ > ++/* { dg-options "-O2 -mfunction-return=keep -fpic -fno-plt -mindirect-branch=thunk-extern" } */ > + > + extern void bar (void); > + > +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-6.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-6.c > +index a8e75254cfe..56c2fe92f25 100644 > +--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-6.c > ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-6.c > +@@ -1,5 +1,5 @@ > + /* { dg-do compile { target *-*-linux* } } */ > +-/* { dg-options "-O2 -fpic -fno-plt -mindirect-branch=thunk-extern" } */ > ++/* { dg-options "-O2 -mfunction-return=keep -fpic -fno-plt -mindirect-branch=thunk-extern" } */ > + > + extern void bar (void); > + > +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-7.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-7.c > +index ab367951c45..e12b88593fe 100644 > +--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-7.c > ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-7.c > +@@ -1,5 +1,5 @@ > + /* { dg-do compile } */ > +-/* { dg-options "-O2 -mindirect-branch=thunk-extern -fno-pic" } */ > ++/* { dg-options "-O2 -mfunction-return=keep -mindirect-branch=thunk-extern -fno-pic" } */ > + > + void func0 (void); > + void func1 (void); > +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-1.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-1.c > +index 09b8ad7d879..87b5429702f 100644 > +--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-1.c > ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-1.c > +@@ -1,5 +1,5 @@ > + /* { dg-do compile } */ > +-/* { dg-options "-O2 -mindirect-branch=thunk-inline -fno-pic" } */ > ++/* { dg-options "-O2 -mfunction-return=keep -mindirect-branch=thunk-inline -fno-pic" } */ > + > + typedef void (*dispatch_t)(long offset); > + > +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-2.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-2.c > +index 1f873758fbe..a496a41a918 100644 > +--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-2.c > ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-2.c > +@@ -1,5 +1,5 @@ > + /* { dg-do compile } */ > +-/* { dg-options "-O2 -mindirect-branch=thunk-inline -fno-pic" } */ > ++/* { dg-options "-O2 -mfunction-return=keep -mindirect-branch=thunk-inline -fno-pic" } */ > + > + typedef void (*dispatch_t)(long offset); > + > +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-3.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-3.c > +index b24af1da963..6fe5ce71abf 100644 > +--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-3.c > ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-3.c > +@@ -1,5 +1,5 @@ > + /* { dg-do compile } */ > +-/* { dg-options "-O2 -mindirect-branch=thunk-inline -fno-pic" } */ > ++/* { dg-options "-O2 -mfunction-return=keep -mindirect-branch=thunk-inline -fno-pic" } */ > + > + typedef void (*dispatch_t)(long offset); > + > +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-4.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-4.c > +index 1a86608f727..65cd997a33f 100644 > +--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-4.c > ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-4.c > +@@ -1,5 +1,5 @@ > + /* { dg-do compile } */ > +-/* { dg-options "-O2 -mindirect-branch=thunk-inline -fno-pic" } */ > ++/* { dg-options "-O2 -mfunction-return=keep -mindirect-branch=thunk-inline -fno-pic" } */ > + > + typedef void (*dispatch_t)(long offset); > + > +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-5.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-5.c > +index f4890fe97b2..7321d015c02 100644 > +--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-5.c > ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-5.c > +@@ -1,5 +1,5 @@ > + /* { dg-do compile { target *-*-linux* } } */ > +-/* { dg-options "-O2 -fpic -fno-plt -mindirect-branch=thunk-inline" } */ > ++/* { dg-options "-O2 -mfunction-return=keep -fpic -fno-plt -mindirect-branch=thunk-inline" } */ > + > + extern void bar (void); > + > +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-6.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-6.c > +index 81b09e73ab8..6ec2e5621ab 100644 > +--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-6.c > ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-6.c > +@@ -1,5 +1,5 @@ > + /* { dg-do compile { target *-*-linux* } } */ > +-/* { dg-options "-O2 -fpic -fno-plt -mindirect-branch=thunk-inline" } */ > ++/* { dg-options "-O2 -mfunction-return=keep -fpic -fno-plt -mindirect-branch=thunk-inline" } */ > + > + extern void bar (void); > + > +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-7.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-7.c > +index 01d45782185..a3d1a13cded 100644 > +--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-7.c > ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-7.c > +@@ -1,5 +1,5 @@ > + /* { dg-do compile } */ > +-/* { dg-options "-O2 -mindirect-branch=thunk-inline -fno-pic" } */ > ++/* { dg-options "-O2 -mfunction-return=keep -mindirect-branch=thunk-inline -fno-pic" } */ > + > + void func0 (void); > + void func1 (void); > +-- > +2.15.1 > + > diff --git a/gnu/packages/patches/gcc-retpoline-Add-mindirect-branch-loop.patch b/gnu/packages/patches/gcc-retpoline-Add-mindirect-branch-loop.patch > new file mode 100644 > index 000000000..ab715f46a > --- /dev/null > +++ b/gnu/packages/patches/gcc-retpoline-Add-mindirect-branch-loop.patch > @@ -0,0 +1,233 @@ > +'Retpoline' mitigation technique for Spectre (branch target injection) > +[CVE-2017-5715]: > + > +https://security.googleblog.com/2018/01/more-details-about-mitigations-for-cpu_4.html > +https://support.google.com/faqs/answer/7625886 > +https://spectreattack.com/ > +https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2017-5715 > + > +Patch copied from the 'retpoline-20180107' branch of upstream source repository > +(please add new / update existing patches when new 'retpoline-xxxxxxxx' branch > +appears): > + > +http://git.infradead.org/users/dwmw2/gcc-retpoline.git > + > +From d667049b53e3d45de057fba2f1ed0e3f268201c1 Mon Sep 17 00:00:00 2001 > +From: "H.J. Lu" <hjl.tools@gmail.com> > +Date: Thu, 16 Nov 2017 14:46:20 -0800 > +Subject: [PATCH 10/17] Add -mindirect-branch-loop= > + > +Add -mindirect-branch-loop= tests. > +--- > + gcc/config/i386/i386-opts.h | 6 ++++++ > + gcc/config/i386/i386.c | 19 +++++++++++++++++-- > + gcc/config/i386/i386.opt | 16 ++++++++++++++++ > + gcc/testsuite/gcc.target/i386/indirect-thunk-loop-1.c | 19 +++++++++++++++++++ > + gcc/testsuite/gcc.target/i386/indirect-thunk-loop-2.c | 19 +++++++++++++++++++ > + gcc/testsuite/gcc.target/i386/indirect-thunk-loop-3.c | 19 +++++++++++++++++++ > + gcc/testsuite/gcc.target/i386/indirect-thunk-loop-4.c | 19 +++++++++++++++++++ > + gcc/testsuite/gcc.target/i386/indirect-thunk-loop-5.c | 19 +++++++++++++++++++ > + 8 files changed, 134 insertions(+), 2 deletions(-) > + create mode 100644 gcc/testsuite/gcc.target/i386/indirect-thunk-loop-1.c > + create mode 100644 gcc/testsuite/gcc.target/i386/indirect-thunk-loop-2.c > + create mode 100644 gcc/testsuite/gcc.target/i386/indirect-thunk-loop-3.c > + create mode 100644 gcc/testsuite/gcc.target/i386/indirect-thunk-loop-4.c > + create mode 100644 gcc/testsuite/gcc.target/i386/indirect-thunk-loop-5.c > + > +diff --git a/gcc/config/i386/i386-opts.h b/gcc/config/i386/i386-opts.h > +index 9e56d7f2d12..b7b8fd280a3 100644 > +--- a/gcc/config/i386/i386-opts.h > ++++ b/gcc/config/i386/i386-opts.h > +@@ -107,4 +107,10 @@ enum indirect_branch { > + indirect_branch_thunk_extern > + }; > + > ++enum indirect_branch_loop { > ++ indirect_branch_loop_lfence, > ++ indirect_branch_loop_pause, > ++ indirect_branch_loop_nop > ++}; > ++ > + #endif > +diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c > +index 590729b3f87..be1ff4752a9 100644 > +--- a/gcc/config/i386/i386.c > ++++ b/gcc/config/i386/i386.c > +@@ -12016,8 +12016,23 @@ output_indirect_thunk (bool need_bnd_p, int regno) > + > + ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, indirectlabel1); > + > +- /* lfence . */ > +- fprintf (asm_out_file, "\tlfence\n"); > ++ switch (ix86_indirect_branch_loop) > ++ { > ++ case indirect_branch_loop_lfence: > ++ /* lfence. */ > ++ fprintf (asm_out_file, "\tlfence\n"); > ++ break; > ++ case indirect_branch_loop_pause: > ++ /* pause. */ > ++ fprintf (asm_out_file, "\tpause\n"); > ++ break; > ++ case indirect_branch_loop_nop: > ++ /* nop. */ > ++ fprintf (asm_out_file, "\tnop\n"); > ++ break; > ++ default: > ++ gcc_unreachable (); > ++ } > + > + /* Jump. */ > + fputs ("\tjmp\t", asm_out_file); > +diff --git a/gcc/config/i386/i386.opt b/gcc/config/i386/i386.opt > +index 4a932e11bf6..bc81e6bea86 100644 > +--- a/gcc/config/i386/i386.opt > ++++ b/gcc/config/i386/i386.opt > +@@ -947,3 +947,19 @@ Enum(indirect_branch) String(thunk-inline) Value(indirect_branch_thunk_inline) > + > + EnumValue > + Enum(indirect_branch) String(thunk-extern) Value(indirect_branch_thunk_extern) > ++ > ++mindirect-branch-loop= > ++Target Report RejectNegative Joined Enum(indirect_branch_loop) Var(ix86_indirect_branch_loop) Undocumented Init(indirect_branch_loop_lfence) > ++ > ++Enum > ++Name(indirect_branch_loop) Type(enum indirect_branch_loop) > ++Known looop choices (for use with the -mindirect-branch-loop= option): > ++ > ++EnumValue > ++Enum(indirect_branch_loop) String(lfence) Value(indirect_branch_loop_lfence) > ++ > ++EnumValue > ++Enum(indirect_branch_loop) String(pause) Value(indirect_branch_loop_pause) > ++ > ++EnumValue > ++Enum(indirect_branch_loop) String(nop) Value(indirect_branch_loop_nop) > +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-loop-1.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-loop-1.c > +new file mode 100644 > +index 00000000000..f0e8f4949c8 > +--- /dev/null > ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-loop-1.c > +@@ -0,0 +1,19 @@ > ++/* { dg-do compile } */ > ++/* { dg-options "-O2 -mindirect-branch=thunk -mindirect-branch-loop=pause -fno-pic" } */ > ++ > ++typedef void (*dispatch_t)(long offset); > ++ > ++dispatch_t dispatch; > ++ > ++void > ++male_indirect_jump (long offset) > ++{ > ++ dispatch(offset); > ++} > ++ > ++/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { ! x32 } } } } */ > ++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" { target { ! x32 } } } } */ > ++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk\.(r|e)ax" { target x32 } } } */ > ++/* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */ > ++/* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */ > ++/* { dg-final { scan-assembler {\tpause} } } */ > +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-loop-2.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-loop-2.c > +new file mode 100644 > +index 00000000000..a577ac2568a > +--- /dev/null > ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-loop-2.c > +@@ -0,0 +1,19 @@ > ++/* { dg-do compile } */ > ++/* { dg-options "-O2 -mindirect-branch=thunk -mindirect-branch-loop=nop -fno-pic" } */ > ++ > ++typedef void (*dispatch_t)(long offset); > ++ > ++dispatch_t dispatch[256]; > ++ > ++void > ++male_indirect_jump (long offset) > ++{ > ++ dispatch[offset](offset); > ++} > ++ > ++/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { ! x32 } } } } */ > ++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" { target { ! x32 } } } } */ > ++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk\.(r|e)ax" { target x32 } } } */ > ++/* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */ > ++/* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */ > ++/* { dg-final { scan-assembler {\tnop} } } */ > +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-loop-3.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-loop-3.c > +new file mode 100644 > +index 00000000000..c8dcb9639c4 > +--- /dev/null > ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-loop-3.c > +@@ -0,0 +1,19 @@ > ++/* { dg-do compile } */ > ++/* { dg-options "-O2 -mindirect-branch=thunk -mindirect-branch-loop=lfence -fno-pic" } */ > ++ > ++typedef void (*dispatch_t)(long offset); > ++ > ++dispatch_t dispatch; > ++ > ++void > ++male_indirect_jump (long offset) > ++{ > ++ dispatch(offset); > ++} > ++ > ++/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { ! x32 } } } } */ > ++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" { target { ! x32 } } } } */ > ++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk\.(r|e)ax" { target x32 } } } */ > ++/* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */ > ++/* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */ > ++/* { dg-final { scan-assembler {\tlfence} } } */ > +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-loop-4.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-loop-4.c > +new file mode 100644 > +index 00000000000..8569dfc92c3 > +--- /dev/null > ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-loop-4.c > +@@ -0,0 +1,19 @@ > ++/* { dg-do compile } */ > ++/* { dg-options "-O2 -mindirect-branch=thunk-inline -mindirect-branch-loop=pause -fno-pic" } */ > ++ > ++typedef void (*dispatch_t)(long offset); > ++ > ++dispatch_t dispatch; > ++ > ++void > ++male_indirect_jump (long offset) > ++{ > ++ dispatch(offset); > ++} > ++ > ++/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { ! x32 } } } } */ > ++/* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */ > ++/* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */ > ++/* { dg-final { scan-assembler {\tpause} } } */ > ++/* { dg-final { scan-assembler-not "__x86.indirect_thunk" } } */ > ++/* { dg-final { scan-assembler-not "pushq\[ \t\]%rax" { target x32 } } } */ > +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-loop-5.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-loop-5.c > +new file mode 100644 > +index 00000000000..bcf19c9ede1 > +--- /dev/null > ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-loop-5.c > +@@ -0,0 +1,19 @@ > ++/* { dg-do compile } */ > ++/* { dg-options "-O2 -mindirect-branch=thunk-extern -mindirect-branch-loop=pause -fno-pic" } */ > ++ > ++typedef void (*dispatch_t)(long offset); > ++ > ++dispatch_t dispatch; > ++ > ++void > ++male_indirect_jump (long offset) > ++{ > ++ dispatch(offset); > ++} > ++ > ++/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { ! x32 } } } } */ > ++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" { target { ! x32 } } } } */ > ++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk\.(r|e)ax" { target x32 } } } */ > ++/* { dg-final { scan-assembler-not {\t(lfence|pause|nop)} } } */ > ++/* { dg-final { scan-assembler-not "jmp\[ \t\]*\.LIND" } } */ > ++/* { dg-final { scan-assembler-not "call\[ \t\]*\.LIND" } } */ > +-- > +2.15.1 > + > diff --git a/gnu/packages/patches/gcc-retpoline-Add-mindirect-branch-register-and-tests.patch b/gnu/packages/patches/gcc-retpoline-Add-mindirect-branch-register-and-tests.patch > new file mode 100644 > index 000000000..de9e373fd > --- /dev/null > +++ b/gnu/packages/patches/gcc-retpoline-Add-mindirect-branch-register-and-tests.patch > @@ -0,0 +1,403 @@ > +'Retpoline' mitigation technique for Spectre (branch target injection) > +[CVE-2017-5715]: > + > +https://security.googleblog.com/2018/01/more-details-about-mitigations-for-cpu_4.html > +https://support.google.com/faqs/answer/7625886 > +https://spectreattack.com/ > +https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2017-5715 > + > +Patch copied from the 'retpoline-20180107' branch of upstream source repository > +(please add new / update existing patches when new 'retpoline-xxxxxxxx' branch > +appears): > + > +http://git.infradead.org/users/dwmw2/gcc-retpoline.git > + > +From fb8875abab630962dbcb08c822b1b960fa5a51d4 Mon Sep 17 00:00:00 2001 > +From: "H.J. Lu" <hjl.tools@gmail.com> > +Date: Wed, 19 Jul 2017 19:23:02 -0700 > +Subject: [PATCH 13/17] Add -mindirect-branch-register and tests > + > +Add -mindirect-branch-register to force indirect branch via register. > +This is implemented by disabling patterns of indirect branch via memory, > +similar to TARGET_X32. With -mindirect-branch-register: > + > +void (*func) (void); > + > +void > +bar (void) > +{ > + func (); > +} > + > +is compiled into: > + > + movq func(%rip), %rax > + jmp __x86.indirect_thunk.ax > + > +__x86.indirect_thunk.ax: > + call .LIND3 > +.LIND2: > + lfence > + jmp .LIND2 > +.LIND3: > + mov %rax, (%rsp) > + ret > + > +and > + > +void (*func) (void); > + > +int > +bar (void) > +{ > + func (); > + return 0; > +} > + > +is compiled into: > + > + subq $8, %rsp > + movq func(%rip), %rax > + call __x86.indirect_thunk.ax > + xorl %eax, %eax > + addq $8, %rsp > + ret > + > + * config/i386/constraints.md (Bs): Disallow memory operand for > + -mindirect-branch-register. > + (Bw): Likewise. > + * config/i386/predicates.md (indirect_branch_operand): Likewise. > + (GOT_memory_operand): Likewise. > + (call_insn_operand): Likewise. > + (sibcall_insn_operand): Likewise. > + (GOT32_symbol_operand): Likewise. > + * config/i386/i386.md (indirect_jump): Call convert_memory_address > + for -mindirect-branch-register. > + (tablejump): Likewise. > + (*sibcall_memory): Likewise. > + (*sibcall_value_memory): Likewise. > + Disallow peepholes of indirect call and jump via memory for > + -mindirect-branch-register. > + (*call_pop): Replace m with Bw. > + (*call_value_pop): Likewise. > + (*sibcall_pop_memory): Replace m with Bs. > +--- > + gcc/config/i386/constraints.md | 12 +++++--- > + gcc/config/i386/i386.md | 34 ++++++++++++++-------- > + gcc/config/i386/i386.opt | 4 +++ > + gcc/config/i386/predicates.md | 21 ++++++++----- > + .../gcc.target/i386/indirect-thunk-register-1.c | 22 ++++++++++++++ > + .../gcc.target/i386/indirect-thunk-register-2.c | 20 +++++++++++++ > + .../gcc.target/i386/indirect-thunk-register-3.c | 19 ++++++++++++ > + 7 files changed, 109 insertions(+), 23 deletions(-) > + create mode 100644 gcc/testsuite/gcc.target/i386/indirect-thunk-register-1.c > + create mode 100644 gcc/testsuite/gcc.target/i386/indirect-thunk-register-2.c > + create mode 100644 gcc/testsuite/gcc.target/i386/indirect-thunk-register-3.c > + > +diff --git a/gcc/config/i386/constraints.md b/gcc/config/i386/constraints.md > +index 38d604fdace..697caf704dd 100644 > +--- a/gcc/config/i386/constraints.md > ++++ b/gcc/config/i386/constraints.md > +@@ -198,16 +198,20 @@ > + > + (define_constraint "Bs" > + "@internal Sibcall memory operand." > +- (ior (and (not (match_test "TARGET_X32")) > ++ (ior (and (not (match_test "TARGET_X32 > ++ || ix86_indirect_branch_thunk_register")) > + (match_operand 0 "sibcall_memory_operand")) > +- (and (match_test "TARGET_X32 && Pmode == DImode") > ++ (and (match_test "TARGET_X32 && Pmode == DImode > ++ && !ix86_indirect_branch_thunk_register") > + (match_operand 0 "GOT_memory_operand")))) > + > + (define_constraint "Bw" > + "@internal Call memory operand." > +- (ior (and (not (match_test "TARGET_X32")) > ++ (ior (and (not (match_test "TARGET_X32 > ++ || ix86_indirect_branch_thunk_register")) > + (match_operand 0 "memory_operand")) > +- (and (match_test "TARGET_X32 && Pmode == DImode") > ++ (and (match_test "TARGET_X32 && Pmode == DImode > ++ && !ix86_indirect_branch_thunk_register") > + (match_operand 0 "GOT_memory_operand")))) > + > + (define_constraint "Bz" > +diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md > +index 00a9afef225..473fa5c089b 100644 > +--- a/gcc/config/i386/i386.md > ++++ b/gcc/config/i386/i386.md > +@@ -11608,7 +11608,7 @@ > + [(set (pc) (match_operand 0 "indirect_branch_operand"))] > + "" > + { > +- if (TARGET_X32) > ++ if (TARGET_X32 || ix86_indirect_branch_thunk_register) > + operands[0] = convert_memory_address (word_mode, operands[0]); > + }) > + > +@@ -11657,7 +11657,7 @@ > + OPTAB_DIRECT); > + } > + > +- if (TARGET_X32) > ++ if (TARGET_X32 || ix86_indirect_branch_thunk_register) > + operands[0] = convert_memory_address (word_mode, operands[0]); > + }) > + > +@@ -11844,7 +11844,7 @@ > + [(call (mem:QI (match_operand:W 0 "memory_operand" "m")) > + (match_operand 1)) > + (unspec [(const_int 0)] UNSPEC_PEEPSIB)] > +- "!TARGET_X32" > ++ "!TARGET_X32 && !ix86_indirect_branch_thunk_register" > + "* return ix86_output_call_insn (insn, operands[0]);" > + [(set_attr "type" "call")]) > + > +@@ -11853,7 +11853,9 @@ > + (match_operand:W 1 "memory_operand")) > + (call (mem:QI (match_dup 0)) > + (match_operand 3))] > +- "!TARGET_X32 && SIBLING_CALL_P (peep2_next_insn (1)) > ++ "!TARGET_X32 > ++ && !ix86_indirect_branch_thunk_register > ++ && SIBLING_CALL_P (peep2_next_insn (1)) > + && !reg_mentioned_p (operands[0], > + CALL_INSN_FUNCTION_USAGE (peep2_next_insn (1)))" > + [(parallel [(call (mem:QI (match_dup 1)) > +@@ -11866,7 +11868,9 @@ > + (unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE) > + (call (mem:QI (match_dup 0)) > + (match_operand 3))] > +- "!TARGET_X32 && SIBLING_CALL_P (peep2_next_insn (2)) > ++ "!TARGET_X32 > ++ && !ix86_indirect_branch_thunk_register > ++ && SIBLING_CALL_P (peep2_next_insn (2)) > + && !reg_mentioned_p (operands[0], > + CALL_INSN_FUNCTION_USAGE (peep2_next_insn (2)))" > + [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE) > +@@ -11888,7 +11892,7 @@ > + }) > + > + (define_insn "*call_pop" > +- [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lmBz")) > ++ [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lBwBz")) > + (match_operand 1)) > + (set (reg:SI SP_REG) > + (plus:SI (reg:SI SP_REG) > +@@ -11908,7 +11912,7 @@ > + [(set_attr "type" "call")]) > + > + (define_insn "*sibcall_pop_memory" > +- [(call (mem:QI (match_operand:SI 0 "memory_operand" "m")) > ++ [(call (mem:QI (match_operand:SI 0 "memory_operand" "Bs")) > + (match_operand 1)) > + (set (reg:SI SP_REG) > + (plus:SI (reg:SI SP_REG) > +@@ -11962,7 +11966,9 @@ > + [(set (match_operand:W 0 "register_operand") > + (match_operand:W 1 "memory_operand")) > + (set (pc) (match_dup 0))] > +- "!TARGET_X32 && peep2_reg_dead_p (2, operands[0])" > ++ "!TARGET_X32 > ++ && !ix86_indirect_branch_thunk_register > ++ && peep2_reg_dead_p (2, operands[0])" > + [(set (pc) (match_dup 1))]) > + > + ;; Call subroutine, returning value in operand 0 > +@@ -12043,7 +12049,7 @@ > + (call (mem:QI (match_operand:W 1 "memory_operand" "m")) > + (match_operand 2))) > + (unspec [(const_int 0)] UNSPEC_PEEPSIB)] > +- "!TARGET_X32" > ++ "!TARGET_X32 && !ix86_indirect_branch_thunk_register" > + "* return ix86_output_call_insn (insn, operands[1]);" > + [(set_attr "type" "callv")]) > + > +@@ -12053,7 +12059,9 @@ > + (set (match_operand 2) > + (call (mem:QI (match_dup 0)) > + (match_operand 3)))] > +- "!TARGET_X32 && SIBLING_CALL_P (peep2_next_insn (1)) > ++ "!TARGET_X32 > ++ && !ix86_indirect_branch_thunk_register > ++ && SIBLING_CALL_P (peep2_next_insn (1)) > + && !reg_mentioned_p (operands[0], > + CALL_INSN_FUNCTION_USAGE (peep2_next_insn (1)))" > + [(parallel [(set (match_dup 2) > +@@ -12068,7 +12076,9 @@ > + (set (match_operand 2) > + (call (mem:QI (match_dup 0)) > + (match_operand 3)))] > +- "!TARGET_X32 && SIBLING_CALL_P (peep2_next_insn (2)) > ++ "!TARGET_X32 > ++ && !ix86_indirect_branch_thunk_register > ++ && SIBLING_CALL_P (peep2_next_insn (2)) > + && !reg_mentioned_p (operands[0], > + CALL_INSN_FUNCTION_USAGE (peep2_next_insn (2)))" > + [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE) > +@@ -12093,7 +12103,7 @@ > + > + (define_insn "*call_value_pop" > + [(set (match_operand 0) > +- (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lmBz")) > ++ (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lBwBz")) > + (match_operand 2))) > + (set (reg:SI SP_REG) > + (plus:SI (reg:SI SP_REG) > +diff --git a/gcc/config/i386/i386.opt b/gcc/config/i386/i386.opt > +index fc2c81c3fb5..802245f4efe 100644 > +--- a/gcc/config/i386/i386.opt > ++++ b/gcc/config/i386/i386.opt > +@@ -952,6 +952,10 @@ Enum(indirect_branch) String(thunk-inline) Value(indirect_branch_thunk_inline) > + EnumValue > + Enum(indirect_branch) String(thunk-extern) Value(indirect_branch_thunk_extern) > + > ++mindirect-branch-register > ++Target Report Var(ix86_indirect_branch_thunk_register) Init(0) > ++Force indirect call and jump via register. > ++ > + mindirect-branch-loop= > + Target Report RejectNegative Joined Enum(indirect_branch_loop) Var(ix86_indirect_branch_loop) Undocumented Init(indirect_branch_loop_lfence) > + > +diff --git a/gcc/config/i386/predicates.md b/gcc/config/i386/predicates.md > +index 8f250a2e720..fc4933e4533 100644 > +--- a/gcc/config/i386/predicates.md > ++++ b/gcc/config/i386/predicates.md > +@@ -635,7 +635,8 @@ > + ;; Test for a valid operand for indirect branch. > + (define_predicate "indirect_branch_operand" > + (ior (match_operand 0 "register_operand") > +- (and (not (match_test "TARGET_X32")) > ++ (and (not (match_test "TARGET_X32 > ++ || ix86_indirect_branch_thunk_register")) > + (match_operand 0 "memory_operand")))) > + > + ;; Return true if OP is a memory operands that can be used in sibcalls. > +@@ -664,7 +665,8 @@ > + > + ;; Return true if OP is a GOT memory operand. > + (define_predicate "GOT_memory_operand" > +- (match_operand 0 "memory_operand") > ++ (and (match_test "!ix86_indirect_branch_thunk_register") > ++ (match_operand 0 "memory_operand")) > + { > + op = XEXP (op, 0); > + return (GET_CODE (op) == CONST > +@@ -678,9 +680,11 @@ > + (ior (match_test "constant_call_address_operand > + (op, mode == VOIDmode ? mode : Pmode)") > + (match_operand 0 "call_register_no_elim_operand") > +- (ior (and (not (match_test "TARGET_X32")) > ++ (ior (and (not (match_test "TARGET_X32 > ++ || ix86_indirect_branch_thunk_register")) > + (match_operand 0 "memory_operand")) > +- (and (match_test "TARGET_X32 && Pmode == DImode") > ++ (and (match_test "TARGET_X32 && Pmode == DImode > ++ && !ix86_indirect_branch_thunk_register") > + (match_operand 0 "GOT_memory_operand"))))) > + > + ;; Similarly, but for tail calls, in which we cannot allow memory references. > +@@ -688,14 +692,17 @@ > + (ior (match_test "constant_call_address_operand > + (op, mode == VOIDmode ? mode : Pmode)") > + (match_operand 0 "register_no_elim_operand") > +- (ior (and (not (match_test "TARGET_X32")) > ++ (ior (and (not (match_test "TARGET_X32 > ++ || ix86_indirect_branch_thunk_register")) > + (match_operand 0 "sibcall_memory_operand")) > +- (and (match_test "TARGET_X32 && Pmode == DImode") > ++ (and (match_test "TARGET_X32 && Pmode == DImode > ++ && !ix86_indirect_branch_thunk_register") > + (match_operand 0 "GOT_memory_operand"))))) > + > + ;; Return true if OP is a 32-bit GOT symbol operand. > + (define_predicate "GOT32_symbol_operand" > +- (match_test "GET_CODE (op) == CONST > ++ (match_test "!ix86_indirect_branch_thunk_register > ++ && GET_CODE (op) == CONST > + && GET_CODE (XEXP (op, 0)) == UNSPEC > + && XINT (XEXP (op, 0), 1) == UNSPEC_GOT")) > + > +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-register-1.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-register-1.c > +new file mode 100644 > +index 00000000000..ef493a05bbf > +--- /dev/null > ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-register-1.c > +@@ -0,0 +1,22 @@ > ++/* { dg-do compile } */ > ++/* { dg-options "-O2 -mindirect-branch=thunk -mindirect-branch-register -fno-pic" } */ > ++ > ++typedef void (*dispatch_t)(long offset); > ++ > ++dispatch_t dispatch; > ++ > ++void > ++male_indirect_jump (long offset) > ++{ > ++ dispatch(offset); > ++} > ++ > ++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk\.(r|e)ax" } } */ > ++/* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */ > ++/* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */ > ++/* { dg-final { scan-assembler "mov\[ \t\](%eax|%rax), \\((%esp|%rsp)\\)" } } */ > ++/* { dg-final { scan-assembler {\tlfence} } } */ > ++/* { dg-final { scan-assembler-not "push(?:l|q)\[ \t\]*_?dispatch" } } */ > ++/* { dg-final { scan-assembler-not "pushq\[ \t\]%rax" } } */ > ++/* { dg-final { scan-assembler-not "__x86.indirect_thunk\n" } } */ > ++/* { dg-final { scan-assembler-not "__x86.indirect_thunk_bnd\n" } } */ > +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-register-2.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-register-2.c > +new file mode 100644 > +index 00000000000..89fc8e6e6c4 > +--- /dev/null > ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-register-2.c > +@@ -0,0 +1,20 @@ > ++/* { dg-do compile } */ > ++/* { dg-options "-O2 -mindirect-branch=thunk-inline -mindirect-branch-register -fno-pic" } */ > ++ > ++typedef void (*dispatch_t)(long offset); > ++ > ++dispatch_t dispatch; > ++ > ++void > ++male_indirect_jump (long offset) > ++{ > ++ dispatch(offset); > ++} > ++ > ++/* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */ > ++/* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */ > ++/* { dg-final { scan-assembler "mov\[ \t\](%eax|%rax), \\((%esp|%rsp)\\)" } } */ > ++/* { dg-final { scan-assembler {\tlfence} } } */ > ++/* { dg-final { scan-assembler-not "push(?:l|q)\[ \t\]*_?dispatch" } } */ > ++/* { dg-final { scan-assembler-not "pushq\[ \t\]%rax" } } */ > ++/* { dg-final { scan-assembler-not "__x86.indirect_thunk" } } */ > +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-register-3.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-register-3.c > +new file mode 100644 > +index 00000000000..31af7ac05b8 > +--- /dev/null > ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-register-3.c > +@@ -0,0 +1,19 @@ > ++/* { dg-do compile } */ > ++/* { dg-options "-O2 -mindirect-branch=thunk-extern -mindirect-branch-register -fno-pic" } */ > ++ > ++typedef void (*dispatch_t)(long offset); > ++ > ++dispatch_t dispatch; > ++ > ++void > ++male_indirect_jump (long offset) > ++{ > ++ dispatch(offset); > ++} > ++ > ++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk\.(r|e)ax" } } */ > ++/* { dg-final { scan-assembler-not "push(?:l|q)\[ \t\]*_?dispatch" } } */ > ++/* { dg-final { scan-assembler-not "pushq\[ \t\]%rax" } } */ > ++/* { dg-final { scan-assembler-not {\t(lfence|pause|nop)} } } */ > ++/* { dg-final { scan-assembler-not "jmp\[ \t\]*\.LIND" } } */ > ++/* { dg-final { scan-assembler-not "call\[ \t\]*\.LIND" } } */ > +-- > +2.15.1 > + > diff --git a/gnu/packages/patches/gcc-retpoline-Add-mindirect-branch-thunk-extern.patch b/gnu/packages/patches/gcc-retpoline-Add-mindirect-branch-thunk-extern.patch > new file mode 100644 > index 000000000..18b2dfaea > --- /dev/null > +++ b/gnu/packages/patches/gcc-retpoline-Add-mindirect-branch-thunk-extern.patch > @@ -0,0 +1,263 @@ > +'Retpoline' mitigation technique for Spectre (branch target injection) > +[CVE-2017-5715]: > + > +https://security.googleblog.com/2018/01/more-details-about-mitigations-for-cpu_4.html > +https://support.google.com/faqs/answer/7625886 > +https://spectreattack.com/ > +https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2017-5715 > + > +Patch copied from the 'retpoline-20180107' branch of upstream source repository > +(please add new / update existing patches when new 'retpoline-xxxxxxxx' branch > +appears): > + > +http://git.infradead.org/users/dwmw2/gcc-retpoline.git > + > +From 4032162fb6d36e20091885d0558f91daaa0080d3 Mon Sep 17 00:00:00 2001 > +From: "H.J. Lu" <hjl.tools@gmail.com> > +Date: Mon, 27 Nov 2017 08:38:41 -0800 > +Subject: [PATCH 07/17] Add -mindirect-branch=thunk-extern > + > +Add -mindirect-branch=thunk-extern tests > +--- > + gcc/config/i386/i386-opts.h | 3 +- > + gcc/config/i386/i386.opt | 3 ++ > + .../gcc.target/i386/indirect-thunk-extern-1.c | 19 ++++++++++ > + .../gcc.target/i386/indirect-thunk-extern-2.c | 19 ++++++++++ > + .../gcc.target/i386/indirect-thunk-extern-3.c | 20 ++++++++++ > + .../gcc.target/i386/indirect-thunk-extern-4.c | 20 ++++++++++ > + .../gcc.target/i386/indirect-thunk-extern-5.c | 16 ++++++++ > + .../gcc.target/i386/indirect-thunk-extern-6.c | 17 +++++++++ > + .../gcc.target/i386/indirect-thunk-extern-7.c | 43 ++++++++++++++++++++++ > + 9 files changed, 159 insertions(+), 1 deletion(-) > + create mode 100644 gcc/testsuite/gcc.target/i386/indirect-thunk-extern-1.c > + create mode 100644 gcc/testsuite/gcc.target/i386/indirect-thunk-extern-2.c > + create mode 100644 gcc/testsuite/gcc.target/i386/indirect-thunk-extern-3.c > + create mode 100644 gcc/testsuite/gcc.target/i386/indirect-thunk-extern-4.c > + create mode 100644 gcc/testsuite/gcc.target/i386/indirect-thunk-extern-5.c > + create mode 100644 gcc/testsuite/gcc.target/i386/indirect-thunk-extern-6.c > + create mode 100644 gcc/testsuite/gcc.target/i386/indirect-thunk-extern-7.c > + > +diff --git a/gcc/config/i386/i386-opts.h b/gcc/config/i386/i386-opts.h > +index f301890575a..f8d80ba7ec6 100644 > +--- a/gcc/config/i386/i386-opts.h > ++++ b/gcc/config/i386/i386-opts.h > +@@ -102,7 +102,8 @@ enum stack_protector_guard { > + enum indirect_branch { > + indirect_branch_keep, > + indirect_branch_thunk, > +- indirect_branch_thunk_inline > ++ indirect_branch_thunk_inline, > ++ indirect_branch_thunk_extern > + }; > + > + #endif > +diff --git a/gcc/config/i386/i386.opt b/gcc/config/i386/i386.opt > +index 68484a75022..4a932e11bf6 100644 > +--- a/gcc/config/i386/i386.opt > ++++ b/gcc/config/i386/i386.opt > +@@ -944,3 +944,6 @@ Enum(indirect_branch) String(thunk) Value(indirect_branch_thunk) > + > + EnumValue > + Enum(indirect_branch) String(thunk-inline) Value(indirect_branch_thunk_inline) > ++ > ++EnumValue > ++Enum(indirect_branch) String(thunk-extern) Value(indirect_branch_thunk_extern) > +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-1.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-1.c > +new file mode 100644 > +index 00000000000..0a1f91be988 > +--- /dev/null > ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-1.c > +@@ -0,0 +1,19 @@ > ++/* { dg-do compile } */ > ++/* { dg-options "-O2 -mindirect-branch=thunk-extern -fno-pic" } */ > ++ > ++typedef void (*dispatch_t)(long offset); > ++ > ++dispatch_t dispatch; > ++ > ++void > ++male_indirect_jump (long offset) > ++{ > ++ dispatch(offset); > ++} > ++ > ++/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { ! x32 } } } } */ > ++/* { dg-final { scan-assembler "pushq\[ \t\]%rax" { target x32 } } } */ > ++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" } } */ > ++/* { dg-final { scan-assembler-not {\t(lfence|pause)} } } */ > ++/* { dg-final { scan-assembler-not "jmp\[ \t\]*\.LIND" } } */ > ++/* { dg-final { scan-assembler-not "call\[ \t\]*\.LIND" } } */ > +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-2.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-2.c > +new file mode 100644 > +index 00000000000..182520ab3dc > +--- /dev/null > ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-2.c > +@@ -0,0 +1,19 @@ > ++/* { dg-do compile } */ > ++/* { dg-options "-O2 -mindirect-branch=thunk-extern -fno-pic" } */ > ++ > ++typedef void (*dispatch_t)(long offset); > ++ > ++dispatch_t dispatch[256]; > ++ > ++void > ++male_indirect_jump (long offset) > ++{ > ++ dispatch[offset](offset); > ++} > ++ > ++/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { ! x32 } } } } */ > ++/* { dg-final { scan-assembler "pushq\[ \t\]%rax" { target x32 } } } */ > ++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" } } */ > ++/* { dg-final { scan-assembler-not {\t(lfence|pause)} } } */ > ++/* { dg-final { scan-assembler-not "jmp\[ \t\]*\.LIND" } } */ > ++/* { dg-final { scan-assembler-not "call\[ \t\]*\.LIND" } } */ > +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-3.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-3.c > +new file mode 100644 > +index 00000000000..5c31ddc34fd > +--- /dev/null > ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-3.c > +@@ -0,0 +1,20 @@ > ++/* { dg-do compile } */ > ++/* { dg-options "-O2 -mindirect-branch=thunk-extern -fno-pic" } */ > ++ > ++typedef void (*dispatch_t)(long offset); > ++ > ++dispatch_t dispatch; > ++ > ++int > ++male_indirect_jump (long offset) > ++{ > ++ dispatch(offset); > ++ return 0; > ++} > ++ > ++/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { ! x32 } } } } */ > ++/* { dg-final { scan-assembler "pushq\[ \t\]%rax" { target x32 } } } */ > ++/* { dg-final { scan-assembler-times "jmp\[ \t\]*\.LIND" 1 } } */ > ++/* { dg-final { scan-assembler-times "call\[ \t\]*\.LIND" 1 } } */ > ++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" } } */ > ++/* { dg-final { scan-assembler-not {\t(lfence|pause)} } } */ > +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-4.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-4.c > +new file mode 100644 > +index 00000000000..f24d0c060f2 > +--- /dev/null > ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-4.c > +@@ -0,0 +1,20 @@ > ++/* { dg-do compile } */ > ++/* { dg-options "-O2 -mindirect-branch=thunk-extern -fno-pic" } */ > ++ > ++typedef void (*dispatch_t)(long offset); > ++ > ++dispatch_t dispatch[256]; > ++ > ++int > ++male_indirect_jump (long offset) > ++{ > ++ dispatch[offset](offset); > ++ return 0; > ++} > ++ > ++/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { ! x32 } } } } */ > ++/* { dg-final { scan-assembler "pushq\[ \t\]%rax" { target x32 } } } */ > ++/* { dg-final { scan-assembler-times "jmp\[ \t\]*\.LIND" 1 } } */ > ++/* { dg-final { scan-assembler-times "call\[ \t\]*\.LIND" 1 } } */ > ++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" } } */ > ++/* { dg-final { scan-assembler-not {\t(lfence|pause)} } } */ > +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-5.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-5.c > +new file mode 100644 > +index 00000000000..ad54aaeac4c > +--- /dev/null > ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-5.c > +@@ -0,0 +1,16 @@ > ++/* { dg-do compile { target *-*-linux* } } */ > ++/* { dg-options "-O2 -fpic -fno-plt -mindirect-branch=thunk-extern" } */ > ++ > ++extern void bar (void); > ++ > ++void > ++foo (void) > ++{ > ++ bar (); > ++} > ++ > ++/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*bar@GOT" } } */ > ++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" } } */ > ++/* { dg-final { scan-assembler-not {\t(lfence|pause)} } } */ > ++/* { dg-final { scan-assembler-not "jmp\[ \t\]*\.LIND" } } */ > ++/* { dg-final { scan-assembler-not "call\[ \t\]*\.LIND" } } */ > +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-6.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-6.c > +new file mode 100644 > +index 00000000000..a8e75254cfe > +--- /dev/null > ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-6.c > +@@ -0,0 +1,17 @@ > ++/* { dg-do compile { target *-*-linux* } } */ > ++/* { dg-options "-O2 -fpic -fno-plt -mindirect-branch=thunk-extern" } */ > ++ > ++extern void bar (void); > ++ > ++int > ++foo (void) > ++{ > ++ bar (); > ++ return 0; > ++} > ++ > ++/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*bar@GOT" } } */ > ++/* { dg-final { scan-assembler-times "jmp\[ \t\]*\.LIND" 1 } } */ > ++/* { dg-final { scan-assembler-times "call\[ \t\]*\.LIND" 1 } } */ > ++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" } } */ > ++/* { dg-final { scan-assembler-not {\t(lfence|pause)} } } */ > +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-7.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-7.c > +new file mode 100644 > +index 00000000000..8d39fb6f939 > +--- /dev/null > ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-7.c > +@@ -0,0 +1,43 @@ > ++/* { dg-do compile } */ > ++/* { dg-options "-O2 -mindirect-branch=thunk-extern -fno-pic" } */ > ++ > ++void func0 (void); > ++void func1 (void); > ++void func2 (void); > ++void func3 (void); > ++void func4 (void); > ++void func4 (void); > ++void func5 (void); > ++ > ++void > ++bar (int i) > ++{ > ++ switch (i) > ++ { > ++ default: > ++ func0 (); > ++ break; > ++ case 1: > ++ func1 (); > ++ break; > ++ case 2: > ++ func2 (); > ++ break; > ++ case 3: > ++ func3 (); > ++ break; > ++ case 4: > ++ func4 (); > ++ break; > ++ case 5: > ++ func5 (); > ++ break; > ++ } > ++} > ++ > ++/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*\.L\[0-9\]+\\(,%" { target { ! x32 } } } } */ > ++/* { dg-final { scan-assembler "pushq\[ \t\]%rax" { target x32 } } } */ > ++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" } } */ > ++/* { dg-final { scan-assembler-not {\t(lfence|pause)} } } */ > ++/* { dg-final { scan-assembler-not "jmp\[ \t\]*\.LIND" } } */ > ++/* { dg-final { scan-assembler-not "call\[ \t\]*\.LIND" } } */ > +-- > +2.15.1 > + > diff --git a/gnu/packages/patches/gcc-retpoline-Add-mindirect-branch-thunk-inline.patch b/gnu/packages/patches/gcc-retpoline-Add-mindirect-branch-thunk-inline.patch > new file mode 100644 > index 000000000..bb12c0e95 > --- /dev/null > +++ b/gnu/packages/patches/gcc-retpoline-Add-mindirect-branch-thunk-inline.patch > @@ -0,0 +1,310 @@ > +'Retpoline' mitigation technique for Spectre (branch target injection) > +[CVE-2017-5715]: > + > +https://security.googleblog.com/2018/01/more-details-about-mitigations-for-cpu_4.html > +https://support.google.com/faqs/answer/7625886 > +https://spectreattack.com/ > +https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2017-5715 > + > +Patch copied from the 'retpoline-20180107' branch of upstream source repository > +(please add new / update existing patches when new 'retpoline-xxxxxxxx' branch > +appears): > + > +http://git.infradead.org/users/dwmw2/gcc-retpoline.git > + > +From 7f4f2bf1688c81496107993080e68a29a24de702 Mon Sep 17 00:00:00 2001 > +From: "H.J. Lu" <hjl.tools@gmail.com> > +Date: Wed, 15 Nov 2017 11:20:31 -0800 > +Subject: [PATCH 06/17] Add -mindirect-branch=thunk-inline > + > +Add -mindirect-branch=thunk-inline tests > +--- > + gcc/config/i386/i386-opts.h | 3 +- > + gcc/config/i386/i386.c | 30 +++++++++++----- > + gcc/config/i386/i386.opt | 3 ++ > + .../gcc.target/i386/indirect-thunk-inline-1.c | 18 ++++++++++ > + .../gcc.target/i386/indirect-thunk-inline-2.c | 18 ++++++++++ > + .../gcc.target/i386/indirect-thunk-inline-3.c | 19 ++++++++++ > + .../gcc.target/i386/indirect-thunk-inline-4.c | 19 ++++++++++ > + .../gcc.target/i386/indirect-thunk-inline-5.c | 15 ++++++++ > + .../gcc.target/i386/indirect-thunk-inline-6.c | 16 +++++++++ > + .../gcc.target/i386/indirect-thunk-inline-7.c | 42 ++++++++++++++++++++++ > + 10 files changed, 173 insertions(+), 10 deletions(-) > + create mode 100644 gcc/testsuite/gcc.target/i386/indirect-thunk-inline-1.c > + create mode 100644 gcc/testsuite/gcc.target/i386/indirect-thunk-inline-2.c > + create mode 100644 gcc/testsuite/gcc.target/i386/indirect-thunk-inline-3.c > + create mode 100644 gcc/testsuite/gcc.target/i386/indirect-thunk-inline-4.c > + create mode 100644 gcc/testsuite/gcc.target/i386/indirect-thunk-inline-5.c > + create mode 100644 gcc/testsuite/gcc.target/i386/indirect-thunk-inline-6.c > + create mode 100644 gcc/testsuite/gcc.target/i386/indirect-thunk-inline-7.c > + > +diff --git a/gcc/config/i386/i386-opts.h b/gcc/config/i386/i386-opts.h > +index 1565d8fdc65..f301890575a 100644 > +--- a/gcc/config/i386/i386-opts.h > ++++ b/gcc/config/i386/i386-opts.h > +@@ -101,7 +101,8 @@ enum stack_protector_guard { > + > + enum indirect_branch { > + indirect_branch_keep, > +- indirect_branch_thunk > ++ indirect_branch_thunk, > ++ indirect_branch_thunk_inline > + }; > + > + #endif > +diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c > +index 96424361a1c..ac542f79846 100644 > +--- a/gcc/config/i386/i386.c > ++++ b/gcc/config/i386/i386.c > +@@ -28600,16 +28600,23 @@ static void > + ix86_output_indirect_branch (rtx call_op, const char *xasm, > + bool sibcall_p) > + { > +- char thunk_name[32]; > ++ char thunk_name_buf[32]; > ++ char *thunk_name; > + char push_buf[64]; > + bool need_bnd_p = ix86_bnd_prefixed_insn_p (current_output_insn); > + > +- bool need_thunk = ix86_indirect_branch == indirect_branch_thunk; > +- if (need_bnd_p) > +- indirect_thunk_bnd_needed |= need_thunk; > ++ if (ix86_indirect_branch != indirect_branch_thunk_inline) > ++ { > ++ bool need_thunk = ix86_indirect_branch == indirect_branch_thunk; > ++ if (need_bnd_p) > ++ indirect_thunk_bnd_needed |= need_thunk; > ++ else > ++ indirect_thunk_needed |= need_thunk; > ++ indirect_thunk_name (thunk_name_buf, need_bnd_p); > ++ thunk_name = thunk_name_buf; > ++ } > + else > +- indirect_thunk_needed |= need_thunk; > +- indirect_thunk_name (thunk_name, need_bnd_p); > ++ thunk_name = NULL; > + > + snprintf (push_buf, sizeof (push_buf), "push{%c}\t%s", > + TARGET_64BIT ? 'q' : 'l', xasm); > +@@ -28683,10 +28690,15 @@ ix86_output_indirect_branch (rtx call_op, const char *xasm, > + > + output_asm_insn (push_buf, &call_op); > + > +- if (need_bnd_p) > +- fprintf (asm_out_file, "\tbnd jmp\t%s\n", thunk_name); > ++ if (thunk_name != NULL) > ++ { > ++ if (need_bnd_p) > ++ fprintf (asm_out_file, "\tbnd jmp\t%s\n", thunk_name); > ++ else > ++ fprintf (asm_out_file, "\tjmp\t%s\n", thunk_name); > ++ } > + else > +- fprintf (asm_out_file, "\tjmp\t%s\n", thunk_name); > ++ output_indirect_thunk (need_bnd_p); > + > + ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, indirectlabel2); > + > +diff --git a/gcc/config/i386/i386.opt b/gcc/config/i386/i386.opt > +index 1773e5614cf..68484a75022 100644 > +--- a/gcc/config/i386/i386.opt > ++++ b/gcc/config/i386/i386.opt > +@@ -941,3 +941,6 @@ Enum(indirect_branch) String(keep) Value(indirect_branch_keep) > + > + EnumValue > + Enum(indirect_branch) String(thunk) Value(indirect_branch_thunk) > ++ > ++EnumValue > ++Enum(indirect_branch) String(thunk-inline) Value(indirect_branch_thunk_inline) > +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-1.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-1.c > +new file mode 100644 > +index 00000000000..071e6c89ac7 > +--- /dev/null > ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-1.c > +@@ -0,0 +1,18 @@ > ++/* { dg-do compile } */ > ++/* { dg-options "-O2 -mindirect-branch=thunk-inline -fno-pic" } */ > ++ > ++typedef void (*dispatch_t)(long offset); > ++ > ++dispatch_t dispatch; > ++ > ++void > ++male_indirect_jump (long offset) > ++{ > ++ dispatch(offset); > ++} > ++ > ++/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { ! x32 } } } } */ > ++/* { dg-final { scan-assembler "pushq\[ \t\]%rax" { target x32 } } } */ > ++/* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */ > ++/* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */ > ++/* { dg-final { scan-assembler-not "__x86.indirect_thunk" } } */ > +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-2.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-2.c > +new file mode 100644 > +index 00000000000..804c7ccdba7 > +--- /dev/null > ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-2.c > +@@ -0,0 +1,18 @@ > ++/* { dg-do compile } */ > ++/* { dg-options "-O2 -mindirect-branch=thunk-inline -fno-pic" } */ > ++ > ++typedef void (*dispatch_t)(long offset); > ++ > ++dispatch_t dispatch[256]; > ++ > ++void > ++male_indirect_jump (long offset) > ++{ > ++ dispatch[offset](offset); > ++} > ++ > ++/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { ! x32 } } } } */ > ++/* { dg-final { scan-assembler "pushq\[ \t\]%rax" { target x32 } } } */ > ++/* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */ > ++/* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */ > ++/* { dg-final { scan-assembler-not "__x86.indirect_thunk" } } */ > +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-3.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-3.c > +new file mode 100644 > +index 00000000000..545a981add5 > +--- /dev/null > ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-3.c > +@@ -0,0 +1,19 @@ > ++/* { dg-do compile } */ > ++/* { dg-options "-O2 -mindirect-branch=thunk-inline -fno-pic" } */ > ++ > ++typedef void (*dispatch_t)(long offset); > ++ > ++dispatch_t dispatch; > ++ > ++int > ++male_indirect_jump (long offset) > ++{ > ++ dispatch(offset); > ++ return 0; > ++} > ++ > ++/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { ! x32 } } } } */ > ++/* { dg-final { scan-assembler "pushq\[ \t\]%rax" { target x32 } } } */ > ++/* { dg-final { scan-assembler-times "jmp\[ \t\]*\.LIND" 2 } } */ > ++/* { dg-final { scan-assembler-times "call\[ \t\]*\.LIND" 2 } } */ > ++/* { dg-final { scan-assembler-not "__x86.indirect_thunk" } } */ > +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-4.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-4.c > +new file mode 100644 > +index 00000000000..d9ff4722cff > +--- /dev/null > ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-4.c > +@@ -0,0 +1,19 @@ > ++/* { dg-do compile } */ > ++/* { dg-options "-O2 -mindirect-branch=thunk-inline -fno-pic" } */ > ++ > ++typedef void (*dispatch_t)(long offset); > ++ > ++dispatch_t dispatch[256]; > ++ > ++int > ++male_indirect_jump (long offset) > ++{ > ++ dispatch[offset](offset); > ++ return 0; > ++} > ++ > ++/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { ! x32 } } } } */ > ++/* { dg-final { scan-assembler "pushq\[ \t\]%rax" { target x32 } } } */ > ++/* { dg-final { scan-assembler-times "jmp\[ \t\]*\.LIND" 2 } } */ > ++/* { dg-final { scan-assembler-times "call\[ \t\]*\.LIND" 2 } } */ > ++/* { dg-final { scan-assembler-not "__x86.indirect_thunk" } } */ > +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-5.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-5.c > +new file mode 100644 > +index 00000000000..f4890fe97b2 > +--- /dev/null > ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-5.c > +@@ -0,0 +1,15 @@ > ++/* { dg-do compile { target *-*-linux* } } */ > ++/* { dg-options "-O2 -fpic -fno-plt -mindirect-branch=thunk-inline" } */ > ++ > ++extern void bar (void); > ++ > ++void > ++foo (void) > ++{ > ++ bar (); > ++} > ++ > ++/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*bar@GOT" } } */ > ++/* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */ > ++/* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */ > ++/* { dg-final { scan-assembler-not "__x86.indirect_thunk" } } */ > +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-6.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-6.c > +new file mode 100644 > +index 00000000000..81b09e73ab8 > +--- /dev/null > ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-6.c > +@@ -0,0 +1,16 @@ > ++/* { dg-do compile { target *-*-linux* } } */ > ++/* { dg-options "-O2 -fpic -fno-plt -mindirect-branch=thunk-inline" } */ > ++ > ++extern void bar (void); > ++ > ++int > ++foo (void) > ++{ > ++ bar (); > ++ return 0; > ++} > ++ > ++/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*bar@GOT" } } */ > ++/* { dg-final { scan-assembler-times "jmp\[ \t\]*\.LIND" 2 } } */ > ++/* { dg-final { scan-assembler-times "call\[ \t\]*\.LIND" 2 } } */ > ++/* { dg-final { scan-assembler-not "__x86.indirect_thunk" } } */ > +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-7.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-7.c > +new file mode 100644 > +index 00000000000..a0ce06b8232 > +--- /dev/null > ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-7.c > +@@ -0,0 +1,42 @@ > ++/* { dg-do compile } */ > ++/* { dg-options "-O2 -mindirect-branch=thunk-inline -fno-pic" } */ > ++ > ++void func0 (void); > ++void func1 (void); > ++void func2 (void); > ++void func3 (void); > ++void func4 (void); > ++void func4 (void); > ++void func5 (void); > ++ > ++void > ++bar (int i) > ++{ > ++ switch (i) > ++ { > ++ default: > ++ func0 (); > ++ break; > ++ case 1: > ++ func1 (); > ++ break; > ++ case 2: > ++ func2 (); > ++ break; > ++ case 3: > ++ func3 (); > ++ break; > ++ case 4: > ++ func4 (); > ++ break; > ++ case 5: > ++ func5 (); > ++ break; > ++ } > ++} > ++ > ++/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*\.L\[0-9\]+\\(,%" { target { ! x32 } } } } */ > ++/* { dg-final { scan-assembler "pushq\[ \t\]%rax" { target x32 } } } */ > ++/* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */ > ++/* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */ > ++/* { dg-final { scan-assembler-not "__x86.indirect_thunk" } } */ > +-- > +2.15.1 > + > diff --git a/gnu/packages/patches/gcc-retpoline-Add-mindirect-branch-thunk.patch b/gnu/packages/patches/gcc-retpoline-Add-mindirect-branch-thunk.patch > new file mode 100644 > index 000000000..edb9a8de5 > --- /dev/null > +++ b/gnu/packages/patches/gcc-retpoline-Add-mindirect-branch-thunk.patch > @@ -0,0 +1,729 @@ > +'Retpoline' mitigation technique for Spectre (branch target injection) > +[CVE-2017-5715]: > + > +https://security.googleblog.com/2018/01/more-details-about-mitigations-for-cpu_4.html > +https://support.google.com/faqs/answer/7625886 > +https://spectreattack.com/ > +https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2017-5715 > + > +Patch copied from the 'retpoline-20180107' branch of upstream source repository > +(please add new / update existing patches when new 'retpoline-xxxxxxxx' branch > +appears): > + > +http://git.infradead.org/users/dwmw2/gcc-retpoline.git > + > +From 63024dad9c00f1613738fd766e2f0afd455b76d1 Mon Sep 17 00:00:00 2001 > +From: "H.J. Lu" <hjl.tools@gmail.com> > +Date: Wed, 1 Nov 2017 16:05:50 -0700 > +Subject: [PATCH 04/17] Add -mindirect-branch=thunk > + > +Add tests for -mindirect-branch=thunk > +--- > + gcc/config/i386/i386-opts.h | 5 + > + gcc/config/i386/i386-protos.h | 1 + > + gcc/config/i386/i386.c | 318 ++++++++++++++++++++++- > + gcc/config/i386/i386.md | 6 +- > + gcc/config/i386/i386.opt | 14 + > + gcc/doc/invoke.texi | 9 +- > + gcc/testsuite/gcc.target/i386/indirect-thunk-1.c | 19 ++ > + gcc/testsuite/gcc.target/i386/indirect-thunk-2.c | 19 ++ > + gcc/testsuite/gcc.target/i386/indirect-thunk-3.c | 20 ++ > + gcc/testsuite/gcc.target/i386/indirect-thunk-4.c | 20 ++ > + gcc/testsuite/gcc.target/i386/indirect-thunk-5.c | 16 ++ > + gcc/testsuite/gcc.target/i386/indirect-thunk-6.c | 17 ++ > + gcc/testsuite/gcc.target/i386/indirect-thunk-7.c | 43 +++ > + 13 files changed, 495 insertions(+), 12 deletions(-) > + create mode 100644 gcc/testsuite/gcc.target/i386/indirect-thunk-1.c > + create mode 100644 gcc/testsuite/gcc.target/i386/indirect-thunk-2.c > + create mode 100644 gcc/testsuite/gcc.target/i386/indirect-thunk-3.c > + create mode 100644 gcc/testsuite/gcc.target/i386/indirect-thunk-4.c > + create mode 100644 gcc/testsuite/gcc.target/i386/indirect-thunk-5.c > + create mode 100644 gcc/testsuite/gcc.target/i386/indirect-thunk-6.c > + create mode 100644 gcc/testsuite/gcc.target/i386/indirect-thunk-7.c > + > +diff --git a/gcc/config/i386/i386-opts.h b/gcc/config/i386/i386-opts.h > +index 542cd0f3d67..1565d8fdc65 100644 > +--- a/gcc/config/i386/i386-opts.h > ++++ b/gcc/config/i386/i386-opts.h > +@@ -99,4 +99,9 @@ enum stack_protector_guard { > + SSP_GLOBAL /* global canary */ > + }; > + > ++enum indirect_branch { > ++ indirect_branch_keep, > ++ indirect_branch_thunk > ++}; > ++ > + #endif > +diff --git a/gcc/config/i386/i386-protos.h b/gcc/config/i386/i386-protos.h > +index 8bdd67eb608..b746429f420 100644 > +--- a/gcc/config/i386/i386-protos.h > ++++ b/gcc/config/i386/i386-protos.h > +@@ -315,6 +315,7 @@ extern enum attr_cpu ix86_schedule; > + #endif > + > + extern const char * ix86_output_call_insn (rtx_insn *insn, rtx call_op); > ++extern const char * ix86_output_indirect_jmp (rtx call_op); > + extern bool ix86_operands_ok_for_move_multiple (rtx *operands, bool load, > + enum machine_mode mode); > + > +diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c > +index 504530a00cf..96424361a1c 100644 > +--- a/gcc/config/i386/i386.c > ++++ b/gcc/config/i386/i386.c > +@@ -11909,6 +11909,145 @@ ix86_setup_frame_addresses (void) > + # endif > + #endif > + > ++static int indirectlabelno; > ++static bool indirect_thunk_needed = false; > ++static bool indirect_thunk_bnd_needed = false; > ++ > ++#ifndef INDIRECT_LABEL > ++# define INDIRECT_LABEL "LIND" > ++#endif > ++ > ++/* Fills in the label name that should be used for the indirect thunk. */ > ++ > ++static void > ++indirect_thunk_name (char name[32], bool need_bnd_p) > ++{ > ++ if (USE_HIDDEN_LINKONCE) > ++ { > ++ const char *bnd = need_bnd_p ? "_bnd" : ""; > ++ sprintf (name, "__x86.indirect_thunk%s", bnd); > ++ } > ++ else > ++ { > ++ if (need_bnd_p) > ++ ASM_GENERATE_INTERNAL_LABEL (name, "LITB", 0); > ++ else > ++ ASM_GENERATE_INTERNAL_LABEL (name, "LIT", 0); > ++ } > ++} > ++ > ++static void > ++output_indirect_thunk (bool need_bnd_p) > ++{ > ++ char indirectlabel1[32]; > ++ char indirectlabel2[32]; > ++ > ++ ASM_GENERATE_INTERNAL_LABEL (indirectlabel1, INDIRECT_LABEL, > ++ indirectlabelno++); > ++ ASM_GENERATE_INTERNAL_LABEL (indirectlabel2, INDIRECT_LABEL, > ++ indirectlabelno++); > ++ > ++ /* Call */ > ++ if (need_bnd_p) > ++ fputs ("\tbnd call\t", asm_out_file); > ++ else > ++ fputs ("\tcall\t", asm_out_file); > ++ assemble_name_raw (asm_out_file, indirectlabel2); > ++ fputc ('\n', asm_out_file); > ++ > ++ ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, indirectlabel1); > ++ > ++ /* lfence . */ > ++ fprintf (asm_out_file, "\tlfence\n"); > ++ > ++ /* Jump. */ > ++ fputs ("\tjmp\t", asm_out_file); > ++ assemble_name_raw (asm_out_file, indirectlabel1); > ++ fputc ('\n', asm_out_file); > ++ > ++ ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, indirectlabel2); > ++ > ++ /* LEA. */ > ++ rtx xops[2]; > ++ xops[0] = stack_pointer_rtx; > ++ xops[1] = plus_constant (Pmode, stack_pointer_rtx, UNITS_PER_WORD); > ++ output_asm_insn ("lea\t{%E1, %0|%0, %E1}", xops); > ++ > ++ if (need_bnd_p) > ++ fputs ("\tbnd ret\n", asm_out_file); > ++ else > ++ fputs ("\tret\n", asm_out_file); > ++} > ++ > ++static void > ++output_indirect_thunk_function (bool need_bnd_p) > ++{ > ++ char name[32]; > ++ tree decl; > ++ > ++ indirect_thunk_name (name, need_bnd_p); > ++ decl = build_decl (BUILTINS_LOCATION, FUNCTION_DECL, > ++ get_identifier (name), > ++ build_function_type_list (void_type_node, NULL_TREE)); > ++ DECL_RESULT (decl) = build_decl (BUILTINS_LOCATION, RESULT_DECL, > ++ NULL_TREE, void_type_node); > ++ TREE_PUBLIC (decl) = 1; > ++ TREE_STATIC (decl) = 1; > ++ DECL_IGNORED_P (decl) = 1; > ++ > ++#if TARGET_MACHO > ++ if (TARGET_MACHO) > ++ { > ++ switch_to_section (darwin_sections[picbase_thunk_section]); > ++ fputs ("\t.weak_definition\t", asm_out_file); > ++ assemble_name (asm_out_file, name); > ++ fputs ("\n\t.private_extern\t", asm_out_file); > ++ assemble_name (asm_out_file, name); > ++ putc ('\n', asm_out_file); > ++ ASM_OUTPUT_LABEL (asm_out_file, name); > ++ DECL_WEAK (decl) = 1; > ++ } > ++ else > ++#endif > ++ if (USE_HIDDEN_LINKONCE) > ++ { > ++ cgraph_node::create (decl)->set_comdat_group (DECL_ASSEMBLER_NAME (decl)); > ++ > ++ targetm.asm_out.unique_section (decl, 0); > ++ switch_to_section (get_named_section (decl, NULL, 0)); > ++ > ++ targetm.asm_out.globalize_label (asm_out_file, name); > ++ fputs ("\t.hidden\t", asm_out_file); > ++ assemble_name (asm_out_file, name); > ++ putc ('\n', asm_out_file); > ++ ASM_DECLARE_FUNCTION_NAME (asm_out_file, name, decl); > ++ } > ++ else > ++ { > ++ switch_to_section (text_section); > ++ ASM_OUTPUT_LABEL (asm_out_file, name); > ++ } > ++ > ++ DECL_INITIAL (decl) = make_node (BLOCK); > ++ current_function_decl = decl; > ++ allocate_struct_function (decl, false); > ++ init_function_start (decl); > ++ /* We're about to hide the function body from callees of final_* by > ++ emitting it directly; tell them we're a thunk, if they care. */ > ++ cfun->is_thunk = true; > ++ first_function_block_is_cold = false; > ++ /* Make sure unwind info is emitted for the thunk if needed. */ > ++ final_start_function (emit_barrier (), asm_out_file, 1); > ++ > ++ output_indirect_thunk (need_bnd_p); > ++ > ++ final_end_function (); > ++ init_insn_lengths (); > ++ free_after_compilation (cfun); > ++ set_cfun (NULL); > ++ current_function_decl = NULL; > ++} > ++ > + static int pic_labels_used; > + > + /* Fills in the label name that should be used for a pc thunk for > +@@ -11935,6 +12074,11 @@ ix86_code_end (void) > + rtx xops[2]; > + int regno; > + > ++ if (indirect_thunk_needed) > ++ output_indirect_thunk_function (false); > ++ if (indirect_thunk_bnd_needed) > ++ output_indirect_thunk_function (true); > ++ > + for (regno = AX_REG; regno <= SP_REG; regno++) > + { > + char name[32]; > +@@ -28452,12 +28596,132 @@ ix86_nopic_noplt_attribute_p (rtx call_op) > + return false; > + } > + > ++static void > ++ix86_output_indirect_branch (rtx call_op, const char *xasm, > ++ bool sibcall_p) > ++{ > ++ char thunk_name[32]; > ++ char push_buf[64]; > ++ bool need_bnd_p = ix86_bnd_prefixed_insn_p (current_output_insn); > ++ > ++ bool need_thunk = ix86_indirect_branch == indirect_branch_thunk; > ++ if (need_bnd_p) > ++ indirect_thunk_bnd_needed |= need_thunk; > ++ else > ++ indirect_thunk_needed |= need_thunk; > ++ indirect_thunk_name (thunk_name, need_bnd_p); > ++ > ++ snprintf (push_buf, sizeof (push_buf), "push{%c}\t%s", > ++ TARGET_64BIT ? 'q' : 'l', xasm); > ++ > ++ if (sibcall_p) > ++ { > ++ output_asm_insn (push_buf, &call_op); > ++ if (thunk_name != NULL) > ++ { > ++ if (need_bnd_p) > ++ fprintf (asm_out_file, "\tbnd jmp\t%s\n", thunk_name); > ++ else > ++ fprintf (asm_out_file, "\tjmp\t%s\n", thunk_name); > ++ } > ++ else > ++ output_indirect_thunk (need_bnd_p); > ++ } > ++ else > ++ { > ++ char indirectlabel1[32]; > ++ char indirectlabel2[32]; > ++ > ++ ASM_GENERATE_INTERNAL_LABEL (indirectlabel1, > ++ INDIRECT_LABEL, > ++ indirectlabelno++); > ++ ASM_GENERATE_INTERNAL_LABEL (indirectlabel2, > ++ INDIRECT_LABEL, > ++ indirectlabelno++); > ++ > ++ /* Jump. */ > ++ if (need_bnd_p) > ++ fputs ("\tbnd jmp\t", asm_out_file); > ++ else > ++ fputs ("\tjmp\t", asm_out_file); > ++ assemble_name_raw (asm_out_file, indirectlabel2); > ++ fputc ('\n', asm_out_file); > ++ > ++ ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, indirectlabel1); > ++ > ++ if (MEM_P (call_op)) > ++ { > ++ struct ix86_address parts; > ++ rtx addr = XEXP (call_op, 0); > ++ if (ix86_decompose_address (addr, &parts) > ++ && parts.base == stack_pointer_rtx) > ++ { > ++ /* Since call will adjust stack by -UNITS_PER_WORD, > ++ we must convert "disp(stack, index, scale)" to > ++ "disp+UNITS_PER_WORD(stack, index, scale)". */ > ++ if (parts.index) > ++ { > ++ addr = gen_rtx_MULT (Pmode, parts.index, > ++ GEN_INT (parts.scale)); > ++ addr = gen_rtx_PLUS (Pmode, stack_pointer_rtx, > ++ addr); > ++ } > ++ else > ++ addr = stack_pointer_rtx; > ++ > ++ rtx disp; > ++ if (parts.disp != NULL_RTX) > ++ disp = plus_constant (Pmode, parts.disp, > ++ UNITS_PER_WORD); > ++ else > ++ disp = GEN_INT (UNITS_PER_WORD); > ++ > ++ addr = gen_rtx_PLUS (Pmode, addr, disp); > ++ call_op = gen_rtx_MEM (GET_MODE (call_op), addr); > ++ } > ++ } > ++ > ++ output_asm_insn (push_buf, &call_op); > ++ > ++ if (need_bnd_p) > ++ fprintf (asm_out_file, "\tbnd jmp\t%s\n", thunk_name); > ++ else > ++ fprintf (asm_out_file, "\tjmp\t%s\n", thunk_name); > ++ > ++ ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, indirectlabel2); > ++ > ++ /* Call. */ > ++ if (need_bnd_p) > ++ fputs ("\tbnd call\t", asm_out_file); > ++ else > ++ fputs ("\tcall\t", asm_out_file); > ++ assemble_name_raw (asm_out_file, indirectlabel1); > ++ fputc ('\n', asm_out_file); > ++ } > ++} > ++ > ++const char * > ++ix86_output_indirect_jmp (rtx call_op) > ++{ > ++ if (ix86_red_zone_size == 0 > ++ && ix86_indirect_branch != indirect_branch_keep) > ++ { > ++ ix86_output_indirect_branch (call_op, "%0", true); > ++ return ""; > ++ } > ++ else > ++ return "%!jmp\t%A0"; > ++} > ++ > + /* Output the assembly for a call instruction. */ > + > + const char * > + ix86_output_call_insn (rtx_insn *insn, rtx call_op) > + { > + bool direct_p = constant_call_address_operand (call_op, VOIDmode); > ++ bool output_indirect_p > ++ = (!TARGET_SEH > ++ && ix86_indirect_branch != indirect_branch_keep); > + bool seh_nop_p = false; > + const char *xasm; > + > +@@ -28467,10 +28731,21 @@ ix86_output_call_insn (rtx_insn *insn, rtx call_op) > + { > + if (ix86_nopic_noplt_attribute_p (call_op)) > + { > ++ direct_p = false; > + if (TARGET_64BIT) > +- xasm = "%!jmp\t{*%p0@GOTPCREL(%%rip)|[QWORD PTR %p0@GOTPCREL[rip]]}"; > ++ { > ++ if (output_indirect_p) > ++ xasm = "{%p0@GOTPCREL(%%rip)|[QWORD PTR %p0@GOTPCREL[rip]]}"; > ++ else > ++ xasm = "%!jmp\t{*%p0@GOTPCREL(%%rip)|[QWORD PTR %p0@GOTPCREL[rip]]}"; > ++ } > + else > +- xasm = "%!jmp\t{*%p0@GOT|[DWORD PTR %p0@GOT]}"; > ++ { > ++ if (output_indirect_p) > ++ xasm = "{%p0@GOT|[DWORD PTR %p0@GOT]}"; > ++ else > ++ xasm = "%!jmp\t{*%p0@GOT|[DWORD PTR %p0@GOT]}"; > ++ } > + } > + else > + xasm = "%!jmp\t%P0"; > +@@ -28480,9 +28755,17 @@ ix86_output_call_insn (rtx_insn *insn, rtx call_op) > + else if (TARGET_SEH) > + xasm = "%!rex.W jmp\t%A0"; > + else > +- xasm = "%!jmp\t%A0"; > ++ { > ++ if (output_indirect_p) > ++ xasm = "%0"; > ++ else > ++ xasm = "%!jmp\t%A0"; > ++ } > + > +- output_asm_insn (xasm, &call_op); > ++ if (output_indirect_p && !direct_p) > ++ ix86_output_indirect_branch (call_op, xasm, true); > ++ else > ++ output_asm_insn (xasm, &call_op); > + return ""; > + } > + > +@@ -28520,18 +28803,37 @@ ix86_output_call_insn (rtx_insn *insn, rtx call_op) > + { > + if (ix86_nopic_noplt_attribute_p (call_op)) > + { > ++ direct_p = false; > + if (TARGET_64BIT) > +- xasm = "%!call\t{*%p0@GOTPCREL(%%rip)|[QWORD PTR %p0@GOTPCREL[rip]]}"; > ++ { > ++ if (output_indirect_p) > ++ xasm = "{%p0@GOTPCREL(%%rip)|[QWORD PTR %p0@GOTPCREL[rip]]}"; > ++ else > ++ xasm = "%!call\t{*%p0@GOTPCREL(%%rip)|[QWORD PTR %p0@GOTPCREL[rip]]}"; > ++ } > + else > +- xasm = "%!call\t{*%p0@GOT|[DWORD PTR %p0@GOT]}"; > ++ { > ++ if (output_indirect_p) > ++ xasm = "{%p0@GOT|[DWORD PTR %p0@GOT]}"; > ++ else > ++ xasm = "%!call\t{*%p0@GOT|[DWORD PTR %p0@GOT]}"; > ++ } > + } > + else > + xasm = "%!call\t%P0"; > + } > + else > +- xasm = "%!call\t%A0"; > ++ { > ++ if (output_indirect_p) > ++ xasm = "%0"; > ++ else > ++ xasm = "%!call\t%A0"; > ++ } > + > +- output_asm_insn (xasm, &call_op); > ++ if (output_indirect_p && !direct_p) > ++ ix86_output_indirect_branch (call_op, xasm, false); > ++ else > ++ output_asm_insn (xasm, &call_op); > + > + if (seh_nop_p) > + return "nop"; > +diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md > +index 81cfba57afc..01b7b2039e6 100644 > +--- a/gcc/config/i386/i386.md > ++++ b/gcc/config/i386/i386.md > +@@ -11615,7 +11615,7 @@ > + (define_insn "*indirect_jump" > + [(set (pc) (match_operand:W 0 "indirect_branch_operand" "rBw"))] > + "" > +- "%!jmp\t%A0" > ++ "* return ix86_output_indirect_jmp (operands[0]);" > + [(set_attr "type" "ibr") > + (set_attr "length_immediate" "0") > + (set_attr "maybe_prefix_bnd" "1")]) > +@@ -11665,7 +11665,7 @@ > + [(set (pc) (match_operand:W 0 "indirect_branch_operand" "rBw")) > + (use (label_ref (match_operand 1)))] > + "" > +- "%!jmp\t%A0" > ++ "* return ix86_output_indirect_jmp (operands[0]);" > + [(set_attr "type" "ibr") > + (set_attr "length_immediate" "0") > + (set_attr "maybe_prefix_bnd" "1")]) > +@@ -12337,7 +12337,7 @@ > + [(simple_return) > + (use (match_operand:SI 0 "register_operand" "r"))] > + "reload_completed" > +- "%!jmp\t%A0" > ++ "* return ix86_output_indirect_jmp (operands[0]);" > + [(set_attr "type" "ibr") > + (set_attr "length_immediate" "0") > + (set_attr "maybe_prefix_bnd" "1")]) > +diff --git a/gcc/config/i386/i386.opt b/gcc/config/i386/i386.opt > +index 9384e29b1de..1773e5614cf 100644 > +--- a/gcc/config/i386/i386.opt > ++++ b/gcc/config/i386/i386.opt > +@@ -927,3 +927,17 @@ Attempt to avoid generating instruction sequences containing ret bytes. > + mgeneral-regs-only > + Target Report RejectNegative Mask(GENERAL_REGS_ONLY) Var(ix86_target_flags) Save > + Generate code which uses only the general registers. > ++ > ++mindirect-branch= > ++Target Report RejectNegative Joined Enum(indirect_branch) Var(ix86_indirect_branch) Init(indirect_branch_keep) > ++Update indirect call and jump. > ++ > ++Enum > ++Name(indirect_branch) Type(enum indirect_branch) > ++Known indirect branch choices (for use with the -mindirect-branch= option): > ++ > ++EnumValue > ++Enum(indirect_branch) String(keep) Value(indirect_branch_keep) > ++ > ++EnumValue > ++Enum(indirect_branch) String(thunk) Value(indirect_branch_thunk) > +diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi > +index a0fb09eb9e1..fafda2926bd 100644 > +--- a/gcc/doc/invoke.texi > ++++ b/gcc/doc/invoke.texi > +@@ -1210,7 +1210,7 @@ See RS/6000 and PowerPC Options. > + -msse2avx -mfentry -mrecord-mcount -mnop-mcount -m8bit-idiv @gol > + -mavx256-split-unaligned-load -mavx256-split-unaligned-store @gol > + -malign-data=@var{type} -mstack-protector-guard=@var{guard} @gol > +--mmitigate-rop -mgeneral-regs-only} > ++-mmitigate-rop -mgeneral-regs-only -mindirect-branch=@var{choice}} > + > + @emph{x86 Windows Options} > + @gccoptlist{-mconsole -mcygwin -mno-cygwin -mdll @gol > +@@ -25648,6 +25648,13 @@ Generate code that uses only the general-purpose registers. This > + prevents the compiler from using floating-point, vector, mask and bound > + registers. > + > ++@item -mindirect-branch=@var{choice} > ++@opindex -mindirect-branch > ++Update indirect call and jump with @var{choice}. The default is > ++@samp{keep}, which keeps indirect call and jump unmodified. > ++@samp{thunk} converts indirect call and jump to push and > ++PC-relative call thunk. > ++ > + @end table > + > + These @samp{-m} switches are supported in addition to the above > +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-1.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-1.c > +new file mode 100644 > +index 00000000000..d8b6f5a06a5 > +--- /dev/null > ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-1.c > +@@ -0,0 +1,19 @@ > ++/* { dg-do compile } */ > ++/* { dg-options "-O2 -mindirect-branch=thunk -fno-pic" } */ > ++ > ++typedef void (*dispatch_t)(long offset); > ++ > ++dispatch_t dispatch; > ++ > ++void > ++male_indirect_jump (long offset) > ++{ > ++ dispatch(offset); > ++} > ++ > ++/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { ! x32 } } } } */ > ++/* { dg-final { scan-assembler "pushq\[ \t\]%rax" { target x32 } } } */ > ++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" } } */ > ++/* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */ > ++/* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */ > ++/* { dg-final { scan-assembler {\tlfence} } } */ > +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-2.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-2.c > +new file mode 100644 > +index 00000000000..f7d5cb315a8 > +--- /dev/null > ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-2.c > +@@ -0,0 +1,19 @@ > ++/* { dg-do compile } */ > ++/* { dg-options "-O2 -mindirect-branch=thunk -fno-pic" } */ > ++ > ++typedef void (*dispatch_t)(long offset); > ++ > ++dispatch_t dispatch[256]; > ++ > ++void > ++male_indirect_jump (long offset) > ++{ > ++ dispatch[offset](offset); > ++} > ++ > ++/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { ! x32 } } } } */ > ++/* { dg-final { scan-assembler "pushq\[ \t\]%rax" { target x32 } } } */ > ++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" } } */ > ++/* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */ > ++/* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */ > ++/* { dg-final { scan-assembler {\tlfence} } } */ > +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-3.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-3.c > +new file mode 100644 > +index 00000000000..736d7cda058 > +--- /dev/null > ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-3.c > +@@ -0,0 +1,20 @@ > ++/* { dg-do compile } */ > ++/* { dg-options "-O2 -mindirect-branch=thunk -fno-pic" } */ > ++ > ++typedef void (*dispatch_t)(long offset); > ++ > ++dispatch_t dispatch; > ++ > ++int > ++male_indirect_jump (long offset) > ++{ > ++ dispatch(offset); > ++ return 0; > ++} > ++ > ++/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { ! x32 } } } } */ > ++/* { dg-final { scan-assembler "pushq\[ \t\]%rax" { target x32 } } } */ > ++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" } } */ > ++/* { dg-final { scan-assembler-times "jmp\[ \t\]*\.LIND" 2 } } */ > ++/* { dg-final { scan-assembler-times "call\[ \t\]*\.LIND" 2 } } */ > ++/* { dg-final { scan-assembler {\tlfence} } } */ > +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-4.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-4.c > +new file mode 100644 > +index 00000000000..cef9b10513e > +--- /dev/null > ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-4.c > +@@ -0,0 +1,20 @@ > ++/* { dg-do compile } */ > ++/* { dg-options "-O2 -mindirect-branch=thunk -fno-pic" } */ > ++ > ++typedef void (*dispatch_t)(long offset); > ++ > ++dispatch_t dispatch[256]; > ++ > ++int > ++male_indirect_jump (long offset) > ++{ > ++ dispatch[offset](offset); > ++ return 0; > ++} > ++ > ++/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { ! x32 } } } } */ > ++/* { dg-final { scan-assembler "pushq\[ \t\]%rax" { target x32 } } } */ > ++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" } } */ > ++/* { dg-final { scan-assembler-times "jmp\[ \t\]*\.LIND" 2 } } */ > ++/* { dg-final { scan-assembler-times "call\[ \t\]*\.LIND" 2 } } */ > ++/* { dg-final { scan-assembler {\tlfence} } } */ > +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-5.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-5.c > +new file mode 100644 > +index 00000000000..1a9bb0e431e > +--- /dev/null > ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-5.c > +@@ -0,0 +1,16 @@ > ++/* { dg-do compile { target *-*-linux* } } */ > ++/* { dg-options "-O2 -fpic -fno-plt -mindirect-branch=thunk" } */ > ++ > ++extern void bar (void); > ++ > ++void > ++foo (void) > ++{ > ++ bar (); > ++} > ++ > ++/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*bar@GOT" } } */ > ++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" } } */ > ++/* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */ > ++/* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */ > ++/* { dg-final { scan-assembler {\tlfence} } } */ > +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-6.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-6.c > +new file mode 100644 > +index 00000000000..bc7d20ec6ad > +--- /dev/null > ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-6.c > +@@ -0,0 +1,17 @@ > ++/* { dg-do compile { target *-*-linux* } } */ > ++/* { dg-options "-O2 -fpic -fno-plt -mindirect-branch=thunk" } */ > ++ > ++extern void bar (void); > ++ > ++int > ++foo (void) > ++{ > ++ bar (); > ++ return 0; > ++} > ++ > ++/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*bar@GOT" } } */ > ++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" } } */ > ++/* { dg-final { scan-assembler-times "jmp\[ \t\]*\.LIND" 2 } } */ > ++/* { dg-final { scan-assembler-times "call\[ \t\]*\.LIND" 2 } } */ > ++/* { dg-final { scan-assembler {\tlfence} } } */ > +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-7.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-7.c > +new file mode 100644 > +index 00000000000..ea0fa312f64 > +--- /dev/null > ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-7.c > +@@ -0,0 +1,43 @@ > ++/* { dg-do compile } */ > ++/* { dg-options "-O2 -mindirect-branch=thunk -fno-pic" } */ > ++ > ++void func0 (void); > ++void func1 (void); > ++void func2 (void); > ++void func3 (void); > ++void func4 (void); > ++void func4 (void); > ++void func5 (void); > ++ > ++void > ++bar (int i) > ++{ > ++ switch (i) > ++ { > ++ default: > ++ func0 (); > ++ break; > ++ case 1: > ++ func1 (); > ++ break; > ++ case 2: > ++ func2 (); > ++ break; > ++ case 3: > ++ func3 (); > ++ break; > ++ case 4: > ++ func4 (); > ++ break; > ++ case 5: > ++ func5 (); > ++ break; > ++ } > ++} > ++ > ++/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*\.L\[0-9\]+\\(,%" { target { ! x32 } } } } */ > ++/* { dg-final { scan-assembler "pushq\[ \t\]%rax" { target x32 } } } */ > ++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" } } */ > ++/* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */ > ++/* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */ > ++/* { dg-final { scan-assembler {\tlfence} } } */ > +-- > +2.15.1 > + > diff --git a/gnu/packages/patches/gcc-retpoline-Add-mno-indirect-branch-register-to-indirect-branch-.patch b/gnu/packages/patches/gcc-retpoline-Add-mno-indirect-branch-register-to-indirect-branch-.patch > new file mode 100644 > index 000000000..2b4ac1b81 > --- /dev/null > +++ b/gnu/packages/patches/gcc-retpoline-Add-mno-indirect-branch-register-to-indirect-branch-.patch > @@ -0,0 +1,554 @@ > +'Retpoline' mitigation technique for Spectre (branch target injection) > +[CVE-2017-5715]: > + > +https://security.googleblog.com/2018/01/more-details-about-mitigations-for-cpu_4.html > +https://support.google.com/faqs/answer/7625886 > +https://spectreattack.com/ > +https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2017-5715 > + > +Patch copied from the 'retpoline-20180107' branch of upstream source repository > +(please add new / update existing patches when new 'retpoline-xxxxxxxx' branch > +appears): > + > +http://git.infradead.org/users/dwmw2/gcc-retpoline.git > + > +From 2c14ecf03978ce6c60e021a2b0d72778a5fe0982 Mon Sep 17 00:00:00 2001 > +From: "H.J. Lu" <hjl.tools@gmail.com> > +Date: Tue, 12 Dec 2017 12:34:26 -0800 > +Subject: [PATCH 14/17] Add -mno-indirect-branch-register to indirect branch > + tests > + > +--- > + gcc/testsuite/gcc.target/i386/indirect-thunk-1.c | 2 +- > + gcc/testsuite/gcc.target/i386/indirect-thunk-2.c | 2 +- > + gcc/testsuite/gcc.target/i386/indirect-thunk-3.c | 2 +- > + gcc/testsuite/gcc.target/i386/indirect-thunk-4.c | 2 +- > + gcc/testsuite/gcc.target/i386/indirect-thunk-5.c | 2 +- > + gcc/testsuite/gcc.target/i386/indirect-thunk-6.c | 2 +- > + gcc/testsuite/gcc.target/i386/indirect-thunk-7.c | 2 +- > + gcc/testsuite/gcc.target/i386/indirect-thunk-attr-1.c | 2 +- > + gcc/testsuite/gcc.target/i386/indirect-thunk-attr-2.c | 2 +- > + gcc/testsuite/gcc.target/i386/indirect-thunk-attr-3.c | 2 +- > + gcc/testsuite/gcc.target/i386/indirect-thunk-attr-4.c | 2 +- > + gcc/testsuite/gcc.target/i386/indirect-thunk-attr-5.c | 2 +- > + gcc/testsuite/gcc.target/i386/indirect-thunk-attr-6.c | 2 +- > + gcc/testsuite/gcc.target/i386/indirect-thunk-attr-7.c | 2 +- > + gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-1.c | 2 +- > + gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-2.c | 2 +- > + gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-3.c | 2 +- > + gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-4.c | 2 +- > + gcc/testsuite/gcc.target/i386/indirect-thunk-extern-1.c | 2 +- > + gcc/testsuite/gcc.target/i386/indirect-thunk-extern-2.c | 2 +- > + gcc/testsuite/gcc.target/i386/indirect-thunk-extern-3.c | 2 +- > + gcc/testsuite/gcc.target/i386/indirect-thunk-extern-4.c | 2 +- > + gcc/testsuite/gcc.target/i386/indirect-thunk-extern-5.c | 2 +- > + gcc/testsuite/gcc.target/i386/indirect-thunk-extern-6.c | 2 +- > + gcc/testsuite/gcc.target/i386/indirect-thunk-extern-7.c | 2 +- > + gcc/testsuite/gcc.target/i386/indirect-thunk-inline-1.c | 2 +- > + gcc/testsuite/gcc.target/i386/indirect-thunk-inline-2.c | 2 +- > + gcc/testsuite/gcc.target/i386/indirect-thunk-inline-3.c | 2 +- > + gcc/testsuite/gcc.target/i386/indirect-thunk-inline-4.c | 2 +- > + gcc/testsuite/gcc.target/i386/indirect-thunk-inline-5.c | 2 +- > + gcc/testsuite/gcc.target/i386/indirect-thunk-inline-6.c | 2 +- > + gcc/testsuite/gcc.target/i386/indirect-thunk-inline-7.c | 2 +- > + gcc/testsuite/gcc.target/i386/indirect-thunk-loop-1.c | 2 +- > + gcc/testsuite/gcc.target/i386/indirect-thunk-loop-2.c | 2 +- > + gcc/testsuite/gcc.target/i386/indirect-thunk-loop-3.c | 2 +- > + gcc/testsuite/gcc.target/i386/indirect-thunk-loop-4.c | 2 +- > + gcc/testsuite/gcc.target/i386/indirect-thunk-loop-5.c | 2 +- > + gcc/testsuite/gcc.target/i386/ret-thunk-10.c | 2 +- > + gcc/testsuite/gcc.target/i386/ret-thunk-11.c | 2 +- > + gcc/testsuite/gcc.target/i386/ret-thunk-12.c | 2 +- > + gcc/testsuite/gcc.target/i386/ret-thunk-13.c | 2 +- > + gcc/testsuite/gcc.target/i386/ret-thunk-14.c | 2 +- > + gcc/testsuite/gcc.target/i386/ret-thunk-15.c | 2 +- > + gcc/testsuite/gcc.target/i386/ret-thunk-9.c | 2 +- > + 44 files changed, 44 insertions(+), 44 deletions(-) > + > +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-1.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-1.c > +index 318db1e7f5c..b0625207b92 100644 > +--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-1.c > ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-1.c > +@@ -1,5 +1,5 @@ > + /* { dg-do compile } */ > +-/* { dg-options "-O2 -mfunction-return=keep -mindirect-branch=thunk -fno-pic" } */ > ++/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=keep -mindirect-branch=thunk -fno-pic" } */ > + > + typedef void (*dispatch_t)(long offset); > + > +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-2.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-2.c > +index f2700dd36cf..0b289685e6b 100644 > +--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-2.c > ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-2.c > +@@ -1,5 +1,5 @@ > + /* { dg-do compile } */ > +-/* { dg-options "-O2 -mfunction-return=keep -mindirect-branch=thunk -fno-pic" } */ > ++/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=keep -mindirect-branch=thunk -fno-pic" } */ > + > + typedef void (*dispatch_t)(long offset); > + > +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-3.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-3.c > +index 46685d9a674..79a9f76285f 100644 > +--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-3.c > ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-3.c > +@@ -1,5 +1,5 @@ > + /* { dg-do compile } */ > +-/* { dg-options "-O2 -mfunction-return=keep -mindirect-branch=thunk -fno-pic" } */ > ++/* { dg-options "-O2 -mno-indirect-branch-register -mno-indirect-branch-register -mno-indirect-branch-register -mfunction-return=keep -mindirect-branch=thunk -fno-pic" } */ > + > + typedef void (*dispatch_t)(long offset); > + > +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-4.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-4.c > +index 8f701775cea..901d94213bd 100644 > +--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-4.c > ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-4.c > +@@ -1,5 +1,5 @@ > + /* { dg-do compile } */ > +-/* { dg-options "-O2 -mfunction-return=keep -mindirect-branch=thunk -fno-pic" } */ > ++/* { dg-options "-O2 -mno-indirect-branch-register -mno-indirect-branch-register -mno-indirect-branch-register -mfunction-return=keep -mindirect-branch=thunk -fno-pic" } */ > + > + typedef void (*dispatch_t)(long offset); > + > +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-5.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-5.c > +index f88ac31d07a..d2c9bd9d7ca 100644 > +--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-5.c > ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-5.c > +@@ -1,5 +1,5 @@ > + /* { dg-do compile { target *-*-linux* } } */ > +-/* { dg-options "-O2 -mfunction-return=keep -fpic -fno-plt -mindirect-branch=thunk" } */ > ++/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=keep -fpic -fno-plt -mindirect-branch=thunk" } */ > + > + extern void bar (void); > + > +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-6.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-6.c > +index d745116d321..f8b028db7a2 100644 > +--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-6.c > ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-6.c > +@@ -1,5 +1,5 @@ > + /* { dg-do compile { target *-*-linux* } } */ > +-/* { dg-options "-O2 -mfunction-return=keep -fpic -fno-plt -mindirect-branch=thunk" } */ > ++/* { dg-options "-O2 -mno-indirect-branch-register -mno-indirect-branch-register -mno-indirect-branch-register -mfunction-return=keep -fpic -fno-plt -mindirect-branch=thunk" } */ > + > + extern void bar (void); > + > +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-7.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-7.c > +index 969cb8c6ddc..465775407ec 100644 > +--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-7.c > ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-7.c > +@@ -1,5 +1,5 @@ > + /* { dg-do compile } */ > +-/* { dg-options "-O2 -mfunction-return=keep -mindirect-branch=thunk -fno-pic" } */ > ++/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=keep -mindirect-branch=thunk -fno-pic" } */ > + > + void func0 (void); > + void func1 (void); > +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-1.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-1.c > +index 12a61c3bbc7..5309d5a3eaa 100644 > +--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-1.c > ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-1.c > +@@ -1,5 +1,5 @@ > + /* { dg-do compile } */ > +-/* { dg-options "-O2 -mfunction-return=keep -fno-pic" } */ > ++/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=keep -fno-pic" } */ > + > + typedef void (*dispatch_t)(long offset); > + > +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-2.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-2.c > +index a06907933a2..dd1efca49fd 100644 > +--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-2.c > ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-2.c > +@@ -1,5 +1,5 @@ > + /* { dg-do compile } */ > +-/* { dg-options "-O2 -mfunction-return=keep -fno-pic" } */ > ++/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=keep -fno-pic" } */ > + > + typedef void (*dispatch_t)(long offset); > + > +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-3.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-3.c > +index 7f56725e6b6..e97ca636020 100644 > +--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-3.c > ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-3.c > +@@ -1,5 +1,5 @@ > + /* { dg-do compile } */ > +-/* { dg-options "-O2 -mfunction-return=keep -fno-pic" } */ > ++/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=keep -fno-pic" } */ > + > + typedef void (*dispatch_t)(long offset); > + > +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-4.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-4.c > +index fd4ab1dbaa0..b547cbbf255 100644 > +--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-4.c > ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-4.c > +@@ -1,5 +1,5 @@ > + /* { dg-do compile } */ > +-/* { dg-options "-O2 -mfunction-return=keep -fno-pic" } */ > ++/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=keep -fno-pic" } */ > + > + typedef void (*dispatch_t)(long offset); > + > +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-5.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-5.c > +index 1ffbf3b1181..353689dc415 100644 > +--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-5.c > ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-5.c > +@@ -1,5 +1,5 @@ > + /* { dg-do compile } */ > +-/* { dg-options "-O2 -mfunction-return=keep -fno-pic" } */ > ++/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=keep -fno-pic" } */ > + > + typedef void (*dispatch_t)(long offset); > + > +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-6.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-6.c > +index 1559072919a..1edef7208f4 100644 > +--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-6.c > ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-6.c > +@@ -1,5 +1,5 @@ > + /* { dg-do compile } */ > +-/* { dg-options "-O2 -mfunction-return=keep -fno-pic" } */ > ++/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=keep -fno-pic" } */ > + > + typedef void (*dispatch_t)(long offset); > + > +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-7.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-7.c > +index 1717e7bb436..c2e816cdfc6 100644 > +--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-7.c > ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-7.c > +@@ -1,5 +1,5 @@ > + /* { dg-do compile } */ > +-/* { dg-options "-O2 -mfunction-return=keep -fno-pic" } */ > ++/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=keep -fno-pic" } */ > + > + void func0 (void); > + void func1 (void); > +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-1.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-1.c > +index 20903b0f79d..5c10de47b7c 100644 > +--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-1.c > ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-1.c > +@@ -1,5 +1,5 @@ > + /* { dg-do compile { target { ! x32 } } } */ > +-/* { dg-options "-O2 -mfunction-return=keep -mindirect-branch=thunk -fcheck-pointer-bounds -mmpx -fno-pic" } */ > ++/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=keep -mindirect-branch=thunk -fcheck-pointer-bounds -mmpx -fno-pic" } */ > + > + void (*dispatch) (char *); > + char buf[10]; > +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-2.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-2.c > +index aef4bd144f4..9eedd9a5a82 100644 > +--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-2.c > ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-2.c > +@@ -1,5 +1,5 @@ > + /* { dg-do compile { target { ! x32 } } } */ > +-/* { dg-options "-O2 -mfunction-return=keep -mindirect-branch=thunk -fcheck-pointer-bounds -mmpx -fno-pic" } */ > ++/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=keep -mindirect-branch=thunk -fcheck-pointer-bounds -mmpx -fno-pic" } */ > + > + void (*dispatch) (char *); > + char buf[10]; > +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-3.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-3.c > +index 2cc0343f828..b2b8587eac7 100644 > +--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-3.c > ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-3.c > +@@ -1,5 +1,5 @@ > + /* { dg-do compile { target { *-*-linux* && { ! x32 } } } } */ > +-/* { dg-options "-O2 -mfunction-return=keep -mindirect-branch=thunk -fcheck-pointer-bounds -mmpx -fpic -fno-plt" } */ > ++/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=keep -mindirect-branch=thunk -fcheck-pointer-bounds -mmpx -fpic -fno-plt" } */ > + > + void bar (char *); > + char buf[10]; > +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-4.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-4.c > +index 91560fef661..9459a2417f4 100644 > +--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-4.c > ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-4.c > +@@ -1,5 +1,5 @@ > + /* { dg-do compile { target { *-*-linux* && { ! x32 } } } } */ > +-/* { dg-options "-O2 -mfunction-return=keep -mindirect-branch=thunk -fcheck-pointer-bounds -mmpx -fpic -fno-plt" } */ > ++/* { dg-options "-O2 -mno-indirect-branch-register -mno-indirect-branch-register -mfunction-return=keep -mindirect-branch=thunk -fcheck-pointer-bounds -mmpx -fpic -fno-plt" } */ > + > + void bar (char *); > + char buf[10]; > +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-1.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-1.c > +index dc6bd10af4c..b0aa3811e65 100644 > +--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-1.c > ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-1.c > +@@ -1,5 +1,5 @@ > + /* { dg-do compile } */ > +-/* { dg-options "-O2 -mfunction-return=keep -mindirect-branch=thunk-extern -fno-pic" } */ > ++/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=keep -mindirect-branch=thunk-extern -fno-pic" } */ > + > + typedef void (*dispatch_t)(long offset); > + > +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-2.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-2.c > +index 955aa256529..75fabcd988c 100644 > +--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-2.c > ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-2.c > +@@ -1,5 +1,5 @@ > + /* { dg-do compile } */ > +-/* { dg-options "-O2 -mfunction-return=keep -mindirect-branch=thunk-extern -fno-pic" } */ > ++/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=keep -mindirect-branch=thunk-extern -fno-pic" } */ > + > + typedef void (*dispatch_t)(long offset); > + > +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-3.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-3.c > +index 1537239416f..1d9dff2e834 100644 > +--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-3.c > ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-3.c > +@@ -1,5 +1,5 @@ > + /* { dg-do compile } */ > +-/* { dg-options "-O2 -mfunction-return=keep -mindirect-branch=thunk-extern -fno-pic" } */ > ++/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=keep -mindirect-branch=thunk-extern -fno-pic" } */ > + > + typedef void (*dispatch_t)(long offset); > + > +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-4.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-4.c > +index c82e53068fe..5b464155e38 100644 > +--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-4.c > ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-4.c > +@@ -1,5 +1,5 @@ > + /* { dg-do compile } */ > +-/* { dg-options "-O2 -mfunction-return=keep -mindirect-branch=thunk-extern -fno-pic" } */ > ++/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=keep -mindirect-branch=thunk-extern -fno-pic" } */ > + > + typedef void (*dispatch_t)(long offset); > + > +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-5.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-5.c > +index 23548d85f78..55ce91c73ec 100644 > +--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-5.c > ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-5.c > +@@ -1,5 +1,5 @@ > + /* { dg-do compile { target *-*-linux* } } */ > +-/* { dg-options "-O2 -mfunction-return=keep -fpic -fno-plt -mindirect-branch=thunk-extern" } */ > ++/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=keep -fpic -fno-plt -mindirect-branch=thunk-extern" } */ > + > + extern void bar (void); > + > +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-6.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-6.c > +index 56c2fe92f25..06180e7bee9 100644 > +--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-6.c > ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-6.c > +@@ -1,5 +1,5 @@ > + /* { dg-do compile { target *-*-linux* } } */ > +-/* { dg-options "-O2 -mfunction-return=keep -fpic -fno-plt -mindirect-branch=thunk-extern" } */ > ++/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=keep -fpic -fno-plt -mindirect-branch=thunk-extern" } */ > + > + extern void bar (void); > + > +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-7.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-7.c > +index e12b88593fe..790a05cec3e 100644 > +--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-7.c > ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-7.c > +@@ -1,5 +1,5 @@ > + /* { dg-do compile } */ > +-/* { dg-options "-O2 -mfunction-return=keep -mindirect-branch=thunk-extern -fno-pic" } */ > ++/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=keep -mindirect-branch=thunk-extern -fno-pic" } */ > + > + void func0 (void); > + void func1 (void); > +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-1.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-1.c > +index 87b5429702f..1ce8ca5aff1 100644 > +--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-1.c > ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-1.c > +@@ -1,5 +1,5 @@ > + /* { dg-do compile } */ > +-/* { dg-options "-O2 -mfunction-return=keep -mindirect-branch=thunk-inline -fno-pic" } */ > ++/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=keep -mindirect-branch=thunk-inline -fno-pic" } */ > + > + typedef void (*dispatch_t)(long offset); > + > +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-2.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-2.c > +index a496a41a918..f6b71e868bd 100644 > +--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-2.c > ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-2.c > +@@ -1,5 +1,5 @@ > + /* { dg-do compile } */ > +-/* { dg-options "-O2 -mfunction-return=keep -mindirect-branch=thunk-inline -fno-pic" } */ > ++/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=keep -mindirect-branch=thunk-inline -fno-pic" } */ > + > + typedef void (*dispatch_t)(long offset); > + > +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-3.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-3.c > +index 6fe5ce71abf..84a09d4d0d6 100644 > +--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-3.c > ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-3.c > +@@ -1,5 +1,5 @@ > + /* { dg-do compile } */ > +-/* { dg-options "-O2 -mfunction-return=keep -mindirect-branch=thunk-inline -fno-pic" } */ > ++/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=keep -mindirect-branch=thunk-inline -fno-pic" } */ > + > + typedef void (*dispatch_t)(long offset); > + > +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-4.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-4.c > +index 65cd997a33f..cfe3aefa0bf 100644 > +--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-4.c > ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-4.c > +@@ -1,5 +1,5 @@ > + /* { dg-do compile } */ > +-/* { dg-options "-O2 -mfunction-return=keep -mindirect-branch=thunk-inline -fno-pic" } */ > ++/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=keep -mindirect-branch=thunk-inline -fno-pic" } */ > + > + typedef void (*dispatch_t)(long offset); > + > +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-5.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-5.c > +index 7321d015c02..6411454243f 100644 > +--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-5.c > ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-5.c > +@@ -1,5 +1,5 @@ > + /* { dg-do compile { target *-*-linux* } } */ > +-/* { dg-options "-O2 -mfunction-return=keep -fpic -fno-plt -mindirect-branch=thunk-inline" } */ > ++/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=keep -fpic -fno-plt -mindirect-branch=thunk-inline" } */ > + > + extern void bar (void); > + > +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-6.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-6.c > +index 6ec2e5621ab..d4297fe21c4 100644 > +--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-6.c > ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-6.c > +@@ -1,5 +1,5 @@ > + /* { dg-do compile { target *-*-linux* } } */ > +-/* { dg-options "-O2 -mfunction-return=keep -fpic -fno-plt -mindirect-branch=thunk-inline" } */ > ++/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=keep -fpic -fno-plt -mindirect-branch=thunk-inline" } */ > + > + extern void bar (void); > + > +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-7.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-7.c > +index a3d1a13cded..eb318efdf4d 100644 > +--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-7.c > ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-7.c > +@@ -1,5 +1,5 @@ > + /* { dg-do compile } */ > +-/* { dg-options "-O2 -mfunction-return=keep -mindirect-branch=thunk-inline -fno-pic" } */ > ++/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=keep -mindirect-branch=thunk-inline -fno-pic" } */ > + > + void func0 (void); > + void func1 (void); > +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-loop-1.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-loop-1.c > +index f0e8f4949c8..605e32bb584 100644 > +--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-loop-1.c > ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-loop-1.c > +@@ -1,5 +1,5 @@ > + /* { dg-do compile } */ > +-/* { dg-options "-O2 -mindirect-branch=thunk -mindirect-branch-loop=pause -fno-pic" } */ > ++/* { dg-options "-O2 -mno-indirect-branch-register -mindirect-branch=thunk -mindirect-branch-loop=pause -fno-pic" } */ > + > + typedef void (*dispatch_t)(long offset); > + > +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-loop-2.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-loop-2.c > +index a577ac2568a..dd7a7b60621 100644 > +--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-loop-2.c > ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-loop-2.c > +@@ -1,5 +1,5 @@ > + /* { dg-do compile } */ > +-/* { dg-options "-O2 -mindirect-branch=thunk -mindirect-branch-loop=nop -fno-pic" } */ > ++/* { dg-options "-O2 -mno-indirect-branch-register -mindirect-branch=thunk -mindirect-branch-loop=nop -fno-pic" } */ > + > + typedef void (*dispatch_t)(long offset); > + > +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-loop-3.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-loop-3.c > +index c8dcb9639c4..338f22c373c 100644 > +--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-loop-3.c > ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-loop-3.c > +@@ -1,5 +1,5 @@ > + /* { dg-do compile } */ > +-/* { dg-options "-O2 -mindirect-branch=thunk -mindirect-branch-loop=lfence -fno-pic" } */ > ++/* { dg-options "-O2 -mno-indirect-branch-register -mindirect-branch=thunk -mindirect-branch-loop=lfence -fno-pic" } */ > + > + typedef void (*dispatch_t)(long offset); > + > +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-loop-4.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-loop-4.c > +index 8569dfc92c3..3b083ee30a8 100644 > +--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-loop-4.c > ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-loop-4.c > +@@ -1,5 +1,5 @@ > + /* { dg-do compile } */ > +-/* { dg-options "-O2 -mindirect-branch=thunk-inline -mindirect-branch-loop=pause -fno-pic" } */ > ++/* { dg-options "-O2 -mno-indirect-branch-register -mindirect-branch=thunk-inline -mindirect-branch-loop=pause -fno-pic" } */ > + > + typedef void (*dispatch_t)(long offset); > + > +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-loop-5.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-loop-5.c > +index bcf19c9ede1..31a9a81a911 100644 > +--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-loop-5.c > ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-loop-5.c > +@@ -1,5 +1,5 @@ > + /* { dg-do compile } */ > +-/* { dg-options "-O2 -mindirect-branch=thunk-extern -mindirect-branch-loop=pause -fno-pic" } */ > ++/* { dg-options "-O2 -mno-indirect-branch-register -mindirect-branch=thunk-extern -mindirect-branch-loop=pause -fno-pic" } */ > + > + typedef void (*dispatch_t)(long offset); > + > +diff --git a/gcc/testsuite/gcc.target/i386/ret-thunk-10.c b/gcc/testsuite/gcc.target/i386/ret-thunk-10.c > +index aecea4224f9..74f37ee9a62 100644 > +--- a/gcc/testsuite/gcc.target/i386/ret-thunk-10.c > ++++ b/gcc/testsuite/gcc.target/i386/ret-thunk-10.c > +@@ -1,5 +1,5 @@ > + /* { dg-do compile } */ > +-/* { dg-options "-O2 -mfunction-return=thunk-inline -mindirect-branch=thunk -fno-pic" } */ > ++/* { dg-options "-O2 -mno-indirect-branch-register -mno-indirect-branch-register -mfunction-return=thunk-inline -mindirect-branch=thunk -fno-pic" } */ > + > + extern void (*bar) (void); > + > +diff --git a/gcc/testsuite/gcc.target/i386/ret-thunk-11.c b/gcc/testsuite/gcc.target/i386/ret-thunk-11.c > +index 3bacfb54dfd..0a52318e86b 100644 > +--- a/gcc/testsuite/gcc.target/i386/ret-thunk-11.c > ++++ b/gcc/testsuite/gcc.target/i386/ret-thunk-11.c > +@@ -1,5 +1,5 @@ > + /* { dg-do compile } */ > +-/* { dg-options "-O2 -mfunction-return=thunk-extern -mindirect-branch=thunk -fno-pic" } */ > ++/* { dg-options "-O2 -mno-indirect-branch-register -mno-indirect-branch-register -mno-indirect-branch-register -mno-indirect-branch-register -mfunction-return=thunk-extern -mindirect-branch=thunk -fno-pic" } */ > + > + extern void (*bar) (void); > + > +diff --git a/gcc/testsuite/gcc.target/i386/ret-thunk-12.c b/gcc/testsuite/gcc.target/i386/ret-thunk-12.c > +index 851115ac507..d2f775490ea 100644 > +--- a/gcc/testsuite/gcc.target/i386/ret-thunk-12.c > ++++ b/gcc/testsuite/gcc.target/i386/ret-thunk-12.c > +@@ -1,5 +1,5 @@ > + /* { dg-do compile } */ > +-/* { dg-options "-O2 -mfunction-return=keep -mindirect-branch=thunk -fno-pic" } */ > ++/* { dg-options "-O2 -mno-indirect-branch-register -mno-indirect-branch-register -mno-indirect-branch-register -mno-indirect-branch-register -mfunction-return=keep -mindirect-branch=thunk -fno-pic" } */ > + > + extern void (*bar) (void); > + > +diff --git a/gcc/testsuite/gcc.target/i386/ret-thunk-13.c b/gcc/testsuite/gcc.target/i386/ret-thunk-13.c > +index 7acb6fa5eae..82d46165f3e 100644 > +--- a/gcc/testsuite/gcc.target/i386/ret-thunk-13.c > ++++ b/gcc/testsuite/gcc.target/i386/ret-thunk-13.c > +@@ -1,5 +1,5 @@ > + /* { dg-do compile } */ > +-/* { dg-options "-O2 -mfunction-return=keep -mindirect-branch=thunk-inline -fno-pic" } */ > ++/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=keep -mindirect-branch=thunk-inline -fno-pic" } */ > + > + extern void (*bar) (void); > + extern int foo (void) __attribute__ ((function_return("thunk"))); > +diff --git a/gcc/testsuite/gcc.target/i386/ret-thunk-14.c b/gcc/testsuite/gcc.target/i386/ret-thunk-14.c > +index bf340fac7c6..6711eb27fa8 100644 > +--- a/gcc/testsuite/gcc.target/i386/ret-thunk-14.c > ++++ b/gcc/testsuite/gcc.target/i386/ret-thunk-14.c > +@@ -1,5 +1,5 @@ > + /* { dg-do compile } */ > +-/* { dg-options "-O2 -mfunction-return=keep -mindirect-branch=thunk-extern -fno-pic" } */ > ++/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=keep -mindirect-branch=thunk-extern -fno-pic" } */ > + > + extern void (*bar) (void); > + > +diff --git a/gcc/testsuite/gcc.target/i386/ret-thunk-15.c b/gcc/testsuite/gcc.target/i386/ret-thunk-15.c > +index 735f8648c96..37758c33371 100644 > +--- a/gcc/testsuite/gcc.target/i386/ret-thunk-15.c > ++++ b/gcc/testsuite/gcc.target/i386/ret-thunk-15.c > +@@ -1,5 +1,5 @@ > + /* { dg-do compile } */ > +-/* { dg-options "-O2 -mfunction-return=keep -mindirect-branch=keep -fno-pic" } */ > ++/* { dg-options "-O2 -mno-indirect-branch-register -mno-indirect-branch-register -mno-indirect-branch-register -mno-indirect-branch-register -mfunction-return=keep -mindirect-branch=keep -fno-pic" } */ > + > + extern void (*bar) (void); > + > +diff --git a/gcc/testsuite/gcc.target/i386/ret-thunk-9.c b/gcc/testsuite/gcc.target/i386/ret-thunk-9.c > +index 569e5f47973..70771ea35d7 100644 > +--- a/gcc/testsuite/gcc.target/i386/ret-thunk-9.c > ++++ b/gcc/testsuite/gcc.target/i386/ret-thunk-9.c > +@@ -1,5 +1,5 @@ > + /* { dg-do compile } */ > +-/* { dg-options "-O2 -mfunction-return=thunk -mindirect-branch=thunk -fno-pic" } */ > ++/* { dg-options "-O2 -mno-indirect-branch-register -mno-indirect-branch-register -mfunction-return=thunk -mindirect-branch=thunk -fno-pic" } */ > + > + extern void (*bar) (void); > + > +-- > +2.15.1 > + > diff --git a/gnu/packages/patches/gcc-retpoline-Add-tests-for-mindirect-branch-thunk-fcheck-pointer-.patch b/gnu/packages/patches/gcc-retpoline-Add-tests-for-mindirect-branch-thunk-fcheck-pointer-.patch > new file mode 100644 > index 000000000..e21bb5039 > --- /dev/null > +++ b/gnu/packages/patches/gcc-retpoline-Add-tests-for-mindirect-branch-thunk-fcheck-pointer-.patch > @@ -0,0 +1,134 @@ > +'Retpoline' mitigation technique for Spectre (branch target injection) > +[CVE-2017-5715]: > + > +https://security.googleblog.com/2018/01/more-details-about-mitigations-for-cpu_4.html > +https://support.google.com/faqs/answer/7625886 > +https://spectreattack.com/ > +https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2017-5715 > + > +Patch copied from the 'retpoline-20180107' branch of upstream source repository > +(please add new / update existing patches when new 'retpoline-xxxxxxxx' branch > +appears): > + > +http://git.infradead.org/users/dwmw2/gcc-retpoline.git > + > +From ece041bc3083aabd00fab9de5ba409fbd7dcad8c Mon Sep 17 00:00:00 2001 > +From: "H.J. Lu" <hjl.tools@gmail.com> > +Date: Mon, 4 Dec 2017 12:58:20 -0800 > +Subject: [PATCH 05/17] Add tests for -mindirect-branch=thunk > + -fcheck-pointer-bounds -mmpx > + > +--- > + gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-1.c | 19 +++++++++++++++++++ > + gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-2.c | 20 ++++++++++++++++++++ > + gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-3.c | 18 ++++++++++++++++++ > + gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-4.c | 19 +++++++++++++++++++ > + 4 files changed, 76 insertions(+) > + create mode 100644 gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-1.c > + create mode 100644 gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-2.c > + create mode 100644 gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-3.c > + create mode 100644 gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-4.c > + > +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-1.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-1.c > +new file mode 100644 > +index 00000000000..a5b1d38e061 > +--- /dev/null > ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-1.c > +@@ -0,0 +1,19 @@ > ++/* { dg-do compile { target { ! x32 } } } */ > ++/* { dg-options "-O2 -mindirect-branch=thunk -fcheck-pointer-bounds -mmpx -fno-pic" } */ > ++ > ++void (*dispatch) (char *); > ++char buf[10]; > ++ > ++void > ++foo (void) > ++{ > ++ dispatch (buf); > ++} > ++ > ++/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { ! x32 } } } } */ > ++/* { dg-final { scan-assembler "pushq\[ \t\]%rax" { target x32 } } } */ > ++/* { dg-final { scan-assembler "bnd jmp\[ \t\]*__x86.indirect_thunk_bnd" } } */ > ++/* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */ > ++/* { dg-final { scan-assembler "bnd call\[ \t\]*\.LIND" } } */ > ++/* { dg-final { scan-assembler "bnd ret" } } */ > ++/* { dg-final { scan-assembler {\tlfence} } } */ > +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-2.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-2.c > +new file mode 100644 > +index 00000000000..a42add209e2 > +--- /dev/null > ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-2.c > +@@ -0,0 +1,20 @@ > ++/* { dg-do compile { target { ! x32 } } } */ > ++/* { dg-options "-O2 -mindirect-branch=thunk -fcheck-pointer-bounds -mmpx -fno-pic" } */ > ++ > ++void (*dispatch) (char *); > ++char buf[10]; > ++ > ++int > ++foo (void) > ++{ > ++ dispatch (buf); > ++ return 0; > ++} > ++ > ++/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { ! x32 } } } } */ > ++/* { dg-final { scan-assembler "pushq\[ \t\]%rax" { target x32 } } } */ > ++/* { dg-final { scan-assembler "bnd jmp\[ \t\]*__x86.indirect_thunk_bnd" } } */ > ++/* { dg-final { scan-assembler "bnd jmp\[ \t\]*\.LIND" } } */ > ++/* { dg-final { scan-assembler "bnd call\[ \t\]*\.LIND" } } */ > ++/* { dg-final { scan-assembler "bnd ret" } } */ > ++/* { dg-final { scan-assembler {\tlfence} } } */ > +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-3.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-3.c > +new file mode 100644 > +index 00000000000..265e010a0fe > +--- /dev/null > ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-3.c > +@@ -0,0 +1,18 @@ > ++/* { dg-do compile { target { *-*-linux* && { ! x32 } } } } */ > ++/* { dg-options "-O2 -mindirect-branch=thunk -fcheck-pointer-bounds -mmpx -fpic -fno-plt" } */ > ++ > ++void bar (char *); > ++char buf[10]; > ++ > ++void > ++foo (void) > ++{ > ++ bar (buf); > ++} > ++ > ++/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*bar@GOT" } } */ > ++/* { dg-final { scan-assembler "bnd jmp\[ \t\]*__x86.indirect_thunk_bnd" } } */ > ++/* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */ > ++/* { dg-final { scan-assembler "bnd call\[ \t\]*\.LIND" } } */ > ++/* { dg-final { scan-assembler "bnd ret" } } */ > ++/* { dg-final { scan-assembler {\tlfence} } } */ > +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-4.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-4.c > +new file mode 100644 > +index 00000000000..1c01bcb7fc6 > +--- /dev/null > ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-4.c > +@@ -0,0 +1,19 @@ > ++/* { dg-do compile { target { *-*-linux* && { ! x32 } } } } */ > ++/* { dg-options "-O2 -mindirect-branch=thunk -fcheck-pointer-bounds -mmpx -fpic -fno-plt" } */ > ++ > ++void bar (char *); > ++char buf[10]; > ++ > ++int > ++foo (void) > ++{ > ++ bar (buf); > ++ return 0; > ++} > ++ > ++/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*bar@GOT" } } */ > ++/* { dg-final { scan-assembler "bnd jmp\[ \t\]*__x86.indirect_thunk" } } */ > ++/* { dg-final { scan-assembler "bnd jmp\[ \t\]*\.LIND" } } */ > ++/* { dg-final { scan-assembler-times "bnd call\[ \t\]*\.LIND" 2 } } */ > ++/* { dg-final { scan-assembler "bnd ret" } } */ > ++/* { dg-final { scan-assembler {\tlfence} } } */ > +-- > +2.15.1 > + > diff --git a/gnu/packages/patches/gcc-retpoline-Disable-red-zone-with-local-indirect-jump.patch b/gnu/packages/patches/gcc-retpoline-Disable-red-zone-with-local-indirect-jump.patch > new file mode 100644 > index 000000000..b22e364af > --- /dev/null > +++ b/gnu/packages/patches/gcc-retpoline-Disable-red-zone-with-local-indirect-jump.patch > @@ -0,0 +1,147 @@ > +'Retpoline' mitigation technique for Spectre (branch target injection) > +[CVE-2017-5715]: > + > +https://security.googleblog.com/2018/01/more-details-about-mitigations-for-cpu_4.html > +https://support.google.com/faqs/answer/7625886 > +https://spectreattack.com/ > +https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2017-5715 > + > +Patch copied from the 'retpoline-20180107' branch of upstream source repository > +(please add new / update existing patches when new 'retpoline-xxxxxxxx' branch > +appears): > + > +http://git.infradead.org/users/dwmw2/gcc-retpoline.git > + > +From f96e28553b0f2253184441f22852d76976e19968 Mon Sep 17 00:00:00 2001 > +From: "H.J. Lu" <hjl.tools@gmail.com> > +Date: Tue, 12 Dec 2017 19:15:25 -0800 > +Subject: [PATCH 15/17] Disable red zone with local indirect jump > + > +--- > + gcc/config/i386/i386-protos.h | 2 +- > + gcc/config/i386/i386.c | 22 +++++++++++++++++----- > + gcc/config/i386/i386.h | 4 ++++ > + gcc/config/i386/i386.md | 8 +++++--- > + 4 files changed, 27 insertions(+), 9 deletions(-) > + > +diff --git a/gcc/config/i386/i386-protos.h b/gcc/config/i386/i386-protos.h > +index 213663811de..a78bfa00427 100644 > +--- a/gcc/config/i386/i386-protos.h > ++++ b/gcc/config/i386/i386-protos.h > +@@ -315,7 +315,7 @@ extern enum attr_cpu ix86_schedule; > + #endif > + > + extern const char * ix86_output_call_insn (rtx_insn *insn, rtx call_op); > +-extern const char * ix86_output_indirect_jmp (rtx call_op); > ++extern const char * ix86_output_indirect_jmp (rtx call_op, bool ret_p); > + extern const char * ix86_output_function_return (bool long_p); > + extern bool ix86_operands_ok_for_move_multiple (rtx *operands, bool load, > + enum machine_mode mode); > +diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c > +index 7ae3523095c..344cafe3dac 100644 > +--- a/gcc/config/i386/i386.c > ++++ b/gcc/config/i386/i386.c > +@@ -4209,12 +4209,19 @@ make_pass_stv (gcc::context *ctxt) > + return new pass_stv (ctxt); > + } > + > +-/* Return true if a red-zone is in use. */ > ++/* Return true if a red-zone is in use. We can't use red-zone when > ++ there are local indirect jumps, like "indirect_jump" or "tablejump", > ++ which jumps to another place in the function, since "call" in the > ++ indirect thunk pushes the return address onto stack, destroying > ++ red-zone. */ > + > + bool > + ix86_using_red_zone (void) > + { > +- return TARGET_RED_ZONE && !TARGET_64BIT_MS_ABI; > ++ return (TARGET_RED_ZONE > ++ && !TARGET_64BIT_MS_ABI > ++ && (!cfun->machine->has_local_indirect_jump > ++ || cfun->machine->indirect_branch_type == indirect_branch_keep)); > + } > + > + /* Return a string that documents the current -m options. The caller is > +@@ -28919,11 +28926,16 @@ ix86_output_indirect_branch (rtx call_op, const char *xasm, > + } > + > + const char * > +-ix86_output_indirect_jmp (rtx call_op) > ++ix86_output_indirect_jmp (rtx call_op, bool ret_p) > + { > +- if (ix86_red_zone_size == 0 > +- && cfun->machine->indirect_branch_type != indirect_branch_keep) > ++ if (cfun->machine->indirect_branch_type != indirect_branch_keep) > + { > ++ /* We can't have red-zone if this isn't a function return since > ++ "call" in the indirect thunk pushes the return address onto > ++ stack, destroying red-zone. */ > ++ if (!ret_p && ix86_red_zone_size != 0) > ++ gcc_unreachable (); > ++ > + ix86_output_indirect_branch (call_op, "%0", true); > + return ""; > + } > +diff --git a/gcc/config/i386/i386.h b/gcc/config/i386/i386.h > +index f248f3ba2f5..5f30d3f8d19 100644 > +--- a/gcc/config/i386/i386.h > ++++ b/gcc/config/i386/i386.h > +@@ -2607,6 +2607,10 @@ struct GTY(()) machine_function { > + /* How to generate indirec branch. */ > + ENUM_BITFIELD(indirect_branch) indirect_branch_type : 3; > + > ++ /* If true, the current function has local indirect jumps, like > ++ "indirect_jump" or "tablejump". */ > ++ BOOL_BITFIELD has_local_indirect_jump : 1; > ++ > + /* How to generate function return. */ > + ENUM_BITFIELD(indirect_branch) function_return_type : 3; > + > +diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md > +index 473fa5c089b..ea95aad7540 100644 > +--- a/gcc/config/i386/i386.md > ++++ b/gcc/config/i386/i386.md > +@@ -11610,12 +11610,13 @@ > + { > + if (TARGET_X32 || ix86_indirect_branch_thunk_register) > + operands[0] = convert_memory_address (word_mode, operands[0]); > ++ cfun->machine->has_local_indirect_jump = true; > + }) > + > + (define_insn "*indirect_jump" > + [(set (pc) (match_operand:W 0 "indirect_branch_operand" "rBw"))] > + "" > +- "* return ix86_output_indirect_jmp (operands[0]);" > ++ "* return ix86_output_indirect_jmp (operands[0], false);" > + [(set_attr "type" "ibr") > + (set_attr "length_immediate" "0") > + (set_attr "maybe_prefix_bnd" "1")]) > +@@ -11659,13 +11660,14 @@ > + > + if (TARGET_X32 || ix86_indirect_branch_thunk_register) > + operands[0] = convert_memory_address (word_mode, operands[0]); > ++ cfun->machine->has_local_indirect_jump = true; > + }) > + > + (define_insn "*tablejump_1" > + [(set (pc) (match_operand:W 0 "indirect_branch_operand" "rBw")) > + (use (label_ref (match_operand 1)))] > + "" > +- "* return ix86_output_indirect_jmp (operands[0]);" > ++ "* return ix86_output_indirect_jmp (operands[0], false);" > + [(set_attr "type" "ibr") > + (set_attr "length_immediate" "0") > + (set_attr "maybe_prefix_bnd" "1")]) > +@@ -12342,7 +12344,7 @@ > + [(simple_return) > + (use (match_operand:SI 0 "register_operand" "r"))] > + "reload_completed" > +- "* return ix86_output_indirect_jmp (operands[0]);" > ++ "* return ix86_output_indirect_jmp (operands[0], true);" > + [(set_attr "type" "ibr") > + (set_attr "length_immediate" "0") > + (set_attr "maybe_prefix_bnd" "1")]) > +-- > +2.15.1 > + > diff --git a/gnu/packages/patches/gcc-retpoline-Rename-thunks-to-__x86_indirect_thunk_rax-etc.-to-re.patch b/gnu/packages/patches/gcc-retpoline-Rename-thunks-to-__x86_indirect_thunk_rax-etc.-to-re.patch > new file mode 100644 > index 000000000..6379270df > --- /dev/null > +++ b/gnu/packages/patches/gcc-retpoline-Rename-thunks-to-__x86_indirect_thunk_rax-etc.-to-re.patch > @@ -0,0 +1,926 @@ > +'Retpoline' mitigation technique for Spectre (branch target injection) > +[CVE-2017-5715]: > + > +https://security.googleblog.com/2018/01/more-details-about-mitigations-for-cpu_4.html > +https://support.google.com/faqs/answer/7625886 > +https://spectreattack.com/ > +https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2017-5715 > + > +Patch copied from the 'retpoline-20180107' branch of upstream source repository > +(please add new / update existing patches when new 'retpoline-xxxxxxxx' branch > +appears): > + > +http://git.infradead.org/users/dwmw2/gcc-retpoline.git > + > +From a072725899c551d9f3f06f3595e2a49748ab0187 Mon Sep 17 00:00:00 2001 > +From: David Woodhouse <dwmw2@infradead.org> > +Date: Sun, 7 Jan 2018 17:27:09 +0000 > +Subject: [PATCH 17/17] Rename thunks to __x86_indirect_thunk_rax etc. to > + remove dots > + > +--- > + gcc/config/i386/i386.c | 8 ++++---- > + gcc/testsuite/gcc.target/i386/indirect-thunk-1.c | 4 ++-- > + gcc/testsuite/gcc.target/i386/indirect-thunk-2.c | 4 ++-- > + gcc/testsuite/gcc.target/i386/indirect-thunk-3.c | 4 ++-- > + gcc/testsuite/gcc.target/i386/indirect-thunk-4.c | 4 ++-- > + gcc/testsuite/gcc.target/i386/indirect-thunk-5.c | 2 +- > + gcc/testsuite/gcc.target/i386/indirect-thunk-6.c | 2 +- > + gcc/testsuite/gcc.target/i386/indirect-thunk-7.c | 4 ++-- > + gcc/testsuite/gcc.target/i386/indirect-thunk-attr-1.c | 4 ++-- > + gcc/testsuite/gcc.target/i386/indirect-thunk-attr-2.c | 4 ++-- > + gcc/testsuite/gcc.target/i386/indirect-thunk-attr-3.c | 2 +- > + gcc/testsuite/gcc.target/i386/indirect-thunk-attr-4.c | 2 +- > + gcc/testsuite/gcc.target/i386/indirect-thunk-attr-5.c | 4 ++-- > + gcc/testsuite/gcc.target/i386/indirect-thunk-attr-6.c | 4 ++-- > + gcc/testsuite/gcc.target/i386/indirect-thunk-attr-7.c | 4 ++-- > + gcc/testsuite/gcc.target/i386/indirect-thunk-attr-8.c | 2 +- > + gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-1.c | 2 +- > + gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-2.c | 2 +- > + gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-3.c | 2 +- > + gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-4.c | 2 +- > + gcc/testsuite/gcc.target/i386/indirect-thunk-extern-1.c | 4 ++-- > + gcc/testsuite/gcc.target/i386/indirect-thunk-extern-2.c | 4 ++-- > + gcc/testsuite/gcc.target/i386/indirect-thunk-extern-3.c | 4 ++-- > + gcc/testsuite/gcc.target/i386/indirect-thunk-extern-4.c | 4 ++-- > + gcc/testsuite/gcc.target/i386/indirect-thunk-extern-5.c | 2 +- > + gcc/testsuite/gcc.target/i386/indirect-thunk-extern-6.c | 2 +- > + gcc/testsuite/gcc.target/i386/indirect-thunk-extern-7.c | 4 ++-- > + gcc/testsuite/gcc.target/i386/indirect-thunk-inline-1.c | 2 +- > + gcc/testsuite/gcc.target/i386/indirect-thunk-inline-2.c | 2 +- > + gcc/testsuite/gcc.target/i386/indirect-thunk-inline-3.c | 2 +- > + gcc/testsuite/gcc.target/i386/indirect-thunk-inline-4.c | 2 +- > + gcc/testsuite/gcc.target/i386/indirect-thunk-inline-5.c | 2 +- > + gcc/testsuite/gcc.target/i386/indirect-thunk-inline-6.c | 2 +- > + gcc/testsuite/gcc.target/i386/indirect-thunk-inline-7.c | 2 +- > + gcc/testsuite/gcc.target/i386/indirect-thunk-loop-1.c | 4 ++-- > + gcc/testsuite/gcc.target/i386/indirect-thunk-loop-2.c | 4 ++-- > + gcc/testsuite/gcc.target/i386/indirect-thunk-loop-3.c | 4 ++-- > + gcc/testsuite/gcc.target/i386/indirect-thunk-loop-4.c | 2 +- > + gcc/testsuite/gcc.target/i386/indirect-thunk-loop-5.c | 4 ++-- > + gcc/testsuite/gcc.target/i386/indirect-thunk-register-1.c | 6 +++--- > + gcc/testsuite/gcc.target/i386/indirect-thunk-register-2.c | 2 +- > + gcc/testsuite/gcc.target/i386/indirect-thunk-register-3.c | 2 +- > + gcc/testsuite/gcc.target/i386/ret-thunk-1.c | 2 +- > + gcc/testsuite/gcc.target/i386/ret-thunk-10.c | 10 +++++----- > + gcc/testsuite/gcc.target/i386/ret-thunk-11.c | 10 +++++----- > + gcc/testsuite/gcc.target/i386/ret-thunk-12.c | 10 +++++----- > + gcc/testsuite/gcc.target/i386/ret-thunk-13.c | 6 +++--- > + gcc/testsuite/gcc.target/i386/ret-thunk-14.c | 6 +++--- > + gcc/testsuite/gcc.target/i386/ret-thunk-15.c | 6 +++--- > + gcc/testsuite/gcc.target/i386/ret-thunk-16.c | 4 ++-- > + gcc/testsuite/gcc.target/i386/ret-thunk-2.c | 2 +- > + gcc/testsuite/gcc.target/i386/ret-thunk-3.c | 2 +- > + gcc/testsuite/gcc.target/i386/ret-thunk-4.c | 2 +- > + gcc/testsuite/gcc.target/i386/ret-thunk-5.c | 2 +- > + gcc/testsuite/gcc.target/i386/ret-thunk-6.c | 2 +- > + gcc/testsuite/gcc.target/i386/ret-thunk-7.c | 2 +- > + gcc/testsuite/gcc.target/i386/ret-thunk-8.c | 2 +- > + gcc/testsuite/gcc.target/i386/ret-thunk-9.c | 10 +++++----- > + 58 files changed, 105 insertions(+), 105 deletions(-) > + > +diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c > +index 6cb0681233a..9e6c9bdb514 100644 > +--- a/gcc/config/i386/i386.c > ++++ b/gcc/config/i386/i386.c > +@@ -12006,13 +12006,13 @@ indirect_thunk_name (char name[32], int regno, bool need_bnd_p, > + reg_prefix = TARGET_64BIT ? "r" : "e"; > + else > + reg_prefix = ""; > +- sprintf (name, "__x86.indirect_thunk%s.%s%s", > ++ sprintf (name, "__x86_indirect_thunk%s_%s%s", > + bnd, reg_prefix, reg_names[regno]); > + } > + else > + { > + const char *ret = ret_p ? "return" : "indirect"; > +- sprintf (name, "__x86.%s_thunk%s", ret, bnd); > ++ sprintf (name, "__x86_%s_thunk%s", ret, bnd); > + } > + } > + else > +@@ -12119,7 +12119,7 @@ output_indirect_thunk_function (bool need_bnd_p, int regno) > + char name[32]; > + tree decl; > + > +- /* Create __x86.indirect_thunk/__x86.indirect_thunk_bnd. */ > ++ /* Create __x86_indirect_thunk/__x86_indirect_thunk_bnd. */ > + indirect_thunk_name (name, regno, need_bnd_p, false); > + decl = build_decl (BUILTINS_LOCATION, FUNCTION_DECL, > + get_identifier (name), > +@@ -12165,7 +12165,7 @@ output_indirect_thunk_function (bool need_bnd_p, int regno) > + > + if (regno < 0) > + { > +- /* Create alias for __x86.return_thunk/__x86.return_thunk_bnd. */ > ++ /* Create alias for __x86_return_thunk/__x86_return_thunk_bnd. */ > + char alias[32]; > + > + indirect_thunk_name (alias, regno, need_bnd_p, true); > +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-1.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-1.c > +index b0625207b92..f4f2b7debe0 100644 > +--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-1.c > ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-1.c > +@@ -12,8 +12,8 @@ male_indirect_jump (long offset) > + } > + > + /* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { ! x32 } } } } */ > +-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" { target { ! x32 } } } } */ > +-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk\.(r|e)ax" { target x32 } } } */ > ++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" { target { ! x32 } } } } */ > ++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk_(r|e)ax" { target x32 } } } */ > + /* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */ > + /* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */ > + /* { dg-final { scan-assembler {\tlfence} } } */ > +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-2.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-2.c > +index 0b289685e6b..d4e5dadd966 100644 > +--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-2.c > ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-2.c > +@@ -12,8 +12,8 @@ male_indirect_jump (long offset) > + } > + > + /* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { ! x32 } } } } */ > +-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" { target { ! x32 } } } } */ > +-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk\.(r|e)ax" { target x32 } } } */ > ++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" { target { ! x32 } } } } */ > ++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk_(r|e)ax" { target x32 } } } */ > + /* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */ > + /* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */ > + /* { dg-final { scan-assembler {\tlfence} } } */ > +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-3.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-3.c > +index 79a9f76285f..9802fae5d04 100644 > +--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-3.c > ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-3.c > +@@ -13,8 +13,8 @@ male_indirect_jump (long offset) > + } > + > + /* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { ! x32 } } } } */ > +-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" { target { ! x32 } } } } */ > +-/* { dg-final { scan-assembler "call\[ \t\]*__x86.indirect_thunk\.(r|e)ax" { target x32 } } } */ > ++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" { target { ! x32 } } } } */ > ++/* { dg-final { scan-assembler "call\[ \t\]*__x86_indirect_thunk_(r|e)ax" { target x32 } } } */ > + /* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */ > + /* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */ > + /* { dg-final { scan-assembler {\tlfence} } } */ > +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-4.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-4.c > +index 901d94213bd..fad3105b50d 100644 > +--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-4.c > ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-4.c > +@@ -13,8 +13,8 @@ male_indirect_jump (long offset) > + } > + > + /* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { ! x32 } } } } */ > +-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" { target { ! x32 } } } } */ > +-/* { dg-final { scan-assembler "call\[ \t\]*__x86.indirect_thunk\.(r|e)ax" { target x32 } } } */ > ++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" { target { ! x32 } } } } */ > ++/* { dg-final { scan-assembler "call\[ \t\]*__x86_indirect_thunk_(r|e)ax" { target x32 } } } */ > + /* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */ > + /* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */ > + /* { dg-final { scan-assembler {\tlfence} } } */ > +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-5.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-5.c > +index d2c9bd9d7ca..e44f2ff5682 100644 > +--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-5.c > ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-5.c > +@@ -10,7 +10,7 @@ foo (void) > + } > + > + /* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*bar@GOT" } } */ > +-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" } } */ > ++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" } } */ > + /* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */ > + /* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */ > + /* { dg-final { scan-assembler {\tlfence} } } */ > +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-6.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-6.c > +index f8b028db7a2..f1e03a30854 100644 > +--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-6.c > ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-6.c > +@@ -11,7 +11,7 @@ foo (void) > + } > + > + /* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*bar@GOT" } } */ > +-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" } } */ > ++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" } } */ > + /* { dg-final { scan-assembler-times "jmp\[ \t\]*\.LIND" 2 } } */ > + /* { dg-final { scan-assembler-times "call\[ \t\]*\.LIND" 2 } } */ > + /* { dg-final { scan-assembler {\tlfence} } } */ > +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-7.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-7.c > +index 465775407ec..fc91a334459 100644 > +--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-7.c > ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-7.c > +@@ -36,8 +36,8 @@ bar (int i) > + } > + > + /* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*\.L\[0-9\]+\\(,%" { target { ! x32 } } } } */ > +-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" { target { ! x32 } } } } */ > +-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk\.(r|e)ax" { target x32 } } } */ > ++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" { target { ! x32 } } } } */ > ++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk_(r|e)ax" { target x32 } } } */ > + /* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */ > + /* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */ > + /* { dg-final { scan-assembler {\tlfence} } } */ > +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-1.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-1.c > +index 5309d5a3eaa..a8ab95b6451 100644 > +--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-1.c > ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-1.c > +@@ -15,8 +15,8 @@ male_indirect_jump (long offset) > + } > + > + /* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { ! x32 } } } } */ > +-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" { target { ! x32 } } } } */ > +-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk\.(r|e)ax" { target x32 } } } */ > ++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" { target { ! x32 } } } } */ > ++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk_(r|e)ax" { target x32 } } } */ > + /* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */ > + /* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */ > + /* { dg-final { scan-assembler {\tlfence} } } */ > +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-2.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-2.c > +index dd1efca49fd..467d62324d5 100644 > +--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-2.c > ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-2.c > +@@ -13,8 +13,8 @@ male_indirect_jump (long offset) > + } > + > + /* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { ! x32 } } } } */ > +-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" { target { ! x32 } } } } */ > +-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk\.(r|e)ax" { target x32 } } } */ > ++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" { target { ! x32 } } } } */ > ++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk_(r|e)ax" { target x32 } } } */ > + /* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */ > + /* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */ > + /* { dg-final { scan-assembler {\tlfence} } } */ > +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-3.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-3.c > +index e97ca636020..02223f8d0f4 100644 > +--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-3.c > ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-3.c > +@@ -17,5 +17,5 @@ male_indirect_jump (long offset) > + /* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { ! x32 } } } } */ > + /* { dg-final { scan-assembler-times "jmp\[ \t\]*\.LIND" 2 } } */ > + /* { dg-final { scan-assembler-times "call\[ \t\]*\.LIND" 2 } } */ > +-/* { dg-final { scan-assembler-not "__x86.indirect_thunk" } } */ > ++/* { dg-final { scan-assembler-not "__x86_indirect_thunk" } } */ > + /* { dg-final { scan-assembler-not "pushq\[ \t\]%rax" { target x32 } } } */ > +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-4.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-4.c > +index b547cbbf255..a80b46af934 100644 > +--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-4.c > ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-4.c > +@@ -16,5 +16,5 @@ male_indirect_jump (long offset) > + /* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { ! x32 } } } } */ > + /* { dg-final { scan-assembler-times "jmp\[ \t\]*\.LIND" 2 } } */ > + /* { dg-final { scan-assembler-times "call\[ \t\]*\.LIND" 2 } } */ > +-/* { dg-final { scan-assembler-not "__x86.indirect_thunk" } } */ > ++/* { dg-final { scan-assembler-not "__x86_indirect_thunk" } } */ > + /* { dg-final { scan-assembler-not "pushq\[ \t\]%rax" { target x32 } } } */ > +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-5.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-5.c > +index 353689dc415..4bb1c5f9220 100644 > +--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-5.c > ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-5.c > +@@ -17,6 +17,6 @@ male_indirect_jump (long offset) > + /* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { ! x32 } } } } */ > + /* { dg-final { scan-assembler-times "jmp\[ \t\]*\.LIND" 1 { target { ! x32 } } } } */ > + /* { dg-final { scan-assembler-times "call\[ \t\]*\.LIND" 1 { target { ! x32 } } } } */ > +-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" { target { ! x32 } } } } */ > +-/* { dg-final { scan-assembler "call\[ \t\]*__x86.indirect_thunk\.(r|e)ax" { target x32 } } } */ > ++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" { target { ! x32 } } } } */ > ++/* { dg-final { scan-assembler "call\[ \t\]*__x86_indirect_thunk_(r|e)ax" { target x32 } } } */ > + /* { dg-final { scan-assembler-not {\t(lfence|pause)} } } */ > +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-6.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-6.c > +index 1edef7208f4..4e33a638862 100644 > +--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-6.c > ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-6.c > +@@ -16,6 +16,6 @@ male_indirect_jump (long offset) > + /* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { ! x32 } } } } */ > + /* { dg-final { scan-assembler-times "jmp\[ \t\]*\.LIND" 1 { target { ! x32 } } } } */ > + /* { dg-final { scan-assembler-times "call\[ \t\]*\.LIND" 1 { target { ! x32 } } } } */ > +-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" { target { ! x32 } } } } */ > +-/* { dg-final { scan-assembler "call\[ \t\]*__x86.indirect_thunk\.(r|e)ax" { target x32 } } } */ > ++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" { target { ! x32 } } } } */ > ++/* { dg-final { scan-assembler "call\[ \t\]*__x86_indirect_thunk_(r|e)ax" { target x32 } } } */ > + /* { dg-final { scan-assembler-not {\t(lfence|pause)} } } */ > +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-7.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-7.c > +index c2e816cdfc6..427ba3ddbb4 100644 > +--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-7.c > ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-7.c > +@@ -37,8 +37,8 @@ bar (int i) > + } > + > + /* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*\.L\[0-9\]+\\(,%" { target { ! x32 } } } } */ > +-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk\.(r|e)ax" { target x32 } } } */ > +-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" } } */ > ++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk_(r|e)ax" { target x32 } } } */ > ++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" } } */ > + /* { dg-final { scan-assembler-not {\t(lfence|pause)} } } */ > + /* { dg-final { scan-assembler-not "jmp\[ \t\]*\.LIND" } } */ > + /* { dg-final { scan-assembler-not "call\[ \t\]*\.LIND" } } */ > +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-8.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-8.c > +index af1bb125a22..c246f974610 100644 > +--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-8.c > ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-8.c > +@@ -36,6 +36,6 @@ bar (int i) > + } > + } > + > +-/* { dg-final { scan-assembler-not "__x86.indirect_thunk" } } */ > ++/* { dg-final { scan-assembler-not "__x86_indirect_thunk" } } */ > + /* { dg-final { scan-assembler-not "jmp\[ \t\]*\.LIND" } } */ > + /* { dg-final { scan-assembler-not "call\[ \t\]*\.LIND" } } */ > +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-1.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-1.c > +index 5c10de47b7c..3399ad56a7f 100644 > +--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-1.c > ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-1.c > +@@ -12,7 +12,7 @@ foo (void) > + > + /* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { ! x32 } } } } */ > + /* { dg-final { scan-assembler "pushq\[ \t\]%rax" { target x32 } } } */ > +-/* { dg-final { scan-assembler "bnd jmp\[ \t\]*__x86.indirect_thunk_bnd" } } */ > ++/* { dg-final { scan-assembler "bnd jmp\[ \t\]*__x86_indirect_thunk_bnd" } } */ > + /* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */ > + /* { dg-final { scan-assembler "bnd call\[ \t\]*\.LIND" } } */ > + /* { dg-final { scan-assembler "bnd ret" } } */ > +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-2.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-2.c > +index 9eedd9a5a82..daa9528f7bd 100644 > +--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-2.c > ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-2.c > +@@ -13,7 +13,7 @@ foo (void) > + > + /* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { ! x32 } } } } */ > + /* { dg-final { scan-assembler "pushq\[ \t\]%rax" { target x32 } } } */ > +-/* { dg-final { scan-assembler "bnd jmp\[ \t\]*__x86.indirect_thunk_bnd" } } */ > ++/* { dg-final { scan-assembler "bnd jmp\[ \t\]*__x86_indirect_thunk_bnd" } } */ > + /* { dg-final { scan-assembler "bnd jmp\[ \t\]*\.LIND" } } */ > + /* { dg-final { scan-assembler "bnd call\[ \t\]*\.LIND" } } */ > + /* { dg-final { scan-assembler "bnd ret" } } */ > +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-3.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-3.c > +index b2b8587eac7..647ec5a4ade 100644 > +--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-3.c > ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-3.c > +@@ -11,7 +11,7 @@ foo (void) > + } > + > + /* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*bar@GOT" } } */ > +-/* { dg-final { scan-assembler "bnd jmp\[ \t\]*__x86.indirect_thunk_bnd" } } */ > ++/* { dg-final { scan-assembler "bnd jmp\[ \t\]*__x86_indirect_thunk_bnd" } } */ > + /* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */ > + /* { dg-final { scan-assembler "bnd call\[ \t\]*\.LIND" } } */ > + /* { dg-final { scan-assembler "bnd ret" } } */ > +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-4.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-4.c > +index 9459a2417f4..3a7a1cea8bc 100644 > +--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-4.c > ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-4.c > +@@ -12,7 +12,7 @@ foo (void) > + } > + > + /* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*bar@GOT" } } */ > +-/* { dg-final { scan-assembler "bnd jmp\[ \t\]*__x86.indirect_thunk" } } */ > ++/* { dg-final { scan-assembler "bnd jmp\[ \t\]*__x86_indirect_thunk" } } */ > + /* { dg-final { scan-assembler "bnd jmp\[ \t\]*\.LIND" } } */ > + /* { dg-final { scan-assembler-times "bnd call\[ \t\]*\.LIND" 2 } } */ > + /* { dg-final { scan-assembler "bnd ret" } } */ > +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-1.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-1.c > +index b0aa3811e65..5c20a35ecec 100644 > +--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-1.c > ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-1.c > +@@ -12,8 +12,8 @@ male_indirect_jump (long offset) > + } > + > + /* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { ! x32 } } } } */ > +-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" { target { ! x32 } } } } */ > +-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk\.(r|e)ax" { target x32 } } } */ > ++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" { target { ! x32 } } } } */ > ++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk_(r|e)ax" { target x32 } } } */ > + /* { dg-final { scan-assembler-not {\t(lfence|pause)} } } */ > + /* { dg-final { scan-assembler-not "jmp\[ \t\]*\.LIND" } } */ > + /* { dg-final { scan-assembler-not "call\[ \t\]*\.LIND" } } */ > +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-2.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-2.c > +index 75fabcd988c..b2fb6e1bcd2 100644 > +--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-2.c > ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-2.c > +@@ -12,8 +12,8 @@ male_indirect_jump (long offset) > + } > + > + /* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { ! x32 } } } } */ > +-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" { target { ! x32 } } } } */ > +-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk\.(r|e)ax" { target x32 } } } */ > ++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" { target { ! x32 } } } } */ > ++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk_(r|e)ax" { target x32 } } } */ > + /* { dg-final { scan-assembler-not {\t(lfence|pause)} } } */ > + /* { dg-final { scan-assembler-not "jmp\[ \t\]*\.LIND" } } */ > + /* { dg-final { scan-assembler-not "call\[ \t\]*\.LIND" } } */ > +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-3.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-3.c > +index 1d9dff2e834..9c84547cd7c 100644 > +--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-3.c > ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-3.c > +@@ -13,8 +13,8 @@ male_indirect_jump (long offset) > + } > + > + /* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { ! x32 } } } } */ > +-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" { target { ! x32 } } } } */ > ++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" { target { ! x32 } } } } */ > + /* { dg-final { scan-assembler-times "jmp\[ \t\]*\.LIND" 1 { target { ! x32 } } } } */ > + /* { dg-final { scan-assembler-times "call\[ \t\]*\.LIND" 1 { target { ! x32 } } } } */ > +-/* { dg-final { scan-assembler "call\[ \t\]*__x86.indirect_thunk\.(r|e)ax" { target x32 } } } */ > ++/* { dg-final { scan-assembler "call\[ \t\]*__x86_indirect_thunk_(r|e)ax" { target x32 } } } */ > + /* { dg-final { scan-assembler-not {\t(lfence|pause)} } } */ > +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-4.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-4.c > +index 5b464155e38..457849564bb 100644 > +--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-4.c > ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-4.c > +@@ -13,8 +13,8 @@ male_indirect_jump (long offset) > + } > + > + /* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { ! x32 } } } } */ > +-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" { target { ! x32 } } } } */ > ++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" { target { ! x32 } } } } */ > + /* { dg-final { scan-assembler-times "jmp\[ \t\]*\.LIND" 1 { target { ! x32 } } } } */ > + /* { dg-final { scan-assembler-times "call\[ \t\]*\.LIND" 1 { target { ! x32 } } } } */ > +-/* { dg-final { scan-assembler "call\[ \t\]*__x86.indirect_thunk\.(r|e)ax" { target x32 } } } */ > ++/* { dg-final { scan-assembler "call\[ \t\]*__x86_indirect_thunk_(r|e)ax" { target x32 } } } */ > + /* { dg-final { scan-assembler-not {\t(lfence|pause)} } } */ > +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-5.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-5.c > +index 55ce91c73ec..5c07e02df6a 100644 > +--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-5.c > ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-5.c > +@@ -10,7 +10,7 @@ foo (void) > + } > + > + /* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*bar@GOT" } } */ > +-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" } } */ > ++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" } } */ > + /* { dg-final { scan-assembler-not {\t(lfence|pause)} } } */ > + /* { dg-final { scan-assembler-not "jmp\[ \t\]*\.LIND" } } */ > + /* { dg-final { scan-assembler-not "call\[ \t\]*\.LIND" } } */ > +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-6.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-6.c > +index 06180e7bee9..3eb440693a0 100644 > +--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-6.c > ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-6.c > +@@ -13,5 +13,5 @@ foo (void) > + /* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*bar@GOT" } } */ > + /* { dg-final { scan-assembler-times "jmp\[ \t\]*\.LIND" 1 } } */ > + /* { dg-final { scan-assembler-times "call\[ \t\]*\.LIND" 1 } } */ > +-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" } } */ > ++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" } } */ > + /* { dg-final { scan-assembler-not {\t(lfence|pause)} } } */ > +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-7.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-7.c > +index 790a05cec3e..d4747ea0764 100644 > +--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-7.c > ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-7.c > +@@ -36,8 +36,8 @@ bar (int i) > + } > + > + /* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*\.L\[0-9\]+\\(,%" { target { ! x32 } } } } */ > +-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" { target { ! x32 } } } } */ > +-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk\.(r|e)ax" { target x32 } } } */ > ++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" { target { ! x32 } } } } */ > ++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk_(r|e)ax" { target x32 } } } */ > + /* { dg-final { scan-assembler-not {\t(lfence|pause)} } } */ > + /* { dg-final { scan-assembler-not "jmp\[ \t\]*\.LIND" } } */ > + /* { dg-final { scan-assembler-not "call\[ \t\]*\.LIND" } } */ > +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-1.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-1.c > +index 1ce8ca5aff1..f7fad345ca4 100644 > +--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-1.c > ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-1.c > +@@ -14,5 +14,5 @@ male_indirect_jump (long offset) > + /* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { ! x32 } } } } */ > + /* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */ > + /* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */ > +-/* { dg-final { scan-assembler-not "__x86.indirect_thunk" } } */ > ++/* { dg-final { scan-assembler-not "__x86_indirect_thunk" } } */ > + /* { dg-final { scan-assembler-not "pushq\[ \t\]%rax" { target x32 } } } */ > +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-2.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-2.c > +index f6b71e868bd..91388544a20 100644 > +--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-2.c > ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-2.c > +@@ -14,5 +14,5 @@ male_indirect_jump (long offset) > + /* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { ! x32 } } } } */ > + /* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */ > + /* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */ > +-/* { dg-final { scan-assembler-not "__x86.indirect_thunk" } } */ > ++/* { dg-final { scan-assembler-not "__x86_indirect_thunk" } } */ > + /* { dg-final { scan-assembler-not "pushq\[ \t\]%rax" { target x32 } } } */ > +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-3.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-3.c > +index 84a09d4d0d6..69f03e6472e 100644 > +--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-3.c > ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-3.c > +@@ -15,5 +15,5 @@ male_indirect_jump (long offset) > + /* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { ! x32 } } } } */ > + /* { dg-final { scan-assembler-times "jmp\[ \t\]*\.LIND" 2 } } */ > + /* { dg-final { scan-assembler-times "call\[ \t\]*\.LIND" 2 } } */ > +-/* { dg-final { scan-assembler-not "__x86.indirect_thunk" } } */ > ++/* { dg-final { scan-assembler-not "__x86_indirect_thunk" } } */ > + /* { dg-final { scan-assembler-not "pushq\[ \t\]%rax" { target x32 } } } */ > +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-4.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-4.c > +index cfe3aefa0bf..226b776abcf 100644 > +--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-4.c > ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-4.c > +@@ -15,5 +15,5 @@ male_indirect_jump (long offset) > + /* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { ! x32 } } } } */ > + /* { dg-final { scan-assembler-times "jmp\[ \t\]*\.LIND" 2 } } */ > + /* { dg-final { scan-assembler-times "call\[ \t\]*\.LIND" 2 } } */ > +-/* { dg-final { scan-assembler-not "__x86.indirect_thunk" } } */ > ++/* { dg-final { scan-assembler-not "__x86_indirect_thunk" } } */ > + /* { dg-final { scan-assembler-not "pushq\[ \t\]%rax" { target x32 } } } */ > +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-5.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-5.c > +index 6411454243f..b9120017c10 100644 > +--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-5.c > ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-5.c > +@@ -12,4 +12,4 @@ foo (void) > + /* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*bar@GOT" } } */ > + /* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */ > + /* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */ > +-/* { dg-final { scan-assembler-not "__x86.indirect_thunk" } } */ > ++/* { dg-final { scan-assembler-not "__x86_indirect_thunk" } } */ > +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-6.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-6.c > +index d4297fe21c4..fbd6f9ec457 100644 > +--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-6.c > ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-6.c > +@@ -13,4 +13,4 @@ foo (void) > + /* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*bar@GOT" } } */ > + /* { dg-final { scan-assembler-times "jmp\[ \t\]*\.LIND" 2 } } */ > + /* { dg-final { scan-assembler-times "call\[ \t\]*\.LIND" 2 } } */ > +-/* { dg-final { scan-assembler-not "__x86.indirect_thunk" } } */ > ++/* { dg-final { scan-assembler-not "__x86_indirect_thunk" } } */ > +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-7.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-7.c > +index eb318efdf4d..2553c56f97f 100644 > +--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-7.c > ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-7.c > +@@ -39,4 +39,4 @@ bar (int i) > + /* { dg-final { scan-assembler-not "pushq\[ \t\]%rax" { target x32 } } } */ > + /* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */ > + /* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */ > +-/* { dg-final { scan-assembler-not "__x86.indirect_thunk" } } */ > ++/* { dg-final { scan-assembler-not "__x86_indirect_thunk" } } */ > +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-loop-1.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-loop-1.c > +index 605e32bb584..c266ca6f2da 100644 > +--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-loop-1.c > ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-loop-1.c > +@@ -12,8 +12,8 @@ male_indirect_jump (long offset) > + } > + > + /* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { ! x32 } } } } */ > +-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" { target { ! x32 } } } } */ > +-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk\.(r|e)ax" { target x32 } } } */ > ++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" { target { ! x32 } } } } */ > ++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk_(r|e)ax" { target x32 } } } */ > + /* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */ > + /* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */ > + /* { dg-final { scan-assembler {\tpause} } } */ > +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-loop-2.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-loop-2.c > +index dd7a7b60621..f7c1cf6c45a 100644 > +--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-loop-2.c > ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-loop-2.c > +@@ -12,8 +12,8 @@ male_indirect_jump (long offset) > + } > + > + /* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { ! x32 } } } } */ > +-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" { target { ! x32 } } } } */ > +-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk\.(r|e)ax" { target x32 } } } */ > ++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" { target { ! x32 } } } } */ > ++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk_(r|e)ax" { target x32 } } } */ > + /* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */ > + /* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */ > + /* { dg-final { scan-assembler {\tnop} } } */ > +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-loop-3.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-loop-3.c > +index 338f22c373c..ef5c4b84312 100644 > +--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-loop-3.c > ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-loop-3.c > +@@ -12,8 +12,8 @@ male_indirect_jump (long offset) > + } > + > + /* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { ! x32 } } } } */ > +-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" { target { ! x32 } } } } */ > +-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk\.(r|e)ax" { target x32 } } } */ > ++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" { target { ! x32 } } } } */ > ++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk_(r|e)ax" { target x32 } } } */ > + /* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */ > + /* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */ > + /* { dg-final { scan-assembler {\tlfence} } } */ > +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-loop-4.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-loop-4.c > +index 3b083ee30a8..941fcdaffb1 100644 > +--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-loop-4.c > ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-loop-4.c > +@@ -15,5 +15,5 @@ male_indirect_jump (long offset) > + /* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */ > + /* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */ > + /* { dg-final { scan-assembler {\tpause} } } */ > +-/* { dg-final { scan-assembler-not "__x86.indirect_thunk" } } */ > ++/* { dg-final { scan-assembler-not "__x86_indirect_thunk" } } */ > + /* { dg-final { scan-assembler-not "pushq\[ \t\]%rax" { target x32 } } } */ > +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-loop-5.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-loop-5.c > +index 31a9a81a911..0c5ace58358 100644 > +--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-loop-5.c > ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-loop-5.c > +@@ -12,8 +12,8 @@ male_indirect_jump (long offset) > + } > + > + /* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { ! x32 } } } } */ > +-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" { target { ! x32 } } } } */ > +-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk\.(r|e)ax" { target x32 } } } */ > ++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" { target { ! x32 } } } } */ > ++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk_(r|e)ax" { target x32 } } } */ > + /* { dg-final { scan-assembler-not {\t(lfence|pause|nop)} } } */ > + /* { dg-final { scan-assembler-not "jmp\[ \t\]*\.LIND" } } */ > + /* { dg-final { scan-assembler-not "call\[ \t\]*\.LIND" } } */ > +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-register-1.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-register-1.c > +index ef493a05bbf..1a28abb4604 100644 > +--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-register-1.c > ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-register-1.c > +@@ -11,12 +11,12 @@ male_indirect_jump (long offset) > + dispatch(offset); > + } > + > +-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk\.(r|e)ax" } } */ > ++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk_(r|e)ax" } } */ > + /* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */ > + /* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */ > + /* { dg-final { scan-assembler "mov\[ \t\](%eax|%rax), \\((%esp|%rsp)\\)" } } */ > + /* { dg-final { scan-assembler {\tlfence} } } */ > + /* { dg-final { scan-assembler-not "push(?:l|q)\[ \t\]*_?dispatch" } } */ > + /* { dg-final { scan-assembler-not "pushq\[ \t\]%rax" } } */ > +-/* { dg-final { scan-assembler-not "__x86.indirect_thunk\n" } } */ > +-/* { dg-final { scan-assembler-not "__x86.indirect_thunk_bnd\n" } } */ > ++/* { dg-final { scan-assembler-not "__x86_indirect_thunk_" } } */ > ++/* { dg-final { scan-assembler-not "__x86_indirect_thunk_bnd\n" } } */ > +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-register-2.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-register-2.c > +index 89fc8e6e6c4..428d6f9e986 100644 > +--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-register-2.c > ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-register-2.c > +@@ -17,4 +17,4 @@ male_indirect_jump (long offset) > + /* { dg-final { scan-assembler {\tlfence} } } */ > + /* { dg-final { scan-assembler-not "push(?:l|q)\[ \t\]*_?dispatch" } } */ > + /* { dg-final { scan-assembler-not "pushq\[ \t\]%rax" } } */ > +-/* { dg-final { scan-assembler-not "__x86.indirect_thunk" } } */ > ++/* { dg-final { scan-assembler-not "__x86_indirect_thunk" } } */ > +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-register-3.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-register-3.c > +index 31af7ac05b8..28dcdcf2855 100644 > +--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-register-3.c > ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-register-3.c > +@@ -11,7 +11,7 @@ male_indirect_jump (long offset) > + dispatch(offset); > + } > + > +-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk\.(r|e)ax" } } */ > ++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk_(r|e)ax" } } */ > + /* { dg-final { scan-assembler-not "push(?:l|q)\[ \t\]*_?dispatch" } } */ > + /* { dg-final { scan-assembler-not "pushq\[ \t\]%rax" } } */ > + /* { dg-final { scan-assembler-not {\t(lfence|pause|nop)} } } */ > +diff --git a/gcc/testsuite/gcc.target/i386/ret-thunk-1.c b/gcc/testsuite/gcc.target/i386/ret-thunk-1.c > +index 406956f48e5..07f382c21b2 100644 > +--- a/gcc/testsuite/gcc.target/i386/ret-thunk-1.c > ++++ b/gcc/testsuite/gcc.target/i386/ret-thunk-1.c > +@@ -6,7 +6,7 @@ foo (void) > + { > + } > + > +-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.return_thunk" } } */ > ++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_return_thunk" } } */ > + /* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */ > + /* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */ > + /* { dg-final { scan-assembler {\tlfence} } } */ > +diff --git a/gcc/testsuite/gcc.target/i386/ret-thunk-10.c b/gcc/testsuite/gcc.target/i386/ret-thunk-10.c > +index 74f37ee9a62..da8029bad49 100644 > +--- a/gcc/testsuite/gcc.target/i386/ret-thunk-10.c > ++++ b/gcc/testsuite/gcc.target/i386/ret-thunk-10.c > +@@ -12,11 +12,11 @@ foo (void) > + > + /* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */ > + /* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */ > +-/* { dg-final { scan-assembler-not "jmp\[ \t\]*__x86.return_thunk" } } */ > ++/* { dg-final { scan-assembler-not "jmp\[ \t\]*__x86_return_thunk" } } */ > + /* { dg-final { scan-assembler-times {\tlfence} 2 } } */ > + /* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?bar" { target { ! x32 } } } } */ > +-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" { target { ! x32 } } } } */ > +-/* { dg-final { scan-assembler "__x86.indirect_thunk:" { target { ! x32 } } } } */ > +-/* { dg-final { scan-assembler "call\[ \t\]*__x86.indirect_thunk\.(r|e)ax" { target { x32 } } } } */ > +-/* { dg-final { scan-assembler "__x86.indirect_thunk\.(r|e)ax:" { target { x32 } } } } */ > ++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" { target { ! x32 } } } } */ > ++/* { dg-final { scan-assembler "__x86_indirect_thunk:" { target { ! x32 } } } } */ > ++/* { dg-final { scan-assembler "call\[ \t\]*__x86_indirect_thunk_(r|e)ax" { target { x32 } } } } */ > ++/* { dg-final { scan-assembler "__x86_indirect_thunk_(r|e)ax:" { target { x32 } } } } */ > + /* { dg-final { scan-assembler-not "pushq\[ \t\]%rax" { target x32 } } } */ > +diff --git a/gcc/testsuite/gcc.target/i386/ret-thunk-11.c b/gcc/testsuite/gcc.target/i386/ret-thunk-11.c > +index 0a52318e86b..6964997871d 100644 > +--- a/gcc/testsuite/gcc.target/i386/ret-thunk-11.c > ++++ b/gcc/testsuite/gcc.target/i386/ret-thunk-11.c > +@@ -10,13 +10,13 @@ foo (void) > + return 0; > + } > + > +-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.return_thunk" } } */ > ++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_return_thunk" } } */ > + /* { dg-final { scan-assembler-times {\tlfence} 1 } } */ > + /* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */ > + /* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */ > + /* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?bar" { target { ! x32 } } } } */ > +-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" { target { ! x32 } } } } */ > +-/* { dg-final { scan-assembler "__x86.indirect_thunk:" { target { ! x32 } } } } */ > +-/* { dg-final { scan-assembler "call\[ \t\]*__x86.indirect_thunk\.(r|e)ax" { target { x32 } } } } */ > +-/* { dg-final { scan-assembler "__x86.indirect_thunk\.(r|e)ax:" { target { x32 } } } } */ > ++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" { target { ! x32 } } } } */ > ++/* { dg-final { scan-assembler "__x86_indirect_thunk:" { target { ! x32 } } } } */ > ++/* { dg-final { scan-assembler "call\[ \t\]*__x86_indirect_thunk_(r|e)ax" { target { x32 } } } } */ > ++/* { dg-final { scan-assembler "__x86_indirect_thunk_(r|e)ax:" { target { x32 } } } } */ > + /* { dg-final { scan-assembler-not "pushq\[ \t\]%rax" { target x32 } } } */ > +diff --git a/gcc/testsuite/gcc.target/i386/ret-thunk-12.c b/gcc/testsuite/gcc.target/i386/ret-thunk-12.c > +index d2f775490ea..ff0234bd17d 100644 > +--- a/gcc/testsuite/gcc.target/i386/ret-thunk-12.c > ++++ b/gcc/testsuite/gcc.target/i386/ret-thunk-12.c > +@@ -10,12 +10,12 @@ foo (void) > + return 0; > + } > + > +-/* { dg-final { scan-assembler-not "jmp\[ \t\]*__x86.return_thunk" } } */ > ++/* { dg-final { scan-assembler-not "jmp\[ \t\]*__x86_return_thunk" } } */ > + /* { dg-final { scan-assembler-times {\tlfence} 1 } } */ > + /* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */ > + /* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */ > +-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" { target { ! x32 } } } } */ > +-/* { dg-final { scan-assembler "__x86.indirect_thunk:" { target { ! x32 } } } } */ > +-/* { dg-final { scan-assembler "call\[ \t\]*__x86.indirect_thunk\.(r|e)ax" { target { x32 } } } } */ > +-/* { dg-final { scan-assembler "__x86.indirect_thunk\.(r|e)ax:" { target { x32 } } } } */ > ++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" { target { ! x32 } } } } */ > ++/* { dg-final { scan-assembler "__x86_indirect_thunk:" { target { ! x32 } } } } */ > ++/* { dg-final { scan-assembler "call\[ \t\]*__x86_indirect_thunk_(r|e)ax" { target { x32 } } } } */ > ++/* { dg-final { scan-assembler "__x86_indirect_thunk_(r|e)ax:" { target { x32 } } } } */ > + /* { dg-final { scan-assembler-not "pushq\[ \t\]%rax" { target x32 } } } */ > +diff --git a/gcc/testsuite/gcc.target/i386/ret-thunk-13.c b/gcc/testsuite/gcc.target/i386/ret-thunk-13.c > +index 82d46165f3e..a5b16472051 100644 > +--- a/gcc/testsuite/gcc.target/i386/ret-thunk-13.c > ++++ b/gcc/testsuite/gcc.target/i386/ret-thunk-13.c > +@@ -11,11 +11,11 @@ foo (void) > + return 0; > + } > + > +-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.return_thunk" } } */ > ++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_return_thunk" } } */ > + /* { dg-final { scan-assembler-times {\tlfence} 2 } } */ > + /* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?bar" { target { ! x32 } } } } */ > + /* { dg-final { scan-assembler-times "jmp\[ \t\]*\.LIND" 3 } } */ > + /* { dg-final { scan-assembler-times "call\[ \t\]*\.LIND" 3 } } */ > +-/* { dg-final { scan-assembler-not "jmp\[ \t\]*__x86.indirect_thunk" } } */ > +-/* { dg-final { scan-assembler-not "call\[ \t\]*__x86.indirect_thunk\.(r|e)ax" { target { x32 } } } } */ > ++/* { dg-final { scan-assembler-not "jmp\[ \t\]*__x86_indirect_thunk" } } */ > ++/* { dg-final { scan-assembler-not "call\[ \t\]*__x86_indirect_thunk_(r|e)ax" { target { x32 } } } } */ > + /* { dg-final { scan-assembler-not "pushq\[ \t\]%rax" { target x32 } } } */ > +diff --git a/gcc/testsuite/gcc.target/i386/ret-thunk-14.c b/gcc/testsuite/gcc.target/i386/ret-thunk-14.c > +index 6711eb27fa8..219d71548bf 100644 > +--- a/gcc/testsuite/gcc.target/i386/ret-thunk-14.c > ++++ b/gcc/testsuite/gcc.target/i386/ret-thunk-14.c > +@@ -12,10 +12,10 @@ foo (void) > + } > + > + /* { dg-final { scan-assembler-times {\tlfence} 1 } } */ > +-/* { dg-final { scan-assembler-not "jmp\[ \t\]*__x86.return_thunk" } } */ > ++/* { dg-final { scan-assembler-not "jmp\[ \t\]*__x86_return_thunk" } } */ > + /* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */ > + /* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */ > + /* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?bar" { target { ! x32 } } } } */ > +-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" { target { ! x32 } } } } */ > +-/* { dg-final { scan-assembler "call\[ \t\]*__x86.indirect_thunk\.(r|e)ax" { target { x32 } } } } */ > ++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" { target { ! x32 } } } } */ > ++/* { dg-final { scan-assembler "call\[ \t\]*__x86_indirect_thunk_(r|e)ax" { target { x32 } } } } */ > + /* { dg-final { scan-assembler-not "pushq\[ \t\]%rax" { target x32 } } } */ > +diff --git a/gcc/testsuite/gcc.target/i386/ret-thunk-15.c b/gcc/testsuite/gcc.target/i386/ret-thunk-15.c > +index 37758c33371..bad6b16820d 100644 > +--- a/gcc/testsuite/gcc.target/i386/ret-thunk-15.c > ++++ b/gcc/testsuite/gcc.target/i386/ret-thunk-15.c > +@@ -11,11 +11,11 @@ foo (void) > + return 0; > + } > + > +-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.return_thunk" } } */ > ++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_return_thunk" } } */ > + /* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */ > + /* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */ > + /* { dg-final { scan-assembler-times {\tlfence} 1 } } */ > + /* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?bar" { target { ! x32 } } } } */ > +-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" { target { ! x32 } } } } */ > +-/* { dg-final { scan-assembler "call\[ \t\]*__x86.indirect_thunk\.(r|e)ax" { target x32 } } } */ > ++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" { target { ! x32 } } } } */ > ++/* { dg-final { scan-assembler "call\[ \t\]*__x86_indirect_thunk_(r|e)ax" { target x32 } } } */ > + /* { dg-final { scan-assembler-not "pushq\[ \t\]%rax" { target x32 } } } */ > +diff --git a/gcc/testsuite/gcc.target/i386/ret-thunk-16.c b/gcc/testsuite/gcc.target/i386/ret-thunk-16.c > +index cf3920563e0..173fe243d7b 100644 > +--- a/gcc/testsuite/gcc.target/i386/ret-thunk-16.c > ++++ b/gcc/testsuite/gcc.target/i386/ret-thunk-16.c > +@@ -11,8 +11,8 @@ foo (void) > + return 0; > + } > + > +-/* { dg-final { scan-assembler-not "__x86.indirect_thunk" } } */ > +-/* { dg-final { scan-assembler-not "__x86.return_thunk" } } */ > ++/* { dg-final { scan-assembler-not "__x86_indirect_thunk" } } */ > ++/* { dg-final { scan-assembler-not "__x86_return_thunk" } } */ > + /* { dg-final { scan-assembler-not {\tlfence} } } */ > + /* { dg-final { scan-assembler-not "jmp\[ \t\]*\.LIND" } } */ > + /* { dg-final { scan-assembler-not "call\[ \t\]*\.LIND" } } */ > +diff --git a/gcc/testsuite/gcc.target/i386/ret-thunk-2.c b/gcc/testsuite/gcc.target/i386/ret-thunk-2.c > +index 190947cc2ca..5516813a290 100644 > +--- a/gcc/testsuite/gcc.target/i386/ret-thunk-2.c > ++++ b/gcc/testsuite/gcc.target/i386/ret-thunk-2.c > +@@ -9,4 +9,4 @@ foo (void) > + /* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */ > + /* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */ > + /* { dg-final { scan-assembler {\tlfence} } } */ > +-/* { dg-final { scan-assembler-not "jmp\[ \t\]*__x86.return_thunk" } } */ > ++/* { dg-final { scan-assembler-not "jmp\[ \t\]*__x86_return_thunk" } } */ > +diff --git a/gcc/testsuite/gcc.target/i386/ret-thunk-3.c b/gcc/testsuite/gcc.target/i386/ret-thunk-3.c > +index d71de3ac520..9f1ade857ef 100644 > +--- a/gcc/testsuite/gcc.target/i386/ret-thunk-3.c > ++++ b/gcc/testsuite/gcc.target/i386/ret-thunk-3.c > +@@ -6,7 +6,7 @@ foo (void) > + { > + } > + > +-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.return_thunk" } } */ > ++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_return_thunk" } } */ > + /* { dg-final { scan-assembler-not {\tlfence} } } */ > + /* { dg-final { scan-assembler-not "jmp\[ \t\]*\.LIND" } } */ > + /* { dg-final { scan-assembler-not "call\[ \t\]*\.LIND" } } */ > +diff --git a/gcc/testsuite/gcc.target/i386/ret-thunk-4.c b/gcc/testsuite/gcc.target/i386/ret-thunk-4.c > +index 68c22122f0d..abecde0a550 100644 > +--- a/gcc/testsuite/gcc.target/i386/ret-thunk-4.c > ++++ b/gcc/testsuite/gcc.target/i386/ret-thunk-4.c > +@@ -6,7 +6,7 @@ foo (void) > + { > + } > + > +-/* { dg-final { scan-assembler-not "jmp\[ \t\]*__x86.return_thunk" } } */ > ++/* { dg-final { scan-assembler-not "jmp\[ \t\]*__x86_return_thunk" } } */ > + /* { dg-final { scan-assembler-not {\tlfence} } } */ > + /* { dg-final { scan-assembler-not "jmp\[ \t\]*\.LIND" } } */ > + /* { dg-final { scan-assembler-not "call\[ \t\]*\.LIND" } } */ > +diff --git a/gcc/testsuite/gcc.target/i386/ret-thunk-5.c b/gcc/testsuite/gcc.target/i386/ret-thunk-5.c > +index 28c576e2267..3b51a9931db 100644 > +--- a/gcc/testsuite/gcc.target/i386/ret-thunk-5.c > ++++ b/gcc/testsuite/gcc.target/i386/ret-thunk-5.c > +@@ -8,7 +8,7 @@ foo (void) > + { > + } > + > +-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.return_thunk" } } */ > ++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_return_thunk" } } */ > + /* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */ > + /* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */ > + /* { dg-final { scan-assembler {\tlfence} } } */ > +diff --git a/gcc/testsuite/gcc.target/i386/ret-thunk-6.c b/gcc/testsuite/gcc.target/i386/ret-thunk-6.c > +index 10ad40b9c26..52160e0ee77 100644 > +--- a/gcc/testsuite/gcc.target/i386/ret-thunk-6.c > ++++ b/gcc/testsuite/gcc.target/i386/ret-thunk-6.c > +@@ -10,4 +10,4 @@ foo (void) > + /* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */ > + /* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */ > + /* { dg-final { scan-assembler {\tlfence} } } */ > +-/* { dg-final { scan-assembler-not "jmp\[ \t\]*__x86.return_thunk" } } */ > ++/* { dg-final { scan-assembler-not "jmp\[ \t\]*__x86_return_thunk" } } */ > +diff --git a/gcc/testsuite/gcc.target/i386/ret-thunk-7.c b/gcc/testsuite/gcc.target/i386/ret-thunk-7.c > +index 7ac0beaa73e..65819c2ab76 100644 > +--- a/gcc/testsuite/gcc.target/i386/ret-thunk-7.c > ++++ b/gcc/testsuite/gcc.target/i386/ret-thunk-7.c > +@@ -7,7 +7,7 @@ foo (void) > + { > + } > + > +-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.return_thunk" } } */ > ++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_return_thunk" } } */ > + /* { dg-final { scan-assembler-not {\tlfence} } } */ > + /* { dg-final { scan-assembler-not "jmp\[ \t\]*\.LIND" } } */ > + /* { dg-final { scan-assembler-not "call\[ \t\]*\.LIND" } } */ > +diff --git a/gcc/testsuite/gcc.target/i386/ret-thunk-8.c b/gcc/testsuite/gcc.target/i386/ret-thunk-8.c > +index 777ab7c8088..a6a1bbc054b 100644 > +--- a/gcc/testsuite/gcc.target/i386/ret-thunk-8.c > ++++ b/gcc/testsuite/gcc.target/i386/ret-thunk-8.c > +@@ -8,7 +8,7 @@ foo (void) > + { > + } > + > +-/* { dg-final { scan-assembler-not "jmp\[ \t\]*__x86.return_thunk" } } */ > ++/* { dg-final { scan-assembler-not "jmp\[ \t\]*__x86_return_thunk" } } */ > + /* { dg-final { scan-assembler-not {\tlfence} } } */ > + /* { dg-final { scan-assembler-not "jmp\[ \t\]*\.LIND" } } */ > + /* { dg-final { scan-assembler-not "call\[ \t\]*\.LIND" } } */ > +diff --git a/gcc/testsuite/gcc.target/i386/ret-thunk-9.c b/gcc/testsuite/gcc.target/i386/ret-thunk-9.c > +index 70771ea35d7..21a0e6bde3d 100644 > +--- a/gcc/testsuite/gcc.target/i386/ret-thunk-9.c > ++++ b/gcc/testsuite/gcc.target/i386/ret-thunk-9.c > +@@ -10,14 +10,14 @@ foo (void) > + return 0; > + } > + > +-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.return_thunk" } } */ > +-/* { dg-final { scan-assembler-not "__x86.return_thunk:" } } */ > ++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_return_thunk" } } */ > ++/* { dg-final { scan-assembler-not "__x86_return_thunk:" } } */ > + /* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */ > + /* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */ > +-/* { dg-final { scan-assembler "__x86.indirect_thunk:" } } */ > ++/* { dg-final { scan-assembler "__x86_indirect_thunk:" } } */ > + /* { dg-final { scan-assembler-times {\tlfence} 1 { target { ! x32 } } } } */ > + /* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?bar" { target { ! x32 } } } } */ > +-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" { target { ! x32 } } } } */ > ++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" { target { ! x32 } } } } */ > + /* { dg-final { scan-assembler-times {\tlfence} 2 { target { x32 } } } } */ > +-/* { dg-final { scan-assembler "call\[ \t\]*__x86.indirect_thunk\.(r|e)ax" { target { x32 } } } } */ > ++/* { dg-final { scan-assembler "call\[ \t\]*__x86_indirect_thunk_(r|e)ax" { target { x32 } } } } */ > + /* { dg-final { scan-assembler-not "pushq\[ \t\]%rax" { target x32 } } } */ > +-- > +2.15.1 > + > diff --git a/gnu/packages/patches/gcc-retpoline-Use-__x86.indirect_thunk.reg-for-indirect-branch-via.patch b/gnu/packages/patches/gcc-retpoline-Use-__x86.indirect_thunk.reg-for-indirect-branch-via.patch > new file mode 100644 > index 000000000..bd6797816 > --- /dev/null > +++ b/gnu/packages/patches/gcc-retpoline-Use-__x86.indirect_thunk.reg-for-indirect-branch-via.patch > @@ -0,0 +1,623 @@ > +'Retpoline' mitigation technique for Spectre (branch target injection) > +[CVE-2017-5715]: > + > +https://security.googleblog.com/2018/01/more-details-about-mitigations-for-cpu_4.html > +https://support.google.com/faqs/answer/7625886 > +https://spectreattack.com/ > +https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2017-5715 > + > +Patch copied from the 'retpoline-20180107' branch of upstream source repository > +(please add new / update existing patches when new 'retpoline-xxxxxxxx' branch > +appears): > + > +http://git.infradead.org/users/dwmw2/gcc-retpoline.git > + > +From e4e33b44a49eaa102806589ce12f021ab6a1e5f1 Mon Sep 17 00:00:00 2001 > +From: "H.J. Lu" <hjl.tools@gmail.com> > +Date: Wed, 13 Dec 2017 12:59:50 -0800 > +Subject: [PATCH 09/17] Use __x86.indirect_thunk.reg for indirect branch via > + register > + > +--- > + gcc/config/i386/i386.c | 137 +++++++++++++++++---- > + gcc/testsuite/gcc.target/i386/indirect-thunk-1.c | 4 +- > + gcc/testsuite/gcc.target/i386/indirect-thunk-2.c | 4 +- > + gcc/testsuite/gcc.target/i386/indirect-thunk-3.c | 8 +- > + gcc/testsuite/gcc.target/i386/indirect-thunk-4.c | 8 +- > + gcc/testsuite/gcc.target/i386/indirect-thunk-7.c | 4 +- > + .../gcc.target/i386/indirect-thunk-attr-1.c | 4 +- > + .../gcc.target/i386/indirect-thunk-attr-2.c | 4 +- > + .../gcc.target/i386/indirect-thunk-attr-3.c | 2 +- > + .../gcc.target/i386/indirect-thunk-attr-4.c | 2 +- > + .../gcc.target/i386/indirect-thunk-attr-5.c | 8 +- > + .../gcc.target/i386/indirect-thunk-attr-6.c | 8 +- > + .../gcc.target/i386/indirect-thunk-attr-7.c | 2 +- > + .../gcc.target/i386/indirect-thunk-extern-1.c | 4 +- > + .../gcc.target/i386/indirect-thunk-extern-2.c | 4 +- > + .../gcc.target/i386/indirect-thunk-extern-3.c | 8 +- > + .../gcc.target/i386/indirect-thunk-extern-4.c | 8 +- > + .../gcc.target/i386/indirect-thunk-extern-7.c | 4 +- > + .../gcc.target/i386/indirect-thunk-inline-1.c | 2 +- > + .../gcc.target/i386/indirect-thunk-inline-2.c | 2 +- > + .../gcc.target/i386/indirect-thunk-inline-3.c | 2 +- > + .../gcc.target/i386/indirect-thunk-inline-4.c | 2 +- > + .../gcc.target/i386/indirect-thunk-inline-7.c | 2 +- > + 23 files changed, 158 insertions(+), 75 deletions(-) > + > +diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c > +index 5e66af08066..590729b3f87 100644 > +--- a/gcc/config/i386/i386.c > ++++ b/gcc/config/i386/i386.c > +@@ -11948,6 +11948,9 @@ static int indirectlabelno; > + static bool indirect_thunk_needed = false; > + static bool indirect_thunk_bnd_needed = false; > + > ++static int indirect_thunks_used; > ++static int indirect_thunks_bnd_used; > ++ > + #ifndef INDIRECT_LABEL > + # define INDIRECT_LABEL "LIND" > + #endif > +@@ -11955,24 +11958,45 @@ static bool indirect_thunk_bnd_needed = false; > + /* Fills in the label name that should be used for the indirect thunk. */ > + > + static void > +-indirect_thunk_name (char name[32], bool need_bnd_p) > ++indirect_thunk_name (char name[32], int regno, bool need_bnd_p) > + { > + if (USE_HIDDEN_LINKONCE) > + { > + const char *bnd = need_bnd_p ? "_bnd" : ""; > +- sprintf (name, "__x86.indirect_thunk%s", bnd); > ++ if (regno >= 0) > ++ { > ++ const char *reg_prefix; > ++ if (LEGACY_INT_REGNO_P (regno)) > ++ reg_prefix = TARGET_64BIT ? "r" : "e"; > ++ else > ++ reg_prefix = ""; > ++ sprintf (name, "__x86.indirect_thunk%s.%s%s", > ++ bnd, reg_prefix, reg_names[regno]); > ++ } > ++ else > ++ sprintf (name, "__x86.indirect_thunk%s", bnd); > + } > + else > + { > +- if (need_bnd_p) > +- ASM_GENERATE_INTERNAL_LABEL (name, "LITB", 0); > ++ if (regno >= 0) > ++ { > ++ if (need_bnd_p) > ++ ASM_GENERATE_INTERNAL_LABEL (name, "LITBR", regno); > ++ else > ++ ASM_GENERATE_INTERNAL_LABEL (name, "LITR", regno); > ++ } > + else > +- ASM_GENERATE_INTERNAL_LABEL (name, "LIT", 0); > ++ { > ++ if (need_bnd_p) > ++ ASM_GENERATE_INTERNAL_LABEL (name, "LITB", 0); > ++ else > ++ ASM_GENERATE_INTERNAL_LABEL (name, "LIT", 0); > ++ } > + } > + } > + > + static void > +-output_indirect_thunk (bool need_bnd_p) > ++output_indirect_thunk (bool need_bnd_p, int regno) > + { > + char indirectlabel1[32]; > + char indirectlabel2[32]; > +@@ -12002,11 +12026,22 @@ output_indirect_thunk (bool need_bnd_p) > + > + ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, indirectlabel2); > + > +- /* LEA. */ > +- rtx xops[2]; > +- xops[0] = stack_pointer_rtx; > +- xops[1] = plus_constant (Pmode, stack_pointer_rtx, UNITS_PER_WORD); > +- output_asm_insn ("lea\t{%E1, %0|%0, %E1}", xops); > ++ if (regno >= 0) > ++ { > ++ /* MOV. */ > ++ rtx xops[2]; > ++ xops[0] = gen_rtx_MEM (word_mode, stack_pointer_rtx); > ++ xops[1] = gen_rtx_REG (word_mode, regno); > ++ output_asm_insn ("mov\t{%1, %0|%0, %1}", xops); > ++ } > ++ else > ++ { > ++ /* LEA. */ > ++ rtx xops[2]; > ++ xops[0] = stack_pointer_rtx; > ++ xops[1] = plus_constant (Pmode, stack_pointer_rtx, UNITS_PER_WORD); > ++ output_asm_insn ("lea\t{%E1, %0|%0, %E1}", xops); > ++ } > + > + if (need_bnd_p) > + fputs ("\tbnd ret\n", asm_out_file); > +@@ -12015,12 +12050,13 @@ output_indirect_thunk (bool need_bnd_p) > + } > + > + static void > +-output_indirect_thunk_function (bool need_bnd_p) > ++output_indirect_thunk_function (bool need_bnd_p, int regno) > + { > + char name[32]; > + tree decl; > + > +- indirect_thunk_name (name, need_bnd_p); > ++ /* Create __x86.indirect_thunk/__x86.indirect_thunk_bnd. */ > ++ indirect_thunk_name (name, regno, need_bnd_p); > + decl = build_decl (BUILTINS_LOCATION, FUNCTION_DECL, > + get_identifier (name), > + build_function_type_list (void_type_node, NULL_TREE)); > +@@ -12074,7 +12110,7 @@ output_indirect_thunk_function (bool need_bnd_p) > + /* Make sure unwind info is emitted for the thunk if needed. */ > + final_start_function (emit_barrier (), asm_out_file, 1); > + > +- output_indirect_thunk (need_bnd_p); > ++ output_indirect_thunk (need_bnd_p, regno); > + > + final_end_function (); > + init_insn_lengths (); > +@@ -12110,15 +12146,31 @@ ix86_code_end (void) > + int regno; > + > + if (indirect_thunk_needed) > +- output_indirect_thunk_function (false); > ++ output_indirect_thunk_function (false, -1); > + if (indirect_thunk_bnd_needed) > +- output_indirect_thunk_function (true); > ++ output_indirect_thunk_function (true, -1); > ++ > ++ for (regno = FIRST_REX_INT_REG; regno <= LAST_REX_INT_REG; regno++) > ++ { > ++ int i = regno - FIRST_REX_INT_REG + LAST_INT_REG + 1; > ++ if ((indirect_thunks_used & (1 << i))) > ++ output_indirect_thunk_function (false, regno); > ++ > ++ if ((indirect_thunks_bnd_used & (1 << i))) > ++ output_indirect_thunk_function (true, regno); > ++ } > + > + for (regno = AX_REG; regno <= SP_REG; regno++) > + { > + char name[32]; > + tree decl; > + > ++ if ((indirect_thunks_used & (1 << regno))) > ++ output_indirect_thunk_function (false, regno); > ++ > ++ if ((indirect_thunks_bnd_used & (1 << regno))) > ++ output_indirect_thunk_function (true, regno); > ++ > + if (!(pic_labels_used & (1 << regno))) > + continue; > + > +@@ -28639,17 +28691,37 @@ ix86_output_indirect_branch (rtx call_op, const char *xasm, > + char *thunk_name; > + char push_buf[64]; > + bool need_bnd_p = ix86_bnd_prefixed_insn_p (current_output_insn); > ++ int regno; > ++ > ++ if (REG_P (call_op)) > ++ regno = REGNO (call_op); > ++ else > ++ regno = -1; > + > + if (cfun->machine->indirect_branch_type > + != indirect_branch_thunk_inline) > + { > +- bool need_thunk > +- = cfun->machine->indirect_branch_type == indirect_branch_thunk; > +- if (need_bnd_p) > +- indirect_thunk_bnd_needed |= need_thunk; > +- else > +- indirect_thunk_needed |= need_thunk; > +- indirect_thunk_name (thunk_name_buf, need_bnd_p); > ++ if (cfun->machine->indirect_branch_type == indirect_branch_thunk) > ++ { > ++ if (regno >= 0) > ++ { > ++ int i = regno; > ++ if (i >= FIRST_REX_INT_REG) > ++ i -= (FIRST_REX_INT_REG - LAST_INT_REG - 1); > ++ if (need_bnd_p) > ++ indirect_thunks_bnd_used |= 1 << i; > ++ else > ++ indirect_thunks_used |= 1 << i; > ++ } > ++ else > ++ { > ++ if (need_bnd_p) > ++ indirect_thunk_bnd_needed = true; > ++ else > ++ indirect_thunk_needed = true; > ++ } > ++ } > ++ indirect_thunk_name (thunk_name_buf, regno, need_bnd_p); > + thunk_name = thunk_name_buf; > + } > + else > +@@ -28660,7 +28732,8 @@ ix86_output_indirect_branch (rtx call_op, const char *xasm, > + > + if (sibcall_p) > + { > +- output_asm_insn (push_buf, &call_op); > ++ if (regno < 0) > ++ output_asm_insn (push_buf, &call_op); > + if (thunk_name != NULL) > + { > + if (need_bnd_p) > +@@ -28669,10 +28742,19 @@ ix86_output_indirect_branch (rtx call_op, const char *xasm, > + fprintf (asm_out_file, "\tjmp\t%s\n", thunk_name); > + } > + else > +- output_indirect_thunk (need_bnd_p); > ++ output_indirect_thunk (need_bnd_p, regno); > + } > + else > + { > ++ if (regno >= 0 && thunk_name != NULL) > ++ { > ++ if (need_bnd_p) > ++ fprintf (asm_out_file, "\tbnd call\t%s\n", thunk_name); > ++ else > ++ fprintf (asm_out_file, "\tcall\t%s\n", thunk_name); > ++ return; > ++ } > ++ > + char indirectlabel1[32]; > + char indirectlabel2[32]; > + > +@@ -28725,7 +28807,8 @@ ix86_output_indirect_branch (rtx call_op, const char *xasm, > + } > + } > + > +- output_asm_insn (push_buf, &call_op); > ++ if (regno < 0) > ++ output_asm_insn (push_buf, &call_op); > + > + if (thunk_name != NULL) > + { > +@@ -28735,7 +28818,7 @@ ix86_output_indirect_branch (rtx call_op, const char *xasm, > + fprintf (asm_out_file, "\tjmp\t%s\n", thunk_name); > + } > + else > +- output_indirect_thunk (need_bnd_p); > ++ output_indirect_thunk (need_bnd_p, regno); > + > + ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, indirectlabel2); > + > +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-1.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-1.c > +index d8b6f5a06a5..785e593405f 100644 > +--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-1.c > ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-1.c > +@@ -12,8 +12,8 @@ male_indirect_jump (long offset) > + } > + > + /* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { ! x32 } } } } */ > +-/* { dg-final { scan-assembler "pushq\[ \t\]%rax" { target x32 } } } */ > +-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" } } */ > ++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" { target { ! x32 } } } } */ > ++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk\.(r|e)ax" { target x32 } } } */ > + /* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */ > + /* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */ > + /* { dg-final { scan-assembler {\tlfence} } } */ > +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-2.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-2.c > +index f7d5cb315a8..b69075e6483 100644 > +--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-2.c > ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-2.c > +@@ -12,8 +12,8 @@ male_indirect_jump (long offset) > + } > + > + /* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { ! x32 } } } } */ > +-/* { dg-final { scan-assembler "pushq\[ \t\]%rax" { target x32 } } } */ > +-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" } } */ > ++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" { target { ! x32 } } } } */ > ++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk\.(r|e)ax" { target x32 } } } */ > + /* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */ > + /* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */ > + /* { dg-final { scan-assembler {\tlfence} } } */ > +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-3.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-3.c > +index 736d7cda058..df8109baf55 100644 > +--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-3.c > ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-3.c > +@@ -13,8 +13,8 @@ male_indirect_jump (long offset) > + } > + > + /* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { ! x32 } } } } */ > +-/* { dg-final { scan-assembler "pushq\[ \t\]%rax" { target x32 } } } */ > +-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" } } */ > +-/* { dg-final { scan-assembler-times "jmp\[ \t\]*\.LIND" 2 } } */ > +-/* { dg-final { scan-assembler-times "call\[ \t\]*\.LIND" 2 } } */ > ++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" { target { ! x32 } } } } */ > ++/* { dg-final { scan-assembler "call\[ \t\]*__x86.indirect_thunk\.(r|e)ax" { target x32 } } } */ > ++/* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */ > ++/* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */ > + /* { dg-final { scan-assembler {\tlfence} } } */ > +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-4.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-4.c > +index cef9b10513e..8f3b9f4d8a5 100644 > +--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-4.c > ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-4.c > +@@ -13,8 +13,8 @@ male_indirect_jump (long offset) > + } > + > + /* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { ! x32 } } } } */ > +-/* { dg-final { scan-assembler "pushq\[ \t\]%rax" { target x32 } } } */ > +-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" } } */ > +-/* { dg-final { scan-assembler-times "jmp\[ \t\]*\.LIND" 2 } } */ > +-/* { dg-final { scan-assembler-times "call\[ \t\]*\.LIND" 2 } } */ > ++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" { target { ! x32 } } } } */ > ++/* { dg-final { scan-assembler "call\[ \t\]*__x86.indirect_thunk\.(r|e)ax" { target x32 } } } */ > ++/* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */ > ++/* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */ > + /* { dg-final { scan-assembler {\tlfence} } } */ > +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-7.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-7.c > +index ea0fa312f64..f0e1cfe1893 100644 > +--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-7.c > ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-7.c > +@@ -36,8 +36,8 @@ bar (int i) > + } > + > + /* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*\.L\[0-9\]+\\(,%" { target { ! x32 } } } } */ > +-/* { dg-final { scan-assembler "pushq\[ \t\]%rax" { target x32 } } } */ > +-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" } } */ > ++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" { target { ! x32 } } } } */ > ++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk\.(r|e)ax" { target x32 } } } */ > + /* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */ > + /* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */ > + /* { dg-final { scan-assembler {\tlfence} } } */ > +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-1.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-1.c > +index 26550fad4c8..8b88449e625 100644 > +--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-1.c > ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-1.c > +@@ -15,8 +15,8 @@ male_indirect_jump (long offset) > + } > + > + /* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { ! x32 } } } } */ > +-/* { dg-final { scan-assembler "pushq\[ \t\]%rax" { target x32 } } } */ > +-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" } } */ > ++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" { target { ! x32 } } } } */ > ++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk\.(r|e)ax" { target x32 } } } */ > + /* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */ > + /* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */ > + /* { dg-final { scan-assembler {\tlfence} } } */ > +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-2.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-2.c > +index f57bb2a92d6..c69f7bf4f60 100644 > +--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-2.c > ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-2.c > +@@ -13,8 +13,8 @@ male_indirect_jump (long offset) > + } > + > + /* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { ! x32 } } } } */ > +-/* { dg-final { scan-assembler "pushq\[ \t\]%rax" { target x32 } } } */ > +-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" } } */ > ++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" { target { ! x32 } } } } */ > ++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk\.(r|e)ax" { target x32 } } } */ > + /* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */ > + /* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */ > + /* { dg-final { scan-assembler {\tlfence} } } */ > +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-3.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-3.c > +index a3668a6586c..c845099a83e 100644 > +--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-3.c > ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-3.c > +@@ -15,7 +15,7 @@ male_indirect_jump (long offset) > + } > + > + /* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { ! x32 } } } } */ > +-/* { dg-final { scan-assembler "pushq\[ \t\]%rax" { target x32 } } } */ > + /* { dg-final { scan-assembler-times "jmp\[ \t\]*\.LIND" 2 } } */ > + /* { dg-final { scan-assembler-times "call\[ \t\]*\.LIND" 2 } } */ > + /* { dg-final { scan-assembler-not "__x86.indirect_thunk" } } */ > ++/* { dg-final { scan-assembler-not "pushq\[ \t\]%rax" { target x32 } } } */ > +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-4.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-4.c > +index a9c4a137dd4..f636f3422fd 100644 > +--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-4.c > ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-4.c > +@@ -14,7 +14,7 @@ male_indirect_jump (long offset) > + } > + > + /* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { ! x32 } } } } */ > +-/* { dg-final { scan-assembler "pushq\[ \t\]%rax" { target x32 } } } */ > + /* { dg-final { scan-assembler-times "jmp\[ \t\]*\.LIND" 2 } } */ > + /* { dg-final { scan-assembler-times "call\[ \t\]*\.LIND" 2 } } */ > + /* { dg-final { scan-assembler-not "__x86.indirect_thunk" } } */ > ++/* { dg-final { scan-assembler-not "pushq\[ \t\]%rax" { target x32 } } } */ > +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-5.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-5.c > +index 9582e0c5824..5f1d6a78041 100644 > +--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-5.c > ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-5.c > +@@ -15,8 +15,8 @@ male_indirect_jump (long offset) > + } > + > + /* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { ! x32 } } } } */ > +-/* { dg-final { scan-assembler "pushq\[ \t\]%rax" { target x32 } } } */ > +-/* { dg-final { scan-assembler-times "jmp\[ \t\]*\.LIND" 1 } } */ > +-/* { dg-final { scan-assembler-times "call\[ \t\]*\.LIND" 1 } } */ > +-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" } } */ > ++/* { dg-final { scan-assembler-times "jmp\[ \t\]*\.LIND" 1 { target { ! x32 } } } } */ > ++/* { dg-final { scan-assembler-times "call\[ \t\]*\.LIND" 1 { target { ! x32 } } } } */ > ++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" { target { ! x32 } } } } */ > ++/* { dg-final { scan-assembler "call\[ \t\]*__x86.indirect_thunk\.(r|e)ax" { target x32 } } } */ > + /* { dg-final { scan-assembler-not {\t(lfence|pause)} } } */ > +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-6.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-6.c > +index 66442cacfe8..56c92da9812 100644 > +--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-6.c > ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-6.c > +@@ -14,8 +14,8 @@ male_indirect_jump (long offset) > + } > + > + /* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { ! x32 } } } } */ > +-/* { dg-final { scan-assembler "pushq\[ \t\]%rax" { target x32 } } } */ > +-/* { dg-final { scan-assembler-times "jmp\[ \t\]*\.LIND" 1 } } */ > +-/* { dg-final { scan-assembler-times "call\[ \t\]*\.LIND" 1 } } */ > +-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" } } */ > ++/* { dg-final { scan-assembler-times "jmp\[ \t\]*\.LIND" 1 { target { ! x32 } } } } */ > ++/* { dg-final { scan-assembler-times "call\[ \t\]*\.LIND" 1 { target { ! x32 } } } } */ > ++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" { target { ! x32 } } } } */ > ++/* { dg-final { scan-assembler "call\[ \t\]*__x86.indirect_thunk\.(r|e)ax" { target x32 } } } */ > + /* { dg-final { scan-assembler-not {\t(lfence|pause)} } } */ > +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-7.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-7.c > +index 2a19b54cd2e..cfb6f5b234b 100644 > +--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-7.c > ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-7.c > +@@ -37,7 +37,7 @@ bar (int i) > + } > + > + /* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*\.L\[0-9\]+\\(,%" { target { ! x32 } } } } */ > +-/* { dg-final { scan-assembler "pushq\[ \t\]%rax" { target x32 } } } */ > ++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk\.(r|e)ax" { target x32 } } } */ > + /* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" } } */ > + /* { dg-final { scan-assembler-not {\t(lfence|pause)} } } */ > + /* { dg-final { scan-assembler-not "jmp\[ \t\]*\.LIND" } } */ > +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-1.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-1.c > +index 0a1f91be988..f1fa0a11922 100644 > +--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-1.c > ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-1.c > +@@ -12,8 +12,8 @@ male_indirect_jump (long offset) > + } > + > + /* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { ! x32 } } } } */ > +-/* { dg-final { scan-assembler "pushq\[ \t\]%rax" { target x32 } } } */ > +-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" } } */ > ++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" { target { ! x32 } } } } */ > ++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk\.(r|e)ax" { target x32 } } } */ > + /* { dg-final { scan-assembler-not {\t(lfence|pause)} } } */ > + /* { dg-final { scan-assembler-not "jmp\[ \t\]*\.LIND" } } */ > + /* { dg-final { scan-assembler-not "call\[ \t\]*\.LIND" } } */ > +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-2.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-2.c > +index 182520ab3dc..d6e078d594b 100644 > +--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-2.c > ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-2.c > +@@ -12,8 +12,8 @@ male_indirect_jump (long offset) > + } > + > + /* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { ! x32 } } } } */ > +-/* { dg-final { scan-assembler "pushq\[ \t\]%rax" { target x32 } } } */ > +-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" } } */ > ++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" { target { ! x32 } } } } */ > ++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk\.(r|e)ax" { target x32 } } } */ > + /* { dg-final { scan-assembler-not {\t(lfence|pause)} } } */ > + /* { dg-final { scan-assembler-not "jmp\[ \t\]*\.LIND" } } */ > + /* { dg-final { scan-assembler-not "call\[ \t\]*\.LIND" } } */ > +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-3.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-3.c > +index 5c31ddc34fd..3bbe2646955 100644 > +--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-3.c > ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-3.c > +@@ -13,8 +13,8 @@ male_indirect_jump (long offset) > + } > + > + /* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { ! x32 } } } } */ > +-/* { dg-final { scan-assembler "pushq\[ \t\]%rax" { target x32 } } } */ > +-/* { dg-final { scan-assembler-times "jmp\[ \t\]*\.LIND" 1 } } */ > +-/* { dg-final { scan-assembler-times "call\[ \t\]*\.LIND" 1 } } */ > +-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" } } */ > ++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" { target { ! x32 } } } } */ > ++/* { dg-final { scan-assembler-times "jmp\[ \t\]*\.LIND" 1 { target { ! x32 } } } } */ > ++/* { dg-final { scan-assembler-times "call\[ \t\]*\.LIND" 1 { target { ! x32 } } } } */ > ++/* { dg-final { scan-assembler "call\[ \t\]*__x86.indirect_thunk\.(r|e)ax" { target x32 } } } */ > + /* { dg-final { scan-assembler-not {\t(lfence|pause)} } } */ > +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-4.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-4.c > +index f24d0c060f2..596fac599f6 100644 > +--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-4.c > ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-4.c > +@@ -13,8 +13,8 @@ male_indirect_jump (long offset) > + } > + > + /* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { ! x32 } } } } */ > +-/* { dg-final { scan-assembler "pushq\[ \t\]%rax" { target x32 } } } */ > +-/* { dg-final { scan-assembler-times "jmp\[ \t\]*\.LIND" 1 } } */ > +-/* { dg-final { scan-assembler-times "call\[ \t\]*\.LIND" 1 } } */ > +-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" } } */ > ++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" { target { ! x32 } } } } */ > ++/* { dg-final { scan-assembler-times "jmp\[ \t\]*\.LIND" 1 { target { ! x32 } } } } */ > ++/* { dg-final { scan-assembler-times "call\[ \t\]*\.LIND" 1 { target { ! x32 } } } } */ > ++/* { dg-final { scan-assembler "call\[ \t\]*__x86.indirect_thunk\.(r|e)ax" { target x32 } } } */ > + /* { dg-final { scan-assembler-not {\t(lfence|pause)} } } */ > +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-7.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-7.c > +index 8d39fb6f939..ab367951c45 100644 > +--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-7.c > ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-7.c > +@@ -36,8 +36,8 @@ bar (int i) > + } > + > + /* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*\.L\[0-9\]+\\(,%" { target { ! x32 } } } } */ > +-/* { dg-final { scan-assembler "pushq\[ \t\]%rax" { target x32 } } } */ > +-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" } } */ > ++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" { target { ! x32 } } } } */ > ++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk\.(r|e)ax" { target x32 } } } */ > + /* { dg-final { scan-assembler-not {\t(lfence|pause)} } } */ > + /* { dg-final { scan-assembler-not "jmp\[ \t\]*\.LIND" } } */ > + /* { dg-final { scan-assembler-not "call\[ \t\]*\.LIND" } } */ > +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-1.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-1.c > +index 071e6c89ac7..09b8ad7d879 100644 > +--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-1.c > ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-1.c > +@@ -12,7 +12,7 @@ male_indirect_jump (long offset) > + } > + > + /* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { ! x32 } } } } */ > +-/* { dg-final { scan-assembler "pushq\[ \t\]%rax" { target x32 } } } */ > + /* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */ > + /* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */ > + /* { dg-final { scan-assembler-not "__x86.indirect_thunk" } } */ > ++/* { dg-final { scan-assembler-not "pushq\[ \t\]%rax" { target x32 } } } */ > +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-2.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-2.c > +index 804c7ccdba7..1f873758fbe 100644 > +--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-2.c > ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-2.c > +@@ -12,7 +12,7 @@ male_indirect_jump (long offset) > + } > + > + /* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { ! x32 } } } } */ > +-/* { dg-final { scan-assembler "pushq\[ \t\]%rax" { target x32 } } } */ > + /* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */ > + /* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */ > + /* { dg-final { scan-assembler-not "__x86.indirect_thunk" } } */ > ++/* { dg-final { scan-assembler-not "pushq\[ \t\]%rax" { target x32 } } } */ > +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-3.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-3.c > +index 545a981add5..b24af1da963 100644 > +--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-3.c > ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-3.c > +@@ -13,7 +13,7 @@ male_indirect_jump (long offset) > + } > + > + /* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { ! x32 } } } } */ > +-/* { dg-final { scan-assembler "pushq\[ \t\]%rax" { target x32 } } } */ > + /* { dg-final { scan-assembler-times "jmp\[ \t\]*\.LIND" 2 } } */ > + /* { dg-final { scan-assembler-times "call\[ \t\]*\.LIND" 2 } } */ > + /* { dg-final { scan-assembler-not "__x86.indirect_thunk" } } */ > ++/* { dg-final { scan-assembler-not "pushq\[ \t\]%rax" { target x32 } } } */ > +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-4.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-4.c > +index d9ff4722cff..1a86608f727 100644 > +--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-4.c > ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-4.c > +@@ -13,7 +13,7 @@ male_indirect_jump (long offset) > + } > + > + /* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { ! x32 } } } } */ > +-/* { dg-final { scan-assembler "pushq\[ \t\]%rax" { target x32 } } } */ > + /* { dg-final { scan-assembler-times "jmp\[ \t\]*\.LIND" 2 } } */ > + /* { dg-final { scan-assembler-times "call\[ \t\]*\.LIND" 2 } } */ > + /* { dg-final { scan-assembler-not "__x86.indirect_thunk" } } */ > ++/* { dg-final { scan-assembler-not "pushq\[ \t\]%rax" { target x32 } } } */ > +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-7.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-7.c > +index a0ce06b8232..01d45782185 100644 > +--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-7.c > ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-7.c > +@@ -36,7 +36,7 @@ bar (int i) > + } > + > + /* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*\.L\[0-9\]+\\(,%" { target { ! x32 } } } } */ > +-/* { dg-final { scan-assembler "pushq\[ \t\]%rax" { target x32 } } } */ > ++/* { dg-final { scan-assembler-not "pushq\[ \t\]%rax" { target x32 } } } */ > + /* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */ > + /* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */ > + /* { dg-final { scan-assembler-not "__x86.indirect_thunk" } } */ > +-- > +2.15.1 > + > diff --git a/gnu/packages/patches/gcc-retpoline-i386-Add-V-register-operand-modifier.patch b/gnu/packages/patches/gcc-retpoline-i386-Add-V-register-operand-modifier.patch > new file mode 100644 > index 000000000..1996a1dfe > --- /dev/null > +++ b/gnu/packages/patches/gcc-retpoline-i386-Add-V-register-operand-modifier.patch > @@ -0,0 +1,76 @@ > +'Retpoline' mitigation technique for Spectre (branch target injection) > +[CVE-2017-5715]: > + > +https://security.googleblog.com/2018/01/more-details-about-mitigations-for-cpu_4.html > +https://support.google.com/faqs/answer/7625886 > +https://spectreattack.com/ > +https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2017-5715 > + > +Patch copied from the 'retpoline-20180107' branch of upstream source repository > +(please add new / update existing patches when new 'retpoline-xxxxxxxx' branch > +appears): > + > +http://git.infradead.org/users/dwmw2/gcc-retpoline.git > + > +From f83391fb22471a2f1c330e2e78f64630d64f497d Mon Sep 17 00:00:00 2001 > +From: "H.J. Lu" <hjl.tools@gmail.com> > +Date: Tue, 19 Dec 2017 08:28:36 -0800 > +Subject: [PATCH 16/17] i386: Add 'V' register operand modifier > + > +For > + > +void > +bar (void (*func) (void)) > +{ > + asm("call *%V0" : : "r"(func)); > +} > + > +it generates: > + > +bar: > + call *rdi > + ret > +--- > + gcc/config/i386/i386.c | 5 ++++- > + 1 file changed, 4 insertions(+), 1 deletion(-) > + > +diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c > +index 344cafe3dac..6cb0681233a 100644 > +--- a/gcc/config/i386/i386.c > ++++ b/gcc/config/i386/i386.c > +@@ -17886,6 +17886,7 @@ put_condition_code (enum rtx_code code, machine_mode mode, bool reverse, > + If CODE is 'h', pretend the reg is the 'high' byte register. > + If CODE is 'y', print "st(0)" instead of "st", if the reg is stack op. > + If CODE is 'd', duplicate the operand for AVX instruction. > ++ If CODE is 'V', print naked register name without %. > + */ > + > + void > +@@ -17896,7 +17897,7 @@ print_reg (rtx x, int code, FILE *file) > + unsigned int regno; > + bool duplicated; > + > +- if (ASSEMBLER_DIALECT == ASM_ATT) > ++ if (ASSEMBLER_DIALECT == ASM_ATT && code != 'V') > + putc ('%', file); > + > + if (x == pc_rtx) > +@@ -18063,6 +18064,7 @@ print_reg (rtx x, int code, FILE *file) > + & -- print some in-use local-dynamic symbol name. > + H -- print a memory address offset by 8; used for sse high-parts > + Y -- print condition for XOP pcom* instruction. > ++ V -- print naked register name without %. > + + -- print a branch hint as 'cs' or 'ds' prefix > + ; -- print a semicolon (after prefixes due to bug in older gas). > + ~ -- print "i" if TARGET_AVX2, "f" otherwise. > +@@ -18287,6 +18289,7 @@ ix86_print_operand (FILE *file, rtx x, int code) > + case 'X': > + case 'P': > + case 'p': > ++ case 'V': > + break; > + > + case 's': > +-- > +2.15.1 > + > diff --git a/gnu/packages/patches/gcc-retpoline-i386-More-use-reference-of-struct-ix86_frame-to-avoi.patch b/gnu/packages/patches/gcc-retpoline-i386-More-use-reference-of-struct-ix86_frame-to-avoi.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=CVE-2017-5715 > + > +Patch copied from the 'retpoline-20180107' branch of upstream source repository > +(please add new / update existing patches when new 'retpoline-xxxxxxxx' branch > +appears): > + > +http://git.infradead.org/users/dwmw2/gcc-retpoline.git > + > +From d96784e4a7355aaab68dec62f31a97bd10714064 Mon Sep 17 00:00:00 2001 > +From: "H.J. Lu" <hjl.tools@gmail.com> > +Date: Tue, 28 Nov 2017 10:26:35 -0800 > +Subject: [PATCH 03/17] i386: More use reference of struct ix86_frame to avoid > + copy > + > +When there is no need to make a copy of ix86_frame, we can use reference > +of struct ix86_frame to avoid copy. > + > + * config/i386/i386.c (ix86_expand_prologue): Use reference of > + struct ix86_frame. > + (ix86_expand_epilogue): Likewise. > +--- > + gcc/config/i386/i386.c | 6 ++---- > + 1 file changed, 2 insertions(+), 4 deletions(-) > + > +diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c > +index 01ecda7643b..504530a00cf 100644 > +--- a/gcc/config/i386/i386.c > ++++ b/gcc/config/i386/i386.c > +@@ -13656,7 +13656,6 @@ ix86_expand_prologue (void) > + { > + struct machine_function *m = cfun->machine; > + rtx insn, t; > +- struct ix86_frame frame; > + HOST_WIDE_INT allocate; > + bool int_registers_saved; > + bool sse_registers_saved; > +@@ -13680,7 +13679,7 @@ ix86_expand_prologue (void) > + m->fs.sp_valid = true; > + > + ix86_compute_frame_layout (); > +- frame = m->frame; > ++ struct ix86_frame &frame = cfun->machine->frame; > + > + if (!TARGET_64BIT && ix86_function_ms_hook_prologue (current_function_decl)) > + { > +@@ -14343,13 +14342,12 @@ ix86_expand_epilogue (int style) > + { > + struct machine_function *m = cfun->machine; > + struct machine_frame_state frame_state_save = m->fs; > +- struct ix86_frame frame; > + bool restore_regs_via_mov; > + bool using_drap; > + > + ix86_finalize_stack_realign_flags (); > + ix86_compute_frame_layout (); > +- frame = m->frame; > ++ struct ix86_frame &frame = cfun->machine->frame; > + > + m->fs.sp_valid = (!frame_pointer_needed > + || (crtl->sp_is_unchanging > +-- > +2.15.1 > + > diff --git a/gnu/packages/patches/gcc-retpoline-i386-Move-struct-ix86_frame-to-machine_function.patch b/gnu/packages/patches/gcc-retpoline-i386-Move-struct-ix86_frame-to-machine_function.patch > new file mode 100644 > index 000000000..908e3cd83 > --- /dev/null > +++ b/gnu/packages/patches/gcc-retpoline-i386-Move-struct-ix86_frame-to-machine_function.patch > @@ -0,0 +1,249 @@ > +'Retpoline' mitigation technique for Spectre (branch target injection) > +[CVE-2017-5715]: > + > +https://security.googleblog.com/2018/01/more-details-about-mitigations-for-cpu_4.html > +https://support.google.com/faqs/answer/7625886 > +https://spectreattack.com/ > +https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2017-5715 > + > +Patch copied from the 'retpoline-20180107' branch of upstream source repository > +(please add new / update existing patches when new 'retpoline-xxxxxxxx' branch > +appears): > + > +http://git.infradead.org/users/dwmw2/gcc-retpoline.git > + > +From 85743811dfa4eb648edbbb637632ac53182b6e05 Mon Sep 17 00:00:00 2001 > +From: "H.J. Lu" <hjl.tools@gmail.com> > +Date: Mon, 6 Nov 2017 09:11:08 -0800 > +Subject: [PATCH 01/17] i386: Move struct ix86_frame to machine_function > + > +Make ix86_frame available to i386 code generation. > + > + * config/i386/i386.c (ix86_frame): Moved to ... > + * config/i386/i386.h (ix86_frame): Here. > + (machine_function): Add frame. > + * config/i386/i386.c (ix86_compute_frame_layout): Repace the > + frame argument with &cfun->machine->frame. > + (ix86_can_use_return_insn_p): Don't pass &frame to > + ix86_compute_frame_layout. Copy frame from cfun->machine->frame. > + (ix86_can_eliminate): Likewise. > + (ix86_expand_prologue): Likewise. > + (ix86_expand_epilogue): Likewise. > + (ix86_expand_split_stack_prologue): Likewise. > +--- > + gcc/config/i386/i386.c | 68 ++++++++++---------------------------------------- > + gcc/config/i386/i386.h | 53 ++++++++++++++++++++++++++++++++++++++- > + 2 files changed, 65 insertions(+), 56 deletions(-) > + > +diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c > +index dc14d205de7..c23c259c538 100644 > +--- a/gcc/config/i386/i386.c > ++++ b/gcc/config/i386/i386.c > +@@ -2441,53 +2441,6 @@ struct GTY(()) stack_local_entry { > + struct stack_local_entry *next; > + }; > + > +-/* Structure describing stack frame layout. > +- Stack grows downward: > +- > +- [arguments] > +- <- ARG_POINTER > +- saved pc > +- > +- saved static chain if ix86_static_chain_on_stack > +- > +- saved frame pointer if frame_pointer_needed > +- <- HARD_FRAME_POINTER > +- [saved regs] > +- <- regs_save_offset > +- [padding0] > +- > +- [saved SSE regs] > +- <- sse_regs_save_offset > +- [padding1] | > +- | <- FRAME_POINTER > +- [va_arg registers] | > +- | > +- [frame] | > +- | > +- [padding2] | = to_allocate > +- <- STACK_POINTER > +- */ > +-struct ix86_frame > +-{ > +- int nsseregs; > +- int nregs; > +- int va_arg_size; > +- int red_zone_size; > +- int outgoing_arguments_size; > +- > +- /* The offsets relative to ARG_POINTER. */ > +- HOST_WIDE_INT frame_pointer_offset; > +- HOST_WIDE_INT hard_frame_pointer_offset; > +- HOST_WIDE_INT stack_pointer_offset; > +- HOST_WIDE_INT hfp_save_offset; > +- HOST_WIDE_INT reg_save_offset; > +- HOST_WIDE_INT sse_reg_save_offset; > +- > +- /* When save_regs_using_mov is set, emit prologue using > +- move instead of push instructions. */ > +- bool save_regs_using_mov; > +-}; > +- > + /* Which cpu are we scheduling for. */ > + enum attr_cpu ix86_schedule; > + > +@@ -2579,7 +2532,7 @@ static unsigned int ix86_function_arg_boundary (machine_mode, > + const_tree); > + static rtx ix86_static_chain (const_tree, bool); > + static int ix86_function_regparm (const_tree, const_tree); > +-static void ix86_compute_frame_layout (struct ix86_frame *); > ++static void ix86_compute_frame_layout (void); > + static bool ix86_expand_vector_init_one_nonzero (bool, machine_mode, > + rtx, rtx, int); > + static void ix86_add_new_builtins (HOST_WIDE_INT, HOST_WIDE_INT); > +@@ -11892,7 +11845,8 @@ ix86_can_use_return_insn_p (void) > + if (crtl->args.pops_args && crtl->args.size >= 32768) > + return 0; > + > +- ix86_compute_frame_layout (&frame); > ++ ix86_compute_frame_layout (); > ++ frame = cfun->machine->frame; > + return (frame.stack_pointer_offset == UNITS_PER_WORD > + && (frame.nregs + frame.nsseregs) == 0); > + } > +@@ -12378,8 +12332,8 @@ ix86_can_eliminate (const int from, const int to) > + HOST_WIDE_INT > + ix86_initial_elimination_offset (int from, int to) > + { > +- struct ix86_frame frame; > +- ix86_compute_frame_layout (&frame); > ++ ix86_compute_frame_layout (); > ++ struct ix86_frame frame = cfun->machine->frame; > + > + if (from == ARG_POINTER_REGNUM && to == HARD_FRAME_POINTER_REGNUM) > + return frame.hard_frame_pointer_offset; > +@@ -12418,8 +12372,9 @@ ix86_builtin_setjmp_frame_value (void) > + /* Fill structure ix86_frame about frame of currently computed function. */ > + > + static void > +-ix86_compute_frame_layout (struct ix86_frame *frame) > ++ix86_compute_frame_layout (void) > + { > ++ struct ix86_frame *frame = &cfun->machine->frame; > + unsigned HOST_WIDE_INT stack_alignment_needed; > + HOST_WIDE_INT offset; > + unsigned HOST_WIDE_INT preferred_alignment; > +@@ -13726,7 +13681,8 @@ ix86_expand_prologue (void) > + m->fs.sp_offset = INCOMING_FRAME_SP_OFFSET; > + m->fs.sp_valid = true; > + > +- ix86_compute_frame_layout (&frame); > ++ ix86_compute_frame_layout (); > ++ frame = m->frame; > + > + if (!TARGET_64BIT && ix86_function_ms_hook_prologue (current_function_decl)) > + { > +@@ -14394,7 +14350,8 @@ ix86_expand_epilogue (int style) > + bool using_drap; > + > + ix86_finalize_stack_realign_flags (); > +- ix86_compute_frame_layout (&frame); > ++ ix86_compute_frame_layout (); > ++ frame = m->frame; > + > + m->fs.sp_valid = (!frame_pointer_needed > + || (crtl->sp_is_unchanging > +@@ -14904,7 +14861,8 @@ ix86_expand_split_stack_prologue (void) > + gcc_assert (flag_split_stack && reload_completed); > + > + ix86_finalize_stack_realign_flags (); > +- ix86_compute_frame_layout (&frame); > ++ ix86_compute_frame_layout (); > ++ frame = cfun->machine->frame; > + allocate = frame.stack_pointer_offset - INCOMING_FRAME_SP_OFFSET; > + > + /* This is the label we will branch to if we have enough stack > +diff --git a/gcc/config/i386/i386.h b/gcc/config/i386/i386.h > +index 9e5f4d857d9..7d9f9020fb3 100644 > +--- a/gcc/config/i386/i386.h > ++++ b/gcc/config/i386/i386.h > +@@ -2446,9 +2446,56 @@ enum avx_u128_state > + > + #define FASTCALL_PREFIX '@' > + > ++#ifndef USED_FOR_TARGET > ++/* Structure describing stack frame layout. > ++ Stack grows downward: > ++ > ++ [arguments] > ++ <- ARG_POINTER > ++ saved pc > ++ > ++ saved static chain if ix86_static_chain_on_stack > ++ > ++ saved frame pointer if frame_pointer_needed > ++ <- HARD_FRAME_POINTER > ++ [saved regs] > ++ <- regs_save_offset > ++ [padding0] > ++ > ++ [saved SSE regs] > ++ <- sse_regs_save_offset > ++ [padding1] | > ++ | <- FRAME_POINTER > ++ [va_arg registers] | > ++ | > ++ [frame] | > ++ | > ++ [padding2] | = to_allocate > ++ <- STACK_POINTER > ++ */ > ++struct GTY(()) ix86_frame > ++{ > ++ int nsseregs; > ++ int nregs; > ++ int va_arg_size; > ++ int red_zone_size; > ++ int outgoing_arguments_size; > ++ > ++ /* The offsets relative to ARG_POINTER. */ > ++ HOST_WIDE_INT frame_pointer_offset; > ++ HOST_WIDE_INT hard_frame_pointer_offset; > ++ HOST_WIDE_INT stack_pointer_offset; > ++ HOST_WIDE_INT hfp_save_offset; > ++ HOST_WIDE_INT reg_save_offset; > ++ HOST_WIDE_INT sse_reg_save_offset; > ++ > ++ /* When save_regs_using_mov is set, emit prologue using > ++ move instead of push instructions. */ > ++ bool save_regs_using_mov; > ++}; > ++ > + /* Machine specific frame tracking during prologue/epilogue generation. */ > + > +-#ifndef USED_FOR_TARGET > + struct GTY(()) machine_frame_state > + { > + /* This pair tracks the currently active CFA as reg+offset. When reg > +@@ -2507,6 +2554,9 @@ struct GTY(()) machine_function { > + int varargs_fpr_size; > + int optimize_mode_switching[MAX_386_ENTITIES]; > + > ++ /* Cached initial frame layout for the current function. */ > ++ struct ix86_frame frame; > ++ > + /* Number of saved registers USE_FAST_PROLOGUE_EPILOGUE > + has been computed for. */ > + int use_fast_prologue_epilogue_nregs; > +@@ -2589,6 +2639,7 @@ struct GTY(()) machine_function { > + #define ix86_current_function_calls_tls_descriptor \ > + (ix86_tls_descriptor_calls_expanded_in_cfun && df_regs_ever_live_p (SP_REG)) > + #define ix86_static_chain_on_stack (cfun->machine->static_chain_on_stack) > ++#define ix86_red_zone_size (cfun->machine->frame.red_zone_size) > + > + /* Control behavior of x86_file_start. */ > + #define X86_FILE_START_VERSION_DIRECTIVE false > +-- > +2.15.1 > + > diff --git a/gnu/packages/patches/gcc-retpoline-i386-Use-reference-of-struct-ix86_frame-to-avoid-cop.patch b/gnu/packages/patches/gcc-retpoline-i386-Use-reference-of-struct-ix86_frame-to-avoid-cop.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=CVE-2017-5715 > + > +Patch copied from the 'retpoline-20180107' branch of upstream source repository > +(please add new / update existing patches when new 'retpoline-xxxxxxxx' branch > +appears): > + > +http://git.infradead.org/users/dwmw2/gcc-retpoline.git > + > +From 0b1769bdce27304a6a91bec234f47f102a2603d5 Mon Sep 17 00:00:00 2001 > +From: hjl <hjl@138bc75d-0d04-0410-961f-82ee72b054a4> > +Date: Mon, 6 Nov 2017 23:04:15 +0000 > +Subject: [PATCH 02/17] i386: Use reference of struct ix86_frame to avoid copy > + > +When there is no need to make a copy of ix86_frame, we can use reference > +of struct ix86_frame to avoid copy. > + > +Tested on x86-64. > + > + * config/i386/i386.c (ix86_can_use_return_insn_p): Use reference > + of struct ix86_frame. > + (ix86_initial_elimination_offset): Likewise. > + (ix86_expand_split_stack_prologue): Likewise. > + > +git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@254480 138bc75d-0d04-0410-961f-82ee72b054a4 > +--- > + gcc/config/i386/i386.c | 9 +++------ > + 1 file changed, 3 insertions(+), 6 deletions(-) > + > +diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c > +index c23c259c538..01ecda7643b 100644 > +--- a/gcc/config/i386/i386.c > ++++ b/gcc/config/i386/i386.c > +@@ -11832,8 +11832,6 @@ symbolic_reference_mentioned_p (rtx op) > + bool > + ix86_can_use_return_insn_p (void) > + { > +- struct ix86_frame frame; > +- > + /* Don't use `ret' instruction in interrupt handler. */ > + if (! reload_completed > + || frame_pointer_needed > +@@ -11846,7 +11844,7 @@ ix86_can_use_return_insn_p (void) > + return 0; > + > + ix86_compute_frame_layout (); > +- frame = cfun->machine->frame; > ++ struct ix86_frame &frame = cfun->machine->frame; > + return (frame.stack_pointer_offset == UNITS_PER_WORD > + && (frame.nregs + frame.nsseregs) == 0); > + } > +@@ -12333,7 +12331,7 @@ HOST_WIDE_INT > + ix86_initial_elimination_offset (int from, int to) > + { > + ix86_compute_frame_layout (); > +- struct ix86_frame frame = cfun->machine->frame; > ++ struct ix86_frame &frame = cfun->machine->frame; > + > + if (from == ARG_POINTER_REGNUM && to == HARD_FRAME_POINTER_REGNUM) > + return frame.hard_frame_pointer_offset; > +@@ -14849,7 +14847,6 @@ static GTY(()) rtx split_stack_fn_large; > + void > + ix86_expand_split_stack_prologue (void) > + { > +- struct ix86_frame frame; > + HOST_WIDE_INT allocate; > + unsigned HOST_WIDE_INT args_size; > + rtx_code_label *label; > +@@ -14862,7 +14859,7 @@ ix86_expand_split_stack_prologue (void) > + > + ix86_finalize_stack_realign_flags (); > + ix86_compute_frame_layout (); > +- frame = cfun->machine->frame; > ++ struct ix86_frame &frame = cfun->machine->frame; > + allocate = frame.stack_pointer_offset - INCOMING_FRAME_SP_OFFSET; > + > + /* This is the label we will branch to if we have enough stack > +-- > +2.15.1 > +
Send a report that this bug log contains spam.
Debbugs is free software and licensed under the terms of the GNU Public License version 2. The current version can be obtained from https://bugs.debian.org/debbugs-source/.
Copyright © 1999 Darren O. Benham, 1997,2003 nCipher Corporation Ltd, 1994-97 Ian Jackson, 2005-2017 Don Armstrong, and many other contributors.