bug-binutils
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Bug ld/21458] New: ld generates none ARM elf ABI compliant code that ca


From: Andrewgoedhart at gmail dot com
Subject: [Bug ld/21458] New: ld generates none ARM elf ABI compliant code that causes a hard fault.
Date: Thu, 04 May 2017 00:58:31 +0000

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 <address@hidden>
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.


reply via email to

[Prev in Thread] Current Thread [Next in Thread]