16
16
package ghidra .app .util .bin .format .swift ;
17
17
18
18
import java .io .IOException ;
19
- import java .util .ArrayList ;
20
- import java .util .List ;
19
+ import java .util .*;
21
20
22
21
import ghidra .app .util .bin .*;
23
22
import ghidra .app .util .bin .format .swift .types .*;
@@ -43,11 +42,11 @@ public class SwiftTypeMetadata {
43
42
44
43
private List <EntryPoint > entryPoints = new ArrayList <>();
45
44
private List <BuiltinTypeDescriptor > builtinTypeDescriptors = new ArrayList <>();
46
- private List < FieldDescriptor > fieldDescriptors = new ArrayList <>();
45
+ private Map < Long , FieldDescriptor > fieldDescriptors = new HashMap <>();
47
46
private List <AssociatedTypeDescriptor > associatedTypeDescriptors = new ArrayList <>();
48
47
private List <CaptureDescriptor > captureDescriptors = new ArrayList <>();
49
48
private List <MultiPayloadEnumDescriptor > mpEnumDescriptors = new ArrayList <>();
50
- private List < TargetTypeContextDescriptor > typeDescriptors = new ArrayList <>();
49
+ private Map < String , TargetTypeContextDescriptor > typeDescriptors = new HashMap <>();
51
50
private List <TargetProtocolDescriptor > protocolDescriptors = new ArrayList <>();
52
51
private List <TargetProtocolConformanceDescriptor > protocolConformanceDescriptors =
53
52
new ArrayList <>();
@@ -72,6 +71,69 @@ public SwiftTypeMetadata(Program program, TaskMonitor monitor, MessageLog log)
72
71
parse ();
73
72
}
74
73
74
+ /**
75
+ * {@return the entry points}
76
+ */
77
+ public List <EntryPoint > getEntryPoints () {
78
+ return entryPoints ;
79
+ }
80
+
81
+ /**
82
+ * {@return the built-in type descriptors}
83
+ */
84
+ public List <BuiltinTypeDescriptor > getBuiltinTypeDescriptors () {
85
+ return builtinTypeDescriptors ;
86
+ }
87
+
88
+ /**
89
+ * {@return the field descriptors}
90
+ */
91
+ public Map <Long , FieldDescriptor > getFieldDescriptors () {
92
+ return fieldDescriptors ;
93
+ }
94
+
95
+ /**
96
+ * {@return the associated type descriptors}
97
+ */
98
+ public List <AssociatedTypeDescriptor > getAssociatedTypeDescriptor () {
99
+ return associatedTypeDescriptors ;
100
+ }
101
+
102
+ /**
103
+ * {@return the capture descriptors}
104
+ */
105
+ public List <CaptureDescriptor > getCaptureDescriptors () {
106
+ return captureDescriptors ;
107
+ }
108
+
109
+ /**
110
+ * {@return the multi-payload enum descriptors}
111
+ */
112
+ public List <MultiPayloadEnumDescriptor > getMultiPayloadEnumDescriptors () {
113
+ return mpEnumDescriptors ;
114
+ }
115
+
116
+ /**
117
+ * {@return the type descriptors}
118
+ */
119
+ public Map <String , TargetTypeContextDescriptor > getTargetTypeContextDescriptors () {
120
+ return typeDescriptors ;
121
+ }
122
+
123
+ /**
124
+ * {@return the target protocol descriptors}
125
+ */
126
+ public List <TargetProtocolDescriptor > getTargetProtocolDescriptors () {
127
+ return protocolDescriptors ;
128
+ }
129
+
130
+ /**
131
+ * {@return the target protocol conformance descriptors}
132
+ */
133
+ public List <TargetProtocolConformanceDescriptor > getTargetProtocolConformanceDescriptors () {
134
+ return protocolConformanceDescriptors ;
135
+ }
136
+
75
137
/**
76
138
* Parses the {@link SwiftTypeMetadata}
77
139
*
@@ -137,14 +199,15 @@ private void parseBuiltinTypeDescriptors(SwiftSection section, BinaryReader read
137
199
for (MemoryBlock block : SwiftUtils .getSwiftBlocks (section , program )) {
138
200
Address blockStart = block .getStart ();
139
201
reader .setPointerIndex (blockStart .getOffset ());
140
- int i = 0 ;
202
+ int i = skipZeroEntries ( reader , 0 , block . getSize ()) ;
141
203
while (i + BuiltinTypeDescriptor .SIZE <= block .getSize ()) {
142
204
monitor .checkCancelled ();
143
205
BuiltinTypeDescriptor descriptor = new BuiltinTypeDescriptor (reader );
144
206
builtinTypeDescriptors .add (descriptor );
145
207
markupList .add (new SwiftStructureInfo (descriptor ,
146
208
new SwiftStructureAddress (blockStart .add (i ), null )));
147
209
i += BuiltinTypeDescriptor .SIZE ;
210
+ i = skipZeroEntries (reader , i , block .getSize ());
148
211
}
149
212
}
150
213
}
@@ -168,11 +231,11 @@ private void parseFieldDescriptors(SwiftSection section, BinaryReader reader)
168
231
for (MemoryBlock block : SwiftUtils .getSwiftBlocks (section , program )) {
169
232
Address blockStart = block .getStart ();
170
233
reader .setPointerIndex (blockStart .getOffset ());
171
- int i = 0 ;
234
+ int i = skipZeroEntries ( reader , 0 , block . getSize ()) ;
172
235
while (i + FieldDescriptor .SIZE <= block .getSize ()) {
173
236
monitor .checkCancelled ();
174
237
FieldDescriptor descriptor = new FieldDescriptor (reader );
175
- fieldDescriptors .add ( descriptor );
238
+ fieldDescriptors .put ( descriptor . getBase (), descriptor );
176
239
markupList .add (new SwiftStructureInfo (descriptor ,
177
240
new SwiftStructureAddress (blockStart .add (i ), null )));
178
241
List <FieldRecord > records = descriptor .getFieldRecords ();
@@ -184,6 +247,7 @@ private void parseFieldDescriptors(SwiftSection section, BinaryReader reader)
184
247
null )));
185
248
}
186
249
i += descriptor .getNumFields () * FieldRecord .SIZE ;
250
+ i = skipZeroEntries (reader , i , block .getSize ());
187
251
}
188
252
}
189
253
}
@@ -207,7 +271,7 @@ private void parseAssociatedTypeDescriptors(SwiftSection section, BinaryReader r
207
271
for (MemoryBlock block : SwiftUtils .getSwiftBlocks (section , program )) {
208
272
Address blockStart = block .getStart ();
209
273
reader .setPointerIndex (blockStart .getOffset ());
210
- int i = 0 ;
274
+ int i = skipZeroEntries ( reader , 0 , block . getSize ()) ;
211
275
while (i + AssociatedTypeDescriptor .SIZE <= block .getSize ()) {
212
276
monitor .checkCancelled ();
213
277
AssociatedTypeDescriptor descriptor = new AssociatedTypeDescriptor (reader );
@@ -223,6 +287,7 @@ private void parseAssociatedTypeDescriptors(SwiftSection section, BinaryReader r
223
287
blockStart .add (i + j * AssociatedTypeRecord .SIZE ), null )));
224
288
}
225
289
i += descriptor .getNumAssociatedTypes () * AssociatedTypeRecord .SIZE ;
290
+ i = skipZeroEntries (reader , i , block .getSize ());
226
291
}
227
292
}
228
293
}
@@ -246,7 +311,7 @@ private void parseCaptureTypeDescriptors(SwiftSection section, BinaryReader read
246
311
for (MemoryBlock block : SwiftUtils .getSwiftBlocks (section , program )) {
247
312
Address blockStart = block .getStart ();
248
313
reader .setPointerIndex (blockStart .getOffset ());
249
- int i = 0 ;
314
+ int i = skipZeroEntries ( reader , 0 , block . getSize ()) ;
250
315
while (i + CaptureDescriptor .SIZE <= block .getSize ()) {
251
316
monitor .checkCancelled ();
252
317
CaptureDescriptor descriptor = new CaptureDescriptor (reader );
@@ -271,6 +336,7 @@ private void parseCaptureTypeDescriptors(SwiftSection section, BinaryReader read
271
336
blockStart .add (i + j * MetadataSourceRecord .SIZE ), null )));
272
337
}
273
338
i += descriptor .getNumMetadataSources () * MetadataSourceRecord .SIZE ;
339
+ i = skipZeroEntries (reader , i , block .getSize ());
274
340
}
275
341
}
276
342
}
@@ -294,14 +360,15 @@ private void parseMultiPayloadEnumDescriptors(SwiftSection section, BinaryReader
294
360
for (MemoryBlock block : SwiftUtils .getSwiftBlocks (section , program )) {
295
361
Address blockStart = block .getStart ();
296
362
reader .setPointerIndex (blockStart .getOffset ());
297
- int i = 0 ;
363
+ int i = skipZeroEntries ( reader , 0 , block . getSize ()) ;
298
364
while (i < block .getSize ()) {
299
365
monitor .checkCancelled ();
300
366
MultiPayloadEnumDescriptor descriptor = new MultiPayloadEnumDescriptor (reader );
301
367
mpEnumDescriptors .add (descriptor );
302
368
markupList .add (new SwiftStructureInfo (descriptor ,
303
369
new SwiftStructureAddress (blockStart .add (i ), null )));
304
370
i += MultiPayloadEnumDescriptor .SIZE + descriptor .getContentsSize ();
371
+ i = skipZeroEntries (reader , i , block .getSize ());
305
372
}
306
373
}
307
374
}
@@ -397,7 +464,7 @@ private void parseTypeDescriptors(SwiftSection section, BinaryReader reader)
397
464
yield null ;
398
465
};
399
466
if (descriptor != null ) {
400
- typeDescriptors .add ( descriptor );
467
+ typeDescriptors .put ( descriptor . getName (), descriptor );
401
468
markupList .add (new SwiftStructureInfo (descriptor ,
402
469
new SwiftStructureAddress (addrPair .structAddr (), addrPair .pointerAddr ())));
403
470
}
@@ -409,7 +476,7 @@ private void parseTypeDescriptors(SwiftSection section, BinaryReader reader)
409
476
}
410
477
411
478
/**
412
- * Parses a table of pointers to {@link SwiftStructure }s found in the given section
479
+ * Parses a table of pointers to {@link SwiftTypeMetadataStructure }s found in the given section
413
480
*
414
481
* @param section The {@link SwiftSection} that contains the pointer table
415
482
* @param reader A {@link BinaryReader}
@@ -428,11 +495,10 @@ private List<SwiftStructureAddress> parsePointerTable(SwiftSection section, Bina
428
495
reader .setPointerIndex (blockAddr .getOffset () + i );
429
496
Address pointerAddr = blockAddr .add (i );
430
497
int offset = reader .readInt (pointerAddr .getOffset ());
431
- if (offset == 0 ) {
432
- break ;
498
+ if (offset != 0 ) {
499
+ Address structAddr = pointerAddr .add (offset );
500
+ result .add (new SwiftStructureAddress (structAddr , pointerAddr ));
433
501
}
434
- Address structAddr = pointerAddr .add (offset );
435
- result .add (new SwiftStructureAddress (structAddr , pointerAddr ));
436
502
}
437
503
}
438
504
}
@@ -454,7 +520,7 @@ public void markup() throws CancelledException {
454
520
monitor .checkCancelled ();
455
521
monitor .incrementProgress (1 );
456
522
try {
457
- SwiftStructure struct = structInfo .struct ();
523
+ SwiftTypeMetadataStructure struct = structInfo .struct ();
458
524
DataType dt = struct .toDataType ();
459
525
DataUtilities .createData (program , structInfo .addr ().structAddr (), dt , -1 ,
460
526
ClearDataMode .CLEAR_ALL_DEFAULT_CONFLICT_DATA );
@@ -465,12 +531,37 @@ public void markup() throws CancelledException {
465
531
relativePtrDataType , -1 , ClearDataMode .CLEAR_ALL_DEFAULT_CONFLICT_DATA );
466
532
}
467
533
}
468
- catch (CodeUnitInsertionException | DuplicateNameException | IOException e ) {
534
+ catch (CodeUnitInsertionException e ) {
535
+ // Probably just called more than once
536
+ }
537
+ catch (DuplicateNameException | IOException e ) {
469
538
log ("Failed to markup: " + structInfo );
470
539
}
471
540
}
472
541
}
473
542
543
+ /**
544
+ * Reads past zeroed out entries in Swift type metadata sections
545
+ *
546
+ * @param reader A {@link BinaryReader} positioned within a type metadata section
547
+ * @param offset The current offset from the start of the type metadata section
548
+ * @param size The size of the type metadata section (in bytes)
549
+ * @return The offset from the start of the type metadata section that contains the next
550
+ * non-zero entry
551
+ * @throws IOException if an IO-related error occurred
552
+ */
553
+ private int skipZeroEntries (BinaryReader reader , int offset , long size ) throws IOException {
554
+ while (offset + 8 <= size ) {
555
+ long possibleZero = reader .readNextLong ();
556
+ if (possibleZero != 0 ) {
557
+ reader .setPointerIndex (reader .getPointerIndex () - 8 );
558
+ return offset ;
559
+ }
560
+ offset += 8 ;
561
+ }
562
+ return offset ;
563
+ }
564
+
474
565
/**
475
566
* Convenience method to perform logging
476
567
*
@@ -481,22 +572,24 @@ private void log(String message) {
481
572
}
482
573
483
574
/**
484
- * The {@link Address} of a {@link SwiftStructure } and the optional {@link Address} of its
485
- * pointer
575
+ * The {@link Address} of a {@link SwiftTypeMetadataStructure } and the optional {@link Address}
576
+ * of its pointer
486
577
*
487
- * @param structAddr The {@link Address} of a {@link SwiftStructure }
488
- * @param pointerAddr The {@link Address} of a pointer to a {@link SwiftStructure} (could be
489
- * null if there is no associated pointer}
578
+ * @param structAddr The {@link Address} of a {@link SwiftTypeMetadataStructure }
579
+ * @param pointerAddr The {@link Address} of a pointer to a {@link SwiftTypeMetadataStructure}
580
+ * (could be null if there is no associated pointer}
490
581
*/
491
582
private record SwiftStructureAddress (Address structAddr , Address pointerAddr ) {}
492
583
493
584
/**
494
- * Information about a {@link SwiftStructure }
585
+ * Information about a {@link SwiftTypeMetadataStructure }
495
586
*
496
- * @param struct The {@link SwiftStructure}
497
- * @param addr The {@link SwiftStructureAddress address} of the {@link SwiftStructure}
587
+ * @param struct The {@link SwiftTypeMetadataStructure}
588
+ * @param addr The {@link SwiftStructureAddress address} of the
589
+ * {@link SwiftTypeMetadataStructure}
498
590
*/
499
- private record SwiftStructureInfo (SwiftStructure struct , SwiftStructureAddress addr ) {
591
+ private record SwiftStructureInfo (SwiftTypeMetadataStructure struct ,
592
+ SwiftStructureAddress addr ) {
500
593
501
594
@ Override
502
595
public String toString () {
0 commit comments