Fixing namespace issues for variables
Joseph Myers
joseph@codesourcery.com
Sat Oct 24 02:03:00 GMT 2015
It has come to my attention that the time.h variables such as tzname
manage to work using aliases, thanks to this piece of linker magic (from
bfd/elflink.c; gold has similar logic):
/* Now set the weakdefs field correctly for all the weak defined
symbols we found. The only way to do this is to search all the
symbols. Since we only need the information for non functions in
dynamic objects, that's the only time we actually put anything on
the list WEAKS. We need this information so that if a regular
object refers to a symbol defined weakly in a dynamic object, the
real symbol in the dynamic object is also put in the dynamic
symbols; we also must arrange for both symbols to point to the
same memory location. We could handle the general case of symbol
aliasing, but a general symbol alias can only be generated in
assembler code, handling it correctly would be very time
consuming, and other ELF linkers don't handle general aliasing
either. */
This means, for example, that programs referencing but not defining tzname
get dynamic symbols for both tzname and __tzname, at the same address, so
that both symbols in glibc get preempted to point to the same variable in
the executable. (Programs defining their own tzname don't get it bound to
the glibc symbol at all, presumably because the glibc symbol is weak.)
This isn't so helpful with existing symbols that weren't set up like this
from the start, because (to take the signgam example) existing binaries
only have dynamic symbols for signgam, not a new __signgam, so if we made
__signgam exported from glibc at the time we made signgam into a weak
alias and made libm functions use __signgam, it would fix things for new
binaries but break old binaries. It might be possible to do something
where the affected functions do address comparisons and set both variables
if the addresses are different (which should only be the case for an old
main executable preempting signgam), however.
(There would still be a quiet API change for programs that do "int
signgam;" intending to get it set by lgamma, as noted in
<https://sourceware.org/ml/libc-alpha/2013-04/msg00771.html>, but I think
that's unavoidable; whatever fix you do, the point is to allow programs to
define their own variable called signgam and *not* have it preempt libm's
variable.)
--
Joseph S. Myers
joseph@codesourcery.com
More information about the Libc-alpha
mailing list