AVR 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 | Percent Complete: | 0% |
Assigned to: | None | Open/Closed: | Closed |
Release: | 1.6.8 | Fixed Release: | None |
Wed 05 May 2010 04:12:31 AM UTC, comment #1: |
Joerg Wunsch <joerg_wunsch>![]() |
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.
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> |
No files currently attached
Depends on the following items: None found
Items that depend on this one: None found
Follow 2 latest changes.
Date | Changed by | Updated Field | Previous Value | => | Replaced by |
---|---|---|---|---|---|
2010-05-05 | joerg_wunsch | Status | None | ![]() |
Invalid |
Open/Closed | Open | ![]() |
Closed |
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.