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
?