Because the symbol arm_lock32 is exported, gas is refusing to resolve the
offset at assembly time. Since it has no way of representing the
relocation in the object file it is then generating an error. You can
work around the problem by defining an alternative local symbol as follows:
.thumb
.globl arm_lock
.globl arm_lock32
arm_lock:
adr r0,.Larm_lock32_internal
bx r0
.align 2
.arm
arm_lock32:
.Larm_lock32_internal:
Note, if all you want to do is switch to ARM state from thumb state (eg
add a Thumb veneer to an ARM function, then the following trick will also
work:
.thumb
.align 2
arm_lock:
bx pc // PC is (. + 4), bit 0 == 0, '.' is word aligned.
nop
.arm
arm_lock32:
...
Note that for this to work, the bx instruction must be word aligned (hence
the ".align 2" before the Thumb code sequence.
R.