gpt4 book ai didi

c++ - 如何检查为什么链接需要某些符号?

转载 作者:行者123 更新时间:2023-12-01 14:47:32 27 4
gpt4 key购买 nike

这个问题变得很麻烦,让我们尝试简短的版本:
通常当你失败时 unresolved symbol reference这是相当困难的,在这里你称之为链接器找不到的东西。您只需为链接器提供库,它就可以正常工作。有时,在某些情况下,您将头撞在墙上,但不明白链接器为什么要在这里和那里使用这个符号,它没有被调用,至少不是直接调用。是否有工具/链接器开关可以解释为什么它认为“此处”需要符号?

原问题:
这都是关于静态链接的。我有一些小实用程序,几行代码,几个包含。该实用程序与名为 lib1 的库静态链接.让我们说 lib1依赖于另一个库,lib2 , 自 lib1使用符号 sym1来自 lib2 .然而没有什么使用 sym1来自 lib2是从实用程序使用/调用的,也不是来自 lib1 的任何内容。可能依赖于 lib2 .然而,前面提到的小实用程序失败了,无法解析 sym1 的符号。 .第一个问题是为什么?因为,在实用程序中 sym1不需要任何地方,甚至不需要来自 lib1 的符号使用 sym1在实用程序中使用,为什么链接器首先要寻找这个符号?第二个问题,包含链有可能引入符号sym1到我的实用程序,然后它回答“为什么”但不应该引入它(至少没有明显的原因),所以第二个问题是我如何找到链接器认为该实用程序需要 sym1 的原因来自 lib2 ?

什么/何时/为什么:Linux、C/C++、GCC-9/Clang-9

最佳答案

好吧,显然我设法回答了这个问题,没有看到代码和错误消息。是时候开启我的 psi 咨询服务了。

关于在 Linux/ELF 目标上链接,重要的是要记住链接器在尝试满足/解析符号时,正在合并(并复制到最终的可执行文件)节(又名段)。通常应用程序具有 .text(代码段)、.rodata(只读数据)段、.data(r/w 初始化数据)段、.bss(未初始化数据)等。因此,如果需要,符号在三个函数中在一个编译文件中,将选择文件的整个 .text 部分。如果未使用但存在于部分函数调用其他东西,链接器将开始搜索“其他东西”来满足,即使它与应用程序无关。

另外,还有一些 C++ 特定的东西:对于具有虚函数的类,编译器生成 vtable,带有指向每个虚函数的指针,并将该表移动到 .rodata 部分。注意,那什么
我们认为代码实际上是在(只读)DATA 部分结束的。

如果您定义了除一个之外的所有虚拟函数,链接器很可能会提示错误消息,例如

/tmp/cc5YTcBb.o:(.rodata._ZTV3CL1[_ZTV3CL1]+0x18): undefined reference to `CL1::fnc2()

您可以在哪里看到问题在于 .rodata,而不是 .text。

故事的寓意:将您的代码和数据切成大量尽可能小的部分/段,即您的链接原子。理想情况下,每个函数都进入自己的部分,以及一段初始化或 r/o 数据。

最后一步是指示链接器(通过 -Wl 选项)丢弃(垃圾收集)所有未使用的部分。

一般来说,人们应该期望链接器使用更多的 RAM,链接阶段可能更慢,但应用程序更小更快。

命令行使用,看看GCC手册wrt选项的含义。
g++ -fdata-sections -ffunction-sections -fipa-pta main.cpp -Wl,--gc-sections -Wl,-O1 -Wl,--as-needed

关于c++ - 如何检查为什么链接需要某些符号?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62450033/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com