-
Notifications
You must be signed in to change notification settings - Fork 3
Fixes for RelativeListList separated into different cache files #14
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
Changes from all commits
8ab926d
b35ce42
cfd2cfd
d0ca25f
5bacc66
f978528
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -28,89 +28,136 @@ extension DyldCache { | |
| } | ||
| } | ||
|
|
||
| // MARK: - locate value | ||
| extension DyldCache { | ||
| var headerOptimizationRO64: ObjCHeaderOptimizationRO64? { | ||
| guard cpu.is64Bit else { | ||
| return nil | ||
| } | ||
| if let objcOptimization { | ||
| return objcOptimization.headerOptimizationRO64(in: self) | ||
| } | ||
| if let oldObjcOptimization { | ||
| return oldObjcOptimization.headerOptimizationRO64(in: self) | ||
| } | ||
| return nil | ||
| /// A tuple containing the DyldCache where the value was found and the resolved value itself. | ||
| /// Useful because values may be located either in the current cache, the main cache, | ||
| /// or one of its subcaches. | ||
| typealias LocatedValue<V> = (cache: DyldCache, value: V) | ||
|
|
||
| /// Locate a value for a given optional KeyPath within this cache hierarchy. | ||
| /// | ||
| /// This resolves the value by checking: | ||
| /// 1. This cache | ||
| /// 2. The main cache | ||
| /// 3. Any subcaches derived from `mainCache` | ||
| /// | ||
| /// - Parameter keyPath: A keyPath returning an optional value. | ||
| /// - Returns: A tuple of `(cache, value)` if resolved, or `nil` if not found. | ||
| func locateValue<V>( | ||
| _ keyPath: KeyPath<DyldCache, V?> | ||
| ) -> LocatedValue<V>? { | ||
| locateValue({ $0[keyPath: keyPath] }) | ||
| } | ||
|
|
||
| var headerOptimizationRO32: ObjCHeaderOptimizationRO32? { | ||
| guard cpu.is64Bit else { | ||
| /// Locate a value using a custom resolver function running against each cache in the hierarchy. | ||
| /// | ||
| /// Resolution order: | ||
| /// 1. This cache | ||
| /// 2. The main cache | ||
| /// 3. Each subcache of the main cache | ||
| /// | ||
| /// - Parameter resolver: A closure returning an optional value for a given DyldCache. | ||
| /// - Returns: A tuple of `(cache, value)` if resolution is successful; otherwise `nil`. | ||
| func locateValue<V>( | ||
| _ resolver: (DyldCache) -> V? | ||
| ) -> LocatedValue<V>? { | ||
| if let value = resolver(self) { return (self, value) } | ||
|
|
||
| guard let mainCache else { return nil } | ||
| if let value = resolver(mainCache) { return (mainCache, value) } | ||
|
|
||
| guard let subCaches = mainCache.subCaches else { | ||
| return nil | ||
| } | ||
| if let objcOptimization { | ||
| return objcOptimization.headerOptimizationRO32(in: self) | ||
| } | ||
| if let oldObjcOptimization { | ||
| return oldObjcOptimization.headerOptimizationRO32(in: self) | ||
| for subCache in subCaches { | ||
| guard let cache = try? subCache.subcache(for: mainCache) else { | ||
| continue | ||
| } | ||
| if let value = resolver(cache) { | ||
| return (cache, value) | ||
| } | ||
| } | ||
| return nil | ||
| } | ||
| } | ||
|
|
||
| var headerOptimizationRW64: ObjCHeaderOptimizationRW64? { | ||
| guard cpu.is64Bit else { | ||
| return nil | ||
| } | ||
| if let objcOptimization { | ||
| return objcOptimization.headerOptimizationRW64(in: self) | ||
| // MARK: - Objective-C | ||
| extension DyldCache { | ||
| var _objcOptimization: LocatedValue<ObjCOptimization>? { | ||
| locateValue(\.objcOptimization) | ||
| } | ||
|
|
||
| var _oldObjcOptimization: LocatedValue<OldObjCOptimization>? { | ||
| locateValue(\.oldObjcOptimization) | ||
| } | ||
| } | ||
|
|
||
| extension DyldCache { | ||
| var headerOptimizationRO64: ObjCHeaderOptimizationRO64? { | ||
| guard cpu.is64Bit else { return nil } | ||
| if let _objcOptimization { | ||
| return _objcOptimization.value.headerOptimizationRO64(in: self) | ||
| } | ||
| if let oldObjcOptimization { | ||
| return oldObjcOptimization.headerOptimizationRW64(in: self) | ||
| if let _oldObjcOptimization { | ||
| return _oldObjcOptimization.value.headerOptimizationRO64(in: self) | ||
| } | ||
| return nil | ||
| } | ||
|
|
||
| var headerOptimizationRW32: ObjCHeaderOptimizationRW32? { | ||
| guard cpu.is64Bit else { | ||
| return nil | ||
| } | ||
| if let objcOptimization { | ||
| return objcOptimization.headerOptimizationRW32(in: self) | ||
| var headerOptimizationRO32: ObjCHeaderOptimizationRO32? { | ||
| guard !cpu.is64Bit else { return nil } | ||
| if let _objcOptimization { | ||
| return _objcOptimization.value.headerOptimizationRO32(in: self) | ||
| } | ||
| if let oldObjcOptimization { | ||
| return oldObjcOptimization.headerOptimizationRW32(in: self) | ||
| if let _oldObjcOptimization { | ||
| return _oldObjcOptimization.value.headerOptimizationRO32(in: self) | ||
| } | ||
| return nil | ||
| } | ||
| } | ||
|
|
||
| extension DyldCache { | ||
| func machO(at index: Int) -> MachOFile? { | ||
| guard let mainCache else { return nil } | ||
| if let ro = mainCache.headerOptimizationRO64, | ||
| var _headerOptimizationRO64: LocatedValue<ObjCHeaderOptimizationRO64>? { | ||
| locateValue(\.headerOptimizationRO64) | ||
| } | ||
|
|
||
| var _headerOptimizationRO32: LocatedValue<ObjCHeaderOptimizationRO32>? { | ||
| locateValue(\.headerOptimizationRO32) | ||
| } | ||
| } | ||
|
|
||
| extension DyldCache { | ||
| func _machO(at index: Int) -> LocatedValue<MachOFile>? { | ||
| if let ro = _headerOptimizationRO64?.value, | ||
| ro.contains(index: index) { | ||
| guard let header = ro.headerInfos(in: mainCache)?.first( | ||
| let headers = locateValue({ ro.headerInfos(in: $0) })?.value | ||
| guard let header = headers?.first( | ||
| where: { | ||
| $0.index == index | ||
| } | ||
| ) else { | ||
| return nil | ||
| } | ||
| return header._machO(mainCache: mainCache) | ||
| return locateValue { header.machO(in: $0) } | ||
|
||
| } | ||
| if let ro = mainCache.headerOptimizationRO32, | ||
| if let ro = _headerOptimizationRO32?.value, | ||
| ro.contains(index: index) { | ||
| guard let header = ro.headerInfos(in: mainCache)?.first( | ||
| let headers = locateValue({ ro.headerInfos(in: $0) })?.value | ||
| guard let header = headers?.first( | ||
| where: { | ||
| $0.index == index | ||
| } | ||
| ) else { | ||
| return nil | ||
| } | ||
| return header._machO(mainCache: mainCache) | ||
| return locateValue { header.machO(in: $0) } | ||
| } | ||
| return nil | ||
| } | ||
| } | ||
|
|
||
| // MARK: - mach-o | ||
| extension DyldCache { | ||
| func machO(containing unslidAddress: UInt64) -> MachOFile? { | ||
| for machO in self.machOFiles() { | ||
|
|
||
| Original file line number | Diff line number | Diff line change | ||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -69,25 +69,16 @@ extension RelativeListListProtocol { | |||||||||||
|
|
||||||||||||
| extension RelativeListListProtocol { | ||||||||||||
| public func entries(in machO: MachOFile) -> [Entry] { | ||||||||||||
|
||||||||||||
| public func entries(in machO: MachOFile) -> [Entry] { | |
| public func entries(in machO: MachOFile) -> [Entry] { | |
| // NOTE: This code depends on `MachOFile.fileHandleAndOffset(forOffset:)` existing. | |
| // This method is expected to resolve a file handle and file offset for a given virtual offset. | |
| // Ensure that `fileHandleAndOffset(forOffset:)` is implemented and documented on `MachOFile`. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[nitpick] Consider using a guard statement pattern to align with the existing code style in this file. Change
if let value = resolver(self) { return (self, value) }toguard let value = resolver(self) else { ... }for consistency with lines 74-76 and 77-79.