使用链接描述文件在地址空间中布置符号时,ld
允许
使用以下内容引用来自静态库的特定符号
语法:
archive.a:object_file.o(.section.symbol_name)
使用gold
而不是ld
,似乎忽略了这样的指令。该
链接过程成功。但是,使用此指令时要具体说明
使用gold
在特定位置的符号,并检查生成的符号布局
使用nm
或查看Map文件时,符号不在预期的范围内
位置。
我使用静态编译的虚拟hello world程序制作了一个小测试用例 与gcc 5.4.0的关系。 C库是musl libc(最后提交的 来自官方git存储库的master分支)。对于binutils,我也使用了 最后在官方git存储库的master分支上提交。
我使用链接描述文件从静态放置特定符号(.text.exit
)
库(musl C库:libc.a
)位于地址空间的特定位置
这是:.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
存档?
答案 0 :(得分:0)
使用链接描述文件在地址空间中布置符号时,ld允许 指的是来自静态内部特定目标文件的特定符号 具有以下语法的库:
archive.a:object_file.o(.section.symbol_name)
这不是语法的意思。当你看到 链接器脚本中的“.section.symbol_name”(或在readelf或 objdump部分列表),这是部分的全名,和 如果你使用的话,你只会看到名称相似的部分 编译时的-ffunction-sections选项。鉴于你的脚本 适用于ld,如果你只使用完整的文件名通配符 黄金,看起来你的musl图书馆确实编译了 -ffunction-sections,但这不是你总能想到的 对系统库来说是真的。所以链接器并没有真正搜索到 名为“.text”的部分,用于定义名为“exit”的符号 - 相反, 它只是寻找一个名为“.text.exit”的部分。微妙 差异,但你应该知道它。
现在,虽然这些都不适用于黄金: MUSL / LIB /文件libc.a:exit.o(.text.exit); MUSL / LIB /文件libc.a(.text.exit);
这有效: *(。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)