From 596d9ac7ffa2a46b2f759854a9592dfd6099ecc4 Mon Sep 17 00:00:00 2001 From: Caroline Tice Date: Sun, 3 Jun 2012 18:06:17 +0000 Subject: 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 --- vtable-security/gcc/common.opt | 13 +++++++++++-- vtable-security/gcc/cp/decl2.c | 13 +++++++++---- vtable-security/gcc/flag-types.h | 6 ++++++ vtable-security/gcc/output.h | 2 ++ vtable-security/gcc/varasm.c | 13 +++++++++++++ 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 -- cgit v1.2.3