If one wants to have call bad_isr instead of jmp bad_isr in the vector table, there are two issues:
generating code that can use the return address and getting the call bad_isr into the vector table.
Here is code for the former:
.global bad_isr_save, bad_isr_ret, bad_isr_wrap bad_isr_wrap: STS bad_isr_save, R0 POP R0 POP R0 STS bad_isr_ret JMP bad_isr
bad_isr and the definitions for bad_isr_save and bad_isr_ret can be written C.
bad_isr can use isr_ret.
The assembly from which the new vector table is to be partially derived is simple:
.rept 100 XCALL bad_isr_wrap .endr
Link it as follows:
avr-ld -o vectors.elf vectors.o --symbols-only application.elf
Now the trick is to get the desired bits of vectors into application.
Which bits are desired can be found by processing application.lss with python or awk.
Look for 'jmp
Again using python or awk, that information can be used to generate an srec command to interleave application.hex and vectors.hex appropriately.