What is the minimum number of libraries to run a “hello world” on iOS Simulator?

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).

Leave a comment

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