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

CLinuxMacosLinkerDynamic Linking

C Problem Overview


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?

C Solutions


Solution 1 - C

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

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
Questionuser405725View Question on Stackoverflow
Solution 1 - CRob_vHView Answer on Stackoverflow