This is the mail archive of the gcc-bugs@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

target/5755: -mregparm=3 and -fomit-frame-pointer corrupt esp register



>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:


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]