This script shows the contents of the AOT shared cache file (/System/Library/dyld/aot_shared_cache).
AOT shared cache is a combined AOT cache file to improve the performance of x64 emulation process initialization.
Its mechanism is similar to the dyld_shared_cache; when a new process is launched, Rosetta 2 runtime tries to look for AOT files of the required libraries from AOT shared cache. If found, the references to those contents are added to the Rosetta 2 runtime, and the loading process of AOT files is skipped.
AOT shared cache file is also undocumented like the dyld_shared_cache. Therefore, I reverse-engineered the structure of AOT shared cache, and write a simple python script to show the contents of AOT shared cache.
Before use this script, you need to install poetry to resolve its dependencies. After that, you can install its dependencies as follows.
$ poetry shell
$ poetry update
Then, you can run this script and show the contents of the AOT shared cache file (/System/Library/dyld/aot_shared_cache).
# Dump contents of an AOT shared cache
$ python main.py dump /path/to/aot_shared_cache
AotCacheHeader:
magic: 0x6568636143746f41
field_0x8: 0x901e87ff163d262d
field_0x10: 0xd530e2b9dd65e280
uuid: ['0xac30dd6830a6b1e2', '0xda54b118c06a36a0']
version: ['0xeeb5da8f5d78c616', '0xed2c96c23df23524', '0x51d12aea4260e7a2', '0xbf5873bbc58776']
offset_to_codesig: 0x9a3fc000
size_of_codesig: 0x134800b
n_entries: 0x784
offset_to_metadata_seg: 0x4000
mapping:
AotCacheMappingInfo:
address: 0x0
size: 0x106e0000
file_offset: 0x0
init_prot: 0x1
max_prot: 0x1
AotCacheMappingInfo:
address: 0x106e0000
size: 0xa58000
file_offset: 0x0
init_prot: 0x3
max_prot: 0x3
AotCacheMappingInfo:
address: 0x11138000
size: 0x89d1c000
file_offset: 0x106e0000
init_prot: 0x85
max_prot: 0x85
metadata segment starts from 0x4000
number of entries is 1924
CodeFragmentMetaData:
type: 0x1
offset_to_path_name: 0x0
offset_to_x64_code: 0x0
size_of_x64_code: 0x0
offset_to_arm64_code: 0x0
...
# Extract a code signature of an AOT shared cache
$ python extract-codesig /path/to/aot_shared_cache codesig
Will extract a code signature located at [0x9a3fc000, 0x9b74400b]
The extracted code signature is saved to code_sig
$ file code_sig
code_sig: Mac OS X Detached Code Signature (non-executable) - 20217867 bytes
Notes about aot_mapped_module_names file
aot_mapped_module_names contains the list of module names in the AOT shared cache file for macOS Bug Sur version 11.1.
The reason for providing this file is that aot_shared_cache does not include a list of module name information.
The information in the module name may depend on the version of macOS.
If you want to create aot_mapped_module_names for your environment, you can get the list of module names by enabling the Rosetta 2 runtime debugging feature (ROSETTA_PRINT_SEGMENTS). For more details, see here.