Here's the info you requested
Thanks.
I have found this PDF to be very useful to understand what lazy,
two-level namespace or flat namespace are.
Yeah, and that means you’ve probably figured out where I’m heading here (-:
Apple platforms default to using a two-level namespace. That is, when a Mach-O image imports a symbol from a dynamic library, it records both the symbol name and the identity of the library. This has a world of benefits, the most important one being the ability to have two symbols of the same name in your process. If one part of your product uses library A with symbol X and another part of your product uses library B that just happens to use X for one of its symbols, things still work.
The flat namespace is effectively deprecated and we encourage folks not to use it.
It seems like libgcrypt.dylib
was built with a flat namespace. One consequence of the flat namespace design is that calls between elements within the library go through the flat namespace. This is necessary because folks using the flat namespace expect to be able to define, say, malloc
, and have it be used by all code in the process [1].
So, here’s what’s happening here:
-
You’ve loaded the libgcrypt.dylib
with RTLD_LAZY
and RTLD_LOCAL
. The first tells the dynamic linker to not immediately bind all the library’s symbols. The second tells it not to publish any of its symbols globally.
-
You try to reference a symbol in the library. As part of this the dynamic linker tries to resolve __gcry_check_version
. This is a flat namespace import, so it tries to find it in the global flat namespace. And that fails because you explicitly told the dynamic linker not to publish any of the libraries symbols globally.
Unless libgcrypt.dylib
has a hard dependency on the flat namespace — which is rare but does happen sometimes when dealing with Unix-y code — the best solution here is to rebuild it the default two-level namespace.
Share and Enjoy
—
Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"
[1] The two-level namespace has a different solution for adding debugging infrastructure to your product, namely dynamic linker interposing. It’s not something we officially support, but you’ll find plenty of info about it online.