public inbox for binutils@sourceware.org
 help / color / mirror / Atom feed
* [PATCH] XCOFF: add support for TLS relocations on hidden symbols
@ 2022-01-06 12:49 CHIGOT, CLEMENT
  2022-01-10  2:21 ` Alan Modra
  0 siblings, 1 reply; 2+ messages in thread
From: CHIGOT, CLEMENT @ 2022-01-06 12:49 UTC (permalink / raw)
  To: binutils

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

This patch adds support for TLS relocation targeting C_HIDEXT symbols.
In gas, TLS relocations, except R_TLSM and R_TLMSL, must keep the value
of their target symbol.
In ld, it simply ensures that internal TLS symbols are added to the
linker hash table for xcoff_reloc_type_tls.

It also improves the tests made by both.

bfd/ChangeLog:

        * coff-rs6000.c (xcoff_howto_table): Fix name of R_TLSML.
        (xcoff_reloc_type_tls): Replace the error when h is NULL by
        an assert.
        (xcoff_complain_overflow_unsigned_func): Adjust comments.
        * coff64-rs6000.c (xcoff64_howto_table): Fix name of R_TLSML.
        * xcofflink.c (xcoff_link_add_symbols_to_hash_table): New
        function.
        (xcoff_link_add_symbols): Add C_HIDEXT TLS symbols to the linker
        hash table.

gas/ChangeLog:

        * config/tc-ppc.c (md_apply_fix): Enable support for TLS
        relocation over internal symbols.
        * testsuite/gas/ppc/aix.exp: Replace xcoff-tlms by xcoff-tls.
        * testsuite/gas/ppc/xcoff-tlsm-32.d: Removed.
        * testsuite/gas/ppc/xcoff-tlsm-64.d: Removed.
        * testsuite/gas/ppc/xcoff-tlsm.s: Removed.
        * testsuite/gas/ppc/xcoff-tls-32.d: New test.
        * testsuite/gas/ppc/xcoff-tls-64.d: New test.
        * testsuite/gas/ppc/xcoff-tls.s: New test.

ld/ChangeLog:

        * testsuite/ld-powerpc/aix52.exp: Improve aix-tls-reloc test.
        * testsuite/ld-powerpc/aix-tls-reloc.s: Likewise.
        * testsuite/ld-powerpc/aix-tls-reloc-32.d: Removed.
        * testsuite/ld-powerpc/aix-tls-reloc-64.d: Removed.
        * testsuite/ld-powerpc/aix-tls-reloc-32.dd: New test.
        * testsuite/ld-powerpc/aix-tls-reloc-32.dt: New test.
        * testsuite/ld-powerpc/aix-tls-reloc-64.dd: New test.
        * testsuite/ld-powerpc/aix-tls-reloc-64.dt: New test.




[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: 0001-XCOFF-add-support-for-TLS-relocations-on-hidden-symb.patch --]
[-- Type: text/x-patch; name="0001-XCOFF-add-support-for-TLS-relocations-on-hidden-symb.patch", Size: 34635 bytes --]

From 2ce009ef323dd5d99bd50b4e8c1af76230e36d3c Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Cl=C3=A9ment=20Chigot?= <clement.chigot@atos.net>
Date: Fri, 17 Dec 2021 14:46:01 +0100
Subject: [PATCH] XCOFF: add support for TLS relocations on hidden symbols

This patch adds support for TLS relocation targeting C_HIDEXT symbols.
In gas, TLS relocations, except R_TLSM and R_TLMSL, must keep the value
of their target symbol.
In ld, it simply ensures that internal TLS symbols are added to the
linker hash table for xcoff_reloc_type_tls.

It also improves the tests made by both.

bfd/ChangeLog:

	* coff-rs6000.c (xcoff_howto_table): Fix name of R_TLSML.
	(xcoff_reloc_type_tls): Replace the error when h is NULL by
	an assert.
	(xcoff_complain_overflow_unsigned_func): Adjust comments.
	* coff64-rs6000.c (xcoff64_howto_table): Fix name of R_TLSML.
	* xcofflink.c (xcoff_link_add_symbols_to_hash_table): New
	function.
	(xcoff_link_add_symbols): Add C_HIDEXT TLS symbols to the linker
	hash table.

gas/ChangeLog:

	* config/tc-ppc.c (md_apply_fix): Enable support for TLS
	relocation over internal symbols.
	* testsuite/gas/ppc/aix.exp: Replace xcoff-tlms by xcoff-tls.
	* testsuite/gas/ppc/xcoff-tlsm-32.d: Removed.
	* testsuite/gas/ppc/xcoff-tlsm-64.d: Removed.
	* testsuite/gas/ppc/xcoff-tlsm.s: Removed.
	* testsuite/gas/ppc/xcoff-tls-32.d: New test.
	* testsuite/gas/ppc/xcoff-tls-64.d: New test.
	* testsuite/gas/ppc/xcoff-tls.s: New test.

ld/ChangeLog:

	* testsuite/ld-powerpc/aix52.exp: Improve aix-tls-reloc test.
	* testsuite/ld-powerpc/aix-tls-reloc.s: Likewise.
	* testsuite/ld-powerpc/aix-tls-reloc-32.d: Removed.
	* testsuite/ld-powerpc/aix-tls-reloc-64.d: Removed.
	* testsuite/ld-powerpc/aix-tls-reloc-32.dd: New test.
	* testsuite/ld-powerpc/aix-tls-reloc-32.dt: New test.
	* testsuite/ld-powerpc/aix-tls-reloc-64.dd: New test.
	* testsuite/ld-powerpc/aix-tls-reloc-64.dt: New test.
---
 bfd/coff-rs6000.c                           |  33 ++---
 bfd/coff64-rs6000.c                         |   2 +-
 bfd/xcofflink.c                             |  55 ++++++-
 gas/config/tc-ppc.c                         |  32 ++--
 gas/testsuite/gas/ppc/aix.exp               |   4 +-
 gas/testsuite/gas/ppc/xcoff-tls-32.d        | 106 ++++++++++++++
 gas/testsuite/gas/ppc/xcoff-tls-64.d        | 124 ++++++++++++++++
 gas/testsuite/gas/ppc/xcoff-tls.s           |  57 ++++++++
 gas/testsuite/gas/ppc/xcoff-tlsm-32.d       |  34 -----
 gas/testsuite/gas/ppc/xcoff-tlsm-64.d       |  36 -----
 gas/testsuite/gas/ppc/xcoff-tlsm.s          |  12 --
 ld/testsuite/ld-powerpc/aix-tls-reloc-32.d  |  35 -----
 ld/testsuite/ld-powerpc/aix-tls-reloc-32.dd | 101 +++++++++++++
 ld/testsuite/ld-powerpc/aix-tls-reloc-32.dt |  18 +++
 ld/testsuite/ld-powerpc/aix-tls-reloc-64.d  |  31 ----
 ld/testsuite/ld-powerpc/aix-tls-reloc-64.dd | 119 +++++++++++++++
 ld/testsuite/ld-powerpc/aix-tls-reloc-64.dt |  23 +++
 ld/testsuite/ld-powerpc/aix-tls-reloc.s     | 154 +++++++++++++++-----
 ld/testsuite/ld-powerpc/aix52.exp           |   3 +-
 19 files changed, 751 insertions(+), 228 deletions(-)
 create mode 100644 gas/testsuite/gas/ppc/xcoff-tls-32.d
 create mode 100644 gas/testsuite/gas/ppc/xcoff-tls-64.d
 create mode 100644 gas/testsuite/gas/ppc/xcoff-tls.s
 delete mode 100644 gas/testsuite/gas/ppc/xcoff-tlsm-32.d
 delete mode 100644 gas/testsuite/gas/ppc/xcoff-tlsm-64.d
 delete mode 100644 gas/testsuite/gas/ppc/xcoff-tlsm.s
 delete mode 100644 ld/testsuite/ld-powerpc/aix-tls-reloc-32.d
 create mode 100644 ld/testsuite/ld-powerpc/aix-tls-reloc-32.dd
 create mode 100644 ld/testsuite/ld-powerpc/aix-tls-reloc-32.dt
 delete mode 100644 ld/testsuite/ld-powerpc/aix-tls-reloc-64.d
 create mode 100644 ld/testsuite/ld-powerpc/aix-tls-reloc-64.dd
 create mode 100644 ld/testsuite/ld-powerpc/aix-tls-reloc-64.dt

diff --git a/bfd/coff-rs6000.c b/bfd/coff-rs6000.c
index 61a655726e7..75463e18346 100644
--- a/bfd/coff-rs6000.c
+++ b/bfd/coff-rs6000.c
@@ -1106,7 +1106,7 @@ reloc_howto_type xcoff_howto_table[] =
 	 0,			/* bitpos */
 	 complain_overflow_bitfield, /* complain_on_overflow */
 	 0,			/* special_function */
-	 "R_TLSM",		/* name */
+	 "R_TLSML",		/* name */
 	 true,			/* partial_inplace */
 	 0xffffffff,		/* src_mask */
 	 0xffffffff,		/* dst_mask */
@@ -3236,27 +3236,19 @@ xcoff_reloc_type_tls (bfd *input_bfd ATTRIBUTE_UNUSED,
 
   h = obj_xcoff_sym_hashes (input_bfd)[rel->r_symndx];
 
-  /* FIXME: R_TLSML is targeting a internal TOC symbol, which will
-     make the following checks failing. It should be moved with
-     R_TLSM bellow once it works.  */
+  /* R_TLSML is handled by the loader but must be from a
+     TOC entry targeting itslef.  This is already verified in
+     xcoff_link_add_symbols.
+     The value must be 0.  */
   if (howto->type == R_TLSML)
     {
       *relocation = 0;
       return true;
     }
 
-  /* FIXME: h is sometimes null, if the TLS symbol is not exported.  */
-  if (!h)
-    {
-      char vaddr_buf[128];
-
-      sprintf_vma (vaddr_buf, rel->r_vaddr);
-      _bfd_error_handler
-	(_("%pB: TLS relocation at 0x%s over internal symbols (C_HIDEXT) not yet possible\n"),
-	 input_bfd, vaddr_buf);
-      return false;
-    }
-
+  /* The target symbol should always be available even if it's not
+     exported.  */
+  BFD_ASSERT (h != NULL);
 
   /* TLS relocations must target a TLS symbol.  */
   if (h->smclas != XMC_TL && h->smclas != XMC_UL)
@@ -3286,9 +3278,8 @@ xcoff_reloc_type_tls (bfd *input_bfd ATTRIBUTE_UNUSED,
       return false;
     }
 
-  /* R_TLSM and R_TLSML are relocations used by the loader.
-     The value must be 0.
-     FIXME: move R_TLSML here.  */
+  /* R_TLSM are relocations used by the loader.
+     The value must be 0.  */
   if (howto->type == R_TLSM)
     {
       *relocation = 0;
@@ -3621,10 +3612,10 @@ xcoff_complain_overflow_unsigned_func (bfd *input_bfd,
    R_TLS_LE:
    Thread-local storage relocation using local-exec model.
 
-   R_TLS:
+   R_TLSM:
    Tread-local storage relocation used by the loader.
 
-   R_TLSM:
+   R_TLSML:
    Tread-local storage relocation used by the loader.
 
    R_TOCU:
diff --git a/bfd/coff64-rs6000.c b/bfd/coff64-rs6000.c
index 6698f4345d8..01326d4503d 100644
--- a/bfd/coff64-rs6000.c
+++ b/bfd/coff64-rs6000.c
@@ -1350,7 +1350,7 @@ reloc_howto_type xcoff64_howto_table[] =
 	 0,			/* bitpos */
 	 complain_overflow_bitfield, /* complain_on_overflow */
 	 0,			/* special_function */
-	 "R_TLSM",		/* name */
+	 "R_TLSML",		/* name */
 	 true,			/* partial_inplace */
 	 MINUS_ONE,		/* src_mask */
 	 MINUS_ONE,		/* dst_mask */
diff --git a/bfd/xcofflink.c b/bfd/xcofflink.c
index a838c4b7726..ba07ba7f045 100644
--- a/bfd/xcofflink.c
+++ b/bfd/xcofflink.c
@@ -1178,6 +1178,26 @@ xcoff_find_reloc (struct internal_reloc *relocs,
   return min;
 }
 
+/* Return true if the symbol has to be added to the linker hash
+   table.  */
+static bool
+xcoff_link_add_symbols_to_hash_table (struct internal_syment sym,
+				      union internal_auxent aux)
+{
+  /* External symbols must be added.  */
+  if (EXTERN_SYM_P (sym.n_sclass))
+    return true;
+
+  /* Hidden TLS symbols must be added to verify TLS relocations
+     in xcoff_reloc_type_tls.  */
+  if (sym.n_sclass == C_HIDEXT
+      && ((aux.x_csect.x_smclas == XMC_TL
+	   || aux.x_csect.x_smclas == XMC_UL)))
+    return true;
+
+  return false;
+}
+
 /* Add all the symbols from an object file to the hash table.
 
    XCOFF is a weird format.  A normal XCOFF .o files will have three
@@ -1551,6 +1571,11 @@ xcoff_link_add_symbols (bfd *abfd, struct bfd_link_info *info)
 	     32 bit has a csect length of 4 for TOC
 	     64 bit has a csect length of 8 for TOC
 
+	     An exception is made for TOC entries with a R_TLSML
+	     relocation.  This relocation is made for the loader.
+	     We must check that the referenced symbol is the TOC entry
+	     itself.
+
 	     The conditions to get past the if-check are not that bad.
 	     They are what is used to create the TOC csects in the first
 	     place.  */
@@ -1580,7 +1605,8 @@ xcoff_link_add_symbols (bfd *abfd, struct bfd_link_info *info)
 		 64 bit R_POS r_size is 63  */
 	      if (relindx < enclosing->reloc_count
 		  && rel->r_vaddr == (bfd_vma) sym.n_value
-		  && rel->r_type == R_POS
+		  && (rel->r_type == R_POS ||
+		      rel->r_type == R_TLSML)
 		  && ((bfd_xcoff_is_xcoff32 (abfd)
 		       && rel->r_size == 31)
 		      || (bfd_xcoff_is_xcoff64 (abfd)
@@ -1652,6 +1678,22 @@ xcoff_link_add_symbols (bfd *abfd, struct bfd_link_info *info)
 			  set_toc = h;
 			}
 		    }
+		  else if (rel->r_type == R_TLSML)
+		    {
+			csect_index = ((esym
+					- (bfd_byte *) obj_coff_external_syms (abfd))
+				       / symesz);
+			if (((unsigned long) rel->r_symndx) != csect_index)
+			  {
+			    _bfd_error_handler
+			      /* xgettext:c-format */
+			      (_("%pB: TOC entry `%s' has a R_TLSML"
+				 "relocation not targeting itself"),
+			       abfd, name);
+			    bfd_set_error (bfd_error_bad_value);
+			    goto error_return;
+			  }
+		    }
 		}
 	    }
 
@@ -1749,9 +1791,10 @@ xcoff_link_add_symbols (bfd *abfd, struct bfd_link_info *info)
 	    if (first_csect == NULL)
 	      first_csect = csect;
 
-	    /* If this symbol is external, we treat it as starting at the
-	       beginning of the newly created section.  */
-	    if (EXTERN_SYM_P (sym.n_sclass))
+	    /* If this symbol must be added to the linker hash table,
+	       we treat it as starting at the beginning of the newly
+	       created section.  */
+	    if (xcoff_link_add_symbols_to_hash_table (sym, aux))
 	      {
 		section = csect;
 		value = 0;
@@ -1847,7 +1890,7 @@ xcoff_link_add_symbols (bfd *abfd, struct bfd_link_info *info)
 	  if (first_csect == NULL)
 	    first_csect = csect;
 
-	  if (EXTERN_SYM_P (sym.n_sclass))
+	  if (xcoff_link_add_symbols_to_hash_table (sym, aux))
 	    {
 	      csect->flags |= SEC_IS_COMMON;
 	      csect->size = 0;
@@ -1888,7 +1931,7 @@ xcoff_link_add_symbols (bfd *abfd, struct bfd_link_info *info)
       /* Now we have enough information to add the symbol to the
 	 linker hash table.  */
 
-      if (EXTERN_SYM_P (sym.n_sclass))
+      if (xcoff_link_add_symbols_to_hash_table (sym, aux))
 	{
 	  bool copy, ok;
 	  flagword flags;
diff --git a/gas/config/tc-ppc.c b/gas/config/tc-ppc.c
index c7af7b76e08..159d3155b4c 100644
--- a/gas/config/tc-ppc.c
+++ b/gas/config/tc-ppc.c
@@ -7426,22 +7426,25 @@ md_apply_fix (fixS *fixP, valueT *valP, segT seg)
 	case BFD_RELOC_PPC64_TLSM:
 	  gas_assert (fixP->fx_addsy != NULL);
 	  S_SET_THREAD_LOCAL (fixP->fx_addsy);
-	  fieldval = 0;
 	  break;
 
-	  /* TLSML relocations are targeting a XMC_TC symbol named
-	     "_$TLSML". We can't check earlier because the relocation
-	     can target any symbol name which will be latter .rename
-	     to "_$TLSML".  */
+	  /* Officially, R_TLSML relocations must be from a TOC entry
+	     targeting itself. In practice, this TOC entry is always
+	     named (or .rename) "_$TLSML".
+	     Thus, as it doesn't seem possible to retrieve the symbol
+	     being relocated here, we simply check that the symbol
+	     targeted by R_TLSML is indeed a TOC entry named "_$TLSML".
+	     FIXME: Find a way to correctly check R_TLSML relocations
+	     as described above.  */
 	case BFD_RELOC_PPC_TLSML:
 	case BFD_RELOC_PPC64_TLSML:
 	  gas_assert (fixP->fx_addsy != NULL);
-	  if (strcmp (symbol_get_tc (fixP->fx_addsy)->real_name, "_$TLSML") != 0)
-	    {
-	      as_bad_where (fixP->fx_file, fixP->fx_line,
-			    _("R_TLSML relocation doesn't target a "
-			      "symbol named \"_$TLSML\". %s"), S_GET_NAME(fixP->fx_addsy));
-	    }
+	  if ((symbol_get_tc (fixP->fx_addsy)->symbol_class != XMC_TC
+	       || symbol_get_tc (fixP->fx_addsy)->symbol_class != XMC_TE)
+	      && strcmp (symbol_get_tc (fixP->fx_addsy)->real_name, "_$TLSML") != 0)
+	    as_bad_where (fixP->fx_file, fixP->fx_line,
+			  _("R_TLSML relocation doesn't target a "
+			    "TOC entry named \"_$TLSML\": %s"), S_GET_NAME(fixP->fx_addsy));
 	  fieldval = 0;
 	  break;
 
@@ -7519,12 +7522,15 @@ md_apply_fix (fixS *fixP, valueT *valP, segT seg)
       *valP = value;
     }
   else if (fixP->fx_r_type == BFD_RELOC_PPC_TLSM
-	   || fixP->fx_r_type == BFD_RELOC_PPC64_TLSM)
+	   || fixP->fx_r_type == BFD_RELOC_PPC64_TLSM
+	   || fixP->fx_r_type == BFD_RELOC_PPC_TLSML
+	   || fixP->fx_r_type == BFD_RELOC_PPC64_TLSML)
     /* AIX ld expects the section contents for these relocations
        to be zero.  Arrange for that to occur when
        bfd_install_relocation is called.  */
     fixP->fx_addnumber = (- bfd_section_vma (S_GET_SEGMENT (fixP->fx_addsy))
-			  - S_GET_VALUE (fixP->fx_addsy));
+			  - S_GET_VALUE (fixP->fx_addsy)
+			  - fieldval);
   else
     fixP->fx_addnumber = 0;
 #endif
diff --git a/gas/testsuite/gas/ppc/aix.exp b/gas/testsuite/gas/ppc/aix.exp
index 85ed06e8a38..78f29f0674d 100644
--- a/gas/testsuite/gas/ppc/aix.exp
+++ b/gas/testsuite/gas/ppc/aix.exp
@@ -79,8 +79,8 @@ if { [istarget "powerpc*-*-aix*"] || [istarget "rs6000-*-aix*"] } then {
     run_dump_test "xcoff-function-1-32"
     run_dump_test "xcoff-function-1-64"
 
-    run_dump_test "xcoff-tlsm-32"
-    run_dump_test "xcoff-tlsm-64"
+    run_dump_test "xcoff-tls-32"
+    run_dump_test "xcoff-tls-64"
 
     run_dump_test "xcoff-stsym-32"
     run_dump_test "xcoff-stsym-64"
diff --git a/gas/testsuite/gas/ppc/xcoff-tls-32.d b/gas/testsuite/gas/ppc/xcoff-tls-32.d
new file mode 100644
index 00000000000..eb71df09e41
--- /dev/null
+++ b/gas/testsuite/gas/ppc/xcoff-tls-32.d
@@ -0,0 +1,106 @@
+#as: -a32
+#source: xcoff-tls.s
+#objdump: -Dr
+#name: XCOFF TLS relocation (32 bit)
+
+.*
+Disassembly of section .data:
+
+00000000 <TOC>:
+   0:	00 00 00 58.*
+			0: R_TLS	tdata_ext.*
+
+00000004 <.tdata_ext_gd>:
+   4:	00 00 00 00.*
+			4: R_TLSM	tdata_ext.*
+
+00000008 <tdata_ext_ld>:
+   8:	00 00 00 58.*
+			8: R_TLS_LD	tdata_ext.*
+
+0000000c <tdata_ext_ie>:
+   c:	00 00 00 58.*
+			c: R_TLS_IE	tdata_ext.*
+
+00000010 <tdata_ext_le>:
+  10:	00 00 00 58.*
+			10: R_TLS_LE	tdata_ext.*
+
+00000014 <tdata_int1_gd>:
+  14:	00 00 00 5c.*
+			14: R_TLS	tdata_int_csect.*
+
+00000018 <.tdata_int1_gd>:
+  18:	00 00 00 00.*
+			18: R_TLSM	tdata_int_csect.*
+
+0000001c <tdata_int1_ld>:
+  1c:	00 00 00 5c.*
+			1c: R_TLS_LD	tdata_int_csect.*
+
+00000020 <tdata_int1_ie>:
+  20:	00 00 00 5c.*
+			20: R_TLS_IE	tdata_int_csect.*
+
+00000024 <tdata_int1_le>:
+  24:	00 00 00 5c.*
+			24: R_TLS_LE	tdata_int_csect.*
+
+00000028 <tdata_int2_gd>:
+  28:	00 00 00 60.*
+			28: R_TLS	tdata_int_csect.*
+
+0000002c <.tdata_int2_gd>:
+  2c:	00 00 00 00.*
+			2c: R_TLSM	tdata_int_csect.*
+
+00000030 <tdata_int2_ld>:
+  30:	00 00 00 60.*
+			30: R_TLS_LD	tdata_int_csect.*
+
+00000034 <tdata_int2_ie>:
+  34:	00 00 00 60.*
+			34: R_TLS_IE	tdata_int_csect.*
+
+00000038 <tdata_int2_le>:
+  38:	00 00 00 60.*
+			38: R_TLS_LE	tdata_int_csect.*
+
+0000003c <tbss_ext_gd>:
+  3c:	00 00 00 68.*
+			3c: R_TLS	tbss_ext.*
+
+00000040 <.tbss_ext_gd>:
+  40:	00 00 00 00.*
+			40: R_TLSM	tbss_ext.*
+
+00000044 <tbss_ext_ld>:
+  44:	00 00 00 68.*
+			44: R_TLS_LD	tbss_ext.*
+
+00000048 <tbss_ext_ie>:
+  48:	00 00 00 68.*
+			48: R_TLS_IE	tbss_ext.*
+
+0000004c <tbss_ext_le>:
+  4c:	00 00 00 68.*
+			4c: R_TLS_LE	tbss_ext.*
+
+00000050 <_\$TLSML>:
+	...
+			50: R_TLSML	_\$TLSML.*
+
+Disassembly of section .tdata:
+
+00000058 <tdata_ext>:
+  58:	00 00 00 01 	.long 0x1
+
+0000005c <tdata_int_csect>:
+  5c:	00 00 00 02 	.long 0x2
+  60:	00 00 00 03 	.long 0x3
+  64:.*
+
+Disassembly of section .tbss:
+
+00000068 <tbss_ext>:
+	...
diff --git a/gas/testsuite/gas/ppc/xcoff-tls-64.d b/gas/testsuite/gas/ppc/xcoff-tls-64.d
new file mode 100644
index 00000000000..7f3b6ebceb6
--- /dev/null
+++ b/gas/testsuite/gas/ppc/xcoff-tls-64.d
@@ -0,0 +1,124 @@
+#as: -a64
+#source: xcoff-tls.s
+#objdump: -Dr
+#name: XCOFF TLS relocation (64 bit)
+
+.*
+
+
+Disassembly of section .data:
+
+0000000000000000 <TOC>:
+   0:	00 00 00 00.*
+			0: R_TLS	tdata_ext.*
+   4:	00 00 00 a8.*
+
+0000000000000008 <.tdata_ext_gd>:
+	...
+			8: R_TLSM	tdata_ext.*
+
+0000000000000010 <tdata_ext_ld>:
+  10:	00 00 00 00.*
+			10: R_TLS_LD	tdata_ext.*
+  14:	00 00 00 a8.*
+
+0000000000000018 <tdata_ext_ie>:
+  18:	00 00 00 00.*
+			18: R_TLS_IE	tdata_ext.*
+  1c:	00 00 00 a8.*
+
+0000000000000020 <tdata_ext_le>:
+  20:	00 00 00 00.*
+			20: R_TLS_LE	tdata_ext.*
+  24:	00 00 00 a8.*
+
+0000000000000028 <tdata_int1_gd>:
+  28:	00 00 00 00.*
+			28: R_TLS	tdata_int_csect.*
+  2c:	00 00 00 ac.*
+
+0000000000000030 <.tdata_int1_gd>:
+	...
+			30: R_TLSM	tdata_int_csect.*
+
+0000000000000038 <tdata_int1_ld>:
+  38:	00 00 00 00.*
+			38: R_TLS_LD	tdata_int_csect.*
+  3c:	00 00 00 ac.*
+
+0000000000000040 <tdata_int1_ie>:
+  40:	00 00 00 00.*
+			40: R_TLS_IE	tdata_int_csect.*
+  44:	00 00 00 ac.*
+
+0000000000000048 <tdata_int1_le>:
+  48:	00 00 00 00.*
+			48: R_TLS_LE	tdata_int_csect.*
+  4c:	00 00 00 ac.*
+
+0000000000000050 <tdata_int2_gd>:
+  50:	00 00 00 00.*
+			50: R_TLS	tdata_int_csect.*
+  54:	00 00 00 b0.*
+
+0000000000000058 <.tdata_int2_gd>:
+	...
+			58: R_TLSM	tdata_int_csect.*
+
+0000000000000060 <tdata_int2_ld>:
+  60:	00 00 00 00.*
+			60: R_TLS_LD	tdata_int_csect.*
+  64:	00 00 00 b0.*
+
+0000000000000068 <tdata_int2_ie>:
+  68:	00 00 00 00.*
+			68: R_TLS_IE	tdata_int_csect.*
+  6c:	00 00 00 b0.*
+
+0000000000000070 <tdata_int2_le>:
+  70:	00 00 00 00.*
+			70: R_TLS_LE	tdata_int_csect.*
+  74:	00 00 00 b0.*
+
+0000000000000078 <tbss_ext_gd>:
+  78:	00 00 00 00.*
+			78: R_TLS	tbss_ext.*
+  7c:	00 00 00 b8.*
+
+0000000000000080 <.tbss_ext_gd>:
+	...
+			80: R_TLSM	tbss_ext.*
+
+0000000000000088 <tbss_ext_ld>:
+  88:	00 00 00 00.*
+			88: R_TLS_LD	tbss_ext.*
+  8c:	00 00 00 b8.*
+
+0000000000000090 <tbss_ext_ie>:
+  90:	00 00 00 00.*
+			90: R_TLS_IE	tbss_ext.*
+  94:	00 00 00 b8.*
+
+0000000000000098 <tbss_ext_le>:
+  98:	00 00 00 00.*
+			98: R_TLS_LE	tbss_ext.*
+  9c:	00 00 00 b8.*
+
+00000000000000a0 <_\$TLSML>:
+	...
+			a0: R_TLSML	_\$TLSML-0xa0
+
+Disassembly of section .tdata:
+
+00000000000000a8 <tdata_ext>:
+  a8:	00 00 00 01 	.long 0x1
+
+00000000000000ac <tdata_int_csect>:
+  ac:	00 00 00 02 	.long 0x2
+  b0:	00 00 00 03 	.long 0x3
+  b4:.*
+
+Disassembly of section .tbss:
+
+00000000000000b8 <tbss_ext>:
+	...
diff --git a/gas/testsuite/gas/ppc/xcoff-tls.s b/gas/testsuite/gas/ppc/xcoff-tls.s
new file mode 100644
index 00000000000..83e77f19c1e
--- /dev/null
+++ b/gas/testsuite/gas/ppc/xcoff-tls.s
@@ -0,0 +1,57 @@
+# An external tdata symbol
+  .globl tdata_ext[TL]
+  .csect tdata_ext[TL]
+  .long 1
+
+  .csect tdata_int_csect[TL]
+# A first internal tdata symbol
+tdata_int1:
+  .long 2
+# A second internal tdata symbol
+tdata_int2:
+  .long 3
+
+# Two external tbss symbols.
+# XCOFF doesn't seem to allow internal tbss
+# (or bss) symbols.
+  .comm tbss_ext[UL],8
+
+  .toc
+# TC entries targeting the external tdata symbol
+# Their value should be "tdata_ext" address,
+# except TLSM value which must be 0.
+# Their relocations should target it.
+  .tc  tdata_ext_gd[TC],tdata_ext[TL]
+  .tc .tdata_ext_gd[TC],tdata_ext[TL]@m
+  .tc  tdata_ext_ld[TC],tdata_ext[TL]@ld
+  .tc  tdata_ext_ie[TC],tdata_ext[TL]@ie
+  .tc  tdata_ext_le[TC],tdata_ext[TL]@le
+
+# TC entries targeting internal tdata symbols.
+# Their value should be "tdata_int1" or "tdata_int2"
+# addresses, except TLSM value which must be 0.
+# Their relocations should target "tdata_int_csect".
+  .tc  tdata_int1_gd[TC],tdata_int1
+  .tc .tdata_int1_gd[TC],tdata_int1@m
+  .tc  tdata_int1_ld[TC],tdata_int1@ld
+  .tc  tdata_int1_ie[TC],tdata_int1@ie
+  .tc  tdata_int1_le[TC],tdata_int1@le
+  .tc  tdata_int2_gd[TC],tdata_int2
+  .tc .tdata_int2_gd[TC],tdata_int2@m
+  .tc  tdata_int2_ld[TC],tdata_int2@ld
+  .tc  tdata_int2_ie[TC],tdata_int2@ie
+  .tc  tdata_int2_le[TC],tdata_int2@le
+
+# TC entries targeting the external tdata symbol
+# Their value should be "tbss_ext" address,
+# except TLSM value which must be 0.
+# Their relocations should target "tbss_ext".
+  .tc  tbss_ext_gd[TC],tbss_ext[UL]
+  .tc .tbss_ext_gd[TC],tbss_ext[UL]@m
+  .tc  tbss_ext_ld[TC],tbss_ext[UL]@ld
+  .tc  tbss_ext_ie[TC],tbss_ext[UL]@ie
+  .tc  tbss_ext_le[TC],tbss_ext[UL]@le
+
+# Module entry
+  .tc  mh[TC],mh[TC]@ml
+.rename mh[TC], "_$TLSML" # Symbol for the module handle
diff --git a/gas/testsuite/gas/ppc/xcoff-tlsm-32.d b/gas/testsuite/gas/ppc/xcoff-tlsm-32.d
deleted file mode 100644
index a09dd1a2e4a..00000000000
--- a/gas/testsuite/gas/ppc/xcoff-tlsm-32.d
+++ /dev/null
@@ -1,34 +0,0 @@
-#as: -a32
-#source: xcoff-tlsm.s
-#objdump: -Dr
-#name: XCOFF TLSM relocation (32 bit)
-
-.*
-Disassembly of section .data:
-
-00000000 <TOC>:
-   0:	00 00 00 10.*
-			0: R_TLS	foo_tdata-0x10
-
-00000004 <.foo_tdata>:
-   4:	00 00 00 00.*
-			4: R_TLSM	foo_tdata-0x10
-
-00000008 <foo_tbss>:
-   8:	00 00 00 20.*
-			8: R_TLS	foo_tbss-0x20
-
-0000000c <.foo_tbss>:
-   c:	00 00 00 00.*
-			c: R_TLSM	foo_tbss-0x20
-
-Disassembly of section .tdata:
-
-00000010 <foo_tdata>:
-  10:	00 00 00 01.*
-	...
-
-Disassembly of section .tbss:
-
-00000020 <foo_tbss>:
-	...
diff --git a/gas/testsuite/gas/ppc/xcoff-tlsm-64.d b/gas/testsuite/gas/ppc/xcoff-tlsm-64.d
deleted file mode 100644
index f447a517742..00000000000
--- a/gas/testsuite/gas/ppc/xcoff-tlsm-64.d
+++ /dev/null
@@ -1,36 +0,0 @@
-#as: -a64
-#source: xcoff-tlsm.s
-#objdump: -Dr
-#name: XCOFF TLSM relocation (64 bit)
-
-.*
-Disassembly of section .data:
-
-0000000000000000 <TOC>:
-   0:	00 00 00 00.*
-			0: R_TLS	foo_tdata-0x20
-   4:	00 00 00 20.*
-
-0000000000000008 <.foo_tdata>:
-	...
-			8: R_TLSM	foo_tdata-0x20
-
-0000000000000010 <foo_tbss>:
-  10:	00 00 00 00.*
-			10: R_TLS	foo_tbss-0x30
-  14:	00 00 00 30.*
-
-0000000000000018 <.foo_tbss>:
-	...
-			18: R_TLSM	foo_tbss-0x30
-
-Disassembly of section .tdata:
-
-0000000000000020 <foo_tdata>:
-  20:	00 00 00 01.*
-	...
-
-Disassembly of section .tbss:
-
-0000000000000030 <foo_tbss>:
-	...
diff --git a/gas/testsuite/gas/ppc/xcoff-tlsm.s b/gas/testsuite/gas/ppc/xcoff-tlsm.s
deleted file mode 100644
index 0c857bf0aa9..00000000000
--- a/gas/testsuite/gas/ppc/xcoff-tlsm.s
+++ /dev/null
@@ -1,12 +0,0 @@
-  .csect foo_tdata[TL],4
-  .align 2
-foo_tdata:
-  .long	1
-
-  .comm foo_tbss[UL],8
-
-  .toc
-  .tc foo_tdata[TC],foo_tdata[TL]
-  .tc .foo_tdata[TC],foo_tdata[TL]@m
-  .tc foo_tbss[TC],foo_tbss[UL]
-  .tc .foo_tbss[TC],foo_tbss[UL]@m
diff --git a/ld/testsuite/ld-powerpc/aix-tls-reloc-32.d b/ld/testsuite/ld-powerpc/aix-tls-reloc-32.d
deleted file mode 100644
index 5103de50618..00000000000
--- a/ld/testsuite/ld-powerpc/aix-tls-reloc-32.d
+++ /dev/null
@@ -1,35 +0,0 @@
-#source: aix-tls-reloc.s
-#as: -a32
-#ld: -b32 -shared -bE:aix-tls-reloc.ex
-#objdump: -dr
-#target: [is_xcoff_format]
-
-.*
-
-Disassembly of section \.text:
-
-.* <\.foo>:
-.*:	80 82 00 00 	l       r4,0\(r2\)
-.*: R_TOC	gd-.*
-.*:	80 62 00 04 	l       r3,4\(r2\)
-.*: R_TOC	.gd-.*
-.*:	48 00 00 03 	bla     0 <\.foo-.*>
-.*: R_BA_26	__tls_get_addr
-.*:	80 62 00 0c 	l       r3,12\(r2\)
-.*: R_TOC	_\$TLSML-.*
-.*:	48 00 00 03 	bla     0 <\.foo-.*>
-.*: R_BA_26	__tls_get_mod
-.*:	80 82 00 08 	l       r4,8\(r2\)
-.*: R_TOC	ld-.*
-.*:	7c a3 22 14 	cax     r5,r3,r4
-.*:	48 00 00 03 	bla     0 <\.foo-.*>
-.*: R_BA_26	__get_tpointer
-.*:	80 82 00 10 	l       r4,16\(r2\)
-.*: R_TOC	ie-.*
-.*:	7c a3 22 14 	cax     r5,r3,r4
-.*:	48 00 00 03 	bla     0 <\.foo-.*>
-.*: R_BA_26	__get_tpointer
-.*:	80 82 00 14 	l       r4,20\(r2\)
-.*: R_TOC	le-.*
-.*:	7c a3 22 14 	cax     r5,r3,r4
-.*
diff --git a/ld/testsuite/ld-powerpc/aix-tls-reloc-32.dd b/ld/testsuite/ld-powerpc/aix-tls-reloc-32.dd
new file mode 100644
index 00000000000..001a7f0c65e
--- /dev/null
+++ b/ld/testsuite/ld-powerpc/aix-tls-reloc-32.dd
@@ -0,0 +1,101 @@
+#source: aix-tls-reloc.s
+#as: -a32
+#ld: -b32 -shared -bE:aix-tls-reloc.ex
+#objdump: -dr -j.data
+#target: [is_xcoff_format]
+
+.*
+
+
+Disassembly of section .data:
+
+.* <foo>:
+.*
+.*
+.*
+.*
+.*
+
+.* <TOC>:
+.*:	ff ff 88 00 .*
+.*: R_TLS	tdata_ext.*
+
+.* <.tdata_ext_gd>:
+.*:	00 00 00 00 .*
+.*: R_TLSM	tdata_ext.*
+
+.* <tdata_ext_ld>:
+.*:	ff ff 88 00 .*
+.*: R_TLS_LD	tdata_ext.*
+
+.* <tdata_ext_ie>:
+.*:	ff ff 88 00 .*
+.*: R_TLS_IE	tdata_ext.*
+
+.* <tdata_ext_le>:
+.*:	ff ff 88 00 .*
+.*: R_TLS_LE	tdata_ext.*
+
+.* <tdata_int1_gd>:
+.*:	ff ff 88 04 .*
+.*: R_TLS	tdata_int_csect.*
+
+.* <.tdata_int1_gd>:
+.*:	00 00 00 00 .*
+.*: R_TLSM	tdata_int_csect.*
+
+.* <tdata_int1_ld>:
+.*:	ff ff 88 04 .*
+.*: R_TLS_LD	tdata_int_csect.*
+
+.* <tdata_int1_ie>:
+.*:	ff ff 88 04 .*
+.*: R_TLS_IE	tdata_int_csect.*
+
+.* <tdata_int1_le>:
+.*:	ff ff 88 04 .*
+.*: R_TLS_LE	tdata_int_csect.*
+
+.* <tdata_int2_gd>:
+.*:	ff ff 88 08 .*
+.*: R_TLS	tdata_int_csect.*
+
+.* <.tdata_int2_gd>:
+.*:	00 00 00 00 .*
+.*: R_TLSM	tdata_int_csect.*
+
+.* <tdata_int2_ld>:
+.*:	ff ff 88 08 .*
+.*: R_TLS_LD	tdata_int_csect.*
+
+.* <tdata_int2_ie>:
+.*:	ff ff 88 08 .*
+.*: R_TLS_IE	tdata_int_csect.*
+
+.* <tdata_int2_le>:
+.*:	ff ff 88 08 .*
+.*: R_TLS_LE	tdata_int_csect.*
+
+.* <tbss_ext_gd>:
+.*:	ff ff 88 10 .*
+.*: R_TLS	tbss_ext.*
+
+.* <.tbss_ext_gd>:
+.*:	00 00 00 00 .*
+.*: R_TLSM	tbss_ext.*
+
+.* <tbss_ext_ld>:
+.*:	ff ff 88 10 .*
+.*: R_TLS_LD	tbss_ext.*
+
+.* <tbss_ext_ie>:
+.*:	ff ff 88 10 .*
+.*: R_TLS_IE	tbss_ext.*
+
+.* <tbss_ext_le>:
+.*:	ff ff 88 10 .*
+.*: R_TLS_LE	tbss_ext.*
+
+.* <_\$TLSML>:
+	...
+.*: R_TLSML	_\$TLSML.*
diff --git a/ld/testsuite/ld-powerpc/aix-tls-reloc-32.dt b/ld/testsuite/ld-powerpc/aix-tls-reloc-32.dt
new file mode 100644
index 00000000000..91ceb669eb9
--- /dev/null
+++ b/ld/testsuite/ld-powerpc/aix-tls-reloc-32.dt
@@ -0,0 +1,18 @@
+
+tmpdir/aix-tls-reloc.so:     file format aixcoff-rs6000
+
+
+Disassembly of section .tdata:
+
+ffff8800 <tdata_ext>:
+ffff8800:	00 00 00 01 	.long 0x1
+
+ffff8804 <tdata_int_csect>:
+ffff8804:	00 00 00 02 	.long 0x2
+ffff8808:	00 00 00 03 	.long 0x3
+ffff880c:	00 00 00 00 	.long 0x0
+
+Disassembly of section .tbss:
+
+ffff8810 <tbss_ext>:
+	...
diff --git a/ld/testsuite/ld-powerpc/aix-tls-reloc-64.d b/ld/testsuite/ld-powerpc/aix-tls-reloc-64.d
deleted file mode 100644
index 71f6302ec4d..00000000000
--- a/ld/testsuite/ld-powerpc/aix-tls-reloc-64.d
+++ /dev/null
@@ -1,31 +0,0 @@
-#source: aix-tls-reloc.s
-#as: -a32
-#ld: -b32 -shared -bE:aix-tls-reloc.ex
-#objdump: -dr
-#target: [is_xcoff_format]
-
-.*
-
-Disassembly of section \.text:
-
-.* <\.foo>:
-.*:	e8 82 00 00 	ld      r4,0\(r2\)
-.*: R_TOC	gd-.*
-.*:	e8 62 00 08 	ld      r3,8\(r2\)
-.*: R_TOC	.gd-.*
-.*:	48 00 00 03 	bla     0 <\.foo-.*>
-.*: R_BA_26	__tls_get_addr
-.*:	e8 62 00 18 	ld      r3,24\(r2\)
-.*: R_TOC	_\$TLSML-.*
-.*:	48 00 00 03 	bla     0 <\.foo-.*>
-.*: R_BA_26	__tls_get_mod
-.*:	80 82 00 10 	lwz     r4,16\(r2\)
-.*: R_TOC	ld-.*
-.*:	7c a3 22 14 	add     r5,r3,r4
-.*:	e8 82 00 20 	ld      r4,32\(r2\)
-.*: R_TOC	ie-.*
-.*:	7c a4 6a 14 	add     r5,r4,r13
-.*:	e8 82 00 28 	ld      r4,40\(r2\)
-.*: R_TOC	le-.*
-.*:	7c a3 6a 14 	add     r5,r3,r13
-.*
diff --git a/ld/testsuite/ld-powerpc/aix-tls-reloc-64.dd b/ld/testsuite/ld-powerpc/aix-tls-reloc-64.dd
new file mode 100644
index 00000000000..dc0c48d1163
--- /dev/null
+++ b/ld/testsuite/ld-powerpc/aix-tls-reloc-64.dd
@@ -0,0 +1,119 @@
+#source: aix-tls-reloc.s
+#as: -a64
+#ld: -b64 -shared -bE:aix-tls-reloc.ex
+#objdump: -dr -j.data
+#target: [is_xcoff_format]
+
+.*
+
+
+Disassembly of section .data:
+
+.* <foo>:
+.*
+.*
+.*
+.*
+.*
+.*
+.*
+
+.* <TOC>:
+.*:	ff ff ff ff .*
+.*: R_TLS	tdata_ext.*
+.*:	ff ff 88 00 .*
+
+.* <.tdata_ext_gd>:
+	...
+.*: R_TLSM	tdata_ext.*
+
+.*<tdata_ext_ld>:
+.*:	ff ff ff ff .*
+.*: R_TLS_LD	tdata_ext.*
+.*:	ff ff 88 00 .*
+
+.* <tdata_ext_ie>:
+.*:	ff ff ff ff .*
+.*: R_TLS_IE	tdata_ext.*
+.*:	ff ff 88 00 .*
+
+.* <tdata_ext_le>:
+.*:	ff ff ff ff .*
+.*: R_TLS_LE	tdata_ext.*
+.*:	ff ff 88 00 .*
+
+.* <tdata_int1_gd>:
+.*:	ff ff ff ff .*
+.*: R_TLS	tdata_int_csect.*
+.*:	ff ff 88 04 .*
+
+.* <.tdata_int1_gd>:
+	...
+.*: R_TLSM	tdata_int_csect.*
+
+.* <tdata_int1_ld>:
+.*:	ff ff ff ff .*
+.*: R_TLS_LD	tdata_int_csect.*
+.*:	ff ff 88 04 .*
+
+.* <tdata_int1_ie>:
+.*:	ff ff ff ff .*
+.*: R_TLS_IE	tdata_int_csect.*
+.*:	ff ff 88 04 .*
+
+.* <tdata_int1_le>:
+.*:	ff ff ff ff .*
+.*: R_TLS_LE	tdata_int_csect.*
+.*:	ff ff 88 04 .*
+
+.* <tdata_int2_gd>:
+.*:	ff ff ff ff .*
+.*: R_TLS	tdata_int_csect.*
+.*:	ff ff 88 08 .*
+
+.* <.tdata_int2_gd>:
+	...
+.*: R_TLSM	tdata_int_csect.*
+
+.* <tdata_int2_ld>:
+.*:	ff ff ff ff .*
+.*: R_TLS_LD	tdata_int_csect.*
+.*:	ff ff 88 08 .*
+
+.* <tdata_int2_ie>:
+.*:	ff ff ff ff .*
+.*: R_TLS_IE	tdata_int_csect.*
+.*:	ff ff 88 08 .*
+
+.* <tdata_int2_le>:
+.*:	ff ff ff ff .*
+.*: R_TLS_LE	tdata_int_csect.*
+.*:	ff ff 88 08 .*
+
+.* <tbss_ext_gd>:
+.*:	ff ff ff ff .*
+.*: R_TLS	tbss_ext.*
+.*:	ff ff 88 10 .*
+
+.* <.tbss_ext_gd>:
+	...
+.*: R_TLSM	tbss_ext.*
+
+.* <tbss_ext_ld>:
+.*:	ff ff ff ff .*
+.*: R_TLS_LD	tbss_ext.*
+.*:	ff ff 88 10 .*
+
+.* <tbss_ext_ie>:
+.*:	ff ff ff ff .*
+.*: R_TLS_IE	tbss_ext.*
+.*:	ff ff 88 10 .*
+
+.* <tbss_ext_le>:
+.*:	ff ff ff ff .*
+.*: R_TLS_LE	tbss_ext.*
+.*:	ff ff 88 10 .*
+
+.* <_\$TLSML>:
+	...
+.*: R_TLSML	_\$TLSML.*
diff --git a/ld/testsuite/ld-powerpc/aix-tls-reloc-64.dt b/ld/testsuite/ld-powerpc/aix-tls-reloc-64.dt
new file mode 100644
index 00000000000..9ddc5737e3a
--- /dev/null
+++ b/ld/testsuite/ld-powerpc/aix-tls-reloc-64.dt
@@ -0,0 +1,23 @@
+#source: aix-tls-reloc.s
+#as: -a64
+#ld: -b64 -shared -bE:aix-tls-reloc.ex
+#objdump: -d -j.tdata -j.tbss
+#target: [is_xcoff_format]
+
+.*
+
+
+Disassembly of section .tdata:
+
+ffffffffffff8800 <tdata_ext>:
+ffffffffffff8800:.*
+
+ffffffffffff8804 <tdata_int_csect>:
+ffffffffffff8804:.*
+ffffffffffff8808:.*
+ffffffffffff880c:.*
+
+Disassembly of section .tbss:
+
+ffffffffffff8810 <tbss_ext>:
+	...
diff --git a/ld/testsuite/ld-powerpc/aix-tls-reloc.s b/ld/testsuite/ld-powerpc/aix-tls-reloc.s
index 62ef73cdc34..062fc949846 100644
--- a/ld/testsuite/ld-powerpc/aix-tls-reloc.s
+++ b/ld/testsuite/ld-powerpc/aix-tls-reloc.s
@@ -1,65 +1,147 @@
-  .globl bar[TL]
-  .csect bar[TL]
+# An external tdata symbol
+  .globl tdata_ext[TL]
+  .csect tdata_ext[TL]
   .long 1
 
+  .csect tdata_int_csect[TL]
+# A first internal tdata symbol
+tdata_int1:
+  .long 2
+# A second internal tdata symbol
+tdata_int2:
+  .long 3
+
+# Two external tbss symbols.
+# XCOFF doesn't seem to allow internal tbss
+# (or bss) symbols.
+  .comm tbss_ext[UL],8
+
   .toc
-  .tc gd[TC],bar[TL]
-  .tc .gd[TC],bar[TL]@m
-  .tc ld[TC],bar[TL]@ld
-  .tc mh[TC],mh[TC]@ml
-  .tc ie[TC],bar[TL]@ie
-  .tc le[TC],bar[TL]@le
+# TC entries targeting the external tdata symbol
+# Their value should be "tdata_ext" address,
+# except TLSM value which must be 0.
+# Their relocations should target it.
+  .tc  tdata_ext_gd[TC],tdata_ext[TL]
+  .tc .tdata_ext_gd[TC],tdata_ext[TL]@m
+  .tc  tdata_ext_ld[TC],tdata_ext[TL]@ld
+  .tc  tdata_ext_ie[TC],tdata_ext[TL]@ie
+  .tc  tdata_ext_le[TC],tdata_ext[TL]@le
 
-  .globl foo
-  .globl .foo
-  .csect foo[DS],3
-foo:
-  .if size == 32
-  .long	.foo, TOC[tc0], 0
-  .else
-  .llong .foo, TOC[tc0], 0
-  .endif
+# TC entries targeting internal tdata symbols.
+# Their value should be "tdata_int1" or "tdata_int2"
+# addresses, except TLSM value which must be 0.
+# Their relocations should target "tdata_int_csect".
+  .tc  tdata_int1_gd[TC],tdata_int1
+  .tc .tdata_int1_gd[TC],tdata_int1@m
+  .tc  tdata_int1_ld[TC],tdata_int1@ld
+  .tc  tdata_int1_ie[TC],tdata_int1@ie
+  .tc  tdata_int1_le[TC],tdata_int1@le
+  .tc  tdata_int2_gd[TC],tdata_int2
+  .tc .tdata_int2_gd[TC],tdata_int2@m
+  .tc  tdata_int2_ld[TC],tdata_int2@ld
+  .tc  tdata_int2_ie[TC],tdata_int2@ie
+  .tc  tdata_int2_le[TC],tdata_int2@le
 
-  .csect foo[PR]
-.foo:
-  #GD
+# TC entries targeting the external tdata symbol
+# Their value should be "tbss_ext" address,
+# except TLSM value which must be 0.
+# Their relocations should target "tbss_ext".
+  .tc  tbss_ext_gd[TC],tbss_ext[UL]
+  .tc .tbss_ext_gd[TC],tbss_ext[UL]@m
+  .tc  tbss_ext_ld[TC],tbss_ext[UL]@ld
+  .tc  tbss_ext_ie[TC],tbss_ext[UL]@ie
+  .tc  tbss_ext_le[TC],tbss_ext[UL]@le
+
+# Module entry
+  .tc  mh[TC],mh[TC]@ml
+  .rename mh[TC], "_$TLSML" # Symbol for the module handle
+
+# Macros
+  .macro gd_macro,sym
   .if size == 32
-  lwz 4, gd[TC](2)
-  lwz 3, .gd[TC](2)
+  lwz 4, \sym\()[TC](2)
+  lwz 3, .\sym\()[TC](2)
   .else
-  ld 4, gd[TC](2)
-  ld 3, .gd[TC](2)
+  ld 4, \sym\()[TC](2)
+  ld 3, .\sym\()[TC](2)
   .endif
   bla __tls_get_addr
+  .endm
 
-  #LD
+  .macro ld_macro, sym
   .if size == 32
-  lwz 3, mh[TC](2)
+  lwz 4, \sym\()[TC](2)
   .else
-  ld 3, mh[TC](2)
+  ld 4, \sym\()[TC](2)
   .endif
-  bla __tls_get_mod
-  lwz 4, ld[TC](2)
   add 5,3,4
+  .endm
 
-  #IE
+  .macro ie_macro, sym
   .if size == 32
   bla __get_tpointer
-  lwz 4, ie[TC](2)
+  lwz 4, \sym\()[TC](2)
   add 5,3,4
   .else
-  ld 4, ie[TC](2)
+  ld 4, \sym\()[TC](2)
   add 5,4,13
   .endif
+  .endm
 
-  #LE
+  .macro le_macro, sym
   .if size == 32
   bla __get_tpointer
-  lwz 4, le[TC](2)
+  lwz 4, \sym\()[TC](2)
   add 5,3,4
   .else
-  ld 4, le[TC](2)
+  ld 4, \sym\()[TC](2)
   add 5,3,13
   .endif
+  .endm
+
+
+# As TLS relocations are made in for TC symbols,
+# this function only aims to avoid garbage collection
+# of these symbols, especially hidden ones.
+  .globl foo
+  .globl .foo
+  .csect foo[DS],3
+foo:
+  .if size == 32
+  .long	.foo, TOC[tc0], 0
+  .else
+  .llong .foo, TOC[tc0], 0
+  .endif
+
+  .csect foo[PR]
+.foo:
+  # External syms
+  #GD
+  gd_macro tdata_ext_gd
+  gd_macro tdata_int1_gd
+  gd_macro tdata_int2_gd
+  gd_macro tbss_ext_gd
+
+  #LD
+  .if size == 32
+  lwz 3, mh[TC](2)
+  .else
+  ld 3, mh[TC](2)
+  .endif
+  bla __tls_get_mod
+  ld_macro tdata_ext_ld
+  ld_macro tdata_int1_ld
+  ld_macro tdata_int2_ld
+  ld_macro tbss_ext_ld
 
-.rename mh[TC], "_$TLSML" # Symbol for the module handle
+  #IE
+  ie_macro tdata_ext_ie
+  ie_macro tdata_int1_ie
+  ie_macro tdata_int2_ie
+  ie_macro tbss_ext_ie
+
+  #LE
+  le_macro tdata_ext_le
+  le_macro tdata_int1_le
+  le_macro tdata_int2_le
+  le_macro tbss_ext_le
diff --git a/ld/testsuite/ld-powerpc/aix52.exp b/ld/testsuite/ld-powerpc/aix52.exp
index 8dccce50ff5..b49f3f5e1cf 100644
--- a/ld/testsuite/ld-powerpc/aix52.exp
+++ b/ld/testsuite/ld-powerpc/aix52.exp
@@ -284,7 +284,8 @@ set aix7tests {
 
     {"TLS relocations" "-shared -bE:aix-tls-reloc.ex"
 	"" {aix-tls-reloc.s}
-	{{objdump -dr aix-tls-reloc-SIZE.d}}
+	{{objdump {-dr -j.data} aix-tls-reloc-SIZE.dd}
+	 {objdump {-dr -j.tdata -j.tbss} aix-tls-reloc-SIZE.dt}}
 	"aix-tls-reloc.so"}
 
     {"TLS section" "-shared -bE:aix-tls-section.ex"
-- 
2.25.1


^ permalink raw reply	[flat|nested] 2+ messages in thread

* Re: [PATCH] XCOFF: add support for TLS relocations on hidden symbols
  2022-01-06 12:49 [PATCH] XCOFF: add support for TLS relocations on hidden symbols CHIGOT, CLEMENT
@ 2022-01-10  2:21 ` Alan Modra
  0 siblings, 0 replies; 2+ messages in thread
From: Alan Modra @ 2022-01-10  2:21 UTC (permalink / raw)
  To: CHIGOT, CLEMENT; +Cc: binutils

On Thu, Jan 06, 2022 at 12:49:20PM +0000, CHIGOT, CLEMENT via Binutils wrote:
> This patch adds support for TLS relocation targeting C_HIDEXT symbols.
> In gas, TLS relocations, except R_TLSM and R_TLMSL, must keep the value
> of their target symbol.
> In ld, it simply ensures that internal TLS symbols are added to the
> linker hash table for xcoff_reloc_type_tls.
> 
> It also improves the tests made by both.

OK.

-- 
Alan Modra
Australia Development Lab, IBM

^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2022-01-10  2:21 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-01-06 12:49 [PATCH] XCOFF: add support for TLS relocations on hidden symbols CHIGOT, CLEMENT
2022-01-10  2:21 ` Alan Modra

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).