aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCaroline Tice <cmtice@google.com>2012-06-03 18:06:17 +0000
committerCaroline Tice <cmtice@google.com>2012-06-03 18:06:17 +0000
commit596d9ac7ffa2a46b2f759854a9592dfd6099ecc4 (patch)
tree6dd6e89aa2df6589941bc35b192f1ebd8bc13d9f
parent6ee6ee4d1d25a05b6082ea6f3a2f5cd855d0bd5c (diff)
Add initialization priority option to fvtable-verify flag; Add
code to put the initializer function into the .preinit_array, if that option is specified for the flag. git-svn-id: https://gcc.gnu.org/svn/gcc/branches/google/gcc-4_6-mobile@188155 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r--vtable-security/gcc/common.opt13
-rw-r--r--vtable-security/gcc/cp/decl2.c13
-rw-r--r--vtable-security/gcc/flag-types.h6
-rw-r--r--vtable-security/gcc/output.h2
-rw-r--r--vtable-security/gcc/varasm.c13
5 files changed, 41 insertions, 6 deletions
diff --git a/vtable-security/gcc/common.opt b/vtable-security/gcc/common.opt
index b1a43969e98..28d72ccc527 100644
--- a/vtable-security/gcc/common.opt
+++ b/vtable-security/gcc/common.opt
@@ -2253,10 +2253,19 @@ Enum(symbol_visibility) String(hidden) Value(VISIBILITY_HIDDEN)
EnumValue
Enum(symbol_visibility) String(protected) Value(VISIBILITY_PROTECTED)
-fvtable-verify
-Common Report Var(flag_vtable_verify)
+fvtable-verify=
+Common Joined RejectNegative Enum(vtv_priority) Var(flag_vtable_verify) Init(VTV_STANDARD_PRIORITY)
Validate vtable pointers before using them.
+Enum
+Name(vtv_priority) Type(enum vtv_priority) UnknownError(unknown vtable verify initialization priority %qs)
+
+EnumValue
+Enum(vtv_priority) String(std) Value(VTV_STANDARD_PRIORITY)
+
+EnumValue
+Enum(vtv_priority) String(preinit) Value(VTV_PREINIT_PRIORITY)
+
fvpt
Common Report Var(flag_value_profile_transformations) Optimization
Use expression value profiles in optimizations
diff --git a/vtable-security/gcc/cp/decl2.c b/vtable-security/gcc/cp/decl2.c
index b0033204ee6..cf6950025f9 100644
--- a/vtable-security/gcc/cp/decl2.c
+++ b/vtable-security/gcc/cp/decl2.c
@@ -4117,25 +4117,30 @@ cp_write_global_declarations (void)
}
sprintf (temp_name, "%.50s.vtable", cptr);
- for (cptr = temp_name, i = 0;
- (cptr[0] != '\0') && (i < 50);
+ for (cptr = temp_name, i = 0;
+ (cptr[0] != '\0') && (i < 50);
cptr++, i++)
if ((cptr[0] == '/') || (cptr[0] == '-') || (cptr[0] == '+'))
cptr[0] = '_';
push_lang_context (lang_name_c);
- body = start_objects ('I', MAX_RESERVED_INIT_PRIORITY + 1,
+ body = start_objects ('I', MAX_RESERVED_INIT_PRIORITY - 1,
(const char *) temp_name);
vtable_classes_found = vtv_register_class_hierarchy_information (body);
if (vtable_classes_found)
{
- finish_objects ('I', MAX_RESERVED_INIT_PRIORITY + 1, body);
+ finish_objects ('I', MAX_RESERVED_INIT_PRIORITY - 1, body);
current_function_decl = vtable_verify_init_fn;
allocate_struct_function (current_function_decl, false);
TREE_STATIC (current_function_decl) = 1;
TREE_USED (current_function_decl) = 1;
TREE_PUBLIC (current_function_decl) = 1;
DECL_PRESERVE_P (current_function_decl) = 1;
+ if (flag_vtable_verify == VTV_PREINIT_PRIORITY)
+ {
+ DECL_STATIC_CONSTRUCTOR (current_function_decl) = 0;
+ assemble_vtv_preinit_initializer (current_function_decl);
+ }
gimplify_function_tree (current_function_decl);
cgraph_add_new_function (current_function_decl, false);
cgraph_process_new_functions ();
diff --git a/vtable-security/gcc/flag-types.h b/vtable-security/gcc/flag-types.h
index 02a13f40382..740dc3515e5 100644
--- a/vtable-security/gcc/flag-types.h
+++ b/vtable-security/gcc/flag-types.h
@@ -211,4 +211,10 @@ enum opt_info_verbosity_levels {
OPT_INFO_MED = 2,
OPT_INFO_MAX = 3
};
+
+/* flag_vtable_verify initialization levels. */
+enum vtv_priority {
+ VTV_STANDARD_PRIORITY = 1,
+ VTV_PREINIT_PRIORITY = 2
+};
#endif /* ! GCC_FLAG_TYPES_H */
diff --git a/vtable-security/gcc/output.h b/vtable-security/gcc/output.h
index c668d352112..2d8d584c201 100644
--- a/vtable-security/gcc/output.h
+++ b/vtable-security/gcc/output.h
@@ -211,6 +211,8 @@ extern void assemble_end_function (tree, const char *);
initial value (that will be done by the caller). */
extern void assemble_variable (tree, int, int, int);
+extern void assemble_vtv_preinit_initializer (tree);
+
/* Compute the alignment of variable specified by DECL.
DONT_OUTPUT_DATA is from assemble_variable. */
extern void align_variable (tree decl, bool dont_output_data);
diff --git a/vtable-security/gcc/varasm.c b/vtable-security/gcc/varasm.c
index 1aa8731f68a..f94121755d3 100644
--- a/vtable-security/gcc/varasm.c
+++ b/vtable-security/gcc/varasm.c
@@ -2063,6 +2063,19 @@ assemble_variable (tree decl, int top_level ATTRIBUTE_UNUSED,
}
}
+void
+assemble_vtv_preinit_initializer (tree fn_decl)
+{
+ section *sect;
+ unsigned flags = SECTION_WRITE;
+ rtx symbol = XEXP (DECL_RTL (fn_decl), 0);
+
+ flags |= SECTION_NOTYPE;
+ sect = get_section (".preinit_array", flags, fn_decl);
+ switch_to_section (sect);
+ assemble_addr_to_section (symbol, sect);
+}
+
/* Return 1 if type TYPE contains any pointers. */
static int