OS X上的弱符号别名与Linux上的符号别名类似,还是最近似的?
我做的事
在为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本地函数的别名。
可能的解决…
现在,我刚刚禁用了这个function(使用macros实现),以便所有符号都是全局符号,并具有默认的可见性。 我现在能想到的唯一方法就是让所有的_foo
函数具有私有的可见性,并具有相应的具有默认可见性的foo
函数,并调用它们的“隐藏”对应函数。
更好的方法?
然而,这需要改变很多代码。 所以我宁愿不去那里,除非没有别的办法。
那么什么是closuresOS X的select或最简单的方法来获得相同的语义/行为?
在OS X上,在库中进行的调用是自动直接调用,不通过dyld存根。 事实的证据是,如果你想能够注入替代函数来服务一个调用,你需要使用interposable来强制间接访问符号,并通过dyld stub强制执行调用。 否则,默认情况下,本地调用将是直接的,不会导致运行dyld的开销。
因此,您在Linux上的优化已经是默认行为,不需要别名。
不过,如果你想这样做只是为了使你的平台兼容代码更简单,你仍然可以制作别名。 你只需要使用“weak_import”或“weak”(如果你想合并)作为你的属性名称。
extern typeof( _NAME )NAME __attribute (weak_import,alias(“_ NAME”));
苹果关于弱连接的参考:弱连接的标记符号
关于Mach-O运行时绑定的Apple参考: 符号定义的范围和处理