Loading...
shared_cache_runtime/SharedCacheRuntime.swift /dev/null dyld-1335
--- /dev/null
+++ dyld/dyld-1335/shared_cache_runtime/SharedCacheRuntime.swift
@@ -0,0 +1,118 @@
+/*
+ * Copyright (c) 2024 Apple Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ *
+ * This file contains Original Code and/or Modifications of Original Code
+ * as defined in and that are subject to the Apple Public Source License
+ * Version 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ and read it before using this
+ * file.
+ *
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ *
+ * @APPLE_LICENSE_HEADER_END@
+ */
+
+// implementationOnly so we don't leak the c types into the public interface
+@_implementationOnly import dyld_cache_module
+//@_implementationOnly import MachO_Private.dyld_cache_format
+
+enum SharedCacheRuntimeError: Error {
+    /// ran out of buffer while parsing
+    case outOfBuffer(limit: Int, required: Int)
+}
+
+// Swift API to be used exclusively by the ExclaveKit loader
+public struct MappingInfo {
+    public let address     : UInt64
+    public let size        : UInt64
+    public let fileOffset  : UInt64
+    public let slideOffset : UInt64
+    public let slideSize   : UInt64
+    public let flags       : UInt64
+    public let maxProt     : UInt32
+    public let initProt    : UInt32
+}
+
+public struct CodeSignatureInfo {
+    public let offset : UInt64
+    public let size   : UInt64
+}
+
+private func loadFromRawBuffer<T>(cacheBuffer: UnsafeRawBufferPointer, offset: Int, end: Int) throws -> T {
+    guard cacheBuffer.count > end else {
+        throw SharedCacheRuntimeError.outOfBuffer(
+            limit: cacheBuffer.count,
+            required: end
+        )
+    }
+    return cacheBuffer.load(fromByteOffset: offset,
+                                  as: T.self)
+}
+public func hasValidMagic(cacheBuffer: UnsafeRawBufferPointer) throws -> Bool {
+    let headerSize = MemoryLayout<dyld_cache_header>.stride
+    let header : dyld_cache_header = try loadFromRawBuffer(cacheBuffer: cacheBuffer,
+                                                       offset: 0,
+                                                       end: headerSize)
+    let isValidMagic = withUnsafeBytes(of: header.magic) {
+        buffer in
+        let magicString = String(decoding: [UInt8](buffer), as: UTF8.self)
+        return magicString == "dyld_v1  arm64e\0"
+    }
+    return isValidMagic
+}
+
+public func getPlatform(cacheBuffer: UnsafeRawBufferPointer) throws -> UInt32 {
+    let headerSize = MemoryLayout<dyld_cache_header>.stride
+    let header : dyld_cache_header = try loadFromRawBuffer(cacheBuffer: cacheBuffer,
+                                                       offset: 0,
+                                                       end: headerSize)
+    return header.platform
+ }
+
+public func getUUID(cacheBuffer: UnsafeRawBufferPointer) throws -> [UInt8] {
+    let headerSize = MemoryLayout<dyld_cache_header>.stride
+    let header : dyld_cache_header = try loadFromRawBuffer(cacheBuffer: cacheBuffer,
+                                                       offset: 0,
+                                                       end: headerSize)
+    return withUnsafeBytes(of: header.uuid) { buf in
+            [UInt8](buf)
+    }
+ }
+
+
+public func getMappingsInfo(cacheBuffer: UnsafeRawBufferPointer) throws -> [MappingInfo] {
+    let headerSize = MemoryLayout<dyld_cache_header>.stride
+    let header : dyld_cache_header = try loadFromRawBuffer(cacheBuffer: cacheBuffer,
+                                                       offset: 0,
+                                                       end: headerSize)
+
+    let mappings = try (0..<Int(header.mappingWithSlideCount)).map { index in
+        let structSize = MemoryLayout<dyld_cache_mapping_and_slide_info>.stride
+        let offset = Int(header.mappingWithSlideOffset) + index * structSize
+        let mappingEnd = offset + structSize
+        let m : dyld_cache_mapping_and_slide_info = try loadFromRawBuffer(cacheBuffer: cacheBuffer,
+                                                                          offset: offset,
+                                                                          end: mappingEnd)
+        return MappingInfo(address: m.address, size: m.size, fileOffset: m.fileOffset,
+                           slideOffset: m.slideInfoFileOffset, slideSize: m.slideInfoFileSize,
+                           flags: m.flags, maxProt: m.maxProt, initProt: m.initProt)
+    }
+    return mappings
+}
+
+public func getCodeSignatureInfo(cacheBuffer: UnsafeRawBufferPointer)throws -> CodeSignatureInfo {
+    let headerSize = MemoryLayout<dyld_cache_header>.stride
+    let header : dyld_cache_header = try loadFromRawBuffer(cacheBuffer: cacheBuffer,
+                                                       offset: 0,
+                                                       end: headerSize)
+    return CodeSignatureInfo(offset: header.codeSignatureOffset, size: header.codeSignatureSize)
+}