Merge remote-tracking branch 'origin/GP-4380_ryanmkurtz_dyld-slide5'

This commit is contained in:
Ryan Kurtz
2024-04-03 06:56:40 -04:00
4 changed files with 276 additions and 217 deletions

View File

@@ -112,7 +112,7 @@ public class DyldCacheSlideInfo3 extends DyldCacheSlideInfoCommon {
}
/**
* Walks the pointer chain at the given reader offset to find necessary {@link DyldFixup}s
* Walks the pointer chain at the given reader offset to find necessary {@link DyldFixup}s
*
* @param segmentOffset The segment offset
* @param pageOffset The page offset

View File

@@ -0,0 +1,166 @@
/* ###
* IP: GHIDRA
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package ghidra.app.util.bin.format.macho.dyld;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import ghidra.app.util.bin.BinaryReader;
import ghidra.app.util.bin.format.macho.MachConstants;
import ghidra.app.util.bin.format.macho.dyld.DyldChainedPtr.DyldChainType;
import ghidra.app.util.importer.MessageLog;
import ghidra.program.model.data.*;
import ghidra.util.exception.CancelledException;
import ghidra.util.exception.DuplicateNameException;
import ghidra.util.task.TaskMonitor;
/**
* Represents a dyld_cache_slide_info5 structure.
* <p>
* Seen in macOS 14.4 and later.
*/
public class DyldCacheSlideInfo5 extends DyldCacheSlideInfoCommon {
private static final int DYLD_CACHE_SLIDE_V5_PAGE_ATTR_NO_REBASE = 0xFFFF;
private static final DyldChainType TYPE = DyldChainType.DYLD_CHAINED_PTR_ARM64E_SHARED_CACHE;
private int pageSize;
private int pageStartsCount;
private long valueAdd;
private short[] pageStarts;
/**
* {@return The page size}
*/
public int getPageSize() {
return pageSize;
}
/**
* {@return The page starts count}
*/
public int getPageStartsCount() {
return pageStartsCount;
}
/**
* {@return The "value add"}
*/
public long getValueAdd() {
return valueAdd;
}
/**
* {@return The page starts array}
*/
public short[] getPageStarts() {
return pageStarts;
}
/**
* Create a new {@link DyldCacheSlideInfo5}.
*
* @param reader A {@link BinaryReader} positioned at the start of a DYLD slide info 5
* @param mappingAddress The base address of where the slide fixups will take place
* @param mappingSize The size of the slide fixups block
* @param mappingFileOffset The base file offset of where the slide fixups will take place
* @throws IOException if there was an IO-related problem creating the DYLD slide info 5
*/
public DyldCacheSlideInfo5(BinaryReader reader, long mappingAddress, long mappingSize,
long mappingFileOffset) throws IOException {
super(reader, mappingAddress, mappingSize, mappingFileOffset);
pageSize = reader.readNextInt();
pageStartsCount = reader.readNextInt();
reader.readNextInt(); // padding
valueAdd = reader.readNextLong();
pageStarts = reader.readNextShortArray(pageStartsCount);
}
@Override
public List<DyldFixup> getSlideFixups(BinaryReader reader, int pointerSize, MessageLog log,
TaskMonitor monitor) throws IOException, CancelledException {
List<DyldFixup> fixups = new ArrayList<>();
monitor.initialize(pageStartsCount, "Getting DYLD Cache V5 slide fixups...");
for (int index = 0; index < pageStartsCount; index++) {
monitor.increment();
long segmentOffset = pageSize * index;
int pageEntry = Short.toUnsignedInt(pageStarts[index]);
if (pageEntry == DYLD_CACHE_SLIDE_V5_PAGE_ATTR_NO_REBASE) {
continue;
}
long pageOffset = (pageEntry / 8) * 8; // first entry byte based;
fixups.addAll(processPointerChain(segmentOffset, pageOffset, reader, monitor));
}
return fixups;
}
/**
* Walks the pointer chain at the given reader offset to find necessary {@link DyldFixup}s
*
* @param segmentOffset The segment offset
* @param pageOffset The page offset
* @param reader A reader positioned at the start of the segment to fix
* @param monitor A cancellable monitor
* @return A {@link List} of {@link DyldFixup}s
* @throws IOException If an IO-related error occurred
* @throws CancelledException If the user cancelled the operation
*/
private List<DyldFixup> processPointerChain(long segmentOffset, long pageOffset,
BinaryReader reader, TaskMonitor monitor) throws IOException, CancelledException {
List<DyldFixup> fixups = new ArrayList<>(1024);
int size = DyldChainedPtr.getSize(TYPE);
long stride = DyldChainedPtr.getStride(TYPE);
for (long delta = -1; delta != 0; pageOffset += delta * stride) {
monitor.checkCancelled();
long dataOffset = segmentOffset + pageOffset;
long chainValue = DyldChainedPtr.getChainValue(reader, dataOffset, TYPE);
long newPtrValue = DyldChainedPtr.getTarget(TYPE, chainValue) + valueAdd;
delta = DyldChainedPtr.getNext(TYPE, chainValue);
if (!DyldChainedPtr.isAuthenticated(TYPE, chainValue)) {
long high8 = (chainValue >>> 34) & 0xff;
newPtrValue |= high8 << 56;
}
fixups.add(new DyldFixup(dataOffset, newPtrValue, size, null, null));
}
return fixups;
}
@Override
public DataType toDataType() throws DuplicateNameException, IOException {
StructureDataType struct = new StructureDataType("dyld_cache_slide_info5", 0);
struct.add(DWORD, "version", "currently 5");
struct.add(DWORD, "page_size", "currently 4096 (may also be 16384)");
struct.add(DWORD, "page_starts_count", "");
struct.add(DWORD, "pad", "");
struct.add(QWORD, "value_add", "");
struct.add(new ArrayDataType(WORD, pageStartsCount, 1), "page_starts", "");
struct.setCategoryPath(new CategoryPath(MachConstants.DATA_TYPE_CATEGORY));
return struct;
}
}

View File

@@ -81,6 +81,8 @@ public abstract class DyldCacheSlideInfoCommon implements StructConverter {
mappingFileOffset);
case 4 -> new DyldCacheSlideInfo4(reader, mappingAddress, mappingSize,
mappingFileOffset);
case 5 -> new DyldCacheSlideInfo5(reader, mappingAddress, mappingSize,
mappingFileOffset);
default -> throw new IOException(); // will be caught and version will be added to message
};
monitor.incrementProgress(1);

View File

@@ -18,11 +18,6 @@ package ghidra.app.util.bin.format.macho.dyld;
import java.io.IOException;
import ghidra.app.util.bin.BinaryReader;
import ghidra.program.model.address.Address;
import ghidra.program.model.mem.Memory;
import ghidra.program.model.mem.MemoryAccessException;
import ghidra.program.model.reloc.Relocation.Status;
import ghidra.program.model.reloc.RelocationResult;
/**
* @see <a href="https://github.com/apple-oss-distributions/dyld/blob/main/include/mach-o/fixup-chains.h">mach-o/fixup-chains.h</a>
@@ -42,6 +37,7 @@ public class DyldChainedPtr {
DYLD_CHAINED_PTR_ARM64E_FIRMWARE(10), // stride 4, unauth target is vmaddr
DYLD_CHAINED_PTR_X86_64_KERNEL_CACHE(11), // stride 1, x86_64 kernel caches
DYLD_CHAINED_PTR_ARM64E_USERLAND24(12), // stride 8, unauth target is vm offset, 24-bit bind
DYLD_CHAINED_PTR_ARM64E_SHARED_CACHE(13), // stride 8, regular/auth targets both vm offsets. Only A keys supported
DYLD_CHAINED_PTR_TYPE_UNKNOWN(-1);
private final int val;
@@ -53,33 +49,22 @@ public class DyldChainedPtr {
}
public static DyldChainType lookupChainPtr(int val) {
switch (val) {
case 1:
return DYLD_CHAINED_PTR_ARM64E;
case 2:
return DYLD_CHAINED_PTR_64;
case 3:
return DYLD_CHAINED_PTR_32;
case 4:
return DYLD_CHAINED_PTR_32_CACHE;
case 5:
return DYLD_CHAINED_PTR_32_FIRMWARE;
case 6:
return DYLD_CHAINED_PTR_64_OFFSET;
case 7:
return DYLD_CHAINED_PTR_ARM64E_KERNEL;
case 8:
return DYLD_CHAINED_PTR_64_KERNEL_CACHE;
case 9:
return DYLD_CHAINED_PTR_ARM64E_USERLAND;
case 10:
return DYLD_CHAINED_PTR_ARM64E_FIRMWARE;
case 11:
return DYLD_CHAINED_PTR_X86_64_KERNEL_CACHE;
case 12:
return DYLD_CHAINED_PTR_ARM64E_USERLAND24;
}
return DYLD_CHAINED_PTR_TYPE_UNKNOWN;
return switch (val) {
case 1 -> DYLD_CHAINED_PTR_ARM64E;
case 2 -> DYLD_CHAINED_PTR_64;
case 3 -> DYLD_CHAINED_PTR_32;
case 4 -> DYLD_CHAINED_PTR_32_CACHE;
case 5 -> DYLD_CHAINED_PTR_32_FIRMWARE;
case 6 -> DYLD_CHAINED_PTR_64_OFFSET;
case 7 -> DYLD_CHAINED_PTR_ARM64E_KERNEL;
case 8 -> DYLD_CHAINED_PTR_64_KERNEL_CACHE;
case 9 -> DYLD_CHAINED_PTR_ARM64E_USERLAND;
case 10 -> DYLD_CHAINED_PTR_ARM64E_FIRMWARE;
case 11 -> DYLD_CHAINED_PTR_X86_64_KERNEL_CACHE;
case 12 -> DYLD_CHAINED_PTR_ARM64E_USERLAND24;
case 13 -> DYLD_CHAINED_PTR_ARM64E_SHARED_CACHE;
default -> DYLD_CHAINED_PTR_TYPE_UNKNOWN;
};
}
public int getValue() {
@@ -96,84 +81,55 @@ public class DyldChainedPtr {
public static final int DYLD_CHAINED_PTR_START_LAST = 0x8000;
public static long getStride(DyldChainType ptrFormat) {
switch (ptrFormat) {
case DYLD_CHAINED_PTR_ARM64E:
case DYLD_CHAINED_PTR_ARM64E_USERLAND:
case DYLD_CHAINED_PTR_ARM64E_USERLAND24:
return 8;
case DYLD_CHAINED_PTR_64:
case DYLD_CHAINED_PTR_64_OFFSET:
case DYLD_CHAINED_PTR_ARM64E_KERNEL:
case DYLD_CHAINED_PTR_64_KERNEL_CACHE:
case DYLD_CHAINED_PTR_ARM64E_FIRMWARE:
case DYLD_CHAINED_PTR_32:
case DYLD_CHAINED_PTR_32_CACHE:
case DYLD_CHAINED_PTR_32_FIRMWARE:
return 4;
case DYLD_CHAINED_PTR_X86_64_KERNEL_CACHE:
return 1;
default:
return 1;
}
}
public static int getSize(DyldChainType ptrFormat) {
return switch (ptrFormat) {
case DYLD_CHAINED_PTR_ARM64E:
case DYLD_CHAINED_PTR_ARM64E_USERLAND:
case DYLD_CHAINED_PTR_ARM64E_USERLAND24:
case DYLD_CHAINED_PTR_64:
case DYLD_CHAINED_PTR_64_OFFSET:
case DYLD_CHAINED_PTR_ARM64E_KERNEL:
case DYLD_CHAINED_PTR_64_KERNEL_CACHE:
case DYLD_CHAINED_PTR_ARM64E_FIRMWARE:
case DYLD_CHAINED_PTR_X86_64_KERNEL_CACHE:
yield 8;
case DYLD_CHAINED_PTR_32:
case DYLD_CHAINED_PTR_32_CACHE:
case DYLD_CHAINED_PTR_32_FIRMWARE:
yield 4;
case DYLD_CHAINED_PTR_ARM64E:
case DYLD_CHAINED_PTR_ARM64E_USERLAND:
case DYLD_CHAINED_PTR_ARM64E_USERLAND24:
case DYLD_CHAINED_PTR_ARM64E_SHARED_CACHE:
yield 8;
case DYLD_CHAINED_PTR_X86_64_KERNEL_CACHE:
default:
yield 1;
};
}
public static int getSize(DyldChainType ptrFormat) {
return switch (ptrFormat) {
case DYLD_CHAINED_PTR_32:
case DYLD_CHAINED_PTR_32_CACHE:
case DYLD_CHAINED_PTR_32_FIRMWARE:
yield 4;
case DYLD_CHAINED_PTR_ARM64E:
case DYLD_CHAINED_PTR_ARM64E_USERLAND:
case DYLD_CHAINED_PTR_ARM64E_USERLAND24:
case DYLD_CHAINED_PTR_64:
case DYLD_CHAINED_PTR_64_OFFSET:
case DYLD_CHAINED_PTR_ARM64E_KERNEL:
case DYLD_CHAINED_PTR_64_KERNEL_CACHE:
case DYLD_CHAINED_PTR_ARM64E_FIRMWARE:
case DYLD_CHAINED_PTR_X86_64_KERNEL_CACHE:
case DYLD_CHAINED_PTR_ARM64E_SHARED_CACHE:
default:
yield 8;
};
}
public static RelocationResult setChainValue(Memory memory, Address chainLoc,
DyldChainType ptrFormat,
long value) throws MemoryAccessException {
int byteLength;
switch (ptrFormat) {
case DYLD_CHAINED_PTR_ARM64E:
case DYLD_CHAINED_PTR_ARM64E_USERLAND:
case DYLD_CHAINED_PTR_ARM64E_USERLAND24:
case DYLD_CHAINED_PTR_64:
case DYLD_CHAINED_PTR_64_OFFSET:
case DYLD_CHAINED_PTR_ARM64E_KERNEL:
case DYLD_CHAINED_PTR_64_KERNEL_CACHE:
case DYLD_CHAINED_PTR_ARM64E_FIRMWARE:
case DYLD_CHAINED_PTR_X86_64_KERNEL_CACHE:
memory.setLong(chainLoc, value);
byteLength = 8;
break;
case DYLD_CHAINED_PTR_32:
case DYLD_CHAINED_PTR_32_CACHE:
case DYLD_CHAINED_PTR_32_FIRMWARE:
memory.setInt(chainLoc, (int) (value & 0xFFFFFFFFL));
byteLength = 4;
break;
default:
return RelocationResult.UNSUPPORTED;
}
return new RelocationResult(Status.APPLIED_OTHER, byteLength);
}
public static long getChainValue(BinaryReader reader, long chainLoc, DyldChainType ptrFormat)
throws IOException {
switch (ptrFormat) {
return switch (ptrFormat) {
case DYLD_CHAINED_PTR_32:
case DYLD_CHAINED_PTR_32_CACHE:
case DYLD_CHAINED_PTR_32_FIRMWARE:
yield reader.readUnsignedInt(chainLoc);
case DYLD_CHAINED_PTR_ARM64E:
case DYLD_CHAINED_PTR_ARM64E_USERLAND:
case DYLD_CHAINED_PTR_ARM64E_USERLAND24:
@@ -183,104 +139,61 @@ public class DyldChainedPtr {
case DYLD_CHAINED_PTR_64_KERNEL_CACHE:
case DYLD_CHAINED_PTR_ARM64E_FIRMWARE:
case DYLD_CHAINED_PTR_X86_64_KERNEL_CACHE:
return reader.readLong(chainLoc);
case DYLD_CHAINED_PTR_32:
case DYLD_CHAINED_PTR_32_CACHE:
case DYLD_CHAINED_PTR_32_FIRMWARE:
return reader.readUnsignedInt(chainLoc);
case DYLD_CHAINED_PTR_ARM64E_SHARED_CACHE:
yield reader.readLong(chainLoc);
default:
return 0;
}
yield 0;
};
}
public static boolean isRelative(DyldChainType ptrFormat) {
switch (ptrFormat) {
return switch (ptrFormat) {
case DYLD_CHAINED_PTR_64_OFFSET:
case DYLD_CHAINED_PTR_ARM64E_KERNEL:
case DYLD_CHAINED_PTR_ARM64E_USERLAND:
case DYLD_CHAINED_PTR_ARM64E_USERLAND24:
case DYLD_CHAINED_PTR_64_KERNEL_CACHE:
case DYLD_CHAINED_PTR_X86_64_KERNEL_CACHE:
return true;
case DYLD_CHAINED_PTR_ARM64E_SHARED_CACHE:
yield true;
default:
return false;
}
yield false;
};
}
public static boolean isBound(DyldChainType ptrFormat, long chainValue) {
switch (ptrFormat) {
return switch (ptrFormat) {
case DYLD_CHAINED_PTR_ARM64E:
case DYLD_CHAINED_PTR_ARM64E_KERNEL:
case DYLD_CHAINED_PTR_ARM64E_USERLAND:
case DYLD_CHAINED_PTR_ARM64E_USERLAND24:
return ((chainValue >>> 62) & 1) != 0;
yield ((chainValue >>> 62) & 1) != 0;
case DYLD_CHAINED_PTR_64:
case DYLD_CHAINED_PTR_64_OFFSET:
return ((chainValue >>> 63) & 1) != 0;
yield ((chainValue >>> 63) & 1) != 0;
case DYLD_CHAINED_PTR_32:
return ((chainValue >>> 31) & 1) != 0;
// Never bound
case DYLD_CHAINED_PTR_ARM64E_FIRMWARE:
case DYLD_CHAINED_PTR_X86_64_KERNEL_CACHE:
case DYLD_CHAINED_PTR_64_KERNEL_CACHE:
case DYLD_CHAINED_PTR_32_CACHE:
case DYLD_CHAINED_PTR_32_FIRMWARE:
yield ((chainValue >>> 31) & 1) != 0;
default:
return false;
}
yield false;
};
}
public static boolean isAuthenticated(DyldChainType ptrFormat, long chainValue) {
switch (ptrFormat) {
return switch (ptrFormat) {
case DYLD_CHAINED_PTR_64:
case DYLD_CHAINED_PTR_64_OFFSET:
case DYLD_CHAINED_PTR_32:
case DYLD_CHAINED_PTR_32_CACHE:
case DYLD_CHAINED_PTR_32_FIRMWARE:
return false;
yield false;
default:
break;
}
boolean isAuthenticated = ((chainValue >>> 63) & 1) != 0;
return isAuthenticated;
}
public static long getDiversity(DyldChainType ptrFormat, long chainValue) {
if (!isAuthenticated(ptrFormat, chainValue)) {
return 0;
}
long diversityData = (chainValue >>> 32) & 0xFFFF;
return diversityData;
}
public static boolean hasAddrDiversity(DyldChainType ptrFormat, long chainValue) {
if (!isAuthenticated(ptrFormat, chainValue)) {
return false;
}
return ((chainValue >>> 48) & 1) == 1;
}
public static long getKey(DyldChainType ptrFormat, long chainValue) {
if (!isAuthenticated(ptrFormat, chainValue)) {
return 0;
}
return (chainValue >>> 49L) & 0x3;
yield ((chainValue >>> 63) & 1) != 0;
};
}
public static long getTarget(DyldChainType ptrFormat, long chainValue) {
long target = 0;
if (isBound(ptrFormat, chainValue)) {
return -1;
}
@@ -295,12 +208,14 @@ public class DyldChainedPtr {
case DYLD_CHAINED_PTR_X86_64_KERNEL_CACHE:
case DYLD_CHAINED_PTR_64_KERNEL_CACHE:
return (chainValue & 0x3FFFFFFFL); // 30 bits
case DYLD_CHAINED_PTR_ARM64E_SHARED_CACHE:
return (chainValue & 0x3FFFFFFFFL); // 34 bits
default:
break;
}
}
switch (ptrFormat) {
return switch (ptrFormat) {
case DYLD_CHAINED_PTR_ARM64E:
case DYLD_CHAINED_PTR_ARM64E_USERLAND:
case DYLD_CHAINED_PTR_ARM64E_USERLAND24:
@@ -311,8 +226,7 @@ public class DyldChainedPtr {
if (top8Bits == 0x80) {
top8Bits = 0;
}
target = (top8Bits << 56) | bottom43Bits;
break;
yield (top8Bits << 56) | bottom43Bits;
case DYLD_CHAINED_PTR_64:
case DYLD_CHAINED_PTR_64_OFFSET:
@@ -322,30 +236,27 @@ public class DyldChainedPtr {
if (top8Bits == 0x80) {
top8Bits = 0;
}
target = (top8Bits << 56) | bottom36Bits;
break;
yield (top8Bits << 56) | bottom36Bits;
case DYLD_CHAINED_PTR_32:
target = (chainValue & 0x3FFFFF); // 26 bits
break;
yield (chainValue & 0x3FFFFF); // 26 bits
case DYLD_CHAINED_PTR_32_CACHE:
target = (chainValue & 0x3FFFFFFF); // 30 bits
break;
yield (chainValue & 0x3FFFFFFF); // 30 bits
case DYLD_CHAINED_PTR_32_FIRMWARE:
target = (chainValue & 0x3FFFFF); // 26 bits
break;
yield (chainValue & 0x3FFFFF); // 26 bits
case DYLD_CHAINED_PTR_X86_64_KERNEL_CACHE:
case DYLD_CHAINED_PTR_64_KERNEL_CACHE:
target = (chainValue & 0x3FFFFFFF); // 30 bits
break;
default:
return 0;
}
yield (chainValue & 0x3FFFFFFF); // 30 bits
return target;
case DYLD_CHAINED_PTR_ARM64E_SHARED_CACHE:
yield (chainValue & 0x3FFFFFFFFL); // 34 bits
default:
yield 0;
};
}
public static long getAddend(DyldChainType ptrFormat, long chainValue) {
@@ -354,103 +265,83 @@ public class DyldChainedPtr {
return 0;
}
switch (ptrFormat) {
return switch (ptrFormat) {
case DYLD_CHAINED_PTR_ARM64E:
case DYLD_CHAINED_PTR_ARM64E_USERLAND:
case DYLD_CHAINED_PTR_ARM64E_USERLAND24:
long addend = (chainValue >>> 32) & 0x7FFFF;
addend = ((addend & 0x40000) != 0 ? (addend | 0xFFFFFFFFFFFC0000L) : addend);
return addend;
yield addend;
case DYLD_CHAINED_PTR_64:
case DYLD_CHAINED_PTR_64_OFFSET:
return (chainValue >>> 24) & 0xFF;
yield (chainValue >>> 24) & 0xFF;
case DYLD_CHAINED_PTR_32:
return (chainValue >>> 20) & 0x3F; // 6 bits
yield (chainValue >>> 20) & 0x3F; // 6 bits
default:
return 0;
}
yield 0;
};
}
public static long getOrdinal(DyldChainType ptrFormat, long chainValue) {
long ordinal = -1;
if (!isBound(ptrFormat, chainValue)) {
return -1;
}
switch (ptrFormat) {
return switch (ptrFormat) {
case DYLD_CHAINED_PTR_ARM64E:
case DYLD_CHAINED_PTR_ARM64E_KERNEL:
case DYLD_CHAINED_PTR_ARM64E_USERLAND:
ordinal = chainValue & 0xFFFF;
break;
yield chainValue & 0xFFFF;
case DYLD_CHAINED_PTR_ARM64E_USERLAND24:
case DYLD_CHAINED_PTR_64:
case DYLD_CHAINED_PTR_64_OFFSET:
ordinal = chainValue & 0xFFFFFF;
break;
yield chainValue & 0xFFFFFF;
case DYLD_CHAINED_PTR_32:
ordinal = chainValue & 0xFFFFF;
break;
yield chainValue & 0xFFFFF;
// Never Ordinal
case DYLD_CHAINED_PTR_ARM64E_FIRMWARE:
case DYLD_CHAINED_PTR_X86_64_KERNEL_CACHE:
case DYLD_CHAINED_PTR_64_KERNEL_CACHE:
case DYLD_CHAINED_PTR_32_CACHE:
case DYLD_CHAINED_PTR_32_FIRMWARE:
break;
default:
break;
}
return ordinal;
yield -1;
};
}
public static long getNext(DyldChainType ptrFormat, long chainValue) {
long next = 1;
switch (ptrFormat) {
return switch (ptrFormat) {
case DYLD_CHAINED_PTR_ARM64E:
case DYLD_CHAINED_PTR_ARM64E_USERLAND:
case DYLD_CHAINED_PTR_ARM64E_USERLAND24:
case DYLD_CHAINED_PTR_ARM64E_KERNEL:
next = (chainValue >>> 51) & 0x7FF; // 11-bits
break;
yield (chainValue >>> 51) & 0x7FF; // 11-bits
case DYLD_CHAINED_PTR_64:
case DYLD_CHAINED_PTR_64_OFFSET:
case DYLD_CHAINED_PTR_X86_64_KERNEL_CACHE:
case DYLD_CHAINED_PTR_64_KERNEL_CACHE:
next = (chainValue >>> 51) & 0xFFF; // 12 bits
break;
yield (chainValue >>> 51) & 0xFFF; // 12 bits
case DYLD_CHAINED_PTR_32:
next = (chainValue >>> 26) & 0x1F; // 5 bits
break;
yield (chainValue >>> 26) & 0x1F; // 5 bits
// Never bound
case DYLD_CHAINED_PTR_ARM64E_FIRMWARE:
next = 0;
break;
yield 0;
case DYLD_CHAINED_PTR_32_CACHE:
next = (chainValue >>> 30) & 0x3; // 2 bits
break;
yield (chainValue >>> 30) & 0x3; // 2 bits
case DYLD_CHAINED_PTR_32_FIRMWARE:
next = (chainValue >>> 26) & 0x3F; // 6 bits
break;
yield (chainValue >>> 26) & 0x3F; // 6 bits
case DYLD_CHAINED_PTR_ARM64E_SHARED_CACHE:
yield (chainValue >>> 52) & 0x7FF; // 11 bits
default:
break;
}
return next;
yield 1;
};
}
}