【发布时间】:2018-10-19 19:35:29
【问题描述】:
让我先说我是与链接器相关的事情的菜鸟。如果我说的话似乎没有意义,它可能没有 - 请叫我出来。
我有以下文件:
-
bar.rs#[no_mangle] pub extern fn bar(x: isize) -> isize { x + 1 } -
foo.cextern int bar(int); extern int baz(int); int foo(int x) { return bar(x) + baz(x); }
我可以将这些链接到一个可重定位的目标文件中:
$ rustc --crate-type=staticlib bar.rs -o bar.a
$ gcc -c foo.c -o foo.o
$ ld -r foo.o bar.a -o out.o
我不确定幕后发生了什么,但我确实得到了我想要的输出:bar 和 foo 已定义,而 baz 未定义。
$ nm out.o | grep '\(foo\|bar\|baz\)$'
0000000000000000 T bar
U baz
0000000000000000 T foo
如果我用ld.bfd 替换ld,会发生完全相同的事情。然而,ld.gold 的事情就分崩离析了。
$ ld.gold -r foo.o bar.a -o out.o
ld.gold: internal error in set_info_section, at ../../gold/output.h:3198
ld.gold 与 binutils 2.24 和 2.26 一起打包。
binutils 2.30 仍然存在问题,尽管我得到的行号不同:
$ ld.gold -r foo.o bar.a -o out.o
ld.gold: internal error in set_info_section, at ../../gold/output.h:3386
此外,即使使用--emit=obj 而不是--crate-type=staticlib,错误仍然存在
所以:
- 错误是什么意思?
- 如何使用
ld.gold实现与ld和ld.bfd相同的可重定位对象输出?
【问题讨论】:
-
您应该尝试用 C 对象文件替换 Rust 对象文件。它可能会吐出一些 Gold 还不知道如何处理的元数据。
-
@Shepmaster 请注意,Rust 正在发布一个成熟的静态库。我敢肯定,gold 链接一个简单的 C 目标文件不会有问题——这就是它的设计目的。
-
我不明白你在哪里定义
baz()? -
@Stargateur 我故意没有。它应该在
out.o中未定义。注意我要求链接器产生一个可重定位的输出。这个想法是,稍后,有人可以将out.o与确实定义baz的东西联系起来。 -
(请注意,
--emit=obj在任何情况下都不是一个好主意:--crate-type=staticlib生成的静态库包含共同定义所有额外花里胡哨的目标文件,例如panic,你需要。)
标签: unix linker rust ld gold-linker