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