[patch] For BZ #17328, mark __errno_location with __attribute__((returns_nonnull)) for gcc >=4.9.0
Rich Felker
dalias@libc.org
Tue Mar 3 14:54:00 GMT 2015
On Tue, Mar 03, 2015 at 11:48:43AM +0100, Florian Weimer wrote:
> On 03/02/2015 11:46 PM, Roland McGrath wrote:
>
> > Something that we could consider as a middle road is exporting errno with a
> > proper symbol version (it's currently GLIBC_PRIVATE, which nothing residing
> > outside the libc source tree should ever use) and then having errno.h do:
> >
> > extern __thread int errno;
>
> Can we make the TLS offset part of the ABI instead and somehow teach GCC
> about it? Then there would at least be an unquestionable improvement.
I would really advise against this. Fixed offsets are really nasty
lock-in and don't save much. For the non-PIE main program they save
basically nothing versus a runtime-variable offset. For shared
libraries or PIE, there is some minor saving especially on archs
(32-bit x86) that need to load a GOT register to load the offset;
however, right now such archs are already loading a GOT pointer to
make the function call to __errno_location, so this is not a new cost.
> Right now, we have (in PIC code):
>
> call __errno_location@PLT
> movl (%rax), %eax
>
> This turns into:
>
> data32
> leaq errcode@tlsgd(%rip), %rdi
> data32
> data32
> rex64
> call __tls_get_addr@PLT
> movl (%rax), %eax
>
> errno is mostly used on error paths, so this just bloats the code and is
> probably even slower, too.
__tls_get_addr is not needed if you use the initial-exec model. And if
you're using GD with TLSDESC rather than the old GD model, it's also
not this ugly/bloated.
However I still prefer just leaving things alone with
__errno_location. Like you say it's tiny and its internals can be
optimized heavily if needed (e.g. using a constant offset like it is
now). In this case the constant is encoded in libc.so so it can change
from one version to another rather than being permanent ABI lock-in.
Rich
More information about the Libc-alpha
mailing list