【问题标题】:Referring to a specific symbol in a static library with the GNU gold linker使用 GNU gold 链接器引用静态库中的特定符号
【发布时间】:2018-01-11 08:53:12
【问题描述】:

使用链接描述文件在地址空间中布局符号时,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) 库(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存档?

【问题讨论】:

    标签: linker ld binutils linker-scripts gold-linker


    【解决方案1】:

    当使用链接描述文件在地址空间中布局符号时,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)
    

    【讨论】:

    • 非常感谢,使用引号的语法有效。我还检查了 musl 编译标志,实际上,这些标志包括 -ffunction-sections。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-04-13
    • 2020-01-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-29
    • 1970-01-01
    相关资源
    最近更新 更多