[8] New libio
Florian Weimer
fweimer@redhat.com
Sat Sep 14 10:51:45 GMT 2024
* Eliminate vtables
* Lose backwards compatibility with glibc 2.0
* Simplify implementation (a lot)
* Additional hardening
* Better performance?
The current stdio streams (FILE *) implementation aims to preserve
backwards compatibility with old ABIs where the concrete stream
structure had a different layout. In addition, stdio etc. used to be
defined as (_IO_FILE*)(&_IO_2_1_stdin_) etc., encoding the size of the
underlying struct into relocations due to the possibility of copy
relocations. The exported _IO_2_1_stdin_ symbols are present in new
ABIs, too, although C and C++ applications using the glibc headers no
longer use them. Certainly we should cease exporting this for future
architectures.
Certain parts of the FILE * struct are part of the ABI because they are
used by fgetc_unlocked and fputc_unlocked, for performing buffering I/O
without function calls. Other parts are scribbled over by gnulib-using
applications. This constrains the future evolution of libio.
The main challenge is that the code is quite baroque and written in such
a way that compatibility with a pre-GCC-3 C++ ABI can be maintained (an
ABI that changed in GCC upstream fairly soon after glibc committed to
the ABI). However, we know that some old i386 binaries rely on the
interoperability between stdio streams and historic libstdc++ streams
that we currently provide. But for most architectures, the GCC backend
post-dates the GCC C++ ABI change away from what glibc implements, so
our libio cannot be integrated with libstdc++ anymore. This means that
a lot of things (like marker support, or certain indirect calls via
vtables) are not usable at all on, say, x86-64. Custom stdio streams
can still be created with fopencookie, a more recent addition, and
fopencookie has only limited exposure of internals.
The goal of this project would be to fully eliminate the old, deeply
layered libio for glibc targets which gained GCC backends in GCC 3.0 or
later (or thereabouts). It may also make sense to instruct historic
i386 users to park on an older glibc release which does not have this
change. This way, we could transition libio on all architectures.
The main benefits would be better performance (we saw some of that
already with the vfprintf refactor, but I think there are still gains to
be had), additional security hardening (no vtables means no more vtable
hardening bypasses, although we need to keep supporting fopencookie, of
course), and of course simplified maintenance.
However, there is a risk that contemporary programming environments that
do not use glibc headers still use some of the old ABIs we export,
although we deprecated a lot of these interfaces in glibc 2.27.
More information about the Libc-alpha
mailing list