| 86 | } |
| 87 | |
| 88 | void ApplySlideInfoV2(MappedFileAccessor& accessor, const SlideMappingInfo& mapping) |
| 89 | { |
| 90 | auto rebaseChain = [&](const dyld_cache_slide_info_v2& slideInfo, uint64_t pageContent, uint16_t startOffset) { |
| 91 | // TODO: This is always zero? |
| 92 | // TODO: This is probably something for runtime offsets provided to the shared cache. |
| 93 | uintptr_t slideAmount = 0; |
| 94 | |
| 95 | auto deltaMask = slideInfo.delta_mask; |
| 96 | auto valueMask = ~deltaMask; |
| 97 | auto valueAdd = slideInfo.value_add; |
| 98 | |
| 99 | auto deltaShift = CountTrailingZeros(deltaMask) - 2; |
| 100 | |
| 101 | uint32_t pageOffset = startOffset; |
| 102 | uint32_t delta = 1; |
| 103 | while (delta != 0) |
| 104 | { |
| 105 | uint64_t loc = pageContent + pageOffset; |
| 106 | uintptr_t rawValue = accessor.ReadUInt64(loc); |
| 107 | delta = (uint32_t)((rawValue & deltaMask) >> deltaShift); |
| 108 | uintptr_t value = (rawValue & valueMask); |
| 109 | if (value != 0) |
| 110 | { |
| 111 | value += valueAdd; |
| 112 | // TODO: slideAmount += value? |
| 113 | // TODO: slideAmount is always zero? What is this suppose to do? |
| 114 | value += slideAmount; |
| 115 | } |
| 116 | pageOffset += delta; |
| 117 | accessor.WritePointer(loc, value); |
| 118 | } |
| 119 | }; |
| 120 | |
| 121 | uint64_t extrasOffset = mapping.address + mapping.slideInfoV2.page_extras_offset; |
| 122 | uint64_t pageStartsOffset = mapping.address + sizeof(dyld_cache_slide_info_v2); |
| 123 | uint64_t pageStartCount = mapping.slideInfoV2.page_starts_count; |
| 124 | uint64_t pageSize = mapping.slideInfoV2.page_size; |
| 125 | |
| 126 | auto cursor = pageStartsOffset; |
| 127 | for (size_t i = 0; i < pageStartCount; i++) |
| 128 | { |
| 129 | uint16_t start = accessor.ReadUInt16(cursor); |
| 130 | cursor += sizeof(uint16_t); |
| 131 | if (start == DYLD_CACHE_SLIDE_PAGE_ATTR_NO_REBASE) |
| 132 | continue; |
| 133 | |
| 134 | if (start & DYLD_CACHE_SLIDE_PAGE_ATTR_EXTRA) |
| 135 | { |
| 136 | int j = (start & 0x3FFF); |
| 137 | bool done = false; |
| 138 | do |
| 139 | { |
| 140 | uint64_t extraCursor = extrasOffset + (j * sizeof(uint16_t)); |
| 141 | auto extra = accessor.ReadUInt16(extraCursor); |
| 142 | uint16_t aStart = extra; |
| 143 | uint64_t page = mapping.mappingInfo.fileOffset + (pageSize * i); |
| 144 | uint16_t pageStartOffset = (aStart & 0x3FFF) * 4; |
| 145 | rebaseChain(mapping.slideInfoV2, page, pageStartOffset); |
no test coverage detected