The following code includes a function that is intended to not be compiled with a stack canary. This is a reduced example from an embedded project, where this function is the function that actually sets the __stack_chk_guard variable. The code is this: #pragma GCC push_options #pragma GCC optimize ("-fno-stack-protector") __attribute__((constructor)) void foo() { asm (""); } #pragma GCC pop_options int main() { return 0; } When compiled without LTO ( gcc -fstack-protector-all -O2 -o main lto-func-attr.c ), it correctly emits a non-stack-protected function foo(): 00000000004004c0 <foo>: 4004c0: c3 ret When compiled with LTO ( gcc -fstack-protector-all -flto -O2 -o main lto-func-attr.c ), it incorrectly emits a stack canary check: 00000000004004a0 <foo>: 4004a0: 48 83 ec 18 sub rsp,0x18 4004a4: 64 48 8b 04 25 28 00 mov rax,QWORD PTR fs:0x28 4004ab: 00 00 4004ad: 48 89 44 24 08 mov QWORD PTR [rsp+0x8],rax 4004b2: 31 c0 xor eax,eax 4004b4: 48 8b 44 24 08 mov rax,QWORD PTR [rsp+0x8] 4004b9: 64 48 33 04 25 28 00 xor rax,QWORD PTR fs:0x28 4004c0: 00 00 4004c2: 75 05 jne 4004c9 <foo+0x29> 4004c4: 48 83 c4 18 add rsp,0x18 4004c8: c3 ret 4004c9: e8 72 ff ff ff call 400440 <__stack_chk_fail@plt> The expected behavior is that even with LTO, no stack canary check is emitted. I am using gcc (GCC) 5.3.1 20160406 (Red Hat 5.3.1-6) running on Fedora 23 x86_64.
This might be fixed already in 6.1.
I can reproduce this on Fedora 24 with GCC 6.1: gcc (GCC) 6.1.1 20160510 (Red Hat 6.1.1-2)
Is there the hope of having at least workaround here?
Hello The problem can be seen on both GCC 6.x and current trunk, where we show following warning message: pr71585.c:2:9: warning: bad option ‘-fno-stack-protector’ to pragma ‘optimize’ [-Wpragmas] #pragma GCC optimize ("-fno-stack-protector") ^~~ pr71585.c:7:1: warning: bad option ‘-fno-stack-protector’ to attribute ‘optimize’ [-Wattributes] { ^ The problem is that '-fstack-protect' is not marked as Optimize option. Following patch fixed that: diff --git a/gcc/common.opt b/gcc/common.opt index 5d90385..a7c5125 100644 --- a/gcc/common.opt +++ b/gcc/common.opt @@ -2221,19 +2221,19 @@ Common RejectNegative Joined Var(common_deferred_options) Defer -fstack-limit-symbol=<name> Trap if the stack goes past symbol <name>. fstack-protector -Common Report Var(flag_stack_protect, 1) Init(-1) +Common Report Var(flag_stack_protect, 1) Init(-1) Optimization Use propolice as a stack protection method. fstack-protector-all -Common Report RejectNegative Var(flag_stack_protect, 2) Init(-1) +Common Report RejectNegative Var(flag_stack_protect, 2) Init(-1) Optimization Use a stack protection method for every function. fstack-protector-strong -Common Report RejectNegative Var(flag_stack_protect, 3) Init(-1) +Common Report RejectNegative Var(flag_stack_protect, 3) Init(-1) Optimization Use a smart stack protection method for certain functions. fstack-protector-explicit -Common Report RejectNegative Var(flag_stack_protect, 4) +Common Report RejectNegative Var(flag_stack_protect, 4) Optimization Use stack protection method only for functions with the stack_protect attribute. The only question is whether we can add the flag to optimize flags? If so, I'll send the patch to mailing list. Btw. I've come to a misleading hint related to the option: PR69265 and accidentally I hit also this: PR71652. Another possible problem I can see is that some i386 target attributes are not handled, for instance: pr71585.c:3:9: error: attribute(target("stack-protector-guard=tls")) is unknown #pragma GCC target ("stack-protector-guard=tls") ^~~ Following hunk is necessary to enable the parsing: diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c index f7944f9..73f2149 100644 --- a/gcc/config/i386/i386.c +++ b/gcc/config/i386/i386.c @@ -6458,6 +6458,7 @@ ix86_valid_target_attribute_inner_p (tree args, char *p_strings[], /* enum options */ IX86_ATTR_ENUM ("fpmath=", OPT_mfpmath_), + IX86_ATTR_ENUM ("stack-protector-guard=", OPT_mstack_protector_guard_), /* string options */ IX86_ATTR_STR ("arch=", IX86_FUNCTION_SPECIFIC_ARCH), I'll write a test-case for that. Martin
> The only question is whether we can add the flag to optimize flags? If so, > I'll send the patch to mailing list. > Btw. I've come to a misleading hint related to the option: PR69265 and > accidentally I hit also this: PR71652. Sorry, the first link should be: PR71651.
Author: marxin Date: Wed Jun 29 12:12:56 2016 New Revision: 237845 URL: https://gcc.gnu.org/viewcvs?rev=237845&root=gcc&view=rev Log: Mark -fstack-protect as optimization flag. PR middle-end/71585 * common.opt (flag_stack_protect): Mark the flag as optimization flag. * ipa-inline-transform.c (inline_call): Remove unnecessary call of build_optimization_node. * gcc.dg/pr71585.c: New test. * gcc.dg/pr71585-2.c: New test. * gcc.dg/pr71585-3.c: New test. Added: trunk/gcc/testsuite/gcc.dg/pr71585-2.c trunk/gcc/testsuite/gcc.dg/pr71585-3.c trunk/gcc/testsuite/gcc.dg/pr71585.c Modified: trunk/gcc/ChangeLog trunk/gcc/common.opt trunk/gcc/ipa-inline-transform.c trunk/gcc/testsuite/ChangeLog
Fixed on trunk.
Hunk in ipa-inline-transform.c has been backported to GCC-6 branch.