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] Fix Thumb-2 JUMP19 relocation


The current handling of the Thumb-2 JUMP19 relocation (used for
certain conditional branches) is rather broken.  There are several
errors, one particularly subtle one being the incorrect use of ~
rather than ! when performing a sign extension.

This patch fixes the problems; I also hope it makes the code a
bit easier to understand.  OK to apply?

Mark

--


2007-05-05 Mark Shinwell <shinwell@codesourcery.com>


	bfd/
	* elf32-arm.c (elf32_arm_final_link_relocate): Correctly
	handle the Thumb-2 JUMP19 relocation.

	ld/testsuite/
	* ld-arm/arm-elf.exp: Add jump19 testcase.
	* ld-arm/jump19.d: New.
	* ld-arm/jump19.s: New.


Index: bfd/elf32-arm.c
===================================================================
RCS file: /cvs/src/src/bfd/elf32-arm.c,v
retrieving revision 1.112
diff -U3 -p -r1.112 elf32-arm.c
--- bfd/elf32-arm.c 3 May 2007 19:27:14 -0000 1.112
+++ bfd/elf32-arm.c 5 May 2007 13:41:29 -0000
@@ -5205,9 +5205,8 @@ elf32_arm_final_link_relocate (reloc_how
bfd_boolean overflow = FALSE;
bfd_vma upper_insn = bfd_get_16 (input_bfd, hit_data);
bfd_vma lower_insn = bfd_get_16 (input_bfd, hit_data + 2);
- bfd_signed_vma reloc_signed_max = ((1 << (howto->bitsize - 1)) - 1) >> howto->rightshift;
- bfd_signed_vma reloc_signed_min = ~ reloc_signed_max;
- bfd_vma check;
+ bfd_signed_vma reloc_signed_max = 0xffffe;
+ bfd_signed_vma reloc_signed_min = -0x100000;
bfd_signed_vma signed_check;


        /* Need to refetch the addend, reconstruct the top three bits,
@@ -5215,14 +5214,14 @@ elf32_arm_final_link_relocate (reloc_how
        if (globals->use_rel)
          {
            bfd_vma S     = (upper_insn & 0x0400) >> 10;
-           bfd_vma upper = (upper_insn & 0x001f);
+           bfd_vma upper = (upper_insn & 0x003f);
            bfd_vma J1    = (lower_insn & 0x2000) >> 13;
            bfd_vma J2    = (lower_insn & 0x0800) >> 11;
            bfd_vma lower = (lower_insn & 0x07ff);

-           upper |= J2 << 6;
-           upper |= J1 << 7;
-           upper |= ~S << 8;
+           upper |= J1 << 6;
+           upper |= J2 << 7;
+           upper |= (!S) << 8;
            upper -= 0x0100; /* Sign extend.  */

            addend = (upper << 12) | (lower << 1);
@@ -5236,17 +5235,8 @@ elf32_arm_final_link_relocate (reloc_how
        relocation -= (input_section->output_section->vma
                       + input_section->output_offset
                       + rel->r_offset);
+       signed_check = (bfd_signed_vma) relocation;

- 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);
-
- /* Assumes two's complement. */
if (signed_check > reloc_signed_max || signed_check < reloc_signed_min)
overflow = TRUE;


@@ -5258,7 +5248,7 @@ elf32_arm_final_link_relocate (reloc_how
          bfd_vma hi = (relocation & 0x0003f000) >> 12;
          bfd_vma lo = (relocation & 0x00000ffe) >>  1;

-         upper_insn = (upper_insn & 0xfb30) | (S << 10) | hi;
+         upper_insn = (upper_insn & 0xfbc0) | (S << 10) | hi;
          lower_insn = (lower_insn & 0xd000) | (J1 << 13) | (J2 << 11) | lo;
        }
Index: ld/testsuite/ld-arm/arm-elf.exp
===================================================================
RCS file: /cvs/src/src/ld/testsuite/ld-arm/arm-elf.exp,v
retrieving revision 1.23
diff -U3 -p -r1.23 arm-elf.exp
--- ld/testsuite/ld-arm/arm-elf.exp     17 Apr 2007 20:09:52 -0000      1.23
+++ ld/testsuite/ld-arm/arm-elf.exp     5 May 2007 13:41:30 -0000
@@ -163,6 +163,9 @@ set armelftests {
      {preempt-app.s}
      {{readelf -Ds preempt-app.sym}}
      "preempt-app"}
+     {"jump19" "-static -T arm.ld" "" {jump19.s}
+      {{objdump -dr jump19.d}}
+      "jump19"}
 }

 run_ld_link_tests $armelftests
Index: ld/testsuite/ld-arm/jump19.d
===================================================================
RCS file: ld/testsuite/ld-arm/jump19.d
diff -N ld/testsuite/ld-arm/jump19.d
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ ld/testsuite/ld-arm/jump19.d        5 May 2007 13:41:30 -0000
@@ -0,0 +1,12 @@
+
+.*jump19:     file format elf32-(big|little)arm
+
+Disassembly of section .text:
+
+00008000 <_start>:
+    8000:      4280            cmp     r0, r0
+    8002:      f010 8000       beq.w   18006 <bar>
+       ...
+
+00018006 <bar>:
+   18006:      4770            bx      lr
Index: ld/testsuite/ld-arm/jump19.s
===================================================================
RCS file: ld/testsuite/ld-arm/jump19.s
diff -N ld/testsuite/ld-arm/jump19.s
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ ld/testsuite/ld-arm/jump19.s        5 May 2007 13:41:30 -0000
@@ -0,0 +1,12 @@
+@ Test the Thumb-2 JUMP19 relocation.
+
+       .syntax unified
+       .thumb
+       .global _start
+_start:
+       cmp     r0, r0
+       beq.w   bar
+       .space 65536
+       .weak bar
+bar:
+       bx      lr


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