Skip to content

Commit 93d1591

Browse files
authored
Merge pull request #15 from MxIris-Reverse-Engineering/optimize/protocol-requirement-signature
2 parents 17ed2be + 16b887a commit 93d1591

19 files changed

+260
-114
lines changed

Package.swift

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -148,14 +148,27 @@ let package = Package(
148148
.product(name: "AssociatedObject", package: "AssociatedObject"),
149149
]
150150
),
151+
152+
.target(
153+
name: "MachOSymbols",
154+
dependencies: [
155+
.MachOKit,
156+
"MachOReading",
157+
"MachOMacro",
158+
"Demangle",
159+
]
160+
),
161+
151162
.target(
152163
name: "MachOPointer",
153164
dependencies: [
154165
.MachOKit,
155166
"MachOReading",
156167
"MachOMacro",
168+
"MachOSymbols",
157169
]
158170
),
171+
159172
.target(
160173
name: "MachOFoundation",
161174
dependencies: [

Sources/Demangle/Main/Demangler.swift

Lines changed: 61 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -280,7 +280,12 @@ extension Demangler {
280280
private mutating func pushMultiSubstitutions(repeatCount: Int, index: Int) throws -> Node {
281281
try require(repeatCount <= maxRepeatCount)
282282
let nd = try require(substitutions.at(index))
283-
(0 ..< max(0, repeatCount - 1)).forEach { _ in nameStack.append(nd) }
283+
// (0 ..< max(0, repeatCount - 1)).forEach { _ in }
284+
var repeatCount = repeatCount
285+
while repeatCount > 1 {
286+
nameStack.append(nd)
287+
repeatCount -= 1
288+
}
284289
return nd
285290
}
286291

@@ -341,11 +346,11 @@ extension Demangler {
341346
}
342347
}
343348

344-
private mutating func getLabel(params: inout Node, idx: Int) throws -> Node {
349+
private mutating func getLabel(params: Node, idx: Int) throws -> Node {
345350
if isOldFunctionTypeMangling {
346351
let param = try require(params.children.at(idx))
347352
if let label = param.children.enumerated().first(where: { $0.element.kind == .tupleElementName }) {
348-
params.children[idx].removeChild(at: label.offset)
353+
param.removeChild(at: label.offset)
349354
return Node(kind: .identifier, contents: .name(label.element.text ?? ""))
350355
}
351356
return Node(kind: .firstElementMarker)
@@ -386,7 +391,7 @@ extension Demangler {
386391
if funcType.children.at(firstChildIndex)?.kind == .differentiableFunctionType {
387392
firstChildIndex += 1
388393
}
389-
if funcType.children.at(firstChildIndex)?.kind == .throwsAnnotation || funcType.children.at(0)?.kind == .typedThrowsAnnotation {
394+
if funcType.children.at(firstChildIndex)?.kind == .throwsAnnotation || funcType.children.at(firstChildIndex)?.kind == .typedThrowsAnnotation {
390395
firstChildIndex += 1
391396
}
392397
if funcType.children.at(firstChildIndex)?.kind == .concurrentFunctionType {
@@ -408,14 +413,14 @@ extension Demangler {
408413
guard numParams > 0 else { return nil }
409414

410415
let possibleTuple = parameterType.children.first?.children.first
411-
guard !isOldFunctionTypeMangling, var tuple = possibleTuple, tuple.kind == .tuple else {
416+
guard !isOldFunctionTypeMangling, let tuple = possibleTuple, tuple.kind == .tuple else {
412417
return Node(kind: .labelList)
413418
}
414419

415420
var hasLabels = false
416421
var children = [Node]()
417422
for i in 0 ..< numParams {
418-
let label = try getLabel(params: &tuple, idx: Int(i))
423+
let label = try getLabel(params: tuple, idx: Int(i))
419424
try require(label.kind == .identifier || label.kind == .firstElementMarker)
420425
children.append(label)
421426
hasLabels = hasLabels || (label.kind != .firstElementMarker)
@@ -429,20 +434,24 @@ extension Demangler {
429434
}
430435

431436
private mutating func popTuple() throws -> Node {
432-
var children: [Node] = []
437+
let root = Node(kind: .tuple)
433438
if pop(kind: .emptyList) == nil {
434439
var firstElem = false
435440
repeat {
436441
firstElem = pop(kind: .firstElementMarker) != nil
437-
var elemChildren: [Node] = pop(kind: .variadicMarker).map { [$0] } ?? []
442+
let tupleElement = Node(kind: .tupleElement)
443+
if let variadicMarker = pop(kind: .variadicMarker) {
444+
tupleElement.addChild(variadicMarker)
445+
}
438446
if let ident = pop(kind: .identifier), case let .name(text) = ident.contents {
439-
elemChildren.append(Node(kind: .tupleElementName, contents: .name(text)))
447+
tupleElement.addChild(Node(kind: .tupleElementName, contents: .name(text)))
440448
}
441-
try elemChildren.append(require(pop(kind: .type)))
442-
children.insert(Node(kind: .tupleElement, children: elemChildren), at: 0)
449+
try tupleElement.addChild(require(pop(kind: .type)))
450+
root.addChild(tupleElement)
443451
} while !firstElem
452+
root.reverseChildren()
444453
}
445-
return Node(typeWithChildKind: .tuple, childChildren: children)
454+
return Node(kind: .type, child: root)
446455
}
447456

448457
private mutating func popPack(kind: Node.Kind = .pack) throws -> Node {
@@ -925,7 +934,7 @@ extension Demangler {
925934
case "p": return Node(swiftBuiltinType: .builtinTypeName, name: "Builtin.RawPointer")
926935
case "t": return Node(swiftBuiltinType: .builtinTypeName, name: "Builtin.SILToken")
927936
case "w": return Node(swiftBuiltinType: .builtinTypeName, name: "Builtin.Word")
928-
case "c": return Node(swiftBuiltinType: .builtinTypeName, name: "Builtin.DefaultActorStorage")
937+
case "c": return Node(swiftBuiltinType: .builtinTypeName, name: "Builtin.RawUnsafeContinuation")
929938
case "D": return Node(swiftBuiltinType: .builtinTypeName, name: "Builtin.DefaultActorStorage")
930939
case "d": return Node(swiftBuiltinType: .builtinTypeName, name: "Builtin.NonDefaultDistributedActorStorage")
931940
case "j": return Node(swiftBuiltinType: .builtinTypeName, name: "Builtin.Job")
@@ -1216,13 +1225,16 @@ extension Demangler {
12161225
case "B": fConv = "block"
12171226
case "C": fConv = "c"
12181227
case "z":
1219-
if scanner.conditional(scalar: "B") {
1228+
switch try scanner.readScalar() {
1229+
case "B":
12201230
hasClangType = true
12211231
fConv = "block"
1222-
} else if scanner.conditional(scalar: "C") {
1232+
case "C":
12231233
hasClangType = true
12241234
fConv = "c"
1225-
} else {
1235+
default:
1236+
try scanner.backtrack()
1237+
try scanner.backtrack()
12261238
fConv = nil
12271239
}
12281240
case "M": fConv = "method"
@@ -1448,6 +1460,7 @@ extension Demangler {
14481460
}
14491461

14501462
private mutating func demangleGenericParamIndex() throws -> Node {
1463+
14511464
switch try scanner.readScalar() {
14521465
case "d":
14531466
let depth = try demangleIndex() + 1
@@ -1544,14 +1557,25 @@ extension Demangler {
15441557
case "f": return try demangleFunctionSpecialization()
15451558
case "K",
15461559
"k":
1547-
let nodeKind: Node.Kind = c == "K" ? .keyPathGetterThunkHelper : .keyPathSetterThunkHelper
1560+
let nodeKind: Node.Kind
1561+
if scanner.conditional(string: "mu") {
1562+
nodeKind = .keyPathUnappliedMethodThunkHelper
1563+
} else if scanner.conditional(string: "MA") {
1564+
nodeKind = .keyPathAppliedMethodThunkHelper
1565+
} else {
1566+
nodeKind = c == "K" ? .keyPathGetterThunkHelper : .keyPathSetterThunkHelper
1567+
}
1568+
15481569
let isSerialized = scanner.conditional(string: "q")
15491570
var types = [Node]()
15501571
var node = pop(kind: .type)
1551-
while let n = node {
1552-
types.append(n)
1572+
repeat {
1573+
if let node {
1574+
types.append(node)
1575+
}
15531576
node = pop(kind: .type)
1554-
}
1577+
} while node != nil && node?.kind == .type
1578+
15551579
var result: Node
15561580
if let n = pop() {
15571581
if n.kind == .dependentGenericSignature {
@@ -1563,7 +1587,7 @@ extension Demangler {
15631587
} else {
15641588
throw failure
15651589
}
1566-
for t in types {
1590+
for t in types.reversed() {
15671591
result.addChild(t)
15681592
}
15691593
if isSerialized {
@@ -1753,7 +1777,8 @@ extension Demangler {
17531777
var str = ""
17541778
let kind = try scanner.readScalar()
17551779
switch kind {
1756-
case "p",
1780+
case "o",
1781+
"p",
17571782
"a",
17581783
"m": str.unicodeScalars.append(kind)
17591784
default: return ""
@@ -2012,7 +2037,7 @@ extension Demangler {
20122037
guard let identifier = pop(where: { $0.isDeclName }) else { throw failure }
20132038
declList.addChild(identifier)
20142039
}
2015-
declList.reverseChildren()
2040+
// declList.reverseChildren()
20162041
return try Node(kind: c == "Z" ? .globalVariableOnceFunction : .globalVariableOnceToken, children: [popContext(), declList])
20172042
case "J":
20182043
return try demangleDifferentiabilityWitness()
@@ -2287,11 +2312,11 @@ extension Demangler {
22872312
if let labelList = labelList {
22882313
ss.addChild(labelList)
22892314
}
2290-
setParentForOpaqueReturnTypeNodes(visited: type, parentId: getParentId(parent: ss, flavor: flavor))
22912315
ss.addChild(type)
22922316
if let pn = privateName {
22932317
ss.addChild(pn)
22942318
}
2319+
setParentForOpaqueReturnTypeNodes(visited: type, parentId: getParentId(parent: ss, flavor: flavor))
22952320
return try demangleAccessor(child: ss)
22962321
}
22972322

@@ -2341,6 +2366,13 @@ extension Demangler {
23412366
sig.insertChild(req, at: requirementsIndex)
23422367
}
23432368
return sig
2369+
/*
2370+
let count = sig.children.count
2371+
while let req = pop(where: { $0.isRequirement }) {
2372+
sig.addChild(req)
2373+
}
2374+
sig.reverseFirst(count)
2375+
*/
23442376
}
23452377

23462378
private mutating func demangleGenericRequirement() throws -> Node {
@@ -2389,7 +2421,7 @@ extension Demangler {
23892421
}
23902422

23912423
switch constraintAndTypeKinds.constraint {
2392-
case .valueMarker: return try Node(kind: .dependentGenericParamPackMarker, children: [constrType, require(pop(kind: .type))])
2424+
case .valueMarker: return try Node(kind: .dependentGenericParamValueMarker, children: [constrType, require(pop(kind: .type))])
23932425
case .packMarker: return Node(kind: .dependentGenericParamPackMarker, children: [constrType])
23942426
case .protocol: return try Node(kind: .dependentGenericConformanceRequirement, children: [constrType, popProtocol()])
23952427
case .inverse: return try Node(kind: .dependentGenericInverseConformanceRequirement, children: [constrType, require(inverseKind)])
@@ -2406,13 +2438,15 @@ extension Demangler {
24062438
"N",
24072439
"C",
24082440
"D",
2409-
"T": break
2441+
"T",
2442+
"B": break
24102443
case "E",
24112444
"M":
24122445
size = try demangleIndexAsName()
24132446
alignment = try demangleIndexAsName()
24142447
case "e",
2415-
"m":
2448+
"m",
2449+
"S":
24162450
size = try demangleIndexAsName()
24172451
default: throw failure
24182452
}

Sources/Demangle/Main/Node/Node+Kind.swift

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -179,6 +179,8 @@ extension Node {
179179
case keyPathGetterThunkHelper
180180
case keyPathHashThunkHelper
181181
case keyPathSetterThunkHelper
182+
case keyPathAppliedMethodThunkHelper
183+
case keyPathUnappliedMethodThunkHelper
182184
case labelList
183185
case lazyProtocolWitnessTableAccessor
184186
case lazyProtocolWitnessTableCacheVariable

Sources/Demangle/Main/Node/Node.swift

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,10 @@ public final class Node: @unchecked Sendable {
142142
public func reverseChildren() {
143143
children.reverse()
144144
}
145+
146+
public func reverseFirst(_ count: Int) {
147+
children.reverseFirst(count)
148+
}
145149
}
146150

147151
extension Node {
@@ -189,7 +193,7 @@ extension Node {
189193
case .tupleElementName: fallthrough
190194
case .typeAlias: fallthrough
191195
case .typeList: fallthrough
192-
case .typeSymbolicReference: fallthrough
196+
case .typeSymbolicReference: return true
193197
case .type:
194198
return children.first.map { $0.isSimpleType } ?? false
195199
case .protocolList:
@@ -221,3 +225,23 @@ extension Node {
221225
}
222226

223227

228+
extension Array {
229+
/// Reverse the first n elements of the array
230+
/// - Parameter count: Number of elements to reverse from the beginning
231+
mutating func reverseFirst(_ count: Int) {
232+
guard count > 0 && count <= self.count else { return }
233+
let endIndex = count - 1
234+
for i in 0..<(count / 2) {
235+
self.swapAt(i, endIndex - i)
236+
}
237+
}
238+
239+
/// Returns a new array with the first n elements reversed
240+
/// - Parameter count: Number of elements to reverse from the beginning
241+
/// - Returns: New array with first n elements reversed
242+
func reversedFirst(_ count: Int) -> Array {
243+
var result = self
244+
result.reverseFirst(count)
245+
return result
246+
}
247+
}

0 commit comments

Comments
 (0)