aix: 64 bit AIX TLS libpthread dependency.
authorClément Chigot <clement.chigot@atos.net>
Thu, 12 Aug 2021 17:17:15 +0000 (13:17 -0400)
committerDavid Edelsohn <dje.gcc@gmail.com>
Sun, 15 Aug 2021 17:26:27 +0000 (13:26 -0400)
64bit XCOFF files will generated TLS access, with local-exec or
global-exec models, by an access to R13. Thus, there isn't
any reference to a TLS symbol.

The problem is that it allows programs with TLS to be compiled and
linked even without -pthread. Most of the time, it will result in
a segfault when trying to access a TLS variable. But sometimes, it
might create a memory corruption.

This patch forces a reference to __tls_get_addr() to ensure link
will fail without -pthread.

gcc/ChangeLog:
2021-08-11  Clément Chigot  <clement.chigot@atos.net>

* config/rs6000/rs6000.c (xcoff_tls_exec_model_detected): New.
(rs6000_legitimize_tls_address_aix): Use it.
(rs6000_xcoff_file_end): Add ".ref __tls_get_addr" when
xcoff_tls_exec_model_detected is true.

gcc/config/rs6000/rs6000.c

index 60f406a..e073b26 100644 (file)
@@ -127,6 +127,9 @@ scalar_int_mode rs6000_pmode;
 bool rs6000_passes_ieee128 = false;
 #endif
 
+/* Track use of r13 in 64bit AIX TLS.  */
+static bool xcoff_tls_exec_model_detected = false;
+
 /* Generate the manged name (i.e. U10__float128) used in GCC 8.1, and not the
    name used in current releases (i.e. u9__ieee128).  */
 static bool ieee128_mangling_gcc_8_1;
@@ -9397,7 +9400,10 @@ rs6000_legitimize_tls_address_aix (rtx addr, enum tls_model model)
       emit_insn (gen_tls_get_tpointer (tlsreg));
     }
   else
-    tlsreg = gen_rtx_REG (DImode, 13);
+    {
+      tlsreg = gen_rtx_REG (DImode, 13);
+      xcoff_tls_exec_model_detected = true;
+    }
 
   /* Load the TOC value into temporary register.  */
   tmpreg = gen_reg_rtx (Pmode);
@@ -21122,6 +21128,12 @@ rs6000_xcoff_file_end (void)
   fputs (TARGET_32BIT
         ? "\t.long _section_.text\n" : "\t.llong _section_.text\n",
         asm_out_file);
+
+  if (xcoff_tls_exec_model_detected)
+    {
+      /* Add a .ref to __tls_get_addr to force libpthread dependency.  */
+      fputs ("\t.extern __tls_get_addr\n\t.ref __tls_get_addr\n", asm_out_file);
+    }
 }
 
 struct declare_alias_data