Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

AOT shared cache #173

Draft
wants to merge 2 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
58 changes: 58 additions & 0 deletions Sources/MachOKit/AotCache.swift
Original file line number Diff line number Diff line change
@@ -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
)
}
}
14 changes: 14 additions & 0 deletions Sources/MachOKit/Extension/String+.swift
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
34 changes: 34 additions & 0 deletions Sources/MachOKit/Header/AotCacheHeader/AotCacheHeader.swift
Original file line number Diff line number Diff line change
@@ -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)
}
}
28 changes: 28 additions & 0 deletions Sources/MachOKitC/include/aot_cache.h
Original file line number Diff line number Diff line change
@@ -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 */