This is the mail archive of the gcc-bugs@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[Bug c/66825] New: RFE: Add attributes for symbol versioning.


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).


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]