diff mbox

[MPX,2/X] Pointers Checker [8/25] Languages support

Message ID 20131031091116.GD54327@msticlxl57.ims.intel.com
State New
Headers show

Commit Message

Ilya Enkovich Oct. 31, 2013, 9:11 a.m. UTC
Hi,

This patch adds support Pointer Bounds Checker into c-family and LTO front-ends.  The main purpose of changes in front-end is to register all statically initialized objects for checker.  We also need to register such objects created by compiler.

Thanks,
Ilya
--

gcc/

2013-10-29  Ilya Enkovich  <ilya.enkovich@intel.com>

	* c/c-lang.c (LANG_HOOKS_CHKP_SUPPORTED): New.
	* cp/cp-lang.c (LANG_HOOKS_CHKP_SUPPORTED): New.
	* objc/objc-lang.c (LANG_HOOKS_CHKP_SUPPORTED): New.
	* objcp/objcp-lang.c (LANG_HOOKS_CHKP_SUPPORTED): New.
	* lto/lto-lang.c (LANG_HOOKS_CHKP_SUPPORTED): New.
	* c/c-parser.c (c_parser_declaration_or_fndef): Register statically
	initialized decls in Pointer Bounds Checker.
	* cp/decl.c (cp_finish_decl): Likewise.
	* gimplify.c (gimplify_init_constructor): Likewise.

Comments

Joseph Myers Nov. 1, 2013, 10:05 p.m. UTC | #1
On Thu, 31 Oct 2013, Ilya Enkovich wrote:

> This patch adds support Pointer Bounds Checker into c-family and LTO 
> front-ends.  The main purpose of changes in front-end is to register all 
> statically initialized objects for checker.  We also need to register 
> such objects created by compiler.

What happens with statically initialized TLS objects?  It would seem that 
you need something like how the C++ front end handles static constructors 
for C++11 thread-local objects, but I don't see anything obvious for that 
here.
Richard Biener Nov. 4, 2013, 10:47 a.m. UTC | #2
On Thu, Oct 31, 2013 at 10:11 AM, Ilya Enkovich <enkovich.gnu@gmail.com> wrote:
> Hi,
>
> This patch adds support Pointer Bounds Checker into c-family and LTO front-ends.  The main purpose of changes in front-end is to register all statically initialized objects for checker.  We also need to register such objects created by compiler.

You define CHKP as supported in LTO.  That means it has to be supported
for all languages and thus you should drop the langhook.

Richard.

> Thanks,
> Ilya
> --
>
> gcc/
>
> 2013-10-29  Ilya Enkovich  <ilya.enkovich@intel.com>
>
>         * c/c-lang.c (LANG_HOOKS_CHKP_SUPPORTED): New.
>         * cp/cp-lang.c (LANG_HOOKS_CHKP_SUPPORTED): New.
>         * objc/objc-lang.c (LANG_HOOKS_CHKP_SUPPORTED): New.
>         * objcp/objcp-lang.c (LANG_HOOKS_CHKP_SUPPORTED): New.
>         * lto/lto-lang.c (LANG_HOOKS_CHKP_SUPPORTED): New.
>         * c/c-parser.c (c_parser_declaration_or_fndef): Register statically
>         initialized decls in Pointer Bounds Checker.
>         * cp/decl.c (cp_finish_decl): Likewise.
>         * gimplify.c (gimplify_init_constructor): Likewise.
>
>
> diff --git a/gcc/c/c-lang.c b/gcc/c/c-lang.c
> index 614c46d..a32bc6b 100644
> --- a/gcc/c/c-lang.c
> +++ b/gcc/c/c-lang.c
> @@ -43,6 +43,8 @@ enum c_language_kind c_language = clk_c;
>  #define LANG_HOOKS_INIT c_objc_common_init
>  #undef LANG_HOOKS_INIT_TS
>  #define LANG_HOOKS_INIT_TS c_common_init_ts
> +#undef LANG_HOOKS_CHKP_SUPPORTED
> +#define LANG_HOOKS_CHKP_SUPPORTED true
>
>  /* Each front end provides its own lang hook initializer.  */
>  struct lang_hooks lang_hooks = LANG_HOOKS_INITIALIZER;
> diff --git a/gcc/c/c-parser.c b/gcc/c/c-parser.c
> index 9ccae3b..65d83c8 100644
> --- a/gcc/c/c-parser.c
> +++ b/gcc/c/c-parser.c
> @@ -1682,6 +1682,12 @@ c_parser_declaration_or_fndef (c_parser *parser, bool fndef_ok,
>                   maybe_warn_string_init (TREE_TYPE (d), init);
>                   finish_decl (d, init_loc, init.value,
>                                init.original_type, asm_name);
> +
> +                 /* Register all decls with initializers in Pointer
> +                    Bounds Checker to generate required static bounds
> +                    initializers.  */
> +                 if (DECL_INITIAL (d) != error_mark_node)
> +                   chkp_register_var_initializer (d);
>                 }
>             }
>           else
> diff --git a/gcc/cp/cp-lang.c b/gcc/cp/cp-lang.c
> index a7fa8e4..6d138bd 100644
> --- a/gcc/cp/cp-lang.c
> +++ b/gcc/cp/cp-lang.c
> @@ -81,6 +81,8 @@ static tree get_template_argument_pack_elems_folded (const_tree);
>  #define LANG_HOOKS_EH_PERSONALITY cp_eh_personality
>  #undef LANG_HOOKS_EH_RUNTIME_TYPE
>  #define LANG_HOOKS_EH_RUNTIME_TYPE build_eh_type_type
> +#undef LANG_HOOKS_CHKP_SUPPORTED
> +#define LANG_HOOKS_CHKP_SUPPORTED true
>
>  /* Each front end provides its own lang hook initializer.  */
>  struct lang_hooks lang_hooks = LANG_HOOKS_INITIALIZER;
> diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c
> index 1e92f2a..db40e75 100644
> --- a/gcc/cp/decl.c
> +++ b/gcc/cp/decl.c
> @@ -6379,6 +6379,12 @@ cp_finish_decl (tree decl, tree init, bool init_const_expr_p,
>              the class specifier.  */
>           if (!DECL_EXTERNAL (decl))
>             var_definition_p = true;
> +
> +         /* If var has initilizer then we need to register it in
> +            Pointer Bounds Checker to generate static bounds initilizer
> +            if required.  */
> +         if (DECL_INITIAL (decl) && DECL_INITIAL (decl) != error_mark_node)
> +           chkp_register_var_initializer (decl);
>         }
>        /* If the variable has an array type, lay out the type, even if
>          there is no initializer.  It is valid to index through the
> diff --git a/gcc/gimplify.c b/gcc/gimplify.c
> index 4f52c27..503450f 100644
> --- a/gcc/gimplify.c
> +++ b/gcc/gimplify.c
> @@ -4111,6 +4111,11 @@ gimplify_init_constructor (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p,
>
>                 walk_tree (&ctor, force_labels_r, NULL, NULL);
>                 ctor = tree_output_constant_def (ctor);
> +
> +               /* We need to register created constant object to
> +                  initialize bounds for pointers in it.  */
> +               chkp_register_var_initializer (ctor);
> +
>                 if (!useless_type_conversion_p (type, TREE_TYPE (ctor)))
>                   ctor = build1 (VIEW_CONVERT_EXPR, type, ctor);
>                 TREE_OPERAND (*expr_p, 1) = ctor;
> diff --git a/gcc/lto/lto-lang.c b/gcc/lto/lto-lang.c
> index 0fa0fc9..b6073d9 100644
> --- a/gcc/lto/lto-lang.c
> +++ b/gcc/lto/lto-lang.c
> @@ -1278,6 +1278,8 @@ static void lto_init_ts (void)
>
>  #undef LANG_HOOKS_INIT_TS
>  #define LANG_HOOKS_INIT_TS lto_init_ts
> +#undef LANG_HOOKS_CHKP_SUPPORTED
> +#define LANG_HOOKS_CHKP_SUPPORTED true
>
>  struct lang_hooks lang_hooks = LANG_HOOKS_INITIALIZER;
>
> diff --git a/gcc/objc/objc-lang.c b/gcc/objc/objc-lang.c
> index bc0008b..5e7e43b 100644
> --- a/gcc/objc/objc-lang.c
> +++ b/gcc/objc/objc-lang.c
> @@ -49,6 +49,8 @@ enum c_language_kind c_language = clk_objc;
>  #define LANG_HOOKS_GIMPLIFY_EXPR objc_gimplify_expr
>  #undef LANG_HOOKS_INIT_TS
>  #define LANG_HOOKS_INIT_TS objc_common_init_ts
> +#undef LANG_HOOKS_CHKP_SUPPORTED
> +#define LANG_HOOKS_CHKP_SUPPORTED true
>
>  /* Each front end provides its own lang hook initializer.  */
>  struct lang_hooks lang_hooks = LANG_HOOKS_INITIALIZER;
> diff --git a/gcc/objcp/objcp-lang.c b/gcc/objcp/objcp-lang.c
> index f9b126f..0bb80eb 100644
> --- a/gcc/objcp/objcp-lang.c
> +++ b/gcc/objcp/objcp-lang.c
> @@ -46,6 +46,8 @@ static void objcxx_init_ts (void);
>  #define LANG_HOOKS_GIMPLIFY_EXPR objc_gimplify_expr
>  #undef LANG_HOOKS_INIT_TS
>  #define LANG_HOOKS_INIT_TS objcxx_init_ts
> +#undef LANG_HOOKS_CHKP_SUPPORTED
> +#define LANG_HOOKS_CHKP_SUPPORTED true
>
>  /* Each front end provides its own lang hook initializer.  */
>  struct lang_hooks lang_hooks = LANG_HOOKS_INITIALIZER;
Ilya Enkovich Nov. 5, 2013, 12:54 p.m. UTC | #3
2013/11/2 Joseph S. Myers <joseph@codesourcery.com>:
> On Thu, 31 Oct 2013, Ilya Enkovich wrote:
>
>> This patch adds support Pointer Bounds Checker into c-family and LTO
>> front-ends.  The main purpose of changes in front-end is to register all
>> statically initialized objects for checker.  We also need to register
>> such objects created by compiler.
>
> What happens with statically initialized TLS objects?  It would seem that
> you need something like how the C++ front end handles static constructors
> for C++11 thread-local objects, but I don't see anything obvious for that
> here.

This patch takes care of pointers initialized by linker.  TLS objects
are dynamically allocated for each thread and should have some
constructor to perform initialization.  And if there is such
constructors then it should be instrumented by Pointer Bounds Checker.
 Therefore it should not require additional changes in front-end,
right?

The only problem I now see for TLS objects is that in my constructors
initialize bounds for an actual TLS object, not for object in .tdata.
How can I refer to .tdata objects in GIMPLE to get correct bounds
initialization for .tdata section?

Thanks,
Ilya

>
> --
> Joseph S. Myers
> joseph@codesourcery.com
Ilya Enkovich Nov. 5, 2013, 1:02 p.m. UTC | #4
2013/11/4 Richard Biener <richard.guenther@gmail.com>:
> On Thu, Oct 31, 2013 at 10:11 AM, Ilya Enkovich <enkovich.gnu@gmail.com> wrote:
>> Hi,
>>
>> This patch adds support Pointer Bounds Checker into c-family and LTO front-ends.  The main purpose of changes in front-end is to register all statically initialized objects for checker.  We also need to register such objects created by compiler.

LTO is quite specific front-end.  For LTO Pointer Bounds Checker
support macro just means it allows instrumented code as input because
all instrumentation is performed before code is streamed out for LTO.

Ilya

>
> You define CHKP as supported in LTO.  That means it has to be supported
> for all languages and thus you should drop the langhook.
>
> Richard.
>
>> Thanks,
>> Ilya
>> --
>>
>> gcc/
>>
>> 2013-10-29  Ilya Enkovich  <ilya.enkovich@intel.com>
>>
>>         * c/c-lang.c (LANG_HOOKS_CHKP_SUPPORTED): New.
>>         * cp/cp-lang.c (LANG_HOOKS_CHKP_SUPPORTED): New.
>>         * objc/objc-lang.c (LANG_HOOKS_CHKP_SUPPORTED): New.
>>         * objcp/objcp-lang.c (LANG_HOOKS_CHKP_SUPPORTED): New.
>>         * lto/lto-lang.c (LANG_HOOKS_CHKP_SUPPORTED): New.
>>         * c/c-parser.c (c_parser_declaration_or_fndef): Register statically
>>         initialized decls in Pointer Bounds Checker.
>>         * cp/decl.c (cp_finish_decl): Likewise.
>>         * gimplify.c (gimplify_init_constructor): Likewise.
>>
>>
>> diff --git a/gcc/c/c-lang.c b/gcc/c/c-lang.c
>> index 614c46d..a32bc6b 100644
>> --- a/gcc/c/c-lang.c
>> +++ b/gcc/c/c-lang.c
>> @@ -43,6 +43,8 @@ enum c_language_kind c_language = clk_c;
>>  #define LANG_HOOKS_INIT c_objc_common_init
>>  #undef LANG_HOOKS_INIT_TS
>>  #define LANG_HOOKS_INIT_TS c_common_init_ts
>> +#undef LANG_HOOKS_CHKP_SUPPORTED
>> +#define LANG_HOOKS_CHKP_SUPPORTED true
>>
>>  /* Each front end provides its own lang hook initializer.  */
>>  struct lang_hooks lang_hooks = LANG_HOOKS_INITIALIZER;
>> diff --git a/gcc/c/c-parser.c b/gcc/c/c-parser.c
>> index 9ccae3b..65d83c8 100644
>> --- a/gcc/c/c-parser.c
>> +++ b/gcc/c/c-parser.c
>> @@ -1682,6 +1682,12 @@ c_parser_declaration_or_fndef (c_parser *parser, bool fndef_ok,
>>                   maybe_warn_string_init (TREE_TYPE (d), init);
>>                   finish_decl (d, init_loc, init.value,
>>                                init.original_type, asm_name);
>> +
>> +                 /* Register all decls with initializers in Pointer
>> +                    Bounds Checker to generate required static bounds
>> +                    initializers.  */
>> +                 if (DECL_INITIAL (d) != error_mark_node)
>> +                   chkp_register_var_initializer (d);
>>                 }
>>             }
>>           else
>> diff --git a/gcc/cp/cp-lang.c b/gcc/cp/cp-lang.c
>> index a7fa8e4..6d138bd 100644
>> --- a/gcc/cp/cp-lang.c
>> +++ b/gcc/cp/cp-lang.c
>> @@ -81,6 +81,8 @@ static tree get_template_argument_pack_elems_folded (const_tree);
>>  #define LANG_HOOKS_EH_PERSONALITY cp_eh_personality
>>  #undef LANG_HOOKS_EH_RUNTIME_TYPE
>>  #define LANG_HOOKS_EH_RUNTIME_TYPE build_eh_type_type
>> +#undef LANG_HOOKS_CHKP_SUPPORTED
>> +#define LANG_HOOKS_CHKP_SUPPORTED true
>>
>>  /* Each front end provides its own lang hook initializer.  */
>>  struct lang_hooks lang_hooks = LANG_HOOKS_INITIALIZER;
>> diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c
>> index 1e92f2a..db40e75 100644
>> --- a/gcc/cp/decl.c
>> +++ b/gcc/cp/decl.c
>> @@ -6379,6 +6379,12 @@ cp_finish_decl (tree decl, tree init, bool init_const_expr_p,
>>              the class specifier.  */
>>           if (!DECL_EXTERNAL (decl))
>>             var_definition_p = true;
>> +
>> +         /* If var has initilizer then we need to register it in
>> +            Pointer Bounds Checker to generate static bounds initilizer
>> +            if required.  */
>> +         if (DECL_INITIAL (decl) && DECL_INITIAL (decl) != error_mark_node)
>> +           chkp_register_var_initializer (decl);
>>         }
>>        /* If the variable has an array type, lay out the type, even if
>>          there is no initializer.  It is valid to index through the
>> diff --git a/gcc/gimplify.c b/gcc/gimplify.c
>> index 4f52c27..503450f 100644
>> --- a/gcc/gimplify.c
>> +++ b/gcc/gimplify.c
>> @@ -4111,6 +4111,11 @@ gimplify_init_constructor (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p,
>>
>>                 walk_tree (&ctor, force_labels_r, NULL, NULL);
>>                 ctor = tree_output_constant_def (ctor);
>> +
>> +               /* We need to register created constant object to
>> +                  initialize bounds for pointers in it.  */
>> +               chkp_register_var_initializer (ctor);
>> +
>>                 if (!useless_type_conversion_p (type, TREE_TYPE (ctor)))
>>                   ctor = build1 (VIEW_CONVERT_EXPR, type, ctor);
>>                 TREE_OPERAND (*expr_p, 1) = ctor;
>> diff --git a/gcc/lto/lto-lang.c b/gcc/lto/lto-lang.c
>> index 0fa0fc9..b6073d9 100644
>> --- a/gcc/lto/lto-lang.c
>> +++ b/gcc/lto/lto-lang.c
>> @@ -1278,6 +1278,8 @@ static void lto_init_ts (void)
>>
>>  #undef LANG_HOOKS_INIT_TS
>>  #define LANG_HOOKS_INIT_TS lto_init_ts
>> +#undef LANG_HOOKS_CHKP_SUPPORTED
>> +#define LANG_HOOKS_CHKP_SUPPORTED true
>>
>>  struct lang_hooks lang_hooks = LANG_HOOKS_INITIALIZER;
>>
>> diff --git a/gcc/objc/objc-lang.c b/gcc/objc/objc-lang.c
>> index bc0008b..5e7e43b 100644
>> --- a/gcc/objc/objc-lang.c
>> +++ b/gcc/objc/objc-lang.c
>> @@ -49,6 +49,8 @@ enum c_language_kind c_language = clk_objc;
>>  #define LANG_HOOKS_GIMPLIFY_EXPR objc_gimplify_expr
>>  #undef LANG_HOOKS_INIT_TS
>>  #define LANG_HOOKS_INIT_TS objc_common_init_ts
>> +#undef LANG_HOOKS_CHKP_SUPPORTED
>> +#define LANG_HOOKS_CHKP_SUPPORTED true
>>
>>  /* Each front end provides its own lang hook initializer.  */
>>  struct lang_hooks lang_hooks = LANG_HOOKS_INITIALIZER;
>> diff --git a/gcc/objcp/objcp-lang.c b/gcc/objcp/objcp-lang.c
>> index f9b126f..0bb80eb 100644
>> --- a/gcc/objcp/objcp-lang.c
>> +++ b/gcc/objcp/objcp-lang.c
>> @@ -46,6 +46,8 @@ static void objcxx_init_ts (void);
>>  #define LANG_HOOKS_GIMPLIFY_EXPR objc_gimplify_expr
>>  #undef LANG_HOOKS_INIT_TS
>>  #define LANG_HOOKS_INIT_TS objcxx_init_ts
>> +#undef LANG_HOOKS_CHKP_SUPPORTED
>> +#define LANG_HOOKS_CHKP_SUPPORTED true
>>
>>  /* Each front end provides its own lang hook initializer.  */
>>  struct lang_hooks lang_hooks = LANG_HOOKS_INITIALIZER;
Jakub Jelinek Nov. 5, 2013, 1:02 p.m. UTC | #5
On Tue, Nov 05, 2013 at 04:54:38PM +0400, Ilya Enkovich wrote:
> 2013/11/2 Joseph S. Myers <joseph@codesourcery.com>:
> > On Thu, 31 Oct 2013, Ilya Enkovich wrote:
> >
> >> This patch adds support Pointer Bounds Checker into c-family and LTO
> >> front-ends.  The main purpose of changes in front-end is to register all
> >> statically initialized objects for checker.  We also need to register
> >> such objects created by compiler.
> >
> > What happens with statically initialized TLS objects?  It would seem that
> > you need something like how the C++ front end handles static constructors
> > for C++11 thread-local objects, but I don't see anything obvious for that
> > here.
> 
> This patch takes care of pointers initialized by linker.  TLS objects
> are dynamically allocated for each thread and should have some
> constructor to perform initialization.  And if there is such
> constructors then it should be instrumented by Pointer Bounds Checker.
>  Therefore it should not require additional changes in front-end,
> right?
> 
> The only problem I now see for TLS objects is that in my constructors
> initialize bounds for an actual TLS object, not for object in .tdata.
> How can I refer to .tdata objects in GIMPLE to get correct bounds
> initialization for .tdata section?

You can't.  .tdata section is only used as data to copy to the TLS objects
when they are initialized (libc copies the whole .tdata section to the right
spot in the TLS are of each thread, followed by clearing the area
corresponding to .tbss section's size).  TLS objects can have dynamic
constructors (fairly recent change), but they don't have to, if they don't,
they are just initialized by the memcpy from .tdata section.

	Jakub
Richard Biener Nov. 5, 2013, 1:13 p.m. UTC | #6
On Tue, Nov 5, 2013 at 2:02 PM, Ilya Enkovich <enkovich.gnu@gmail.com> wrote:
> 2013/11/4 Richard Biener <richard.guenther@gmail.com>:
>> On Thu, Oct 31, 2013 at 10:11 AM, Ilya Enkovich <enkovich.gnu@gmail.com> wrote:
>>> Hi,
>>>
>>> This patch adds support Pointer Bounds Checker into c-family and LTO front-ends.  The main purpose of changes in front-end is to register all statically initialized objects for checker.  We also need to register such objects created by compiler.
>
> LTO is quite specific front-end.  For LTO Pointer Bounds Checker
> support macro just means it allows instrumented code as input because
> all instrumentation is performed before code is streamed out for LTO.

But your patch doesn't even make use of the langhook...

Richard.

> Ilya
>
>>
>> You define CHKP as supported in LTO.  That means it has to be supported
>> for all languages and thus you should drop the langhook.
>>
>> Richard.
>>
>>> Thanks,
>>> Ilya
>>> --
>>>
>>> gcc/
>>>
>>> 2013-10-29  Ilya Enkovich  <ilya.enkovich@intel.com>
>>>
>>>         * c/c-lang.c (LANG_HOOKS_CHKP_SUPPORTED): New.
>>>         * cp/cp-lang.c (LANG_HOOKS_CHKP_SUPPORTED): New.
>>>         * objc/objc-lang.c (LANG_HOOKS_CHKP_SUPPORTED): New.
>>>         * objcp/objcp-lang.c (LANG_HOOKS_CHKP_SUPPORTED): New.
>>>         * lto/lto-lang.c (LANG_HOOKS_CHKP_SUPPORTED): New.
>>>         * c/c-parser.c (c_parser_declaration_or_fndef): Register statically
>>>         initialized decls in Pointer Bounds Checker.
>>>         * cp/decl.c (cp_finish_decl): Likewise.
>>>         * gimplify.c (gimplify_init_constructor): Likewise.
>>>
>>>
>>> diff --git a/gcc/c/c-lang.c b/gcc/c/c-lang.c
>>> index 614c46d..a32bc6b 100644
>>> --- a/gcc/c/c-lang.c
>>> +++ b/gcc/c/c-lang.c
>>> @@ -43,6 +43,8 @@ enum c_language_kind c_language = clk_c;
>>>  #define LANG_HOOKS_INIT c_objc_common_init
>>>  #undef LANG_HOOKS_INIT_TS
>>>  #define LANG_HOOKS_INIT_TS c_common_init_ts
>>> +#undef LANG_HOOKS_CHKP_SUPPORTED
>>> +#define LANG_HOOKS_CHKP_SUPPORTED true
>>>
>>>  /* Each front end provides its own lang hook initializer.  */
>>>  struct lang_hooks lang_hooks = LANG_HOOKS_INITIALIZER;
>>> diff --git a/gcc/c/c-parser.c b/gcc/c/c-parser.c
>>> index 9ccae3b..65d83c8 100644
>>> --- a/gcc/c/c-parser.c
>>> +++ b/gcc/c/c-parser.c
>>> @@ -1682,6 +1682,12 @@ c_parser_declaration_or_fndef (c_parser *parser, bool fndef_ok,
>>>                   maybe_warn_string_init (TREE_TYPE (d), init);
>>>                   finish_decl (d, init_loc, init.value,
>>>                                init.original_type, asm_name);
>>> +
>>> +                 /* Register all decls with initializers in Pointer
>>> +                    Bounds Checker to generate required static bounds
>>> +                    initializers.  */
>>> +                 if (DECL_INITIAL (d) != error_mark_node)
>>> +                   chkp_register_var_initializer (d);
>>>                 }
>>>             }
>>>           else
>>> diff --git a/gcc/cp/cp-lang.c b/gcc/cp/cp-lang.c
>>> index a7fa8e4..6d138bd 100644
>>> --- a/gcc/cp/cp-lang.c
>>> +++ b/gcc/cp/cp-lang.c
>>> @@ -81,6 +81,8 @@ static tree get_template_argument_pack_elems_folded (const_tree);
>>>  #define LANG_HOOKS_EH_PERSONALITY cp_eh_personality
>>>  #undef LANG_HOOKS_EH_RUNTIME_TYPE
>>>  #define LANG_HOOKS_EH_RUNTIME_TYPE build_eh_type_type
>>> +#undef LANG_HOOKS_CHKP_SUPPORTED
>>> +#define LANG_HOOKS_CHKP_SUPPORTED true
>>>
>>>  /* Each front end provides its own lang hook initializer.  */
>>>  struct lang_hooks lang_hooks = LANG_HOOKS_INITIALIZER;
>>> diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c
>>> index 1e92f2a..db40e75 100644
>>> --- a/gcc/cp/decl.c
>>> +++ b/gcc/cp/decl.c
>>> @@ -6379,6 +6379,12 @@ cp_finish_decl (tree decl, tree init, bool init_const_expr_p,
>>>              the class specifier.  */
>>>           if (!DECL_EXTERNAL (decl))
>>>             var_definition_p = true;
>>> +
>>> +         /* If var has initilizer then we need to register it in
>>> +            Pointer Bounds Checker to generate static bounds initilizer
>>> +            if required.  */
>>> +         if (DECL_INITIAL (decl) && DECL_INITIAL (decl) != error_mark_node)
>>> +           chkp_register_var_initializer (decl);
>>>         }
>>>        /* If the variable has an array type, lay out the type, even if
>>>          there is no initializer.  It is valid to index through the
>>> diff --git a/gcc/gimplify.c b/gcc/gimplify.c
>>> index 4f52c27..503450f 100644
>>> --- a/gcc/gimplify.c
>>> +++ b/gcc/gimplify.c
>>> @@ -4111,6 +4111,11 @@ gimplify_init_constructor (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p,
>>>
>>>                 walk_tree (&ctor, force_labels_r, NULL, NULL);
>>>                 ctor = tree_output_constant_def (ctor);
>>> +
>>> +               /* We need to register created constant object to
>>> +                  initialize bounds for pointers in it.  */
>>> +               chkp_register_var_initializer (ctor);
>>> +
>>>                 if (!useless_type_conversion_p (type, TREE_TYPE (ctor)))
>>>                   ctor = build1 (VIEW_CONVERT_EXPR, type, ctor);
>>>                 TREE_OPERAND (*expr_p, 1) = ctor;
>>> diff --git a/gcc/lto/lto-lang.c b/gcc/lto/lto-lang.c
>>> index 0fa0fc9..b6073d9 100644
>>> --- a/gcc/lto/lto-lang.c
>>> +++ b/gcc/lto/lto-lang.c
>>> @@ -1278,6 +1278,8 @@ static void lto_init_ts (void)
>>>
>>>  #undef LANG_HOOKS_INIT_TS
>>>  #define LANG_HOOKS_INIT_TS lto_init_ts
>>> +#undef LANG_HOOKS_CHKP_SUPPORTED
>>> +#define LANG_HOOKS_CHKP_SUPPORTED true
>>>
>>>  struct lang_hooks lang_hooks = LANG_HOOKS_INITIALIZER;
>>>
>>> diff --git a/gcc/objc/objc-lang.c b/gcc/objc/objc-lang.c
>>> index bc0008b..5e7e43b 100644
>>> --- a/gcc/objc/objc-lang.c
>>> +++ b/gcc/objc/objc-lang.c
>>> @@ -49,6 +49,8 @@ enum c_language_kind c_language = clk_objc;
>>>  #define LANG_HOOKS_GIMPLIFY_EXPR objc_gimplify_expr
>>>  #undef LANG_HOOKS_INIT_TS
>>>  #define LANG_HOOKS_INIT_TS objc_common_init_ts
>>> +#undef LANG_HOOKS_CHKP_SUPPORTED
>>> +#define LANG_HOOKS_CHKP_SUPPORTED true
>>>
>>>  /* Each front end provides its own lang hook initializer.  */
>>>  struct lang_hooks lang_hooks = LANG_HOOKS_INITIALIZER;
>>> diff --git a/gcc/objcp/objcp-lang.c b/gcc/objcp/objcp-lang.c
>>> index f9b126f..0bb80eb 100644
>>> --- a/gcc/objcp/objcp-lang.c
>>> +++ b/gcc/objcp/objcp-lang.c
>>> @@ -46,6 +46,8 @@ static void objcxx_init_ts (void);
>>>  #define LANG_HOOKS_GIMPLIFY_EXPR objc_gimplify_expr
>>>  #undef LANG_HOOKS_INIT_TS
>>>  #define LANG_HOOKS_INIT_TS objcxx_init_ts
>>> +#undef LANG_HOOKS_CHKP_SUPPORTED
>>> +#define LANG_HOOKS_CHKP_SUPPORTED true
>>>
>>>  /* Each front end provides its own lang hook initializer.  */
>>>  struct lang_hooks lang_hooks = LANG_HOOKS_INITIALIZER;
Ilya Enkovich Nov. 5, 2013, 1:13 p.m. UTC | #7
2013/11/5 Jakub Jelinek <jakub@redhat.com>:
> On Tue, Nov 05, 2013 at 04:54:38PM +0400, Ilya Enkovich wrote:
>> 2013/11/2 Joseph S. Myers <joseph@codesourcery.com>:
>> > On Thu, 31 Oct 2013, Ilya Enkovich wrote:
>> >
>> >> This patch adds support Pointer Bounds Checker into c-family and LTO
>> >> front-ends.  The main purpose of changes in front-end is to register all
>> >> statically initialized objects for checker.  We also need to register
>> >> such objects created by compiler.
>> >
>> > What happens with statically initialized TLS objects?  It would seem that
>> > you need something like how the C++ front end handles static constructors
>> > for C++11 thread-local objects, but I don't see anything obvious for that
>> > here.
>>
>> This patch takes care of pointers initialized by linker.  TLS objects
>> are dynamically allocated for each thread and should have some
>> constructor to perform initialization.  And if there is such
>> constructors then it should be instrumented by Pointer Bounds Checker.
>>  Therefore it should not require additional changes in front-end,
>> right?
>>
>> The only problem I now see for TLS objects is that in my constructors
>> initialize bounds for an actual TLS object, not for object in .tdata.
>> How can I refer to .tdata objects in GIMPLE to get correct bounds
>> initialization for .tdata section?
>
> You can't.  .tdata section is only used as data to copy to the TLS objects
> when they are initialized (libc copies the whole .tdata section to the right
> spot in the TLS are of each thread, followed by clearing the area
> corresponding to .tbss section's size).  TLS objects can have dynamic
> constructors (fairly recent change), but they don't have to, if they don't,
> they are just initialized by the memcpy from .tdata section.

It's sad I cannot just initialize bounds in Bounds Tables for .tdata,
memcpy would do all the job for me copying them for each new TLS
instance. The other way is to move all bounds initialization for TLS
objects into separate constructor.  How can I make such constructor?

>
>         Jakub
Jakub Jelinek Nov. 5, 2013, 1:17 p.m. UTC | #8
On Tue, Nov 05, 2013 at 05:13:12PM +0400, Ilya Enkovich wrote:
> It's sad I cannot just initialize bounds in Bounds Tables for .tdata,
> memcpy would do all the job for me copying them for each new TLS

Why do you think so?  glibc will surely use an internal version of
memcpy rather than the global one, so unless glibc is MPX enabled, it would
not do the job.

> instance. The other way is to move all bounds initialization for TLS
> objects into separate constructor.  How can I make such constructor?

Just create a constructor for those, similarly how the C++ FE for __thread
vars with constructors (or OpenMP lowering for #pragma omp threadprivate
vars with constructors) expands them.

	Jakub
Ilya Enkovich Nov. 5, 2013, 1:24 p.m. UTC | #9
2013/11/5 Jakub Jelinek <jakub@redhat.com>:
> On Tue, Nov 05, 2013 at 05:13:12PM +0400, Ilya Enkovich wrote:
>> It's sad I cannot just initialize bounds in Bounds Tables for .tdata,
>> memcpy would do all the job for me copying them for each new TLS
>
> Why do you think so?  glibc will surely use an internal version of
> memcpy rather than the global one, so unless glibc is MPX enabled, it would
> not do the job.
>
>> instance. The other way is to move all bounds initialization for TLS
>> objects into separate constructor.  How can I make such constructor?
>
> Just create a constructor for those, similarly how the C++ FE for __thread
> vars with constructors (or OpenMP lowering for #pragma omp threadprivate
> vars with constructors) expands them.

Will look into it. Thanks!

Ilya
>
>         Jakub
diff mbox

Patch

diff --git a/gcc/c/c-lang.c b/gcc/c/c-lang.c
index 614c46d..a32bc6b 100644
--- a/gcc/c/c-lang.c
+++ b/gcc/c/c-lang.c
@@ -43,6 +43,8 @@  enum c_language_kind c_language = clk_c;
 #define LANG_HOOKS_INIT c_objc_common_init
 #undef LANG_HOOKS_INIT_TS
 #define LANG_HOOKS_INIT_TS c_common_init_ts
+#undef LANG_HOOKS_CHKP_SUPPORTED
+#define LANG_HOOKS_CHKP_SUPPORTED true
 
 /* Each front end provides its own lang hook initializer.  */
 struct lang_hooks lang_hooks = LANG_HOOKS_INITIALIZER;
diff --git a/gcc/c/c-parser.c b/gcc/c/c-parser.c
index 9ccae3b..65d83c8 100644
--- a/gcc/c/c-parser.c
+++ b/gcc/c/c-parser.c
@@ -1682,6 +1682,12 @@  c_parser_declaration_or_fndef (c_parser *parser, bool fndef_ok,
 		  maybe_warn_string_init (TREE_TYPE (d), init);
 		  finish_decl (d, init_loc, init.value,
 		      	       init.original_type, asm_name);
+
+		  /* Register all decls with initializers in Pointer
+		     Bounds Checker to generate required static bounds
+		     initializers.  */
+		  if (DECL_INITIAL (d) != error_mark_node)
+		    chkp_register_var_initializer (d);
 		}
 	    }
 	  else
diff --git a/gcc/cp/cp-lang.c b/gcc/cp/cp-lang.c
index a7fa8e4..6d138bd 100644
--- a/gcc/cp/cp-lang.c
+++ b/gcc/cp/cp-lang.c
@@ -81,6 +81,8 @@  static tree get_template_argument_pack_elems_folded (const_tree);
 #define LANG_HOOKS_EH_PERSONALITY cp_eh_personality
 #undef LANG_HOOKS_EH_RUNTIME_TYPE
 #define LANG_HOOKS_EH_RUNTIME_TYPE build_eh_type_type
+#undef LANG_HOOKS_CHKP_SUPPORTED
+#define LANG_HOOKS_CHKP_SUPPORTED true
 
 /* Each front end provides its own lang hook initializer.  */
 struct lang_hooks lang_hooks = LANG_HOOKS_INITIALIZER;
diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c
index 1e92f2a..db40e75 100644
--- a/gcc/cp/decl.c
+++ b/gcc/cp/decl.c
@@ -6379,6 +6379,12 @@  cp_finish_decl (tree decl, tree init, bool init_const_expr_p,
 	     the class specifier.  */
 	  if (!DECL_EXTERNAL (decl))
 	    var_definition_p = true;
+
+	  /* If var has initilizer then we need to register it in
+	     Pointer Bounds Checker to generate static bounds initilizer
+	     if required.  */
+	  if (DECL_INITIAL (decl) && DECL_INITIAL (decl) != error_mark_node)
+	    chkp_register_var_initializer (decl);
 	}
       /* If the variable has an array type, lay out the type, even if
 	 there is no initializer.  It is valid to index through the
diff --git a/gcc/gimplify.c b/gcc/gimplify.c
index 4f52c27..503450f 100644
--- a/gcc/gimplify.c
+++ b/gcc/gimplify.c
@@ -4111,6 +4111,11 @@  gimplify_init_constructor (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p,
 
 		walk_tree (&ctor, force_labels_r, NULL, NULL);
 		ctor = tree_output_constant_def (ctor);
+
+		/* We need to register created constant object to
+		   initialize bounds for pointers in it.  */
+		chkp_register_var_initializer (ctor);
+
 		if (!useless_type_conversion_p (type, TREE_TYPE (ctor)))
 		  ctor = build1 (VIEW_CONVERT_EXPR, type, ctor);
 		TREE_OPERAND (*expr_p, 1) = ctor;
diff --git a/gcc/lto/lto-lang.c b/gcc/lto/lto-lang.c
index 0fa0fc9..b6073d9 100644
--- a/gcc/lto/lto-lang.c
+++ b/gcc/lto/lto-lang.c
@@ -1278,6 +1278,8 @@  static void lto_init_ts (void)
 
 #undef LANG_HOOKS_INIT_TS
 #define LANG_HOOKS_INIT_TS lto_init_ts
+#undef LANG_HOOKS_CHKP_SUPPORTED
+#define LANG_HOOKS_CHKP_SUPPORTED true
 
 struct lang_hooks lang_hooks = LANG_HOOKS_INITIALIZER;
 
diff --git a/gcc/objc/objc-lang.c b/gcc/objc/objc-lang.c
index bc0008b..5e7e43b 100644
--- a/gcc/objc/objc-lang.c
+++ b/gcc/objc/objc-lang.c
@@ -49,6 +49,8 @@  enum c_language_kind c_language = clk_objc;
 #define LANG_HOOKS_GIMPLIFY_EXPR objc_gimplify_expr
 #undef LANG_HOOKS_INIT_TS
 #define LANG_HOOKS_INIT_TS objc_common_init_ts
+#undef LANG_HOOKS_CHKP_SUPPORTED
+#define LANG_HOOKS_CHKP_SUPPORTED true
 
 /* Each front end provides its own lang hook initializer.  */
 struct lang_hooks lang_hooks = LANG_HOOKS_INITIALIZER;
diff --git a/gcc/objcp/objcp-lang.c b/gcc/objcp/objcp-lang.c
index f9b126f..0bb80eb 100644
--- a/gcc/objcp/objcp-lang.c
+++ b/gcc/objcp/objcp-lang.c
@@ -46,6 +46,8 @@  static void objcxx_init_ts (void);
 #define LANG_HOOKS_GIMPLIFY_EXPR objc_gimplify_expr
 #undef LANG_HOOKS_INIT_TS
 #define LANG_HOOKS_INIT_TS objcxx_init_ts
+#undef LANG_HOOKS_CHKP_SUPPORTED
+#define LANG_HOOKS_CHKP_SUPPORTED true
 
 /* Each front end provides its own lang hook initializer.  */
 struct lang_hooks lang_hooks = LANG_HOOKS_INITIALIZER;