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/
/* 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?
+
+ 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).
+
+
+/* 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.
+
+/* 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?
+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.
+
+ 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?
+ 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'?
+ 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.
+
+ if (!next_stmt)
+ {
+ pop_gimplify_context (NULL);
Likewise.
+ gsi_insert_after (&gsi_vtbl_assign, call_stmt,
+ GSI_NEW_STMT);
+
+ pop_gimplify_context (NULL);
Likewise.
Diego.