I am using the GCC 4.1.1 ARM build for Cygwin from GNUARM.
$ arm-elf-gcc -v
Using built-in specs.
Target: arm-elf
Configured with: ../gcc-4.1.1/configure --target=arm-elf
--prefix=/g/gnuarm-4.1.1 --enable-interwork --enable-multilib --with-float=soft
--with-newlib --with-headers=../newlib-1.14.0/newlib/libc/include
--enable-languages=c,c++
Thread model: single
gcc version 4.1.1

In a certain situation, the compiler generates incorrect code for a function
which results in the stack pointer being restored to the wrong value on return
from the function, and the stack then becomes corrupted. The following code
demonstrates the bug:

void dummy_func() {
}

int test_func(void *p) {
        dummy_func();
        register int r;
        register void *h;
        if (p == 0) {
                return 0;
        }
        //r = (int)h;
        return r;
}

Save it as register_bug.c, and compile with:
$ arm-elf-gcc -mthumb -mtpcs-frame -S  -mcpu=arm7tdmi -fno-builtin
-fno-exceptions -mlittle-endian -fomit-frame-pointer   -o register_bug_nor.s
register_bug.c
Uncomment the commented-out line, and compile again:
$ arm-elf-gcc -mthumb -mtpcs-frame -S  -mcpu=arm7tdmi -fno-builtin
-fno-exceptions -mlittle-endian -fomit-frame-pointer   -o register_bug_r.s
register_bug.c

If you now diff the two assembly files, you will notice that uncommenting the
line results in the following lines being added near the start of the function:
+       mov     r2, r8
+       push    {r2, lr}
and near the end:
+       pop     {r2}
+       mov     r8, r2

As you can see, more registers are pushed than popped. This means that when the
stack pointer register is later restored from the stack (pop {r1, r2, r3}; mov 
   sp, r3) it gets the wrong value.


-- 
           Summary: GCC generates incorrect code on ARM in certain case,
                    resulting in stack corruption
           Product: gcc
           Version: 4.1.1
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: c
        AssignedTo: unassigned at gcc dot gnu dot org
        ReportedBy: awalbran at innaworks dot com
GCC target triplet: arm-elf


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=34341

Reply via email to