BZ #122: ARM: mismatch between codegenerator and address patcher when disp == 4096
The arm codegenerator created the following instructions:
pc[-2] 0x47736388: undefined
pc[-1] 0x4773638c: sub r12, r12, #4096 ; 0x1000
pc[ 0] 0x47736390: ldr r12, [r12]
pc[ 1] 0x47736394: mov lr, pc
pc[ 2] 0x47736398: mov pc, r12
By executing the code that handles ICMD_INOKESPECIAL. In my case the instruction is
unresolved and an entry in the dseg is created. The entry is 4096 byte before the
instruction, thus disp == 4096.
A patcher is created to handle that.
When the md_jit_method_patch_address function runs it falls into this case:
if (M_MEM_GET_Rbase(mcode) == REG_PV && (mcode & 0x00800000) == 0x00800000)
(mcode is pc)
Inside this case another if is run:
if ((mcode & 0xffffff00) == 0xe28bca00)
disp += (int32_t) ((mcode & 0x00ff) << 12);
vm_abort_disassemble(pc - 1, 4, "md_jit_method_patch_address: unknown instruction %x",
(where mcode is pc[-1])
The code expects an 'add' instruction and as such it will fail for me since pc[-1] is
clearly a 'sub'.
The problem happens in a very large method (MetalLookAndFeel.initComponentDefaults) and
only in my JIT cache implementation. However I have not changed anything in the
codegeneration that should affect this. One reason I think why this affects me is that I
am using more dseg entries than normally.
Still I believe that this is a bug in either the codegenerator or the
The easiest solution I can think of is to add an if-clause which checks whether the
instruction at pc[-1] is a 'sub' and if so interprets this as a large offset which needs
to be substracted from PV.