public inbox for gcc-bugs@sourceware.org
help / color / mirror / Atom feed
* [Bug c/24675]  New: Stack corruption in ARM arch. if 64bit variable is passed to a function of which the low 32 use the register and the up 32 use the stack
@ 2005-11-04 15:05 bill dot thompsons at gmail dot com
  2005-11-04 15:08 ` [Bug target/24675] " pinskia at gcc dot gnu dot org
                   ` (9 more replies)
  0 siblings, 10 replies; 11+ messages in thread
From: bill dot thompsons at gmail dot com @ 2005-11-04 15:05 UTC (permalink / raw)
  To: gcc-bugs

Reproducable: Very easy to reproduce with the sample code 
application provided. PLEASE COMPILE the code with -O2 option.

Product: GCC for ARMV5L

Component: C

Version: 3.2.1. (Reported also in ARM Linux community to 
be see with gcc 3.3.4, gcc 3.4.2) 

Host Platform: x86 Linux 2.4.x

Target Platform: Intel Xscale 80315 (ARMV5L) running Linux 2.4.28.
Issue should be seen with most of the ARM target.

Description:
Stack corruption is seen in ARM arch. when many variables 
are passed to a function AND
if one of the variable is long long AND
if that long long variable is passed by its lower-32 use the 
register and the upper-32 use the stack (a case when r0, r1, 
r2 is already used by other passed variables)

Values are not correctly passed to the function.

Sample Code (PLEASE COMPILE with -O2 option):
------------------------------------------------------------
#include <stdio.h>

typedef unsigned char u8;
typedef unsigned int u32;
typedef unsigned long long u64;

void testfunction (void *buffer1, void *buffer2, u8 count, u64 startsector);
void calledfunction1(void *buffer, u64 startsector, u32 count, u8
opcode, u32 sign);

main()
{
   testfunction (NULL, NULL, 8, 0x700ULL);
}

void testfunction (void *buffer1, void *buffer2, u8 count, u64 startsector)
{
    calledfunction1 (NULL, startsector, 0x55, 0x20, 0x3a3a3a3a);
}

void calledfunction1 (void *buffer, u64 startsector, u32 count, 
u8 opcode, u32 sign)
{
   if(opcode == 0x3a)
      printf( "opcode now is 0x3a!!!!\n");

   printf ("opcode: %x, ", opcode);
   printf( "sign:%x\n",sign);

   return;
}
------------------------------------------------------------

Output of the Sample Code:
--------------------------------
opcode now is 0x3a!!!!
opcode: 3a, sign:40039420
--------------------------------

Expected Output of the Sample Code:
--------------------------------
opcode: 20, sign:3a3a3a3a
--------------------------------


-- 
           Summary: Stack corruption in ARM arch. if 64bit variable is
                    passed to a function of which the low 32 use the
                    register and the up 32 use the stack
           Product: gcc
           Version: 3.2.1
            Status: UNCONFIRMED
          Severity: critical
          Priority: P3
         Component: c
        AssignedTo: unassigned at gcc dot gnu dot org
        ReportedBy: bill dot thompsons at gmail dot com


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


^ permalink raw reply	[flat|nested] 11+ messages in thread

* [Bug target/24675] Stack corruption in ARM arch. if 64bit variable is passed to a function of which the low 32 use the register and the up 32 use the stack
  2005-11-04 15:05 [Bug c/24675] New: Stack corruption in ARM arch. if 64bit variable is passed to a function of which the low 32 use the register and the up 32 use the stack bill dot thompsons at gmail dot com
@ 2005-11-04 15:08 ` pinskia at gcc dot gnu dot org
  2005-11-09  2:11 ` armcc2000 at yahoo dot com
                   ` (8 subsequent siblings)
  9 siblings, 0 replies; 11+ messages in thread
From: pinskia at gcc dot gnu dot org @ 2005-11-04 15:08 UTC (permalink / raw)
  To: gcc-bugs



------- Comment #1 from pinskia at gcc dot gnu dot org  2005-11-04 15:08 -------
3.2.1 is an old compiler and the 3.2 series is no longer being updated, can you
try either a 3.3.6 (note the 3.3 series is not being updated either) or a 3.4.4
or a 4.0.2 GCC?


-- 

pinskia at gcc dot gnu dot org changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
           Severity|critical                    |normal
           Keywords|                            |wrong-code


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


^ permalink raw reply	[flat|nested] 11+ messages in thread

* [Bug target/24675] Stack corruption in ARM arch. if 64bit variable is passed to a function of which the low 32 use the register and the up 32 use the stack
  2005-11-04 15:05 [Bug c/24675] New: Stack corruption in ARM arch. if 64bit variable is passed to a function of which the low 32 use the register and the up 32 use the stack bill dot thompsons at gmail dot com
  2005-11-04 15:08 ` [Bug target/24675] " pinskia at gcc dot gnu dot org
@ 2005-11-09  2:11 ` armcc2000 at yahoo dot com
  2005-11-09  4:21 ` armcc2000 at yahoo dot com
                   ` (7 subsequent siblings)
  9 siblings, 0 replies; 11+ messages in thread
From: armcc2000 at yahoo dot com @ 2005-11-09  2:11 UTC (permalink / raw)
  To: gcc-bugs



------- Comment #2 from armcc2000 at yahoo dot com  2005-11-09 02:11 -------
Here's a slightly smaller test case:

------------------------------------------------------------
extern void foo (int f1, int f2, int f3, int f4, int f5, int f6);

void good (int g1, int g2, int g3, int g4, int g5)
{
        foo (0, 0, 0, 0, 0, 0);
}

void bad (int b1, int b2, int b3, long long b45)
{
        foo (0, 0, 0, 0, 0, 0);
}
------------------------------------------------------------

Compiled with gcc 4.0.1 (-Os), this gives:

        .file   "tst.c"
        .text
        .align  2
        .global good
        .type   good, %function
good:
        @ args = 4, pretend = 0, frame = 0
        @ frame_needed = 0, uses_anonymous_args = 0
        str     lr, [sp, #-4]!
        mov     ip, #0
        sub     sp, sp, #8
        mov     r0, ip
        mov     r1, ip
        mov     r2, ip
        mov     r3, ip
        str     ip, [sp, #0]
        str     ip, [sp, #4]
        bl      foo
        add     sp, sp, #8
        ldmfd   sp!, {pc}
        .size   good, .-good
        .align  2
        .global bad
        .type   bad, %function
bad:
        @ args = 8, pretend = 4, frame = 0
        @ frame_needed = 0, uses_anonymous_args = 0
        @ link register save eliminated.
        mov     ip, #0
        sub     sp, sp, #4
        str     r3, [sp, #0]
        mov     r0, ip
        mov     r1, ip
        mov     r2, ip
        mov     r3, ip
        @ lr needed for prologue
        str     ip, [sp, #4]
        str     ip, [sp, #8]    <-- BANG... caller's stack is overwritten !!
        add     sp, sp, #4
        b       foo
        .size   bad, .-bad
        .ident  "GCC: (GNU) 4.0.1"

------------------------------------------------------------

The bug is also present in 3.4.4


-- 


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


^ permalink raw reply	[flat|nested] 11+ messages in thread

* [Bug target/24675] Stack corruption in ARM arch. if 64bit variable is passed to a function of which the low 32 use the register and the up 32 use the stack
  2005-11-04 15:05 [Bug c/24675] New: Stack corruption in ARM arch. if 64bit variable is passed to a function of which the low 32 use the register and the up 32 use the stack bill dot thompsons at gmail dot com
  2005-11-04 15:08 ` [Bug target/24675] " pinskia at gcc dot gnu dot org
  2005-11-09  2:11 ` armcc2000 at yahoo dot com
@ 2005-11-09  4:21 ` armcc2000 at yahoo dot com
  2005-11-09  4:31 ` pinskia at gcc dot gnu dot org
                   ` (6 subsequent siblings)
  9 siblings, 0 replies; 11+ messages in thread
From: armcc2000 at yahoo dot com @ 2005-11-09  4:21 UTC (permalink / raw)
  To: gcc-bugs



------- Comment #3 from armcc2000 at yahoo dot com  2005-11-09 04:21 -------
A few more results...

1) gcc 4.0.2 _is_ also buggy

2) Bug seems to be associated with -foptimize-sibling-calls 
ie previous code compiled with:

arm-linux-gcc-4.0.2 -O1 -foptimize-sibling-calls

gives:

        .align  2
        .global bad
        .type   bad, %function
bad:
        @ args = 8, pretend = 4, frame = 0
        @ frame_needed = 0, uses_anonymous_args = 0
        @ link register save eliminated.
        sub     sp, sp, #4
        @ lr needed for prologue
        str     r3, [sp, #0]
        mov     r3, #0
        str     r3, [sp, #4]
        str     r3, [sp, #8]    <-- BANG... caller's stack overwritten !!
        mov     r0, r3
        mov     r1, r3
        mov     r2, r3
        add     sp, sp, #4
        b       foo
        .size   bad, .-bad
        .ident  "GCC: (GNU) 4.0.2"


For reference, arm-linux-gcc-4.0.2 -O1 
gives:

        .align  2
        .global bad
        .type   bad, %function
bad:
        @ args = 8, pretend = 4, frame = 0
        @ frame_needed = 0, uses_anonymous_args = 0
        sub     sp, sp, #4
        str     lr, [sp, #-4]!
        sub     sp, sp, #8
        str     r3, [sp, #12]
        mov     r3, #0
        str     r3, [sp, #0]
        str     r3, [sp, #4]
        mov     r0, r3
        mov     r1, r3
        mov     r2, r3
        bl      foo
        add     sp, sp, #8
        ldr     lr, [sp], #4
        add     sp, sp, #4
        bx      lr
        .size   bad, .-bad
        .ident  "GCC: (GNU) 4.0.2"

(ie not particularly optimal, but no stack corruption).


-- 

armcc2000 at yahoo dot com changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |armcc2000 at yahoo dot com


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


^ permalink raw reply	[flat|nested] 11+ messages in thread

* [Bug target/24675] Stack corruption in ARM arch. if 64bit variable is passed to a function of which the low 32 use the register and the up 32 use the stack
  2005-11-04 15:05 [Bug c/24675] New: Stack corruption in ARM arch. if 64bit variable is passed to a function of which the low 32 use the register and the up 32 use the stack bill dot thompsons at gmail dot com
                   ` (2 preceding siblings ...)
  2005-11-09  4:21 ` armcc2000 at yahoo dot com
@ 2005-11-09  4:31 ` pinskia at gcc dot gnu dot org
  2005-11-09  6:21 ` armcc2000 at yahoo dot com
                   ` (5 subsequent siblings)
  9 siblings, 0 replies; 11+ messages in thread
From: pinskia at gcc dot gnu dot org @ 2005-11-09  4:31 UTC (permalink / raw)
  To: gcc-bugs



------- Comment #4 from pinskia at gcc dot gnu dot org  2005-11-09 04:31 -------
I think this is a dup of bug 23150 which was fixed in 4.1.0.


-- 

pinskia at gcc dot gnu dot org changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
  BugsThisDependsOn|                            |23150


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


^ permalink raw reply	[flat|nested] 11+ messages in thread

* [Bug target/24675] Stack corruption in ARM arch. if 64bit variable is passed to a function of which the low 32 use the register and the up 32 use the stack
  2005-11-04 15:05 [Bug c/24675] New: Stack corruption in ARM arch. if 64bit variable is passed to a function of which the low 32 use the register and the up 32 use the stack bill dot thompsons at gmail dot com
                   ` (3 preceding siblings ...)
  2005-11-09  4:31 ` pinskia at gcc dot gnu dot org
@ 2005-11-09  6:21 ` armcc2000 at yahoo dot com
  2005-11-09 22:04 ` mikpe at csd dot uu dot se
                   ` (4 subsequent siblings)
  9 siblings, 0 replies; 11+ messages in thread
From: armcc2000 at yahoo dot com @ 2005-11-09  6:21 UTC (permalink / raw)
  To: gcc-bugs



------- Comment #5 from armcc2000 at yahoo dot com  2005-11-09 06:21 -------
(In reply to comment #4)
> I think this is a dup of bug 23150 which was fixed in 4.1.0.
> 

I don't think so.

I rebuilt 4.0.2 after applying the patch given for bug 23150.
The patched version of 4.0.2 gives the same result as the vanilla one for this
test.

Also, the testcase for 23150 does not seem to fail with any of the
arm-linux-gcc (ie not arm-eabi) versions I tried it with. Then again, the
testcase for 23150 doesn't fail with 'gcc version 3.4.4 (release) (CodeSourcery
ARM 2005q3-1)', which is the only arm-eabi compiler I have (but maybe new
enough to have that bug fixed).


-- 


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


^ permalink raw reply	[flat|nested] 11+ messages in thread

* [Bug target/24675] Stack corruption in ARM arch. if 64bit variable is passed to a function of which the low 32 use the register and the up 32 use the stack
  2005-11-04 15:05 [Bug c/24675] New: Stack corruption in ARM arch. if 64bit variable is passed to a function of which the low 32 use the register and the up 32 use the stack bill dot thompsons at gmail dot com
                   ` (4 preceding siblings ...)
  2005-11-09  6:21 ` armcc2000 at yahoo dot com
@ 2005-11-09 22:04 ` mikpe at csd dot uu dot se
  2005-11-09 23:33 ` armcc2000 at yahoo dot com
                   ` (3 subsequent siblings)
  9 siblings, 0 replies; 11+ messages in thread
From: mikpe at csd dot uu dot se @ 2005-11-09 22:04 UTC (permalink / raw)
  To: gcc-bugs



------- Comment #6 from mikpe at csd dot uu dot se  2005-11-09 22:04 -------
Here's a standalone test case. This fails (returns 1 from main())
on armv5b-linux when compiled with gcc-3.4.4, 3.3.6, or 3.3.3,
at -O2 or -O1 -foptimize-sibling-calls. Disabling sibcall optimisation
hides the bug.

If the variable x in main() is removed (passing NULL not &x to
clobbers_callers_stack()), then the return address slot in main()'s
frame gets clobbered, causing main() to return to la-la land,
resulting in a seg fault.

#include <stdio.h>

void doit(void *p, unsigned long long ull, unsigned c, unsigned a, unsigned s)
{
    if (!(int)ull)
        printf("%p %016llx %x %x %x\n", p, ull, c, a, s);
}

void clobbers_callers_stack(void *p1, void *p2, unsigned c, unsigned long long
ull)
{
    doit(NULL, ull, 0x55, 0x20, 0x3a3a3a3a);
}

int main(void)
{
    int x = 0;
    clobbers_callers_stack(&x, NULL, 8, 0x700ULL);
    if (x != 0) {
        printf("main: x == %#x\n", x);
        return 1;
    }
    return 0;
}


-- 


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


^ permalink raw reply	[flat|nested] 11+ messages in thread

* [Bug target/24675] Stack corruption in ARM arch. if 64bit variable is passed to a function of which the low 32 use the register and the up 32 use the stack
  2005-11-04 15:05 [Bug c/24675] New: Stack corruption in ARM arch. if 64bit variable is passed to a function of which the low 32 use the register and the up 32 use the stack bill dot thompsons at gmail dot com
                   ` (5 preceding siblings ...)
  2005-11-09 22:04 ` mikpe at csd dot uu dot se
@ 2005-11-09 23:33 ` armcc2000 at yahoo dot com
  2005-11-09 23:41 ` pinskia at gcc dot gnu dot org
                   ` (2 subsequent siblings)
  9 siblings, 0 replies; 11+ messages in thread
From: armcc2000 at yahoo dot com @ 2005-11-09 23:33 UTC (permalink / raw)
  To: gcc-bugs



------- Comment #7 from armcc2000 at yahoo dot com  2005-11-09 23:32 -------
(In reply to comment #4)
>
> I think this is a dup of bug 23150 which was fixed in 4.1.0.
> 

Something has certainly changed in 4.1 - the stack corruption is gone.
With -Os, the good() and bad() testcases compile to:

------------------------------------------------------------

bad:
        @ args = 8, pretend = 4, frame = 0
        @ frame_needed = 0, uses_anonymous_args = 0
        sub     sp, sp, #4
        str     lr, [sp, #-4]!
        mov     ip, #0
        sub     sp, sp, #8
        str     r3, [sp, #12]
        mov     r0, ip
        mov     r1, ip
        mov     r2, ip
        mov     r3, ip
        str     ip, [sp, #0]
        str     ip, [sp, #4]
        bl      foo
        add     sp, sp, #8
        ldr     lr, [sp], #4
        add     sp, sp, #4
        bx      lr

good:
        @ args = 4, pretend = 0, frame = 0
        @ frame_needed = 0, uses_anonymous_args = 0
        str     lr, [sp, #-4]!
        mov     ip, #0
        sub     sp, sp, #8
        mov     r0, ip
        mov     r1, ip
        mov     r2, ip
        mov     r3, ip
        str     ip, [sp, #0]
        str     ip, [sp, #4]
        bl      foo
        add     sp, sp, #8
        ldmfd   sp!, {pc}

        .ident  "GCC: (GNU) 4.1.0 20051105 (experimental)"

------------------------------------------------------------

The bug with previous compilers seems to be that the amount of stack space
already allocated by the caller was over estimated by the callee (ie
incorrectly calculated to be 8 bytes instead of 4 - as if the entire long long
param is passed on the stack when in fact only half of it has been).

However with 4.1, neither good() or bad() make any use of the 4 bytes of stack
already allocated for them by their caller ??. They both assume they start off
with 0 bytes allocated to them and then correctly allocate as required.

Therefore it seems that 4.1 is generating correct code because of a missing
optimisation that was present in previous versions ??

------------------------------------------------------------

As an aside, if gcc were smart enough, I believe good() and bad() should
compile to exactly the same assembler, so there's still some optimisation
tweaks that could be done... ;-)

------------------------------------------------------------


-- 


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


^ permalink raw reply	[flat|nested] 11+ messages in thread

* [Bug target/24675] Stack corruption in ARM arch. if 64bit variable is passed to a function of which the low 32 use the register and the up 32 use the stack
  2005-11-04 15:05 [Bug c/24675] New: Stack corruption in ARM arch. if 64bit variable is passed to a function of which the low 32 use the register and the up 32 use the stack bill dot thompsons at gmail dot com
                   ` (6 preceding siblings ...)
  2005-11-09 23:33 ` armcc2000 at yahoo dot com
@ 2005-11-09 23:41 ` pinskia at gcc dot gnu dot org
  2005-11-10  1:25 ` armcc2000 at yahoo dot com
  2005-11-11  0:56 ` bill dot thompsons at gmail dot com
  9 siblings, 0 replies; 11+ messages in thread
From: pinskia at gcc dot gnu dot org @ 2005-11-09 23:41 UTC (permalink / raw)
  To: gcc-bugs



------- Comment #8 from pinskia at gcc dot gnu dot org  2005-11-09 23:41 -------
(In reply to comment #7)
> (In reply to comment #4)
> >
> > I think this is a dup of bug 23150 which was fixed in 4.1.0.
> > 
> Something has certainly changed in 4.1 - the stack corruption is gone.

Yes then this is a dup of that bug then.  The problem is that the middle-end
did not know what the target was doing so it rejected sib calling in this case.

*** This bug has been marked as a duplicate of 23150 ***


-- 

pinskia at gcc dot gnu dot org changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|UNCONFIRMED                 |RESOLVED
         Resolution|                            |DUPLICATE


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


^ permalink raw reply	[flat|nested] 11+ messages in thread

* [Bug target/24675] Stack corruption in ARM arch. if 64bit variable is passed to a function of which the low 32 use the register and the up 32 use the stack
  2005-11-04 15:05 [Bug c/24675] New: Stack corruption in ARM arch. if 64bit variable is passed to a function of which the low 32 use the register and the up 32 use the stack bill dot thompsons at gmail dot com
                   ` (7 preceding siblings ...)
  2005-11-09 23:41 ` pinskia at gcc dot gnu dot org
@ 2005-11-10  1:25 ` armcc2000 at yahoo dot com
  2005-11-11  0:56 ` bill dot thompsons at gmail dot com
  9 siblings, 0 replies; 11+ messages in thread
From: armcc2000 at yahoo dot com @ 2005-11-10  1:25 UTC (permalink / raw)
  To: gcc-bugs



------- Comment #9 from armcc2000 at yahoo dot com  2005-11-10 01:25 -------
(In reply to comment #8)
> 
> Yes then this is a dup of that bug then.  The problem is that the middle-end
> did not know what the target was doing so it rejected sib calling in this case.
> 

Any idea why the patch for bug 23150 doesn't fix 4.0.2 ??
(the patch applies OK without any manual editing).

What is the procedure for getting fixes in 3.4.x and 4.0.x ??
Or should users just wait until 4.1 is released ??


-- 


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


^ permalink raw reply	[flat|nested] 11+ messages in thread

* [Bug target/24675] Stack corruption in ARM arch. if 64bit variable is passed to a function of which the low 32 use the register and the up 32 use the stack
  2005-11-04 15:05 [Bug c/24675] New: Stack corruption in ARM arch. if 64bit variable is passed to a function of which the low 32 use the register and the up 32 use the stack bill dot thompsons at gmail dot com
                   ` (8 preceding siblings ...)
  2005-11-10  1:25 ` armcc2000 at yahoo dot com
@ 2005-11-11  0:56 ` bill dot thompsons at gmail dot com
  9 siblings, 0 replies; 11+ messages in thread
From: bill dot thompsons at gmail dot com @ 2005-11-11  0:56 UTC (permalink / raw)
  To: gcc-bugs



------- Comment #10 from bill dot thompsons at gmail dot com  2005-11-11 00:56 -------
Subject: Re:  Stack corruption in ARM arch. if 64bit variable is passed to a
function of which the low 32 use the register and the up 32 use the stack

> What is the procedure for getting fixes in 3.4.x and 4.0.x ??
> Or should users just wait until 4.1 is released ??

I am new to the gcc bug fixing process. For getting this fixed in 3.4.4,
should I log this bug against gcc 3.4.4?


-- 


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


^ permalink raw reply	[flat|nested] 11+ messages in thread

end of thread, other threads:[~2005-11-11  0:56 UTC | newest]

Thread overview: 11+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2005-11-04 15:05 [Bug c/24675] New: Stack corruption in ARM arch. if 64bit variable is passed to a function of which the low 32 use the register and the up 32 use the stack bill dot thompsons at gmail dot com
2005-11-04 15:08 ` [Bug target/24675] " pinskia at gcc dot gnu dot org
2005-11-09  2:11 ` armcc2000 at yahoo dot com
2005-11-09  4:21 ` armcc2000 at yahoo dot com
2005-11-09  4:31 ` pinskia at gcc dot gnu dot org
2005-11-09  6:21 ` armcc2000 at yahoo dot com
2005-11-09 22:04 ` mikpe at csd dot uu dot se
2005-11-09 23:33 ` armcc2000 at yahoo dot com
2005-11-09 23:41 ` pinskia at gcc dot gnu dot org
2005-11-10  1:25 ` armcc2000 at yahoo dot com
2005-11-11  0:56 ` bill dot thompsons at gmail dot com

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).