我可以用自己的版本替换静态库中的符号吗?

时间:2018-08-08 15:04:46

标签: c linker

使用gcc / ld,我要使用libfoo.a,它包含一个符号symbol_foo(这是一个函数-如果重要的话,请参阅ISR)。 libfoo中的其他函数显然使用了此函数。我想做的是使用libfoo.a编译我自己的二进制文件,但是链接到我自己的symbol_foo版本中。

这可能吗?当前,由于符号的多个定义,我得到ld错误。即它没有声明为“软链接”或原始静态库中的类似内容。

理想情况下,我希望那里存在类似__attribute__((ld_override))之类的东西,但是我猜那里没有。有什么想法吗?

2 个答案:

答案 0 :(得分:5)

这取决于库的设计。对于您而言,答案是“否”,因为该函数未在库中隔离。有关图书馆建设的良好论述,请参阅P J Plauger The Standard C Library1992。是的,它已经相当老了,因此Standard C的版本是C90,但是它所支持的思想仍然有效。

链接器在构建程序时,将处理一系列目标文件和库,以查找不满意的引用(符号名)和跟踪定义。在大多数情况下,它以未定义的符号main开头。

  • 在处理目标文件时,它会记下定义的满足未定义符号的符号,并记住该文件定义的所有名称(并且它抱怨发现的符号之一与它已经知道的符号发生冲突)。
  • 在处理静态库时,它会查找已定义但尚未为其定义的符号。找到这样的符号后,它将链接库中的目标文件,并指出已定义的符号和仍未定义的符号。

现在,如果包含symbol_foo的目标文件仅定义了symbol_foo,那么如果您在读取库之前已经链接了symbol_foo,则链接器将忽略{{1} };它已经有一个定义,不需要另一个。但是,symbol_foo库中包含symbol_foo的目标文件可能还会定义一些其他符号,而链接器需要这些其他符号,因此它必须链接包含{{ 1}},并且抱怨该符号是双重定义的,即使同一文件中的其他符号不是该符号也是如此。

Plauger提倡(静态)库中的每个目标文件应定义一个外部符号。这样可以最大程度地替代库中的功能。我相信可以假设libfoo.a的设计者没有做出决定,至少要加上symbol_foo

您可以从libfoo.a中提取目标文件(使用临时目录)并使用symbol_foo检查其内容;您也许可以直接在库本身上执行此操作。与正确的选项一起使用,将向您显示哪些文件定义和引用了其他符号。

请注意,与共享库链接的规则有些不同。还有“弱”符号会改变行为。您通常还可以从多个目标文件中创建“可重定位”或“可重新链接”的目标文件(通常为libfoo.a);这样可以为您提供一个更大的目标文件并更改方程式。最后,现在,链接描述文件可以控制哪些符号在库外部可见。因此,这不过是整个主题的掩饰。

答案 1 :(得分:0)

作为一般规则,如果您要覆盖(替换)静态库中的一个非弱全局符号,而仍然使用该库的其余部分,那么您还需要替换所有其他非-静态库中同一编译单元中的弱全局符号。

您可以使用$ python manage.py runserver 在库中找到所有符号-运行
nm将列出库中的每个对象(编译单元),然后列出所有非弱全局对象该对象中的符号。