diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/macho/dyld/DyldCacheSlideInfo3.java b/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/macho/dyld/DyldCacheSlideInfo3.java
index db60d3819f..d20096a458 100644
--- a/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/macho/dyld/DyldCacheSlideInfo3.java
+++ b/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/macho/dyld/DyldCacheSlideInfo3.java
@@ -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
diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/macho/dyld/DyldCacheSlideInfo5.java b/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/macho/dyld/DyldCacheSlideInfo5.java
new file mode 100644
index 0000000000..2bfb271ace
--- /dev/null
+++ b/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/macho/dyld/DyldCacheSlideInfo5.java
@@ -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.
+ *
+ * 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 getSlideFixups(BinaryReader reader, int pointerSize, MessageLog log,
+ TaskMonitor monitor) throws IOException, CancelledException {
+ List 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 processPointerChain(long segmentOffset, long pageOffset,
+ BinaryReader reader, TaskMonitor monitor) throws IOException, CancelledException {
+
+ List 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;
+ }
+}
diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/macho/dyld/DyldCacheSlideInfoCommon.java b/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/macho/dyld/DyldCacheSlideInfoCommon.java
index dac7b89fe1..13c06cd9b6 100644
--- a/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/macho/dyld/DyldCacheSlideInfoCommon.java
+++ b/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/macho/dyld/DyldCacheSlideInfoCommon.java
@@ -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);
diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/macho/dyld/DyldChainedPtr.java b/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/macho/dyld/DyldChainedPtr.java
index c38c93ef77..e91e0f5b60 100644
--- a/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/macho/dyld/DyldChainedPtr.java
+++ b/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/macho/dyld/DyldChainedPtr.java
@@ -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 mach-o/fixup-chains.h
@@ -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;
+ };
}
}