This is the mail archive of the
mailing list for the binutils project.
Re: [Mips}Using DT tags for handling local ifuncs
- From: Richard Sandiford <rdsandiford at googlemail dot com>
- To: Jack Carter <Jack dot Carter at imgtec dot com>
- Cc: "Maciej W. Rozycki" <macro at codesourcery dot com>, "binutils\ at sourceware dot org" <binutils at sourceware dot org>, Doug Gilmore <Doug dot Gilmore at imgtec dot com>
- Date: Wed, 18 Dec 2013 20:37:17 +0000
- Subject: Re: [Mips}Using DT tags for handling local ifuncs
- Authentication-results: sourceware.org; auth=none
- References: <4CEFBC1BE64A8048869F799EF2D2EEEE4C6DDC0F at BADAG02 dot ba dot imgtec dot org> <87r49p9dit dot fsf at talisman dot default> <alpine dot DEB dot 1 dot 10 dot 1312092333190 dot 19368 at tp dot orcam dot me dot uk> <4CEFBC1BE64A8048869F799EF2D2EEEE4C6DDFC3 at BADAG02 dot ba dot imgtec dot org> <87ob4p6qdt dot fsf at talisman dot default> <87k3fd6owc dot fsf at talisman dot default> <4CEFBC1BE64A8048869F799EF2D2EEEE4C6DE23E at BADAG02 dot ba dot imgtec dot org> <87txef6a07 dot fsf at talisman dot default> <4CEFBC1BE64A8048869F799EF2D2EEEE4C6DE3B8 at BADAG02 dot ba dot imgtec dot org> <87haaf5hbg dot fsf at talisman dot default> <4CEFBC1BE64A8048869F799EF2D2EEEE4C6DE50C at BADAG02 dot ba dot imgtec dot org> <877gbb5c2k dot fsf at talisman dot default> <4CEFBC1BE64A8048869F799EF2D2EEEE4C6DE59A at BADAG02 dot ba dot imgtec dot org> <alpine dot DEB dot 1 dot 10 dot 1312112311480 dot 19368 at tp dot orcam dot me dot uk> <87y53q4czx dot fsf at talisman dot default> <alpine dot DEB dot 1 dot 10 dot 1312121406040 dot 19368 at tp dot orcam dot me dot uk> <87ppp14wr7 dot fsf at talisman dot default> <alpine dot DEB dot 1 dot 10 dot 1312131400280 dot 19368 at tp dot orcam dot me dot uk> <87d2kz4uhi dot fsf at talisman dot default> <4CEFBC1BE64A8048869F799EF2D2EEEE4C6DF550 at BADAG02 dot ba dot imgtec dot org>
Jack Carter <Jack.Carter@imgtec.com> writes:
> On 12/14/2013 02:06 AM, Richard Sandiford wrote:> "Maciej W. Rozycki"
> <firstname.lastname@example.org> writes:
>>> On Thu, 12 Dec 2013, Richard Sandiford wrote:
>>>>> Hmm, thanks for reminding me that, that rules out the space before the
>>>>> ABI GOT. We still have space afterwards for things like this (or e.g. for
>>>>> a small-data area if we ever implement it) though.
>>>> Yeah, putting it afterwards is what we already do for TLS relocs.
>>>> The problem with that is that the ABI global GOT has to include all
>>>> symbols that have a relocation against them, even if there's no need
>>>> for a $gp-relative GOT access. And there can be quite a lot of symbols
>>>> like that, especially for things like vtables in C++ code.
> I am missing this part of the ABI. If a symbol has a relocation
> against it why does it have to be in the GOT? TLS symbols that are
> referenced through the PLT are specified to be in the GOT, but
TLS symbols don't need to be in the ABI global GOT. They're treated
as a special case.
>>>> So if we put the relocations after the ABI GOT we would end up forcing
>>>> the use of multigots even though the number of "real" GOT entries
>>>> (those that need to be accessed $gp-relative) is small enough for
>>>> a single GOT. The idea of the tag is to avoid that.
>>> I see, that makes sense to me. Do we already care to sort GOT entries
>> Yeah, this is GGA_NORMAL vs. GGA_RELOC_ONLY in elfxx-mips.cs
> I don't understand this either. Local GOT and global GOT both are GP
> relative. Don't you have to include both along with any other GP
> relative section in the multigot accounting? And if so, don't you have
> to include pieces of both the local and global GOT in each multigot
> region that needs it?
> In my mind it shouldn't matter where you put a GOT entry in terms of multigot
> threshold accounting.
The point is that if foo binds globally:
requires a GOT entry for foo. But this .word doesn't on its own require
the GOT entry to be within range of a $gp-relative access. It could be at
$gp+0x8000, say, without breaking anything. So we sort the GOT entries
that do need to be accessed $gp-relative from those that don't.
The ones that don't go after the ones that do.
Therefore, when creating multigots for normal local and global entries,
we can ignore the entries that don't need to be $gp-relative, because
they will always come later. The problem is that TLS GOT entries need
to be after _all_ global GOT entries. So if the last entry of the
global GOT is out of range of $gp, a single TLS reloc in an input bfd
will force that bfd to use multigot, even if the last entry of the
global GOT doesn't itself need to be accessed $gp-relative.
> Is there a way that I can reduce the multigot threshold in binutils for
> testing purposes?
Well, for testsuite tests we want the real threshold to be used. .rept is
your friend here.
For local testing you could hack elfxx-mips.c though.
>>> Also let's make sure old ld.so binaries fail in a sensible way with ifunc
>>> binaries though, i.e. no segfault or suchlike.
>> I agree it's worth checking, but in this case it should do, because we'll
>> only be using the new area for R_MIPS_IRELATIVE, which is a new relocation
>> type. ld.so does complain about types it doesn't understand.
> Is there no versioning or features list that is currently checked? How
> do you currently
> deal with forward incompatibility in ld.so?
There is no versioning system, unfortunately.
>>> For executables using traditional SVR4 PIC code we could use the absolute
>>> sequence indeed. However I checked the ifunc ABI description again and no
>>> lazy binding is proposed for ifuncs so no stub of any kind will be
>>> required for PIC code (be it an executables or a shared library) as all
>>> calls are made through the GOT there anyway and this will have been
>>> relocated by the time any ifunc call is reached.
>> OK, once we start using the new GOT region then I agree we can make
>> that the case. In terms of the ABI and patch as posted though, we used
>> IPLTs for all ifuncs defined in executables:
>> Dynamically linked executables with ifunc definitions are for the most
>> part the same as static executables, with the following exceptions:
>> *) No __rel_iplt_start/end symbols. The dynamic linker handles dynamic
>> *) Generate STT_GNU_IFUNC symbols in the .dynsym section with the value
>> being the iplt entry for this IFUNC and transform them into
>> STT_FUNC symbols. Any references to this IFUNC have to go through
>> the stub. The dynamic linker (ld.so) will be doing the fixup at start-
> If the dso LOCAL/INTERNAL/HIDDEN IIfunc GOT entry has a symbol
> associated with it,
> it does not need to go through an iplt stub since the call is referenced
> through the GOT
> value which will be fixed up by ld.so.
> The only time I would see a dso defined ifunc call going through the
> iplt is for local calls that
> go through the local got offset table. That is, the offset in the GOT is
> shared among multiple
> addresses and the call needs an additional addend to get the final
> address. Does this occur
> for function calls in GCC/binutils or do all function addresses get
> their own GOT entry?
Either we should disallow GOT page accesses for ifuncs or the static linker
should treat them in the same way as globals (i.e. by directing the GOT
reloc to the function's own GOT slot and making the offset reloc resolve
> Getting back to using dynsym symbols:
> But symbol lookups are expensive. That is why we have implicit fixups
> in the GOT. If we are going to sequester these "local" ifunc entries
> in their own GOT partition, why make them look up a symbol?
Not sure what you mean. We're adding the new area so that we can create
R_MIPS_IRELATIVE relocs. R_MIPS_IRELATIVE doesn't take a symbol
(or more accurately, it takes symbol 0). It's a base-relative
relocation, like R_MIPS_REL32.