diff mbox

AIX symbol encoding

Message ID CAGWvny=mb1X9MLCNa-F+-4Yva=98JvB7UO49uyDdHptCut=cbw@mail.gmail.com
State New
Headers show

Commit Message

David Edelsohn Oct. 17, 2016, 1:54 p.m. UTC
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.

Comments

Segher Boessenkool Oct. 17, 2016, 6:32 p.m. UTC | #1
Hi David,

On Mon, Oct 17, 2016 at 09:54:35AM -0400, David Edelsohn wrote:
> This patch shifts earlier the point during compilation where the
> rs6000 backend adds decoration to symbols: to encode_section_info.

> -  /* 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.  */

I think this comment should go...

>    if (VTABLE_NAME_P (name))
>      {
>        RS6000_OUTPUT_BASENAME (file, name);

... before here.

Otherwise looks fine.  Do you want this tested on Linux before you
commit?  We never test on AIX beforehand either ;-)


Segher
diff mbox

Patch

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 */