> -----Original Message-----
> From: Jeff Law [mailto:l...@redhat.com]
> Sent: Friday, August 25, 2017 10:50 PM
> To: Tsimbalist, Igor V <igor.v.tsimbal...@intel.com>; 'gcc-
> patc...@gcc.gnu.org' <gcc-patches@gcc.gnu.org>
> Subject: Re: 0001-Part-1.-Add-generic-part-for-Intel-CET-enabling
> 
> On 08/01/2017 02:56 AM, Tsimbalist, Igor V wrote:
> > Part#1. Add generic part for Intel CET enabling.
> >
> > The spec is available at
> >
> > https://software.intel.com/sites/default/files/managed/4d/2a/control-f
> > low-enforcement-technology-preview.pdf
> >
> > High-level design.
> > ------------------
> >
> > A proposal is to introduce a target independent flag
> > -finstrument-control-flow with a semantic to instrument a code to
> > control validness or integrity of control-flow transfers using jump
> > and call instructions. The main goal is to detect and block a possible
> > malware execution through transfer the execution to unknown target
> > address. Implementation could be either software or target based. Any
> > target platforms can provide their implementation for instrumentation
> > under this option.
> >
> > When the -finstrument-control-flow flag is set each implementation has
> > to check if a support exists for a target platform and report an error
> > if no support is found.
> >
> > The compiler should instrument any control-flow transfer points in a
> > program (ex. call/jmp/ret) as well as any landing pads, which are
> > targets of for control-flow transfers.
> >
> > A new 'notrack' attribute is introduced to provide hand tuning support.
> > The attribute directs the compiler to skip a call to a function and a
> > function's landing pad from instrumentation (tracking). The attribute
> > can be used for function and pointer to function types, otherwise it
> > will be ignored. The attribute is saved in a type and propagated to a
> > GIMPLE call statement and later to a call instruction.
> >
> > Currently all platforms except i386 will report the error and do no
> > instrumentation. i386 will provide the implementation based on a
> > specification published by Intel for a new technology called
> > Control-flow Enforcement Technology (CET).
> >
> >
> > 0001-Part-1.-Add-generic-part-for-Intel-CET-enabling.patch
> >
> >
> > From 403fc8239fb1f690cc378287b4def57dcc9d25bf Mon Sep 17 00:00:00
> 2001
> > From: Igor Tsimbalist <igor.v.tsimbal...@intel.com>
> > Date: Mon, 3 Jul 2017 17:11:58 +0300
> > Subject: [PATCH 1/9] Part#1. Add generic part for Intel CET enabling.
> >
> > The spec is available at
> >
> > https://software.intel.com/sites/default/files/managed/4d/2a/control-f
> > low-enforcement-technology-preview.pdf
> >
> > High-level design.
> > ------------------
> >
> > A proposal is to introduce a target independent flag
> > -finstrument-control-flow with a semantic to instrument a code to
> > control validness or integrity of control-flow transfers using jump
> > and call instructions. The main goal is to detect and block a possible
> > malware execution through transfer the execution to unknown target
> > address. Implementation could be either software or target based. Any
> > target platforms can provide their implementation for instrumentation
> > under this option.
> >
> > When the -finstrument-control-flow flag is set each implementation has
> > to check if a support exists for a target platform and report an error
> > if no support is found.
> >
> > The compiler should instrument any control-flow transfer points in a
> > program (ex. call/jmp/ret) as well as any landing pads, which are
> > targets of for control-flow transfers.
> >
> > A new 'notrack' attribute is introduced to provide hand tuning support.
> > The attribute directs the compiler to skip a call to a function and a
> > function's landing pad from instrumentation (tracking). The attribute
> > can be used for function and pointer to function types, otherwise it
> > will be ignored. The attribute is saved in a type and propagated to a
> > GIMPLE call statement and later to a call instruction.
> >
> > Currently all platforms except i386 will report the error and do no
> > instrumentation. i386 will provide the implementation based on a
> > specification published by Intel for a new technology called
> > Control-flow Enforcement Technology (CET).
> >
> > gcc/c-family/
> >
> >     * c-attribs.c (handle_notrack_attribute): New function.
> >     (c_common_attribute_table): Add 'notrack' handling.
> >
> > gcc/
> >
> >     * cfgexpand.c (expand_call_stmt): Set REG_CALL_NOTRACK.
> >     * combine.c (distribute_notes): Add REG_CALL_NOTRACK handling.
> >     * common.opt: Add finstrument-control-flow flag.
> >     * emit-rtl.c (try_split): Add REG_CALL_NOTRACK handling.
> >     * gimple.c (gimple_build_call_from_tree): Add 'notrack'
> >     propogation.
> >     * gimple.h (gf_mask): Add GF_CALL_WITH_NOTRACK.
> >     (gimple_call_with_notrack_p): function.
> >     (gimple_call_set_with_notrack): Likewise.
> >     * recog.c (peep2_attempt): Add REG_CALL_NOTRACK handling.
> >     * reg-notes.def: Add REG_NOTE (CALL_NOTRACK).
> >     * toplev.c (process_options): Add flag_instrument_control_flow
> >     handling.
> > ---
> >  gcc/c-family/c-attribs.c | 23 +++++++++++++++++++++++
> >  gcc/cfgexpand.c          | 11 +++++++++++
> >  gcc/combine.c            |  1 +
> >  gcc/common.opt           |  5 +++++
> >  gcc/emit-rtl.c           |  1 +
> >  gcc/gimple.c             | 17 +++++++++++++++++
> >  gcc/gimple.h             | 34 ++++++++++++++++++++++++++++++++++
> >  gcc/recog.c              |  1 +
> >  gcc/reg-notes.def        |  7 +++++++
> >  gcc/toplev.c             | 11 +++++++++++
> >  10 files changed, 111 insertions(+)
> > ---
> >  gcc/c-family/c-attribs.c | 23 +++++++++++++++++++++++
> >  gcc/cfgexpand.c          | 11 +++++++++++
> >  gcc/combine.c            |  1 +
> >  gcc/common.opt           |  5 +++++
> >  gcc/emit-rtl.c           |  1 +
> >  gcc/gimple.c             | 17 +++++++++++++++++
> >  gcc/gimple.h             | 34 ++++++++++++++++++++++++++++++++++
> >  gcc/recog.c              |  1 +
> >  gcc/reg-notes.def        |  7 +++++++
> >  gcc/toplev.c             | 11 +++++++++++
> >  10 files changed, 111 insertions(+)
> >
> > diff --git a/gcc/c-family/c-attribs.c b/gcc/c-family/c-attribs.c index
> > 0d9ab2d..4d62f7c 100644
> > --- a/gcc/c-family/c-attribs.c
> > +++ b/gcc/c-family/c-attribs.c
> > diff --git a/gcc/cfgexpand.c b/gcc/cfgexpand.c index c9d8118..ed344c5
> > 100644
> > --- a/gcc/cfgexpand.c
> > +++ b/gcc/cfgexpand.c
> > @@ -2657,12 +2657,23 @@ expand_call_stmt (gcall *stmt)
> >       }
> >      }
> >
> > +  rtx_insn *before_call = get_last_insn ();
> >    lhs = gimple_call_lhs (stmt);
> >    if (lhs)
> >      expand_assignment (lhs, exp, false);
> >    else
> >      expand_expr (exp, const0_rtx, VOIDmode, EXPAND_NORMAL);
> >
> > +  /* Find a generated CALL insn to propagate a 'notrack' attribute.
> > +*/
> > +  rtx_insn *last = get_last_insn ();
> > +  while (!CALL_P (last)
> > +    && (last != before_call))
> > +    last = PREV_INSN (last);
> > +
> > +  if (last != before_call
> > +      && gimple_call_with_notrack_p (stmt))
> > +    add_reg_note (last, REG_CALL_NOTRACK, const0_rtx);
> > +
> >    mark_transaction_restart_calls (stmt);  }
> Just to be sure -- this is only searching through the currently open sequence
> to find the RTL call emitted into the sequence to implement the gimple call
> we're expanding, right?
> 
> ISTM that you don't need to do the search if !gimple_call_with_notrack_p,
> right?  Which would imply this code should look something like
> 
> if (gimple_call_with_notrack_p (stmt))
>   {
>     rtx insn *last = get_last_insn ();
>     while (!CALL_P (last)
>            && last != before_call)
>       last = PREV_INSN (last);
>     add_reg_note (last, REG_CALL_NOTRACK, const0_rtx)
>   }
> 
> Or something close to that?
> 
> 
> I'd be slightly concerned if expansion of an argument resulted in a call.  I'm
> not sure if that can happen anymore, but if it does, then you could end up
> marking the wrong CALL_INSN.
> 
> THe only cases where I think that might be possible would be if we needed
> to emit a libcall or memcpy.  So perhaps you want to verify that last is a 
> call
> *and* that it's an indirect call.
I've rewrote the code as you suggested to check if gimple call is an indirect 
call and is 'noverify_cf' call.

> 
> > diff --git a/gcc/gimple.c b/gcc/gimple.c index 479f90c..2e4ab2d 100644
> > --- a/gcc/gimple.c
> > +++ b/gcc/gimple.c
> > @@ -378,6 +378,23 @@ gimple_build_call_from_tree (tree t)
> >    gimple_set_no_warning (call, TREE_NO_WARNING (t));
> >    gimple_call_set_with_bounds (call, CALL_WITH_BOUNDS_P (t));
> >
> > +  if (fndecl == NULL_TREE)
> > +    {
> > +      /* Find the type of an indirect call.  */
> > +      tree addr = CALL_EXPR_FN (t);
> > +      if (TREE_CODE (addr) != FUNCTION_DECL)
> > +   {
> > +     tree fntype = TREE_TYPE (addr);
> > +     gcc_assert (POINTER_TYPE_P (fntype));
> > +     fntype = TREE_TYPE (fntype);
> > +
> > +     /* Check if its type has the no-track attribute and propagate
> > +        it to the CALL insn.  */
> > +     if (lookup_attribute ("notrack", TYPE_ATTRIBUTES (fntype)))
> > +       gimple_call_set_with_notrack (call, TRUE);
> > +   }
> > +    }
> > +
> >    return call;
> As Richi noted, this deserves a better comment.
> 
> It may even be advisable to build a predicate to test if a given gimple
> statement is an indirect call and use that rather than fndecl == NULL_TREE.
> That would help make this code clearer as well.
I've rewrote the code above according to Richard's suggestion: second parameter 
was introduced
and a proper type is passed to the function to look if it has the required 
attribute.

> Q. Do we need to do anything with ICF (identical code folding) and CFE?
> Given two functions which have the same implementation in gimple, except
> that one has a notrack indirect call and the other has a tracked indirect 
> call,
> what is proper behavior?  I think we'd keep them separate which implies we
> need to make sure the notrack attribute is part of the ICF hashing
> implementation.  It'd probably even be worth building a test for this :-)
Are you talking about a case when such two functions are inlined? Or there is a 
possibility to merge
function bodies if they are identical?

I agree with you that the functions should be kept separate. I haven't looked 
into such optimization
in gcc so I need to learn it.

> >  }
> >
> >
> > +/* Return true if call GS is marked as no-track.  */
> > +
> > +static inline bool
> > +gimple_call_with_notrack_p (const gcall *gs) {
> > +  return (gs->subcode & GF_CALL_WITH_NOTRACK) != 0; }
> > +
> > +static inline bool
> > +gimple_call_with_notrack_p (const gimple *gs) {
> > +  const gcall *gc = GIMPLE_CHECK2<const gcall *> (gs);
> > +  return gimple_call_with_notrack_p (gc); }
> Agree with Richi WRT avoiding gimple * overloads.
Fixed.

Thanks,
Igor

> 
> 
> Jeff

Reply via email to