Big Sur and built-in dynamic linker cache

By | April 16, 2021

On Big Sur Apple made significant changes in OS X file system. System-provided libraries are moved from filesystem to dynamic linker cache. Probably it is done because Big Sur OS X supports 2 different CPUs: Inter and Apple Silicon processors and currently dynamic linker cache contains 2 versions for the both processors: Apple Silicon ARM and Intel. How it works in practice, the some running process does not link to shared library object but instead takes its binary image from dynamic linker cache. For example on my Big Sur machine /usr/sbin/netbiosd process is running:


# ps -ef | grep netbios
222 232  1  0 22Feb21 ??   0:38.51 /usr/sbin/netbiosd

otool command shows the list of shared libraries used by this process:


# otool -L /usr/sbin/netbiosd
/usr/sbin/netbiosd:
   /System/Library/Frameworks/SystemConfiguration.framework/Versions/A/SystemConfiguration (compatibility version 1.0.0, current version 1109.40.9)
   /System/Library/Frameworks/IOKit.framework/Versions/A/IOKit (compatibility version 1.0.0, current version 275.0.0)
   /System/Library/Frameworks/CoreFoundation.framework/Versions/A/CoreFoundation (compatibility version 150.0.0, current version 1770.106.0)
   /System/Library/PrivateFrameworks/SMBClient.framework/Versions/A/SMBClient (compatibility version 1.0.0, current version 1.0.0)
   /System/Library/Frameworks/CoreServices.framework/Versions/A/CoreServices (compatibility version 1.0.0, current version 1122.5.1)
  &nbsp/System/Library/PrivateFrameworks/NetFSServer.framework/Versions/A/NetFSServer (compatibility version 1.0.0, current version 1.0.0)
   /usr/lib/libc++.1.dylib (compatibility version 1.0.0, current version 904.4.0)
   /usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1292.50.1)

Let us do ls command for the last item in the library list:


# ls /usr/lib/libSystem.B.dylib
ls: /usr/lib/libSystem.B.dylib: No such file or directory

It shows that file /usr/lib/libSystem.B.dylib does not exist. If you repeat the same for previous version of Mac OS X the file will be found.
It is possible to find reference to /usr/lib/libSystem.B.dylib in dyld_shared_cache_arm64e.map and dyld_shared_cache_x86_64.map text files located in dynamic linker cache directory – /System/Library/dyld:


/usr/lib/libSystem.B.dylib
      __TEXT 0x7FFF2A64C000 -> 0x7FFF2A64E000
      __DATA 0x7FFF89277020 -> 0x7FFF89277378
     __LINKEDIT 0x7FFFC05C8000 -> 0x7FFFDE94E345

This innovation creates for me real head ache when I linking c++ code to some system libraries, for example libssl.dylib and libcrypto.dylib. Definitely it is possible to extract the system libraries from dynamic linker cache as presented there or use dlyd function something like this:


#include <stdio.h>
#include <openssl/ssl.h>
#include <dlfcn.h>
int main(int n, char ** s)
{
// Example how to call SSL_library_init();
   void (*func_SSL_library_init)();
   void *handle = dlopen("/usr/lib/libssl.35.dylib", RTLD_NOW);
   if (!handle)
   {
      // fail to load the library from dynamic linker cache
      fprintf(stderr, “Error: %s\n”, dlerror());
      return EXIT_FAILURE;
   }
   *(void**)(&func_SSL_library_init) = dlsym(handle, “SSL_library_init”);
   if (!func_SSL_library_init)
   {
      // cannot find "SSL_library_init" function
      fprintf(stderr, "Error: %s\n", dlerror());
      dlclose(handle);
      return EXIT_FAILURE;
   }
   func_SSL_library_init();
   dlclose(handle);
   return EXIT_SUCCESS;
}

However the both solutions looks ugly for me and I am still looking for better way to link to libraries located in dynamic linker cache.

Leave a Reply

Your email address will not be published. Required fields are marked *