Re: Multigot mechanism and a related MIPS linker error

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



"Umashankar V.K." <shankar.vk@xxxxxxxxx> writes:
> We want to reproduce the failure with a test program.  As  a first
> step, we are are trying to access  many extern symbols
> from main(). But when the GOT table size  exceeds 64 Kb,  the linker
> fails with message such as :
> "relocation truncated to fit: R_MIPS_GOT16 against `global_variable__d13155'"
>
> With less than 64 Kb GOT ,  I can see that the binary is in multigot
> mode. (Each function's prolog is assigning
> a different value for gp reg. )
>
> a) In multigot mode, why should linker fail to create larger-than-64Kb
>  GOT ?   The very purpose of multigot
> is to overcome this limit, isn't it ?

Yes, but it assigns GOTs on a _per-object_ basis.  There isn't enough
information in a relocatable object file to tell for sure which function
"owns" a particular GP-relative relocation (such as a R_MIPS_GPREL32
relocation in a data section), so the linker has to use the same _gp
throughout a given input object.

There's also the issue that nested functions and parent functions might
assume the same GOT, and again, there's no defined way of telling whether
one function is nested within another.  Also, non-escaping static functions
can in principle be optimised to use the caller's GOT (since every
caller is then in the same input object).

So the purpose of the multigot feature is to make sure that input
objects can be linked together when each input object individually
uses less than 64k of GOT.  It can't cope with the case where
individual functions (or individual input objects) need a bigger GOT.
Like you say, any input object that requires such a big GOT must be
compiled with -mxgot.

> b) I looked at another application built in our company with same
> toolchain.  Its GOT is 188 Kb in size.
> (There are about 33000 extern symbol entries in the GOT .) I  looked
> at its linking options and did not find anything special.
> I looked  at its binary.  It is NOT in xgot mode.  Any clues ?

I'm guessing the individual objects in this case used less than 64k
of GOT each.

> c) For the above binary mentioned in  ,  I can see lot of relocation
> entries in .rel.dyn for the GOT table fixup.  From what I know,
> in MIPS,  reloc entries are not needed for GOT relocation.  Why would
> the linker output those for this binary?

MIPS multigots are a trick.  The ABI only defines a single GOT,
which I'll call the "ABI-defined" GOT.  As you say, this GOT needs
no relocations.  The information is instead provided in two ways:

  (a) Dymamic tags give the limits of the local and global parts
      of the GOT.

  (b) The global part of the GOT is directly mapped to the end
      of the dynamic symbol table.

But what do you do if you need multiple GOTs, and several GOTs
need to refer to the same symbol S?  S appears only once in the
dynamic symbol table, so it can only appear once in the ABI-defined GOT.

Multigots could only share GOT entries like this if you were able to
sort the symbols in such a way that every multigot represented a 64k
(or smaller) window into the ABI-defined GOT.  And that isn't possible
in the general case.  Objects often refer to both common symbols (like
stdio routines) and object-specific symbols.  Once you get >128k of
object-specific symbols, it isn't possible for all of them to be in
a 64k window that also contains the ABI GOT entries for the stdio
routines.

So what we do instead is create a set of entirely separate GOTs,
each <64k in size.  We designate one of them as the "primary" GOT and
refer to the others as "secondary" GOTs.  We try to put as much as
possible into the primary GOT.

The primary GOT lives at the start of the ABI-defined GOT, and is
managed in the usual relocation-free way.  The secondary GOTs are
instead just blobs of data that are relocated in the same way as
ordinary data, using the R_MIPS_REL32s that you saw.

Of course, every global symbol involved in a relocation must also
be in the ABI-defined GOT, so that GOT is often bigger than 64k.
However, the primary GOT lives at the beginning of the ABI-defined
GOT and is always <64k in size.

We could try to optimise the case where input objects (or groups
of input objects) have GOTs that don't overlap at all, but that's
so rare that I don't think it's worth bothering in practice.

Richard



[Index of Archives]     [Linux C Programming]     [Linux Kernel]     [eCos]     [Fedora Development]     [Fedora Announce]     [Autoconf]     [The DWARVES Debugging Tools]     [Yosemite Campsites]     [Yosemite News]     [Linux GCC]

  Powered by Linux