diff options
author | Jan Hubicka <hubicka@ucw.cz> | 2019-11-30 22:03:25 +0100 |
---|---|---|
committer | Jan Hubicka <hubicka@gcc.gnu.org> | 2019-11-30 21:03:25 +0000 |
commit | d7ddfbcb7fa6e700639c9b916bf8a5ed15600950 (patch) | |
tree | 3e8ad36922e2df05cdc896aec48daa30135163d6 /gcc/cgraphunit.c | |
parent | 65ef05d0b7fb429c5760189e638c441dc3da33f4 (diff) | |
download | gcc-d7ddfbcb7fa6e700639c9b916bf8a5ed15600950.zip gcc-d7ddfbcb7fa6e700639c9b916bf8a5ed15600950.tar.gz gcc-d7ddfbcb7fa6e700639c9b916bf8a5ed15600950.tar.bz2 |
cgraph.h (symtab_node): Add symver flag.
2019-11-30 Jan Hubicka <hubicka@ucw.cz>
* cgraph.h (symtab_node): Add symver flag.
* cgraphunit.c (process_symver_attribute): New.
(process_common_attributes): Use process_symver_attribute.
* lto-cgraph.c (lto_output_node): Stream symver.
(lto_output_varpool_node): Stream symver.
(input_overwrite_node): Stream symver.
(input_varpool_node): Stream symver.
* output.h (do_assemble_symver): Decalre.
* symtab.c (symtab_node::dump_base): Dump symver.
(symtab_node::verify_base): Verify symver.
(symtab_node::resolve_alias): Handle symver.
* varasm.c (do_assemble_symver): New function.
* varpool.c (varpool_node::assemble_aliases): Use it.
* doc/extend.texi: (symver attribute): Document.
* config/elfos.h (ASM_OUTPUT_SYMVER_DIRECTIVE): New.
c-family/ChangeLog:
2019-11-30 Jan Hubicka <hubicka@ucw.cz>
* c-attribs.c (handle_symver_attribute): New function
(c_common_attributes): Add symver.
From-SVN: r278878
Diffstat (limited to 'gcc/cgraphunit.c')
-rw-r--r-- | gcc/cgraphunit.c | 92 |
1 files changed, 90 insertions, 2 deletions
diff --git a/gcc/cgraphunit.c b/gcc/cgraphunit.c index aa26160..75ff10b 100644 --- a/gcc/cgraphunit.c +++ b/gcc/cgraphunit.c @@ -711,6 +711,89 @@ symbol_table::process_same_body_aliases (void) cpp_implicit_aliases_done = true; } +/* Process a symver attribute. */ + +static void +process_symver_attribute (symtab_node *n) +{ + tree value = lookup_attribute ("symver", DECL_ATTRIBUTES (n->decl)); + + if (!value) + return; + if (lookup_attribute ("symver", TREE_CHAIN (value))) + { + error_at (DECL_SOURCE_LOCATION (n->decl), + "multiple versions for one symbol"); + return; + } + tree symver = get_identifier_with_length + (TREE_STRING_POINTER (TREE_VALUE (TREE_VALUE (value))), + TREE_STRING_LENGTH (TREE_VALUE (TREE_VALUE (value)))); + symtab_node *def = symtab_node::get_for_asmname (symver); + + if (def) + { + error_at (DECL_SOURCE_LOCATION (n->decl), + "duplicate definition of a symbol version"); + inform (DECL_SOURCE_LOCATION (def->decl), + "same version was previously defined here"); + return; + } + if (!n->definition) + { + error_at (DECL_SOURCE_LOCATION (n->decl), + "symbol needs to be defined to have a version"); + return; + } + if (DECL_COMMON (n->decl)) + { + error_at (DECL_SOURCE_LOCATION (n->decl), + "common symbol cannot be versioned"); + return; + } + if (DECL_COMDAT (n->decl)) + { + error_at (DECL_SOURCE_LOCATION (n->decl), + "comdat symbol cannot be versioned"); + return; + } + if (n->weakref) + { + error_at (DECL_SOURCE_LOCATION (n->decl), + "weakref cannot be versioned"); + return; + } + if (!TREE_PUBLIC (n->decl)) + { + error_at (DECL_SOURCE_LOCATION (n->decl), + "versioned symbol must be public"); + return; + } + if (DECL_VISIBILITY (n->decl) != VISIBILITY_DEFAULT) + { + error_at (DECL_SOURCE_LOCATION (n->decl), + "versioned symbol must have default visibility"); + return; + } + + /* Create new symbol table entry representing the version. */ + tree new_decl = copy_node (n->decl); + + DECL_INITIAL (new_decl) = NULL_TREE; + if (TREE_CODE (new_decl) == FUNCTION_DECL) + DECL_STRUCT_FUNCTION (new_decl) = NULL; + SET_DECL_ASSEMBLER_NAME (new_decl, symver); + TREE_PUBLIC (new_decl) = 1; + DECL_ATTRIBUTES (new_decl) = NULL; + + symtab_node *symver_node = symtab_node::get_create (new_decl); + symver_node->alias = true; + symver_node->definition = true; + symver_node->symver = true; + symver_node->create_reference (n, IPA_REF_ALIAS, NULL); + symver_node->analyzed = true; +} + /* Process attributes common for vars and functions. */ static void @@ -730,6 +813,7 @@ process_common_attributes (symtab_node *node, tree decl) if (lookup_attribute ("no_reorder", DECL_ATTRIBUTES (decl))) node->no_reorder = 1; + process_symver_attribute (node); } /* Look for externally_visible and used attributes and mark cgraph nodes @@ -2137,8 +2221,12 @@ cgraph_node::assemble_thunks_and_aliases (void) /* Force assemble_alias to really output the alias this time instead of buffering it in same alias pairs. */ TREE_ASM_WRITTEN (decl) = 1; - do_assemble_alias (alias->decl, - DECL_ASSEMBLER_NAME (decl)); + if (alias->symver) + do_assemble_symver (alias->decl, + DECL_ASSEMBLER_NAME (decl)); + else + do_assemble_alias (alias->decl, + DECL_ASSEMBLER_NAME (decl)); alias->assemble_thunks_and_aliases (); TREE_ASM_WRITTEN (decl) = saved_written; } |