This is the mail archive of the
binutils@sources.redhat.com
mailing list for the binutils project.
PATCH Add GOT and GOTOFF support for ARM/Thumb code symbols
- From: Richard Earnshaw <rearnsha at arm dot com>
- To: binutils at sources dot redhat dot com
- Cc: Richard dot Earnshaw at arm dot com, pb at nexus dot co dot uk
- Date: Tue, 19 Mar 2002 14:10:06 +0000
- Subject: PATCH Add GOT and GOTOFF support for ARM/Thumb code symbols
- Organization: ARM Ltd.
- Reply-to: Richard dot Earnshaw at arm dot com
If we are building a GOT entry for a Thumb symbol, or if we are generating
an offset from the GOT to a Thumb function, then we need to make sure that
the resulting pointer has bit[0] set. Otherwise, attempts to call the
function pointer will cause the processor to switch to ARM mode and hence
miss-execute the code.
I think I've found all the relevant parts to change, but I'm not familiar
with the linker code. Have I missed anything?
For -mthumb -fPIC, this fixes 75 failures in the gcc.c-torture tests of
the gcc testsuite (I never managed to get the g++ tests to complete before
adding this patch), and 152 failures in the GDB testsuite.
<date> Richard Earnshaw <rearnsha@arm.com>
* elf32-arm.h (elf32_arm_final_link_relocate case R_ARM_GOTOFF)
(case R_ARM_GOT): Handle relocations to Thumb functions.
Index: elf32-arm.h
===================================================================
RCS file: /cvs/src/src/bfd/elf32-arm.h,v
retrieving revision 1.76
diff -p -r1.76 elf32-arm.h
*** elf32-arm.h 2002/02/19 12:40:23 1.76
--- elf32-arm.h 2002/03/19 13:55:17
*************** elf32_arm_final_link_relocate (howto, in
*** 1560,1565 ****
--- 1560,1571 ----
if (sgot == NULL)
return bfd_reloc_notsupported;
+ /* If we are addressing a Thumb function, we need to adjust the
+ address by one, so that attempts to call the function pointer will
+ correctly interpret it as Thumb code. */
+ if (sym_flags == STT_ARM_TFUNC)
+ value += 1;
+
/* Note that sgot->output_offset is not involved in this
calculation. We always want the start of .got. If we
define _GLOBAL_OFFSET_TABLE in a different way, as is
*************** elf32_arm_final_link_relocate (howto, in
*** 1612,1617 ****
--- 1618,1630 ----
off &= ~1;
else
{
+ /* If we are addressing a Thumb function, we need to
+ adjust the address by one, so that attempts to
+ call the function pointer will correctly
+ interpret it as Thumb code. */
+ if (sym_flags == STT_ARM_TFUNC)
+ value |= 1;
+
bfd_put_32 (output_bfd, value, sgot->contents + off);
h->got.offset |= 1;
}