2

使用链接描述文件在地址空间中布局符号时,ld允许使用以下语法引用来自静态库的特定符号:

archive.a:object_file.o(.section.symbol_name)

使用gold而不是ld,似乎这样的指令被忽略了。链接过程成功。但是,当使用此指令将特定符号放置在特定位置gold并使用或查看 Map 文件检查生成的符号布局nm时,该符号不在预期位置。

我使用gcc 5.4.0在其entrety中静态编译的虚拟hello world程序制作了一个小测试用例。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*) }
}

我的制作文件:

# 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

4

1 回答 1

0

使用链接描述文件在地址空间中布局符号时,ld 允许使用以下语法引用来自静态库中特定目标文件的特定符号:

archive.a:object_file.o(.section.symbol_name)

这不是该语法的含义。当您在链接描述文件(或 readelf 或 objdump 节列表)中看到“.section.symbol_name”时,这就是节的全名,如果您使用 -编译时的 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)
于 2017-08-03T23:21:27.190 回答