Lockup when executing relocated ISR in ARM Cortex-M0+
I just wanted to post a followup since I fixed the problem. It doesn't match any existing answer, but that's because it was from an unexpected source.

I was thinking about how exactly the NVIC stores the context since that seems to be the moment that causes things to go nuts and I realized that it likely uses the stack.

I execute the following sequence in SWD when loading my program (its likely not the best way to do it, but its a work in progress):


Enable debug in DHCSR
Enable reset catch in DEMCR
Clear any reset flag in DHCSR
Use AIRCR to request a reset and wait for it to occur by polling DHCSR. The processor is now halted just after a reset occurs. The VTOR is now 0x0, register 15 now points to 0xffffffff since the flash (located at 0x0) is unprogrammed), ...and the stack pointer is also 0xffffffff (didn't realize this until now)
Use the AHB-AP to load the program
Set the VTOR to point to the new VTOR in my program. Set register 15 to the start of the reset routine in my code (whose address is found at VTOR+4).
Unhalt the processor and let it run.


The processor would then run until the first interrupt. My realization was that since I had neglected to set the stack pointer during step 6 and it was still pointing to somewhere outside of RAM, the NVIC likely had nowhere to save the context and probably caused a fault. This would eventually let the WDT go off since it just loops endlessly in those routines which would cause the VTOR to reset back to 0x0, then attempting to execute 0xffffffff (since that's what is at address 0x4) which would result in a LOCKUP.

By simply setting the stack pointer (register 14) to the top of my stack during step 6 above I fixed my problem.