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:
- Define
_foo()
and_bar()
functions that have private visibility. - Define
foo()
andbar()
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?
ld
man page section about the-interposable_list
argument. It states that calls to symbols within a module will be direct calls unless that symbol is marked as being interposable, in which case it would be made via a dyld stub. – Indevout