In looking at issues with libgfortran, I noticed the include definitions in 
libquadmath.h resulted
in declarations for functions in libquadmath being of type DATA.  As a result, 
the HP linker ended
up looking for data symbols instead of code symbols.  This occurred for 
functions declared with the
attribute .weakref.

On further investigation, I found that this was caused by using the generic 
.weakref assembler mnemonic
which doesn't work on the SOM target because of the code/data typing for 
symbols.  When configure finds
assembler .weakref support, this results in ASM_OUTPUT_WEAKREF being defined in 
defaults.h.  When it
is not defined the code in varasm.c will use either ASM_WEAKEN_DECL or 
ASM_WEAKEN_LABEL to handle weak
references.

After disabling ASM_WEAKEN_LABEL, it turned out that ASM_WEAKEN_LABEL can't 
handle external symbols.
It has no way to distinguish between local and external symbols.  External 
symbols need to be imported.

This patch replaces ASM_WEAKEN_LABEL with ASM_WEAKEN_DECL, and it disables the 
use of ASM_OUTPUT_WEAKREF.
It correctly handles the weakening of both local and external symbols.  The 
SDEF bit and the code/data type
are both correctly set in the symbol table.

I tried to fix the symbol type with ASM_OUTPUT_WEAKREF but this didn't work.  
The SDEF bit didn't get set.
I may go back and try to fix ASM_OUTPUT_WEAKREF in the future.

Tested on hppa2.0w-hp-hpux11.11 with no observed regressions.

Committed to trunk.

Dave

2020-04-21  John David Anglin  <dang...@gcc.gnu.org>

        * config/pa/som.h (ASM_WEAKEN_LABEL): Delete.
        (ASM_WEAKEN_DECL): New define.
        (HAVE_GAS_WEAKREF): Undefine.

diff --git a/gcc/config/pa/som.h b/gcc/config/pa/som.h
index 505fdd65d79..81aee862aa0 100644
--- a/gcc/config/pa/som.h
+++ b/gcc/config/pa/som.h
@@ -277,7 +277,7 @@ do {                                                \
 /* If GAS supports weak, we can support weak when we have working linker
    support for secondary definitions and are generating code for GAS.
    This is primarily for one-only support as SOM doesn't allow undefined
-   weak symbols.  */
+   weak symbols or weak aliases.  */
 #ifdef HAVE_GAS_WEAK
 #define TARGET_SUPPORTS_WEAK (TARGET_SOM_SDEF && TARGET_GAS)
 #else
@@ -328,12 +328,43 @@ do {                                              \
    be used to remove dead procedures.  Thus, support for named sections
    is not needed and in previous testing caused problems with various
    HP tools.  */
-#define ASM_WEAKEN_LABEL(FILE,NAME) \
-  do { fputs ("\t.weak\t", FILE);                              \
-       assemble_name (FILE, NAME);                             \
-       fputc ('\n', FILE);                                     \
-       targetm.asm_out.globalize_label (FILE, NAME);           \
-  } while (0)
+#if defined HAVE_GAS_WEAK
+#define ASM_WEAKEN_DECL(FILE,DECL,NAME,VALUE) \
+  do                                                                   \
+    {                                                                  \
+      if ((VALUE) != NULL)                                             \
+       error_at (DECL_SOURCE_LOCATION (DECL),                          \
+                 "weak aliases are not supported");                    \
+      fputs ("\t.weak\t", FILE);                                       \
+      assemble_name (FILE, NAME);                                      \
+      fputc ('\n', FILE);                                              \
+                                                                       \
+      /* Import external objects.  */                                  \
+      if (DECL_EXTERNAL (DECL))                                                
\
+       {                                                               \
+         fputs ("\t.IMPORT ", FILE);                                   \
+         assemble_name (FILE, NAME);                                   \
+         if (TREE_CODE (DECL) == FUNCTION_DECL)                        \
+           fputs (",CODE\n", FILE);                                    \
+         else                                                          \
+           fputs (",DATA\n", FILE);                                    \
+       }                                                               \
+      /* Functions are globalized by ASM_DECLARE_FUNCTION_NAME.  */    \
+      else if (TREE_CODE (DECL) != FUNCTION_DECL)                      \
+       {                                                               \
+         fputs ("\t.EXPORT ", FILE);                                   \
+         assemble_name (FILE, NAME);                                   \
+         fputs (",DATA\n", FILE);                                      \
+       }                                                               \
+    }                                                                  \
+  while (0)
+#endif
+
+/* Although gas accepts .weakref, it doesn't provide the correct symbol
+   type for function references.  For now, we use ASM_WEAKEN_DECL instead.
+   We have to undefine HAVE_GAS_WEAKREF to prevent default.h from defining
+   ASM_OUTPUT_WEAKREF.  */
+#undef HAVE_GAS_WEAKREF

 /* We can't handle weak aliases, and therefore can't support pragma weak.
    Suppress the use of pragma weak in gthr-dce.h and gthr-posix.h.  */

Reply via email to