When laying out symbols in the address space using a linker script, ld allows to
refer to a specific symbol coming from a static library with the following
syntax:
archive.a:object_file.o(.section.symbol_name)
Using gold rather than ld, it seems that such a directive is ignored. The
linking process succeeds. However, when using this instruction to put a specific
symbol at a specific location with gold and checking the resulting symbol layout
using nm or having a look at the Map file, the symbol is not in the expected
location.
I made a small test case using a dummy hello world program statically compiled in its entrety with gcc 5.4.0. The C library is musl libc (last commit on the master branch from the official git repository). For binutils, I also use the last commit on the master branch from the official git repository.
I use the linker script to place a specific symbol (.text.exit) from a static
library (musl C library: libc.a) at a specific location in the address space
which is: the first position in the .text section.
My linker script is:
ENTRY(_start)
SECTIONS
{
. = 0x10000;
.text :
{
/* Forcing .text.exit in the first position in .text section */
musl/lib/libc.a:exit.o(.text.exit);
*(.text*);
}
. = 0x8000000;
.data : { *(.data*) }
.rodata : { *(.rodata*) }
.bss : { *(.bss*) }
}
My Makefile:
# Set this to 1 to link with gold, 0 to link with ld
GOLD=1
SRC=test.c
OBJ=test.o
LIBS=musl/lib/crt1.o \
musl/lib/libc.a \
musl/lib/crtn.o
CC=gcc
CFLAGS=-nostdinc -I musl/include -I musl/obj/include
BIN=test
LDFLAGS=-static
SCRIPT=linker-script.x
MAP=map
ifeq ($(GOLD), 1)
LD=binutils-gdb/gold/ld-new
else
LD=binutils-gdb/ld/ld-new
endif
all:
$(CC) $(CFLAGS) -c $(SRC) -o $(OBJ)
$(LD) --output $(BIN) $(LDFLAGS) $(OBJ) $(LIBS) -T $(SCRIPT) \
-Map $(MAP)
clean:
rm -rf $(OBJ) $(BIN) $(MAP)
After compiling and linking I'm checking the map file (obtained using the -Map
ld/gold flag) to have a look at the location of .text.exit. Using ld as the
linker, it is indeed in the first position of the text section. Using gold, it
is not (it is present farther in the address space, as if my directive was not
taken into account).
Now, while neither of these work with gold:
musl/lib/libc.a:exit.o(.text.exit);
musl/lib/libc.a(.text.exit)
This works:
*(.text.exit);
Is that a missing feature in gold? or am I doing something wrong, maybe there is
another way to refer to a specific symbol of a specific object file in an
archive using gold?