Skip to content

Commit f6fea70

Browse files
committed
Merge remote-tracking branch 'origin/GP-3535_ryanmkurtz_swift--SQUASHED'
2 parents 5a4315f + 32a0cf7 commit f6fea70

File tree

104 files changed

+6438
-161
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

104 files changed

+6438
-161
lines changed

Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/analysis/SwiftTypeMetadataAnalyzer.java

+11-1
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,8 @@ public class SwiftTypeMetadataAnalyzer extends AbstractAnalyzer {
3131
private static final String NAME = "Swift Type Metadata Analyzer";
3232
private static final String DESCRIPTION = "Discovers Swift type metadata records.";
3333

34+
private SwiftTypeMetadata typeMetadata;
35+
3436
public SwiftTypeMetadataAnalyzer() {
3537
super(NAME, DESCRIPTION, AnalyzerType.BYTE_ANALYZER);
3638
setDefaultEnablement(true);
@@ -45,13 +47,21 @@ public boolean canAnalyze(Program program) {
4547
@Override
4648
public boolean added(Program program, AddressSetView set, TaskMonitor monitor, MessageLog log)
4749
throws CancelledException {
50+
if (typeMetadata != null) {
51+
return true;
52+
}
4853
try {
49-
SwiftTypeMetadata typeMetadata = new SwiftTypeMetadata(program, monitor, log);
54+
typeMetadata = new SwiftTypeMetadata(program, monitor, log);
5055
typeMetadata.markup();
5156
}
5257
catch (IOException e) {
5358
return false;
5459
}
5560
return true;
5661
}
62+
63+
@Override
64+
public void analysisEnded(Program program) {
65+
typeMetadata = null;
66+
}
5767
}

Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/swift/SwiftSection.java

+3-2
Original file line numberDiff line numberDiff line change
@@ -35,8 +35,9 @@ public enum SwiftSection {
3535
BLOCK_PROTOCS("__swift5_protos", "swift5_protocols", ".sw5prt"),
3636
BLOCK_ACFUNCS("__swift5_acfuncs", "swift5_accessible_functions", ".sw5acfn"),
3737
BLOCK_MPENUM("__swift5_mpenum", "swift5_mpenum", ".sw5mpen"),
38-
BLOCK_TYPES("__swift5_types", "swift5_types", ".sw5tymd"),
39-
BLOCK_ENTRY("__swift5_entry", "swift5_entry", ".sw5entr");
38+
BLOCK_TYPES("__swift5_types", "swift5_type_metadata", ".sw5tymd"),
39+
BLOCK_ENTRY("__swift5_entry", "swift5_entry", ".sw5entr"),
40+
BLOCK_SWIFTAST("__swift_ast", ".swift_ast", "swiftast");
4041

4142
private List<String> sectionNames;
4243

Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/swift/SwiftTypeMetadata.java

+120-27
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,7 @@
1616
package ghidra.app.util.bin.format.swift;
1717

1818
import java.io.IOException;
19-
import java.util.ArrayList;
20-
import java.util.List;
19+
import java.util.*;
2120

2221
import ghidra.app.util.bin.*;
2322
import ghidra.app.util.bin.format.swift.types.*;
@@ -43,11 +42,11 @@ public class SwiftTypeMetadata {
4342

4443
private List<EntryPoint> entryPoints = new ArrayList<>();
4544
private List<BuiltinTypeDescriptor> builtinTypeDescriptors = new ArrayList<>();
46-
private List<FieldDescriptor> fieldDescriptors = new ArrayList<>();
45+
private Map<Long, FieldDescriptor> fieldDescriptors = new HashMap<>();
4746
private List<AssociatedTypeDescriptor> associatedTypeDescriptors = new ArrayList<>();
4847
private List<CaptureDescriptor> captureDescriptors = new ArrayList<>();
4948
private List<MultiPayloadEnumDescriptor> mpEnumDescriptors = new ArrayList<>();
50-
private List<TargetTypeContextDescriptor> typeDescriptors = new ArrayList<>();
49+
private Map<String, TargetTypeContextDescriptor> typeDescriptors = new HashMap<>();
5150
private List<TargetProtocolDescriptor> protocolDescriptors = new ArrayList<>();
5251
private List<TargetProtocolConformanceDescriptor> protocolConformanceDescriptors =
5352
new ArrayList<>();
@@ -72,6 +71,69 @@ public SwiftTypeMetadata(Program program, TaskMonitor monitor, MessageLog log)
7271
parse();
7372
}
7473

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+
75137
/**
76138
* Parses the {@link SwiftTypeMetadata}
77139
*
@@ -137,14 +199,15 @@ private void parseBuiltinTypeDescriptors(SwiftSection section, BinaryReader read
137199
for (MemoryBlock block : SwiftUtils.getSwiftBlocks(section, program)) {
138200
Address blockStart = block.getStart();
139201
reader.setPointerIndex(blockStart.getOffset());
140-
int i = 0;
202+
int i = skipZeroEntries(reader, 0, block.getSize());
141203
while (i + BuiltinTypeDescriptor.SIZE <= block.getSize()) {
142204
monitor.checkCancelled();
143205
BuiltinTypeDescriptor descriptor = new BuiltinTypeDescriptor(reader);
144206
builtinTypeDescriptors.add(descriptor);
145207
markupList.add(new SwiftStructureInfo(descriptor,
146208
new SwiftStructureAddress(blockStart.add(i), null)));
147209
i += BuiltinTypeDescriptor.SIZE;
210+
i = skipZeroEntries(reader, i, block.getSize());
148211
}
149212
}
150213
}
@@ -168,11 +231,11 @@ private void parseFieldDescriptors(SwiftSection section, BinaryReader reader)
168231
for (MemoryBlock block : SwiftUtils.getSwiftBlocks(section, program)) {
169232
Address blockStart = block.getStart();
170233
reader.setPointerIndex(blockStart.getOffset());
171-
int i = 0;
234+
int i = skipZeroEntries(reader, 0, block.getSize());
172235
while (i + FieldDescriptor.SIZE <= block.getSize()) {
173236
monitor.checkCancelled();
174237
FieldDescriptor descriptor = new FieldDescriptor(reader);
175-
fieldDescriptors.add(descriptor);
238+
fieldDescriptors.put(descriptor.getBase(), descriptor);
176239
markupList.add(new SwiftStructureInfo(descriptor,
177240
new SwiftStructureAddress(blockStart.add(i), null)));
178241
List<FieldRecord> records = descriptor.getFieldRecords();
@@ -184,6 +247,7 @@ private void parseFieldDescriptors(SwiftSection section, BinaryReader reader)
184247
null)));
185248
}
186249
i += descriptor.getNumFields() * FieldRecord.SIZE;
250+
i = skipZeroEntries(reader, i, block.getSize());
187251
}
188252
}
189253
}
@@ -207,7 +271,7 @@ private void parseAssociatedTypeDescriptors(SwiftSection section, BinaryReader r
207271
for (MemoryBlock block : SwiftUtils.getSwiftBlocks(section, program)) {
208272
Address blockStart = block.getStart();
209273
reader.setPointerIndex(blockStart.getOffset());
210-
int i = 0;
274+
int i = skipZeroEntries(reader, 0, block.getSize());
211275
while (i + AssociatedTypeDescriptor.SIZE <= block.getSize()) {
212276
monitor.checkCancelled();
213277
AssociatedTypeDescriptor descriptor = new AssociatedTypeDescriptor(reader);
@@ -223,6 +287,7 @@ private void parseAssociatedTypeDescriptors(SwiftSection section, BinaryReader r
223287
blockStart.add(i + j * AssociatedTypeRecord.SIZE), null)));
224288
}
225289
i += descriptor.getNumAssociatedTypes() * AssociatedTypeRecord.SIZE;
290+
i = skipZeroEntries(reader, i, block.getSize());
226291
}
227292
}
228293
}
@@ -246,7 +311,7 @@ private void parseCaptureTypeDescriptors(SwiftSection section, BinaryReader read
246311
for (MemoryBlock block : SwiftUtils.getSwiftBlocks(section, program)) {
247312
Address blockStart = block.getStart();
248313
reader.setPointerIndex(blockStart.getOffset());
249-
int i = 0;
314+
int i = skipZeroEntries(reader, 0, block.getSize());
250315
while (i + CaptureDescriptor.SIZE <= block.getSize()) {
251316
monitor.checkCancelled();
252317
CaptureDescriptor descriptor = new CaptureDescriptor(reader);
@@ -271,6 +336,7 @@ private void parseCaptureTypeDescriptors(SwiftSection section, BinaryReader read
271336
blockStart.add(i + j * MetadataSourceRecord.SIZE), null)));
272337
}
273338
i += descriptor.getNumMetadataSources() * MetadataSourceRecord.SIZE;
339+
i = skipZeroEntries(reader, i, block.getSize());
274340
}
275341
}
276342
}
@@ -294,14 +360,15 @@ private void parseMultiPayloadEnumDescriptors(SwiftSection section, BinaryReader
294360
for (MemoryBlock block : SwiftUtils.getSwiftBlocks(section, program)) {
295361
Address blockStart = block.getStart();
296362
reader.setPointerIndex(blockStart.getOffset());
297-
int i = 0;
363+
int i = skipZeroEntries(reader, 0, block.getSize());
298364
while (i < block.getSize()) {
299365
monitor.checkCancelled();
300366
MultiPayloadEnumDescriptor descriptor = new MultiPayloadEnumDescriptor(reader);
301367
mpEnumDescriptors.add(descriptor);
302368
markupList.add(new SwiftStructureInfo(descriptor,
303369
new SwiftStructureAddress(blockStart.add(i), null)));
304370
i += MultiPayloadEnumDescriptor.SIZE + descriptor.getContentsSize();
371+
i = skipZeroEntries(reader, i, block.getSize());
305372
}
306373
}
307374
}
@@ -397,7 +464,7 @@ private void parseTypeDescriptors(SwiftSection section, BinaryReader reader)
397464
yield null;
398465
};
399466
if (descriptor != null) {
400-
typeDescriptors.add(descriptor);
467+
typeDescriptors.put(descriptor.getName(), descriptor);
401468
markupList.add(new SwiftStructureInfo(descriptor,
402469
new SwiftStructureAddress(addrPair.structAddr(), addrPair.pointerAddr())));
403470
}
@@ -409,7 +476,7 @@ private void parseTypeDescriptors(SwiftSection section, BinaryReader reader)
409476
}
410477

411478
/**
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
413480
*
414481
* @param section The {@link SwiftSection} that contains the pointer table
415482
* @param reader A {@link BinaryReader}
@@ -428,11 +495,10 @@ private List<SwiftStructureAddress> parsePointerTable(SwiftSection section, Bina
428495
reader.setPointerIndex(blockAddr.getOffset() + i);
429496
Address pointerAddr = blockAddr.add(i);
430497
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));
433501
}
434-
Address structAddr = pointerAddr.add(offset);
435-
result.add(new SwiftStructureAddress(structAddr, pointerAddr));
436502
}
437503
}
438504
}
@@ -454,7 +520,7 @@ public void markup() throws CancelledException {
454520
monitor.checkCancelled();
455521
monitor.incrementProgress(1);
456522
try {
457-
SwiftStructure struct = structInfo.struct();
523+
SwiftTypeMetadataStructure struct = structInfo.struct();
458524
DataType dt = struct.toDataType();
459525
DataUtilities.createData(program, structInfo.addr().structAddr(), dt, -1,
460526
ClearDataMode.CLEAR_ALL_DEFAULT_CONFLICT_DATA);
@@ -465,12 +531,37 @@ public void markup() throws CancelledException {
465531
relativePtrDataType, -1, ClearDataMode.CLEAR_ALL_DEFAULT_CONFLICT_DATA);
466532
}
467533
}
468-
catch (CodeUnitInsertionException | DuplicateNameException | IOException e) {
534+
catch (CodeUnitInsertionException e) {
535+
// Probably just called more than once
536+
}
537+
catch (DuplicateNameException | IOException e) {
469538
log("Failed to markup: " + structInfo);
470539
}
471540
}
472541
}
473542

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+
474565
/**
475566
* Convenience method to perform logging
476567
*
@@ -481,22 +572,24 @@ private void log(String message) {
481572
}
482573

483574
/**
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
486577
*
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}
490581
*/
491582
private record SwiftStructureAddress(Address structAddr, Address pointerAddr) {}
492583

493584
/**
494-
* Information about a {@link SwiftStructure}
585+
* Information about a {@link SwiftTypeMetadataStructure}
495586
*
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}
498590
*/
499-
private record SwiftStructureInfo(SwiftStructure struct, SwiftStructureAddress addr) {
591+
private record SwiftStructureInfo(SwiftTypeMetadataStructure struct,
592+
SwiftStructureAddress addr) {
500593

501594
@Override
502595
public String toString() {
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
/* ###
2+
* IP: GHIDRA
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package ghidra.app.util.bin.format.swift;
17+
18+
import ghidra.app.util.bin.StructConverter;
19+
20+
/**
21+
* Implemented by all Swift type metadata structures
22+
*/
23+
public abstract class SwiftTypeMetadataStructure implements StructConverter {
24+
25+
public static final String DATA_TYPE_CATEGORY = "/SwiftTypeMetadata";
26+
27+
private long base;
28+
29+
public SwiftTypeMetadataStructure(long base) {
30+
this.base = base;
31+
}
32+
33+
/**
34+
* Gets the base "address" of this {@link SwiftTypeMetadataStructure}
35+
*
36+
* @return The base "address" of this {@link SwiftTypeMetadataStructure}
37+
*/
38+
public long getBase() {
39+
return base;
40+
}
41+
42+
/**
43+
* Gets the name of the {@link SwiftTypeMetadataStructure}
44+
*
45+
* @return The name of the {@link SwiftTypeMetadataStructure}
46+
*/
47+
public abstract String getStructureName();
48+
49+
/**
50+
* Gets a short description of the {@link SwiftTypeMetadataStructure}
51+
*
52+
* @return A short description of the {@link SwiftTypeMetadataStructure}
53+
*/
54+
public abstract String getDescription();
55+
}

0 commit comments

Comments
 (0)