https://sourceware.org/bugzilla/show_bug.cgi?id=21458
Bug ID: 21458 Summary: ld generates none ARM elf ABI compliant code that causes a hard fault. Product: binutils Version: 2.29 (HEAD) Status: UNCONFIRMED Severity: normal Priority: P2 Component: ld Assignee: unassigned at sourceware dot org Reporter: Andrewgoedhart at gmail dot com Target Milestone: --- According to the ELF for the ARM Architecture ABI r2.10 (http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ihi0044f/index.html) the relocation R_ARM_THM_ALU_PREL_10_0 needs to generate code according to: 53 R_ARM_THM_ALU_PREL_11_0 Static Thumb32 ((S + A) | T) – Pa This means that if the SYMBOL is of type STT_FUNC and the code is thumb, the LSb of the loaded value needs to be set. This is not done in the current code. GCC seems not to use this relocation when generating function pointers to thumb code but IAR does. when linking GCC code to an IAR library containing this the linked code HARD faults. Code Analysis ------------- In elf32-arm.c On reading in the symbols and mangling them via elf32_arm_swap_symbol_in, the test is done for STT_FUNC and the LSb of the symbol value being set. The LSb of the symbol is then cleared. /* 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) { if (dst->st_value & 1) { dst->st_value &= ~(bfd_vma) 1; ARM_SET_SYM_BRANCH_TYPE (dst->st_target_internal, ST_BRANCH_TO_THUMB); } else ARM_SET_SYM_BRANCH_TYPE (dst->st_target_internal, ST_BRANCH_TO_ARM); } No check is made and the LSb of the value is not set, for a branch types of ST_BRANCH_TO_ARM in the function generating the relocations: elf32_arm_final_link_relocate(), case R_ARM_THM_ALU_PREL_11_0: Test Case --------- The object file G3_LIB.o (attched) contains three symbols: 97: 00000469 26 FUNC LOCAL DEFAULT 12 G3_LIB_UpdateTablesEvent_15Sec 98: 0000044d 26 FUNC LOCAL DEFAULT 12 G3_LIB_UpdateTablesEvent_Minute 99: 00000485 22 FUNC LOCAL DEFAULT 12 G3_LIB_UpdateTablesEvent_TwoSec When linking in function g3_timed_events_init() the above symbols are used to generate function pointers with even addresses that later are called causing a hard fault. Disassembly on the hardware device showing the invalid thumb addresses being generated at addresses 0xd720, 0xd738, 0xd752 ?Subroutine5: 0000d710: 0x00000192 str r2, [sp, #4] 0000d712: 0x00000023 movs r3, #0 0000d714: 0x43f69822 movw r2, #15000 ; 0x3a98 0000d718: 0x00000092 str r2, [sp, #0] 0000d71a: 0x00008218 adds r2, r0, r2 0000d71c: 0x00004b41 adcs r3, r1 0000d71e: 0x00000021 movs r1, #0 0000d720: 0x0ff27400 addw r0, pc, #116 ; 0x74 0000d724: 0x0ef023b9 b.w 0x1b96e <g3_timed_events_add> ?Subroutine4: 0000d728: 0x00000192 str r2, [sp, #4] 0000d72a: 0x00000023 movs r3, #0 0000d72c: 0x4ef66022 movw r2, #60000 ; 0xea60 0000d730: 0x00000092 str r2, [sp, #0] 0000d732: 0x00008218 adds r2, r0, r2 0000d734: 0x00004b41 adcs r3, r1 0000d736: 0x00000021 movs r1, #0 0000d738: 0x0ff24000 addw r0, pc, #64 ; 0x40 0000d73c: 0x0ef017b9 b.w 0x1b96e <g3_timed_events_add> ?Subroutine3: 0000d740: 0x00000192 str r2, [sp, #4] 0000d742: 0x4ff4fa62 mov.w r2, #2000 ; 0x7d0 0000d746: 0x00000092 str r2, [sp, #0] 0000d748: 0x10f5fa62 adds.w r2, r0, #2000 ; 0x7d0 0000d74c: 0x41f10003 adc.w r3, r1, #0 0000d750: 0x00000021 movs r1, #0 0000d752: 0x0ff26000 addw r0, pc, #96 ; 0x60 0000d756: 0x0ef00ab9 b.w 0x1b96e <g3_timed_events_add> Unfortunately I don't have the code or the IAR compiler to generate a simpler test object file. It was supplied as a compiled library from which I extracted the G3_LIB.o after tracing the cause of the hard fault on a CortexM4 based processor. PATCH ----- The disassembly of the linked code after applying the patch: ?Subroutine5: 0000d710: 0x00000192 str r2, [sp, #4] 0000d712: 0x00000023 movs r3, #0 0000d714: 0x43f69822 movw r2, #15000 ; 0x3a98 0000d718: 0x00000092 str r2, [sp, #0] 0000d71a: 0x00008218 adds r2, r0, r2 0000d71c: 0x00004b41 adcs r3, r1 0000d71e: 0x00000021 movs r1, #0 0000d720: 0x0ff27500 addw r0, pc, #117 ; 0x75 0000d724: 0x0ef023b9 b.w 0x1b96e <g3_timed_events_add> ?Subroutine4: 0000d728: 0x00000192 str r2, [sp, #4] 0000d72a: 0x00000023 movs r3, #0 0000d72c: 0x4ef66022 movw r2, #60000 ; 0xea60 0000d730: 0x00000092 str r2, [sp, #0] 0000d732: 0x00008218 adds r2, r0, r2 0000d734: 0x00004b41 adcs r3, r1 0000d736: 0x00000021 movs r1, #0 0000d738: 0x0ff24100 addw r0, pc, #65 ; 0x41 0000d73c: 0x0ef017b9 b.w 0x1b96e <g3_timed_events_add> ?Subroutine3: 0000d740: 0x00000192 str r2, [sp, #4] 0000d742: 0x4ff4fa62 mov.w r2, #2000 ; 0x7d0 0000d746: 0x00000092 str r2, [sp, #0] 0000d748: 0x10f5fa62 adds.w r2, r0, #2000 ; 0x7d0 0000d74c: 0x41f10003 adc.w r3, r1, #0 0000d750: 0x00000021 movs r1, #0 0000d752: 0x0ff26100 addw r0, pc, #97 ; 0x61 0000d756: 0x0ef00ab9 b.w 0x1b96e <g3_timed_events_add> The GIT patch off 2.29 to fix the problem is: From 962abfea5b59dc8ec7f5dc0e1c38704aac0094e3 Mon Sep 17 00:00:00 2001 From: Andrew Goedhart <andrewgoedh...@simplepowersolutions.co.za> Date: Thu, 4 May 2017 02:17:54 +0200 Subject: [PATCH] Fix R_ARM_THM_ALU_PREL relocation to conform to ARM elf abi set thumb bit on branch to thumb code --- bfd/elf32-arm.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/bfd/elf32-arm.c b/bfd/elf32-arm.c index 434649f..9acd9c7 100644 --- a/bfd/elf32-arm.c +++ b/bfd/elf32-arm.c @@ -10508,6 +10508,10 @@ elf32_arm_final_link_relocate (reloc_howto_type * howto, value = relocation; + if ( branch_type == ST_BRANCH_TO_THUMB){ + value |= 1; + } + if (value >= 0x1000) return bfd_reloc_overflow; -- 2.9.3 -- You are receiving this mail because: You are on the CC list for the bug. _______________________________________________ bug-binutils mailing list bug-binutils@gnu.org https://lists.gnu.org/mailman/listinfo/bug-binutils