使用GNU gold链接器引用静态库中的特定符号
使用链接描述文件在地址空间中布置符号时,ld
允许 引用来自静态库的特定符号,其语法如下 :使用GNU gold链接器引用静态库中的特定符号
archive.a:object_file.o(.section.symbol_name)
使用gold
而不是ld
,似乎这样的指令被忽略。 链接过程成功。但是,当使用此指令将特定 符号放在特定位置gold
并使用nm
检查生成的符号布局 或查看映射文件时,符号不在预期的 位置中。
我用一个虚拟hello世界程序制作了一个小测试用例,其静态编译为 ,其gcc版本为5.4.0。 C库是musl libc(最后一次在官方git仓库的 master分支上提交)。对于binutils,我还使用官方git仓库master分支上的 最后一次提交。
我使用链接脚本从静态 库(MUSL C库:libc.a
)放置一个特定符号(.text.exit
)在地址空间 这是一个特定的位置:在.text
部分中的第一位置。
我的链接脚本是:
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*) }
}
我的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)
(使用-Map ld
/gold
标志获得)来编译和链接我检查的地图文件后看看.text.exit
的位置。使用ld
作为 链接器,它确实在文本部分的第一个位置。使用gold
,它不是 (它存在于地址空间的更远处,就好像我的指令不是考虑到 一样)。
现在,虽然既不gold
这些工作:
musl/lib/libc.a:exit.o(.text.exit);
musl/lib/libc.a(.text.exit)
这工作:
*(.text.exit);
的是,在gold
缺少功能?或者我做错了什么,也许有 使用gold
在 存档中引用特定目标文件的特定符号的另一种方法?
当使用链接脚本铺设在地址空间符号,LD允许 指从一个特定的对象文件来静态 库里面的语法如下特定符号:
存档。答:object_file.o(.section伪。symbol_name)
这不完全是什么语法的含义。当在链接描述文件中(或者在某个节点的重新下载或 objdump列表中)看到 “.section.symbol_name”,这是该节的全名,而 只有当您看到类似名称的节时编译时使用 -ffunction-sections选项。鉴于您的脚本 适用于ld,并且如果您只使用完整文件名通配符,则看起来您的musl库确实是使用 -ffunction-sections编译的,但这并不总是假设为 true用于系统库。因此,链接器并不是真的在搜索名为“.text”的 节,该节定义了一个名为“exit”的符号 - 相反,它只是寻找名为“.text.exit”的节。微妙的 区别,但你应该知道它。
现在,虽然这些工作都没有金: musl/lib/libc.a:exit.o(.text.exit); musl/lib/libc.a(.text.exit);
This works: *(.text.exit);
这是黄金缺失的功能吗?或者我做错了什么,也许有 另一种方式来引用一个 存档使用黄金中的特定对象文件的特定符号?
如果你看一下导致-Map输出文件,我怀疑你会看到 目标文件的名称被写成“MUSL/lib目录/文件libc.a(exit.o)”。 这就是您需要在脚本中使用的拼写,并且因为括号内有 ,所以您需要引用它。这:
"musl/lib/libc.a(exit.o)"(.text.exit)
应该工作。如果你想要的东西,会在这两个接头工作,尝试 是这样的:
"musl/lib/libc.a*exit.o*"(.text.exit)
或只是
"*exit.o*"(.text.exit)
非常感谢您使用引号语法工作。我还检查了musl编译标志,实际上,这些包括-ffunction-sections。 –