Hi, This is now superceded by https://gcc.gnu.org/ml/gcc-patches/2018-01/msg01204.html. Sorry for the noise.
Thanks, Bill > On Jan 12, 2018, at 4:33 PM, Bill Schmidt <wschm...@linux.vnet.ibm.com> wrote: > > Hi, > > This patch adds a new option for the compiler to produce only "safe" indirect > jumps, in the sense that these jumps are deliberately mispredicted to inhibit > speculative execution. For now, this option is undocumented; this may change > at some future date. It is intended eventually for the linker to also honor > this flag when creating PLT stubs, for example. > > In addition to the new option, I've included changes to indirect calls for > the ELFv2 ABI when the option is specified. In place of bctrl, we generate > a seteq followed by a beqctrl-. Using the CR0.eq bit is safe since CR0 is > volatile over the call. > > Future patches will address uses of the bctr instruction, which will require > a virtual condition register, since no assumptions can be made about CR > availability at bctr locations. > > Bootstrapped and tested on powerpc64le-linux-gnu with no regressions. Is this > okay for trunk? > > Thanks, > Bill > > > [gcc] > > 2018-01-12 Bill Schmidt <wschm...@linux.vnet.ibm.com> > > * config/rs6000/rs6000.c (rs6000_opt_vars): Add entry for > safe-indirect-jumps. > * config/rs6000/rs6000.md (*call_indirect_elfv2<mode>): Restrict > to case where -msafe-indirect-jumps is not in effect. > (*call_indirect_elf2<mode>_safe): New define_insn. > (*call_value_indirect_elfv2<mode>): Restrict to case where > -msafe-indirect-jumps is not in effect. > (*call_value_indirect_elfv2<mode>_safe): New define_insn. > * config/rs6000/rs6000.opt (msafe-indirect-jumps): New option. > > [gcc/testsuite] > > 2018-01-12 Bill Schmidt <wschm...@linux.vnet.ibm.com> > > * gcc.target/powerpc/safe-indirect-jump-1.c: New file. > > > Index: gcc/config/rs6000/rs6000.c > =================================================================== > --- gcc/config/rs6000/rs6000.c (revision 256364) > +++ gcc/config/rs6000/rs6000.c (working copy) > @@ -36726,6 +36726,9 @@ static struct rs6000_opt_var const rs6000_opt_vars > { "sched-epilog", > offsetof (struct gcc_options, x_TARGET_SCHED_PROLOG), > offsetof (struct cl_target_option, x_TARGET_SCHED_PROLOG), }, > + { "safe-indirect-jumps", > + offsetof (struct gcc_options, x_rs6000_safe_indirect_jumps), > + offsetof (struct cl_target_option, x_rs6000_safe_indirect_jumps), }, > }; > > /* Inner function to handle attribute((target("..."))) and #pragma GCC target > Index: gcc/config/rs6000/rs6000.md > =================================================================== > --- gcc/config/rs6000/rs6000.md (revision 256364) > +++ gcc/config/rs6000/rs6000.md (working copy) > @@ -11222,11 +11222,22 @@ > (match_operand 1 "" "g,g")) > (set (reg:P TOC_REGNUM) (unspec:P [(match_operand:P 2 "const_int_operand" > "n,n")] UNSPEC_TOCSLOT)) > (clobber (reg:P LR_REGNO))] > - "DEFAULT_ABI == ABI_ELFv2" > + "DEFAULT_ABI == ABI_ELFv2 && !rs6000_safe_indirect_jumps" > "b%T0l\;<ptrload> 2,%2(1)" > [(set_attr "type" "jmpreg") > (set_attr "length" "8")]) > > +;; Variant with deliberate misprediction. > +(define_insn "*call_indirect_elfv2<mode>_safe" > + [(call (mem:SI (match_operand:P 0 "register_operand" "c,*l")) > + (match_operand 1 "" "g,g")) > + (set (reg:P TOC_REGNUM) (unspec:P [(match_operand:P 2 "const_int_operand" > "n,n")] UNSPEC_TOCSLOT)) > + (clobber (reg:P LR_REGNO))] > + "DEFAULT_ABI == ABI_ELFv2 && rs6000_safe_indirect_jumps" > + "seteq\;beq%T0l-\;<ptrload> 2,%2(1)" > + [(set_attr "type" "jmpreg") > + (set_attr "length" "12")]) > + > (define_insn "*call_value_indirect_elfv2<mode>" > [(set (match_operand 0 "" "") > (call (mem:SI (match_operand:P 1 "register_operand" "c,*l")) > @@ -11233,11 +11244,22 @@ > (match_operand 2 "" "g,g"))) > (set (reg:P TOC_REGNUM) (unspec:P [(match_operand:P 3 "const_int_operand" > "n,n")] UNSPEC_TOCSLOT)) > (clobber (reg:P LR_REGNO))] > - "DEFAULT_ABI == ABI_ELFv2" > + "DEFAULT_ABI == ABI_ELFv2 && !rs6000_safe_indirect_jumps" > "b%T1l\;<ptrload> 2,%3(1)" > [(set_attr "type" "jmpreg") > (set_attr "length" "8")]) > > +; Variant with deliberate misprediction. > +(define_insn "*call_value_indirect_elfv2<mode>_safe" > + [(set (match_operand 0 "" "") > + (call (mem:SI (match_operand:P 1 "register_operand" "c,*l")) > + (match_operand 2 "" "g,g"))) > + (set (reg:P TOC_REGNUM) (unspec:P [(match_operand:P 3 "const_int_operand" > "n,n")] UNSPEC_TOCSLOT)) > + (clobber (reg:P LR_REGNO))] > + "DEFAULT_ABI == ABI_ELFv2 && rs6000_safe_indirect_jumps" > + "seteq\;beq%T1l-\;<ptrload> 2,%3(1)" > + [(set_attr "type" "jmpreg") > + (set_attr "length" "12")]) > > ;; Call subroutine returning any type. > (define_expand "untyped_call" > Index: gcc/config/rs6000/rs6000.opt > =================================================================== > --- gcc/config/rs6000/rs6000.opt (revision 256364) > +++ gcc/config/rs6000/rs6000.opt (working copy) > @@ -617,3 +617,8 @@ Use the given offset for addressing the stack-prot > > TargetVariable > long rs6000_stack_protector_guard_offset = 0 > + > +;; -msafe-indirect-jumps adds deliberate misprediction to indirect > +;; branches via the CTR. > +msafe-indirect-jumps > +Target Undocumented Var(rs6000_safe_indirect_jumps) Init(0) Save > Index: gcc/testsuite/gcc.target/powerpc/safe-indirect-jump-1.c > =================================================================== > --- gcc/testsuite/gcc.target/powerpc/safe-indirect-jump-1.c (nonexistent) > +++ gcc/testsuite/gcc.target/powerpc/safe-indirect-jump-1.c (working copy) > @@ -0,0 +1,14 @@ > +/* { dg-do compile { target { powerpc64le-*-* } } } */ > +/* { dg-options "-msafe-indirect-jumps" } */ > + > +/* Test for deliberate misprediction of indirect calls for ELFv2. */ > + > +extern int (*f)(); > + > +int bar () > +{ > + return (*f) (); > +} > + > +/* { dg-final { scan-assembler "seteq" } } */ > +/* { dg-final { scan-assembler "beqctrl-" } } */ >