summaryrefslogtreecommitdiff
path: root/view/sharedcache/core/MachOProcessor.cpp
diff options
context:
space:
mode:
authorMark Rowe <mark@vector35.com>2025-09-13 16:17:43 -0700
committerMark Rowe <mark@vector35.com>2025-09-17 20:45:26 -0700
commite937b89628f3b3ce039d641fe849796cc295c41a (patch)
tree0cf7e14946c65d1ca818483f18ea4d77a46aa786 /view/sharedcache/core/MachOProcessor.cpp
parent11dc8b216d0852c83ff5c9bfd7d3ca146a93fe84 (diff)
[DSC] Rework handling of .symbols files to be compatible with iOS 15
In some iOS 15 caches, the .symbols file's mapping has an address of 0. This would cause it to be returned by `SharedCache::GetEntryContaining` and loaded into the view. The .symbols file contains the local symbol tables for images in the shared cache. It is not intended to be mapped into the same address space as the rest of the shared cache. `SharedCache` now tracks the symbols cache entry separately from other entries. A dedicated `VirtualMemory` region is used when accessing the data it contains. This could be a `FileAccessor`, but that would require additional changes within `SharedCacheMachOHeader`. `SharedCacheMachOProcessor` now directly accesses the local symbols cache entry rather than needing to search for it.
Diffstat (limited to 'view/sharedcache/core/MachOProcessor.cpp')
-rw-r--r--view/sharedcache/core/MachOProcessor.cpp84
1 files changed, 46 insertions, 38 deletions
diff --git a/view/sharedcache/core/MachOProcessor.cpp b/view/sharedcache/core/MachOProcessor.cpp
index df2fcfde..281f40c2 100644
--- a/view/sharedcache/core/MachOProcessor.cpp
+++ b/view/sharedcache/core/MachOProcessor.cpp
@@ -84,50 +84,58 @@ void SharedCacheMachOProcessor::ApplyHeader(const SharedCache& cache, SharedCach
}
// Apply symbols from the .symbols cache files.
- for (const auto &entry: cache.GetEntries())
- {
- // NOTE: We check addr size as we only support 64bit .symbols files currently.
- if (entry.GetType() != CacheEntryType::Symbols && m_vm->GetAddressSize() == 8)
- continue;
- const auto& entryHeader = entry.GetHeader();
+ ApplyUnmappedLocalSymbols(cache, header, std::move(typeLib));
+}
- // This is where we get the symbol and string table information from in the .symbols file.
- dyld_cache_local_symbols_info localSymbolsInfo = {};
- auto localSymbolsInfoAddr = entry.GetMappedAddress(entryHeader.localSymbolsOffset);
- if (!localSymbolsInfoAddr.has_value())
- continue;
- m_vm->Read(&localSymbolsInfo, *localSymbolsInfoAddr, sizeof(dyld_cache_local_symbols_info));
+void SharedCacheMachOProcessor::ApplyUnmappedLocalSymbols(const SharedCache& cache, const SharedCacheMachOHeader& header, Ref<TypeLibrary> typeLib)
+{
+ const auto& localSymbolsCacheEntry = cache.GetLocalSymbolsEntry();
+ auto localSymbolsVM = cache.GetLocalSymbolsVM();
+ if (!localSymbolsCacheEntry || !localSymbolsVM)
+ return;
+
+ // NOTE: We check addr size as we only support 64bit .symbols files currently.
+ // TODO: Support 32-bit nlist
+ if (localSymbolsVM->GetAddressSize() != 8)
+ return;
+
+ const auto& entryHeader = localSymbolsCacheEntry->GetHeader();
+
+ // This is where we get the symbol and string table information from in the .symbols file.
+ dyld_cache_local_symbols_info localSymbolsInfo = {};
+ auto localSymbolsInfoAddr = entryHeader.localSymbolsOffset;
+
+ localSymbolsVM->Read(&localSymbolsInfo, localSymbolsInfoAddr, sizeof(dyld_cache_local_symbols_info));
- // Read each symbols entry, looking for the current image entry.
- uint64_t localEntriesAddr = *localSymbolsInfoAddr + localSymbolsInfo.entriesOffset;
- uint64_t localSymbolsAddr = *localSymbolsInfoAddr + localSymbolsInfo.nlistOffset;
- uint64_t localStringsAddr = *localSymbolsInfoAddr + localSymbolsInfo.stringsOffset;
+ // Read each symbols entry, looking for the current image entry.
+ uint64_t localEntriesAddr = localSymbolsInfoAddr + localSymbolsInfo.entriesOffset;
+ uint64_t localSymbolsAddr = localSymbolsInfoAddr + localSymbolsInfo.nlistOffset;
+ uint64_t localStringsAddr = localSymbolsInfoAddr + localSymbolsInfo.stringsOffset;
+ for (uint32_t i = 0; i < localSymbolsInfo.entriesCount; i++)
+ {
dyld_cache_local_symbols_entry_64 localSymbolsEntry = {};
- for (uint32_t i = 0; i < localSymbolsInfo.entriesCount; i++)
+ localSymbolsVM->Read(&localSymbolsEntry, localEntriesAddr + i * sizeof(dyld_cache_local_symbols_entry_64),
+ sizeof(dyld_cache_local_symbols_entry_64));
+
+ // The dylibOffset is the offset from the cache base address to the image header.
+ const auto imageAddr = cache.GetBaseAddress() + localSymbolsEntry.dylibOffset;
+ if (imageAddr != header.textBase)
+ continue;
+
+ // We have found the entry to read!
+ uint64_t symbolTableStart = localSymbolsAddr + (localSymbolsEntry.nlistStartIndex * sizeof(nlist_64));
+ TableInfo symbolInfo = {symbolTableStart, localSymbolsEntry.nlistCount};
+ TableInfo stringInfo = {localStringsAddr, localSymbolsInfo.stringsSize};
+ m_view->BeginBulkModifySymbols();
+ const auto symbols = header.ReadSymbolTable(*localSymbolsVM, symbolInfo, stringInfo);
+ for (const auto &sym: symbols)
{
- m_vm->Read(&localSymbolsEntry, localEntriesAddr + i * sizeof(dyld_cache_local_symbols_entry_64),
- sizeof(dyld_cache_local_symbols_entry_64));
- // The dylibOffset is the offset from the cache base address to the image header.
- const auto imageAddr = cache.GetBaseAddress() + localSymbolsEntry.dylibOffset;
- if (imageAddr == header.textBase)
- {
- // We have found the entry to read!
- // TODO: Support 32bit nlist
- uint64_t symbolTableStart = localSymbolsAddr + (localSymbolsEntry.nlistStartIndex * sizeof(nlist_64));
- TableInfo symbolInfo = {symbolTableStart, localSymbolsEntry.nlistCount};
- TableInfo stringInfo = {localStringsAddr, localSymbolsInfo.stringsSize};
- m_view->BeginBulkModifySymbols();
- const auto symbols = header.ReadSymbolTable(*m_vm, symbolInfo, stringInfo);
- for (const auto &sym: symbols)
- {
- auto [symbol, symbolType] = sym.GetBNSymbolAndType(*m_view);
- ApplySymbol(m_view, typeLib, symbol, symbolType);
- }
- m_view->EndBulkModifySymbols();
- break;
- }
+ auto [symbol, symbolType] = sym.GetBNSymbolAndType(*m_view);
+ ApplySymbol(m_view, typeLib, std::move(symbol), std::move(symbolType));
}
+ m_view->EndBulkModifySymbols();
+ return;
}
}