summaryrefslogtreecommitdiff
path: root/view/sharedcache/core/SharedCache.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'view/sharedcache/core/SharedCache.cpp')
-rw-r--r--view/sharedcache/core/SharedCache.cpp44
1 files changed, 44 insertions, 0 deletions
diff --git a/view/sharedcache/core/SharedCache.cpp b/view/sharedcache/core/SharedCache.cpp
index 0f61da63..b9150c31 100644
--- a/view/sharedcache/core/SharedCache.cpp
+++ b/view/sharedcache/core/SharedCache.cpp
@@ -75,6 +75,8 @@ struct SharedCache::State
std::vector<MemoryRegion> dyldDataRegions;
std::vector<MemoryRegion> nonImageRegions;
+ std::optional<std::pair<size_t, size_t>> objcOptimizationDataRange;
+
std::string baseFilePath;
SharedCacheFormat cacheFormat;
DSCViewState viewState = DSCViewStateUnloaded;
@@ -311,6 +313,10 @@ void SharedCache::PerformInitialLoad()
MutableState().cacheFormat = iOS16CacheFormat;
}
+ if (primaryCacheHeader.objcOptsOffset && primaryCacheHeader.objcOptsSize) {
+ MutableState().objcOptimizationDataRange = {primaryCacheHeader.objcOptsOffset, primaryCacheHeader.objcOptsSize};
+ }
+
switch (State().cacheFormat)
{
case RegularCacheFormat:
@@ -3673,4 +3679,42 @@ const std::unordered_map<uint64_t, SharedCacheMachOHeader>& SharedCache::AllImag
{
return State().headers;
}
+size_t SharedCache::GetBaseAddress() const {
+ if (State().backingCaches.empty()) {
+ return 0;
+ }
+
+ const BackingCache& primaryCache = State().backingCaches[0];
+ if (!primaryCache.isPrimary) {
+ abort();
+ return 0;
+ }
+
+ if (primaryCache.mappings.empty()) {
+ return 0;
+ }
+
+ return primaryCache.mappings[0].address;
+}
+
+// Intentionally takes a copy to avoid modifying the cursor position in the original reader.
+std::optional<ObjCOptimizationHeader> SharedCache::GetObjCOptimizationHeader(VMReader reader) const {
+ if (!State().objcOptimizationDataRange) {
+ return {};
+ }
+
+ ObjCOptimizationHeader header{};
+ // Ignoring `objcOptsSize` in favor of `sizeof(ObjCOptimizationHeader)` matches dyld's behavior.
+ reader.Read(&header, GetBaseAddress() + State().objcOptimizationDataRange->first, sizeof(ObjCOptimizationHeader));
+
+ return header;
+}
+
+size_t SharedCache::GetObjCRelativeMethodBaseAddress(const VMReader& reader) const {
+ if (auto header = GetObjCOptimizationHeader(reader); header.has_value()) {
+ return GetBaseAddress() + header->relativeMethodSelectorBaseAddressOffset;
+ }
+ return 0;
+}
+
} // namespace SharedCacheCore