avr-libc-dev
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [avr-gcc-list] Re: [avr-libc-dev] [bug #29774] prologue/epilogue st


From: Bob Paddock
Subject: Re: [avr-gcc-list] Re: [avr-libc-dev] [bug #29774] prologue/epilogue stack pointer manipulation not interrupt safe in XMega
Date: Tue, 8 Jun 2010 15:01:46 -0400

On Tue, Jun 8, 2010 at 2:22 PM, Stu Bell <address@hidden> wrote:
>
>>
>> > There are several places that handle SP adjustment:
>> >
>> > avr.c: output_movhi, expand_prologue, expand_epilogue
>> > avr.md: movhi_sp_r_irq_off, movhi_sp_r_irq_on (both generated in
>> > epilogue/prologue)
>> > libgcc.S: __prologue_saves__, __epilogue_restores__
>> >
>> > For changes in libgcc.S to take effect, appropriate builtin-defines
>> > must be provided so that the right multilib variants will
>> be generated.
>>
>> When I was patching my libgcc.a for the avrxmega7 lib, the
>> only place that I saw, that turned off the IRQs were the
>> epilogue/prologue.
>> Is there some reason they don't need turned off in the other contexts?
>>  Seems like such a problem would have shown up long before now?
>
> Do you mean on entry/exit to ISRs?  Surely you wouldn't want to do that
> in generic prologue/epilogue code, right?

Not really what we are discussing, you are correct that would be bad.

I believe the context was lost in the migration from AVR-LibC list to
the AVR-GCC list where this really belongs.

For those just tuning in on the AVR-GCC list, from Matthew's original
bug report to AVR-LibC:

0001b082 <__epilogue_restores__>:
  ...
  1b0aa:       0f b6           in      r0, 0x3f        ; 63
  1b0ac:       f8 94           cli
  1b0ae:       de bf           out     0x3e, r29       ; 62
  1b0b0:       0f be           out     0x3f, r0        ; 63
  1b0b2:       cd bf           out     0x3d, r28       ; 61
  1b0b4:       ed 01           movw    r28, r26
  1b0b6:       08 95           ret


The XMega, however, can jump to an interrupt immediately after the status
register is restored and before the second half of the stack is written.
Therefore any interrupt code that uses the stack will potentially write to an
arbitrary memory location. In my application this results in stack corruption
and a function return to an arbitrary address."

Same problem is in the _saves section as well.

In XMega parts SPL needs to be written before SPH.

For more context from Galen Seitz:
=================
I have gcc 4.3.3 plus multiple patches, in particular
gcc-4.3.3-xmega-v13.  My gcc should closely match winavr20100110.

I'm not sure I'm looking in the correct place, but avr.c in my gcc
build has the following code:

const char *
output_movhi (rtx insn, rtx operands[], int *l)
{
...
             if(AVR_XMEGA)
               {
                 *l = 2;
                 return (AS2 (out,__SP_L__,%A1)  CR_TAB
                         AS2 (out,__SP_H__,%B1));
               }
             else
               {
                 *l = 5;
                 return (AS2 (in,__tmp_reg__,__SREG__)  CR_TAB
                         "cli"                          CR_TAB
                         AS2 (out,__SP_H__,%B1)         CR_TAB
                         AS2 (out,__SREG__,__tmp_reg__) CR_TAB
                         AS2 (out,__SP_L__,%A1));


This suggests that xmega code should simply be restoring the stack
pointer.  (Note that on the xmega, when SPL is written all interrupts
are disabled for up to four instructions or until SPH is also
written.)  However, when I look at the disassembly of the
__prologue_saves__ and __epilogue_restores__ code for the xmega
libgcc.a libraries, I see the code for the non-AVR_XMEGA path.  The
libgcc.a libraries from winavr20100110 are the same.
============



reply via email to

[Prev in Thread] Current Thread [Next in Thread]