Fix shared libraries on mips-sgi-irix6 --with-gnu-ld

Richard Sandiford rsandifo@redhat.com
Mon Nov 24 21:01:00 GMT 2003


IRIX 6 doesn't provide traditional .init/.fini support, so we instead
use the following set-up:

   crtend.o contains:
      __do_global_ctors, which acts as the DT_INIT function.  Defined here
         to gain access to __CTOR_END__.  Treated as global so that it can
         be used with the linker's -init option.

   crtbegin.o contains:
      __do_global_dtors, which acts as the DT_FINI function.  Defined here
         to gain access to __DTOR_LIST__.  Treated as global so that it can
         be used with the linker's -fini option.

      __do_global_ctors_1, which is called by __do_global_ctors.  Defined
         here to gain access to __EH_FRAME_BEGIN__, etc.  Treated as global
         so that it can be called from crtend.o.

We then use the native linker's -hidden_symbol option to hide all
three symbols.

Unfortunately, GNU ld has no equivalent of -hidden_symbol, and the current
--with-gnu-ld configuration will leave the symbols as global.  This means
that a library's __do_global_ctors will end up calling the executable's
__do_global_ctors_1.

There are at least three ways to fix this:

    (1) Use visibility attributes to hide the symbols if HAVE_GAS_HIDDEN.

    (2) Define __do_global_ctors in crtbegin.o instead.  Walk .ctor
        forwards to find the end of the list, then walk backwards
        calling each constructor.

    (3) Add .init/.fini support.

I've tried all three, and they seem to work.

I think (2) is better than (1) since it works for all possible (GNU,SGI)
combinations.  However, after various hassles with the SGI assemblers,
it seems quite likely that we'll require gas at some point in future.

On that basis, I think (3) is the best choice:

   - It should be easy to adapt it to --with-gnu-as --without-gnu-ld
     in future, should we need to.

   - It's better than (2) because we don't need to walk .ctor twice.

   - It's better than both (1) and (2) in terms of future maintenance since
     we could then drop the IRIX 6 alternative from crtstuff.c.

Anyway, I've attached a patch for (3) below.  At the moment it's only
selected for --with-ld, since that's the only combination that suffers
from the bug described above.  It:

   - Creates new crt files, irix6-crti.asm and irix6-crtn.asm,
     defined in much the same way as the generic *-elf versions.

   - Builds irix6-crt[in].o as extra multilib files, using a new
     makefile fragment.

   - Links irix6-crti.o after the system crt files but before crtbegin.o.

   - Links irix6-crtn.o after crtend.o but before the system crt files.

Although the crt files don't provide normal .init/.fini support, they
do put an __istart function in .init:

    crt1.o:
        __istart:
                nop

    crtn.o:
                jr $31
                nop

This function is called by __start, so we have to protect the new
.init and .fini functions with return statements.  Any existing user
code that expects to be part of __istart should still work with the
new setup.

Bootstrapped & regression tested on mips-sgi-irix6.5, both with native
tools and with CVS binutils.  No regressions.  Fortran, C++ and ObjC now
work with -shared using binutils, and binutils gives better results than
the native tools for n32 & n64.  OK to install?

Richard

PS. I've been using a patch for (2) in my local tree for the last couple
    of months.  I've attached it below in case (3) isn't acceptable.


	* config.gcc (mips-sgi-irix6*): Add t-iris6gld to tmake_file when
	using GNU ld.
	* config/mips/iris6.h (IRIX6_STARTFILE_SPEC): New, taking the
	whole of the previous STARTFILE_SPEC except crtbegin.o%s.
	(IRIX6_ENDFILE_SPEC): Likewise ENDFILE_SPEC and crtend.o%s.
	(STARTFILE_SPEC, ENDFILE_SPEC): Define in terms of the above.
	(SUBTARGET_EXTRA_SPECS): Define.
	* config/mips/iris6gld.h (LINK_SPEC): Change -init function
	to __gcc_init and -fini function to __gcc_fini.
	(STARTFILE_SPEC): Redefine, including irix6-crti.o before crtbegin.o.
	(ENDFILE_SPEC): Likewise, including irix6-crtn.o after crtend.o.
	(INIT_SECTION_ASM_OP, FINI_SECTION_ASM_OP): Define.
	* config/mips/t-iris6gld,
	* config/mips/irix6-crti.asm,
	* config/mips/irix6-crtn.asm: New files.

-------------- next part --------------
An embedded and charset-unspecified text was scrubbed...
Name: init-fini-version.diff
URL: <http://gcc.gnu.org/pipermail/gcc-patches/attachments/20031124/c5022722/attachment.ksh>
-------------- next part --------------
An embedded and charset-unspecified text was scrubbed...
Name: crtstuff-version.diff
URL: <http://gcc.gnu.org/pipermail/gcc-patches/attachments/20031124/c5022722/attachment-0001.ksh>


More information about the Gcc-patches mailing list