[llvm-bugs] [Bug 47253] New: [AVR] Interrupt stack pointer and register corruption

via llvm-bugs llvm-bugs at lists.llvm.org
Thu Aug 20 06:48:32 PDT 2020


https://bugs.llvm.org/show_bug.cgi?id=47253

            Bug ID: 47253
           Summary: [AVR] Interrupt stack pointer and register corruption
           Product: new-bugs
           Version: unspecified
          Hardware: PC
                OS: Linux
            Status: NEW
          Severity: normal
          Priority: P
         Component: new bugs
          Assignee: unassignedbugs at nondot.org
          Reporter: hi at andrewcou.ch
                CC: htmldeveloper at gmail.com, llvm-bugs at lists.llvm.org

I have identified a reliable corruption of the stack pointer in interrupts on
the AVR platform.  Compiling any interrupt handler with a non-zero frame size
produces the bug.

A minimal Rust reproduction can be found on the original Rust issue where I
identified the bug: https://github.com/rust-lang/rust/issues/75504  I believe
the following IR will produce the issue, though I haven't yet tested it as I'm
running into toolchain issues.


define avr_signalcc void @__vector_0() unnamed_addr addrspace(1) #0 {
start:
  %item = alloca i8, align 1
  ret void
}

attributes #0 = { nounwind writeonly }


The end of the assembler generated by a problematic ISR is:


        pop     r29
        pop     r28
        pop     r25
        pop     r24
        pop     r0
        out     63, r0
        adiw    r28, 1
        in      r0, 63
        cli
        out     62, r29
        out     63, r0
        out     61, r28
        pop     r1
        pop     r0
        reti


Note that the callee-saved registers are popped BEFORE restoring the stack
pointer, so the wrong value will be used in the calculation, and we corrupt r0,
r28, and r29 in the process.

The bug seems to be in AVRFrameLowering::emitEpilogue.  That routine first
inserts machine instructions to restore R0, R1, and SREG (lines 157-161), then
attempts to skip the callee-saved pop instructions (lines 170-176).  However,
it immediately sees the AVR::OUTARr (out 63, r0) that was inserted a few lines
above.  It stops there, presuming this to be the end of the callee-saved
register pop sequence, and inserts the frame pointer code AFTER the relevant
registers have already been restored, rather than before.

The tip commit is currently 445739826567e5402b558f2c130d76dc916c82ec.  The
relevant sections of the code have not been modified since
192405a31a8125ec4454ec5471b2506aaef5b81e.

-- 
You are receiving this mail because:
You are on the CC list for the bug.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-bugs/attachments/20200820/e34f303f/attachment-0001.html>


More information about the llvm-bugs mailing list