This is the mail archive of the binutils@sourceware.org mailing list for the binutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH] PREL_11_0 and PC12 Thumb-2 relocations


Here is bfd support for the ARM Thumb-2 PREL_11_0 and PC12 relocs.
At this stage gas support is not provided, but that is a QoI issue
rather than an EABI-compliance issue.

Since gas support is lacking, this patch has been tested manually.
Anyone who is interested can see the details of that testing below.

OK?

Mark

--

2006-08-31 Mark Shinwell <shinwell@codesourcery.com>

        bfd/
        * elf32-arm.c (elf32_arm_howto_table_1): Adjust entries for
        R_ARM_THM_ALU_PREL_11_0 and R_ARM_THM_PC12 relocations.
        (elf32_arm_final_link_relocate): Handle R_ARM_THM_ALU_PREL_11_0
        and R_ARM_THM_PC12 relocations.

--

Testing of PREL_11_0
--------------------

I've tested this by using a hex editor to construct an object that dumps
thus:

test.o: file format elf32-littlearm

Disassembly of section .text:

00000000 <_start>:
    0:   f60f 0000       addw    r0, pc, #2048
                         0: R_ARM_THM_ALU_PREL_11_0      f
    4:   f6af 0000       subw    r0, pc, #2048
                         4: R_ARM_THM_ALU_PREL_11_0      f
    8:   f60f 0000       addw    r0, pc, #2048
                         8: R_ARM_THM_ALU_PREL_11_0      g
    c:   f6af 0000       subw    r0, pc, #2048
                         c: R_ARM_THM_ALU_PREL_11_0      g
Disassembly of section .after:

00000000 <f>:
    0:   f240 0000       movw    r0, #0  ; 0x0
Disassembly of section .before:

00000000 <g>:
    0:   f240 0000       movw    r0, #0  ; 0x0

Then we link this with:

-Ttext 0x8000 --section-start .after=0x87fc --section-start .before=0x7900

and the resulting executable is as follows:

test: file format elf32-littlearm

Disassembly of section .text:

00008000 <_start>:
     8000:       f60f 70fc       addw    r0, pc, #4092   ; 0xffc
     8004:       f2af 0008       subw    r0, pc, #8      ; 0x8
     8008:       f20f 00f8       addw    r0, pc, #248    ; 0xf8
     800c:       f6af 700c       subw    r0, pc, #3852   ; 0xf0c
Disassembly of section .after:

000087fc <f>:
     87fc:       f240 0000       movw    r0, #0  ; 0x0
Disassembly of section .before:

00007900 <g>:
     7900:       f240 0000       movw    r0, #0  ; 0x0

Setting --section-start .after=0x8800 yields an overflow as expected.

Testing of PC12
---------------

Again a hex editor was used, this time to construct the following:

test-ldr.o: file format elf32-littlearm

Disassembly of section .text:

00000000 <_start>:
    0:   f8df 0800       ldr.w   r0, [pc, #2048]
                         0: R_ARM_THM_PC12       f
    4:   f85f 0800       ldr.w   r0, [pc, #-2048]
                         4: R_ARM_THM_PC12       f
    8:   f8df 0800       ldr.w   r0, [pc, #2048]
                         8: R_ARM_THM_PC12       g
    c:   f85f 0800       ldr.w   r0, [pc, #-2048]
                         c: R_ARM_THM_PC12       g
Disassembly of section .after:

00000000 <f>:
    0:   f240 0000       movw    r0, #0  ; 0x0
Disassembly of section .before:

00000000 <g>:
    0:   f240 0000       movw    r0, #0  ; 0x0

Linking this as above we end up with:

test-ldr: file format elf32-littlearm

Disassembly of section .text:

00008000 <_start>:
     8000:       f8df 0ffc       ldr.w   r0, [pc, #4092]
     8004:       f85f 0008       ldr.w   r0, [pc, #-8]
     8008:       f8df 00f8       ldr.w   r0, [pc, #248]
     800c:       f85f 0f0c       ldr.w   r0, [pc, #-3852]
Disassembly of section .after:

000087fc <f>:
     87fc:       f240 0000       movw    r0, #0  ; 0x0
Disassembly of section .before:

00007900 <g>:
     7900:       f240 0000       movw    r0, #0  ; 0x0

Again, placing .after at 0x8800 yields an overflow.

Index: bfd/elf32-arm.c
===================================================================
RCS file: /cvs/src/src/bfd/elf32-arm.c,v
retrieving revision 1.70.2.12
diff -U3 -p -r1.70.2.12 elf32-arm.c
--- bfd/elf32-arm.c	30 Aug 2006 17:39:17 -0000	1.70.2.12
+++ bfd/elf32-arm.c	31 Aug 2006 11:15:13 -0000
@@ -834,12 +834,12 @@ static reloc_howto_type elf32_arm_howto_
 	 13,			/* bitsize */
 	 TRUE,			/* pc_relative */
 	 0,			/* bitpos */
-	 complain_overflow_signed,/* complain_on_overflow */
+	 complain_overflow_dont,/* complain_on_overflow */
 	 bfd_elf_generic_reloc,	/* special_function */
 	 "R_ARM_THM_ALU_PREL_11_0",/* name */
 	 FALSE,			/* partial_inplace */
-	 0x040070ff,		/* src_mask */
-	 0x040070ff,		/* dst_mask */
+	 0xffffffff,		/* src_mask */
+	 0xffffffff,		/* dst_mask */
 	 TRUE),			/* pcrel_offset */
 
   HOWTO (R_ARM_THM_PC12,	/* type */
@@ -848,12 +848,12 @@ static reloc_howto_type elf32_arm_howto_
 	 13,			/* bitsize */
 	 TRUE,			/* pc_relative */
 	 0,			/* bitpos */
-	 complain_overflow_signed,/* complain_on_overflow */
+	 complain_overflow_dont,/* complain_on_overflow */
 	 bfd_elf_generic_reloc,	/* special_function */
 	 "R_ARM_THM_PC12",	/* name */
 	 FALSE,			/* partial_inplace */
-	 0x040070ff,		/* src_mask */
-	 0x040070ff,		/* dst_mask */
+	 0x0fffffff,		/* src_mask */
+	 0x0fffffff,		/* dst_mask */
 	 TRUE),			/* pcrel_offset */
 
   HOWTO (R_ARM_ABS32_NOI,	/* type */
@@ -3958,6 +3958,81 @@ elf32_arm_final_link_relocate (reloc_how
       bfd_put_16 (input_bfd, value, hit_data);
       return bfd_reloc_ok;
 
+    case R_ARM_THM_ALU_PREL_11_0:
+      /* Corresponds to: addw.w reg, pc, #offset (and similarly for subw).  */
+      {
+	bfd_vma insn;
+	bfd_signed_vma relocation;
+
+	insn = (bfd_get_16 (input_bfd, hit_data) << 16)
+             | bfd_get_16 (input_bfd, hit_data + 2);
+
+        if (globals->use_rel)
+          {
+            signed_addend = (insn & 0xff) | ((insn & 0x7000) >> 4)
+                          | ((insn & (1 << 26)) >> 15);
+            if (insn & 0xf00000)
+              signed_addend = -signed_addend;
+          }
+
+	relocation = value + signed_addend;
+	relocation -= (input_section->output_section->vma
+		       + input_section->output_offset
+		       + rel->r_offset);
+
+        value = abs (relocation);
+
+        if (value >= 0x1000)
+          return bfd_reloc_overflow;
+
+	insn = (insn & 0xfb0f8f00) | (value & 0xff)
+             | ((value & 0x700) << 4)
+             | ((value & 0x800) << 15);
+        if (relocation < 0)
+          insn |= 0xa00000;
+
+	bfd_put_16 (input_bfd, insn >> 16, hit_data);
+	bfd_put_16 (input_bfd, insn & 0xffff, hit_data + 2);
+
+        return bfd_reloc_ok;
+      }
+
+    case R_ARM_THM_PC12:
+      /* Corresponds to: ldr.w reg, [pc, #offset].  */
+      {
+	bfd_vma insn;
+	bfd_signed_vma relocation;
+
+	insn = (bfd_get_16 (input_bfd, hit_data) << 16)
+             | bfd_get_16 (input_bfd, hit_data + 2);
+
+        if (globals->use_rel)
+          {
+            signed_addend = insn & 0xfff;
+            if (!(insn & (1 << 23)))
+              signed_addend = -signed_addend;
+          }
+
+	relocation = value + signed_addend;
+	relocation -= (input_section->output_section->vma
+		       + input_section->output_offset
+		       + rel->r_offset);
+
+        value = abs (relocation);
+
+        if (value >= 0x1000)
+          return bfd_reloc_overflow;
+
+	insn = (insn & 0xff7ff000) | value;
+        if (relocation >= 0)
+          insn |= (1 << 23);
+
+	bfd_put_16 (input_bfd, insn >> 16, hit_data);
+	bfd_put_16 (input_bfd, insn & 0xffff, hit_data + 2);
+
+        return bfd_reloc_ok;
+      }
+
     case R_ARM_THM_XPC22:
     case R_ARM_THM_CALL:
       /* Thumb BL (branch long instruction).  */

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]