Weak symbol aliases on OS X similar to those on Linux, or a closest equivalent?

纵然是瞬间 提交于 2020-01-31 00:54:26

问题


What I do

When writing shared libraries for Linux, I tend to pay attention to relocations, symbol visibility, GOT/PLT etc.

When applicable, I am trying to avoid calling PLT stubs when functions from the same library call each other. For example, let's say a shared object provides two public functions - foo() and bar() (either of those can be called by user). The bar() function, however, also calls foo(). So what I do in this case is this:

  1. Define _foo() and _bar() functions that have private visibility.
  2. Define foo() and bar() weak aliases for _foo() and _bar() respectively.

That way, the code in shared object never uses weak symbols. It only invokes local functions, directly. For example, when _bar() is invoked, it calls _foo() directly.

But users are not aware of _* functions and always use corresponding weak aliases.

How I do it

In Linux, this is achieved by using the following construct:

extern __typeof (_NAME) NAME __attribute__(weak, alias("_NAME"));

The problem

Unfortunately, this does not work for OS X. I have no deep knowledge of OS X or its binary formats, so I poked around a bit and found a few examples of weak functions (like this one), but those don't quite do the same as you can have a weak symbol, but not a weak symbol that is an alias for DSO's local function.

Possible solution...

For now, I have just disabled this feature (that is implemented using macros) so that all symbols are global and have default visibility. The only way I can think of to achieve the same for now is to have all _foo functions with private visibility and have corresponding foo functions with default visibility and calling their "hidden" counterparts.

A better way?

That, however, requires a good chunk of code to be changed. Therefore I would prefer not to go there unless there is really no other way.

So what is the closes OS X alternative or the easiest way to get the same semantics/behavior?


回答1:


On OS X, calls made within the library are automatically direct calls and do not go through the dyld stub. The evidence to the fact is that if you want to be able to inject alternative functions to service a call, you'll need to use interposable to force indirect access to the symbols and force execution of the call through the dyld stubs. Otherwise, by default, local calls will be direct and will not incur the overhead of running through dyld.

Thus, your optimization on Linux is already the default behavior and the alias is not needed.

Still, if you want to do this just to make your platform compatible code simpler, you can still make the aliases. You just need to use "weak_import" or "weak" (if you want coalesced) as your attribute name.

extern typeof (_NAME) NAME __attribute(weak_import, alias("_NAME"));

Apple reference on Weak Linking: Marking Symbols for Weak Linking
Apple reference on Mach-O runtime binding : Scope and Treatment of Symbol Definitions



来源:https://stackoverflow.com/questions/18260207/weak-symbol-aliases-on-os-x-similar-to-those-on-linux-or-a-closest-equivalent

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!