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

Bug#270620: gcc for mips/mipsel creates non xgot capable startup/shutdown objects



Matthias Klose wrote:
> 
> Thiemo Seufer writes:
> > tags 270620 +patch
> > thanks
> > 
> > This patch adds xgot support to the CRTSTUFF files for Linux/MIPS.
> > Without it, programs using -mxgot tend to segfault in the constructor.
> > For other programs it will cause a slight increase in overall size.
> 
> is the patch still needed with the new binutils?

Yes, and it's not the only mips/mipsel gcc problem (the following is
stuff for several bug reports). The full story as far as I know ATM is:

  - gcc 3.3/3.4 on mips/mipsel is broken for o32 ABI. This shows up in
    function calls where the first argument is a float and the second
    is also only word-sized: The first float occupies the same space as
    a double. Such functions are apparently uncommon enough to let this
    slip for a long time. A simple testcase is
  
    void f(float a, float b, float c, float d)
    {
    }

    int main(void)
    {
	f(1.0, 2.0, 3.0, 4.0);
	return 0;
    }

    which results in the broken call sequence

 	lwc1    $f2,$LC2
	lwc1    $f4,$LC3
	lwc1    $f6,$LC4
	lwc1    $f0,$LC6
	swc1    $f0,16($sp)
	mov.s   $f12,$f2
	mov.s   $f14,$f4
	mfc1    $7,$f6
	jal  f

    that is, the fourth float argument gets pushed to the stack. Caller
    and callee are consistent, so it is only a problem for programs
    which rely on the correct ABI. (I found this while reviving the
    clisp ffi implementation for mips/mipsel, the mozilla xpcom stuff
    avoids the problem because it is for C++, the first argument is
    always the "this" pointer).

    With gcc 2.95/3.0, the testcase compiles correctly:
  
	li.s    $f12,1.00000000000000000000e0
	li.s    $f14,2.00000000000000000000e0
	li.s    $6,3.00000000000000000000e0
	li.s    $7,4.00000000000000000000e0
	la      $25,f
	jal     $31,$25

    The first two floats are loaded in the fp argument registers, and
    the next two us the remaining gp argument registers.

    This bug is still unreported in debian, but it caused clisp to
    disable its ffi interface for mips/mipsel, which in turn made
    mcvs fail to build (#253895).

  - Now to the xgot/multigot stuff: The normal GOT size on mips/mipsel
    is limited to 16k entries for both local and global symbols.
    Everything exceeding this limit had to use xgot, which is
    practically unlimited but less efficient.

    Beginning with binutils 2.14, multigot was introduced, which uses
    several GOTs in the binary, but is limited to a single GOT for
    globals, which means 16k globals at most. Mozilla's libgklayout.so
    has currently 19k globals, so it tries to use xgot.

    Multigot is (supposed to be) transparent to the user, but in its
    current implementation it appears to conflict with xgot. The xgot
    specific relocations are distorted, and binutils is silent about
    this breakage.

    Xgot fails in current binutils when multigot kicks in, i.e. when
    the GOT gets larger than 64kB, which is the whole point of xgot.
    Commenting out the multigot handling in bfd/elfxx-mips.c allows
    binutils to handle this correctly, but that's of course no good
    option for non-xgot builds.

    The binutils xgot/multigot bug is not yet reported in the BTS.

    Gcc's and glibc's crt* files are not built with xgot support. The
    glibc crt* cause no immediate problems, but gcc crt* cause segfaults
    in contructors. The Linker is silent about this breakage.

    Enabling xgot support unconditionally would increase the size of
    each binary by a few byte. That would be IMHO tolerable, but
    multigot links may break on it (I haven't tested this). So ATM,
    xgot and multigot seem to be mutually exclusive. This also means
    that the suggested patch in #270620 is probably a bad idea.

    With multigot disabled in binutils, the gcc patch for crt* with
    xgot support and some unrelated fixes to mozilla's xpcom layer
    I was able to create working mips packages of mozilla-firefox
    (#270621) and mozilla-thunderbird (#267017). The monolithic mozilla
    (#266850) is likely to work that way as well.

    I have currently no good idea how to fix this mess.


Thiemo



Reply to: