bug-gnu-utils
[Top][All Lists]
Advanced

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

Handle R_ARM_THM_PC11 relocs


From: Nick Clifton
Subject: Handle R_ARM_THM_PC11 relocs
Date: 03 Jan 2002 14:17:27 +0000

Hi Guys,

  The ARM linker was not handling relocs for the Thumb branch
  instruction.  This patch fixes the problem.

Cheers
        Nick

2002-01-03  Nick Clifton  <address@hidden>

        * elf32-arm.h (elf32_arm_final_link_relocate): Handle
        R_ARM_THM_PC11 reloc.

Index: bfd/elf32-arm.h
===================================================================
RCS file: /cvs/src/src/bfd/elf32-arm.h,v
retrieving revision 1.68
diff -p -c -r1.68 elf32-arm.h
*** elf32-arm.h 2002/01/02 15:36:27     1.68
--- elf32-arm.h 2002/01/03 14:20:49
*************** elf32_arm_final_link_relocate (howto, in
*** 1499,1504 ****
--- 1499,1545 ----
        }
        break;
  
+     case R_ARM_THM_PC11:
+       /* Thumb B (branch) instruction).  */
+       {
+       bfd_vma        relocation;
+       bfd_signed_vma reloc_signed_max = (1 << (howto->bitsize - 1)) - 1;
+       bfd_signed_vma reloc_signed_min = ~ reloc_signed_max;
+       bfd_vma        check;
+       bfd_signed_vma signed_check;
+ 
+ #ifdef USE_REL
+       /* Need to refetch addend.  */
+       addend = bfd_get_16 (input_bfd, hit_data) & howto->src_mask;
+       /* ??? Need to determine shift amount from operand size.  */
+       addend >>= howto->rightshift;
+ #endif
+       relocation = value + addend;
+ 
+       relocation -= (input_section->output_section->vma
+                      + input_section->output_offset
+                      + rel->r_offset);
+ 
+       check = relocation >> howto->rightshift;
+ 
+       /* If this is a signed value, the rightshift just
+          dropped leading 1 bits (assuming twos complement).  */
+       if ((bfd_signed_vma) relocation >= 0)
+         signed_check = check;
+       else
+         signed_check = check | ~((bfd_vma) -1 >> howto->rightshift);
+ 
+       relocation |= (bfd_get_16 (input_bfd, hit_data) & (~ howto->dst_mask));
+  
+       bfd_put_16 (input_bfd, relocation, hit_data);
+ 
+       /* Assumes two's complement.  */
+       if (signed_check > reloc_signed_max || signed_check < reloc_signed_min)
+         return bfd_reloc_overflow;
+ 
+       return bfd_reloc_ok;
+       }
+       
      case R_ARM_GNU_VTINHERIT:
      case R_ARM_GNU_VTENTRY:
        return bfd_reloc_ok;




reply via email to

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