This patch shifts earlier the point during compilation where the
rs6000 backend adds decoration to symbols: to encode_section_info.

AIX uses the XCOFF file format, which extends COFF in a few ways,
including some increased granularity of sections through a mechanism
called Storage Mapping Class -- a decoration for identifiers that maps
to a COFF section.

Because of the order in which GCC emits symbols and the behavior of
the AIX Assembler, the AIX Assembler can see an early reference to an
undeclared identifier and create a symbol in the wrong section.

The rs6000 backend has been addressing this by emitting storage
mapping class decorations on DECLs declared external in
OUTPUT_SYMBOL_REF.  The rs6000 port replaces the string so that future
references also contain the mapping class.  This string replacement
conflicts with some hash tables so that the port emitted multiple
references to the symbol.

This patch changes the point at which the mapping class is added and
the string is replaced to encode_section_info hook called by
make_decl_rtl() and friends.  The patch also moves the string
management to the stringpool instead of malloc() called by concat().

Bootstrapped on powerpc-ibm-aix7.1.0.0.

Thanks, David

* config/rs6000/rs6000.c (rs6000_output_symbol_ref): Move storage
mapping class decoration from here ...
(rs6000_xcoff_encode_section): to here.

Index: rs6000.c
===================================================================
--- rs6000.c    (revision 241237)
+++ rs6000.c    (working copy)
@@ -30667,31 +30668,8 @@ rs6000_xcoff_strip_dollar (const char *name)
 void
 rs6000_output_symbol_ref (FILE *file, rtx x)
 {
-  /* Currently C++ toc references to vtables can be emitted before it
-     is decided whether the vtable is public or private.  If this is
-     the case, then the linker will eventually complain that there is
-     a reference to an unknown section.  Thus, for vtables only,
-     we emit the TOC reference to reference the symbol and not the
-     section.  */
   const char *name = XSTR (x, 0);

-  tree decl = SYMBOL_REF_DECL (x);
-  if (decl /* sync condition with assemble_external () */
-      && DECL_P (decl) && DECL_EXTERNAL (decl) && TREE_PUBLIC (decl)
-      && (TREE_CODE (decl) == VAR_DECL
-         || TREE_CODE (decl) == FUNCTION_DECL)
-      && name[strlen (name) - 1] != ']')
-    {
-      name = concat (name,
-                    (TREE_CODE (decl) == FUNCTION_DECL
-                     ? "[DS]" : "[UA]"),
-                    NULL);
-
-      /* Don't modify name in extern VAR_DECL to include mapping class.  */
-      if (TREE_CODE (decl) == FUNCTION_DECL)
-       XSTR (x, 0) = name;
-    }
-
   if (VTABLE_NAME_P (name))
     {
       RS6000_OUTPUT_BASENAME (file, name);
@@ -35264,6 +35242,7 @@ rs6000_xcoff_encode_section_info (tree decl, rtx r
 {
   rtx symbol;
   int flags;
+  const char *symname;

   default_encode_section_info (decl, rtl, first);

@@ -35280,6 +35259,28 @@ rs6000_xcoff_encode_section_info (tree decl, rtx r
     flags &= ~SYMBOL_FLAG_HAS_BLOCK_INFO;

   SYMBOL_REF_FLAGS (symbol) = flags;
+
+  /* Currently C++ toc references to vtables can be emitted before it
+     is decided whether the vtable is public or private.  If this is
+     the case, then the linker will eventually complain that there is
+     a reference to an unknown section.  Thus, for vtables only,
+     we emit the TOC reference to reference the symbol and not the
+     label identifier.  */
+  symname = XSTR (symbol, 0);
+
+  if (decl /* sync condition with assemble_external () */
+      && DECL_P (decl) && DECL_EXTERNAL (decl) && TREE_PUBLIC (decl)
+      && ((TREE_CODE (decl) == VAR_DECL && !DECL_THREAD_LOCAL_P (decl))
+         || TREE_CODE (decl) == FUNCTION_DECL)
+      && symname[strlen (symname) - 1] != ']')
+    {
+      char *newname = (char *) alloca (strlen (symname) + 5);
+      strcpy (newname, symname);
+      strcat (newname, (TREE_CODE (decl) == FUNCTION_DECL
+                       ? "[DS]" : "[UA]"));
+      XSTR (symbol, 0) = ggc_strdup (newname);
+    }
+
 }
 #endif /* HAVE_AS_TLS */
 #endif /* TARGET_XCOFF */

Reply via email to