This is the mail archive of the binutils-cvs@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]

[binutils-gdb] [BFD][AARCH64]Add TLSGD relaxation support under large memory model.


https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=ac734732481451698ee23990aaa64907e56dd082

commit ac734732481451698ee23990aaa64907e56dd082
Author: Renlin Li <renlin.li@arm.com>
Date:   Fri Oct 2 17:22:36 2015 +0100

    [BFD][AARCH64]Add TLSGD relaxation support under large memory model.
    
    bfd/
    
    2015-10-02  Renlin Li <renlin.li@arm.com>
    
    	* elfnn-aarch64.c(IS_AARCH64_TLS_RELAX_RELOC):
    	Add relaxation support for TLSGD_MOVW_G0_NC and TLSGD_MOVW_G1.
    	(aarch64_tls_transition_without_check): Likewise
    	(elfNN_aarch64_tls_relax): Likwise.
    
    ld/testsuite/
    
    2015-10-02  Renlin Li <renlin.li@arm.com>
    
    	* ld-aarch64/aarch64-elf.exp: run new test
    	* ld-aarch64/tls-relax-large-gd-ie.d: New.
    	* ld-aarch64/tls-relax-large-gd-ie.s: New.
    	* ld-aarch64/tls-relax-large-gd-le.d: New.
    	* ld-aarch64/tls-relax-large-gd-le.s: New.

Diff:
---
 bfd/ChangeLog                                   |  7 +++
 bfd/elfnn-aarch64.c                             | 60 +++++++++++++++++++++++++
 ld/testsuite/ChangeLog                          |  8 ++++
 ld/testsuite/ld-aarch64/aarch64-elf.exp         |  2 +
 ld/testsuite/ld-aarch64/tls-relax-large-gd-ie.d | 16 +++++++
 ld/testsuite/ld-aarch64/tls-relax-large-gd-ie.s | 20 +++++++++
 ld/testsuite/ld-aarch64/tls-relax-large-gd-le.d | 16 +++++++
 ld/testsuite/ld-aarch64/tls-relax-large-gd-le.s | 19 ++++++++
 8 files changed, 148 insertions(+)

diff --git a/bfd/ChangeLog b/bfd/ChangeLog
index ecf5d56..bad620e 100644
--- a/bfd/ChangeLog
+++ b/bfd/ChangeLog
@@ -1,5 +1,12 @@
 2015-10-02  Renlin Li  <renlin.li@arm.com>
 
+	* elfnn-aarch64.c(IS_AARCH64_TLS_RELAX_RELOC):
+	Add relaxation support for TLSGD_MOVW_G0_NC and TLSGD_MOVW_G1.
+	(aarch64_tls_transition_without_check): Likewise
+	(elfNN_aarch64_tls_relax): Likwise.
+
+2015-10-02  Renlin Li  <renlin.li@arm.com>
+
 	* elfnn-aarch64.c (elfNN_aarch64_check_relocs): Create GOT section
 	for TLSLE_MOVW_TPREL_G(1, 1_NC, 2) relocation.
 
diff --git a/bfd/elfnn-aarch64.c b/bfd/elfnn-aarch64.c
index d71a76f..cff77ce 100644
--- a/bfd/elfnn-aarch64.c
+++ b/bfd/elfnn-aarch64.c
@@ -218,6 +218,8 @@
    || (R_TYPE) == BFD_RELOC_AARCH64_TLSGD_ADR_PAGE21		\
    || (R_TYPE) == BFD_RELOC_AARCH64_TLSGD_ADR_PREL21		\
    || (R_TYPE) == BFD_RELOC_AARCH64_TLSGD_ADD_LO12_NC		\
+   || (R_TYPE) == BFD_RELOC_AARCH64_TLSGD_MOVW_G0_NC		\
+   || (R_TYPE) == BFD_RELOC_AARCH64_TLSGD_MOVW_G1		\
    || (R_TYPE) == BFD_RELOC_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21	\
    || (R_TYPE) == BFD_RELOC_AARCH64_TLSIE_LD_GOTTPREL_PREL19	\
    || (R_TYPE) == BFD_RELOC_AARCH64_TLSIE_LDNN_GOTTPREL_LO12_NC	\
@@ -4460,6 +4462,18 @@ aarch64_tls_transition_without_check (bfd_reloc_code_real_type r_type,
     case BFD_RELOC_AARCH64_TLSLD_ADR_PREL21:
       return is_local ? BFD_RELOC_AARCH64_NONE : r_type;
 
+#if ARCH_SIZE == 64
+    case BFD_RELOC_AARCH64_TLSGD_MOVW_G0_NC:
+      return is_local
+	? BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G1_NC
+	: BFD_RELOC_AARCH64_TLSIE_MOVW_GOTTPREL_G0_NC;
+
+    case BFD_RELOC_AARCH64_TLSGD_MOVW_G1:
+      return is_local
+	? BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G2
+	: BFD_RELOC_AARCH64_TLSIE_MOVW_GOTTPREL_G1;
+#endif
+
     default:
       break;
     }
@@ -5692,6 +5706,52 @@ elfNN_aarch64_tls_relax (struct elf_aarch64_link_hash_table *globals,
 	  return bfd_reloc_continue;
 	}
 
+#if ARCH_SIZE == 64
+    case BFD_RELOC_AARCH64_TLSGD_MOVW_G1:
+      BFD_ASSERT (ELFNN_R_TYPE (rel[1].r_info) == AARCH64_R (TLSGD_MOVW_G0_NC));
+      BFD_ASSERT (rel->r_offset + 12 == rel[2].r_offset);
+      BFD_ASSERT (ELFNN_R_TYPE (rel[2].r_info) == AARCH64_R (CALL26));
+
+      if (is_local)
+	{
+	  /* Large GD->LE relaxation:
+	     movz x0, #:tlsgd_g1:var    => movz x0, #:tprel_g2:var, lsl #32
+	     movk x0, #:tlsgd_g0_nc:var => movk x0, #:tprel_g1_nc:var, lsl #16
+	     add x0, gp, x0             => movk x0, #:tprel_g0_nc:var
+	     bl __tls_get_addr          => mrs x1, tpidr_el0
+	     nop                        => add x0, x0, x1
+	   */
+	  rel[2].r_info = ELFNN_R_INFO (ELFNN_R_SYM (rel->r_info),
+					AARCH64_R (TLSLE_MOVW_TPREL_G0_NC));
+	  rel[2].r_offset = rel->r_offset + 8;
+
+	  bfd_putl32 (0xd2c00000, contents + rel->r_offset + 0);
+	  bfd_putl32 (0xf2a00000, contents + rel->r_offset + 4);
+	  bfd_putl32 (0xf2800000, contents + rel->r_offset + 8);
+	  bfd_putl32 (0xd53bd041, contents + rel->r_offset + 12);
+	  bfd_putl32 (0x8b000020, contents + rel->r_offset + 16);
+	}
+      else
+	{
+	  /* Large GD->IE relaxation:
+	     movz x0, #:tlsgd_g1:var    => movz x0, #:gottprel_g1:var, lsl #16
+	     movk x0, #:tlsgd_g0_nc:var => movk x0, #:gottprel_g0_nc:var
+	     add x0, gp, x0             => ldr x0, [gp, x0]
+	     bl __tls_get_addr          => mrs x1, tpidr_el0
+	     nop                        => add x0, x0, x1
+	   */
+	  rel[2].r_info = ELFNN_R_INFO (STN_UNDEF, R_AARCH64_NONE);
+	  bfd_putl32 (0xd2a80000, contents + rel->r_offset + 0);
+	  bfd_putl32 (0x58000000, contents + rel->r_offset + 8);
+	  bfd_putl32 (0xd53bd041, contents + rel->r_offset + 12);
+	  bfd_putl32 (0x8b000020, contents + rel->r_offset + 16);
+	}
+      return bfd_reloc_continue;
+
+    case BFD_RELOC_AARCH64_TLSGD_MOVW_G0_NC:
+      return bfd_reloc_continue;
+#endif
+
     case BFD_RELOC_AARCH64_TLSIE_LD_GOTTPREL_PREL19:
       return bfd_reloc_continue;
 
diff --git a/ld/testsuite/ChangeLog b/ld/testsuite/ChangeLog
index e486bba..a95de8c 100644
--- a/ld/testsuite/ChangeLog
+++ b/ld/testsuite/ChangeLog
@@ -1,5 +1,13 @@
 2015-10-02  Renlin Li  <renlin.li@arm.com>
 
+	* ld-aarch64/aarch64-elf.exp: run new test
+	* ld-aarch64/tls-relax-large-gd-ie.d: New.
+	* ld-aarch64/tls-relax-large-gd-ie.s: New.
+	* ld-aarch64/tls-relax-large-gd-le.d: New.
+	* ld-aarch64/tls-relax-large-gd-le.s: New.
+
+2015-10-02  Renlin Li  <renlin.li@arm.com>
+
 	* ld-aarch64/tls-large-ie.d: New.
 	* ld-aarch64/tls-large-ie.s: New.
 	* ld-aarch64/aarch64-elf.exp: Run new test.
diff --git a/ld/testsuite/ld-aarch64/aarch64-elf.exp b/ld/testsuite/ld-aarch64/aarch64-elf.exp
index d0da92f..f51de9c 100644
--- a/ld/testsuite/ld-aarch64/aarch64-elf.exp
+++ b/ld/testsuite/ld-aarch64/aarch64-elf.exp
@@ -181,6 +181,8 @@ run_dump_test "tls-relax-all"
 run_dump_test "tls-relax-gd-le"
 run_dump_test "tls-relax-gdesc-le"
 run_dump_test "tls-relax-gd-ie"
+run_dump_test "tls-relax-large-gd-ie"
+run_dump_test "tls-relax-large-gd-le"
 run_dump_test "tls-relax-gdesc-ie"
 run_dump_test "tls-relax-ie-le"
 run_dump_test "tls-relax-ld-le-small"
diff --git a/ld/testsuite/ld-aarch64/tls-relax-large-gd-ie.d b/ld/testsuite/ld-aarch64/tls-relax-large-gd-ie.d
new file mode 100644
index 0000000..f3407ef
--- /dev/null
+++ b/ld/testsuite/ld-aarch64/tls-relax-large-gd-ie.d
@@ -0,0 +1,16 @@
+#source: tls-relax-large-gd-ie.s
+#ld: -T relocs.ld -e0
+#objdump: -dr
+#...
+0000000000010000 <test>:
+ +10000:	58000121 	ldr	x1, 10024 <test\+0x24>
+ +10004:	10000102 	adr	x2, 10024 <test\+0x24>
+ +10008:	8b010041 	add	x1, x2, x1
+ +1000c:	d2a00000 	movz	x0, #0x0, lsl #16
+ +10010:	f2800100 	movk	x0, #0x8
+ +10014:	58000000 	ldr	x0, 10014 <test\+0x14>
+ +10018:	d53bd041 	mrs	x1, tpidr_el0
+ +1001c:	8b000020 	add	x0, x1, x0
+ +10020:	b9400000 	ldr	w0, \[x0\]
+ +10024:	0000ffdc 	.word	0x0000ffdc
+ +10028:	00000000 	.word	0x00000000
diff --git a/ld/testsuite/ld-aarch64/tls-relax-large-gd-ie.s b/ld/testsuite/ld-aarch64/tls-relax-large-gd-ie.s
new file mode 100644
index 0000000..8e0310d
--- /dev/null
+++ b/ld/testsuite/ld-aarch64/tls-relax-large-gd-ie.s
@@ -0,0 +1,20 @@
+	.global var
+	.section	.tdata,"awT",%progbits
+var:
+	.word	2
+
+	.text
+test:
+	ldr	x1, .Lgot
+	adr	x2, .Lgot
+	add	x1, x2, x1
+
+	movz	x0, #:tlsgd_g1:var
+	movk	x0, #:tlsgd_g0_nc:var
+	add	x0, x1, x0
+	bl	__tls_get_addr
+	nop
+	ldr	w0, [x0]
+
+.Lgot:
+	.dword _GLOBAL_OFFSET_TABLE_ - .
diff --git a/ld/testsuite/ld-aarch64/tls-relax-large-gd-le.d b/ld/testsuite/ld-aarch64/tls-relax-large-gd-le.d
new file mode 100644
index 0000000..acaea58
--- /dev/null
+++ b/ld/testsuite/ld-aarch64/tls-relax-large-gd-le.d
@@ -0,0 +1,16 @@
+#source: tls-relax-large-gd-le.s
+#ld: -T relocs.ld -e0
+#objdump: -dr
+#...
+0000000000010000 <test>:
+ +10000:	58000121 	ldr	x1, 10024 <test\+0x24>
+ +10004:	10000102 	adr	x2, 10024 <test\+0x24>
+ +10008:	8b010041 	add	x1, x2, x1
+ +1000c:	d2c00000 	movz	x0, #0x0, lsl #32
+ +10010:	f2a00000 	movk	x0, #0x0, lsl #16
+ +10014:	f2800200 	movk	x0, #0x10
+ +10018:	d53bd041 	mrs	x1, tpidr_el0
+ +1001c:	8b000020 	add	x0, x1, x0
+ +10020:	b9400000 	ldr	w0, \[x0\]
+ +10024:	0000ffdc 	.word	0x0000ffdc
+ +10028:	00000000 	.word	0x00000000
diff --git a/ld/testsuite/ld-aarch64/tls-relax-large-gd-le.s b/ld/testsuite/ld-aarch64/tls-relax-large-gd-le.s
new file mode 100644
index 0000000..781f6cc
--- /dev/null
+++ b/ld/testsuite/ld-aarch64/tls-relax-large-gd-le.s
@@ -0,0 +1,19 @@
+	.section	.tdata
+var:
+	.word	2
+
+	.text
+test:
+	ldr	x1, .Lgot
+	adr	x2, .Lgot
+	add	x1, x2, x1
+
+	movz	x0, #:tlsgd_g1:var
+	movk	x0, #:tlsgd_g0_nc:var
+	add	x0, x1, x0
+	bl	__tls_get_addr
+	nop
+	ldr	w0, [x0]
+
+.Lgot:
+	.dword _GLOBAL_OFFSET_TABLE_ - .


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