Message from discussion Suspicious assembly code generated by GCC 4.5.2
Received: by 10.205.126.4 with SMTP id gu4mr2973751bkc.8.1343752114317;
Tue, 31 Jul 2012 09:28:34 -0700 (PDT)
Received: by 10.180.82.226 with SMTP id l2mr158639wiy.1.1343752030013;
Tue, 31 Jul 2012 09:27:10 -0700 (PDT)
NNTP-Posting-Date: Tue, 31 Jul 2012 11:27:09 -0500
From: Andrew Haley <andre...@littlepinkcloud.invalid>
Subject: Re: Suspicious assembly code generated by GCC 4.5.2
References: <email@example.com> <4_GdnURYjo-tPorNnZ2dnUVZ8oqdnZ2d@supernews.com> <firstname.lastname@example.org>
User-Agent: tin/1.9.2-20070201 ("Dalaruan") (UNIX) (Linux/3.4.6-2.fc17.x86_64 (x86_64))
Date: Tue, 31 Jul 2012 11:27:09 -0500
X-Abuse-and-DMCA-Info: Please be sure to forward a copy of ALL headers
X-Abuse-and-DMCA-Info: Otherwise we will be unable to process your complaint properly
el <elgar...@gmail.com> wrote:
> On Tuesday, July 31, 2012 12:19:44 PM UTC+3, Andrew Haley wrote:
>> el wrote:
>> > I'm working on a MIPS-based embedded system.
>> > Below is an assembly code snippet of the end of some function.
>> > This code was compiled by gcc 4.5.2 with -mips16e and -Os flags.
>> > - Line 6: the stack frame is released and ra,s0 and s1 registers are restored from the stack.
>> > - Line 8: returns to the caller function (jump to the return address)
>> > - Line 9: branch delay slot instruction which stores in v0 (return value) a value pointed by register a0
>> > Note that 0(a) is located in the stack (sp + 26) - see lines 2,3,5
>> > 1) 8024c3be: 9206 lw v0,24(sp)
>> > 2) 8024c3c0: 677d move v1,sp
>> > 3) 8024c3c2: 4387 addiu a0,v1,7
>> > 4) 8024c3c4: 67bc move a1,gp
>> > 5) 8024c3c6: 4c13 addiu a0,19
>> > 6) 8024c3c8: 6478 restore 64,ra,s0-s1
>> > 7) 8024c3ca: f3a6 dd50 sw v0,13232(a1)
>> > 8) 8024c3ce: e820 jr ra
>> > 9) 8024c3d0: 8c40 lh v0,0(a0) // sp+26
>> > 10) 8024c3d2: 6500 nop
>> > This asm code (generated by GCC) seems to be faulty as the cpu reads value from the stack frame (line 9) after it was 'released' (line 6).
>> > Here is a problematic scenario which demonsrates the issue:
>> > 1. A task is running this function.
>> > 1. Interrupt is triggered between lines 7 and 8.
>> > 2. The context of the task is stored in the stack (which was restored beforehand in line 6).
>> > 3. As a result the value stored in 0(a0)=sp+26 is overwritten by the context information!
>> > 4. The ISR ends and the task context is resotred.
>> > 5. the instruction in line 9 is executed --> The function returns in v0 incorrect value!
>> > Regardless of the RTOS I'm using (it's not linux), is this code legitimate?
>> It's not necessarily wrong. This is a matter of whether the system
>> ABI uses a "red zone", an area beyond the stack pointer. I don't
>> think MIPS usually does, but I don't know anything about the OS you're
> Our OS is FreeRTOS and use MIPS without shadow registers. so upon
> context switch we save all current registers on the stack of the
> task/interrupt (in the 'red zone').
> So far we worked with an old version of the compiler 'gcc version
> 3.4.4 mipssde-6.06.01-20070420' - we didn't see the problem there,
> the 'red zone' was never used by a function.
> Recently we switched to a new compiler 'gcc version 4.5.2 Sourcery
> CodeBench Lite 2011.09-86' and we started seeing this problem.
> Note that this will only happen if we compile to mips16 and apply
> size optimization. Otherwise this problem won't occur.
I see that you got another answer on the gcc list: it's a bug. MIPS
doesn't use a red zone.