On Tue, Jun 8, 2010 at 2:22 PM, Stu Bell <sb...@dataplay.com> 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. ============ _______________________________________________ AVR-libc-dev mailing list AVR-libc-dev@nongnu.org http://lists.nongnu.org/mailman/listinfo/avr-libc-dev