我所做的
在为 Linux 编写共享库时,我倾向于关注重定位、符号可见性、GOT/PLT 等。
如果适用,我会尽量避免在同一个库中的函数相互调用时调用 PLT 存根。例如,假设一个共享对象提供了两个公共函数 -foo()
和bar()
(其中任何一个都可以由用户调用)。bar()
但是,该函数也调用foo()
. 所以我在这种情况下要做的是:
- 定义具有私有可见性的函数
_foo()
。_bar()
- 分别为和定义
foo()
和bar()
弱别名。_foo()
_bar()
这样,共享对象中的代码就不会使用弱符号。它只直接调用本地函数。例如,当_bar()
被调用时,它_foo()
直接调用。
但用户不了解_*
函数,总是使用相应的弱别名。
我是怎么做的
在 Linux 中,这是通过使用以下结构来实现的:
extern __typeof (_NAME) NAME __attribute__(weak, alias("_NAME"));
问题
不幸的是,这不适用于 OS X。我对 OS X 或其二进制格式没有深入的了解,所以我翻了一下,发现了一些弱函数的例子(比如这个),但那些并不完全就像你可以有一个弱符号一样,但不能有一个弱符号,它是 DSO 本地函数的别名。
可能的解决方案...
现在,我刚刚禁用了这个功能(使用宏实现),以便所有符号都是全局的并且具有默认可见性。我现在能想到的唯一方法是让所有_foo
函数都具有私有可见性,并具有foo
具有默认可见性的相应函数并调用它们的“隐藏”对应项。
更好的方法?
但是,这需要更改大量代码。因此,除非真的没有其他办法,否则我宁愿不去那里。
那么关闭 OS X 替代方案或获得相同语义/行为的最简单方法是什么?