bugAVR C Runtime Library - Bugs: bug #29774, prologue/epilogue stack pointer...

 
 

You are not allowed to post comments on this tracker with your current authentication level.

bug #29774: prologue/epilogue stack pointer manipulation not interrupt safe in XMega

Submitter:  Matthew Vernon <sunergos>
Submitted:  Tue 04 May 2010 04:05:21 PM UTC
   
 
Category:  Library Severity:  3 - Normal
Priority:  5 - Normal Item Group:  Unknown
Status:  Invalid Assigned to:  None
Percent Complete:  0% Open/Closed:  Closed
Release:  1.6.8 Fixed Release:  None

Wed 05 May 2010 04:12:31 AM UTC, comment #1: 

As you already noticed, the function prologue/epilogue
handling is not part of avr-libc.  It's part of GCC.

So please report this to GCC's bugzilla.

Joerg Wunsch <joerg_wunsch>
Group administrator
Tue 04 May 2010 04:05:21 PM UTC, original submission:  

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.


Matthew Vernon <sunergos>

 

(Note: upload size limit is set to 16384 kB, after insertion of the required escape characters.)

No files currently attached

 

Depends on the following items: None found

Items that depend on this one: None found

 

Carbon-Copy List
  • -email is unavailable- added by joerg_wunsch (Posted a comment)
  • -email is unavailable- added by sunergos (Submitted the item)
  •  

    Follow 2 latest changes.

    Date Changed by Updated Field Previous Value => Replaced by
    2010-05-05 joerg_wunsch StatusNone Invalid
        Open/ClosedOpen Closed

    Back to the top

    Powered by Savane 3.13-4448.
    Corresponding source code