用一些相同的符号链接两个共享库 [英] Linking two shared libraries with some of the same symbols

查看:26
本文介绍了用一些相同的符号链接两个共享库的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我链接了两个不同的共享库.两个库都定义了一些共享名称但具有不同实现的符号.我不能让每个库使用自己的实现而不是另一个.

I link with two different shared libraries. Both libraries define some symbols that share a name but have different implementations. I can't make each library use its own implementation over the other.

例如,两个库都定义了一个全局函数 bar(),每个函数都在内部调用.库一从 foo1() 调用它,库二从 foo2() 调用它.

For example, both libraries define a global function bar() that each calls internally. Library one calls it from foo1() and library two calls it from foo2().

Lib1.so:

T bar
T foo1()     // calls bar()

Lib2.so:

T bar
T foo2()     // calls bar()

如果我将我的应用程序链接到 Lib1.so,然后链接到 Lib2.so,即使在调用 foo2() 时也会调用来自 Lib1.so 的 bar 实现.另一方面,如果我将我的应用程序链接到 Lib2.so,然后链接到 Lib1.so,那么 bar 总是从 Lib2.so 调用.

If I link my application against Lib1.so and then Lib2.so the bar implementation from Lib1.so is called even when calling foo2(). If on the other hand, I link my application against Lib2.so and then Lib1.so, then bar is always called from Lib2.so.

有没有办法让一个库总是比任何其他库更喜欢它自己的实现?

Is there a way to make a library always prefer its own implementation above any other library?

推荐答案

有几种方法可以解决这个问题:

There are several ways to solve this:

  • -Bsymbolic-Bsymbolic-functions 传递给链接器.这具有全局效果:对可以解析为库中符号的全局符号(-Bsymbolic-functions 的函数类型)的每个引用都解析为该符号.这样您就无法使用 LD_PRELOAD 将内部库调用插入到这些符号中.符号仍会导出,因此可以从库外部引用它们.

  • Pass -Bsymbolic or -Bsymbolic-functions to the linker. This has a global effect: every reference to a global symbol (of function type for -Bsymbolic-functions) that can be resolved to a symbol in the library is resolved to that symbol. With this you lose the ability to interpose internal library calls to those symbols using LD_PRELOAD. The symbols are still exported, so they can be referenced from outside the library.

使用版本脚本将符号标记为库的本地,例如使用类似:{local: bar;}; 并将 --version-script=versionfile 传递给链接器.符号导出.

Use a version script to mark symbols as local to the library, e.g. use something like: {local: bar;}; and pass --version-script=versionfile to the linker. The symbols are not exported.

用适当的可见性标记符号(用于可见性的 GCC 信息页面),这将是隐藏内部保护.protected 可见性符号导出为 .protected隐藏 符号是不导出,并且内部符号不导出,你妥协了不从库外部调用它们,即使是通过函数指针间接调用.

Mark symbols with an approppiate visibility (GCC info page for visibility), which will be either hidden, internal, or protected. protected visibility symbols are exported as .protected, hidden symbols are not exported, and internal symbols are not exported and you compromise not to call them from outside the library, even indirectly through function pointers.

您可以使用 objdump -T 检查导出了哪些符号.

You can check which symbols are exported with objdump -T.

这篇关于用一些相同的符号链接两个共享库的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆