On 2016-08-28 15:58, Florian Weimer wrote:
* Aurelien Jarno:
On some architectures the _IO_stdin_used symbol is used to determine if
the executable has been linked against the older version of libio or the
newer. More and more executables start to be linked with a version
script in order to control the symbols they export to their plugins.
Examples of such software are firefox, network-manager or mplayer. When
using a version-script without explicitly adding an entry for the
_IO_stdin_used symbol, it appears as a local symbol in the resulting
libraries. This causes random crashes or strange behaviours. We have
observed that in Debian at least on alpha, mips* and powerpc.
The first part would be to figure out what _IO_stdin_used is actually
about. I think it's there to preserve the libio ABI (as far as
vtables are concerned) despite the fact that the struct layout was
changed (possibly to reflect a C++ ABI change).
For what I understood, the libio ABI has changed with glibc 2.1 in order
to support for wide-character streams and 64 bit offsets. These
changes required an incompatible change to the FILE structure. That's
why we have two versions of libio functions one tagged GLIBC_2.0 and one
tagged GLIBC_2.1. The problem is that the FILE structure can be passed
as a pointer so that the symbol versioning mechanism doesn't work.
Therefore when a binary is build against glibc >= 2.1, there will be a
reference to _IO_stdin_used add. If there are no references to
_IO_stdin_used, the compatibility layer will kick in, and make the
stdin/stdout/stderr pointers by pointers to the compatibility objects.
One fairly conservative change would version the symbols which
activate vtable compatibility, and have the new versions override the
_IO_stdin_used mechanism. There should be room for such a flag in the
_flags2 member of struct _IO_file.
The other idea would be to simply disable this compatibility layer. This
means that binaries older than 15 years old would not work anymore, but
that *might* be acceptable for some architectures, although maybe not
for i386.