Skip to content

Commit 4153326

Browse files
authored
Merge pull request #146 from p-x9/feature/trie-tree-search
2 parents 94fe4fa + 4620021 commit 4153326

22 files changed

+694
-402
lines changed

Sources/MachOKit/DyldCache.swift

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -216,12 +216,12 @@ extension DyldCache {
216216
}
217217

218218
extension DyldCache {
219-
public typealias DylibsTrieEntries = DataTrieTree<DylibsTrieNodeContent>
219+
public typealias DylibsTrie = DataTrieTree<DylibsTrieNodeContent>
220220

221221
/// Dylibs trie is for searching by dylib name.
222222
///
223223
/// The ``dylibIndices`` are retrieved from this trie tree.
224-
public var dylibsTrieEntries: DylibsTrieEntries? {
224+
public var dylibsTrie: DylibsTrie? {
225225
guard mainCacheHeader.dylibsTrieAddr > 0,
226226
mainCacheHeader.hasProperty(\.dylibsTrieSize) else {
227227
return nil
@@ -246,20 +246,20 @@ extension DyldCache {
246246
/// 0 /usr/lib/libobjc.dylib
247247
/// ```
248248
public var dylibIndices: [DylibIndex] {
249-
guard let dylibsTrieEntries else {
249+
guard let dylibsTrie else {
250250
return []
251251
}
252-
return dylibsTrieEntries.dylibIndices
252+
return dylibsTrie.dylibIndices
253253
}
254254
}
255255

256256
extension DyldCache {
257-
public typealias ProgramsTrieEntries = DataTrieTree<ProgramsTrieNodeContent>
257+
public typealias ProgramsTrie = DataTrieTree<ProgramsTrieNodeContent>
258258

259259
/// Pair of program name/cdhash and offset to prebuiltLoaderSet
260260
///
261261
/// The ``programOffsets`` are retrieved from this trie tree.
262-
public var programsTrieEntries: ProgramsTrieEntries? {
262+
public var programsTrie: ProgramsTrie? {
263263
guard mainCacheHeader.programTrieAddr > 0,
264264
mainCacheHeader.hasProperty(\.programTrieSize) else {
265265
return nil
@@ -269,7 +269,7 @@ extension DyldCache {
269269
}
270270
let size = mainCacheHeader.programTrieSize
271271

272-
return ProgramsTrieEntries(
272+
return ProgramsTrie(
273273
data: fileHandle.readData(offset: offset, size: Int(size))
274274
)
275275
}
@@ -284,10 +284,10 @@ extension DyldCache {
284284
/// 131776 /cdhash/fed26a75645fed2a674b5c4d01001bfa69b9dbea
285285
/// ```
286286
public var programOffsets: [ProgramOffset] {
287-
guard let programsTrieEntries else {
287+
guard let programsTrie else {
288288
return []
289289
}
290-
return programsTrieEntries.programOffsets
290+
return programsTrie.programOffsets
291291
}
292292

293293
/// Get the prebuiltLoaderSet indicated by programOffset.

Sources/MachOKit/DyldCacheLoaded.swift

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -207,12 +207,12 @@ extension DyldCacheLoaded {
207207
}
208208

209209
extension DyldCacheLoaded {
210-
public typealias DylibsTrieEntries = MemoryTrieTree<DylibsTrieNodeContent>
210+
public typealias DylibsTrie = MemoryTrieTree<DylibsTrieNodeContent>
211211

212212
/// Dylibs trie is for searching by dylib name.
213213
///
214214
/// The ``dylibIndices`` are retrieved from this trie tree.
215-
public var dylibsTrieEntries: DylibsTrieEntries? {
215+
public var dylibsTrie: DylibsTrie? {
216216
guard header.dylibsTrieAddr > 0,
217217
header.hasProperty(\.dylibsTrieSize),
218218
let slide else {
@@ -242,20 +242,20 @@ extension DyldCacheLoaded {
242242
/// 0 /usr/lib/libobjc.dylib
243243
/// ```
244244
public var dylibIndices: [DylibIndex] {
245-
guard let dylibsTrieEntries else {
245+
guard let dylibsTrie else {
246246
return []
247247
}
248-
return dylibsTrieEntries.dylibIndices
248+
return dylibsTrie.dylibIndices
249249
}
250250
}
251251

252252
extension DyldCacheLoaded {
253-
public typealias ProgramsTrieEntries = MemoryTrieTree<ProgramsTrieNodeContent>
253+
public typealias ProgramsTrie = MemoryTrieTree<ProgramsTrieNodeContent>
254254

255255
/// Pair of program name/cdhash and offset to prebuiltLoaderSet
256256
///
257257
/// The ``programOffsets`` are retrieved from this trie tree.
258-
public var programsTrieEntries: ProgramsTrieEntries? {
258+
public var programsTrie: ProgramsTrie? {
259259
guard header.programTrieAddr > 0,
260260
header.hasProperty(\.programTrieSize),
261261
let slide else {
@@ -268,7 +268,7 @@ extension DyldCacheLoaded {
268268
return nil
269269
}
270270

271-
return ProgramsTrieEntries(
271+
return ProgramsTrie(
272272
basePointer: basePointer,
273273
size: numericCast(size)
274274
)
@@ -284,10 +284,10 @@ extension DyldCacheLoaded {
284284
/// 131776 /cdhash/fed26a75645fed2a674b5c4d01001bfa69b9dbea
285285
/// ```
286286
public var programOffsets: [ProgramOffset] {
287-
guard let programsTrieEntries else {
287+
guard let programsTrie else {
288288
return []
289289
}
290-
return programsTrieEntries.programOffsets
290+
return programsTrie.programOffsets
291291
}
292292

293293
/// Get the prebuiltLoaderSet indicated by programOffset.
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
//
2+
// FixedWidthInteger+.swift
3+
// MachOKit
4+
//
5+
// Created by p-x9 on 2024/11/20
6+
//
7+
//
8+
9+
import Foundation
10+
11+
extension FixedWidthInteger {
12+
var uleb128Size: Int {
13+
var value = self
14+
var result = 0
15+
16+
repeat {
17+
value = value >> 7
18+
result += 1
19+
} while value != 0
20+
21+
return result
22+
}
23+
}

Sources/MachOKit/Extension/Sequence+.swift

Lines changed: 0 additions & 178 deletions
Original file line numberDiff line numberDiff line change
@@ -8,74 +8,6 @@
88

99
import Foundation
1010

11-
extension Sequence<ExportTrieEntry> {
12-
public var exportedSymbols: [ExportedSymbol] {
13-
let entries = Array(self)
14-
guard !entries.isEmpty else { return [] }
15-
16-
let map: [Int: Element] = Dictionary(
17-
uniqueKeysWithValues: entries.map {
18-
($0.offset, $0)
19-
}
20-
)
21-
return extractExportedSymbols(
22-
currentName: "",
23-
currentOffset: 0,
24-
entry: entries[0],
25-
map: map
26-
)
27-
}
28-
29-
/// https://opensource.apple.com/source/dyld/dyld-421.1/interlinked-dylibs/Trie.hpp.auto.html
30-
private func extractExportedSymbols(
31-
currentName: String,
32-
currentOffset: Int,
33-
entry: Element,
34-
map: [Int: Element]
35-
) -> [ExportedSymbol] {
36-
var currentOffset = currentOffset
37-
if let offset = entry.symbolOffset {
38-
currentOffset += Int(bitPattern: offset)
39-
}
40-
41-
guard !entry.children.isEmpty else {
42-
return [
43-
ExportedSymbol(
44-
name: currentName,
45-
offset: currentOffset,
46-
flags: entry.flags ?? [],
47-
ordinal: entry.ordinal,
48-
importedName: entry.importedName,
49-
stub: entry.stub,
50-
resolver: entry.resolver
51-
)
52-
]
53-
}
54-
return entry.children.map {
55-
if let entry = map[Int($0.offset)] {
56-
return extractExportedSymbols(
57-
currentName: currentName + $0.label,
58-
currentOffset: currentOffset,
59-
entry: entry,
60-
map: map
61-
)
62-
} else {
63-
return [
64-
ExportedSymbol(
65-
name: currentName + $0.label,
66-
offset: currentOffset,
67-
flags: entry.flags ?? [],
68-
ordinal: entry.ordinal,
69-
importedName: entry.importedName,
70-
stub: entry.stub,
71-
resolver: entry.resolver
72-
)
73-
]
74-
}
75-
}.flatMap { $0 }
76-
}
77-
}
78-
7911
// https://opensource.apple.com/source/ld64/ld64-253.9/src/other/dyldinfo.cpp.auto.html
8012
extension Sequence<BindOperation> {
8113
func bindings(
@@ -348,113 +280,3 @@ extension Sequence where Element == CodeSignCodeDirectory {
348280
}
349281
}
350282
}
351-
352-
extension Sequence<DylibsTrieEntry> {
353-
public var dylibIndices: [DylibIndex] {
354-
let entries = Array(self)
355-
guard !entries.isEmpty else { return [] }
356-
357-
let map: [Int: Element] = Dictionary(
358-
uniqueKeysWithValues: entries.map {
359-
($0.offset, $0)
360-
}
361-
)
362-
return extractDylibIndices(
363-
currentName: "",
364-
currentOffset: 0,
365-
entry: entries[0],
366-
map: map
367-
)
368-
}
369-
370-
private func extractDylibIndices(
371-
currentName: String,
372-
currentOffset: Int,
373-
entry: Element,
374-
map: [Int: Element]
375-
) -> [DylibIndex] {
376-
guard !entry.children.isEmpty else {
377-
if let content = entry.content {
378-
return [
379-
.init(name: currentName, index: content.index)
380-
]
381-
}
382-
return []
383-
}
384-
return entry.children.map {
385-
if let entry = map[Int($0.offset)] {
386-
return extractDylibIndices(
387-
currentName: currentName + $0.label,
388-
currentOffset: currentOffset,
389-
entry: entry,
390-
map: map
391-
)
392-
} else {
393-
if let content = entry.content {
394-
return [
395-
.init(
396-
name: currentName + $0.label,
397-
index: content.index
398-
)
399-
]
400-
}
401-
return []
402-
}
403-
}.flatMap { $0 }
404-
}
405-
}
406-
407-
extension Sequence<ProgramsTrieEntry> {
408-
public var programOffsets: [ProgramOffset] {
409-
let entries = Array(self)
410-
guard !entries.isEmpty else { return [] }
411-
412-
let map: [Int: Element] = Dictionary(
413-
uniqueKeysWithValues: entries.map {
414-
($0.offset, $0)
415-
}
416-
)
417-
return extractProgramOffsets(
418-
currentName: "",
419-
currentOffset: 0,
420-
entry: entries[0],
421-
map: map
422-
)
423-
}
424-
425-
private func extractProgramOffsets(
426-
currentName: String,
427-
currentOffset: Int,
428-
entry: Element,
429-
map: [Int: Element]
430-
) -> [ProgramOffset] {
431-
guard !entry.children.isEmpty else {
432-
if let content = entry.content {
433-
return [
434-
.init(name: currentName, offset: content.offset)
435-
]
436-
}
437-
return []
438-
}
439-
return entry.children.map {
440-
if let entry = map[Int($0.offset)] {
441-
return extractProgramOffsets(
442-
currentName: currentName + $0.label,
443-
currentOffset: currentOffset,
444-
entry: entry,
445-
map: map
446-
)
447-
} else {
448-
if let content = entry.content {
449-
return [
450-
.init(
451-
name: currentName + $0.label,
452-
offset: content.offset
453-
)
454-
]
455-
}
456-
return []
457-
}
458-
}.flatMap { $0 }
459-
}
460-
}

0 commit comments

Comments
 (0)