Issue
I have a gcc
binary which was compiled on Solaris 8. For an experiment, I've brought it over to a NetBSD 8.2 virtual machine to see if I can get it working in that environment. The compilation phase of that gcc
appears to work successfully (i.e. gcc -c some_program.c
), but if the linker is involved, the linker appears to generate a segmentation violation. I suspect this has something to do with the built-in linker path in gcc
. Is there a way to alter this path without completely rebuilding the binary?
Below is the output of gcc -v -o small small.c
, where small.c
simply has int main() { return 0; }
:
Reading specs from /usr/local/lib/gcc-lib/sparc-sun-solaris2.8/2.95.1/specs
gcc version 2.95.1 19990816 (release)
/usr/local/lib/gcc-lib/sparc-sun-solaris2.8/2.95.1/cpp -lang-c -v -D__GNUC__=2 -D__GNUC_MINOR__=95 -Dsparc -Dsun -Dunix -D__svr4__ -D__SVR4 -D__sparc__ -D__sun__ -D__unix__ -D__svr4__ -D__SVR4 -D__sparc -D__sun -D__unix -Asystem(unix) -Asystem(svr4) -D__GCC_NEW_VARARGS__ -Acpu(sparc) -Amachine(sparc) small.c /var/tmp/ccibWaJl.i
GNU CPP version 2.95.1 19990816 (release) (sparc)
#include "..." search starts here:
#include <...> search starts here:
.
.
.
.
End of search list.
The following default directories have been omitted from the search path:
/usr/local/lib/gcc-lib/sparc-sun-solaris2.8/2.95.1/../../../../include/g++-3
End of omitted list.
/usr/local/lib/gcc-lib/sparc-sun-solaris2.8/2.95.1/cc1 /var/tmp/ccibWaJl.i -quiet -dumpbase small.c -version -o /var/tmp/ccCCiV6u.s
GNU C version 2.95.1 19990816 (release) (sparc-sun-solaris2.8) compiled by GNU C version 2.95.1 19990816 (release).
/usr/ccs/bin/as -V -Qy -s -o /var/tmp/ccqr3F3G.o /var/tmp/ccCCiV6u.s
/usr/ccs/bin/as: Sun WorkShop 6 99/08/18
/usr/local/lib/gcc-lib/sparc-sun-solaris2.8/2.95.1/collect2 -V -Y P,/usr/ccs/lib:/usr/lib -Qy -o small /usr/local/lib/gcc-lib/sparc-sun-solaris2.8/2.95.1/crt1.o /usr/local/lib/gcc-lib/sparc-sun-solaris2.8/2.95.1/crti.o /usr/ccs/lib/values-Xa.o /usr/local/lib/gcc-lib/sparc-sun-solaris2.8/2.95.1/crtbegin.o -L/usr/local/lib/gcc-lib/sparc-sun-solaris2.8/2.95.1 -L/usr/ccs/bin -L/usr/ccs/lib -L/usr/local/lib /var/tmp/ccqr3F3G.o -lgcc -lc -lgcc /usr/local/lib/gcc-lib/sparc-sun-solaris2.8/2.95.1/crtend.o /usr/local/lib/gcc-lib/sparc-sun-solaris2.8/2.95.1/crtn.o
collect2: ld terminated with signal 11 [Segmentation Fault]
ld: Software Generation Utilities - Solaris Link Editors: 5.8-1.281
Update: For comparison, here is the output of the same compile string using the gcc
binary on NetBSD:
Using built-in specs.
COLLECT_GCC=gcc
COLLECT_LTO_WRAPPER=/usr/libexec/lto-wrapper
Target: sparc--netbsdelf
Configured with: /usr/src/tools/gcc/../../external/gpl3/gcc/dist/configure --target=sparc--netbsdelf --enable-long-long --enable-threads --with-bugurl=http://www.NetBSD.org/Misc/send-pr.html --with-pkgversion='NetBSD nb3 20180905' --with-system-zlib --disable-libstdcxx-dual-abi --enable-__cxa_atexit --enable-libstdcxx-time=rt --enable-libstdcxx-threads --with-diagnostics-color=auto-if-env --with-mpc-lib=/var/obj/mknative/sparc/usr/src/external/lgpl3/mpc/lib/libmpc --with-mpfr-lib=/var/obj/mknative/sparc/usr/src/external/lgpl3/mpfr/lib/libmpfr --with-gmp-lib=/var/obj/mknative/sparc/usr/src/external/lgpl3/gmp/lib/libgmp --with-mpc-include=/usr/src/external/lgpl3/mpc/dist/src --with-mpfr-include=/usr/src/external/lgpl3/mpfr/dist/src --with-gmp-include=/usr/src/external/lgpl3/gmp/lib/libgmp/arch/sparc --enable-tls --disable-multilib --disable-symvers --disable-libstdcxx-pch --disable-libstdcxx-dual-abi --build=sparc--netbsdelf --host=sparc--netbsdelf --with-sysroot=/var/obj/mknative/sparc/usr/src/destdir.sparc
Thread model: posix
gcc version 5.5.0 (nb3 20180905)
COLLECT_GCC_OPTIONS='-v' '-o' 'small' '-mcpu=v7'
/usr/libexec/cc1 -quiet -v small.c -quiet -dumpbase small.c -mcpu=v7 -auxbase small -version -o /tmp//ccZMD7zc.s
GNU C11 (nb3 20180905) version 5.5.0 (sparc--netbsdelf)
compiled by GNU C version 5.5.0, GMP version 5.1.3, MPFR version 3.1.2, MPC version 1.0.1
GGC heuristics: --param ggc-min-expand=46 --param ggc-min-heapsize=30704
#include "..." search starts here:
#include <...> search starts here:
/usr/include/gcc-5
/usr/include
End of search list.
GNU C11 (nb3 20180905) version 5.5.0 (sparc--netbsdelf)
compiled by GNU C version 5.5.0, GMP version 5.1.3, MPFR version 3.1.2, MPC version 1.0.1
GGC heuristics: --param ggc-min-expand=46 --param ggc-min-heapsize=30704
Compiler executable checksum: 2df9f867f6d360c5052229962b633018
COLLECT_GCC_OPTIONS='-v' '-o' 'small' '-mcpu=v7'
as -v -32 -relax -o /tmp//ccXtMemo.o /tmp//ccZMD7zc.s
GNU assembler version 2.27 (sparc--netbsdelf) using BFD version (NetBSD Binutils nb1) 2.27
COMPILER_PATH=/usr/libexec/
LIBRARY_PATH=/usr/lib/
COLLECT_GCC_OPTIONS='-v' '-o' 'small' '-mcpu=v7'
ld -plugin /usr/libexec/liblto_plugin.so -plugin-opt=/usr/libexec/lto-wrapper -plugin-opt=-fresolution=/tmp//ccyzsYKQ.res -plugin-opt=-pass-through=-lgcc_s -plugin-opt=-pass-through=-lgcc -plugin-opt=-pass-through=-lc -plugin-opt=-pass-through=-lgcc_s -plugin-opt=-pass-through=-lgcc -plugin-opt=-pass-through=-lc --eh-frame-hdr -m elf32_sparc -relax -dc -dp -e __start -dynamic-linker /usr/libexec/ld.elf_so -o small /usr/lib/crt0.o /usr/lib/crti.o /usr/lib/crtbegin.o /tmp//ccXtMemo.o --as-needed -lgcc_s --no-as-needed -lgcc -lc --as-needed -lgcc_s --no-as-needed -lgcc -lc /usr/lib/crtend.o /usr/lib/crtn.o
Update as of 04/20/2022 5:46 PM EST: I've installed gcc
version 3.4.6 on my Solaris 8 virtual machine, and it appears to work there. However, transferring that binary as well as all of the necessary libraries over to NetBSD results in an immediate segmentation violation whenever the Solaris 8 gcc
binary runs. Some other dynamically linked binaries from the Solaris 8 VM still seem functional, though.
I also attempted specifying the -B
flag to the original 2.95.1 gcc
binary and passing the directory containing the collect2
executable. This seemed to have no effect on the result. Perhaps I will try to use other versions of gcc
...
Solution
It seems that invoking the linker separately, as per Eugene's suggestion in the first comment on the OP, worked. Here are the high level steps I took to get a working executable:
- Compile the small program with
gcc -c
to get an object file. - Run all phases of
gcc
with-v
to get the linker command thatgcc
is trying to run. - Copy the linker line of that output to a shell script and replace the respective paths to the linker as well as all of the object files involved with the correct paths.
- Add the
-rpath
parameter to the command to cover any "*.so
library not found" errors. - Run the shell script.
- Run the produced program.
Thanks to everyone who commented on the OP as well!
Answered By - fireshadow52 Answer Checked By - Mildred Charles (WPSolving Admin)