The routine subs pc, lr, #4 arrow to the recorder PC the value of the recorder LR (which as mentioned is zero) minus the immediate #4 that is, in the next cycle the processor should summarize the execution from LR - 4 which is an invalid address, so the SEGFAULT.
Steps to be taken to safely enable interruptions IRQ described in ARM documentation sane:
- Build the return address and save it to the mode stack
IRQ.
- Save the required registers and the
SPSR in the way IRQ.
- Identify and clear source of interruption.
- Switch to mode
System keeping the IRQs disabled.
- Check that the stack is aligned to eight bytes and adjust if necessary.
- Save the
LR in the way User and the adjustment, 0 or 4 for ARMv4 or ARMv5TE, used in the SP in the way User.
- Enable interruptions and call interrupt handler function.
- When the handler function returns, disable interruptions.
- Restore the
LR in the way User and the stack setting value.
- Reset the battery if necessary.
- Switch to mode
IRQ.
- Restore the other registers and the
SPSR in the way IRQ.
- Return from
IRQ.
In short: make sure you’re using the value of LR in the right way and that is not overwriting anywhere.
Important: The return of an interruption is different of the return of a function because the PC saves the address of the next instruction to be executed and in an exception/interruption the value of PC is copied to LR_<mode> then if you jumped to that value the instruction referenced by this address would never be executed, so that’s the subtraction (LR - 4).