For iOS simulators, dyld_sim is used as the dynamic linker. How small can the list of dependencies be to run a “hello world” in such an environment?
When a binary that uses the simulator is loaded, dyld uses DYLD_ROOT_PATH to be able to locate usr/lib/dyld_sim, which is a build of dyld compiled for the iOS-sim platform target.
We can note that file system namespaces are not used within the iOS Simulator, which shares the same file system view as the host instead of using a chroot.
What happens if we do not specify the DYLD_ROOT_PATH variable for the dynamic linker to use the right search folder as a reference? Turns out, we get an error early.
% cat hello.c
#include <stdio.h>
int main(int argc, char** argv) {
puts("hello");
}
% xcrun --sdk iphonesimulator clang hello.c -arch arm64 -o hellosim
% ./hellosim
dyld[2512]: DYLD_ROOT_PATH not set for simulator program
zsh: abort ./hellosim
Let’s add the path and see what happens:
% DYLD_ROOT_PATH=/Users/test/devlab/fakeroot ./hellosim
hello
And the minimal set of libraries that it took to get there:
% find *
usr
usr/lib
usr/lib/libSystem.B.dylib
usr/lib/system
usr/lib/system/libsystem_trace.dylib
usr/lib/system/libsystem_c.dylib
usr/lib/system/libcommonCrypto.dylib
usr/lib/system/libsystem_containermanager.dylib
usr/lib/system/libsystem_sim_platform_host.dylib
usr/lib/system/libxpc.dylib
usr/lib/system/libsystem_notify.dylib
usr/lib/system/libsystem_configuration.dylib
usr/lib/system/libsystem_malloc.dylib
usr/lib/system/libcorecrypto.dylib
usr/lib/system/libsystem_networkextension.dylib
usr/lib/system/libsystem_featureflags.dylib
usr/lib/system/libsystem_sim_platform.dylib
usr/lib/system/libsystem_sim_kernel.dylib
usr/lib/system/libsystem_coreservices.dylib
usr/lib/system/libcopyfile.dylib
usr/lib/system/libunwind.dylib
usr/lib/system/libdyld.dylib
usr/lib/system/libremovefile.dylib
usr/lib/system/libsystem_collections.dylib
usr/lib/system/libsystem_product_info_filter.dylib
usr/lib/system/libsystem_sim_kernel_host.dylib
usr/lib/system/libsystem_darwin.dylib
usr/lib/system/libsystem_sim_pthread_host.dylib
usr/lib/system/libsystem_sim_pthread.dylib
usr/lib/system/libcache.dylib
usr/lib/system/libmacho.dylib
usr/lib/system/libdispatch.dylib
usr/lib/system/libsystem_info.dylib
usr/lib/system/libsystem_sandbox.dylib
usr/lib/system/libsystem_blocks.dylib
usr/lib/system/libsystem_dnssd.dylib
usr/lib/system/libcompiler_rt.dylib
usr/lib/system/libsystem_m.dylib
usr/lib/system/libsystem_asl.dylib
usr/lib/dyld_sim
usr/lib/libobjc.A.dylib
usr/lib/libc++.1.dylib
usr/lib/libc++abi.dylib
… that’s 40 Mach-Os, one of which is dyld_sim itself.
We can note the huge number of dynamic libraries used even for a “Hello world” sample program. Use of a high number of dynamic libraries is a characteristic of modern Apple operating systems.
And unlike when trying to target the iOS platform, we can run outside of the sandbox in Full Security on that environment (which is however not very representative of a device).