LTO inlining appears to misuse the stack

Bug #1808884 reported by Marc Singer
6
This bug affects 1 person
Affects Status Importance Assigned to Milestone
GNU Arm Embedded Toolchain
New
Undecided
Unassigned

Bug Description

A sample program that produces this bug follows.

With LTO enabled, some of startup code for my application is inlined into main. Hurray for LTO! The error I'm seeing is that the inlined code is storing to [sp, #0] and [sp, #4]. The second of these is clobbering a data structure that immediately follows the stack in RAM. As far as I can tell, there is no interpretation of the source code that would make it valid for the inlined function to store to the stack of the calling function...of which there is none as we're looking at main(). There is no add sp,#4, for example, which would allocate room for locals.

What is more peculiar to me is that the value being stored came from the literal pool at instruction 0x080000e6. The eight stores through [r2, r0] are initializing the NVIC. r2 holds the base address of the NVIC.

Below is the top of main with the inlined code. You can see at instruction 0x08000116 a store through sp.

int main (void)
{
 80000d0: 2101 movs r1, #1
 80000d2: 4bbf ldr r3, [pc, #764] ; (80003d0 <_start+0x310>)
 80000d4: 4abf ldr r2, [pc, #764] ; (80003d4 <_start+0x314>)
 80000d6: 6059 str r1, [r3, #4]
 80000d8: 2382 movs r3, #130 ; 0x82
 80000da: 6950 ldr r0, [r2, #20]
 80000dc: 009b lsls r3, r3, #2
 80000de: 4303 orrs r3, r0
 80000e0: 20c0 movs r0, #192 ; 0xc0
 80000e2: 6153 str r3, [r2, #20]
 80000e4: 2300 movs r3, #0
 80000e6: 4abc ldr r2, [pc, #752] ; (80003d8 <_start+0x318>)
 80000e8: 0080 lsls r0, r0, #2
 80000ea: 5013 str r3, [r2, r0]
 80000ec: 3004 adds r0, #4
 80000ee: 5013 str r3, [r2, r0]
 80000f0: 3004 adds r0, #4
 80000f2: 5013 str r3, [r2, r0]
 80000f4: 3004 adds r0, #4
 80000f6: 5013 str r3, [r2, r0]
 80000f8: 3004 adds r0, #4
 80000fa: 5013 str r3, [r2, r0]
 80000fc: 3004 adds r0, #4
 80000fe: 5013 str r3, [r2, r0]
 8000100: 3004 adds r0, #4
 8000102: 5013 str r3, [r2, r0]
 8000104: 3004 adds r0, #4
 8000106: 5013 str r3, [r2, r0]
 8000108: 4db4 ldr r5, [pc, #720] ; (80003dc <_start+0x31c>)
 800010a: 48b5 ldr r0, [pc, #724] ; (80003e0 <_start+0x320>)
 800010c: 4eb5 ldr r6, [pc, #724] ; (80003e4 <_start+0x324>)
 800010e: 602b str r3, [r5, #0]
 8000110: 6068 str r0, [r5, #4]
 8000112: 6029 str r1, [r5, #0]
 8000114: 6870 ldr r0, [r6, #4]
 8000116: 9200 str r2, [sp, #0]
 8000118: 06c0 lsls r0, r0, #27
 800011a: 0f80 lsrs r0, r0, #30
 800011c: 4298 cmp r0, r3
 800011e: d011 beq.n 8000144 <_start+0x84>

If I can build a test case, I'll add it to this report.

Cheers

Revision history for this message
Marc Singer (eleventen) wrote :

FWIW, the version of the compiler gcc-arm-none-eabi-7-2017-q4-major also exhibits the issue. I am not able to go back further because the program depends on some compiler features added in GCC7.

Revision history for this message
Marc Singer (eleventen) wrote :

I believe I have a test case for this issue. I've run it through the three releases from 2017 and on the one release in 2018. All of them produce the same erroneous code.

Revision history for this message
Marc Singer (eleventen) wrote :

The attached archive has the pre-processed compiler output from the source file to eliminate a need for headers. It can be converted into a ELF file with the build.sh script. The linker script is necessary to generate the broken output. The output of my build is included as well.

The problem instruction is at address 0x080000cc:

 80000cc: 9201 str r2, [sp, #4]

Before this instruction, there is no stack space reserved for temporaries.

In the original build, a value was stored on the stack, but never retrieved. This build doesn't have that specific construct, probably because much of the original program has been removed.

description: updated
To post a comment you must log in.
This report contains Public information  
Everyone can see this information.

Other bug subscribers

Remote bug watches

Bug watches keep track of this bug in other bug trackers.