This is the mail archive of the
libc-alpha@sourceware.org
mailing list for the glibc project.
Evolution of ELF symbol management
- From: Florian Weimer <fweimer at redhat dot com>
- To: GNU C Library <libc-alpha at sourceware dot org>
- Date: Tue, 18 Oct 2016 11:26:33 +0200
- Subject: Evolution of ELF symbol management
- Authentication-results: sourceware.org; auth=none
In the ancient past, all glibc symbols, including internal ones, were
public. Then came symbol versioning, and hidden symbols.
This did not solve all problems. For static linking, we often have to
mangle symbols so that an implementation of a function in one standard
does not implicitly require the application to be conforming to another
standard (or standard version): the application might define a symbol
which is reserved by the other standard, and we cannot use this function
in the implementation.
For essentially the same reason, we need to mangle references in
non-libc DSOs to libc symbols which are not present in all of the
standards implied by all symbol references to the non-libc DSO.
Symbol versioning does not help here, for two reasons: We do not provide
symbol versions for static builds. For backwards compatibility reasons,
non-versioned symbols interpose all versioned symbols, irrespective of
their version (not just the base definition). The second reason is
important in practice; it is required for interposing malloc.
I think the above sums up the status quo. With this message, I want to
start a discussion why this symbol mangling stops at glibc-internal
cross-DSO references (or static linking). Wouldn't other system
libraries, such as libstdc++, glib, Qt and so on need to do the same
thing? After all, if Qt calls foo@GLIBC_2.31, and the main program
defines foo (which the static linker automatically exports to enable
interposition), we almost certainly would want Qt to continue to call
foo@GLIBC_2.31, and not the potentially incompatible implementation of
foo in the main program.
To keep things simple, I suggest that for all new function symbols, we
declare __libc_foo in the header file, redirect foo to __libc_foo,
export both at the same symbol version from the DSO, and make __libc_foo
a strong definition and foo a weak one. (We should not add new variable
symbols.)
For existing symbols, we only do this if we receive reports of conflicts
causing problems in the field. In this case, we add __libc_foo and the
redirect to the header file, and use the current symbol version for the
__libc_foo export (not the one of foo).
Comments?
Thanks,
Florian