@@ -14,17 +14,17 @@ use std::time::{SystemTime, UNIX_EPOCH}; |
| 14 | 14 | |
| 15 | 15 | use afs_ld::leb::{read_sleb, read_uleb}; |
| 16 | 16 | use afs_ld::macho::constants::{ |
| 17 | | - BIND_IMMEDIATE_MASK, BIND_OPCODE_ADD_ADDR_ULEB, BIND_OPCODE_DO_BIND, |
| 17 | + BIND_IMMEDIATE_MASK, BIND_OPCODE_ADD_ADDR_ULEB, BIND_OPCODE_DONE, BIND_OPCODE_DO_BIND, |
| 18 | 18 | BIND_OPCODE_DO_BIND_ADD_ADDR_IMM_SCALED, BIND_OPCODE_DO_BIND_ADD_ADDR_ULEB, |
| 19 | | - BIND_OPCODE_DO_BIND_ULEB_TIMES_SKIPPING_ULEB, BIND_OPCODE_DONE, BIND_OPCODE_MASK, |
| 20 | | - BIND_OPCODE_SET_ADDEND_SLEB, BIND_OPCODE_SET_DYLIB_ORDINAL_IMM, |
| 21 | | - BIND_OPCODE_SET_DYLIB_ORDINAL_ULEB, BIND_OPCODE_SET_DYLIB_SPECIAL_IMM, |
| 22 | | - BIND_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB, BIND_OPCODE_SET_SYMBOL_TRAILING_FLAGS_IMM, |
| 23 | | - BIND_OPCODE_SET_TYPE_IMM, BIND_SYMBOL_FLAGS_WEAK_IMPORT, BIND_TYPE_POINTER, |
| 24 | | - INDIRECT_SYMBOL_ABS, INDIRECT_SYMBOL_LOCAL, LC_BUILD_VERSION, LC_CODE_SIGNATURE, |
| 25 | | - LC_DATA_IN_CODE, LC_DYLD_CHAINED_FIXUPS, LC_DYLD_EXPORTS_TRIE, LC_DYLD_INFO_ONLY, LC_DYSYMTAB, |
| 26 | | - LC_FUNCTION_STARTS, LC_ID_DYLIB, LC_LOAD_DYLIB, LC_LOAD_UPWARD_DYLIB, LC_LOAD_WEAK_DYLIB, |
| 27 | | - LC_REEXPORT_DYLIB, LC_SEGMENT_64, LC_SYMTAB, LC_UUID, N_TYPE, N_UNDF, |
| 19 | + BIND_OPCODE_DO_BIND_ULEB_TIMES_SKIPPING_ULEB, BIND_OPCODE_MASK, BIND_OPCODE_SET_ADDEND_SLEB, |
| 20 | + BIND_OPCODE_SET_DYLIB_ORDINAL_IMM, BIND_OPCODE_SET_DYLIB_ORDINAL_ULEB, |
| 21 | + BIND_OPCODE_SET_DYLIB_SPECIAL_IMM, BIND_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB, |
| 22 | + BIND_OPCODE_SET_SYMBOL_TRAILING_FLAGS_IMM, BIND_OPCODE_SET_TYPE_IMM, |
| 23 | + BIND_SYMBOL_FLAGS_WEAK_IMPORT, BIND_TYPE_POINTER, INDIRECT_SYMBOL_ABS, INDIRECT_SYMBOL_LOCAL, |
| 24 | + LC_BUILD_VERSION, LC_CODE_SIGNATURE, LC_DATA_IN_CODE, LC_DYLD_CHAINED_FIXUPS, |
| 25 | + LC_DYLD_EXPORTS_TRIE, LC_DYLD_INFO_ONLY, LC_DYSYMTAB, LC_FUNCTION_STARTS, LC_ID_DYLIB, |
| 26 | + LC_LOAD_DYLIB, LC_LOAD_UPWARD_DYLIB, LC_LOAD_WEAK_DYLIB, LC_REEXPORT_DYLIB, LC_SEGMENT_64, |
| 27 | + LC_SYMTAB, LC_UUID, N_TYPE, N_UNDF, |
| 28 | 28 | }; |
| 29 | 29 | use afs_ld::macho::dylib::DylibFile; |
| 30 | 30 | use afs_ld::macho::exports::ExportKind; |
@@ -1788,9 +1788,21 @@ fn symbol_partition_names(bytes: &[u8]) -> Result<(Vec<String>, Vec<String>, Vec |
| 1788 | 1788 | } |
| 1789 | 1789 | |
| 1790 | 1790 | fn has_optional_dyld_stub_binder(bytes: &[u8]) -> Result<bool, String> { |
| 1791 | | - Ok(canonical_symbol_records(bytes)? |
| 1792 | | - .into_iter() |
| 1793 | | - .any(|record| record.name == "dyld_stub_binder")) |
| 1791 | + let (symtab, _) = symtab_and_dysymtab(bytes)?; |
| 1792 | + let symbols = |
| 1793 | + parse_nlist_table(bytes, symtab.symoff, symtab.nsyms).map_err(|e| e.to_string())?; |
| 1794 | + let strings = |
| 1795 | + StringTable::from_file(bytes, symtab.stroff, symtab.strsize).map_err(|e| e.to_string())?; |
| 1796 | + Ok(symbols.iter().any(|symbol| { |
| 1797 | + strings |
| 1798 | + .get(symbol.strx()) |
| 1799 | + .map(|name| { |
| 1800 | + name == "dyld_stub_binder" |
| 1801 | + && (symbol.raw.n_type & N_TYPE) == N_UNDF |
| 1802 | + && symbol.raw.n_sect == 0 |
| 1803 | + }) |
| 1804 | + .unwrap_or(false) |
| 1805 | + })) |
| 1794 | 1806 | } |
| 1795 | 1807 | |
| 1796 | 1808 | fn raw_string_table(bytes: &[u8]) -> Result<Vec<u8>, String> { |
@@ -2277,7 +2289,10 @@ fn canonical_bind_location( |
| 2277 | 2289 | ) -> Result<CanonicalBindLocation, String> { |
| 2278 | 2290 | let segments = segment_regions(bytes)?; |
| 2279 | 2291 | let sections = section_regions(bytes)?; |
| 2280 | | - let Some(segment) = segments.iter().find(|segment| segment.index == segment_index) else { |
| 2292 | + let Some(segment) = segments |
| 2293 | + .iter() |
| 2294 | + .find(|segment| segment.index == segment_index) |
| 2295 | + else { |
| 2281 | 2296 | return Ok(CanonicalBindLocation::Segment { |
| 2282 | 2297 | segment_index, |
| 2283 | 2298 | segment_offset, |
@@ -2471,7 +2486,9 @@ fn decode_stub_target(bytes: &[u8], stub_addr: u64) -> Result<u64, String> { |
| 2471 | 2486 | return Err(format!("stub at 0x{stub_addr:x} does not start with ADRP")); |
| 2472 | 2487 | } |
| 2473 | 2488 | if (ldr & 0xffc0_0000) != 0xf940_0000 { |
| 2474 | | - return Err(format!("stub at 0x{stub_addr:x} does not use LDR (unsigned)")); |
| 2489 | + return Err(format!( |
| 2490 | + "stub at 0x{stub_addr:x} does not use LDR (unsigned)" |
| 2491 | + )); |
| 2475 | 2492 | } |
| 2476 | 2493 | if (br & 0xffff_fc1f) != 0xd61f_0000 { |
| 2477 | 2494 | return Err(format!("stub at 0x{stub_addr:x} does not end with BR")); |