public inbox for binutils@sourceware.org
 help / color / mirror / Atom feed
From: Mark Shinwell <shinwell@codesourcery.com>
To: binutils@sourceware.org
Subject: [PATCH] Thumb-2 BL support for bfd
Date: Thu, 24 Aug 2006 15:48:00 -0000	[thread overview]
Message-ID: <44EDC478.2090103@codesourcery.com> (raw)

[-- Attachment #1: Type: text/plain, Size: 1100 bytes --]

Hello,

Here is the necessary bfd support for the exploitation of the extra
offset available when dealing with Thumb-2 BL instructions.  The
assembler does not require any further modifications to enable this
to be used, as can be seen from the testcases.  (A colleague commented
earlier that the sources of some of the test cases are very similar, but
I'd prefer to keep them separate so as to not mix up dump tests and the
other ones with explicit rules in arm-elf.exp.)

Tested on arm-none-linux-gnueabi.  OK?

Mark

--

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

	bfd/
	* elf32-arm.c (elf32_arm_howto_table_1): Change offset for
	R_THM_CALL to 25 and remove FIXME comment.
	(using_thumb2): New function.
	(elf32_arm_final_link_relocate): Cope with Thumb-2 BL encoding.

	ld/testsuite/
	* arm-elf.exp: Add thumb1-bl, thumb2-bl, thumb2-bl-as-thumb1-bad
	and thumb2-bl-bad tests.
	* thumb1-bl.d: New.
	* thumb1-bl.s: New.
	* thumb2-bl-as-thumb1-bad.d: New.
	* thumb2-bl-as-thumb1-bad.s: New.
	* thumb2-bl-bad.d: New.
	* thumb2-bl-bad.s: New.
	* thumb2-bl.d: New.
	* thumb2-bl.s: New.



[-- Attachment #2: thumb2-mainline.patch --]
[-- Type: text/plain, Size: 5727 bytes --]

Index: bfd/elf32-arm.c
===================================================================
RCS file: /cvs/src/src/bfd/elf32-arm.c,v
retrieving revision 1.87
diff -U3 -p -r1.87 elf32-arm.c
--- bfd/elf32-arm.c	22 Aug 2006 13:18:03 -0000	1.87
+++ bfd/elf32-arm.c	24 Aug 2006 15:05:41 -0000
@@ -217,11 +217,10 @@ static reloc_howto_type elf32_arm_howto_
 	 0xffffffff,		/* dst_mask */
 	 FALSE),		/* pcrel_offset */
 
-  /* FIXME: Has two more bits of offset in Thumb32.  */
   HOWTO (R_ARM_THM_CALL,	/* type */
 	 1,			/* rightshift */
 	 2,			/* size (0 = byte, 1 = short, 2 = long) */
-	 23,			/* bitsize */
+	 25,			/* bitsize */
 	 TRUE,			/* pc_relative */
 	 0,			/* bitpos */
 	 complain_overflow_signed,/* complain_on_overflow */
@@ -3534,6 +3533,14 @@ identify_add_or_sub(bfd_vma insn)
   return 0;
 }
 
+/* Determine if we're dealing with a Thumb-2 object.  */
+
+static int using_thumb2 (struct elf32_arm_link_hash_table *globals)
+{
+  int arch = elf32_arm_get_eabi_attr_int (globals->obfd, Tag_CPU_arch);
+  return arch == 8 || arch >= 10;
+}
+
 /* Perform a relocation as part of a final link.  */
 
 static bfd_reloc_status_type
@@ -3950,22 +3957,33 @@ elf32_arm_final_link_relocate (reloc_how
       /* Thumb BL (branch long instruction).  */
       {
 	bfd_vma relocation;
+        bfd_vma reloc_sign;
 	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_signed_vma reloc_signed_max;
+	bfd_signed_vma reloc_signed_min;
 	bfd_vma check;
 	bfd_signed_vma signed_check;
+	int bitsize;
+	int thumb2 = using_thumb2 (globals);
 
-	/* Need to refetch the addend and squish the two 11 bit pieces
-	   together.  */
+	/* Fetch the addend.  We use the Thumb-2 encoding (backwards compatible
+           with Thumb-1) involving the J1 and J2 bits.  */
 	if (globals->use_rel)
 	  {
-	    bfd_vma upper = upper_insn & 0x7ff;
-	    bfd_vma lower = lower_insn & 0x7ff;
-	    upper = (upper ^ 0x400) - 0x400; /* Sign extend.  */
-	    addend = (upper << 12) | (lower << 1);
+            bfd_vma s = (upper_insn & (1 << 10)) >> 10;
+            bfd_vma upper = upper_insn & 0x3ff;
+            bfd_vma lower = lower_insn & 0x7ff;
+	    bfd_vma j1 = (lower_insn & (1 << 13)) >> 13;
+	    bfd_vma j2 = (lower_insn & (1 << 11)) >> 11;
+            bfd_vma i1 = j1 ^ s ? 0 : 1;
+            bfd_vma i2 = j2 ^ s ? 0 : 1;
+
+            addend = (i1 << 23) | (i2 << 22) | (upper << 12) | (lower << 1);
+            /* Sign extend.  */
+            addend = (addend | ((s ? 0 : 1) << 24)) - (1 << 24);
+
 	    signed_addend = addend;
 	  }
 
@@ -4042,6 +4060,15 @@ elf32_arm_final_link_relocate (reloc_how
 	else
 	  signed_check = check | ~((bfd_vma) -1 >> howto->rightshift);
 
+	/* Calculate the permissable maximum and minimum values for
+	   this relocation according to whether we're relocating for
+	   Thumb-2 or not.  */
+	bitsize = howto->bitsize;
+	if (!thumb2)
+	  bitsize -= 2;
+	reloc_signed_max = ((1 << (bitsize - 1)) - 1) >> howto->rightshift;
+	reloc_signed_min = ~reloc_signed_max;
+
 	/* Assumes two's complement.  */
 	if (signed_check > reloc_signed_max || signed_check < reloc_signed_min)
 	  overflow = TRUE;
@@ -4053,9 +4080,17 @@ elf32_arm_final_link_relocate (reloc_how
 	     1 of the base address.  */
 	  relocation = (relocation + 2) & ~ 3;
 
-	/* Put RELOCATION back into the insn.  */
-	upper_insn = (upper_insn & ~(bfd_vma) 0x7ff) | ((relocation >> 12) & 0x7ff);
-	lower_insn = (lower_insn & ~(bfd_vma) 0x7ff) | ((relocation >> 1) & 0x7ff);
+	/* Put RELOCATION back into the insn.  Assumes two's complement.
+	   We use the Thumb-2 encoding, which is safe even if dealing with
+	   a Thumb-1 instruction by virtue of our overflow check above.  */
+        reloc_sign = (signed_check < 0) ? 1 : 0;
+	upper_insn = (upper_insn & ~(bfd_vma) 0x7ff)
+                     | ((relocation >> 12) & 0x3ff)
+                     | (reloc_sign << 10);
+	lower_insn = (lower_insn & ~(bfd_vma) 0x2fff) 
+                     | (((!((relocation >> 23) & 1)) ^ reloc_sign) << 13)
+                     | (((!((relocation >> 22) & 1)) ^ reloc_sign) << 11)
+                     | ((relocation >> 1) & 0x7ff);
 
 	/* Put the relocated value back in the object file:  */
 	bfd_put_16 (input_bfd, upper_insn, hit_data);
Index: ld/testsuite/ld-arm/arm-elf.exp
===================================================================
RCS file: /cvs/src/src/ld/testsuite/ld-arm/arm-elf.exp,v
retrieving revision 1.17
diff -U3 -p -r1.17 arm-elf.exp
--- ld/testsuite/ld-arm/arm-elf.exp	18 Aug 2006 15:00:18 -0000	1.17
+++ ld/testsuite/ld-arm/arm-elf.exp	24 Aug 2006 15:05:43 -0000
@@ -62,6 +62,12 @@ set armelftests {
     {"Group relocations" "-Ttext 0x8000 --section-start zero=0x0 --section-start alpha=0xeef0 --section-start beta=0xffeef0" "" {group-relocs.s}
      {{objdump -Dr group-relocs.d}}
      "group-relocs"}
+    {"Thumb-1 BL" "-Ttext 0x1000 --section-start .foo=0x401000" "" {thumb1-bl.s}
+     {{objdump -dr thumb1-bl.d}}
+     "thumb1-bl"}
+    {"Thumb-2 BL" "-Ttext 0x1000 --section-start .foo=0x1001000" "" {thumb2-bl.s}
+     {{objdump -dr thumb2-bl.d}}
+     "thumb2-bl"}
     {"Simple non-PIC shared library" "-shared" "" {arm-lib.s}
      {{objdump -fdw arm-lib.d} {objdump -Rw arm-lib.r}}
      "arm-lib.so"}
@@ -146,4 +152,6 @@ run_dump_test "group-relocs-alu-bad"
 run_dump_test "group-relocs-ldr-bad"
 run_dump_test "group-relocs-ldrs-bad"
 run_dump_test "group-relocs-ldc-bad"
+run_dump_test "thumb2-bl-as-thumb1-bad"
+run_dump_test "thumb2-bl-bad"
 

[-- Attachment #3: thumb2-bl-bad.d --]
[-- Type: text/plain, Size: 190 bytes --]

#name: Thumb-2 BL failure test
#source: thumb2-bl-bad.s
#ld: -Ttext 0x1000 --section-start .foo=0x1001004
#error: .*\(.text\+0x0\): relocation truncated to fit: R_ARM_THM_CALL against `bar'

[-- Attachment #4: thumb2-bl.s --]
[-- Type: text/plain, Size: 323 bytes --]

@ Test to ensure that a Thumb-2 BL works with an offset that is
@ not permissable for Thumb-1.

	.arch armv7
	.global _start
	.syntax unified

@ We will place the section .text at 0x1000.

	.text
	.thumb_func

_start:
	bl bar

@ We will place the section .foo at 0x1001000.

	.section .foo, "xa"
	.thumb_func

bar:
	bx lr


[-- Attachment #5: thumb2-bl.d --]
[-- Type: text/plain, Size: 204 bytes --]


.*thumb2-bl:     file format elf32-.*arm

Disassembly of section .text:

00001000 <_start>:
    1000:	f3ff d7fe 	bl	1001000 <bar>
Disassembly of section .foo:

01001000 <bar>:
 1001000:	4770      	bx	lr

[-- Attachment #6: thumb1-bl.d --]
[-- Type: text/plain, Size: 203 bytes --]


.*thumb1-bl:     file format elf32-.*arm

Disassembly of section .text:

00001000 <_start>:
    1000:	f3ff fffe 	bl	401000 <bar>
Disassembly of section .foo:

00401000 <bar>:
  401000:	4770      	bx	lr

[-- Attachment #7: thumb2-bl-bad.s --]
[-- Type: text/plain, Size: 294 bytes --]

@ Test to ensure that a Thumb-2 BL with an oversize offset fails.

	.arch armv7
	.global _start
	.syntax unified

@ We will place the section .text at 0x1000.

	.text
	.thumb_func

_start:
	bl bar

@ We will place the section .foo at 0x1001004.

	.section .foo, "xa"
	.thumb_func

bar:
	bx lr


[-- Attachment #8: thumb2-bl-as-thumb1-bad.s --]
[-- Type: text/plain, Size: 297 bytes --]

@ Test to ensure that a Thumb-1 BL with a Thumb-2-only offset fails.

	.arch armv5t
	.global _start
	.syntax unified

@ We will place the section .text at 0x1000.

	.text
	.thumb_func

_start:
	bl bar

@ We will place the section .foo at 0x401004.

	.section .foo, "xa"
	.thumb_func

bar:
	bx lr


[-- Attachment #9: thumb2-bl-as-thumb1-bad.d --]
[-- Type: text/plain, Size: 210 bytes --]

#name: Thumb-2-as-Thumb-1 BL failure test
#source: thumb2-bl-as-thumb1-bad.s
#ld: -Ttext 0x1000 --section-start .foo=0x401004
#error: .*\(.text\+0x0\): relocation truncated to fit: R_ARM_THM_CALL against `bar'

[-- Attachment #10: thumb1-bl.s --]
[-- Type: text/plain, Size: 270 bytes --]

@ Test to ensure that a Thumb-1 BL works.

	.arch armv5t
	.global _start
	.syntax unified

@ We will place the section .text at 0x1000.

	.text
	.thumb_func

_start:
	bl bar

@ We will place the section .foo at 0x401000.

	.section .foo, "xa"
	.thumb_func

bar:
	bx lr


             reply	other threads:[~2006-08-24 15:23 UTC|newest]

Thread overview: 3+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2006-08-24 15:48 Mark Shinwell [this message]
2006-09-01 15:51 ` Richard Earnshaw
2006-09-01 15:52   ` Mark Shinwell

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=44EDC478.2090103@codesourcery.com \
    --to=shinwell@codesourcery.com \
    --cc=binutils@sourceware.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).