Bug 44091 - [ARM/Thumb] Invalid stack frame usage at -Os
Summary: [ARM/Thumb] Invalid stack frame usage at -Os
Status: RESOLVED DUPLICATE of bug 38644
Alias: None
Product: gcc
Classification: Unclassified
Component: c (show other bugs)
Version: 4.4.4
: P3 normal
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2010-05-12 07:20 UTC by Sebastian Huber
Modified: 2010-05-13 14:22 UTC (History)
13 users (show)

See Also:
Host: x86_64-unknown-linux-gnu
Target: arm-rtems4.10
Build: x86_64-unknown-linux-gnu
Known to work:
Known to fail:
Last reconfirmed:


Attachments
Log. (1019 bytes, text/plain)
2010-05-12 07:21 UTC, Sebastian Huber
Details
Preprocessed source file. (39.55 KB, text/plain)
2010-05-12 07:21 UTC, Sebastian Huber
Details
Generated assembler file. (10.10 KB, text/plain)
2010-05-12 07:22 UTC, Sebastian Huber
Details
Difference between bdbuf.s in revsions 130051 and 130052 (1.13 KB, text/plain)
2010-05-13 09:50 UTC, Sebastian Huber
Details

Note You need to log in before you can comment on or make changes to this bug.
Description Sebastian Huber 2010-05-12 07:20:37 UTC
GCC generates an invalid stack frame usage sequence in a function epilogue.

Function prologue with comments:

	.align	2
	.global	rtems_bdbuf_read
	.code	16
	.thumb_func
	.type	rtems_bdbuf_read, %function
rtems_bdbuf_read:
	push	{r4, r5, r6, r7, lr}
	sub	sp, sp, #60
	add	r7, sp, #8
        /*
         * We have now reserved a stack frame in a two step process.  The
         * non-volatile register r7 will be use as an local variable anchor.
         */
	str	r3, [r7, #4]
	mov	r3, #0
	str	r3, [r7, #48]
	str	r3, [r7, #44]
	str	r3, [r7, #40]
	mov	r3, r7
	add	r3, r3, #44
	str	r3, [sp]
	sub	r3, r3, #4
	str	r3, [sp, #4]
	add	r3, r3, #8
	bl	rtems_bdbuf_obtain_disk
	str	r0, [r7, #12]
	cmp	r0, #0
	beq	.LCB3661
	b	.L520	@long jump
.LCB3661:

Function epilogue with comments:
.L520:
	mov	sp, r7
	add	sp, sp, #52
        /*
         * Here we released the second part of our stack frame which contains
         * local variables.
         */
	ldr	r0, [r7, #12]
        /*
         * Here we used the second part of our stack frame which contains local
         * variables.  We read a status variable from the stack frame that will
         * be returned now.  That means we use a part of the frame that we
         * already released.  In case an interrupt happens between these two
         * instructions (add and ldr) we may have a big problem.  These two
         * instructions are in the wrong order, the reverse order is correct.
         */
	@ sp needed for prologue
	pop	{r4, r5, r6, r7, pc}

Attached files follow.
Comment 1 Sebastian Huber 2010-05-12 07:21:25 UTC
Created attachment 20641 [details]
Log.
Comment 2 Sebastian Huber 2010-05-12 07:21:49 UTC
Created attachment 20642 [details]
Preprocessed source file.
Comment 3 Sebastian Huber 2010-05-12 07:22:09 UTC
Created attachment 20643 [details]
Generated assembler file.
Comment 4 Sebastian Huber 2010-05-12 09:40:50 UTC
GCC 4.5.0 20100414 has this problem too.
Comment 5 Sebastian Huber 2010-05-12 10:03:44 UTC
GCC 4.2.4 does not have this problem.

Function epilogue:

.L672:
	ldr	r0, [r7, #4]
	mov	sp, r7
	add	sp, sp, #52
	@ sp needed for prologue
	pop	{r4, r5, r6, r7, pc}

You can see here that the mov/add and ldr instructions are in the right order.
Comment 6 Sebastian Huber 2010-05-12 11:06:48 UTC
If you use GCC 4.5.0 20100414 with '-march=armv7' '-mthumb' '-Os' the function epilogue is also correct.  It seems that this is a Thumb 1 problem.
Comment 7 Sebastian Huber 2010-05-12 11:13:13 UTC
GCC 4.3.2 20080827 has this problem too.
Comment 8 Sebastian Huber 2010-05-12 12:03:48 UTC
A summary follows.  Broken means bdbuf.i generates an invalid stack frame usage sequence in a function epilogue.  Works means that the corresponding area is valid.

Flags: -march=armv5t -mthumb -Os
  Broken:
    GCC 4.3.2 20080827
    GCC 4.4.4 20100429
    GCC 4.5.0 20100414
  Works:
    GCC 4.2.4

Flags: -march=armv7 -mthumb -Os
  Works:
    GCC 4.5.0 20100414

Flags: -march=armv5t -mthumb -O2
  Suspicious:
    GCC 4.5.0 20100414

Suspicious means that the epilogue sequence is this:

.L577:
	mov	sp, r7
	add	sp, sp, #36
	mov	r0, r4
	/*
	 * Here we don't have a problem since r0 comes from r4
	 * and not from the stack frame.  Is this always the case?
	 */
	@ sp needed for prologue
	pop	{r2, r3, r4, r5}
	mov	r8, r2
	mov	r9, r3
	mov	sl, r4
	mov	fp, r5
	pop	{r4, r5, r6, r7, pc}
Comment 9 Mikael Pettersson 2010-05-12 16:34:10 UTC
Confirmed with cross to armv5tel-unknown-linux-gnueabi. 4.3/4.4/4.5/4.6 all generate the signal-unsafe epilogue.
Comment 10 Sebastian Huber 2010-05-13 09:42:08 UTC
Binary search through trunk revisions yield:

r159321 BROKEN
r150000 BROKEN
r140000 BROKEN
r135000 BROKEN
r132500 BROKEN
r131024 BROKEN
r130512 BROKEN
r130256 BROKEN
r130128 BROKEN
r130064 BROKEN
r130056 BROKEN
r130052 BROKEN
r130051 OK
r130050 OK
r130048 OK
r130032 OK
r130000 OK
Comment 11 Sebastian Huber 2010-05-13 09:50:34 UTC
Created attachment 20654 [details]
Difference between bdbuf.s in revsions 130051 and 130052

This clearly shows how the frame usage sequence changed.
Comment 12 Mikael Pettersson 2010-05-13 10:28:19 UTC
r130052 is a generic scheduling tweak originally described here:
http://gcc.gnu.org/ml/gcc-patches/2007-10/msg01814.html
Comment 13 Andrew Pinski 2010-05-13 14:22:06 UTC

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