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

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

Re: [avr-libc-dev] [bug #29774] prologue/epilogue stack pointer manipula


From: Bob Paddock
Subject: Re: [avr-libc-dev] [bug #29774] prologue/epilogue stack pointer manipulation not interrupt safe in XMega
Date: Thu, 10 Feb 2011 12:22:25 -0500

http://savannah.nongnu.org/bugs/?29774

Was this issue ever resolved in GCC, being an invalid bug for AVR-LibC?
There was discussion of it back in June, and Eric had a patch, but I
could not pick it out of the GCC Bug list.
http://www.nongnu.org/avr-libc/bugs.html


On Tue, May 4, 2010 at 12:05 PM, Matthew Vernon <address@hidden> wrote:
>
> URL:
>  <http://savannah.nongnu.org/bugs/?29774>
>
>                 Summary: prologue/epilogue stack pointer manipulation not
> interrupt safe in XMega
>                 Project: AVR C Runtime Library
>            Submitted by: sunergos
>            Submitted on: Tue 04 May 2010 04:05:21 PM GMT
>                Category: Library
>                Severity: 3 - Normal
>                Priority: 5 - Normal
>              Item Group: Unknown
>                  Status: None
>        Percent Complete: 0%
>             Assigned to: None
>             Open/Closed: Open
>         Discussion Lock: Any
>                 Release: 1.6.8
>           Fixed Release: None
>
>    _______________________________________________________
>
> Details:
>
> The function prologue and epilogue code (in list files __prologue_saves__ and
> __epilogue_restores__) finish by clearing interrupts, changing the stack
> pointer, then restoring the status register (potentially enabling
> interrupts).
>
> The actual code from the list file for my XMega project is shown below. Note
> that 0x3F is the status register (including interrupt enable), and 0x3D with
> 0x3E are the stack pointer.
>
> The status register is preserved, then interrupts are cleared. Half of the
> stack is written, the status register is restored, then the other half of the
> stack is written. On most architectures this is correct as one instruction can
> safely execute after enabling interrupts (restore SREG) before an interrupt
> can occur.
>
>
> 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.
>
> The solution is to restore the status register on line later ("out      0x3f, 
> r0"
> after "out      0x3d, r28"). Since this code appears to be external to the 
> avr-libc
> project I am not sure how to implement the fix beyond my own version of the
> library.
>
> This behavior can be tested by setting an interrupt to be always active such
> as a very fast timer interrupt. The code will execute one instruction between
> interrupts and therefore an interrupt will occur at the point indicated
> above.
>
>
>
>
>
>
>    _______________________________________________________
>
> Reply to this item at:
>
>  <http://savannah.nongnu.org/bugs/?29774>
>
> _______________________________________________
>  Message sent via/by Savannah
>  http://savannah.nongnu.org/
>
>
>
> _______________________________________________
> AVR-libc-dev mailing list
> address@hidden
> http://lists.nongnu.org/mailman/listinfo/avr-libc-dev
>



reply via email to

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