Hi,
sorry I forgot to include cgraph and varpool changes in the patch.
Index: varpool.c
===================================================================
--- varpool.c (revision 279467)
+++ varpool.c (working copy)
@@ -539,8 +539,7 @@ varpool_node::assemble_aliases (void)
{
varpool_node *alias = dyn_cast <varpool_node *> (ref->referring);
if (alias->symver)
- do_assemble_symver (alias->decl,
- DECL_ASSEMBLER_NAME (decl));
+ do_assemble_symver (alias->decl, decl);
else if (!alias->transparent_alias)
do_assemble_alias (alias->decl,
DECL_ASSEMBLER_NAME (decl));
Index: cgraphunit.c
===================================================================
--- cgraphunit.c (revision 279467)
+++ cgraphunit.c (working copy)
@@ -2222,8 +2222,7 @@ cgraph_node::assemble_thunks_and_aliases
of buffering it in same alias pairs. */
TREE_ASM_WRITTEN (decl) = 1;
if (alias->symver)
- do_assemble_symver (alias->decl,
- DECL_ASSEMBLER_NAME (decl));
+ do_assemble_symver (alias->decl, decl);
else
do_assemble_alias (alias->decl,
DECL_ASSEMBLER_NAME (decl));
Index: varasm.c
===================================================================
--- varasm.c (revision 279467)
+++ varasm.c (working copy)
@@ -5970,9 +5970,47 @@ do_assemble_symver (tree decl, tree targ
ultimate_transparent_alias_target (&id);
ultimate_transparent_alias_target (&target);
#ifdef ASM_OUTPUT_SYMVER_DIRECTIVE
- ASM_OUTPUT_SYMVER_DIRECTIVE (asm_out_file,
- IDENTIFIER_POINTER (target),
- IDENTIFIER_POINTER (id));
+ if (TREE_PUBLIC (target) && DECL_VISIBILITY (target) == VISIBILITY_DEFAULT)
+ ASM_OUTPUT_SYMVER_DIRECTIVE (asm_out_file,
+ IDENTIFIER_POINTER
+ (DECL_ASSEMBLER_NAME (target)),
+ IDENTIFIER_POINTER (id));
+ else
+ {
+ int nameend;
+ for (nameend = 0; IDENTIFIER_POINTER (id)[nameend] != '@'; nameend++)
+ ;
+ if (IDENTIFIER_POINTER (id)[nameend + 1] != '@'
+ || IDENTIFIER_POINTER (id)[nameend + 2] == '@')
+ {
+ sorry_at (DECL_SOURCE_LOCATION (target),
+ "can not produce %<symver%> of a symbol that is "
+ "not exported with default visibility");
+ return;
+ }
+ tree tmpdecl = copy_node (decl);
+ char buf[256];
+ static int symver_labelno;
+ targetm.asm_out.generate_internal_label (buf,
+ "LSYMVER", symver_labelno++);
+ SET_DECL_ASSEMBLER_NAME (tmpdecl, get_identifier (buf));
+ globalize_decl (tmpdecl);
+#ifdef ASM_OUTPUT_DEF_FROM_DECLS
+ ASM_OUTPUT_DEF_FROM_DECLS (asm_out_file, tmpdecl,
+ DECL_ASSEMBLER_NAME (target));
+#else
+ ASM_OUTPUT_DEF (asm_out_file,
+ IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (tmpdecl)),
+ IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (target)));
+#endif
+ memcpy (buf, IDENTIFIER_POINTER (id), nameend + 2);
+ buf[nameend + 2] = '@';
+ strcpy (buf + nameend + 3, IDENTIFIER_POINTER (id) + nameend + 2);
+ ASM_OUTPUT_SYMVER_DIRECTIVE (asm_out_file,
+ IDENTIFIER_POINTER
+ (DECL_ASSEMBLER_NAME (tmpdecl)),
+ buf);
+ }
#else
error ("symver is only supported on ELF platforms");
#endif
Index: lto/lto-common.c
===================================================================
--- lto/lto-common.c (revision 279467)
+++ lto/lto-common.c (working copy)
@@ -2818,6 +2818,10 @@ read_cgraph_and_symbols (unsigned nfiles
IDENTIFIER_POINTER
(DECL_ASSEMBLER_NAME (snode->decl)));
}
+ /* Symbol versions are always used externally, but linker does not
+ report that correctly. */
+ else if (snode->symver && *res == LDPR_PREVAILING_DEF_IRONLY)
+ snode->resolution = LDPR_PREVAILING_DEF_IRONLY_EXP;
else
snode->resolution = *res;
}