The MIPS linker has an option -exports_file <filename> which controls the set of symbols exported from a shared library. However, if this argument is given, then the default action is to hide symbols unless so specified, and -- here's the annoying part -- it rejects the -hidden_symbol argument as "conflicting". And guess what? When given "-shared" and using the native linker, gcc unconditionally passes "-hidden_symbol __do_global_ctors,__do_global_ctors_1,__do_global_dtors", and the link fails. The basic workaround is easy: Don't use an exports list; that can lead to namespace pollution, symbol name conflicts, etc. Or, hack the specs file to punt the hidden_symbol option; that's just ugly. Near as I can tell, "-Wl,-foo" and "-Xlinker -foo" options can't be checked with %{!foo:...} patterns in the specs file, so there's no easy way to see if the option is being given to the linker. A fix might be to give gcc on IRIX a new command-line option which takes a filename parameter, and can be checked in the specs file. (Actually, maybe two options; I think the exported_symbol variant might also tweak the default and conflict with hidden_symbol.) Export lists are a fairly common feature of linkers these days. Perhaps such options should be added to the gcc command line where they'll be common to the platforms that support them? Then -exports_file can be passed to the MIPS linker, something else to the Tru64 linker, something else to the GNU linker, etc.
% /u2/gnu/build/gcc-no-binutils/gcc/xgcc -shared -Wl,-ignore_unresolved -Wl,-update_registry -Wl,../../so_locations -Wl,-soname -Wl,libcom_err.so.3 -o libcom_err.so.3.0 error_message.o et_name.o com_err.o -Wl,-exports_file -Wl,../../../src/util/et/libcom_err.exports -v Reading specs from /u2/gnu/Install-no-binutils/lib/gcc/mips-sgi-irix6.5/3.4.0/specs Configured with: ../../src/gcc-3.4.0/configure --prefix=/u2/gnu/Install-no-binutils --disable-multilib Thread model: single gcc version 3.4.0 /u2/gnu/Install-no-binutils/libexec/gcc/mips-sgi-irix6.5/3.4.0/collect2 -shared -init __do_global_ctors -fini __do_global_dtors -hidden_symbol __do_global_ctors,__do_global_ctors_1,__do_global_dtors -_SYSTYPE_SVR4 -woff 131 -n32 -o libcom_err.so.3.0 /u2/gnu/Install-no-binutils/lib/gcc/mips-sgi-irix6.5/3.4.0/crtbegin.o -L/u2/gnu/Install-no-binutils/lib/gcc/mips-sgi-irix6.5/3.4.0 -L/usr/bin -L/u2/gnu/Install-no-binutils/lib/gcc/mips-sgi-irix6.5/3.4.0/../../.. -ignore_unresolved -update_registry ../../so_locations -soname libcom_err.so.3 error_message.o et_name.o com_err.o -exports_file ../../../src/util/et/libcom_err.exports -dont_warn_unused -lgcc_s -warn_unused -L/usr/lib32/mips3 -L/usr/lib32 -dont_warn_unused -lgcc_s -warn_unused /u2/gnu/Install-no-binutils/lib/gcc/mips-sgi-irix6.5/3.4.0/crtend.o ld32: ERROR 4 : Conflicting flag setting: -exports_file -_SYSTYPE_SVR4 set multiple times collect2: ld returned 2 exit status
Sorry, here's some data from another run with -Wl,-v so the linker command is shown: collect2 version 3.4.0 /usr/bin/ld -shared -init __do_global_ctors -fini __do_global_dtors -hidden_symbol __do_global_ctors,__do_global_ctors_1,__do_global_dtors -_SYSTYPE_SVR4 -woff 131 -n32 -o libcom_err.so.3.0 /u2/gnu/Install-no-binutils/lib/gcc/mips-sgi-irix6.5/3.4.0/crtbegin.o -L/u2/gnu/Install-no-binutils/lib/gcc/mips-sgi-irix6.5/3.4.0 -L/usr/bin -L/u2/gnu/Install-no-binutils/lib/gcc/mips-sgi-irix6.5/3.4.0/../../.. -ignore_unresolved -update_registry ../../so_locations -soname libcom_err.so.3 error_message.o et_name.o com_err.o -exports_file ../../../src/util/et/libcom_err.exports -v -dont_warn_unused -lgcc_s -warn_unused -L/usr/lib32/mips3 -L/usr/lib32 -dont_warn_unused -lgcc_s -warn_unused /u2/gnu/Install-no-binutils/lib/gcc/mips-sgi-irix6.5/3.4.0/crtend.o ld32: ERROR 4 : Conflicting flag setting: -exports_file -_SYSTYPE_SVR4 set multiple times ld32: 1: loading /u2/gnu/Install-no-binutils/lib/gcc/mips-sgi-irix6.5/3.4.0/crtbegin.o. ld32: 2: loading error_message.o. [...] It looks like the linker continues going about its business, but has already decided to return an error at the end.
Confirmed the SPEC entry comes from the LINK_SPEC in the following files: iris5gas.h, iris6.h, and iris6gas.h. I think the hidden_symbol is remove the global [dc]tors functions from the namespace.
The irix configurations have been reworked for 3.5. A downside of this change (from one POV) is that we now require the GNU assembler. An upside is that we can avoid using -hidden_symbol, so -exports_file should work fine.