使用 GNU gold 链接器引用静态库中的特定符号
Referring to a specific symbol in a static library with the GNU gold linker
使用链接描述文件在地址 space 中布置符号时,ld
允许
使用以下内容引用来自静态库的特定符号
语法:
archive.a:object_file.o(.section.symbol_name)
使用gold
而不是ld
,似乎这样的指令被忽略了。这
链接过程成功。然而,当使用这个指令来放置一个特定的
使用 gold
在特定位置的符号并检查生成的符号布局
使用 nm
或查看地图文件,该符号不在预期范围内
位置。
我使用静态编译的虚拟 hello world 程序制作了一个小测试用例
在 gcc 5.4.0 中。 C 库是 musl libc(最后一次提交
来自官方 git 存储库的 master 分支)。对于 binutils,我还使用
来自官方 git 存储库的 master 分支的最后一次提交。
我使用链接描述文件从静态文件中放置一个特定的符号(.text.exit
)
地址 space 中特定位置的库(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*) }
}
我的生成文件:
# 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
,它
不是(它出现在地址 space 更远的地方,就好像我的指令不是
考虑在内)。
现在,虽然这些都不适用于 gold
:
musl/lib/libc.a:exit.o(.text.exit);
musl/lib/libc.a(.text.exit)
这个有效:
*(.text.exit);
这是 gold
中缺少的功能吗?或者我做错了什么,也许有
另一种引用特定目标文件的特定符号的方法
使用 gold
?
存档
When laying out symbols in the address space using a linker script, ld allows to
refer to a specific symbol coming from a specific object file inside a static
library with the following syntax:
archive.a:object_file.o(.section.symbol_name)
这不是语法的意思。当你看到
“.section.symbol_name” 在链接器脚本中(或在 readelf 或
objdump 列表部分),即部分的全名,以及
如果您使用
编译时的 -ffunction-sections 选项。鉴于你的脚本
与 ld 一起工作,如果你只是使用完整的文件名通配符
gold,看起来你的 musl 库确实是用
-ffunction-sections,但这不是你总是可以假设的
适用于系统库。所以链接器并不是真的在寻找一个
名为“.text”的部分定义了一个名为 "exit" 的符号——相反,
它只是在寻找名为“.text.exit”的部分。微妙的
区别,但你应该意识到这一点。
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?
如果您查看生成的 -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)
使用链接描述文件在地址 space 中布置符号时,ld
允许
使用以下内容引用来自静态库的特定符号
语法:
archive.a:object_file.o(.section.symbol_name)
使用gold
而不是ld
,似乎这样的指令被忽略了。这
链接过程成功。然而,当使用这个指令来放置一个特定的
使用 gold
在特定位置的符号并检查生成的符号布局
使用 nm
或查看地图文件,该符号不在预期范围内
位置。
我使用静态编译的虚拟 hello world 程序制作了一个小测试用例 在 gcc 5.4.0 中。 C 库是 musl libc(最后一次提交 来自官方 git 存储库的 master 分支)。对于 binutils,我还使用 来自官方 git 存储库的 master 分支的最后一次提交。
我使用链接描述文件从静态文件中放置一个特定的符号(.text.exit
)
地址 space 中特定位置的库(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*) }
}
我的生成文件:
# 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
,它
不是(它出现在地址 space 更远的地方,就好像我的指令不是
考虑在内)。
现在,虽然这些都不适用于 gold
:
musl/lib/libc.a:exit.o(.text.exit);
musl/lib/libc.a(.text.exit)
这个有效:
*(.text.exit);
这是 gold
中缺少的功能吗?或者我做错了什么,也许有
另一种引用特定目标文件的特定符号的方法
使用 gold
?
When laying out symbols in the address space using a linker script, ld allows to refer to a specific symbol coming from a specific object file inside a static library with the following syntax:
archive.a:object_file.o(.section.symbol_name)
这不是语法的意思。当你看到 “.section.symbol_name” 在链接器脚本中(或在 readelf 或 objdump 列表部分),即部分的全名,以及 如果您使用 编译时的 -ffunction-sections 选项。鉴于你的脚本 与 ld 一起工作,如果你只是使用完整的文件名通配符 gold,看起来你的 musl 库确实是用 -ffunction-sections,但这不是你总是可以假设的 适用于系统库。所以链接器并不是真的在寻找一个 名为“.text”的部分定义了一个名为 "exit" 的符号——相反, 它只是在寻找名为“.text.exit”的部分。微妙的 区别,但你应该意识到这一点。
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?
如果您查看生成的 -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)