https://gcc.gnu.org/bugzilla/show_bug.cgi?id=89222
--- Comment #6 from Jonathan Larmour <jifl-bugzilla at jifvik dot org> --- Just to confirm with concrete values from a real program: myhandler2() is at 0x200003a8 (which means the branch target address if the function is called should be 0x200003a9 with LS bit set to indicate Thumb). The assembler inserts an R_ARM_ABS32 reloc for the symbol myhandler2 with addend of -1, and the linker sets the value at .L22 to 0x200003a7, i.e. what is then loaded into r5 in the disassembly I provided. If I manually edit the asm to use "myhandler2" in place of "myhandler2-1" then the linker puts in 0x200003a9 instead. If I use "myhandler2-2" in place of "myhandler2-1" then the linker puts in 0x200003a7, same as the "myhandler2-1" case. So I infer that if the reloc is an offset of a *function* symbol, the behaviour of the linker is to compute the value and then always set the LS bit in the result. This matches the ABI at: http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.subset.swdev.abi/index.html specifically 4.6.1.1 (page 26) where the table indicates that R_ARM_ABS32 should be handled as "(S + A ) | T" where "T is 1 if the target symbol S has type STT_FUNC and the Symbol addresses a Thumb instruction; it is 0 otherwise." So it looks to me like the linker is right and GCC is mistaken. Wilco is exactly right that you shouldn't do arithmetic with function symbols, at least if there's any chance that the symbol is Thumb.