From 4219ed7b35a8d709800f38fbcc1e81da53e62743 Mon Sep 17 00:00:00 2001
From: p-x9 <50244599+p-x9@users.noreply.github.com>
Date: Thu, 30 Jan 2025 18:35:58 +0900
Subject: [PATCH 1/2] Add c header for aot cache

---
 Sources/MachOKitC/include/aot_cache.h | 28 +++++++++++++++++++++++++++
 1 file changed, 28 insertions(+)
 create mode 100644 Sources/MachOKitC/include/aot_cache.h

diff --git a/Sources/MachOKitC/include/aot_cache.h b/Sources/MachOKitC/include/aot_cache.h
new file mode 100644
index 0000000..c9e2a3c
--- /dev/null
+++ b/Sources/MachOKitC/include/aot_cache.h
@@ -0,0 +1,28 @@
+//
+//  aot_cache.h
+//  MachOKit
+//
+//  Created by p-x9 on 2025/01/29
+//  
+//
+
+#ifndef aot_cache_h
+#define aot_cache_h
+
+#include <stdint.h>
+
+// ref: /Applications/Xcode-16.2.0.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/System/Library/Frameworks/Kernel.framework/Versions/A/Headers/kern/debug.h
+#define CAMBRIA_VERSION_INFO_SIZE 32
+struct aot_cache_header {
+    char     magic[8];
+    uint8_t  uuid[16];
+    uint8_t  x86_uuid[16];
+    uint8_t  cambria_version[CAMBRIA_VERSION_INFO_SIZE];
+    uint64_t code_signature_offset;
+    uint64_t code_signature_size;
+    uint32_t num_code_fragments;
+    uint32_t header_size;
+    // shared_file_mapping_np mappings is omitted here
+};
+
+#endif /* aot_cache_h */

From 833b9cc56b8a03ae5042adb55447954a2302bf07 Mon Sep 17 00:00:00 2001
From: p-x9 <50244599+p-x9@users.noreply.github.com>
Date: Fri, 31 Jan 2025 01:41:23 +0900
Subject: [PATCH 2/2] Implemented `AotCache`

---
 Sources/MachOKit/AotCache.swift               | 58 +++++++++++++++++++
 Sources/MachOKit/Extension/String+.swift      | 14 +++++
 .../AotCacheHeader/AotCacheHeader.swift       | 34 +++++++++++
 3 files changed, 106 insertions(+)
 create mode 100644 Sources/MachOKit/AotCache.swift
 create mode 100644 Sources/MachOKit/Header/AotCacheHeader/AotCacheHeader.swift

diff --git a/Sources/MachOKit/AotCache.swift b/Sources/MachOKit/AotCache.swift
new file mode 100644
index 0000000..965a1f5
--- /dev/null
+++ b/Sources/MachOKit/AotCache.swift
@@ -0,0 +1,58 @@
+//
+//  AotCache.swift
+//  MachOKit
+//
+//  Created by p-x9 on 2025/01/29
+//  
+//
+
+import Foundation
+
+public struct AotCache {
+    /// URL of loaded dyld cache file
+    public let url: URL
+    let fileHandle: FileHandle
+
+//    public var headerSize: Int {
+//        header.headerSize
+//    }
+
+    /// Header for dyld cache
+    public let header: AotCacheHeader
+
+    public init(url: URL) throws {
+        self.url = url
+        let fileHandle = try FileHandle(forReadingFrom: url)
+        self.fileHandle = fileHandle
+
+        // read header
+        self.header = fileHandle.read(
+            offset: 0
+        )
+
+        // check magic of header
+        guard header.magic == "AotCache" else {
+            throw MachOKitError.invalidMagic
+        }
+    }
+}
+
+extension AotCache {
+    public var codeSign: MachOFile.CodeSign? {
+        let data = fileHandle.readData(
+            offset: numericCast(header.code_signature_offset),
+            size: numericCast(header.code_signature_size)
+        )
+        return .init(data: data)
+    }
+}
+
+extension AotCache {
+    /// Sequence of mapping infos
+    public var mappingInfos: DataSequence<DyldCacheMappingInfo>? {
+        fileHandle.readDataSequence(
+            offset: numericCast(header.layoutSize),
+            numberOfElements: 3
+        )
+    }
+}
diff --git a/Sources/MachOKit/Extension/String+.swift b/Sources/MachOKit/Extension/String+.swift
index ef500d4..477e854 100644
--- a/Sources/MachOKit/Extension/String+.swift
+++ b/Sources/MachOKit/Extension/String+.swift
@@ -8,6 +8,20 @@
 
 import Foundation
 
+extension String {
+    @_spi(Support)
+    public typealias CCharTuple8 = (CChar, CChar, CChar, CChar, CChar, CChar, CChar, CChar)
+
+    @_spi(Support)
+    public init(tuple: CCharTuple8) {
+        self = withUnsafePointer(to: tuple) {
+            let size = MemoryLayout<CCharTuple8>.size
+            let data = Data(bytes: $0, count: size) + [0]
+            return String(cString: data) ?? ""
+        }
+    }
+}
+
 extension String {
     @_spi(Support)
     public typealias CCharTuple16 = (CChar, CChar, CChar, CChar, CChar, CChar, CChar, CChar, CChar, CChar, CChar, CChar, CChar, CChar, CChar, CChar)
diff --git a/Sources/MachOKit/Header/AotCacheHeader/AotCacheHeader.swift b/Sources/MachOKit/Header/AotCacheHeader/AotCacheHeader.swift
new file mode 100644
index 0000000..2025e22
--- /dev/null
+++ b/Sources/MachOKit/Header/AotCacheHeader/AotCacheHeader.swift
@@ -0,0 +1,34 @@
+//
+//  AotCacheHeader.swift
+//  MachOKit
+//
+//  Created by p-x9 on 2025/01/29
+//  
+//
+
+import Foundation
+import MachOKitC
+
+public struct AotCacheHeader: LayoutWrapper {
+    public typealias Layout = aot_cache_header
+
+    public var layout: Layout
+}
+
+extension AotCacheHeader {
+    public var magic: String {
+        .init(tuple: layout.magic)
+    }
+
+    public var uuid: UUID {
+        .init(uuid: layout.uuid)
+    }
+
+    public var x86UUID: UUID {
+        .init(uuid: layout.x86_uuid)
+    }
+
+    public var headerSize: Int {
+        numericCast(layout.header_size)
+    }
+}