https://gcc.gnu.org/bugzilla/show_bug.cgi?id=68818
Bug ID: 68818
Summary: Issue switching stacks on x86 with -fdefer-pop and
-fomit-frame-pointer
Product: gcc
Version: 5.3.0
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: middle-end
Assignee: unassigned at gcc dot gnu.org
Reporter: mdaniels at qnx dot com
Target Milestone: ---
Created attachment 36975
--> https://gcc.gnu.org/bugzilla/attachment.cgi?id=36975&action=edit
Minimal example to reproduce
If you switch stacks to make a function call and -fdefer-pop is enabled, the
push is happening after before the function call, but the pop gets deferred
until after the stack gets switched back.
If you have frame pointers, this is fine, as the stack pointer will be restored
before returning, but if they are omitted then your stack pointer is incorrect
at the point when you pop the return address off the stack.
I have attached a minimal example.
I am testing with a x86_64 Ubuntu 14.04 host. I see this with 4.9 and 5.3, but
not 4.8. The specific versions I am using:
gcc-4.8 (Ubuntu 4.8.4-2ubuntu1~14.04) 4.8.4
gcc-4.9 (Ubuntu 4.9.3-8ubuntu2~14.04) 4.9.3
gcc-5 (Ubuntu 5.3.0-3ubuntu1~14.04) 5.3.0 20151204
And this is how I am building it:
gcc -m32 -o stk stk.c -fomit-frame-pointer -fdefer-pop
Here is the assembly for 4.8.3 and 5.3.0 for comparison:
0804846d <func>:
804846d: 83 ec 2c sub $0x2c,%esp
8048470: 8b 44 24 30 mov 0x30(%esp),%eax
8048474: 89 64 24 1c mov %esp,0x1c(%esp)
8048478: 89 c4 mov %eax,%esp
804847a: c7 04 24 60 85 04 08 movl $0x8048560,(%esp)
8048481: e8 ba fe ff ff call 8048340 <puts@plt>
8048486: 8b 44 24 1c mov 0x1c(%esp),%eax
804848a: 89 c4 mov %eax,%esp
804848c: 83 c4 2c add $0x2c,%esp
804848f: c3 ret
0804846b <func>:
804846b: 83 ec 1c sub $0x1c,%esp
804846e: 8b 44 24 20 mov 0x20(%esp),%eax
8048472: 89 64 24 0c mov %esp,0xc(%esp)
8048476: 89 c4 mov %eax,%esp
8048478: 83 ec 0c sub $0xc,%esp
804847b: 68 80 85 04 08 push $0x8048580
8048480: e8 bb fe ff ff call 8048340 <puts@plt>
8048485: 8b 44 24 1c mov 0x1c(%esp),%eax
8048489: 89 c4 mov %eax,%esp
804848b: 83 c4 10 add $0x10,%esp
804848e: 83 c4 1c add $0x1c,%esp
8048491: c3 ret