On Wed, Mar 13, 2013 at 10:48 AM, Diego Novillo <dnovi...@google.com> wrote:
>
> On 2013-02-25 14:27 , Caroline Tice wrote:
>
>> Index: libgcc/Makefile.in
>> ===================================================================
>> --- libgcc/Makefile.in    (revision 196266)
>> +++ libgcc/Makefile.in    (working copy)
>> @@ -22,6 +22,7 @@
>>  libgcc_topdir = @libgcc_topdir@
>>  host_subdir = @host_subdir@
>>
>> +gcc_srcdir = $(libgcc_topdir)/gcc
>>  gcc_objdir = $(MULTIBUILDTOP)../../$(host_subdir)/gcc
>>
>>  srcdir = @srcdir@
>> @@ -969,6 +970,16 @@ crtendS$(objext): $(srcdir)/crtstuff.c
>>  # This is a version of crtbegin for -static links.
>>  crtbeginT$(objext): $(srcdir)/crtstuff.c
>>      $(crt_compile) $(CRTSTUFF_T_CFLAGS) -c $< -DCRT_BEGIN -DCRTSTUFFT_O
>> +
>> +# These are used in vtable verification; see comments in source files for
>> +# more details.
>> +vtv_start$(objext): $(gcc_srcdir)/vtv_start.c
>> +    $(crt_compile) $(CRTSTUFF_T_CFLAGS_S) \
>> +      -c $(gcc_srcdir)/vtv_start.c
>> +
>> +vtv_end$(objext): $(gcc_srcdir)/vtv_end.c
>> +    $(crt_compile) $(CRTSTUFF_T_CFLAGS_S) \
>> +      -c $(gcc_srcdir)/vtv_end.c
>>  endif
>
>
> Why not have these two files in libgcc?  I don't think we want to depend on 
> source files in gcc/ from libgcc/
>

I will put them there.

>>
>>
>>  /* IPA Passes */
>>  extern struct simple_ipa_opt_pass pass_ipa_lower_emutls;
>> Index: gcc/tree-vtable-verify.c
>> ===================================================================
>> --- gcc/tree-vtable-verify.c    (revision 0)
>> +++ gcc/tree-vtable-verify.c    (revision 0)
>
> I would like to get rid of this naming convention where we prefix file names 
> with 'tree-'.  Just vtable-verify.c is fine.
>
>> @@ -0,0 +1,724 @@
>> +/*   Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010, 2011
>
> Copyright (C) 2013
>
>>
>> +/* Virtual Table Pointer Security Pass - Detect corruption of vtable 
>> pointers
>> +   before using them for virtual method dispatches.  */
>
>
> Do you have a URL to a paper/presentation for it?

No, I don't at this time.

>
>> +
>> +  To find and reference the set of valid vtable pointers for any given
>> +  virtual class, we create a special global varible for each virtual
>
> s/varible/variable/
>
>>
>> +
>> +  Some implementation details for this pass:
>> +
>> +  To find the all of the virtual calls, we iterate through all the
>
> s/the all/all/
>>
>>
>> +  struct vtable_registration key;
>> +  struct vtable_registration **slot;
>> +
>> +  gcc_assert (node && node->registered);
>> +
>> +  key.vtable_decl = vtable_decl;
>> +  slot = (struct vtable_registration **) htab_find_slot (node->registered,
>> + &key, NO_INSERT);
>
> Unless you need to use this in an old branch, I strongly suggest using the 
> new hash table facilities (hash-table.h).
>

Ok, will do.

>> +
>> +
>> +/* Here are the three two structures into which we insert vtable map nodes.
>
> 'three two'?
>>
>>
>> +  /* Verify that there aren't any qualifiers on the type.  */
>> +  type_quals = TYPE_QUALS (TREE_TYPE (class_type_decl));
>> +  gcc_assert (type_quals == TYPE_UNQUALIFIED);
>> +
>> +  /* Get the mangled name for the unqualified type.  */
>> +  class_name = DECL_ASSEMBLER_NAME (class_type_decl);
>
>
> DECL_ASSEMBLER_NAME has side-effects (it generates one if there isn't one 
> already).  Just to avoid this unwanted side effect, protect it with if 
> (HAS_DECL_ASSEMBLER_NAME_P).  In fact, I think you should abort if the 
> class_type_decl does *not* have one.  So, just adding gcc_assert 
> (HAS_DECL_ASSEMBLER_NAME_P(class_type_decl)) should be sufficient.
>

Will do.

>>
>> +
>> +/* This function attempts to recover the declared class of an object
>> +   that is used in making a virtual call.  We try to get the type from
>> +   the type cast in the gimple assignment statement that extracts the
>> +   vtable pointer from the object (DEF_STMT).  The gimple statment
>
> s/statment/statement/
>>
>> +   usually looks something like this:
>> +
>> +   D.2201_4 = MEM[(struct Event *)this_1(D)]._vptr.Event    */
>> +
>> +static tree
>> +/* extract_object_class_type (gimple def_stmt) */
>
> Remove this?

Yes (I didn't realize I had left the commented out code in the patch;
I'm sorry about that).

>>
>> +extract_object_class_type (tree rhs)
>> +{
>> +  /* tree rhs = NULL_TREE; */
>> +
>> +  /* Try to find and extract the type cast from that stmt.  */
>> +
>> +  /* rhs = gimple_assign_rhs1 (def_stmt); */
>> +  /*
>> +  if (TREE_CODE (rhs) == COMPONENT_REF)
>> +    {
>> +      while (TREE_CODE (rhs) == COMPONENT_REF
>> +             && (TREE_CODE (TREE_OPERAND (rhs, 0)) == COMPONENT_REF))
>> +        rhs = TREE_OPERAND (rhs, 0);
>> +
>> +      if (TREE_CODE (rhs) == COMPONENT_REF
>> +          && TREE_CODE (TREE_OPERAND (rhs, 0)) == MEM_REF
>> +          && TREE_CODE (TREE_TYPE (TREE_OPERAND (rhs, 0)))== RECORD_TYPE)
>> +        rhs = TREE_TYPE (TREE_OPERAND (rhs, 0));
>> +      else
>> +        rhs = NULL_TREE;
>> +    }
>> +  else
>> +    rhs = NULL_TREE;
>> +  */
>
>
> What's this?  Is it needed?  There's some other commented code here that 
> seems out of place.
>

I will remove it.  I didn't mean for it to be in the patch.

>> +
>> +  tree result = NULL_TREE;
>> +
>> +
>> +  if (TREE_CODE (rhs) == COMPONENT_REF)
>> +    {
>> +      tree op0 = TREE_OPERAND (rhs, 0);
>> +      tree op1 = TREE_OPERAND (rhs, 1);
>> +
>> +      if (TREE_CODE (op1) == FIELD_DECL
>> +      && DECL_VIRTUAL_P (op1))
>> +    {
>> +      if (TREE_CODE (op0) == COMPONENT_REF
>> +          && TREE_CODE (TREE_OPERAND (op0, 0)) == MEM_REF
>> +          && TREE_CODE (TREE_TYPE (TREE_OPERAND (op0, 0)))== RECORD_TYPE)
>> +        result = TREE_TYPE (TREE_OPERAND (op0, 0));
>> +      else
>> +        result = TREE_TYPE (op0);
>> +    }
>> +      else if (TREE_CODE (op0) == COMPONENT_REF)
>> +    {
>> +      result = extract_object_class_type (op0);
>> +      if (result == NULL_TREE
>> +          && TREE_CODE (op1) == COMPONENT_REF)
>> +        result = extract_object_class_type (op1);
>> +    }
>> +    }
>
> Indentation seems off here.
>>
>> +
>> +  return result;
>> +}
>> +
>> +bool
>> +vtv_defuse_fn (tree var, gimple def_stmt, void *data)
>> +{
>> +  bool retval = false;
>> +
>> +  return retval;
>> +}
>
>
> Huh?
>

Another piece I meant to remove previously (sorry again).

>>
>> +  for (; !gsi_end_p (gsi_virtual_call); gsi_next (&gsi_virtual_call))
>> +    {
>> +      stmt = gsi_stmt (gsi_virtual_call);
>> +      if (is_vtable_assignment_stmt (stmt))
>> +        {
>> +          tree lhs = gimple_assign_lhs (stmt);
>> +          tree vtbl_var_decl = NULL_TREE;
>> +          struct vtbl_map_node *vtable_map_node;
>> +          tree vtbl_decl = NULL_TREE;
>> +          gimple call_stmt;
>> +          struct gimplify_ctx gctx;
>> +          const char *vtable_name = "<unknown>";
>> +          tree tmp0;
>> +          bool found;
>> +
>> +          gsi_vtbl_assign = gsi_for_stmt (stmt);
>
> Why not use 'gsi_virtual_call'?
>

I really do want to use two separate iterators here.  gsi_virtual_call
iterates linearly through all the statements in the basic block.
gsi_vtbl_assign gets moved around a bit, later down in the code, to
find the exact position for inserting the verification call.

>>
>> +                  if (TREE_CODE (vtbl_decl) == VAR_DECL)
>> +                    vtable_name = IDENTIFIER_POINTER (DECL_NAME 
>> (vtbl_decl));
>> +
>> +                  push_gimplify_context (&gctx);
>
> Not needed.  You are not calling the gimplifier.
>

Ok.

>>
>> +
>> +          if (!next_stmt)
>> +            {
>> +              pop_gimplify_context (NULL);
>
> Likewise.

Ok.

>
>>
>> +          gsi_insert_after (&gsi_vtbl_assign, call_stmt,
>> +                    GSI_NEW_STMT);
>> +
>> +                  pop_gimplify_context (NULL);
>
> Likewise.
>

Ok.
>
> Diego.

Reply via email to