This is the mail archive of the
gcc-help@gcc.gnu.org
mailing list for the GCC project.
Re: Why -mxgot on MIPS and not -fpic/-fPIC?
On Mon, 3 Oct 2016, Florian Weimer wrote:
> > For MIPS `-fPIC' is an alias to `-fpic' and the actual reason is these
> > options have only been retrofitted to the MIPS target when non-PIC support
> > has been added to shared-library (as opposed to bare-metal) targets. The
> > original MIPS SVR4 psABI mandated all code to be PIC, even executables,
> > and the model chosen was controlled with the `-mxgot' option, hardly ever
> > used, due to the code bloat implied and link-time incompatibility with the
> > default `-mno-xgot' code. The latter could be rectified to some extent by
> > a specific GOT entry ordering, but with the advent of multi-GOT there was
> > little incentive to actually implement it.
>
> GHC produces objects which need -mxgot.
Ouch, what a waste of memory!
> The GCC documentation doesn't say anything about incompatibilities
> between -mxgot and -mno-xgot. Will this result in a linker failure at
> least?
The incompatibility is I believe noted in the psABI documents; it
wouldn't hurt mentioning it in compiler documentation, although I do hope
you realise it is not meant to stand for ABI documentation.
You won't always get a link error as the incompatibility is not inherent
(which is why I've noted it could be supported although nobody has cared
to make it); if a link does succeed, then the binary will work correctly.
The thing is as soon as GOT expands beyond the 16-bit limit entries
outside this limit will become out of reach for 16-bit GOT references
(R_MIPS_GOT16 relocations in the o32 ABI; R_MIPS_GOT_DISP and
R_MIPS_GOT_PAGE relocations in the new ABIs, although for brevity I'll use
R_MIPS_GOT16 from now on with an implicit reference to any of these) and
we currently do nothing to arrange entries in the GOT such that these
referred with R_MIPS_GOT16 relocations fall within the 16-bit limit if
possible.
If we did that, then we could interlink `-mno-xgot' system libraries
(which necessarily do not trigger the creation of GOT entries beyond the
16-bit limit as otherwise no `-mno-xgot' application would link) using
R_MIPS_GOT16 relocations, and `-mxgot' application code using
R_MIPS_GOT_HI16/R_MIPS_GOT_LO16 relocation pairs suitable to access 32-bit
GOT.
> (On the glibc side, I don't think we compile libc_nonshared.a twice,
> once for -mxgot and once for mno-xgot.)
You might have to build GCC's startup files twice too, and generally
anything and everything static that goes into a link.
However as I have implicitly noted above I think the solution is to make
the linker arrange GOT entries such that ones referred with R_MIPS_GOT16
relocations fall within the 16-bit limit, whereas ones referred with
R_MIPS_GOT_HI16/R_MIPS_GOT_LO16 relocation pairs only use slots outside
the limit. I think only positive GP offsets can be used for these
out-of-range entries as there is an assumption there in the ABI that
GP-0x7ff0 points to the beginning of GOT.
So if you do really need to support such a code model, then this might be
the solution for you to pursue. It might be easier than it seems these
days, reusing the existing GOT arrangement infrastructure in the MIPS BFD
backend and assigning any symbols referred with an R_MIPS_GOT16 relocation
to the GGA_NORMAL area and letting symbols only referred with
R_MIPS_GOT_HI16/R_MIPS_GOT_LO16 relocations be assigned to the
GGA_RELOC_ONLY area (currently used for R_MIPS_REL32 dynamic relocations
only, whose handling would remain unchanged). It would make sense to
rename the GGA_RELOC_ONLY macro too at that point to reflect its extended
meaning; maybe to GGA_32BIT.
This raises a question however: why do you need it in the first place?
The only case where multi-got does not work is where you have a single
object (.o) file which requires more than 16378 GOT entries (8188 in the
n64 ABI case). A GOT entry is required per each individual global symbol
and per each 64kB chunk of local (static) symbols -- do you really have
such a huge object file? Perhaps you could split the source so that
multiple objects are created instead?
Maciej