https://gcc.gnu.org/bugzilla/show_bug.cgi?id=66825
Bug ID: 66825 Summary: RFE: Add attributes for symbol versioning. Product: gcc Version: 6.0 Status: UNCONFIRMED Severity: enhancement Priority: P3 Component: c Assignee: unassigned at gcc dot gnu.org Reporter: carlos at redhat dot com Target Milestone: --- At present gcc supports alias, weak, section, optimize, used, visibility, tls_model, and that lets user application do a lot of things with functions, particularly with respect to creating aliases, changing their visibility and linkage properties (weak vs. strong). I expect that some of these attributes apply only to ELF support in the toolchain as a whole. What we are missing is symbol versioning for ELF, and the alias attribute can't be used for this (treats the target as the function name without understanding versions). At present in glibc we need to do the following: # define _symbol_version(real, name, version) \ __asm__ (".symver " #real "," #name "@" #version) # define _default_symbol_version(real, name, version) \ __asm__ (".symver " #real "," #name "@@" #version) It would be nice if symbol versioning did not require __asm__ directives which in general hide such information from the compiler and potential plugins. I have no requirements as to how it should or could be implemented, and I leave that up to the gcc developers to think about. My suggestion is that at a minimum it needs a name, version, and default flag (to avoid conflating "@" or "@@" into the version name), and it might look like this: version_def (target, version, default) * The attribute may only be applied to a function definition. The attribute creates a definition of a versioned symbol. The function is aliased under the symbol TARGET with version VERSION. The symbol TARGET is the default symbol, resolves other references without versions, only if DEFAULT is true. Example: int foo (void) __attribute__ ((version (bar, "BARLIB_1.0", true))) { return 0; } int foo2 (void) __atttribute__ ((version (bar, "BARLIB_0.9", false))) { return 2; } These functions will be available for linking and if that is not what you want then you must use the features of your linker to limit the set of exported functions. For GNU ld the link map nodes will correspond to the versions and a link map will be required. e.g. BARLIB_1.0 { global: bar; local: *; } BARLIB_0.9 { global: bar; local: *; } Implementation note: - Use `.symver` to implement the attribute, and if default is true you use @@ otherwise one @ for the symbol version. Notes: - After implementing this we could make gcc us it also and update the wiki page: https://gcc.gnu.org/wiki/SymbolVersioning - A follow-up to this is "version_ref" attribute which allows you to create a declaration of a function e.g. extern int memcpy (void) __attribute__ ((version_ref (memcpy, GLIBC_2.2.5, false))); at a particular version/default (for symmetry with version_def) and then all callers in the compilation unit will call through that version (the version you want to reference, hence "version_ref"). This can be used to create test applications that call old versions of symbols without needing the old DSOs to link against. This again works using .symver, but requires that memcpy not be implemented in the present object file. The .symver without a definition of the function causes the object to reference the alias at that particular version and thus lets you link against old versions of functions. This is limited in scope to just the single file you compiled. So you could for example write tests that test each of the new and old symbol versions without using asm inlines and the compiler could be aware of function versions (for some future purpose).