我做了什么
在为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。我对OS或它的二进制格式没有很深的了解,所以我浏览了一下,并发现了一些弱函数的例子(如这一个),但是这些例子不太像您可以有一个弱符号,但不是一个弱符号,而弱符号是DSO的本地函数的别名。
可能的解决方案.
现在,我刚刚禁用了这个特性(它是使用宏实现的),这样所有符号都是全局的,并且具有默认的可见性。我现在唯一能想到的实现这个目标的方法是拥有所有具有私有可见性的_foo函数,并拥有相应的具有默认可见性的foo函数,并调用它们的“隐藏”对应方。
更好的方法?
然而,这需要修改大量的代码。因此,除非真的没有其他办法,否则我宁愿不去那里。
那么,关闭OS替代方案或获得相同语义/行为的最简单方法是什么?
发布于 2014-06-13 23:13:57
在OS上,库中的调用是自动直接调用的,不会通过dyld存根。这一事实的证据是,如果您想要注入替代函数来服务调用,则需要使用可插入性强制对符号的间接访问并通过dyld存根强制执行调用。否则,默认情况下,本地调用将是直接的,并且不会引起运行dyld的开销。
因此,您在Linux上的优化已经是默认行为,并且不需要别名。
不过,如果您想这样做只是为了使您的平台兼容代码更简单,您仍然可以做别名。您只需要使用"weak_import“或”弱“(如果您想合并)作为属性名。
外型 (_NAME)名为__attribute(weak_import,别名(“_NAME”));
苹果弱链接参考:弱链接标记符号
苹果在Mach-O运行时绑定上的引用:符号定义的范围与处理
https://stackoverflow.com/questions/18260207
复制相似问题