This is the mail archive of the
gcc-bugs@gcc.gnu.org
mailing list for the GCC project.
target/5755: -mregparm=3 and -fomit-frame-pointer corrupt esp register
- From: mendel at cs dot stanford dot edu
- To: gcc-gnats at gcc dot gnu dot org
- Date: 23 Feb 2002 02:25:54 -0000
- Subject: target/5755: -mregparm=3 and -fomit-frame-pointer corrupt esp register
- Reply-to: mendel at cs dot stanford dot edu
>Number: 5755
>Category: target
>Synopsis: -mregparm=3 and -fomit-frame-pointer corrupt esp register
>Confidential: no
>Severity: serious
>Priority: medium
>Responsible: unassigned
>State: open
>Class: wrong-code
>Submitter-Id: net
>Arrival-Date: Fri Feb 22 18:26:00 PST 2002
>Closed-Date:
>Last-Modified:
>Originator: mendel@cs.stanford.edu
>Release: gcc 3.0.2 and gcc 3.0.3 (and probably other gcc3)
>Organization:
>Environment:
Reading specs from /usr/lib/gcc-lib/i386-pld linux/3.0.2/specs
Configured with: ../configure --prefix=/usr --infodir=/usr/share/info --mandir=/usr/share/man --enable-shared --enable-threads=posix --enable-haifa --enable-languages=c,c++,f77,gcov,java,objc --enable-long-long --enable-namespaces --enable-multilib --with-gnu-as --with-gnu-ld --with-system-zlib --with-slibdir=/lib --without-x i386-pld-linux
Thread model: posix
gcc version 3.0.2
>Description:
This program fails if compiled with -fomit-frame-pointer but
works (possibly by accident) otherwise.
The problems appears to be that functions declared to return structures and declared to pass arguments in registers end up messing up the stack pointer (esp)
when called.
If we look a the code generated by gcc version 3.0.2 for the x86..
* without -fomit-frame-pointer
*
* 0x8048474 <test>: push %ebp
* 0x8048475 <test+1>: mov %esp,%ebp
* 0x8048477 <test+3>: sub $0x18,%esp
* 0x804847a <test+6>: mov %eax,0xfffffffc(%ebp)
* 0x804847d <test+9>: lea 0xfffffff0(%ebp),%eax
* 0x8048480 <test+12>: mov $0x0,%edx
* 0x8048485 <test+17>: call 0x8048454 <A_Function_Returning_A_Structure>
* 0x804848a <test+22>: sub $0x4,%esp <<< why!!!
* 0x804848d <test+25>: mov 0xfffffff4(%ebp),%eax
* 0x8048490 <test+28>: mov %eax,0xfffffff8(%ebp)
* 0x8048493 <test+31>: mov 0xfffffff8(%ebp),%eax
* 0x8048496 <test+34>: leave
* 0x8048497 <test+35>: ret
*
* with -fomit-frame-pointer
*
* 0x8048474 <test>: sub $0x1c,%esp
* 0x8048477 <test+3>: mov %eax,0x14(%esp,1)
* 0x804847b <test+7>: lea 0x8(%esp,1),%eax
* 0x804847f <test+11>: mov $0x0,%edx
* 0x8048484 <test+16>: call 0x8048454 <A_Function_Returning_A_Structure>
* 0x8048489 <test+21>: sub $0x4,%esp <<< very bad!!
* 0x804848c <test+24>: mov 0xc(%esp,1),%eax
* 0x8048490 <test+28>: mov %eax,0x10(%esp,1)
* 0x8048494 <test+32>: mov 0x10(%esp,1),%eax
* 0x8048498 <test+36>: add $0x1c,%esp
* 0x804849b <test+39>: ret
*
typedef struct A_Structure {
unsigned int structure_field_1;
unsigned int structure_field_2;
} A_Structure;
A_Structure a_global_structure;
extern A_Structure A_Function_Returning_A_Structure(int num) __attribute__((regparm(2)));
A_Structure
A_Function_Returning_A_Structure(int num)
{
return a_global_structure;
}
extern int test(int n) __attribute__((regparm(2)));
int
test(int n)
{
unsigned int m = A_Function_Returning_A_Structure(0).structure_field_2;
return m;
}
int
main()
{
unsigned int f;
f = test(0);
printf("It works!! return value = %d\n", f);
return 0;
}
>How-To-Repeat:
Compile bug.c with gcc3 -fomit-frame-pointer and it will
core dump when run.
>Fix:
>Release-Note:
>Audit-Trail:
>Unformatted: