It's possible to have local symbols in the dynamic symbol table,
and sh_info should count these, the same as it already does
for SHT_SYMTAB.
Also be sure to exclude these from the GNU hash table.
.dynstr doesn't need to be present if there are no dynamic strings.
- handle section index 0 in read::elf::SectionTable::strings
- don't require .dynstr when writing if there are no strings
- don't print name of symbol index 0 in readobj example
This allows successful parsing of dyld caches on
macOS 13 and above on Intel Macs.
The main dyld cache file on macOS contains an array of
subcache info structs, each of which specifies the UUID
(and some other information) of each subcache.
`DyldCache::parse` checks that the subcache UUIDs match
these expected UUIDs.
In macOS 13, the format of the subcache info struct
changed: it gained an additional field after the UUID
field. This means that as soon as you had more than
one subcache, our UUID check would fail, because the
second subcache UUID would be read from the wrong offset.
I didn't notice this on my Apple Silicon Mac, because
the arm64e dyld cache only has one subcache:
`dyld_shared_cache_arm64e.01`.
But on Intel Macs, there are currently four subcaches:
`dyld_shared_cache_x86_64.01`, `.02`, `.03`, and `.04`.
In practice this means that my software hasn't been able to
symbolicate macOS system libraries on Intel Macs since
the release of macOS 13.
This commit adds the new struct definition and makes
the UUID check work correctly.
This is a breaking change to the public API. I added
a `DyldSubCacheSlice` enum, but I'm not particularly
fond of it.
dyldcachedump was working correctly on macOS 13+ because it was trying
the "leading zero" suffix format as well as the "no leading zero" suffix
format. This commit changes it to read the suffix from the main cache
header.
objdump was not able to parse dyld shared cache files on macOS 13+ because
it was only using the "no leading zero" suffix format, and thus not finding
the subcaches.
The Builder can be created from an existing ELF file, modified,
and then written out again.
Also add the `object-rewrite` crate which provides higher
level operations for modification. Use this to replace
the elfcopy example.
This was removed in eb58357f for consistency (nowhere else in
the read API allows mutation), but there are existing users
so add it back in for convenience.
The exception is reusing common definitions that are reexported
in the read module (preexisting) and write module (newly added).
This is for consistency, and makes it easier to experiment with a
restructure.