OS X上的弱符号别名与Linux上的符号别名类似,还是最近似的?

我做的事

在为Linux编写共享库时,我倾向于注意重定位,符号可见性,GOT / PLT等。

适用时,我试图避免在同一个库中的函数互相调用时调用PLT存根。 例如,假设一个共享对象提供了两个公共函数foo()bar() (这两个函数都可以被用户调用)。 bar()函数也会调用foo() 。 所以我在这种情况下做的是这样的:

  1. 定义具有私有可见性的_foo()_bar()函数。
  2. 分别为_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参考: 符号定义的范围和处理