Take a simple hello world program and compile it as follows:
> g++ --version
g++ 6.3.0
Copyright (C) 2016 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
> g++ -fuse-ld=gold test.cpp -o test
Inspecting the binary produced:
> readelf -l ./test
Elf file type is EXEC (Executable file)
Entry point 0x400750
There are 9 program headers, starting at offset 64
Program Headers:
Type Offset VirtAddr PhysAddr
FileSiz MemSiz Flags Align
PHDR 0x0000000000000040 0x0000000000400040 0x0000000000400040
0x00000000000001f8 0x00000000000001f8 R 8
INTERP 0x0000000000000238 0x0000000000400238 0x0000000000400238
0x000000000000001c 0x000000000000001c R 1
[Requesting program interpreter: /lib64/ld-linux-x86-64.so.2]
LOAD 0x0000000000000000 0x0000000000400000 0x0000000000400000
0x0000000000000ac8 0x0000000000000ac8 R E 1000
LOAD 0x0000000000000dc0 0x0000000000401dc0 0x0000000000401dc0
0x0000000000000288 0x00000000000003d0 RW 1000
DYNAMIC 0x0000000000000de0 0x0000000000401de0 0x0000000000401de0
0x0000000000000200 0x0000000000000200 RW 8
NOTE 0x0000000000000254 0x0000000000400254 0x0000000000400254
0x0000000000000044 0x0000000000000044 R 4
GNU_EH_FRAME 0x0000000000000a8c 0x0000000000400a8c 0x0000000000400a8c
0x000000000000003c 0x000000000000003c R 4
GNU_STACK 0x0000000000000000 0x0000000000000000 0x0000000000000000
0x0000000000000000 0x0000000000000000 RW 0
GNU_RELRO 0x0000000000000dc0 0x0000000000401dc0 0x0000000000401dc0
0x0000000000000240 0x0000000000000240 RW 8
Section to Segment mapping:
Segment Sections...
00
01 .interp
02 .interp .note.ABI-tag .note.gnu.build-id .dynsym .dynstr .gnu.hash .gnu.version .gnu.version_r .rela.dyn .rela.plt .init .plt .text .fini .rodata .eh_frame .eh_frame_hdr
03 .jcr .fini_array .init_array .dynamic .got .got.plt .data .bss
04 .dynamic
05 .note.ABI-tag .note.gnu.build-id
06 .eh_frame_hdr
07
08 .jcr .fini_array .init_array .dynamic .got
Notice that the interpreter used is ld
. Whilst the program happens to work, I've not been able to find any information on whether this is safe. For all I know, gold
interprets the ELF specification in a subtly different and incompatible way that requires a different interpreter.
I've done my best to research this, but have been unable to find anything that answers my question. The closest I've found is that gold
struggles to link the Linux kernel (or struggled, since time has past and it may have been fixed).
You're falling into the naming trap — gold
is a link editor, while ld.so
is a dynamic loader. Although at different times, they are called linkers (the latter often referred to also as runtime linker.)
Their scope and usage is very different, the first one generates the final executable you'll eventually run, while the latter takes the generated file, finds its dependencies, and resolve (links) the undefined symbols between those.
Indeed, gold
and ld
(precisely, bfd-ld
), the link editors, are provided by binutils
(or alternative toolchain packages such as clang
and so on), while ld.so
is provided by the C library package, usually glibc
on Linux distributions, but alternatively uclibc
or musl
.
Combining this with Martin Rosenau's comment...
Looking at the content of /usr/bin/gold, you can see that the string /lib64/ld-linux-x86-64.so.2 is stored inside the gold executable. This means that the gold linker itself "decides" using that runtime interpreter. For this reason I doubt that there are incompatibilities.
... ld.so
should be compatible with the gold
linker.