diff mbox

Don't expand targetm.stack_protect_fail if it's NULL_TREE

Message ID c763d912-0806-7007-0381-807c94a9b746@foss.arm.com
State New
Headers show

Commit Message

Jiong Wang Oct. 20, 2016, 3:28 p.m. UTC
The current code suppose targetm.stack_protect_fail always generate something.
But in case one target start to generate NULL_TREE, there will be ICE.  This
patch adds a simple sanity check to only call expand if it's not NULL_TREE.

OK for trunk?

gcc/
2016-10-20  Jiong Wang  <jiong.wang@arm.com>

         * function.c (stack_protect_epilogue): Only expands
         targetm.stack_protect_fail if it's not NULL_TREE.

Comments

Jeff Law Oct. 20, 2016, 6:50 p.m. UTC | #1
On 10/20/2016 09:28 AM, Jiong Wang wrote:
> The current code suppose targetm.stack_protect_fail always generate

> something.

> But in case one target start to generate NULL_TREE, there will be ICE.

> This

> patch adds a simple sanity check to only call expand if it's not NULL_TREE.

>

> OK for trunk?

>

> gcc/

> 2016-10-20  Jiong Wang  <jiong.wang@arm.com>

>

>         * function.c (stack_protect_epilogue): Only expands

>         targetm.stack_protect_fail if it's not NULL_TREE.

Is there some reason we don't want to issue an error here and stop 
compilation?  I'm not at all comfortable silently ignoring failure to 
generate stack protector code.

jeff
Jiong Wang Oct. 20, 2016, 7:46 p.m. UTC | #2
2016-10-20 19:50 GMT+01:00 Jeff Law <law@redhat.com>:
>

> On 10/20/2016 09:28 AM, Jiong Wang wrote:

>>

>> The current code suppose targetm.stack_protect_fail always generate

>> something.

>> But in case one target start to generate NULL_TREE, there will be ICE.

>> This

>> patch adds a simple sanity check to only call expand if it's not NULL_TREE.

>>

>> OK for trunk?

>>

>> gcc/

>> 2016-10-20  Jiong Wang  <jiong.wang@arm.com>

>>

>>         * function.c (stack_protect_epilogue): Only expands

>>         targetm.stack_protect_fail if it's not NULL_TREE.

>

> Is there some reason we don't want to issue an error here and stop compilation?  I'm not at all comfortable silently ignoring failure to generate stack protector code.

>

> jeff



Hi Jeff,

  That's because I am doing some work where I will borrow
stack-protector's analysis infrastructure but for those
stack-protector standard rtl insn, they just need to be expanded into
empty, for example stack_protect_set/test just need to be expanded
into NOTE_INSN_DELETED.   The same for targetm.stack_protect_fail ()
which I want to simply return NULL_TREE.  but it's not an error.

  This do seems affect other targets (x86, rs6000) if NULL_TREE should
never be returned for them.  Currently I can see all of them use the
either default_external_stack_protect_fail or
default_hidden_stack_protect_fail, both of which are "return
build_call_expr (..", so I should also assert the the return value of
build_call_expr?

  Thanks.
Jeff Law Oct. 24, 2016, 3:22 p.m. UTC | #3
On 10/20/2016 01:46 PM, Jiong Wang wrote:
> 2016-10-20 19:50 GMT+01:00 Jeff Law <law@redhat.com>:

>>

>> On 10/20/2016 09:28 AM, Jiong Wang wrote:

>>>

>>> The current code suppose targetm.stack_protect_fail always generate

>>> something.

>>> But in case one target start to generate NULL_TREE, there will be ICE.

>>> This

>>> patch adds a simple sanity check to only call expand if it's not NULL_TREE.

>>>

>>> OK for trunk?

>>>

>>> gcc/

>>> 2016-10-20  Jiong Wang  <jiong.wang@arm.com>

>>>

>>>         * function.c (stack_protect_epilogue): Only expands

>>>         targetm.stack_protect_fail if it's not NULL_TREE.

>>

>> Is there some reason we don't want to issue an error here and stop compilation?  I'm not at all comfortable silently ignoring failure to generate stack protector code.

>>

>> jeff

>

>

> Hi Jeff,

>

>   That's because I am doing some work where I will borrow

> stack-protector's analysis infrastructure but for those

> stack-protector standard rtl insn, they just need to be expanded into

> empty, for example stack_protect_set/test just need to be expanded

> into NOTE_INSN_DELETED.   The same for targetm.stack_protect_fail ()

> which I want to simply return NULL_TREE.  but it's not an error.

Right.  But your change could mask backend problems.  Specifically if 
their expander for stack_protect_fail did fail and returned NULL_TREE.

That would cause it to silently ignore stack protector failures, which 
seems inadvisable.

Is there another way you can re-use the analysis code without resorting 
to something like this?


>

>   This do seems affect other targets (x86, rs6000) if NULL_TREE should

> never be returned for them.  Currently I can see all of them use the

> either default_external_stack_protect_fail or

> default_hidden_stack_protect_fail, both of which are "return

> build_call_expr (..", so I should also assert the the return value of

> build_call_expr?

Asserting couldn't hurt.  I'd much rather have the compiler issue an 
error, ICE or somesuch than silently not generate a call to the stack 
protector fail routine.

jeff
Jiong Wang Oct. 24, 2016, 4:29 p.m. UTC | #4
On 24/10/16 16:22, Jeff Law wrote:
> On 10/20/2016 01:46 PM, Jiong Wang wrote:

>> 2016-10-20 19:50 GMT+01:00 Jeff Law <law@redhat.com>:

>>>

>>> On 10/20/2016 09:28 AM, Jiong Wang wrote:

>>>>

>>>> The current code suppose targetm.stack_protect_fail always generate

>>>> something.

>>>> But in case one target start to generate NULL_TREE, there will be ICE.

>>>> This

>>>> patch adds a simple sanity check to only call expand if it's not 

>>>> NULL_TREE.

>>>>

>>>> OK for trunk?

>>>>

>>>> gcc/

>>>> 2016-10-20  Jiong Wang  <jiong.wang@arm.com>

>>>>

>>>>         * function.c (stack_protect_epilogue): Only expands

>>>>         targetm.stack_protect_fail if it's not NULL_TREE.

>>>

>>> Is there some reason we don't want to issue an error here and stop 

>>> compilation?  I'm not at all comfortable silently ignoring failure 

>>> to generate stack protector code.

>>>

>>> jeff

>>

>>

>> Hi Jeff,

>>

>>   That's because I am doing some work where I will borrow

>> stack-protector's analysis infrastructure but for those

>> stack-protector standard rtl insn, they just need to be expanded into

>> empty, for example stack_protect_set/test just need to be expanded

>> into NOTE_INSN_DELETED.   The same for targetm.stack_protect_fail ()

>> which I want to simply return NULL_TREE.  but it's not an error.

> Right.  But your change could mask backend problems.  Specifically if 

> their expander for stack_protect_fail did fail and returned NULL_TREE.

>

> That would cause it to silently ignore stack protector failures, which 

> seems inadvisable.

>

> Is there another way you can re-use the analysis code without 

> resorting to something like this?


In my case, I only want the canary variable which is 
"crtl->stack_protect_guard", then I don't want the current runtime 
support which GCC will always generate once crl->stack_protect_guard is 
initialized.

I was thinking to let stack_protect_fail to generate a tree that 
expand_call will expand into NULL_RTX unconditionally under any 
optimization level, but it seems impossible.  Really appreicate for any 
idea on this.

>

>

>>

>>   This do seems affect other targets (x86, rs6000) if NULL_TREE should

>> never be returned for them.  Currently I can see all of them use the

>> either default_external_stack_protect_fail or

>> default_hidden_stack_protect_fail, both of which are "return

>> build_call_expr (..", so I should also assert the the return value of

>> build_call_expr?

> Asserting couldn't hurt.  I'd much rather have the compiler issue an 

> error, ICE or somesuch than silently not generate a call to the stack 

> protector fail routine.
Jeff Law Nov. 23, 2016, 9:40 p.m. UTC | #5
On 10/24/2016 10:29 AM, Jiong Wang wrote:
> Right.  But your change could mask backend problems.  Specifically if

>> their expander for stack_protect_fail did fail and returned NULL_TREE.

>>

>> That would cause it to silently ignore stack protector failures, which

>> seems inadvisable.

>>

>> Is there another way you can re-use the analysis code without

>> resorting to something like this?

>

> In my case, I only want the canary variable which is

> "crtl->stack_protect_guard", then I don't want the current runtime

> support which GCC will always generate once crl->stack_protect_guard is

> initialized.

Presumably you're using this with the new AArch64 security features. 
ISTM we ought to be able to separate access to the guard from the rest 
of the runtime bits.

Jeff
diff mbox

Patch

diff --git a/gcc/function.c b/gcc/function.c
index cdd2721cdf904be6457d090fe20345d3dee0b4dd..304c32ed2b1ace06139786680f30502d8483a8ed 100644
--- a/gcc/function.c
+++ b/gcc/function.c
@@ -5077,7 +5077,9 @@  stack_protect_epilogue (void)
   if (JUMP_P (tmp))
     predict_insn_def (tmp, PRED_NORETURN, TAKEN);
 
-  expand_call (targetm.stack_protect_fail (), NULL_RTX, /*ignore=*/true);
+  tree fail_check = targetm.stack_protect_fail ();
+  if (fail_check != NULL_TREE)
+    expand_call (fail_check, NULL_RTX, /*ignore=*/true);
   free_temp_slots ();
   emit_label (label);
 }