[PATCH] Support for R_ARM_MOVW_BREL_NC et al.

Mark Shinwell shinwell@codesourcery.com
Wed Oct 18 00:49:00 GMT 2006


Mark Shinwell wrote:
> This patch provides support for the ARM relocations listed below.
> Tested on arm-none-linux-gnueabi.  OK?

Sorry, I failed to use the correct diff format.  Try again...

--

Index: bfd/elf32-arm.c
===================================================================
RCS file: /cvs/src/src/bfd/elf32-arm.c,v
retrieving revision 1.95
diff -U3 -p -r1.95 elf32-arm.c
--- bfd/elf32-arm.c     17 Oct 2006 15:46:21 -0000      1.95
+++ bfd/elf32-arm.c     17 Oct 2006 16:01:00 -0000
@@ -4832,6 +4832,13 @@ elf32_arm_final_link_relocate (reloc_how
      case R_ARM_MOVT_ABS:
      case R_ARM_MOVW_PREL_NC:
      case R_ARM_MOVT_PREL:
+    /* Until we properly support segment-base-relative addressing then
+       we assume the segment base to be zero, as for the group relocations.
+       Thus R_ARM_MOVW_BREL_NC has the same semantics as R_ARM_MOVW_ABS_NC
+       and R_ARM_MOVT_BREL has the same semantics as R_ARM_MOVT_ABS.  */
+    case R_ARM_MOVW_BREL_NC:
+    case R_ARM_MOVW_BREL:
+    case R_ARM_MOVT_BREL:
        {
         bfd_vma insn = bfd_get_32 (input_bfd, hit_data);

@@ -4840,15 +4847,21 @@ elf32_arm_final_link_relocate (reloc_how
             addend = ((insn >> 4) & 0xf000) | (insn & 0xfff);
             signed_addend = (addend ^ 0x10000) - 0x10000;
           }
+
         value += signed_addend;
-       if (sym_flags == STT_ARM_TFUNC)
-         value |= 1;

         if (r_type == R_ARM_MOVW_PREL_NC || r_type == R_ARM_MOVT_PREL)
           value -= (input_section->output_section->vma
                     + input_section->output_offset + rel->r_offset);

-       if (r_type == R_ARM_MOVT_ABS || r_type == R_ARM_MOVT_PREL)
+       if (r_type == R_ARM_MOVW_BREL && value >= 0x10000)
+          return bfd_reloc_overflow;
+
+       if (sym_flags == STT_ARM_TFUNC)
+         value |= 1;
+
+       if (r_type == R_ARM_MOVT_ABS || r_type == R_ARM_MOVT_PREL
+            || r_type == R_ARM_MOVT_BREL)
           value >>= 16;

         insn &= 0xfff0f000;
@@ -4862,6 +4875,14 @@ elf32_arm_final_link_relocate (reloc_how
      case R_ARM_THM_MOVT_ABS:
      case R_ARM_THM_MOVW_PREL_NC:
      case R_ARM_THM_MOVT_PREL:
+    /* Until we properly support segment-base-relative addressing then
+       we assume the segment base to be zero, as for the above relocations.
+       Thus R_ARM_THM_MOVW_BREL_NC has the same semantics as
+       R_ARM_THM_MOVW_ABS_NC and R_ARM_THM_MOVT_BREL has the same semantics
+       as R_ARM_THM_MOVT_ABS.  */
+    case R_ARM_THM_MOVW_BREL_NC:
+    case R_ARM_THM_MOVW_BREL:
+    case R_ARM_THM_MOVT_BREL:
        {
         bfd_vma insn;

@@ -4876,15 +4897,21 @@ elf32_arm_final_link_relocate (reloc_how
                    | (insn         & 0x00ff);
             signed_addend = (addend ^ 0x10000) - 0x10000;
           }
+
         value += signed_addend;
-       if (sym_flags == STT_ARM_TFUNC)
-         value |= 1;

         if (r_type == R_ARM_THM_MOVW_PREL_NC || r_type == R_ARM_THM_MOVT_PREL)
           value -= (input_section->output_section->vma
                     + input_section->output_offset + rel->r_offset);

-       if (r_type == R_ARM_THM_MOVT_ABS || r_type == R_ARM_THM_MOVT_PREL)
+       if (r_type == R_ARM_THM_MOVW_BREL && value >= 0x10000)
+          return bfd_reloc_overflow;
+
+       if (sym_flags == STT_ARM_TFUNC)
+         value |= 1;
+
+       if (r_type == R_ARM_THM_MOVT_ABS || r_type == R_ARM_THM_MOVT_PREL
+            || r_type == R_ARM_THM_MOVT_BREL)
           value >>= 16;

         insn &= 0xfbf08f00;



More information about the Binutils mailing list