I have a program(arm) and some instructions in there(disas by IDA):
.plt:000083F0 ADRL R12, 0x83F8
.plt:000083F8 LDR PC, [R12,#(off_90D8 - 0x83F8)
The instruction B sub_83D0
is PC relative. The instruction sequence,
.plt:000083F0 ADRL R12, 0x83F8
.plt:000083F8 LDR PC, [R12,#(off_90D8 - 0x83F8)]! ; sub_83D0
000090D8: D0 83 00 00
Is PC relative, but it jumps to an absolute address. Your assumption is that the link address is the runtime address. This is not always true, especially in bootstrap code which may relocate or enable an MMU.
The sequence above can run from any address and will transfer control to the absolute 0x83d0, the branch variant only changes the PC
by adding an offset. Ie,
PC = PC + (SignExtend) (immediate << 2);
An equivalent would be mov pc, #0x83D0
, but this will not fit the mov
immediates limitation of an 8bit rotated by a multiple of 2. You could try,
mov r12, #0x8300
orr pc, r12, #0xd0
but the code that is transferred to may also need the r12
value set to the older runtime address.