-
Notifications
You must be signed in to change notification settings - Fork 153
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Support macOS 12 dyld shared cache format #358
Comments
It's probably a good idea to wait for macOS 12 to be released and for the new dyld source to become available, before making any changes to object. This issue is just a heads-up. |
The implementation I suggested above doesn't seem to work in all cases. For example, for arm64e libsystem_malloc.dylib, it looks like two chunks are needed in order to get symbol names: The list of symbols is in the first chunk and the string table is in the second chunk. |
The strings are in the chunk which contains the All images in the arm64e dyld shared cache share the same
And the subcache mappings are as follows:
|
Fixes gimli-rs#358. This adds support for the dyld cache format that is used on macOS 12 and iOS 15. The cache is split over multiple files, with a "root" cache and one or more subcaches, for example: ``` /System/Library/dyld/dyld_shared_cache_x86_64 /System/Library/dyld/dyld_shared_cache_x86_64.1 /System/Library/dyld/dyld_shared_cache_x86_64.2 /System/Library/dyld/dyld_shared_cache_x86_64.3 ``` Each file has a set of mappings. For each image in the cache, the segments of that image can be distributed over multiple files: For example, on macOS 12.0.1, the image for libsystem_malloc.dylib for the arm64e architecture has its __TEXT segment in the root cache and the __LINKEDIT segment in the .1 subcache - there's a single __LINKEDIT segment which is shared between all images across both files. The remaining libsystem_malloc.dylib segments are in the same file as the __TEXT segment. This has some unfortunate implications on the API: The DyldSharedCache API now requires the data for all subcaches to be supplied to the constructor, and the File::parse_at API now receives two "data" arguments: One which contains the __LINKEDIT segment and one which contains the other segments. The symtab and str information is read from the data that contains the __LINKEDIT segment. It is possible that there are other things that need to be read from the __LINKEDIT segment. This also adds an assumption that the __LINKEDIT segment is the only segment that could be split out. I don't know if that's an ok assumption to make. It's also an assumption that's not checked at the moment; a check for this could be added. With this patch, the following command outputs correct symbols for libsystem_malloc.dylib: ``` cargo run --release --bin objdump -- /System/Library/dyld/dyld_shared_cache_arm64e /usr/lib/system/libsystem_malloc.dylib ```
I have this working now. |
Fixes gimli-rs#358. This adds support for the dyld cache format that is used on macOS 12 and iOS 15. The cache is split over multiple files, with a "root" cache and one or more subcaches, for example: ``` /System/Library/dyld/dyld_shared_cache_x86_64 /System/Library/dyld/dyld_shared_cache_x86_64.1 /System/Library/dyld/dyld_shared_cache_x86_64.2 /System/Library/dyld/dyld_shared_cache_x86_64.3 ``` Each file has a set of mappings. For each image in the cache, the segments of that image can be distributed over multiple files: For example, on macOS 12.0.1, the image for libsystem_malloc.dylib for the arm64e architecture has its __TEXT segment in the root cache and the __LINKEDIT segment in the .1 subcache - there's a single __LINKEDIT segment which is shared between all images across both files. The remaining libsystem_malloc.dylib segments are in the same file as the __TEXT segment. This has some unfortunate implications on the API: The DyldCache API now requires the data for all subcaches to be supplied to the constructor, and the File::parse_at API now receives two "data" arguments: One which contains the __LINKEDIT segment and one which contains the other segments. The symtab and str information is read from the data that contains the __LINKEDIT segment. It is possible that there are other things that need to be read from the __LINKEDIT segment. This also adds an assumption that the __LINKEDIT segment is the only segment that could be split out. I don't know if that's an ok assumption to make. It's also an assumption that's not checked at the moment; a check for this could be added. With this patch, the following command outputs correct symbols for libsystem_malloc.dylib: ``` cargo run --release --bin objdump -- /System/Library/dyld/dyld_shared_cache_arm64e /usr/lib/system/libsystem_malloc.dylib ```
Fixes gimli-rs#358. This adds support for the dyld cache format that is used on macOS 12 and iOS 15. The cache is split over multiple files, with a "root" cache and one or more subcaches, for example: ``` /System/Library/dyld/dyld_shared_cache_x86_64 /System/Library/dyld/dyld_shared_cache_x86_64.1 /System/Library/dyld/dyld_shared_cache_x86_64.2 /System/Library/dyld/dyld_shared_cache_x86_64.3 ``` Each file has a set of mappings. For each image in the cache, the segments of that image can be distributed over multiple files: For example, on macOS 12.0.1, the image for libsystem_malloc.dylib for the arm64e architecture has its __TEXT segment in the root cache and the __LINKEDIT segment in the .1 subcache - there's a single __LINKEDIT segment which is shared between all images across both files. The remaining libsystem_malloc.dylib segments are in the same file as the __TEXT segment. This has some unfortunate implications on the API: The DyldCache API now requires the data for all subcaches to be supplied to the constructor, and the File::parse_at API now receives two "data" arguments: One which contains the __LINKEDIT segment and one which contains the other segments. The symtab and str information is read from the data that contains the __LINKEDIT segment. It is possible that there are other things that need to be read from the __LINKEDIT segment. This also adds an assumption that the __LINKEDIT segment is the only segment that could be split out. I don't know if that's an ok assumption to make. It's also an assumption that's not checked at the moment; a check for this could be added. With this patch, the following command outputs correct symbols for libsystem_malloc.dylib: ``` cargo run --release --bin objdump -- /System/Library/dyld/dyld_shared_cache_arm64e /usr/lib/system/libsystem_malloc.dylib ```
Fixes gimli-rs#358. This adds support for the dyld cache format that is used on macOS 12 and iOS 15. The cache is split over multiple files, with a "root" cache and one or more subcaches, for example: ``` /System/Library/dyld/dyld_shared_cache_x86_64 /System/Library/dyld/dyld_shared_cache_x86_64.1 /System/Library/dyld/dyld_shared_cache_x86_64.2 /System/Library/dyld/dyld_shared_cache_x86_64.3 ``` Each file has a set of mappings. For each image in the cache, the segments of that image can be distributed over multiple files: For example, on macOS 12.0.1, the image for libsystem_malloc.dylib for the arm64e architecture has its __TEXT segment in the root cache and the __LINKEDIT segment in the .1 subcache - there's a single __LINKEDIT segment which is shared between all images across both files. The remaining libsystem_malloc.dylib segments are in the same file as the __TEXT segment. This has some unfortunate implications on the API: The DyldCache API now requires the data for all subcaches to be supplied to the constructor, and the File::parse_at API now receives two "data" arguments: One which contains the __LINKEDIT segment and one which contains the other segments. The symtab and str information is read from the data that contains the __LINKEDIT segment. It is possible that there are other things that need to be read from the __LINKEDIT segment. This also adds an assumption that the __LINKEDIT segment is the only segment that could be split out. I don't know if that's an ok assumption to make. It's also an assumption that's not checked at the moment; a check for this could be added. With this patch, the following command outputs correct symbols for libsystem_malloc.dylib: ``` cargo run --release --bin objdump -- /System/Library/dyld/dyld_shared_cache_arm64e /usr/lib/system/libsystem_malloc.dylib ```
It works with ipsw, but I know Golang isn't pleasant to read to some people;) |
Thanks for the pointer! This suggests that I should also add support for the .symbols subcache. Symbol subcaches seem to be only used on iOS, not on macOS. For reference, ipsw's dsc header definition is here: https://github.com/blacktop/ipsw/blob/05af7d2bde570035b25e7bfdf316d9f363c0106c/hack/extras/Dyld.bt#L116-L124 (I've found a small issue with that header definition, filed as blacktop/ipsw#49.) |
Yes on the non-macOS caches all the |
Fixes gimli-rs#358. This adds support for the dyld cache format that is used on macOS 12 and iOS 15. The cache is split over multiple files, with a "root" cache and one or more subcaches, for example: ``` /System/Library/dyld/dyld_shared_cache_x86_64 /System/Library/dyld/dyld_shared_cache_x86_64.1 /System/Library/dyld/dyld_shared_cache_x86_64.2 /System/Library/dyld/dyld_shared_cache_x86_64.3 ``` Each file has a set of mappings. For each image in the cache, the segments of that image can be distributed over multiple files: For example, on macOS 12.0.1, the image for libsystem_malloc.dylib for the arm64e architecture has its __TEXT segment in the root cache and the __LINKEDIT segment in the .1 subcache - there's a single __LINKEDIT segment which is shared between all images across both files. The remaining libsystem_malloc.dylib segments are in the same file as the __TEXT segment. The DyldCache API now requires the data for all subcaches to be supplied to the constructor. The parse_at methods have been removed and been replaced with a parse_dyld_cache_image method. With this patch, the following command outputs correct symbols for libsystem_malloc.dylib: ``` cargo run --release --bin objdump -- /System/Library/dyld/dyld_shared_cache_arm64e /usr/lib/system/libsystem_malloc.dylib ```
Fixes gimli-rs#358. This adds support for the dyld cache format that is used on macOS 12 and iOS 15. The cache is split over multiple files, with a "root" cache and one or more subcaches, for example: ``` /System/Library/dyld/dyld_shared_cache_x86_64 /System/Library/dyld/dyld_shared_cache_x86_64.1 /System/Library/dyld/dyld_shared_cache_x86_64.2 /System/Library/dyld/dyld_shared_cache_x86_64.3 ``` Additionally, on iOS, there is a separate .symbols subcache, which contains local symbols. Each file has a set of mappings. For each image in the cache, the segments of that image can be distributed over multiple files: For example, on macOS 12.0.1, the image for libsystem_malloc.dylib for the arm64e architecture has its __TEXT segment in the root cache and the __LINKEDIT segment in the .1 subcache - there's a single __LINKEDIT segment which is shared between all images across both files. The remaining libsystem_malloc.dylib segments are in the same file as the __TEXT segment. The DyldCache API now requires the data for all subcaches to be supplied to the constructor. The parse_at methods have been removed and been replaced with a parse_dyld_cache_image method. With this patch, the following command outputs correct symbols for libsystem_malloc.dylib: ``` cargo run --release --bin objdump -- /System/Library/dyld/dyld_shared_cache_arm64e /usr/lib/system/libsystem_malloc.dylib ``` Support for local symbols is not implemented. But, as a first step, DyldCache::parse requires the .symbols subcache to be supplied (if the root cache expects one to be present) and checks that its UUID is correct. MachOFile doesn't do anything with ilocalsym and nlocalsym yet, and we don't yet have the struct definitions for dyld_cache_local_symbols_info and dyld_cache_local_symbols_entry.
Fixes gimli-rs#358. This adds support for the dyld cache format that is used on macOS 12 and iOS 15. The cache is split over multiple files, with a "root" cache and one or more subcaches, for example: ``` /System/Library/dyld/dyld_shared_cache_x86_64 /System/Library/dyld/dyld_shared_cache_x86_64.1 /System/Library/dyld/dyld_shared_cache_x86_64.2 /System/Library/dyld/dyld_shared_cache_x86_64.3 ``` Additionally, on iOS, there is a separate .symbols subcache, which contains local symbols. Each file has a set of mappings. For each image in the cache, the segments of that image can be distributed over multiple files: For example, on macOS 12.0.1, the image for libsystem_malloc.dylib for the arm64e architecture has its __TEXT segment in the root cache and the __LINKEDIT segment in the .1 subcache - there's a single __LINKEDIT segment which is shared between all images across both files. The remaining libsystem_malloc.dylib segments are in the same file as the __TEXT segment. The DyldCache API now requires the data for all subcaches to be supplied to the constructor. The parse_at methods have been removed and been replaced with a parse_dyld_cache_image method. With this patch, the following command outputs correct symbols for libsystem_malloc.dylib: ``` cargo run --release --bin objdump -- /System/Library/dyld/dyld_shared_cache_arm64e /usr/lib/system/libsystem_malloc.dylib ``` Support for local symbols is not implemented. But, as a first step, DyldCache::parse requires the .symbols subcache to be supplied (if the root cache expects one to be present) and checks that its UUID is correct. MachOFile doesn't do anything with ilocalsym and nlocalsym yet, and we don't yet have the struct definitions for dyld_cache_local_symbols_info and dyld_cache_local_symbols_entry.
Fixes gimli-rs#358. This adds support for the dyld cache format that is used on macOS 12 and iOS 15. The cache is split over multiple files, with a "root" cache and one or more subcaches, for example: ``` /System/Library/dyld/dyld_shared_cache_x86_64 /System/Library/dyld/dyld_shared_cache_x86_64.1 /System/Library/dyld/dyld_shared_cache_x86_64.2 /System/Library/dyld/dyld_shared_cache_x86_64.3 ``` Additionally, on iOS, there is a separate .symbols subcache, which contains local symbols. Each file has a set of mappings. For each image in the cache, the segments of that image can be distributed over multiple files: For example, on macOS 12.0.1, the image for libsystem_malloc.dylib for the arm64e architecture has its __TEXT segment in the root cache and the __LINKEDIT segment in the .1 subcache - there's a single __LINKEDIT segment which is shared between all images across both files. The remaining libsystem_malloc.dylib segments are in the same file as the __TEXT segment. The DyldCache API now requires the data for all subcaches to be supplied to the constructor. The parse_at methods have been removed and been replaced with a parse_dyld_cache_image method. With this patch, the following command outputs correct symbols for libsystem_malloc.dylib: ``` cargo run --release --bin objdump -- /System/Library/dyld/dyld_shared_cache_arm64e /usr/lib/system/libsystem_malloc.dylib ``` Support for local symbols is not implemented. But, as a first step, DyldCache::parse requires the .symbols subcache to be supplied (if the root cache expects one to be present) and checks that its UUID is correct. MachOFile doesn't do anything with ilocalsym and nlocalsym yet, and we don't yet have the struct definitions for dyld_cache_local_symbols_info and dyld_cache_local_symbols_entry.
Fixes gimli-rs#358. This adds support for the dyld cache format that is used on macOS 12 and iOS 15. The cache is split over multiple files, with a "root" cache and one or more subcaches, for example: ``` /System/Library/dyld/dyld_shared_cache_x86_64 /System/Library/dyld/dyld_shared_cache_x86_64.1 /System/Library/dyld/dyld_shared_cache_x86_64.2 /System/Library/dyld/dyld_shared_cache_x86_64.3 ``` Additionally, on iOS, there is a separate .symbols subcache, which contains local symbols. Each file has a set of mappings. For each image in the cache, the segments of that image can be distributed over multiple files: For example, on macOS 12.0.1, the image for libsystem_malloc.dylib for the arm64e architecture has its __TEXT segment in the root cache and the __LINKEDIT segment in the .1 subcache - there's a single __LINKEDIT segment which is shared between all images across both files. The remaining libsystem_malloc.dylib segments are in the same file as the __TEXT segment. The DyldCache API now requires the data for all subcaches to be supplied to the constructor. The parse_at methods have been removed and been replaced with a parse_dyld_cache_image method. With this patch, the following command outputs correct symbols for libsystem_malloc.dylib: ``` cargo run --release --bin objdump -- /System/Library/dyld/dyld_shared_cache_arm64e /usr/lib/system/libsystem_malloc.dylib ``` Support for local symbols is not implemented. But, as a first step, DyldCache::parse requires the .symbols subcache to be supplied (if the root cache expects one to be present) and checks that its UUID is correct. MachOFile doesn't do anything with ilocalsym and nlocalsym yet, and we don't yet have the struct definitions for dyld_cache_local_symbols_info and dyld_cache_local_symbols_entry.
Fixes gimli-rs#358. This adds support for the dyld cache format that is used on macOS 12 and iOS 15. The cache is split over multiple files, with a "root" cache and one or more subcaches, for example: ``` /System/Library/dyld/dyld_shared_cache_x86_64 /System/Library/dyld/dyld_shared_cache_x86_64.1 /System/Library/dyld/dyld_shared_cache_x86_64.2 /System/Library/dyld/dyld_shared_cache_x86_64.3 ``` Additionally, on iOS, there is a separate .symbols subcache, which contains local symbols. Each file has a set of mappings. For each image in the cache, the segments of that image can be distributed over multiple files: For example, on macOS 12.0.1, the image for libsystem_malloc.dylib for the arm64e architecture has its __TEXT segment in the root cache and the __LINKEDIT segment in the .1 subcache - there's a single __LINKEDIT segment which is shared between all images across both files. The remaining libsystem_malloc.dylib segments are in the same file as the __TEXT segment. The DyldCache API now requires the data for all subcaches to be supplied to the constructor. The parse_at methods have been removed and been replaced with a parse_dyld_cache_image method. With this patch, the following command outputs correct symbols for libsystem_malloc.dylib: ``` cargo run --release --bin objdump -- /System/Library/dyld/dyld_shared_cache_arm64e /usr/lib/system/libsystem_malloc.dylib ``` Support for local symbols is not implemented. But, as a first step, DyldCache::parse requires the .symbols subcache to be supplied (if the root cache expects one to be present) and checks that its UUID is correct. MachOFile doesn't do anything with ilocalsym and nlocalsym yet, and we don't yet have the struct definitions for dyld_cache_local_symbols_info and dyld_cache_local_symbols_entry.
Fixes gimli-rs#358. This adds support for the dyld cache format that is used on macOS 12 and iOS 15. The cache is split over multiple files, with a "root" cache and one or more subcaches, for example: ``` /System/Library/dyld/dyld_shared_cache_x86_64 /System/Library/dyld/dyld_shared_cache_x86_64.1 /System/Library/dyld/dyld_shared_cache_x86_64.2 /System/Library/dyld/dyld_shared_cache_x86_64.3 ``` Additionally, on iOS, there is a separate .symbols subcache, which contains local symbols. Each file has a set of mappings. For each image in the cache, the segments of that image can be distributed over multiple files: For example, on macOS 12.0.1, the image for libsystem_malloc.dylib for the arm64e architecture has its __TEXT segment in the root cache and the __LINKEDIT segment in the .1 subcache - there's a single __LINKEDIT segment which is shared between all images across both files. The remaining libsystem_malloc.dylib segments are in the same file as the __TEXT segment. The DyldCache API now requires the data for all subcaches to be supplied to the constructor. The parse_at methods have been removed and been replaced with a parse_dyld_cache_image method. With this patch, the following command outputs correct symbols for libsystem_malloc.dylib: ``` cargo run --release --bin objdump -- /System/Library/dyld/dyld_shared_cache_arm64e /usr/lib/system/libsystem_malloc.dylib ``` Support for local symbols is not implemented. But, as a first step, DyldCache::parse requires the .symbols subcache to be supplied (if the root cache expects one to be present) and checks that its UUID is correct. MachOFile doesn't do anything with ilocalsym and nlocalsym yet, and we don't yet have the struct definitions for dyld_cache_local_symbols_info and dyld_cache_local_symbols_entry.
Fixes #358. This adds support for the dyld cache format that is used on macOS 12 and iOS 15. The cache is split over multiple files, with a "root" cache and one or more subcaches, for example: ``` /System/Library/dyld/dyld_shared_cache_x86_64 /System/Library/dyld/dyld_shared_cache_x86_64.1 /System/Library/dyld/dyld_shared_cache_x86_64.2 /System/Library/dyld/dyld_shared_cache_x86_64.3 ``` Additionally, on iOS, there is a separate .symbols subcache, which contains local symbols. Each file has a set of mappings. For each image in the cache, the segments of that image can be distributed over multiple files: For example, on macOS 12.0.1, the image for libsystem_malloc.dylib for the arm64e architecture has its __TEXT segment in the root cache and the __LINKEDIT segment in the .1 subcache - there's a single __LINKEDIT segment which is shared between all images across both files. The remaining libsystem_malloc.dylib segments are in the same file as the __TEXT segment. The DyldCache API now requires the data for all subcaches to be supplied to the constructor. The parse_at methods have been removed and been replaced with a parse_dyld_cache_image method. With this patch, the following command outputs correct symbols for libsystem_malloc.dylib: ``` cargo run --release --bin objdump -- /System/Library/dyld/dyld_shared_cache_arm64e /usr/lib/system/libsystem_malloc.dylib ``` Support for local symbols is not implemented. But, as a first step, DyldCache::parse requires the .symbols subcache to be supplied (if the root cache expects one to be present) and checks that its UUID is correct. MachOFile doesn't do anything with ilocalsym and nlocalsym yet, and we don't yet have the struct definitions for dyld_cache_local_symbols_info and dyld_cache_local_symbols_entry.
The source for macOS Monterey dyld has been released now. The new fields which I called |
Fixes gimli-rs#358. This adds support for the dyld cache format that is used on macOS 12 and iOS 15. The cache is split over multiple files, with a "root" cache and one or more subcaches, for example: ``` /System/Library/dyld/dyld_shared_cache_x86_64 /System/Library/dyld/dyld_shared_cache_x86_64.1 /System/Library/dyld/dyld_shared_cache_x86_64.2 /System/Library/dyld/dyld_shared_cache_x86_64.3 ``` Additionally, on iOS, there is a separate .symbols subcache, which contains local symbols. Each file has a set of mappings. For each image in the cache, the segments of that image can be distributed over multiple files: For example, on macOS 12.0.1, the image for libsystem_malloc.dylib for the arm64e architecture has its __TEXT segment in the root cache and the __LINKEDIT segment in the .1 subcache - there's a single __LINKEDIT segment which is shared between all images across both files. The remaining libsystem_malloc.dylib segments are in the same file as the __TEXT segment. The DyldCache API now requires the data for all subcaches to be supplied to the constructor. The parse_at methods have been removed and been replaced with a parse_dyld_cache_image method. With this patch, the following command outputs correct symbols for libsystem_malloc.dylib: ``` cargo run --release --bin objdump -- /System/Library/dyld/dyld_shared_cache_arm64e /usr/lib/system/libsystem_malloc.dylib ``` Support for local symbols is not implemented. But, as a first step, DyldCache::parse requires the .symbols subcache to be supplied (if the root cache expects one to be present) and checks that its UUID is correct. MachOFile doesn't do anything with ilocalsym and nlocalsym yet, and we don't yet have the struct definitions for dyld_cache_local_symbols_info and dyld_cache_local_symbols_entry.
On macOS 12 the dyld shared cache format seems to have changed. At least this is the case in the Beta that I have running at the moment.
Instead of one cache file per architecture, the cache is now split up into multiple files, each being a little over 700MB. The filenames are:
(and similarly for the other architectures)
The old list of images (currently parsed by
DyldCache::images
) in each file is now empty.Instead, the header points to a new list of images, let's call them
images_across_all_chunks
. For a given architecture, all cache chunk files have the same full list ofimages_across_all_chunks
, with the same image addresses.For example the x86_64 cache has the following list, in all cache chunk files:
However, the cache files differ in the mappings. It looks like each chunk covers a 4 GiB range of virtual addresses.
The
images_across_all_chunks
list can be accessed from the header like this:The
mapping_offset
in the build I have is 456. This is also the size of the header at the same time. (The list of mappings starts right after the header.)The text was updated successfully, but these errors were encountered: