[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[avr-libc-dev] [bug #29774] prologue/epilogue stack pointer manipulation
From: |
Matthew Vernon |
Subject: |
[avr-libc-dev] [bug #29774] prologue/epilogue stack pointer manipulation not interrupt safe in XMega |
Date: |
Tue, 04 May 2010 16:05:22 +0000 |
User-agent: |
Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1.6) Gecko/20091201 Firefox/3.5.6 |
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] [bug #29774] prologue/epilogue stack pointer manipulation not interrupt safe in XMega,
Matthew Vernon <=