From 8dbc67a4ba883a79e955459e24a665b9f916abc1 Mon Sep 17 00:00:00 2001 From: Paul Brook Date: Tue, 31 May 2011 14:07:56 +0000 Subject: 2011-05-31 Paul Brook bfd/ * elf32-arm.c (elf32_arm_final_link_relocate): Only do bl conversion for known functions. (elf32_arm_swap_symbol_in): Only set ST_BRANCH_TO_ARM for function symbols. include/elf/ * arm.h (arm_st_branch_type): Add ST_BRANCH_UNKNOWN. ld/testsuite/ * ld-arm/cortex-a8-far.d: Adjust expected output. * ld-arm/arm-call1.s: Give function symbol correct type. * ld-arm/arm-call2.s: Ditto. * ld-arm/farcall-group4.s: Ditto. * ld-arm/arm-elf.exp (cortex-a8-far): Define far symbols with correct type via assembly file. * ld-arm/cortex-a8-far-3.s: New file. * ld-arm/abs-call-1.s: Add Thumb tests --- bfd/elf32-arm.c | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) (limited to 'bfd/elf32-arm.c') diff --git a/bfd/elf32-arm.c b/bfd/elf32-arm.c index 611e08ed142..58bb367780b 100644 --- a/bfd/elf32-arm.c +++ b/bfd/elf32-arm.c @@ -8304,7 +8304,7 @@ elf32_arm_final_link_relocate (reloc_howto_type * howto, case, mode switching is performed by the stub. */ if (branch_type == ST_BRANCH_TO_THUMB && !stub_entry) value |= (1 << 28); - else + else if (stub_entry || branch_type != ST_BRANCH_UNKNOWN) { value &= ~(bfd_vma)(1 << 28); value |= (1 << 24); @@ -15131,12 +15131,16 @@ elf32_arm_swap_symbol_in (bfd * abfd, /* New EABI objects mark thumb function symbols by setting the low bit of the address. */ - if ((ELF_ST_TYPE (dst->st_info) == STT_FUNC - || ELF_ST_TYPE (dst->st_info) == STT_GNU_IFUNC) - && (dst->st_value & 1)) + if (ELF_ST_TYPE (dst->st_info) == STT_FUNC + || ELF_ST_TYPE (dst->st_info) == STT_GNU_IFUNC) { - dst->st_value &= ~(bfd_vma) 1; - dst->st_target_internal = ST_BRANCH_TO_THUMB; + if (dst->st_value & 1) + { + dst->st_value &= ~(bfd_vma) 1; + dst->st_target_internal = ST_BRANCH_TO_THUMB; + } + else + dst->st_target_internal = ST_BRANCH_TO_ARM; } else if (ELF_ST_TYPE (dst->st_info) == STT_ARM_TFUNC) { @@ -15146,7 +15150,7 @@ elf32_arm_swap_symbol_in (bfd * abfd, else if (ELF_ST_TYPE (dst->st_info) == STT_SECTION) dst->st_target_internal = ST_BRANCH_LONG; else - dst->st_target_internal = ST_BRANCH_TO_ARM; + dst->st_target_internal = ST_BRANCH_UNKNOWN; return TRUE; } -- cgit v1.2.1