mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2026-01-06 20:53:55 -05:00
GP-6281: More Swift type metadata markup (mostly TrailingObjects)
This commit is contained in:
@@ -77,6 +77,10 @@ public interface StructConverter {
|
||||
* Reusable 64-bit image base offset datatype.
|
||||
*/
|
||||
public final static DataType IBO64 = IBO64DataType.dataType;
|
||||
/**
|
||||
* Reusable boolean data type.
|
||||
*/
|
||||
public final static DataType BOOL = BooleanDataType.dataType;
|
||||
|
||||
/**
|
||||
* Reusable Unsigned LEB128 dynamic length data type
|
||||
|
||||
@@ -4,9 +4,9 @@
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
@@ -51,9 +51,7 @@ public enum SwiftSection {
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a {@link List} of the {@link SwiftSection}'s names
|
||||
*
|
||||
* @return A {@link List} of the {@link SwiftSection}'s names
|
||||
* {@return a {@link List} of the {@link SwiftSection}'s names}
|
||||
*/
|
||||
public List<String> getSwiftSectionNames() {
|
||||
return sectionNames;
|
||||
|
||||
@@ -4,9 +4,9 @@
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
@@ -168,19 +168,19 @@ public class SwiftTypeMetadata {
|
||||
throws CancelledException {
|
||||
monitor.setMessage("Parsing Swift entry point(s)...");
|
||||
monitor.setIndeterminate(true);
|
||||
try {
|
||||
for (MemoryBlock block : SwiftUtils.getSwiftBlocks(section, program)) {
|
||||
monitor.checkCancelled();
|
||||
Address blockStart = block.getStart();
|
||||
for (MemoryBlock block : SwiftUtils.getSwiftBlocks(section, program)) {
|
||||
monitor.checkCancelled();
|
||||
Address blockStart = block.getStart();
|
||||
try {
|
||||
reader.setPointerIndex(blockStart.getOffset());
|
||||
EntryPoint entryPoint = new EntryPoint(reader);
|
||||
entryPoints.add(entryPoint);
|
||||
markupList.add(new SwiftStructureInfo(entryPoint,
|
||||
new SwiftStructureAddress(blockStart, null)));
|
||||
}
|
||||
}
|
||||
catch (IOException e) {
|
||||
log("Failed to parse entry point(s) from section '" + section + "'");
|
||||
catch (IOException e) {
|
||||
log("Failed to parse entry point at %s: %s".formatted(blockStart, e.getMessage()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -386,20 +386,20 @@ public class SwiftTypeMetadata {
|
||||
*/
|
||||
private void parseProtocolDescriptors(SwiftSection section, BinaryReader reader)
|
||||
throws CancelledException {
|
||||
monitor.setMessage("Parsing Swift protocol descriptors...");
|
||||
monitor.setIndeterminate(true);
|
||||
try {
|
||||
List<SwiftStructureAddress> addrPairs = parsePointerTable(section, reader);
|
||||
for (SwiftStructureAddress addrPair : addrPairs) {
|
||||
reader.setPointerIndex(addrPair.structAddr().getOffset());
|
||||
List<SwiftStructureAddress> addrPairs = parsePointerTable(section, reader);
|
||||
monitor.initialize(addrPairs.size(), "Parsing Swift protocol descriptors...");
|
||||
for (SwiftStructureAddress addrPair : addrPairs) {
|
||||
monitor.increment();
|
||||
reader.setPointerIndex(addrPair.structAddr().getOffset());
|
||||
try {
|
||||
TargetProtocolDescriptor descriptor = new TargetProtocolDescriptor(reader);
|
||||
protocolDescriptors.add(descriptor);
|
||||
markupList.add(new SwiftStructureInfo(descriptor,
|
||||
new SwiftStructureAddress(addrPair.structAddr(), addrPair.pointerAddr())));
|
||||
markupList.add(new SwiftStructureInfo(descriptor, addrPair));
|
||||
}
|
||||
catch (IOException e) {
|
||||
log("Failed to parse protocol descriptors at %s: %s"
|
||||
.formatted(addrPair.structAddr(), e.getMessage()));
|
||||
}
|
||||
}
|
||||
catch (IOException e) {
|
||||
log("Failed to parse protocol descriptors from section '" + section + "'");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -412,23 +412,21 @@ public class SwiftTypeMetadata {
|
||||
*/
|
||||
private void parseProtocolConformanceDescriptors(SwiftSection section, BinaryReader reader)
|
||||
throws CancelledException {
|
||||
monitor.setMessage("Parsing Swift protocol conformance descriptors...");
|
||||
monitor.setIndeterminate(true);
|
||||
try {
|
||||
List<SwiftStructureAddress> addrPairs = parsePointerTable(section, reader);
|
||||
for (SwiftStructureAddress addrPair : addrPairs) {
|
||||
List<SwiftStructureAddress> addrPairs = parsePointerTable(section, reader);
|
||||
monitor.initialize(addrPairs.size(), "Parsing Swift protocol conformance descriptors...");
|
||||
for (SwiftStructureAddress addrPair : addrPairs) {
|
||||
monitor.increment();
|
||||
try {
|
||||
reader.setPointerIndex(addrPair.structAddr().getOffset());
|
||||
TargetProtocolConformanceDescriptor descriptor =
|
||||
new TargetProtocolConformanceDescriptor(reader);
|
||||
protocolConformanceDescriptors.add(descriptor);
|
||||
markupList.add(new SwiftStructureInfo(descriptor,
|
||||
new SwiftStructureAddress(addrPair.structAddr(),
|
||||
addrPair.pointerAddr())));
|
||||
markupList.add(new SwiftStructureInfo(descriptor, addrPair));
|
||||
}
|
||||
catch (IOException e) {
|
||||
log("Failed to parse protocol conformance descriptor at %s: %s"
|
||||
.formatted(addrPair.structAddr(), e.getMessage()));
|
||||
}
|
||||
}
|
||||
catch (IOException e) {
|
||||
log("Failed to parse protocol conformance descriptors from section '" + section +
|
||||
"'");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -441,37 +439,37 @@ public class SwiftTypeMetadata {
|
||||
*/
|
||||
private void parseTypeDescriptors(SwiftSection section, BinaryReader reader)
|
||||
throws CancelledException {
|
||||
monitor.setMessage("Parsing Swift type descriptors...");
|
||||
monitor.setIndeterminate(true);
|
||||
try {
|
||||
List<SwiftStructureAddress> addrPairs = parsePointerTable(section, reader);
|
||||
for (SwiftStructureAddress addrPair : addrPairs) {
|
||||
List<SwiftStructureAddress> addrPairs = parsePointerTable(section, reader);
|
||||
monitor.initialize(addrPairs.size(), "Parsing Swift type descriptors...");
|
||||
for (SwiftStructureAddress addrPair : addrPairs) {
|
||||
monitor.increment();
|
||||
try {
|
||||
reader.setPointerIndex(addrPair.structAddr().getOffset());
|
||||
long origIndex = reader.getPointerIndex();
|
||||
TargetTypeContextDescriptor descriptor = new TargetTypeContextDescriptor(reader);
|
||||
reader.setPointerIndex(origIndex);
|
||||
int contextDescriptorKind = ContextDescriptorKind.getKind(descriptor.getFlags());
|
||||
descriptor = switch (contextDescriptorKind) {
|
||||
case ContextDescriptorKind.CLASS:
|
||||
ContextDescriptorKind kind = descriptor.getFlags().getKind();
|
||||
descriptor = switch (kind) {
|
||||
case Class:
|
||||
yield new TargetClassDescriptor(reader);
|
||||
case ContextDescriptorKind.STRUCT:
|
||||
case Struct:
|
||||
yield new TargetStructDescriptor(reader);
|
||||
case ContextDescriptorKind.ENUM:
|
||||
case Enum:
|
||||
yield new TargetEnumDescriptor(reader);
|
||||
default:
|
||||
log("Unrecognized type descriptor %d at index: 0x%x"
|
||||
.formatted(contextDescriptorKind, origIndex));
|
||||
.formatted(kind.getValue(), origIndex));
|
||||
yield null;
|
||||
};
|
||||
if (descriptor != null) {
|
||||
typeDescriptors.put(descriptor.getName(), descriptor);
|
||||
markupList.add(new SwiftStructureInfo(descriptor,
|
||||
new SwiftStructureAddress(addrPair.structAddr(), addrPair.pointerAddr())));
|
||||
markupList.add(new SwiftStructureInfo(descriptor, addrPair));
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (IOException e) {
|
||||
log("Failed to parse type descriptors from section '" + section + "'");
|
||||
catch (IOException e) {
|
||||
log("Failed to parse type descriptor at %s: %s".formatted(addrPair,
|
||||
e.getMessage()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -487,6 +485,8 @@ public class SwiftTypeMetadata {
|
||||
throws CancelledException {
|
||||
final int POINTER_SIZE = 4;
|
||||
List<SwiftStructureAddress> result = new ArrayList<>();
|
||||
monitor.setMessage("Parsing Swift protocol conformance descriptors...");
|
||||
monitor.setIndeterminate(true);
|
||||
try {
|
||||
for (MemoryBlock block : SwiftUtils.getSwiftBlocks(section, program)) {
|
||||
Address blockAddr = block.getStart();
|
||||
@@ -503,7 +503,7 @@ public class SwiftTypeMetadata {
|
||||
}
|
||||
}
|
||||
catch (IOException e) {
|
||||
log("Failed to parse Swift struction pointers from section '" + section + "'");
|
||||
log("Failed to parse Swift structure pointers from section '" + section + "'");
|
||||
}
|
||||
return result;
|
||||
}
|
||||
@@ -514,27 +514,45 @@ public class SwiftTypeMetadata {
|
||||
* @throws CancelledException if the user cancelled the operation
|
||||
*/
|
||||
public void markup() throws CancelledException {
|
||||
monitor.setMessage("Marking up Swift structures...");
|
||||
monitor.initialize(markupList.size());
|
||||
monitor.initialize(markupList.size(), "Marking up Swift structures...");
|
||||
for (SwiftStructureInfo structInfo : markupList) {
|
||||
monitor.checkCancelled();
|
||||
monitor.incrementProgress(1);
|
||||
monitor.increment();
|
||||
try {
|
||||
SwiftTypeMetadataStructure struct = structInfo.struct();
|
||||
DataType dt = struct.toDataType();
|
||||
DataUtilities.createData(program, structInfo.addr().structAddr(), dt, -1,
|
||||
ClearDataMode.CLEAR_ALL_DEFAULT_CONFLICT_DATA);
|
||||
try {
|
||||
DataUtilities.createData(program, structInfo.addr().structAddr(), dt, -1,
|
||||
ClearDataMode.CLEAR_ALL_DEFAULT_CONFLICT_DATA);
|
||||
}
|
||||
catch (CodeUnitInsertionException e) {
|
||||
// Probably multiple pointers to same structure
|
||||
}
|
||||
for (SwiftTypeMetadataStructure trailingStruct : struct.getTrailingObjects()) {
|
||||
Address trailingAddr = structInfo.addr()
|
||||
.structAddr()
|
||||
.add(trailingStruct.getBase() - struct.getBase());
|
||||
DataType trailingDt = trailingStruct.toDataType();
|
||||
try {
|
||||
DataUtilities.createData(program, trailingAddr, trailingDt, -1,
|
||||
ClearDataMode.CLEAR_ALL_DEFAULT_CONFLICT_DATA);
|
||||
}
|
||||
catch (CodeUnitInsertionException e) {
|
||||
// Probably multiple pointers to same structure
|
||||
}
|
||||
}
|
||||
if (structInfo.addr().pointerAddr() != null) {
|
||||
PointerTypedef relativePtrDataType =
|
||||
new PointerTypedef(null, dt, 4, null, PointerType.RELATIVE);
|
||||
DataUtilities.createData(program, structInfo.addr().pointerAddr(),
|
||||
relativePtrDataType, -1, ClearDataMode.CLEAR_ALL_DEFAULT_CONFLICT_DATA);
|
||||
try {
|
||||
DataUtilities.createData(program, structInfo.addr().pointerAddr(),
|
||||
relativePtrDataType, -1, ClearDataMode.CLEAR_ALL_DEFAULT_CONFLICT_DATA);
|
||||
}
|
||||
catch (CodeUnitInsertionException e) {
|
||||
// Unexpected, but safe to ignore
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (CodeUnitInsertionException e) {
|
||||
// Probably just called more than once
|
||||
}
|
||||
catch (DuplicateNameException | IOException e) {
|
||||
catch (IllegalArgumentException | DuplicateNameException | IOException e) {
|
||||
log("Failed to markup: " + structInfo);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,9 +4,9 @@
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
@@ -15,41 +15,52 @@
|
||||
*/
|
||||
package ghidra.app.util.bin.format.swift;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import ghidra.app.util.bin.StructConverter;
|
||||
import ghidra.program.model.data.CategoryPath;
|
||||
|
||||
/**
|
||||
* Implemented by all Swift type metadata structures
|
||||
*/
|
||||
public abstract class SwiftTypeMetadataStructure implements StructConverter {
|
||||
|
||||
public static final String DATA_TYPE_CATEGORY = "/SwiftTypeMetadata";
|
||||
public static final String CATEGORY = "/SwiftTypeMetadata";
|
||||
public static final CategoryPath CATEGORY_PATH = new CategoryPath(CATEGORY);
|
||||
|
||||
private long base;
|
||||
|
||||
/**
|
||||
* Creates a new {@link SwiftTypeMetadataStructure}
|
||||
*
|
||||
* @param base The base "address" of this {@link SwiftTypeMetadataStructure}
|
||||
*/
|
||||
public SwiftTypeMetadataStructure(long base) {
|
||||
this.base = base;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the base "address" of this {@link SwiftTypeMetadataStructure}
|
||||
*
|
||||
* @return The base "address" of this {@link SwiftTypeMetadataStructure}
|
||||
* {@return the base "address" of this {@link SwiftTypeMetadataStructure}}
|
||||
*/
|
||||
public long getBase() {
|
||||
return base;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the name of the {@link SwiftTypeMetadataStructure}
|
||||
*
|
||||
* @return The name of the {@link SwiftTypeMetadataStructure}
|
||||
* {@return a {@link List} of {@link SwiftTypeMetadataStructure structures} that trail this
|
||||
* {@link SwiftTypeMetadataStructure structure}}
|
||||
*/
|
||||
public List<SwiftTypeMetadataStructure> getTrailingObjects() {
|
||||
return List.of();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@return the name of the {@link SwiftTypeMetadataStructure}}
|
||||
*/
|
||||
public abstract String getStructureName();
|
||||
|
||||
/**
|
||||
* Gets a short description of the {@link SwiftTypeMetadataStructure}
|
||||
*
|
||||
* @return A short description of the {@link SwiftTypeMetadataStructure}
|
||||
* {@return a short description of the {@link SwiftTypeMetadataStructure}}
|
||||
*/
|
||||
public abstract String getDescription();
|
||||
}
|
||||
|
||||
@@ -32,10 +32,21 @@ public class SwiftUtils {
|
||||
public static final String SWIFT_COMPILER = "swift";
|
||||
|
||||
/**
|
||||
* A {@link PointerTypedef pointer} to a relative 4-byte offset
|
||||
* A {@link TypeDef pointer} to a relative 4-byte offset
|
||||
*/
|
||||
public static final PointerTypedef PTR_RELATIVE =
|
||||
new PointerTypedef(null, null, 4, null, PointerType.RELATIVE);
|
||||
public static final TypeDef PTR_RELATIVE =
|
||||
new PointerTypedefBuilder(Pointer32DataType.dataType, null)
|
||||
.type(PointerType.RELATIVE)
|
||||
.build();
|
||||
|
||||
/**
|
||||
* A {@link TypeDef pointer} to a relative 4-byte offset (low bit masked off)
|
||||
*/
|
||||
public static final TypeDef PTR_RELATIVE_MASKED =
|
||||
new PointerTypedefBuilder(Pointer32DataType.dataType, null)
|
||||
.type(PointerType.RELATIVE)
|
||||
.bitMask(~1)
|
||||
.build();
|
||||
|
||||
/**
|
||||
* A {@link PointerTypedef string pointer} to a 4-byte relative offset
|
||||
@@ -44,10 +55,9 @@ public class SwiftUtils {
|
||||
new PointerTypedef(null, StringDataType.dataType, 4, null, PointerType.RELATIVE);
|
||||
|
||||
/**
|
||||
* Checks if the given {@link Program} is a Swift program
|
||||
* {@return true if the given {@link Program} is a Swift program; otherwise, false}
|
||||
*
|
||||
* @param program The {@link Program} to check
|
||||
* @return True if the given {@link Program} is a Swift program; otherwise, false
|
||||
*/
|
||||
public static boolean isSwift(Program program) {
|
||||
List<String> prefixes = List.of("__swift", "swift", ".sw5");
|
||||
@@ -60,11 +70,10 @@ public class SwiftUtils {
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the given {@link List} of section names contains a Swift section name
|
||||
* {@return true if the given {@link List} of section names contains a Swift section name;
|
||||
* otherwise, false}
|
||||
*
|
||||
* @param sectionNames The {@link List} of section names to check
|
||||
* @return True if the given {@link List} of section names contains a Swift section name; otherwise,
|
||||
* false
|
||||
*/
|
||||
public static boolean isSwift(List<String> sectionNames) {
|
||||
List<String> prefixes = List.of("__swift", "swift", ".sw5");
|
||||
@@ -77,11 +86,10 @@ public class SwiftUtils {
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a {@link List} of {@link MemoryBlock}s that match the given {@link SwiftSection}
|
||||
* {@return a {@link List} of {@link MemoryBlock}s that match the given {@link SwiftSection}}
|
||||
*
|
||||
* @param section The {@link SwiftSection}
|
||||
* @param program The {@link Program}
|
||||
* @return A {@link List} of {@link MemoryBlock}s that match the given {@link SwiftSection}
|
||||
*/
|
||||
public static List<MemoryBlock> getSwiftBlocks(SwiftSection section, Program program) {
|
||||
List<MemoryBlock> result = new ArrayList<>();
|
||||
|
||||
@@ -22,11 +22,12 @@ import java.util.List;
|
||||
import ghidra.app.util.bin.BinaryReader;
|
||||
import ghidra.app.util.bin.format.swift.SwiftTypeMetadataStructure;
|
||||
import ghidra.app.util.bin.format.swift.SwiftUtils;
|
||||
import ghidra.program.model.data.*;
|
||||
import ghidra.program.model.data.DataType;
|
||||
import ghidra.program.model.data.StructureDataType;
|
||||
import ghidra.util.exception.DuplicateNameException;
|
||||
|
||||
/**
|
||||
* Represents a Swift AssociatedTypeDescriptor structure
|
||||
* Represents a Swift {@code AssociatedTypeDescriptor} structure
|
||||
*
|
||||
* @see <a href="https://github.com/swiftlang/swift/blob/main/include/swift/RemoteInspection/Records.h">swift/RemoteInspection/Records.h</a>
|
||||
*/
|
||||
@@ -63,45 +64,35 @@ public final class AssociatedTypeDescriptor extends SwiftTypeMetadataStructure {
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the conforming type name
|
||||
*
|
||||
* @return The conforming type name
|
||||
* {@return the conforming type name}
|
||||
*/
|
||||
public String getConformingTypeName() {
|
||||
return conformingTypeName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the protocol type name
|
||||
*
|
||||
* @return The protocol type name
|
||||
* {@return the protocol type name}
|
||||
*/
|
||||
public String getProtocolTypeName() {
|
||||
return protocolTypeName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the number of associated types
|
||||
*
|
||||
* @return The number of associated types
|
||||
* {@return the number of associated types}
|
||||
*/
|
||||
public int getNumAssociatedTypes() {
|
||||
return numAssociatedTypes;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the associated type record size
|
||||
*
|
||||
* @return The associated type record size
|
||||
* {@return the associated type record size}
|
||||
*/
|
||||
public int getAssociatedTypeRecordSize() {
|
||||
return associatedTypeRecordSize;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the {@link List} of {@link AssociatedTypeRecord}s
|
||||
*
|
||||
* @return The {@link List} of {@link AssociatedTypeRecord}s
|
||||
* {@return The {@link List} of {@link AssociatedTypeRecord}s}
|
||||
*/
|
||||
public List<AssociatedTypeRecord> getAssociatedTypeRecords() {
|
||||
return associatedTypeRecords;
|
||||
@@ -119,12 +110,11 @@ public final class AssociatedTypeDescriptor extends SwiftTypeMetadataStructure {
|
||||
|
||||
@Override
|
||||
public DataType toDataType() throws DuplicateNameException, IOException {
|
||||
StructureDataType struct = new StructureDataType(getStructureName(), 0);
|
||||
StructureDataType struct = new StructureDataType(CATEGORY_PATH, getStructureName(), 0);
|
||||
struct.add(SwiftUtils.PTR_STRING, "ConformingTypeName", "");
|
||||
struct.add(SwiftUtils.PTR_STRING, "ProtocolTypeName", "");
|
||||
struct.add(DWORD, "NumAssociatedTypes", "");
|
||||
struct.add(DWORD, "AssociatedTypeRecordSize", "");
|
||||
struct.setCategoryPath(new CategoryPath(DATA_TYPE_CATEGORY));
|
||||
return struct;
|
||||
}
|
||||
|
||||
|
||||
@@ -20,11 +20,12 @@ import java.io.IOException;
|
||||
import ghidra.app.util.bin.BinaryReader;
|
||||
import ghidra.app.util.bin.format.swift.SwiftTypeMetadataStructure;
|
||||
import ghidra.app.util.bin.format.swift.SwiftUtils;
|
||||
import ghidra.program.model.data.*;
|
||||
import ghidra.program.model.data.DataType;
|
||||
import ghidra.program.model.data.StructureDataType;
|
||||
import ghidra.util.exception.DuplicateNameException;
|
||||
|
||||
/**
|
||||
* Represents a Swift AssociatedTypeRecord structure
|
||||
* Represents a Swift {@code AssociatedTypeRecord} structure
|
||||
*
|
||||
* @see <a href="https://github.com/swiftlang/swift/blob/main/include/swift/RemoteInspection/Records.h">swift/RemoteInspection/Records.h</a>
|
||||
*/
|
||||
@@ -51,18 +52,14 @@ public final class AssociatedTypeRecord extends SwiftTypeMetadataStructure {
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the name
|
||||
*
|
||||
* @return The name
|
||||
* {@return the name}
|
||||
*/
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the substituted type name
|
||||
*
|
||||
* @return The substituted type name
|
||||
* {@return the substituted type name}
|
||||
*/
|
||||
public String getSubstitutedTypeName() {
|
||||
return substitutedTypeName;
|
||||
@@ -80,10 +77,9 @@ public final class AssociatedTypeRecord extends SwiftTypeMetadataStructure {
|
||||
|
||||
@Override
|
||||
public DataType toDataType() throws DuplicateNameException, IOException {
|
||||
StructureDataType struct = new StructureDataType(getStructureName(), 0);
|
||||
StructureDataType struct = new StructureDataType(CATEGORY_PATH, getStructureName(), 0);
|
||||
struct.add(SwiftUtils.PTR_STRING, "Name", "");
|
||||
struct.add(SwiftUtils.PTR_STRING, "SubstitutedTypeName", "");
|
||||
struct.setCategoryPath(new CategoryPath(DATA_TYPE_CATEGORY));
|
||||
return struct;
|
||||
}
|
||||
|
||||
|
||||
@@ -20,11 +20,12 @@ import java.io.IOException;
|
||||
import ghidra.app.util.bin.BinaryReader;
|
||||
import ghidra.app.util.bin.format.swift.SwiftTypeMetadataStructure;
|
||||
import ghidra.app.util.bin.format.swift.SwiftUtils;
|
||||
import ghidra.program.model.data.*;
|
||||
import ghidra.program.model.data.DataType;
|
||||
import ghidra.program.model.data.StructureDataType;
|
||||
import ghidra.util.exception.DuplicateNameException;
|
||||
|
||||
/**
|
||||
* Represents a Swift BuiltinTypeDescriptor structure
|
||||
* Represents a Swift {@code BuiltinTypeDescriptor} structure
|
||||
*
|
||||
* @see <a href="https://github.com/swiftlang/swift/blob/main/include/swift/RemoteInspection/Records.h">swift/RemoteInspection/Records.h</a>
|
||||
*/
|
||||
@@ -57,45 +58,35 @@ public final class BuiltinTypeDescriptor extends SwiftTypeMetadataStructure {
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the type name
|
||||
*
|
||||
* @return The type name
|
||||
* {@return the type name}
|
||||
*/
|
||||
public String getTypeName() {
|
||||
return typeName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the size
|
||||
*
|
||||
* @return The size
|
||||
* {@return the size}
|
||||
*/
|
||||
public int getSize() {
|
||||
return size;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the alignment and flags
|
||||
*
|
||||
* @return The alignment and flags
|
||||
* {@return the alignment and flags}
|
||||
*/
|
||||
public int getAlignmentAndFlags() {
|
||||
return alignmentAndFlags;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the stride
|
||||
*
|
||||
* @return The stride
|
||||
* {@return the stride}
|
||||
*/
|
||||
public int getStride() {
|
||||
return stride;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the number of extra inhabitants
|
||||
*
|
||||
* @return The number of extra inhabitants
|
||||
* {@return the number of extra inhabitants}
|
||||
*/
|
||||
public int getNumExtraInhabitants() {
|
||||
return numExtraInhabitants;
|
||||
@@ -113,13 +104,12 @@ public final class BuiltinTypeDescriptor extends SwiftTypeMetadataStructure {
|
||||
|
||||
@Override
|
||||
public DataType toDataType() throws DuplicateNameException, IOException {
|
||||
StructureDataType struct = new StructureDataType(getStructureName(), 0);
|
||||
StructureDataType struct = new StructureDataType(CATEGORY_PATH, getStructureName(), 0);
|
||||
struct.add(SwiftUtils.PTR_STRING, "TypeName", "");
|
||||
struct.add(DWORD, "Size", "");
|
||||
struct.add(DWORD, "AlignmentAndFlags", "");
|
||||
struct.add(DWORD, "Stride", "");
|
||||
struct.add(DWORD, "NumExtraInhabitants", "");
|
||||
struct.setCategoryPath(new CategoryPath(DATA_TYPE_CATEGORY));
|
||||
return struct;
|
||||
}
|
||||
|
||||
|
||||
@@ -21,11 +21,12 @@ import java.util.List;
|
||||
|
||||
import ghidra.app.util.bin.BinaryReader;
|
||||
import ghidra.app.util.bin.format.swift.SwiftTypeMetadataStructure;
|
||||
import ghidra.program.model.data.*;
|
||||
import ghidra.program.model.data.DataType;
|
||||
import ghidra.program.model.data.StructureDataType;
|
||||
import ghidra.util.exception.DuplicateNameException;
|
||||
|
||||
/**
|
||||
* Represents a Swift CaptureDescriptor structure
|
||||
* Represents a Swift {@code CaptureDescriptor} structure
|
||||
*
|
||||
* @see <a href="https://github.com/swiftlang/swift/blob/main/include/swift/RemoteInspection/Records.h">swift/RemoteInspection/Records.h</a>
|
||||
*/
|
||||
@@ -65,45 +66,35 @@ public final class CaptureDescriptor extends SwiftTypeMetadataStructure {
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the number of capture types
|
||||
*
|
||||
* @return The number of capture types
|
||||
* {@return the number of capture types}
|
||||
*/
|
||||
public int getNumCaptureTypes() {
|
||||
return numCaptureTypes;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the number of metadata sources
|
||||
*
|
||||
* @return The number of metadata sources
|
||||
* {@return the number of metadata sources}
|
||||
*/
|
||||
public int getNumMetadataSources() {
|
||||
return numMetadataSources;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the number of bindings
|
||||
*
|
||||
* @return The number of bindings
|
||||
* {@return the number of bindings}
|
||||
*/
|
||||
public int getNumBindings() {
|
||||
return numBindings;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the {@link List} of {@link CaptureTypeRecord}s
|
||||
*
|
||||
* @return The {@link List} of {@link CaptureTypeRecord}s
|
||||
* {@return the {@link List} of {@link CaptureTypeRecord}s}
|
||||
*/
|
||||
public List<CaptureTypeRecord> getCaptureTypeRecords() {
|
||||
return captureTypeRecords;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the {@link List} of {@link MetadataSourceRecord}s
|
||||
*
|
||||
* @return The {@link List} of {@link MetadataSourceRecord}s
|
||||
* {@return the {@link List} of {@link MetadataSourceRecord}s}
|
||||
*/
|
||||
public List<MetadataSourceRecord> getMetadataSourceRecords() {
|
||||
return metadataSourceRecords;
|
||||
@@ -121,11 +112,10 @@ public final class CaptureDescriptor extends SwiftTypeMetadataStructure {
|
||||
|
||||
@Override
|
||||
public DataType toDataType() throws DuplicateNameException, IOException {
|
||||
StructureDataType struct = new StructureDataType(getStructureName(), 0);
|
||||
StructureDataType struct = new StructureDataType(CATEGORY_PATH, getStructureName(), 0);
|
||||
struct.add(DWORD, "NumCaptureTypes", "");
|
||||
struct.add(DWORD, "NumMetadataSources", "");
|
||||
struct.add(DWORD, "NumBindings", "");
|
||||
struct.setCategoryPath(new CategoryPath(DATA_TYPE_CATEGORY));
|
||||
return struct;
|
||||
}
|
||||
|
||||
|
||||
@@ -20,11 +20,12 @@ import java.io.IOException;
|
||||
import ghidra.app.util.bin.BinaryReader;
|
||||
import ghidra.app.util.bin.format.swift.SwiftTypeMetadataStructure;
|
||||
import ghidra.app.util.bin.format.swift.SwiftUtils;
|
||||
import ghidra.program.model.data.*;
|
||||
import ghidra.program.model.data.DataType;
|
||||
import ghidra.program.model.data.StructureDataType;
|
||||
import ghidra.util.exception.DuplicateNameException;
|
||||
|
||||
/**
|
||||
* Represents a Swift CaptureTypeRecord structure
|
||||
* Represents a Swift {@code CaptureTypeRecord} structure
|
||||
*
|
||||
* @see <a href="https://github.com/swiftlang/swift/blob/main/include/swift/RemoteInspection/Records.h">swift/RemoteInspection/Records.h</a>
|
||||
*/
|
||||
@@ -50,9 +51,7 @@ public final class CaptureTypeRecord extends SwiftTypeMetadataStructure {
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the mangled type name
|
||||
*
|
||||
* @return The mangled type name
|
||||
* {@return the mangled type name}
|
||||
*/
|
||||
public String getMangledTypeName() {
|
||||
return mangledTypeName;
|
||||
@@ -70,9 +69,8 @@ public final class CaptureTypeRecord extends SwiftTypeMetadataStructure {
|
||||
|
||||
@Override
|
||||
public DataType toDataType() throws DuplicateNameException, IOException {
|
||||
StructureDataType struct = new StructureDataType(getStructureName(), 0);
|
||||
StructureDataType struct = new StructureDataType(CATEGORY_PATH, getStructureName(), 0);
|
||||
struct.add(SwiftUtils.PTR_STRING, "MangledTypeName", "");
|
||||
struct.setCategoryPath(new CategoryPath(DATA_TYPE_CATEGORY));
|
||||
return struct;
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,153 @@
|
||||
/* ###
|
||||
* IP: GHIDRA
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package ghidra.app.util.bin.format.swift.types;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import ghidra.app.util.bin.BinaryReader;
|
||||
import ghidra.app.util.bin.format.swift.SwiftTypeMetadataStructure;
|
||||
import ghidra.program.model.data.*;
|
||||
import ghidra.util.exception.DuplicateNameException;
|
||||
|
||||
/**
|
||||
* Represents a Swift {@code ConformanceFlags} structure
|
||||
*
|
||||
* @see <a href="https://github.com/swiftlang/swift/blob/main/include/swift/ABI/MetadataValues.h">swift/ABI/MetadataValues.h</a>
|
||||
*/
|
||||
public class ConformanceFlags extends SwiftTypeMetadataStructure {
|
||||
|
||||
/**
|
||||
* The size (in bytes) of a {@link ConformanceFlags} structure
|
||||
*/
|
||||
public static final int SIZE = 4;
|
||||
|
||||
private int flags;
|
||||
|
||||
/**
|
||||
* Create a new {@link ConformanceFlags}
|
||||
*
|
||||
* @param reader A {@link BinaryReader} positioned at the start of the structure
|
||||
* @throws IOException if there was an IO-related problem creating the structure
|
||||
*/
|
||||
public ConformanceFlags(BinaryReader reader) throws IOException {
|
||||
super(reader.getPointerIndex());
|
||||
flags = reader.readNextInt();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@return the flags}
|
||||
*/
|
||||
public int getFlags() {
|
||||
return flags;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@return the {@link TypeReferenceKind}}
|
||||
*/
|
||||
public TypeReferenceKind getKind() {
|
||||
return TypeReferenceKind.valueOf((flags >> 3) & 0x3);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@return whether or not it is retroactive}
|
||||
*/
|
||||
public boolean isRetroactive() {
|
||||
return ((flags >> 6) & 0x1) != 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@return whether or not it is synthesized non-unique}
|
||||
*/
|
||||
public boolean isSynthesizedNonUnique() {
|
||||
return ((flags >> 7) & 0x1) != 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@return the number of conditional requirements}
|
||||
*/
|
||||
public int getNumConditionalRequirements() {
|
||||
return (flags >> 8) & 0x8;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@return whether or not it has resilient witnesses}
|
||||
*/
|
||||
public boolean hasResilientWitnesses() {
|
||||
return ((flags >> 16) & 0x1) != 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@return whether or not it a generic witness table}
|
||||
*/
|
||||
public boolean hasGenericWitnessTable() {
|
||||
return ((flags >> 17) & 0x1) != 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@return whether or not it is conformance of protocol}
|
||||
*/
|
||||
public boolean isConformanceOfProtocol() {
|
||||
return ((flags >> 18) & 0x1) != 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@return whether or not it has global actor isolation}
|
||||
*/
|
||||
public boolean hasGlobalActorIsolation() {
|
||||
return ((flags >> 19) & 0x1) != 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@return the number of conditional pack descriptors}
|
||||
*/
|
||||
public int getNumConditionalPackDescriptor() {
|
||||
return (flags >> 24) & 0x8;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getStructureName() {
|
||||
return ConformanceFlags.class.getSimpleName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDescription() {
|
||||
return "conformance flags";
|
||||
}
|
||||
|
||||
@Override
|
||||
public DataType toDataType() throws DuplicateNameException, IOException {
|
||||
StructureDataType struct = new StructureDataType(CATEGORY_PATH, getStructureName(), SIZE);
|
||||
struct.setPackingEnabled(true);
|
||||
try {
|
||||
struct.addBitField(DWORD, 3, "UnusedLowBits", "historical conformance kind");
|
||||
struct.addBitField(getKind().toDataType(), 3, "TypeMetadataKind",
|
||||
"8 type reference kinds");
|
||||
struct.addBitField(BOOL, 1, "IsRetroactive", null);
|
||||
struct.addBitField(BOOL, 1, "IsSynthesizedNonUnique", null);
|
||||
struct.addBitField(DWORD, 8, "NumConditionalRequirements", null);
|
||||
struct.addBitField(BOOL, 1, "HasResilientWitnesses", null);
|
||||
struct.addBitField(BOOL, 1, "HasGenericWitnessTable", null);
|
||||
struct.addBitField(BOOL, 1, "IsConformanceOfProtocol", null);
|
||||
struct.addBitField(BOOL, 1, "HasGlobalActorIsolation", null);
|
||||
struct.addBitField(DWORD, 4, "reserved", null);
|
||||
struct.addBitField(DWORD, 8, "NumConditionalPackDescriptor", null);
|
||||
}
|
||||
catch (InvalidDataTypeException e) {
|
||||
throw new IOException(e);
|
||||
}
|
||||
return struct;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,231 @@
|
||||
/* ###
|
||||
* IP: GHIDRA
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package ghidra.app.util.bin.format.swift.types;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import ghidra.app.util.bin.BinaryReader;
|
||||
import ghidra.app.util.bin.format.swift.SwiftTypeMetadataStructure;
|
||||
import ghidra.program.model.data.*;
|
||||
import ghidra.util.exception.DuplicateNameException;
|
||||
|
||||
/**
|
||||
* Represents a Swift {@code ContextDescriptorFlags} structure
|
||||
*
|
||||
* @see <a href="https://github.com/swiftlang/swift/blob/main/include/swift/ABI/MetadataValues.h">swift/ABI/MetadataValues.h</a>
|
||||
*/
|
||||
public class ContextDescriptorFlags extends SwiftTypeMetadataStructure {
|
||||
|
||||
/**
|
||||
* The size (in bytes) of a {@link ContextDescriptorFlags} structure
|
||||
*/
|
||||
public static final int SIZE = 4;
|
||||
|
||||
private int flags;
|
||||
|
||||
/**
|
||||
* Create a new {@link ContextDescriptorFlags}
|
||||
*
|
||||
* @param reader A {@link BinaryReader} positioned at the start of the structure
|
||||
* @throws IOException if there was an IO-related problem creating the structure
|
||||
*/
|
||||
public ContextDescriptorFlags(BinaryReader reader) throws IOException {
|
||||
super(reader.getPointerIndex());
|
||||
flags = reader.readNextInt();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@return the flags}
|
||||
*/
|
||||
public int getFlags() {
|
||||
return flags;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@return the {@link ContextDescriptorKind}}
|
||||
*/
|
||||
public ContextDescriptorKind getKind() {
|
||||
return ContextDescriptorKind.valueOf(flags & 0x1f);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@return whether or not the context has information about invertable protocols, which will
|
||||
* show up as a trailing field in the context descriptor}
|
||||
*/
|
||||
public boolean hasInvertableProtocols() {
|
||||
return (flags & 0x20) != 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@return whether this is a unique record describing the referenced context}
|
||||
*/
|
||||
public boolean isUnique() {
|
||||
return (flags & 0x40) != 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@return whether the context being described is generic}
|
||||
*/
|
||||
public boolean isGeneric() {
|
||||
return (flags & 0x80) != 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@return whether there's something unusual about how the metadata is initialized}
|
||||
*/
|
||||
public MetadataInitializationKind getMetadataInitialization() {
|
||||
return MetadataInitializationKind.valueOf((flags >> 16) & 0x3);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@return whether or not the type has extended import information}
|
||||
*/
|
||||
public boolean hasImportInfo() {
|
||||
return ((flags >> 18) & 0x1) != 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@return whether or not the generic type descriptor has a pointer to a list of canonical
|
||||
* prespecializations, or the non-generic type descriptor has a pointer to its singleton
|
||||
* metadata}
|
||||
*/
|
||||
public boolean hasCanonicalMetadataPrespecializationsOrSingletonMetadataPonter() {
|
||||
return ((flags >> 19) & 0x1) != 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@return whether or not the metadata contains a pointer to a layout string}
|
||||
*/
|
||||
public boolean hasLayoutString() {
|
||||
return ((flags >> 20) & 0x1) != 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@return whether or not the class has a default override table}
|
||||
*/
|
||||
public boolean hasClassDefaultOverrideTable() {
|
||||
return ((flags >> 22) & 0x1) != 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@return whether or not the class is an actor}
|
||||
*/
|
||||
public boolean isClassActor() {
|
||||
return ((flags >> 23) & 0x1) != 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@return whether or not the class is a default actor}
|
||||
*/
|
||||
public boolean isClassDefaultActor() {
|
||||
return ((flags >> 24) & 0x1) != 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@return the kind of reference that this class makes to its resilient superclass descriptor.
|
||||
* A TypeReferenceKind.}
|
||||
*/
|
||||
public int getClassResilientSuperclassReferenceKind() {
|
||||
return (flags >> 25) & 0x7;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@return whether the immediate class members in this metadata are allocated at negative
|
||||
* offsets}
|
||||
*/
|
||||
public boolean areClassImmediateMembersNegative() {
|
||||
return ((flags >> 28) & 0x1) != 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@return Whether or not the context descriptor is for a class with resilient ancestry}
|
||||
*/
|
||||
public boolean hasClassResilientSuperclass() {
|
||||
return ((flags >> 29) & 0x1) != 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@return whether or not the context descriptor includes metadata for dynamically installing
|
||||
* method overrides at metadata instantiation time}
|
||||
*/
|
||||
public boolean hasClassOverrideTable() {
|
||||
return ((flags >> 30) & 0x1) != 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@return whether or not the context descriptor includes metadata for dynamically constructing
|
||||
* a class's vtables at metadata instantiation time}
|
||||
*/
|
||||
public boolean hasClassVTable() {
|
||||
return ((flags >> 31) & 0x1) != 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getStructureName() {
|
||||
return ContextDescriptorFlags.class.getSimpleName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDescription() {
|
||||
return "context descriptor flags";
|
||||
}
|
||||
|
||||
@Override
|
||||
public DataType toDataType() throws DuplicateNameException, IOException {
|
||||
StructureDataType struct = new StructureDataType(CATEGORY_PATH, getStructureName(), SIZE);
|
||||
struct.setPackingEnabled(true);
|
||||
try {
|
||||
struct.addBitField(ContextDescriptorKind.values()[0].toDataType(), 5, "kind",
|
||||
"Kind of context descriptor");
|
||||
struct.addBitField(BOOL, 1, "hasInvertableProtocols",
|
||||
"Whether or not the context has information about invertable protocols, which will show up as a trailing field in the context descriptor.");
|
||||
struct.addBitField(BOOL, 1, "isUnique",
|
||||
"Whether this is a unique record describing the referenced context.");
|
||||
struct.addBitField(BOOL, 1, "isGeneric",
|
||||
"Whether the context being described is generic.");
|
||||
struct.addBitField(DWORD, 8, "reserved", null);
|
||||
struct.addBitField(MetadataInitializationKind.values()[0].toDataType(), 2,
|
||||
"MetadataInitialization",
|
||||
"Whether there's something unusual about how the metadata is initialized.");
|
||||
struct.addBitField(BOOL, 1, "HasImportInfo",
|
||||
"Set if the type has extended import information.");
|
||||
struct.addBitField(BOOL, 1,
|
||||
"HasCanonicalMetadataPrespecializationsOrSingletonMetadataPonter",
|
||||
"Set if the generic type descriptor has a pointer to a list of canonical prespecializations, or the non-generic type descriptor has a pointer to its singleton metadata.");
|
||||
struct.addBitField(BOOL, 1, "HasLayoutString",
|
||||
"Set if the metadata contains a pointer to a layout string.");
|
||||
struct.addBitField(DWORD, 1, "reserved", null);
|
||||
struct.addBitField(BOOL, 1, "Class_HasDefaultOverrideTable", null);
|
||||
struct.addBitField(BOOL, 1, "Class_IsActor", "Set if the class is an actor.");
|
||||
struct.addBitField(BOOL, 1, "Class_IsDefaultActor",
|
||||
"Set if the class is a default actor class.");
|
||||
struct.addBitField(DWORD, 3, "Class_ResilientSuperclassReferenceKind",
|
||||
"The kind of reference that this class makes to its resilient superclass descriptor. A TypeReferenceKind.");
|
||||
struct.addBitField(BOOL, 1, "Class_AreImmediateMembersNegative",
|
||||
"Whether the immediate class members in this metadata are allocated at negative offsets.");
|
||||
struct.addBitField(BOOL, 1, "Class_HasResilientSuperclass",
|
||||
"Set if the context descriptor is for a class with resilient ancestry.");
|
||||
struct.addBitField(BOOL, 1, "Class_HasOverrideTable",
|
||||
"Set if the context descriptor includes metadata for dynamically installing method overrides at metadata instantiation time.");
|
||||
struct.addBitField(BOOL, 1, "Class_HasVTable",
|
||||
"Set if the context descriptor includes metadata for dynamically constructing a class's vtables at metadata instantiation time.");
|
||||
}
|
||||
catch (InvalidDataTypeException e) {
|
||||
throw new IOException(e);
|
||||
}
|
||||
return struct;
|
||||
}
|
||||
}
|
||||
@@ -15,80 +15,98 @@
|
||||
*/
|
||||
package ghidra.app.util.bin.format.swift.types;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Arrays;
|
||||
|
||||
import ghidra.app.util.bin.StructConverter;
|
||||
import ghidra.app.util.bin.format.swift.SwiftTypeMetadataStructure;
|
||||
import ghidra.program.model.data.DataType;
|
||||
import ghidra.program.model.data.EnumDataType;
|
||||
import ghidra.util.exception.DuplicateNameException;
|
||||
|
||||
/**
|
||||
* Swift ContextDescriptorKind values
|
||||
* Swift {@code ContextDescriptorKind} values
|
||||
*
|
||||
* @see <a href="https://github.com/swiftlang/swift/blob/main/include/swift/ABI/MetadataValues.h">swift/ABI/MetadataValues.h</a>
|
||||
*/
|
||||
public class ContextDescriptorKind {
|
||||
|
||||
/**
|
||||
* The mask to apply to the {@link TargetContextDescriptor#getFlags() flags} to get the
|
||||
* {@link ContextDescriptorKind} value
|
||||
*/
|
||||
private static int KIND_MASK = 0x1f;
|
||||
|
||||
/**
|
||||
* Gets the {@link ContextDescriptorKind} value from the
|
||||
* {@link TargetContextDescriptor#getFlags() flags}
|
||||
*
|
||||
* @param flags The {@link TargetContextDescriptor#getFlags() flags} that contain the kind
|
||||
* @return The {@link ContextDescriptorKind} value
|
||||
*/
|
||||
public static int getKind(int flags) {
|
||||
return flags & KIND_MASK;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------
|
||||
|
||||
public enum ContextDescriptorKind implements StructConverter {
|
||||
|
||||
/**
|
||||
* This context descriptor represents a module
|
||||
*/
|
||||
public static final int MODULE = 0;
|
||||
Module(0),
|
||||
|
||||
/**
|
||||
* This context descriptor represents an extension
|
||||
*/
|
||||
public static final int EXTENSION = 1;
|
||||
Extension(1),
|
||||
|
||||
/**
|
||||
* This context descriptor represents an anonymous possibly-generic context such as a function
|
||||
* body
|
||||
*/
|
||||
public static final int ANONYMOUS = 2;
|
||||
Anonymous(2),
|
||||
|
||||
/**
|
||||
* This context descriptor represents a protocol context
|
||||
*/
|
||||
public static final int PROTOCOL = 3;
|
||||
Protocol(3),
|
||||
|
||||
/**
|
||||
* This context descriptor represents an opaque type alias
|
||||
*/
|
||||
public static final int OPAQUE_TYPE = 4;
|
||||
|
||||
/**
|
||||
* First kind that represents a type of any sort
|
||||
*/
|
||||
public static final int TYPE_FIRST = 16;
|
||||
OpaqueType(4),
|
||||
|
||||
/**
|
||||
* This context descriptor represents a class
|
||||
*/
|
||||
public static final int CLASS = TYPE_FIRST;
|
||||
Class(16),
|
||||
|
||||
/**
|
||||
* This context descriptor represents a struct
|
||||
*/
|
||||
public static final int STRUCT = TYPE_FIRST + 1;
|
||||
Struct(17),
|
||||
|
||||
/**
|
||||
* This context descriptor represents an enum
|
||||
*/
|
||||
public static final int ENUM = TYPE_FIRST + 2;
|
||||
Enum(18);
|
||||
|
||||
private int value;
|
||||
|
||||
/**
|
||||
* Last kind that represents a type of any sort
|
||||
* Creates a new {@link ContextDescriptorKind}
|
||||
*
|
||||
* @param value The kind value
|
||||
*/
|
||||
public static final int TYPE_LAST = 31;
|
||||
private ContextDescriptorKind(int value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@return the kind value}
|
||||
*/
|
||||
public int getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@return the {@link ContextDescriptorKind} with the given kind value, or {@code null} if it
|
||||
* does not exist}
|
||||
*
|
||||
* @param value The kind value to get the value of
|
||||
*/
|
||||
public static ContextDescriptorKind valueOf(int value) {
|
||||
return Arrays.stream(values()).filter(e -> e.getValue() == value).findFirst().orElse(null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public DataType toDataType() throws DuplicateNameException, IOException {
|
||||
EnumDataType dt = new EnumDataType(SwiftTypeMetadataStructure.CATEGORY_PATH,
|
||||
ContextDescriptorKind.class.getSimpleName(), 1);
|
||||
for (ContextDescriptorKind kind : values()) {
|
||||
dt.add(kind.name(), kind.getValue());
|
||||
}
|
||||
return dt;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,9 +4,9 @@
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
@@ -47,9 +47,7 @@ public final class EntryPoint extends SwiftTypeMetadataStructure {
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the entry point
|
||||
*
|
||||
* @return The entry point
|
||||
* {@return the entry point}
|
||||
*/
|
||||
public int getEntryPoint() {
|
||||
return entryPoint;
|
||||
|
||||
@@ -0,0 +1,90 @@
|
||||
/* ###
|
||||
* IP: GHIDRA
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package ghidra.app.util.bin.format.swift.types;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import ghidra.app.util.bin.BinaryReader;
|
||||
import ghidra.app.util.bin.format.swift.SwiftTypeMetadataStructure;
|
||||
import ghidra.program.model.data.*;
|
||||
import ghidra.util.exception.DuplicateNameException;
|
||||
|
||||
/**
|
||||
* Represents a Swift {@code ExtraClassDescriptorFlags} enum
|
||||
*
|
||||
* @see <a href="https://github.com/swiftlang/swift/blob/main/include/swift/ABI/MetadataValues.h">swift/ABI/MetadataValues.h</a>
|
||||
*/
|
||||
public class ExtraClassDescriptorFlags extends SwiftTypeMetadataStructure {
|
||||
|
||||
/**
|
||||
* The size (in bytes) of a {@link ExtraClassDescriptorFlags} structure
|
||||
*/
|
||||
public static final int SIZE = 4;
|
||||
|
||||
private int flags;
|
||||
|
||||
/**
|
||||
* Creates a new {@link ExtraClassDescriptorFlags}
|
||||
*
|
||||
* @param reader A {@link BinaryReader} positioned at the start of the structure
|
||||
* @throws IOException if there was an IO-related problem creating the structure
|
||||
*/
|
||||
public ExtraClassDescriptorFlags(BinaryReader reader) throws IOException {
|
||||
super(reader.getPointerIndex());
|
||||
flags = reader.readNextInt();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@return the flags}
|
||||
*/
|
||||
public int getFlags() {
|
||||
return flags;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@return whether or not the context descriptor includes a pointer to an Objective-C resilient class stub structure}
|
||||
* <p>
|
||||
* Only meaningful for class descriptors when Objective-C interop is enabled.
|
||||
*/
|
||||
public boolean hasObjcResilientClassStub() {
|
||||
return (flags & 0x1) != 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getStructureName() {
|
||||
return ExtraClassDescriptorFlags.class.getSimpleName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDescription() {
|
||||
return "extra class descriptor flags";
|
||||
}
|
||||
|
||||
@Override
|
||||
public DataType toDataType() throws DuplicateNameException, IOException {
|
||||
StructureDataType struct = new StructureDataType(CATEGORY_PATH, getStructureName(), SIZE);
|
||||
struct.setPackingEnabled(true);
|
||||
try {
|
||||
struct.addBitField(BOOL, 1, "HasObjCResilientClassStub",
|
||||
"Set if the context descriptor includes a pointer to an Objective-C resilient class stub structure. Only meaningful for class descriptors when Objective-C interop is enabled.");
|
||||
struct.addBitField(DWORD, 31, "reserved", null);
|
||||
}
|
||||
catch (InvalidDataTypeException e) {
|
||||
throw new IOException(e);
|
||||
}
|
||||
return struct;
|
||||
}
|
||||
}
|
||||
@@ -22,11 +22,12 @@ import java.util.List;
|
||||
import ghidra.app.util.bin.BinaryReader;
|
||||
import ghidra.app.util.bin.format.swift.SwiftTypeMetadataStructure;
|
||||
import ghidra.app.util.bin.format.swift.SwiftUtils;
|
||||
import ghidra.program.model.data.*;
|
||||
import ghidra.program.model.data.DataType;
|
||||
import ghidra.program.model.data.StructureDataType;
|
||||
import ghidra.util.exception.DuplicateNameException;
|
||||
|
||||
/**
|
||||
* Represents a Swift FieldDescriptor structure
|
||||
* Represents a Swift {@code FieldDescriptor} structure
|
||||
*
|
||||
* @see <a href="https://github.com/swiftlang/swift/blob/main/include/swift/RemoteInspection/Records.h">swift/RemoteInspection/Records.h</a>
|
||||
*/
|
||||
@@ -65,54 +66,42 @@ public final class FieldDescriptor extends SwiftTypeMetadataStructure {
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the mangled type name
|
||||
*
|
||||
* @return The mangled type name
|
||||
* {@return the mangled type name}
|
||||
*/
|
||||
public String getMangledTypeName() {
|
||||
return mangledTypeName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the superclass
|
||||
*
|
||||
* @return The superclass
|
||||
* {@return the superclass}
|
||||
*/
|
||||
public int getSuperclass() {
|
||||
return superclass;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the kind
|
||||
*
|
||||
* @return The kind
|
||||
* {@return the kind}
|
||||
*/
|
||||
public int getKind() {
|
||||
return kind;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the field record size
|
||||
*
|
||||
* @return The field record size
|
||||
* {@return the field record size}
|
||||
*/
|
||||
public int getFieldRecordSize() {
|
||||
return fieldRecordSize;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the number of fields
|
||||
*
|
||||
* @return The number of fields
|
||||
* {@return the number of fields}
|
||||
*/
|
||||
public int getNumFields() {
|
||||
return numFields;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the {@link List} of {@link FieldRecord}s
|
||||
*
|
||||
* @return The {@link List} of {@link FieldRecord}s
|
||||
* {@return the {@link List} of {@link FieldRecord}s}
|
||||
*/
|
||||
public List<FieldRecord> getFieldRecords() {
|
||||
return fieldRecords;
|
||||
@@ -130,13 +119,12 @@ public final class FieldDescriptor extends SwiftTypeMetadataStructure {
|
||||
|
||||
@Override
|
||||
public DataType toDataType() throws DuplicateNameException, IOException {
|
||||
StructureDataType struct = new StructureDataType(getStructureName(), 0);
|
||||
StructureDataType struct = new StructureDataType(CATEGORY_PATH, getStructureName(), 0);
|
||||
struct.add(SwiftUtils.PTR_STRING, "MangledTypeName", "");
|
||||
struct.add(SwiftUtils.PTR_RELATIVE, "Superclass", "");
|
||||
struct.add(WORD, "Kind", "");
|
||||
struct.add(WORD, "FieldRecordSize", "");
|
||||
struct.add(DWORD, "NumFields", "");
|
||||
struct.setCategoryPath(new CategoryPath(DATA_TYPE_CATEGORY));
|
||||
return struct;
|
||||
}
|
||||
|
||||
|
||||
@@ -20,11 +20,12 @@ import java.io.IOException;
|
||||
import ghidra.app.util.bin.BinaryReader;
|
||||
import ghidra.app.util.bin.format.swift.SwiftTypeMetadataStructure;
|
||||
import ghidra.app.util.bin.format.swift.SwiftUtils;
|
||||
import ghidra.program.model.data.*;
|
||||
import ghidra.program.model.data.DataType;
|
||||
import ghidra.program.model.data.StructureDataType;
|
||||
import ghidra.util.exception.DuplicateNameException;
|
||||
|
||||
/**
|
||||
* Represents a Swift FieldRecord structure
|
||||
* Represents a Swift {@code FieldRecord} structure
|
||||
*
|
||||
* @see <a href="https://github.com/swiftlang/swift/blob/main/include/swift/RemoteInspection/Records.h">swift/RemoteInspection/Records.h</a>
|
||||
*/
|
||||
@@ -53,27 +54,21 @@ public final class FieldRecord extends SwiftTypeMetadataStructure {
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the flags
|
||||
*
|
||||
* @return The flags
|
||||
* {@return the flags}
|
||||
*/
|
||||
public int getFlags() {
|
||||
return flags;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the mangled type name
|
||||
*
|
||||
* @return The mangled type name
|
||||
* {@return the mangled type name}
|
||||
*/
|
||||
public String getMangledTypeName() {
|
||||
return mangledTypeName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the field name
|
||||
*
|
||||
* @return The field name
|
||||
* {@return the field name}
|
||||
*/
|
||||
public String getFieldName() {
|
||||
return fieldName;
|
||||
@@ -91,11 +86,10 @@ public final class FieldRecord extends SwiftTypeMetadataStructure {
|
||||
|
||||
@Override
|
||||
public DataType toDataType() throws DuplicateNameException, IOException {
|
||||
StructureDataType struct = new StructureDataType(getStructureName(), 0);
|
||||
StructureDataType struct = new StructureDataType(CATEGORY_PATH, getStructureName(), 0);
|
||||
struct.add(DWORD, "Flags", "");
|
||||
struct.add(SwiftUtils.PTR_STRING, "MangledTypeName", "");
|
||||
struct.add(SwiftUtils.PTR_STRING, "FieldName", "");
|
||||
struct.setCategoryPath(new CategoryPath(DATA_TYPE_CATEGORY));
|
||||
return struct;
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,110 @@
|
||||
/* ###
|
||||
* IP: GHIDRA
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package ghidra.app.util.bin.format.swift.types;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import ghidra.app.util.bin.BinaryReader;
|
||||
import ghidra.app.util.bin.format.swift.SwiftTypeMetadataStructure;
|
||||
import ghidra.program.model.data.*;
|
||||
import ghidra.util.exception.DuplicateNameException;
|
||||
|
||||
/**
|
||||
* Represents a Swift {@code GenericRequirementFlags} structure
|
||||
*
|
||||
* @see <a href="https://github.com/swiftlang/swift/blob/main/include/swift/ABI/MetadataValues.h">swift/ABI/MetadataValues.h</a>
|
||||
*/
|
||||
public class GenericContextDescriptorFlags extends SwiftTypeMetadataStructure {
|
||||
|
||||
/**
|
||||
* The size (in bytes) of a {@link GenericContextDescriptorFlags} structure
|
||||
*/
|
||||
public static final int SIZE = 2;
|
||||
|
||||
private short flags;
|
||||
|
||||
/**
|
||||
* Create a new {@link GenericContextDescriptorFlags}
|
||||
*
|
||||
* @param reader A {@link BinaryReader} positioned at the start of the structure
|
||||
* @throws IOException if there was an IO-related problem creating the structure
|
||||
*/
|
||||
public GenericContextDescriptorFlags(BinaryReader reader) throws IOException {
|
||||
super(reader.getPointerIndex());
|
||||
flags = reader.readNextShort();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@return the flags}
|
||||
*/
|
||||
public short getFlags() {
|
||||
return flags;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@return whether or not the generic context has at least one type parameter pack, in which
|
||||
* case the generic context will have a trailing GenericPackShapeHeader}
|
||||
*/
|
||||
public boolean hasTypePacks() {
|
||||
return (flags & 0x1) != 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@return whether or not the generic context has any conditional conformances to inverted
|
||||
* protocols, in which case the generic context will have a trailing InvertibleProtocolSet and
|
||||
* conditional requirements}
|
||||
*/
|
||||
public boolean hasConditionalInvertedProtocols() {
|
||||
return (flags & 0x2) != 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@return whether or not the generic context has at least one value parameter, in which case
|
||||
* the generic context will have a trailing GenericValueHeader}
|
||||
*/
|
||||
public boolean hasValues() {
|
||||
return (flags & 0x4) != 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getStructureName() {
|
||||
return GenericContextDescriptorFlags.class.getSimpleName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDescription() {
|
||||
return "generic context descriptor flags";
|
||||
}
|
||||
|
||||
@Override
|
||||
public DataType toDataType() throws DuplicateNameException, IOException {
|
||||
StructureDataType struct = new StructureDataType(CATEGORY_PATH, getStructureName(), SIZE);
|
||||
struct.setPackingEnabled(true);
|
||||
try {
|
||||
struct.addBitField(BOOL, 1, "TypePacks",
|
||||
"Has at least one type parameter pack and a trailing GenericPackShapeHeader.");
|
||||
struct.addBitField(BOOL, 1, "ConditionalInvertedProtocols",
|
||||
"Has any conditional conformances to inverted protocols and a trailing InvertibleProtocolSet and conditional requirements.");
|
||||
struct.addBitField(BOOL, 1, "Values",
|
||||
"Has at least one value parameter, and a trailing GenericValueHeader.");
|
||||
struct.addBitField(WORD, 13, "reserved", null);
|
||||
}
|
||||
catch (InvalidDataTypeException e) {
|
||||
throw new IOException(e);
|
||||
}
|
||||
return struct;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,94 @@
|
||||
/* ###
|
||||
* IP: GHIDRA
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package ghidra.app.util.bin.format.swift.types;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import ghidra.app.util.bin.BinaryReader;
|
||||
import ghidra.app.util.bin.format.swift.SwiftTypeMetadataStructure;
|
||||
import ghidra.program.model.data.*;
|
||||
import ghidra.util.exception.DuplicateNameException;
|
||||
|
||||
/**
|
||||
* Represents a Swift {@code GenericParamDescriptor} structure
|
||||
*
|
||||
* @see <a href="https://github.com/swiftlang/swift/blob/main/include/swift/ABI/MetadataValues.h">swift/ABI/MetadataValues.h</a>
|
||||
*/
|
||||
public class GenericParamDescriptor extends SwiftTypeMetadataStructure {
|
||||
|
||||
/**
|
||||
* The size (in bytes) of a {@link GenericParamDescriptor} structure
|
||||
*/
|
||||
public static final int SIZE = 1;
|
||||
|
||||
private int value;
|
||||
|
||||
/**
|
||||
* Create a new {@link GenericParamDescriptor}
|
||||
*
|
||||
* @param reader A {@link BinaryReader} positioned at the start of the structure
|
||||
* @throws IOException if there was an IO-related problem creating the structure
|
||||
*/
|
||||
public GenericParamDescriptor(BinaryReader reader) throws IOException {
|
||||
super(reader.getPointerIndex());
|
||||
value = reader.readNextUnsignedByte();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@return the value}
|
||||
*/
|
||||
public int getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@return the {@link GenericParamKind}}
|
||||
*/
|
||||
public GenericParamKind getKind() {
|
||||
return GenericParamKind.valueOf(value & 0x3f);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@return whether or not the subject type of the requirement has a key argument}
|
||||
*/
|
||||
public boolean hasKeyArgument() {
|
||||
return (value & 0x80) != 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getStructureName() {
|
||||
return GenericParamDescriptor.class.getSimpleName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDescription() {
|
||||
return "generic param descriptor";
|
||||
}
|
||||
|
||||
@Override
|
||||
public DataType toDataType() throws DuplicateNameException, IOException {
|
||||
StructureDataType struct = new StructureDataType(CATEGORY_PATH, getStructureName(), SIZE);
|
||||
struct.setPackingEnabled(true);
|
||||
try {
|
||||
struct.addBitField(GenericParamKind.values()[0].toDataType(), 7, "kind", null);
|
||||
struct.addBitField(BOOL, 1, "HasKeyArgument", null);
|
||||
}
|
||||
catch (InvalidDataTypeException e) {
|
||||
throw new IOException(e);
|
||||
}
|
||||
return struct;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,75 @@
|
||||
/* ###
|
||||
* IP: GHIDRA
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package ghidra.app.util.bin.format.swift.types;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Arrays;
|
||||
|
||||
import ghidra.app.util.bin.StructConverter;
|
||||
import ghidra.app.util.bin.format.swift.SwiftTypeMetadataStructure;
|
||||
import ghidra.program.model.data.DataType;
|
||||
import ghidra.program.model.data.EnumDataType;
|
||||
import ghidra.util.exception.DuplicateNameException;
|
||||
|
||||
/**
|
||||
* Swift {@code GenericParamKind} values
|
||||
*
|
||||
* @see <a href="https://github.com/swiftlang/swift/blob/main/include/swift/ABI/MetadataValues.h">swift/ABI/MetadataValues.h</a>
|
||||
*/
|
||||
public enum GenericParamKind implements StructConverter {
|
||||
|
||||
Type(0),
|
||||
TypePack(1),
|
||||
Value(2);
|
||||
|
||||
private int value;
|
||||
|
||||
/**
|
||||
* Creates a new {@link GenericRequirementKind}
|
||||
*
|
||||
* @param value The kind value
|
||||
*/
|
||||
private GenericParamKind(int value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@return the kind value}
|
||||
*/
|
||||
public int getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@return the {@link GenericParamKind} with the given kind value, or {@code null} if it
|
||||
* does not exist}
|
||||
*
|
||||
* @param value The kind value to get the value of
|
||||
*/
|
||||
public static GenericParamKind valueOf(int value) {
|
||||
return Arrays.stream(values()).filter(e -> e.getValue() == value).findFirst().orElse(null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public DataType toDataType() throws DuplicateNameException, IOException {
|
||||
EnumDataType dt = new EnumDataType(SwiftTypeMetadataStructure.CATEGORY_PATH,
|
||||
GenericParamKind.class.getSimpleName(), 1);
|
||||
for (GenericParamKind kind : values()) {
|
||||
dt.add(kind.name(), kind.getValue());
|
||||
}
|
||||
return dt;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,115 @@
|
||||
/* ###
|
||||
* IP: GHIDRA
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package ghidra.app.util.bin.format.swift.types;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import ghidra.app.util.bin.BinaryReader;
|
||||
import ghidra.app.util.bin.format.swift.SwiftTypeMetadataStructure;
|
||||
import ghidra.program.model.data.*;
|
||||
import ghidra.util.exception.DuplicateNameException;
|
||||
|
||||
/**
|
||||
* Represents a Swift {@code GenericRequirementFlags} structure
|
||||
*
|
||||
* @see <a href="https://github.com/swiftlang/swift/blob/main/include/swift/ABI/MetadataValues.h">swift/ABI/MetadataValues.h</a>
|
||||
*/
|
||||
public class GenericRequirementFlags extends SwiftTypeMetadataStructure {
|
||||
|
||||
/**
|
||||
* The size (in bytes) of a {@link GenericRequirementFlags} structure
|
||||
*/
|
||||
public static final int SIZE = 4;
|
||||
|
||||
private int flags;
|
||||
|
||||
/**
|
||||
* Create a new {@link GenericRequirementFlags}
|
||||
*
|
||||
* @param reader A {@link BinaryReader} positioned at the start of the structure
|
||||
* @throws IOException if there was an IO-related problem creating the structure
|
||||
*/
|
||||
public GenericRequirementFlags(BinaryReader reader) throws IOException {
|
||||
super(reader.getPointerIndex());
|
||||
flags = reader.readNextInt();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@return the flags}
|
||||
*/
|
||||
public int getFlags() {
|
||||
return flags;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@return the {@link GenericRequirementKind}}
|
||||
*/
|
||||
public GenericRequirementKind getKind() {
|
||||
return GenericRequirementKind.valueOf(flags & 0x1f);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@return whether or not the subject type of the requirement is a pack}
|
||||
*/
|
||||
public boolean isPackRequirement() {
|
||||
return (flags & 0x20) != 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@return whether or not the subject type of the requirement has a key argument}
|
||||
*/
|
||||
public boolean hasKeyArgument() {
|
||||
return (flags & 0x80) != 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@return whether or not the subject type of the requirement is a value}
|
||||
*/
|
||||
public boolean isValueRequirement() {
|
||||
return (flags & 0x100) != 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getStructureName() {
|
||||
return GenericRequirementFlags.class.getSimpleName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDescription() {
|
||||
return "generic requirement flags";
|
||||
}
|
||||
|
||||
@Override
|
||||
public DataType toDataType() throws DuplicateNameException, IOException {
|
||||
StructureDataType struct = new StructureDataType(CATEGORY_PATH, getStructureName(), SIZE);
|
||||
struct.setPackingEnabled(true);
|
||||
try {
|
||||
struct.addBitField(GenericRequirementKind.values()[0].toDataType(), 5, "kind", null);
|
||||
struct.addBitField(BOOL, 1, "isPackRequirement",
|
||||
"If true, the subject type of the requirement is a pack.");
|
||||
struct.addBitField(BOOL, 1, "legacy",
|
||||
"Don't set 0x40 for compatibility with pre-Swift 5.8 runtimes");
|
||||
struct.addBitField(BOOL, 1, "hasKeyArgument", null);
|
||||
struct.addBitField(BOOL, 1, "isValueRequirement",
|
||||
"If true, the subject type of the requirement is a value.");
|
||||
struct.addBitField(DWORD, 23, "reserved", null);
|
||||
}
|
||||
catch (InvalidDataTypeException e) {
|
||||
throw new IOException(e);
|
||||
}
|
||||
return struct;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,79 @@
|
||||
/* ###
|
||||
* IP: GHIDRA
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package ghidra.app.util.bin.format.swift.types;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Arrays;
|
||||
|
||||
import ghidra.app.util.bin.StructConverter;
|
||||
import ghidra.app.util.bin.format.swift.SwiftTypeMetadataStructure;
|
||||
import ghidra.program.model.data.DataType;
|
||||
import ghidra.program.model.data.EnumDataType;
|
||||
import ghidra.util.exception.DuplicateNameException;
|
||||
|
||||
/**
|
||||
* Swift {@code GenericRequirementKind} values
|
||||
*
|
||||
* @see <a href="https://github.com/swiftlang/swift/blob/main/include/swift/ABI/MetadataValues.h">swift/ABI/MetadataValues.h</a>
|
||||
*/
|
||||
public enum GenericRequirementKind implements StructConverter {
|
||||
|
||||
Protocol(0),
|
||||
SameType(1),
|
||||
BaseClass(2),
|
||||
SameConformance(3),
|
||||
SameShape(4),
|
||||
IntertedProtocol(5),
|
||||
Layout(0x1f);
|
||||
|
||||
private int value;
|
||||
|
||||
/**
|
||||
* Creates a new {@link GenericRequirementKind}
|
||||
*
|
||||
* @param value The kind value
|
||||
*/
|
||||
private GenericRequirementKind(int value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@return the kind value}
|
||||
*/
|
||||
public int getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@return the {@link GenericRequirementKind} with the given kind value, or {@code null} if it
|
||||
* does not exist}
|
||||
*
|
||||
* @param value The kind value to get the value of
|
||||
*/
|
||||
public static GenericRequirementKind valueOf(int value) {
|
||||
return Arrays.stream(values()).filter(e -> e.getValue() == value).findFirst().orElse(null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public DataType toDataType() throws DuplicateNameException, IOException {
|
||||
EnumDataType dt = new EnumDataType(SwiftTypeMetadataStructure.CATEGORY_PATH,
|
||||
GenericRequirementKind.class.getSimpleName(), 1);
|
||||
for (GenericRequirementKind kind : values()) {
|
||||
dt.add(kind.name(), kind.getValue());
|
||||
}
|
||||
return dt;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,73 @@
|
||||
/* ###
|
||||
* IP: GHIDRA
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package ghidra.app.util.bin.format.swift.types;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Arrays;
|
||||
|
||||
import ghidra.app.util.bin.StructConverter;
|
||||
import ghidra.app.util.bin.format.swift.SwiftTypeMetadataStructure;
|
||||
import ghidra.program.model.data.DataType;
|
||||
import ghidra.program.model.data.EnumDataType;
|
||||
import ghidra.util.exception.DuplicateNameException;
|
||||
|
||||
/**
|
||||
* Swift {@code GenericRequirementLayoutKind} values
|
||||
*
|
||||
* @see <a href="https://github.com/swiftlang/swift/blob/main/include/swift/ABI/MetadataValues.h">swift/ABI/MetadataValues.h</a>
|
||||
*/
|
||||
public enum GenericRequirementLayoutKind implements StructConverter {
|
||||
|
||||
Class(0);
|
||||
|
||||
private int value;
|
||||
|
||||
/**
|
||||
* Creates a new {@link GenericRequirementLayoutKind}
|
||||
*
|
||||
* @param value The kind value
|
||||
*/
|
||||
private GenericRequirementLayoutKind(int value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@return the kind value}
|
||||
*/
|
||||
public int getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@return the {@link GenericRequirementLayoutKind} with the given kind value, or {@code null}
|
||||
* if it does not exist}
|
||||
*
|
||||
* @param value The kind value to get the value of
|
||||
*/
|
||||
public static GenericRequirementLayoutKind valueOf(int value) {
|
||||
return Arrays.stream(values()).filter(e -> e.getValue() == value).findFirst().orElse(null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public DataType toDataType() throws DuplicateNameException, IOException {
|
||||
EnumDataType dt = new EnumDataType(SwiftTypeMetadataStructure.CATEGORY_PATH,
|
||||
GenericRequirementLayoutKind.class.getSimpleName(), 1);
|
||||
for (GenericRequirementLayoutKind kind : values()) {
|
||||
dt.add(kind.name(), kind.getValue());
|
||||
}
|
||||
return dt;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,75 @@
|
||||
/* ###
|
||||
* IP: GHIDRA
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package ghidra.app.util.bin.format.swift.types;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Arrays;
|
||||
|
||||
import ghidra.app.util.bin.StructConverter;
|
||||
import ghidra.app.util.bin.format.swift.SwiftTypeMetadataStructure;
|
||||
import ghidra.program.model.data.DataType;
|
||||
import ghidra.program.model.data.EnumDataType;
|
||||
import ghidra.util.exception.DuplicateNameException;
|
||||
|
||||
/**
|
||||
* Swift {@code MetadataInitializationKind} values
|
||||
*
|
||||
* @see <a href="https://github.com/swiftlang/swift/blob/main/include/swift/ABI/MetadataValues.h">swift/ABI/MetadataValues.h</a>
|
||||
*/
|
||||
public enum MetadataInitializationKind implements StructConverter {
|
||||
|
||||
NoMetadataInitialization(0),
|
||||
SingletonMetadataInitialization(1),
|
||||
ForeignMetadataInitialization(2);
|
||||
|
||||
private int value;
|
||||
|
||||
/**
|
||||
* Creates a new {@link MetadataInitializationKind}
|
||||
*
|
||||
* @param value The kind value
|
||||
*/
|
||||
private MetadataInitializationKind(int value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@return the kind value}
|
||||
*/
|
||||
public int getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@return the {@link MetadataInitializationKind} with the given kind value, or {@code null} if it
|
||||
* does not exist}
|
||||
*
|
||||
* @param value The kind value to get the value of
|
||||
*/
|
||||
public static MetadataInitializationKind valueOf(int value) {
|
||||
return Arrays.stream(values()).filter(e -> e.getValue() == value).findFirst().orElse(null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public DataType toDataType() throws DuplicateNameException, IOException {
|
||||
EnumDataType dt = new EnumDataType(SwiftTypeMetadataStructure.CATEGORY_PATH,
|
||||
MetadataInitializationKind.class.getSimpleName(), 1);
|
||||
for (MetadataInitializationKind kind : values()) {
|
||||
dt.add(kind.name(), kind.getValue());
|
||||
}
|
||||
return dt;
|
||||
}
|
||||
}
|
||||
@@ -20,11 +20,12 @@ import java.io.IOException;
|
||||
import ghidra.app.util.bin.BinaryReader;
|
||||
import ghidra.app.util.bin.format.swift.SwiftTypeMetadataStructure;
|
||||
import ghidra.app.util.bin.format.swift.SwiftUtils;
|
||||
import ghidra.program.model.data.*;
|
||||
import ghidra.program.model.data.DataType;
|
||||
import ghidra.program.model.data.StructureDataType;
|
||||
import ghidra.util.exception.DuplicateNameException;
|
||||
|
||||
/**
|
||||
* Represents a Swift MetadataSourceRecord structure
|
||||
* Represents a Swift {@code MetadataSourceRecord} structure
|
||||
*
|
||||
* @see <a href="https://github.com/swiftlang/swift/blob/main/include/swift/RemoteInspection/Records.h">swift/RemoteInspection/Records.h</a>
|
||||
*/
|
||||
@@ -51,18 +52,14 @@ public final class MetadataSourceRecord extends SwiftTypeMetadataStructure {
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the mangled type name
|
||||
*
|
||||
* @return The mangled type name
|
||||
* {@return the mangled type name}
|
||||
*/
|
||||
public String getMangledTypeName() {
|
||||
return mangledTypeName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the mangled metadata source
|
||||
*
|
||||
* @return The mangled metadata source
|
||||
* {@return the mangled metadata source}
|
||||
*/
|
||||
public String getMangledMetadataSource() {
|
||||
return mangledMetadataSource;
|
||||
@@ -80,10 +77,9 @@ public final class MetadataSourceRecord extends SwiftTypeMetadataStructure {
|
||||
|
||||
@Override
|
||||
public DataType toDataType() throws DuplicateNameException, IOException {
|
||||
StructureDataType struct = new StructureDataType(getStructureName(), 0);
|
||||
StructureDataType struct = new StructureDataType(CATEGORY_PATH, getStructureName(), 0);
|
||||
struct.add(SwiftUtils.PTR_STRING, "MangledTypeName", "");
|
||||
struct.add(SwiftUtils.PTR_STRING, "MangledMetadataSource", "");
|
||||
struct.setCategoryPath(new CategoryPath(DATA_TYPE_CATEGORY));
|
||||
return struct;
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,119 @@
|
||||
/* ###
|
||||
* IP: GHIDRA
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package ghidra.app.util.bin.format.swift.types;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import ghidra.app.util.bin.BinaryReader;
|
||||
import ghidra.app.util.bin.format.swift.SwiftTypeMetadataStructure;
|
||||
import ghidra.program.model.data.*;
|
||||
import ghidra.util.exception.DuplicateNameException;
|
||||
|
||||
/**
|
||||
* Represents a Swift {@code MethodDescriptorFlags} structure
|
||||
*
|
||||
* @see <a href="https://github.com/swiftlang/swift/blob/main/include/swift/ABI/MetadataValues.h">swift/ABI/MetadataValues.h</a>
|
||||
*/
|
||||
public class MethodDescriptorFlags extends SwiftTypeMetadataStructure {
|
||||
|
||||
/**
|
||||
* The size (in bytes) of a {@link MethodDescriptorFlags} structure
|
||||
*/
|
||||
public static final int SIZE = 4;
|
||||
|
||||
private int flags;
|
||||
|
||||
/**
|
||||
* Create a new {@link MethodDescriptorFlags}
|
||||
*
|
||||
* @param reader A {@link BinaryReader} positioned at the start of the structure
|
||||
* @throws IOException if there was an IO-related problem creating the structure
|
||||
*/
|
||||
public MethodDescriptorFlags(BinaryReader reader) throws IOException {
|
||||
super(reader.getPointerIndex());
|
||||
flags = reader.readNextInt();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@return the flags}
|
||||
*/
|
||||
public int getFlags() {
|
||||
return flags;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@return the {@link MethodDescriptorKind}}
|
||||
*/
|
||||
public MethodDescriptorKind getKind() {
|
||||
return MethodDescriptorKind.valueOf(flags & 0x0f);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@return whether or not the method is an instance method}
|
||||
*/
|
||||
public boolean isInstance() {
|
||||
return (flags & 0x10) != 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@return whether or not the method is dynamic}
|
||||
*/
|
||||
public boolean isDynamic() {
|
||||
return (flags & 0x20) != 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@return whether or not the method is async}
|
||||
*/
|
||||
public boolean isAnsyc() {
|
||||
return (flags & 0x40) != 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@return the extra descriminator}
|
||||
*/
|
||||
public int getExtraDescriminator() {
|
||||
return (flags >> 16) & 0xffff;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getStructureName() {
|
||||
return MethodDescriptorFlags.class.getSimpleName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDescription() {
|
||||
return "method descriptor flags";
|
||||
}
|
||||
|
||||
@Override
|
||||
public DataType toDataType() throws DuplicateNameException, IOException {
|
||||
StructureDataType struct = new StructureDataType(CATEGORY_PATH, getStructureName(), SIZE);
|
||||
struct.setPackingEnabled(true);
|
||||
try {
|
||||
struct.addBitField(MethodDescriptorKind.values()[0].toDataType(), 4, "kind", null);
|
||||
struct.addBitField(BOOL, 1, "IsInstance", null);
|
||||
struct.addBitField(BOOL, 1, "IsDynamic", null);
|
||||
struct.addBitField(BOOL, 1, "IsAsync", null);
|
||||
struct.addBitField(DWORD, 9, "reserved", null);
|
||||
struct.addBitField(DWORD, 16, "ExtraDescriminator", null);
|
||||
}
|
||||
catch (InvalidDataTypeException e) {
|
||||
throw new IOException(e);
|
||||
}
|
||||
return struct;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,78 @@
|
||||
/* ###
|
||||
* IP: GHIDRA
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package ghidra.app.util.bin.format.swift.types;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Arrays;
|
||||
|
||||
import ghidra.app.util.bin.StructConverter;
|
||||
import ghidra.app.util.bin.format.swift.SwiftTypeMetadataStructure;
|
||||
import ghidra.program.model.data.DataType;
|
||||
import ghidra.program.model.data.EnumDataType;
|
||||
import ghidra.util.exception.DuplicateNameException;
|
||||
|
||||
/**
|
||||
* Swift {@code MethodDescriptorFlags.Kind} values
|
||||
*
|
||||
* @see <a href="https://github.com/swiftlang/swift/blob/main/include/swift/ABI/MetadataValues.h">swift/ABI/MetadataValues.h</a>
|
||||
*/
|
||||
public enum MethodDescriptorKind implements StructConverter {
|
||||
|
||||
Method(0),
|
||||
Init(1),
|
||||
Getter(2),
|
||||
Setter(3),
|
||||
ModifyCoroutine(4),
|
||||
ReadCoroutine(5);
|
||||
|
||||
private int value;
|
||||
|
||||
/**
|
||||
* Creates a new {@link MethodDescriptorKind}
|
||||
*
|
||||
* @param value The kind value
|
||||
*/
|
||||
private MethodDescriptorKind(int value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@return the kind value}
|
||||
*/
|
||||
public int getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@return the {@link MethodDescriptorKind} with the given kind value, or {@code null} if it
|
||||
* does not exist}
|
||||
*
|
||||
* @param value The kind value to get the value of
|
||||
*/
|
||||
public static MethodDescriptorKind valueOf(int value) {
|
||||
return Arrays.stream(values()).filter(e -> e.getValue() == value).findFirst().orElse(null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public DataType toDataType() throws DuplicateNameException, IOException {
|
||||
EnumDataType dt = new EnumDataType(SwiftTypeMetadataStructure.CATEGORY_PATH,
|
||||
MethodDescriptorKind.class.getSimpleName(), 1);
|
||||
for (MethodDescriptorKind kind : values()) {
|
||||
dt.add(kind.name(), kind.getValue());
|
||||
}
|
||||
return dt;
|
||||
}
|
||||
}
|
||||
@@ -24,7 +24,7 @@ import ghidra.program.model.data.DataType;
|
||||
import ghidra.util.exception.DuplicateNameException;
|
||||
|
||||
/**
|
||||
* Represents a Swift MultiPayloadEnumDescriptor structure
|
||||
* Represents a Swift {@code MultiPayloadEnumDescriptor} structure
|
||||
*
|
||||
* @see <a href="https://github.com/swiftlang/swift/blob/main/include/swift/RemoteInspection/Records.h">swift/RemoteInspection/Records.h</a>
|
||||
*/
|
||||
@@ -32,7 +32,7 @@ public final class MultiPayloadEnumDescriptor extends SwiftTypeMetadataStructure
|
||||
|
||||
/**
|
||||
* The size (in bytes) of a {@link MultiPayloadEnumDescriptor} structure. This size does not
|
||||
* take into account the size of the <code>contents</code> array.
|
||||
* take into account the size of the {@code contents} array.
|
||||
*
|
||||
* @see #getContentsSize()
|
||||
*/
|
||||
@@ -56,27 +56,21 @@ public final class MultiPayloadEnumDescriptor extends SwiftTypeMetadataStructure
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the type name
|
||||
*
|
||||
* @return The type name
|
||||
* {@return the type name}
|
||||
*/
|
||||
public String getTypeName() {
|
||||
return typeName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the contents
|
||||
*
|
||||
* @return The contents
|
||||
* {@return the contents}
|
||||
*/
|
||||
public int[] getContents() {
|
||||
return contents;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the size of the contents in bytes
|
||||
*
|
||||
* @return The size of the contents in bytes
|
||||
* {@return The size of the contents in bytes}
|
||||
*/
|
||||
public long getContentsSize() {
|
||||
return contents.length * Integer.BYTES;
|
||||
|
||||
@@ -0,0 +1,111 @@
|
||||
/* ###
|
||||
* IP: GHIDRA
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package ghidra.app.util.bin.format.swift.types;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import ghidra.app.util.bin.BinaryReader;
|
||||
import ghidra.app.util.bin.format.swift.SwiftTypeMetadataStructure;
|
||||
import ghidra.program.model.data.*;
|
||||
import ghidra.util.exception.DuplicateNameException;
|
||||
|
||||
/**
|
||||
* Represents a Swift {@code ProtocolRequirementFlags} structure
|
||||
*
|
||||
* @see <a href="https://github.com/swiftlang/swift/blob/main/include/swift/ABI/MetadataValues.h">swift/ABI/MetadataValues.h</a>
|
||||
*/
|
||||
public class ProtocolRequirementFlags extends SwiftTypeMetadataStructure {
|
||||
|
||||
/**
|
||||
* The size (in bytes) of a {@link ProtocolRequirementFlags} structure
|
||||
*/
|
||||
public static final int SIZE = 4;
|
||||
|
||||
private int flags;
|
||||
|
||||
/**
|
||||
* Create a new {@link ProtocolRequirementFlags}
|
||||
*
|
||||
* @param reader A {@link BinaryReader} positioned at the start of the structure
|
||||
* @throws IOException if there was an IO-related problem creating the structure
|
||||
*/
|
||||
public ProtocolRequirementFlags(BinaryReader reader) throws IOException {
|
||||
super(reader.getPointerIndex());
|
||||
flags = reader.readNextInt();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@return the flags}
|
||||
*/
|
||||
public int getFlags() {
|
||||
return flags;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@return the {@link ProtocolRequirementKind}}
|
||||
*/
|
||||
public ProtocolRequirementKind getKind() {
|
||||
return ProtocolRequirementKind.valueOf(flags & 0x0f);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@return whether or not the protocol requirement is instance}
|
||||
*/
|
||||
public boolean isInstance() {
|
||||
return (flags & 0x10) != 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@return whether or not the protocol requirement is async}
|
||||
*/
|
||||
public boolean isAnsyc() {
|
||||
return (flags & 0x20) != 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@return the extra descriminator}
|
||||
*/
|
||||
public int getExtraDescriminator() {
|
||||
return (flags >> 16) & 0xffff;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getStructureName() {
|
||||
return ProtocolRequirementFlags.class.getSimpleName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDescription() {
|
||||
return "protocol requirements flags";
|
||||
}
|
||||
|
||||
@Override
|
||||
public DataType toDataType() throws DuplicateNameException, IOException {
|
||||
StructureDataType struct = new StructureDataType(CATEGORY_PATH, getStructureName(), SIZE);
|
||||
struct.setPackingEnabled(true);
|
||||
try {
|
||||
struct.addBitField(getKind().toDataType(), 4, "kind", null);
|
||||
struct.addBitField(BOOL, 1, "IsInstance", null);
|
||||
struct.addBitField(BOOL, 1, "IsAsync", null);
|
||||
struct.addBitField(DWORD, 10, "reserved", null);
|
||||
struct.addBitField(DWORD, 16, "ExtraDescriminator", null);
|
||||
}
|
||||
catch (InvalidDataTypeException e) {
|
||||
throw new IOException(e);
|
||||
}
|
||||
return struct;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,81 @@
|
||||
/* ###
|
||||
* IP: GHIDRA
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package ghidra.app.util.bin.format.swift.types;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Arrays;
|
||||
|
||||
import ghidra.app.util.bin.StructConverter;
|
||||
import ghidra.app.util.bin.format.swift.SwiftTypeMetadataStructure;
|
||||
import ghidra.program.model.data.DataType;
|
||||
import ghidra.program.model.data.EnumDataType;
|
||||
import ghidra.util.exception.DuplicateNameException;
|
||||
|
||||
/**
|
||||
* Swift {@code ProtocolRequirementFlags.Kind} values
|
||||
*
|
||||
* @see <a href="https://github.com/swiftlang/swift/blob/main/include/swift/ABI/MetadataValues.h">swift/ABI/MetadataValues.h</a>
|
||||
*/
|
||||
public enum ProtocolRequirementKind implements StructConverter {
|
||||
|
||||
BaseProtocol(0),
|
||||
Method(1),
|
||||
Init(2),
|
||||
Getter(3),
|
||||
Setter(4),
|
||||
ReadCoroutine(5),
|
||||
ModifyCoroutine(6),
|
||||
AssociatedTypeAccessFunction(7),
|
||||
AssociatedConformanceAccessFunction(8);
|
||||
|
||||
private int value;
|
||||
|
||||
/**
|
||||
* Creates a new {@link ProtocolRequirementKind}
|
||||
*
|
||||
* @param value The kind value
|
||||
*/
|
||||
private ProtocolRequirementKind(int value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@return the kind value}
|
||||
*/
|
||||
public int getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@return the {@link ProtocolRequirementKind} with the given kind value, or {@code null} if it
|
||||
* does not exist}
|
||||
*
|
||||
* @param value The kind value to get the value of
|
||||
*/
|
||||
public static ProtocolRequirementKind valueOf(int value) {
|
||||
return Arrays.stream(values()).filter(e -> e.getValue() == value).findFirst().orElse(null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public DataType toDataType() throws DuplicateNameException, IOException {
|
||||
EnumDataType dt = new EnumDataType(SwiftTypeMetadataStructure.CATEGORY_PATH,
|
||||
ProtocolRequirementKind.class.getSimpleName(), 1);
|
||||
for (ProtocolRequirementKind kind : values()) {
|
||||
dt.add(kind.name(), kind.getValue());
|
||||
}
|
||||
return dt;
|
||||
}
|
||||
}
|
||||
@@ -16,14 +16,17 @@
|
||||
package ghidra.app.util.bin.format.swift.types;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import ghidra.app.util.bin.BinaryReader;
|
||||
import ghidra.app.util.bin.format.swift.SwiftTypeMetadataStructure;
|
||||
import ghidra.app.util.bin.format.swift.SwiftUtils;
|
||||
import ghidra.program.model.data.*;
|
||||
import ghidra.util.exception.DuplicateNameException;
|
||||
|
||||
/**
|
||||
* Represents a Swift TargetClassDescriptor structure
|
||||
* Represents a Swift {@code TargetClassDescriptor} structure
|
||||
*
|
||||
* @see <a href="https://github.com/swiftlang/swift/blob/main/include/swift/ABI/Metadata.h">swift/ABI/Metadata.h</a>
|
||||
*/
|
||||
@@ -31,11 +34,24 @@ public final class TargetClassDescriptor extends TargetTypeContextDescriptor {
|
||||
|
||||
private int superclassType;
|
||||
private int metadataNegativeSizeInWords;
|
||||
private int resilientMetadataBounds;
|
||||
private int metadataPositiveSizeInWords;
|
||||
private ExtraClassDescriptorFlags extraClassFlags;
|
||||
private int numImmediateMembers;
|
||||
private int numFields;
|
||||
private int fieldOffsetVectorOffset;
|
||||
|
||||
// Trailing Objects
|
||||
private TargetTypeGenericContextDescriptorHeader genericHeader;
|
||||
private TargetResilientSuperclass resilientSuperclass;
|
||||
private TargetSingletonMetadataInitialization singleton;
|
||||
private TargetForeignMetadataInitialization foreign;
|
||||
private TargetVTableDescriptorHeader vtableHeader;
|
||||
private List<TargetMethodDescriptor> methodDescriptors = new ArrayList<>();
|
||||
private TargetOverrideTableHeader overrideHeader;
|
||||
private List<TargetMethodOverrideDescriptor> methodOverrideDescriptors = new ArrayList<>();
|
||||
private TargetObjCResilientClassStubInfo objcResilientClassStub;
|
||||
|
||||
/**
|
||||
* Creates a new {@link TargetClassDescriptor}
|
||||
*
|
||||
@@ -45,79 +61,231 @@ public final class TargetClassDescriptor extends TargetTypeContextDescriptor {
|
||||
public TargetClassDescriptor(BinaryReader reader) throws IOException {
|
||||
super(reader);
|
||||
superclassType = reader.readNextInt();
|
||||
metadataNegativeSizeInWords = reader.readNextInt();
|
||||
metadataPositiveSizeInWords = reader.readNextInt();
|
||||
resilientMetadataBounds = reader.readNextInt();
|
||||
metadataNegativeSizeInWords = resilientMetadataBounds; // union
|
||||
extraClassFlags = new ExtraClassDescriptorFlags(reader);
|
||||
metadataPositiveSizeInWords = extraClassFlags.getFlags(); // union
|
||||
numImmediateMembers = reader.readNextInt();
|
||||
numFields = reader.readNextInt();
|
||||
fieldOffsetVectorOffset = reader.readNextInt();
|
||||
|
||||
if (flags.isGeneric()) {
|
||||
genericHeader = new TargetTypeGenericContextDescriptorHeader(reader);
|
||||
}
|
||||
|
||||
if (flags.hasClassResilientSuperclass()) {
|
||||
resilientSuperclass = new TargetResilientSuperclass(reader);
|
||||
}
|
||||
|
||||
switch (flags.getMetadataInitialization()) {
|
||||
case NoMetadataInitialization:
|
||||
break;
|
||||
case SingletonMetadataInitialization:
|
||||
singleton = new TargetSingletonMetadataInitialization(reader, flags);
|
||||
break;
|
||||
case ForeignMetadataInitialization:
|
||||
foreign = new TargetForeignMetadataInitialization(reader);
|
||||
break;
|
||||
}
|
||||
|
||||
if (flags.hasClassVTable()) {
|
||||
vtableHeader = new TargetVTableDescriptorHeader(reader);
|
||||
for (int i = 0; i < vtableHeader.getVTableSize(); i++) {
|
||||
methodDescriptors.add(new TargetMethodDescriptor(reader));
|
||||
}
|
||||
}
|
||||
|
||||
if (flags.hasClassOverrideTable()) {
|
||||
overrideHeader = new TargetOverrideTableHeader(reader);
|
||||
for (int i = 0; i < overrideHeader.getNumEntries(); i++) {
|
||||
methodOverrideDescriptors.add(new TargetMethodOverrideDescriptor(reader));
|
||||
}
|
||||
}
|
||||
|
||||
if (flags.hasClassResilientSuperclass() &&
|
||||
extraClassFlags.hasObjcResilientClassStub()) {
|
||||
objcResilientClassStub = new TargetObjCResilientClassStubInfo(reader);
|
||||
}
|
||||
|
||||
if (flags.isGeneric() &&
|
||||
flags.hasCanonicalMetadataPrespecializationsOrSingletonMetadataPonter()) {
|
||||
throw new IOException("Unimplemented TargetCanonicalSpecializedMetadatas detected.");
|
||||
}
|
||||
|
||||
if (flags.hasInvertableProtocols()) {
|
||||
throw new IOException("Unimplemented InvertibleProtocolSet detected.");
|
||||
}
|
||||
|
||||
if (!flags.isGeneric() &&
|
||||
flags.hasCanonicalMetadataPrespecializationsOrSingletonMetadataPonter()) {
|
||||
throw new IOException("Unimplemented TargetSingletonMetadataPointer detected.");
|
||||
}
|
||||
|
||||
if (flags.hasClassDefaultOverrideTable()) {
|
||||
throw new IOException("Unimplemented TargetMethodDefaultOverride detected.");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the type of the superclass, expressed as a mangled type name that can refer to the
|
||||
* generic arguments of the subclass type
|
||||
*
|
||||
* @return The type of the superclass, expressed as a mangled type name that can refer to the
|
||||
* generic arguments of the subclass type
|
||||
* {@return the type of the superclass, expressed as a mangled type name that can refer to the
|
||||
* generic arguments of the subclass type}
|
||||
*/
|
||||
public int getSuperclassType() {
|
||||
return superclassType;
|
||||
}
|
||||
|
||||
/**
|
||||
* If this descriptor does not have a resilient superclass, this is the negative size of
|
||||
* metadata objects of this class (in words). If this descriptor has a resilient superclass,
|
||||
* this is a reference to a cache holding the metadata's extents.
|
||||
*
|
||||
* @return The negative size of metadata objects of this class (in words) or a reference to a
|
||||
* cache holding the metadata's extents
|
||||
* {@return a reference to a cache holding the metadata's extents if this descriptor has a
|
||||
* resilient superclass; otherwise, 0}
|
||||
*/
|
||||
public int getResilientMetadataBounds() {
|
||||
return flags.hasClassResilientSuperclass() ? resilientMetadataBounds : 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@return the negative size of metadata objects of this class (in words) if this descriptor
|
||||
* does not have a resilient superclass}
|
||||
*/
|
||||
public int getMetadataNegativeSizeInWords() {
|
||||
return metadataNegativeSizeInWords;
|
||||
return !flags.hasClassResilientSuperclass() ? metadataNegativeSizeInWords : 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* If this descriptor does not have a resilient superclass, this is the positive size of
|
||||
* metadata objects of this class (in words). Otherwise, these flags are used to do things like
|
||||
* indicate the presence of an Objective-C resilient class stub.
|
||||
*
|
||||
* @return The positive size of metadata objects of this class (in words) or flags used to do
|
||||
* things like indicate the presence of an Objective-C resilient class stub.
|
||||
* {@return flags used to do things like indicate the presence of an Objective-C resilient class
|
||||
* stub if this descriptor has a resilient superclass; otherwise, {@code null}}
|
||||
*/
|
||||
public ExtraClassDescriptorFlags getExtraClassDescriptorFlags() {
|
||||
return flags.hasClassResilientSuperclass() ? extraClassFlags : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@return the positive size of metadata objects of this class (in words) if this descriptor
|
||||
* does not have a resilient superclass}
|
||||
*/
|
||||
public int getMetadataPositiveSizeInWords() {
|
||||
return metadataPositiveSizeInWords;
|
||||
return !flags.hasClassResilientSuperclass() ? metadataPositiveSizeInWords : 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the number of additional members added by this class to the class metadata
|
||||
*
|
||||
* @return The number of additional members added by this class to the class metadata
|
||||
* {@return the number of additional members added by this class to the class metadata}
|
||||
*/
|
||||
public int getNumImmediateMembers() {
|
||||
return numImmediateMembers;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the number of stored properties in the class, not including its superclasses. If there
|
||||
* is a field offset vector, this is its length.
|
||||
*
|
||||
* @return The number of stored properties in the class, not including its superclasses.
|
||||
* If there is a field offset vector, this is its length.
|
||||
* {@return the number of stored properties in the class, not including its superclasses}
|
||||
* <p>
|
||||
* If there is a field offset vector, this is its length.
|
||||
*/
|
||||
public int getNumFields() {
|
||||
return numFields;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the offset of the field offset vector for this class's stored properties in its
|
||||
* metadata, in words. 0 means there is no field offset vector.
|
||||
*
|
||||
* @return THe offset of the field offset vector for this class's stored properties in its
|
||||
* metadata, in words. 0 means there is no field offset vector.
|
||||
* {@return the offset of the field offset vector for this class's stored properties in its
|
||||
* metadata, in words (0 means there is no field offset vector)}
|
||||
*/
|
||||
public int getFieldOffsetVectorOffset() {
|
||||
return fieldOffsetVectorOffset;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@return the {@link TargetTypeGenericContextDescriptorHeader}, or {@code null} if it doesn't
|
||||
* exist}
|
||||
*/
|
||||
public TargetTypeGenericContextDescriptorHeader getGenericHeader() {
|
||||
return genericHeader;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@return the {@link TargetResilientSuperclass}, or {@code null} if it doesn't exist}
|
||||
*/
|
||||
public TargetResilientSuperclass getResilientSuperclass() {
|
||||
return resilientSuperclass;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@return the {@link TargetSingletonMetadataInitialization}, or {@code null} if it doesn't
|
||||
* exist}
|
||||
*/
|
||||
public TargetSingletonMetadataInitialization getTargetSingletonMetadataInitialization() {
|
||||
return singleton;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@return the {@link TargetForeignMetadataInitialization}, or {@code null} if it doesn't
|
||||
* exist}
|
||||
*/
|
||||
public TargetForeignMetadataInitialization getTargetForeignMetadataInitialization() {
|
||||
return foreign;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@return the {@link TargetVTableDescriptorHeader}, or {@code null} if it doesn't exist}
|
||||
*/
|
||||
public TargetVTableDescriptorHeader getVTableDescriptorHeader() {
|
||||
return vtableHeader;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@return the {@link List} of method descriptors}
|
||||
*/
|
||||
public List<TargetMethodDescriptor> getMethodDescriptors() {
|
||||
return methodDescriptors;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@return the {@link TargetOverrideTableHeader}, or {@code null} if it doesn't exist}
|
||||
*/
|
||||
public TargetOverrideTableHeader getTargetOverrideTableHeader() {
|
||||
return overrideHeader;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@return the {@link List} of method override descriptors}
|
||||
*/
|
||||
public List<TargetMethodOverrideDescriptor> getMethodOverrideDescriptors() {
|
||||
return methodOverrideDescriptors;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@return the {@link TargetObjCResilientClassStubInfo}, or {@code null} if it doesn't exist}
|
||||
*/
|
||||
public TargetObjCResilientClassStubInfo getObjcResilientClassStub() {
|
||||
return objcResilientClassStub;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<SwiftTypeMetadataStructure> getTrailingObjects() {
|
||||
List<SwiftTypeMetadataStructure> ret = new ArrayList<>();
|
||||
if (genericHeader != null) {
|
||||
ret.add(genericHeader);
|
||||
ret.addAll(genericHeader.getTrailingObjects());
|
||||
}
|
||||
if (resilientSuperclass != null) {
|
||||
ret.add(resilientSuperclass);
|
||||
}
|
||||
if (singleton != null) {
|
||||
ret.add(singleton);
|
||||
}
|
||||
if (foreign != null) {
|
||||
ret.add(foreign);
|
||||
}
|
||||
if (vtableHeader != null) {
|
||||
ret.add(vtableHeader);
|
||||
ret.addAll(methodDescriptors);
|
||||
}
|
||||
if (overrideHeader != null) {
|
||||
ret.add(overrideHeader);
|
||||
ret.addAll(methodOverrideDescriptors);
|
||||
}
|
||||
if (objcResilientClassStub != null) {
|
||||
ret.add(objcResilientClassStub);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getStructureName() {
|
||||
return TargetClassDescriptor.class.getSimpleName();
|
||||
@@ -130,22 +298,32 @@ public final class TargetClassDescriptor extends TargetTypeContextDescriptor {
|
||||
|
||||
@Override
|
||||
public DataType toDataType() throws DuplicateNameException, IOException {
|
||||
StructureDataType struct = new StructureDataType(getStructureName(), 0);
|
||||
UnionDataType union1 = new UnionDataType(CATEGORY_PATH,
|
||||
"Union_MetadataNegativeSizeInWords_ResilientMetadataBounds");
|
||||
union1.add(DWORD, "MetadataNegativeSizeInWords",
|
||||
"If this descriptor does not have a resilient superclass, this is the negative size of metadata objects of this class (in words)");
|
||||
union1.add(SwiftUtils.PTR_RELATIVE, "ResilientMetadataBounds",
|
||||
"If this descriptor has a resilient superclass, this is a reference to a cache holding the metadata's extends.");
|
||||
|
||||
UnionDataType union2 =
|
||||
new UnionDataType(CATEGORY_PATH, "Union_MetadataPositiveSizeInWords/ExtraClassFlags");
|
||||
union2.add(DWORD, "MetadataPositiveSizeInWords",
|
||||
"If this descriptor does not have a resilient superclass, this is the positive size of metadata objects of this class (in words)");
|
||||
union2.add(extraClassFlags.toDataType(), "ExtraClassFlags",
|
||||
"Otherwise, these flags are used to do things like indicating the presence of an Objective-C resilient class stub.");
|
||||
|
||||
StructureDataType struct = new StructureDataType(CATEGORY_PATH, getStructureName(), 0);
|
||||
struct.add(super.toDataType(), super.getStructureName(), "");
|
||||
struct.add(SwiftUtils.PTR_STRING, "SuperclassType",
|
||||
"The type of the superclass, expressed as a mangled type name that can refer to the generic arguments of the subclass type");
|
||||
struct.add(DWORD, "MetadataNegativeSizeInWords",
|
||||
"If this descriptor does not have a resilient superclass, this is the negative size of metadata objects of this class (in words)");
|
||||
struct.add(DWORD, "MetadataPositiveSizeInWords",
|
||||
"If this descriptor does not have a resilient superclass, this is the positive size of metadata objects of this class (in words)");
|
||||
struct.add(union1, "MetadataNegativeSizeInWords/ResilientMetadataBounds", null);
|
||||
struct.add(union2, "MetadataPositiveSizeInWords/ExtraClassFlags", null);
|
||||
struct.add(DWORD, "NumImmediateMembers",
|
||||
"The number of additional members added by this class to the class metadata");
|
||||
struct.add(DWORD, "NumFields",
|
||||
"The number of stored properties in the class, not including its superclasses. If there is a field offset vector, this is its length.");
|
||||
struct.add(DWORD, "FieldOffsetVectorOffset",
|
||||
"The offset of the field offset vector for this class's stored properties in its metadata, in words. 0 means there is no field offset vector.");
|
||||
struct.setCategoryPath(new CategoryPath(DATA_TYPE_CATEGORY));
|
||||
return struct;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -20,11 +20,12 @@ import java.io.IOException;
|
||||
import ghidra.app.util.bin.BinaryReader;
|
||||
import ghidra.app.util.bin.format.swift.SwiftTypeMetadataStructure;
|
||||
import ghidra.app.util.bin.format.swift.SwiftUtils;
|
||||
import ghidra.program.model.data.*;
|
||||
import ghidra.program.model.data.DataType;
|
||||
import ghidra.program.model.data.StructureDataType;
|
||||
import ghidra.util.exception.DuplicateNameException;
|
||||
|
||||
/**
|
||||
* Represents a Swift TargetContextDescriptor structure
|
||||
* Represents a Swift {@code TargetContextDescriptor} structure
|
||||
*
|
||||
* @see <a href="https://github.com/swiftlang/swift/blob/main/include/swift/ABI/Metadata.h">swift/ABI/Metadata.h</a>
|
||||
*/
|
||||
@@ -35,7 +36,7 @@ public class TargetContextDescriptor extends SwiftTypeMetadataStructure {
|
||||
*/
|
||||
public static final int SIZE = 8;
|
||||
|
||||
private int flags;
|
||||
protected ContextDescriptorFlags flags;
|
||||
private int parent;
|
||||
|
||||
/**
|
||||
@@ -46,23 +47,19 @@ public class TargetContextDescriptor extends SwiftTypeMetadataStructure {
|
||||
*/
|
||||
public TargetContextDescriptor(BinaryReader reader) throws IOException {
|
||||
super(reader.getPointerIndex());
|
||||
flags = reader.readNextInt();
|
||||
flags = new ContextDescriptorFlags(reader);
|
||||
parent = reader.readNextInt();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the flags
|
||||
*
|
||||
* @return The flags
|
||||
* {@return the flags}
|
||||
*/
|
||||
public int getFlags() {
|
||||
public ContextDescriptorFlags getFlags() {
|
||||
return flags;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the parent's relative offset
|
||||
*
|
||||
* @return The parent's relative offset
|
||||
* {@return the parent's relative offset}
|
||||
*/
|
||||
public int getParent() {
|
||||
return parent;
|
||||
@@ -79,9 +76,7 @@ public class TargetContextDescriptor extends SwiftTypeMetadataStructure {
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets this class's structure name (will not be affected by subclass's name)
|
||||
*
|
||||
* @return This class's structure name
|
||||
* {@return this class's structure name (will not be affected by subclass's name)}
|
||||
*/
|
||||
private final String getMyStructureName() {
|
||||
return TargetContextDescriptor.class.getSimpleName();
|
||||
@@ -89,12 +84,11 @@ public class TargetContextDescriptor extends SwiftTypeMetadataStructure {
|
||||
|
||||
@Override
|
||||
public DataType toDataType() throws DuplicateNameException, IOException {
|
||||
StructureDataType struct = new StructureDataType(getMyStructureName(), 0);
|
||||
struct.add(DWORD, "Flags",
|
||||
StructureDataType struct = new StructureDataType(CATEGORY_PATH, getMyStructureName(), 0);
|
||||
struct.add(flags.toDataType(), "Flags",
|
||||
"Flags describing the context, including its kind and format version");
|
||||
struct.add(SwiftUtils.PTR_RELATIVE, "Parent",
|
||||
struct.add(SwiftUtils.PTR_RELATIVE_MASKED, "Parent",
|
||||
"The parent context, or null if this is a top-level context");
|
||||
struct.setCategoryPath(new CategoryPath(DATA_TYPE_CATEGORY));
|
||||
return struct;
|
||||
}
|
||||
|
||||
|
||||
@@ -16,15 +16,17 @@
|
||||
package ghidra.app.util.bin.format.swift.types;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import ghidra.app.util.bin.BinaryReader;
|
||||
import ghidra.program.model.data.CategoryPath;
|
||||
import ghidra.app.util.bin.format.swift.SwiftTypeMetadataStructure;
|
||||
import ghidra.program.model.data.DataType;
|
||||
import ghidra.program.model.data.StructureDataType;
|
||||
import ghidra.util.exception.DuplicateNameException;
|
||||
|
||||
/**
|
||||
* Represents a Swift TargetEnumDescriptor structure
|
||||
* Represents a Swift {@code TargetEnumDescriptor} structure
|
||||
*
|
||||
* @see <a href="https://github.com/swiftlang/swift/blob/main/include/swift/ABI/Metadata.h">swift/ABI/Metadata.h</a>
|
||||
*/
|
||||
@@ -33,6 +35,11 @@ public final class TargetEnumDescriptor extends TargetTypeContextDescriptor {
|
||||
private int numPayloadCasesAndPayloadSizeOffset;
|
||||
private int numEmptyCases;
|
||||
|
||||
// Trailing objects
|
||||
private TargetTypeGenericContextDescriptorHeader genericHeader;
|
||||
private TargetSingletonMetadataInitialization singleton;
|
||||
private TargetForeignMetadataInitialization foreign;
|
||||
|
||||
/**
|
||||
* Creates a new {@link TargetEnumDescriptor}
|
||||
*
|
||||
@@ -43,6 +50,35 @@ public final class TargetEnumDescriptor extends TargetTypeContextDescriptor {
|
||||
super(reader);
|
||||
numPayloadCasesAndPayloadSizeOffset = reader.readNextInt();
|
||||
numEmptyCases = reader.readNextInt();
|
||||
|
||||
if (flags.isGeneric()) {
|
||||
genericHeader = new TargetTypeGenericContextDescriptorHeader(reader);
|
||||
}
|
||||
|
||||
switch (flags.getMetadataInitialization()) {
|
||||
case NoMetadataInitialization:
|
||||
break;
|
||||
case SingletonMetadataInitialization:
|
||||
singleton = new TargetSingletonMetadataInitialization(reader, flags);
|
||||
break;
|
||||
case ForeignMetadataInitialization:
|
||||
foreign = new TargetForeignMetadataInitialization(reader);
|
||||
break;
|
||||
}
|
||||
|
||||
if (flags.isGeneric() &&
|
||||
flags.hasCanonicalMetadataPrespecializationsOrSingletonMetadataPonter()) {
|
||||
throw new IOException("Unimplemented TargetCanonicalSpecializedMetadatas detected.");
|
||||
}
|
||||
|
||||
if (flags.hasInvertableProtocols()) {
|
||||
throw new IOException("Unimplemented InvertibleProtocolSet detected.");
|
||||
}
|
||||
|
||||
if (!flags.isGeneric() &&
|
||||
flags.hasCanonicalMetadataPrespecializationsOrSingletonMetadataPonter()) {
|
||||
throw new IOException("Unimplemented TargetSingletonMetadataPointer detected.");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -56,14 +92,52 @@ public final class TargetEnumDescriptor extends TargetTypeContextDescriptor {
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the number of empty cases in the enum
|
||||
*
|
||||
* @return The number of empty cases in the enum
|
||||
* {@return the number of empty cases in the enum}
|
||||
*/
|
||||
public int getNumEmptyCases() {
|
||||
return numEmptyCases;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@return the {@link TargetTypeGenericContextDescriptorHeader}, or {@code null} if it doesn't
|
||||
* exist}
|
||||
*/
|
||||
public TargetTypeGenericContextDescriptorHeader getGenericHeader() {
|
||||
return genericHeader;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@return the {@link TargetSingletonMetadataInitialization}, or {@code null} if it doesn't
|
||||
* exist}
|
||||
*/
|
||||
public TargetSingletonMetadataInitialization getTargetSingletonMetadataInitialization() {
|
||||
return singleton;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@return the {@link TargetForeignMetadataInitialization}, or {@code null} if it doesn't
|
||||
* exist}
|
||||
*/
|
||||
public TargetForeignMetadataInitialization getTargetForeignMetadataInitialization() {
|
||||
return foreign;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<SwiftTypeMetadataStructure> getTrailingObjects() {
|
||||
List<SwiftTypeMetadataStructure> ret = new ArrayList<>();
|
||||
if (genericHeader != null) {
|
||||
ret.add(genericHeader);
|
||||
ret.addAll(genericHeader.getTrailingObjects());
|
||||
}
|
||||
if (singleton != null) {
|
||||
ret.add(singleton);
|
||||
}
|
||||
if (foreign != null) {
|
||||
ret.add(foreign);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getStructureName() {
|
||||
return TargetEnumDescriptor.class.getSimpleName();
|
||||
@@ -76,12 +150,11 @@ public final class TargetEnumDescriptor extends TargetTypeContextDescriptor {
|
||||
|
||||
@Override
|
||||
public DataType toDataType() throws DuplicateNameException, IOException {
|
||||
StructureDataType struct = new StructureDataType(getStructureName(), 0);
|
||||
StructureDataType struct = new StructureDataType(CATEGORY_PATH, getStructureName(), 0);
|
||||
struct.add(super.toDataType(), super.getStructureName(), "");
|
||||
struct.add(DWORD, "NumPayloadCasesAndPayloadSizeOffset",
|
||||
"The number of non-empty cases in the enum are in the low 24 bits; the offset of the payload size in the metadata record in words, if any, is stored in the high 8 bits.");
|
||||
struct.add(DWORD, "NumEmptyCases", "The number of empty cases in the enum");
|
||||
struct.setCategoryPath(new CategoryPath(DATA_TYPE_CATEGORY));
|
||||
return struct;
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,71 @@
|
||||
/* ###
|
||||
* IP: GHIDRA
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package ghidra.app.util.bin.format.swift.types;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import ghidra.app.util.bin.BinaryReader;
|
||||
import ghidra.app.util.bin.format.swift.SwiftTypeMetadataStructure;
|
||||
import ghidra.app.util.bin.format.swift.SwiftUtils;
|
||||
import ghidra.program.model.data.DataType;
|
||||
import ghidra.program.model.data.StructureDataType;
|
||||
import ghidra.util.exception.DuplicateNameException;
|
||||
|
||||
/**
|
||||
* Represents a Swift {@code TargetForeignMetadataInitialization} structure
|
||||
*
|
||||
* @see <a href="https://github.com/swiftlang/swift/blob/main/include/swift/ABI/Metadata.h">swift/ABI/Metadata.h</a>
|
||||
*/
|
||||
public class TargetForeignMetadataInitialization extends SwiftTypeMetadataStructure {
|
||||
|
||||
private int completionFunction;
|
||||
|
||||
/**
|
||||
* Creates a new {@link TargetForeignMetadataInitialization}
|
||||
*
|
||||
* @param reader A {@link BinaryReader} positioned at the start of the structure
|
||||
* @throws IOException if there was an IO-related problem creating the structure
|
||||
*/
|
||||
public TargetForeignMetadataInitialization(BinaryReader reader) throws IOException {
|
||||
super(reader.getPointerIndex());
|
||||
completionFunction = reader.readNextInt();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@return the completion function (the pattern will always be null)}
|
||||
*/
|
||||
public int getCompletionFunction() {
|
||||
return completionFunction;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getStructureName() {
|
||||
return TargetForeignMetadataInitialization.class.getSimpleName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDescription() {
|
||||
return "foreign metadata initialization";
|
||||
}
|
||||
|
||||
@Override
|
||||
public DataType toDataType() throws DuplicateNameException, IOException {
|
||||
StructureDataType struct = new StructureDataType(CATEGORY_PATH, getStructureName(), 0);
|
||||
struct.add(SwiftUtils.PTR_RELATIVE, "CompletionFunction",
|
||||
"The completion function. The pattern will always be null.");
|
||||
return struct;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,144 @@
|
||||
/* ###
|
||||
* IP: GHIDRA
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package ghidra.app.util.bin.format.swift.types;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import ghidra.app.util.bin.BinaryReader;
|
||||
import ghidra.app.util.bin.format.swift.SwiftTypeMetadataStructure;
|
||||
import ghidra.program.model.data.DataType;
|
||||
import ghidra.program.model.data.StructureDataType;
|
||||
import ghidra.util.exception.DuplicateNameException;
|
||||
|
||||
/**
|
||||
* Represents a Swift {@code TargetGenericContextDescriptorHeader} structure
|
||||
*
|
||||
* @see <a href="https://github.com/swiftlang/swift/blob/main/include/swift/ABI/GenericContext.h">swift/ABI/GenericContext.h</a>
|
||||
*/
|
||||
public class TargetGenericContextDescriptorHeader extends SwiftTypeMetadataStructure {
|
||||
|
||||
private int numParams;
|
||||
private int numRequirements;
|
||||
private int numKeyArguments;
|
||||
private GenericContextDescriptorFlags flags;
|
||||
|
||||
private List<GenericParamDescriptor> params = new ArrayList<>();
|
||||
private List<TargetGenericRequirementsDescriptor> requirements = new ArrayList<>();
|
||||
|
||||
/**
|
||||
* Creates a new {@link TargetGenericContextDescriptorHeader}
|
||||
*
|
||||
* @param reader A {@link BinaryReader} positioned at the start of the structure
|
||||
* @throws IOException if there was an IO-related problem creating the structure
|
||||
*/
|
||||
public TargetGenericContextDescriptorHeader(BinaryReader reader) throws IOException {
|
||||
super(reader.getPointerIndex());
|
||||
numParams = reader.readNextUnsignedShort();
|
||||
numRequirements = reader.readNextUnsignedShort();
|
||||
numKeyArguments = reader.readNextUnsignedShort();
|
||||
flags = new GenericContextDescriptorFlags(reader);
|
||||
|
||||
for (int i = 0; i < numParams; i++) {
|
||||
params.add(new GenericParamDescriptor(reader));
|
||||
}
|
||||
|
||||
// It seems we have to round to the next 4 byte boundary after reading the params???
|
||||
reader.setPointerIndex((reader.getPointerIndex() + 3) & (~3));
|
||||
|
||||
for (int i = 0; i < numRequirements; i++) {
|
||||
requirements.add(new TargetGenericRequirementsDescriptor(reader));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@return the number of (source-written) generic parameters, and thus the number of
|
||||
* GenericParamDescriptors associated with this context}
|
||||
*/
|
||||
public int getNumParams() {
|
||||
return numParams;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@return the number of GenericRequirementDescriptors in this generic signature}
|
||||
*/
|
||||
public int getNumRequirements() {
|
||||
return numRequirements;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@return the size of the "key" area of the argument layout, in words}
|
||||
* <p>
|
||||
* Key arguments include shape classes, generic parameters, and conformance requirements which
|
||||
* are part of the identity of the context.
|
||||
*/
|
||||
public int getNumKeyArguments() {
|
||||
return numKeyArguments;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@return the flags}
|
||||
*/
|
||||
public GenericContextDescriptorFlags getFlags() {
|
||||
return flags;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@return the {@link List} of generic parameter descriptors}
|
||||
*/
|
||||
public List<GenericParamDescriptor> getParams() {
|
||||
return params;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@return the {@link List} of generic requirements descriptors}
|
||||
*/
|
||||
public List<TargetGenericRequirementsDescriptor> getRequirements() {
|
||||
return requirements;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<SwiftTypeMetadataStructure> getTrailingObjects() {
|
||||
List<SwiftTypeMetadataStructure> ret = new ArrayList<>();
|
||||
ret.addAll(params);
|
||||
ret.addAll(requirements);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getStructureName() {
|
||||
return TargetGenericContextDescriptorHeader.class.getSimpleName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDescription() {
|
||||
return "generic context descriptor header";
|
||||
}
|
||||
|
||||
@Override
|
||||
public DataType toDataType() throws DuplicateNameException, IOException {
|
||||
StructureDataType struct = new StructureDataType(CATEGORY_PATH, getStructureName(), 0);
|
||||
struct.add(WORD, "NumParams",
|
||||
"The number of (source-written) generic parameters, and thus the number of GenericParamDescriptors associated with this context.");
|
||||
struct.add(WORD, "NumRequirements",
|
||||
"The number of GenericRequirementDescriptors in this generic signature.");
|
||||
struct.add(WORD, "NumKeyArguments",
|
||||
"The size of the key area of the argument layout, in words.");
|
||||
struct.add(flags.toDataType(), "Flags", "");
|
||||
return struct;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,132 @@
|
||||
/* ###
|
||||
* IP: GHIDRA
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package ghidra.app.util.bin.format.swift.types;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import ghidra.app.util.bin.BinaryReader;
|
||||
import ghidra.app.util.bin.format.swift.SwiftTypeMetadataStructure;
|
||||
import ghidra.app.util.bin.format.swift.SwiftUtils;
|
||||
import ghidra.program.model.data.*;
|
||||
import ghidra.util.exception.DuplicateNameException;
|
||||
|
||||
public class TargetGenericRequirementsDescriptor extends SwiftTypeMetadataStructure {
|
||||
|
||||
private GenericRequirementFlags flags;
|
||||
private int param;
|
||||
private int thing;
|
||||
private GenericRequirementLayoutKind layout;
|
||||
private int genericParamIndex;
|
||||
private int protocols; // TODO: Make this a real InvertibleProtocolSet
|
||||
|
||||
/**
|
||||
* Creates a new {@link TargetGenericRequirementsDescriptor}
|
||||
*
|
||||
* @param reader A {@link BinaryReader} positioned at the start of the structure
|
||||
* @throws IOException if there was an IO-related problem creating the structure
|
||||
*/
|
||||
public TargetGenericRequirementsDescriptor(BinaryReader reader) throws IOException {
|
||||
super(reader.getPointerIndex());
|
||||
flags = new GenericRequirementFlags(reader);
|
||||
param = reader.readNextInt();
|
||||
thing = reader.readNextInt();
|
||||
layout = GenericRequirementLayoutKind.valueOf(thing); // union
|
||||
genericParamIndex = thing & 0xffff; // union
|
||||
protocols = (thing) & 0xffff; // union
|
||||
}
|
||||
|
||||
/**
|
||||
* {@return the flags}
|
||||
*/
|
||||
public GenericRequirementFlags getFlags() {
|
||||
return flags;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@return the type that's constrained, described as a mangled name}
|
||||
*/
|
||||
public int getParam() {
|
||||
return param;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@return the thing (same-type, class, protocol, conformance) the param is constrained to}
|
||||
*/
|
||||
public int getThing() {
|
||||
return thing;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@return the layout if the requirement has Layout kind; otherwise, {@code null}}
|
||||
*/
|
||||
public GenericRequirementLayoutKind getLayout() {
|
||||
return layout;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@return the index of the generic parameter whose set of invertible protocols has disabled
|
||||
* checks}
|
||||
* <p>
|
||||
* Only valid if the requirement has {@link GenericRequirementKind#IntertedProtocol} kind
|
||||
*/
|
||||
public int getGenericParamIndex() {
|
||||
return genericParamIndex;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@return the set of invertible protocols whose check is disabled}
|
||||
* <p>
|
||||
* Only valid if the requirement has {@link GenericRequirementKind#IntertedProtocol} kind
|
||||
*/
|
||||
public int getProtocols() {
|
||||
return protocols;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getStructureName() {
|
||||
return TargetGenericRequirementsDescriptor.class.getSimpleName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDescription() {
|
||||
return "generic requirements descriptor";
|
||||
}
|
||||
|
||||
@Override
|
||||
public DataType toDataType() throws DuplicateNameException, IOException {
|
||||
StructureDataType invertedProtocolsStruct = new StructureDataType(CATEGORY_PATH, "InvertedProtocols", 0);
|
||||
invertedProtocolsStruct.add(WORD, "GenericParamIndex",
|
||||
"The index of the generic parameter to which this applies.");
|
||||
invertedProtocolsStruct.add(WORD, "Protocols",
|
||||
"The set of invertiable protocols whose check is disabled.");
|
||||
|
||||
UnionDataType union =
|
||||
new UnionDataType(CATEGORY_PATH, "Union_TargetGenericRequirementsDescriptor");
|
||||
union.add(SwiftUtils.PTR_RELATIVE, "Type", "A mangled representation of the same-type or base class the param is constrained to.");
|
||||
union.add(SwiftUtils.PTR_RELATIVE, "Protocol", "The protocol the param is constrained to.");
|
||||
union.add(SwiftUtils.PTR_RELATIVE, "Conformance", "The conformance the param is constrained to use.");
|
||||
union.add(GenericRequirementLayoutKind.values()[0].toDataType(), "Layout",
|
||||
"The kind of layout constraint.");
|
||||
union.add(invertedProtocolsStruct, invertedProtocolsStruct.getName(), null);
|
||||
|
||||
StructureDataType struct = new StructureDataType(CATEGORY_PATH, getStructureName(), 0);
|
||||
struct.add(flags.toDataType(), "Flags", null);
|
||||
struct.add(SwiftUtils.PTR_RELATIVE, "Param",
|
||||
"The type that's constrained, described as a mangled name.");
|
||||
struct.add(union, union.getName(), null);
|
||||
return struct;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,104 @@
|
||||
/* ###
|
||||
* IP: GHIDRA
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package ghidra.app.util.bin.format.swift.types;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import ghidra.app.util.bin.BinaryReader;
|
||||
import ghidra.app.util.bin.format.swift.SwiftTypeMetadataStructure;
|
||||
import ghidra.app.util.bin.format.swift.SwiftUtils;
|
||||
import ghidra.program.model.data.DataType;
|
||||
import ghidra.program.model.data.StructureDataType;
|
||||
import ghidra.util.exception.DuplicateNameException;
|
||||
|
||||
public class TargetGenericWitnessTable extends SwiftTypeMetadataStructure {
|
||||
|
||||
private int witnessTableSizeInWords;
|
||||
private int witnessTablePrivateSizeInWordsAndRequiresInstantiation;
|
||||
private int instantiator;
|
||||
private int privateData;
|
||||
|
||||
/**
|
||||
* Creates a new {@link TargetGenericWitnessTable}
|
||||
*
|
||||
* @param reader A {@link BinaryReader} positioned at the start of the structure
|
||||
* @throws IOException if there was an IO-related problem creating the structure
|
||||
*/
|
||||
public TargetGenericWitnessTable(BinaryReader reader) throws IOException {
|
||||
super(reader.getPointerIndex());
|
||||
witnessTableSizeInWords = reader.readNextUnsignedShort();
|
||||
witnessTablePrivateSizeInWordsAndRequiresInstantiation = reader.readNextUnsignedShort();
|
||||
instantiator = reader.readNextInt();
|
||||
privateData = reader.readNextInt();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@return the size of the witness table in words}
|
||||
* <p>
|
||||
* The amount is copied from the witness table template into the instantiated witness table.
|
||||
*/
|
||||
public int getWitnessTableSizeInWords() {
|
||||
return witnessTableSizeInWords;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@return the amount of private storage to allocate before the address point, in words}
|
||||
* <p>
|
||||
* This memory is zeroed out in the instantiated witness table template. The low bit is used to
|
||||
* indicate whether this witness table is known to require instantiation.
|
||||
*/
|
||||
public int getWitnessTablePrivateSizeInWordsAndRequiresInstantiation() {
|
||||
return witnessTablePrivateSizeInWordsAndRequiresInstantiation;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@return the instantiation function, which is called after the template is copied}
|
||||
*/
|
||||
public int getInstantiator() {
|
||||
return instantiator;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@return the private data for the instantiator}
|
||||
* <p>
|
||||
* Might be null with building with {@code -disable-preallocated-instantiation-caches}.
|
||||
*/
|
||||
public int getPrivateData() {
|
||||
return privateData;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getStructureName() {
|
||||
return TargetGenericWitnessTable.class.getSimpleName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDescription() {
|
||||
return "generic witness table";
|
||||
}
|
||||
|
||||
@Override
|
||||
public DataType toDataType() throws DuplicateNameException, IOException {
|
||||
StructureDataType struct = new StructureDataType(CATEGORY_PATH, getStructureName(), 0);
|
||||
struct.add(WORD, "WitnessTableSizeInWords", "The size of the witness table in words.");
|
||||
struct.add(WORD, "WitnessTablePrivateSizeInWordsAndRequiresInstantiation",
|
||||
"The amount of private storage to allocate before the address point, in words.");
|
||||
struct.add(SwiftUtils.PTR_RELATIVE, "Instantiator",
|
||||
"The instantiation function, which is called after the template is copied.");
|
||||
struct.add(SwiftUtils.PTR_RELATIVE, "PrivateData", "Private data for the instantiator.");
|
||||
return struct;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,85 @@
|
||||
/* ###
|
||||
* IP: GHIDRA
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package ghidra.app.util.bin.format.swift.types;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import ghidra.app.util.bin.BinaryReader;
|
||||
import ghidra.app.util.bin.format.swift.SwiftTypeMetadataStructure;
|
||||
import ghidra.app.util.bin.format.swift.SwiftUtils;
|
||||
import ghidra.program.model.data.DataType;
|
||||
import ghidra.program.model.data.StructureDataType;
|
||||
import ghidra.util.exception.DuplicateNameException;
|
||||
|
||||
/**
|
||||
* Represents a Swift {@code TargetMethodDescriptor} structure
|
||||
*
|
||||
* @see <a href="https://github.com/swiftlang/swift/blob/main/include/swift/ABI/Metadata.h">swift/ABI/Metadata.h</a>
|
||||
*/
|
||||
public class TargetMethodDescriptor extends SwiftTypeMetadataStructure {
|
||||
|
||||
/**
|
||||
* The size (in bytes) of a {@link TargetMethodDescriptor} structure
|
||||
*/
|
||||
public static final int SIZE = 8;
|
||||
|
||||
private MethodDescriptorFlags flags;
|
||||
private int impl;
|
||||
|
||||
/**
|
||||
* Creates a new {@link TargetMethodDescriptor}
|
||||
*
|
||||
* @param reader A {@link BinaryReader} positioned at the start of the structure
|
||||
* @throws IOException if there was an IO-related problem creating the structure
|
||||
*/
|
||||
public TargetMethodDescriptor(BinaryReader reader) throws IOException {
|
||||
super(reader.getPointerIndex());
|
||||
flags = new MethodDescriptorFlags(reader);
|
||||
impl = reader.readNextInt();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@return the flags}
|
||||
*/
|
||||
public MethodDescriptorFlags getFlags() {
|
||||
return flags;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@return the method implementation's relative offset}
|
||||
*/
|
||||
public int getImpl() {
|
||||
return impl;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getStructureName() {
|
||||
return TargetMethodDescriptor.class.getSimpleName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDescription() {
|
||||
return "method descriptor";
|
||||
}
|
||||
|
||||
@Override
|
||||
public DataType toDataType() throws DuplicateNameException, IOException {
|
||||
StructureDataType struct = new StructureDataType(CATEGORY_PATH, getStructureName(), 0);
|
||||
struct.add(flags.toDataType(), "Flags", "Flags describing the method");
|
||||
struct.add(SwiftUtils.PTR_RELATIVE, "Impl", "The method implementation");
|
||||
return struct;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,96 @@
|
||||
/* ###
|
||||
* IP: GHIDRA
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package ghidra.app.util.bin.format.swift.types;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import ghidra.app.util.bin.BinaryReader;
|
||||
import ghidra.app.util.bin.format.swift.SwiftTypeMetadataStructure;
|
||||
import ghidra.app.util.bin.format.swift.SwiftUtils;
|
||||
import ghidra.program.model.data.DataType;
|
||||
import ghidra.program.model.data.StructureDataType;
|
||||
import ghidra.util.exception.DuplicateNameException;
|
||||
|
||||
/**
|
||||
* Represents a Swift {@code TargetMethodOverrideDescriptor} structure
|
||||
*
|
||||
* @see <a href="https://github.com/swiftlang/swift/blob/main/include/swift/ABI/Metadata.h">swift/ABI/Metadata.h</a>
|
||||
*/
|
||||
public class TargetMethodOverrideDescriptor extends SwiftTypeMetadataStructure {
|
||||
|
||||
/**
|
||||
* The size (in bytes) of a {@link TargetMethodOverrideDescriptor} structure
|
||||
*/
|
||||
public static final int SIZE = 8;
|
||||
|
||||
private int classPtr;
|
||||
private int methodPtr;
|
||||
private int impl;
|
||||
|
||||
/**
|
||||
* Creates a new {@link TargetMethodOverrideDescriptor}
|
||||
*
|
||||
* @param reader A {@link BinaryReader} positioned at the start of the structure
|
||||
* @throws IOException if there was an IO-related problem creating the structure
|
||||
*/
|
||||
public TargetMethodOverrideDescriptor(BinaryReader reader) throws IOException {
|
||||
super(reader.getPointerIndex());
|
||||
classPtr = reader.readNextInt();
|
||||
methodPtr = reader.readNextInt();
|
||||
impl = reader.readNextInt();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@return the class containing the base method}
|
||||
*/
|
||||
public int getClassPtr() {
|
||||
return classPtr;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@return the base method}
|
||||
*/
|
||||
public int getMethodPtr() {
|
||||
return methodPtr;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@return the implementation of the override}
|
||||
*/
|
||||
public int getImpl() {
|
||||
return impl;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getStructureName() {
|
||||
return TargetMethodOverrideDescriptor.class.getSimpleName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDescription() {
|
||||
return "method override descriptor";
|
||||
}
|
||||
|
||||
@Override
|
||||
public DataType toDataType() throws DuplicateNameException, IOException {
|
||||
StructureDataType struct = new StructureDataType(CATEGORY_PATH, getStructureName(), 0);
|
||||
struct.add(SwiftUtils.PTR_RELATIVE_MASKED, "Class",
|
||||
"The class containing the base method.");
|
||||
struct.add(SwiftUtils.PTR_RELATIVE_MASKED, "Method", "The base method.");
|
||||
struct.add(SwiftUtils.PTR_RELATIVE, "Impl", "The implementation of the override");
|
||||
return struct;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,79 @@
|
||||
/* ###
|
||||
* IP: GHIDRA
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package ghidra.app.util.bin.format.swift.types;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import ghidra.app.util.bin.BinaryReader;
|
||||
import ghidra.app.util.bin.format.swift.SwiftTypeMetadataStructure;
|
||||
import ghidra.app.util.bin.format.swift.SwiftUtils;
|
||||
import ghidra.program.model.data.DataType;
|
||||
import ghidra.program.model.data.StructureDataType;
|
||||
import ghidra.util.exception.DuplicateNameException;
|
||||
|
||||
/**
|
||||
* Represents a Swift {@code TargetObjCResilientClassStubInfo} structure
|
||||
*
|
||||
* @see <a href="https://github.com/swiftlang/swift/blob/main/include/swift/ABI/Metadata.h">swift/ABI/Metadata.h</a>
|
||||
*/
|
||||
public class TargetObjCResilientClassStubInfo extends SwiftTypeMetadataStructure {
|
||||
|
||||
private int stub;
|
||||
|
||||
/**
|
||||
* Create a new {@link TargetObjCResilientClassStubInfo}
|
||||
*
|
||||
* @param reader A {@link BinaryReader} positioned at the start of the structure
|
||||
* @throws IOException if there was an IO-related problem creating the structure
|
||||
*/
|
||||
public TargetObjCResilientClassStubInfo(BinaryReader reader) throws IOException {
|
||||
super(reader.getPointerIndex());
|
||||
stub = reader.readNextInt();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@return a relative pointer to an Objective-C resilient class stub}
|
||||
*/
|
||||
public int getStub() {
|
||||
return stub;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getStructureName() {
|
||||
return getMyStructureName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDescription() {
|
||||
return "objc resilient class stub";
|
||||
}
|
||||
|
||||
/**
|
||||
* {@return this class's structure name (will not be affected by subclass's name)}
|
||||
*/
|
||||
private final String getMyStructureName() {
|
||||
return TargetObjCResilientClassStubInfo.class.getSimpleName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public DataType toDataType() throws DuplicateNameException, IOException {
|
||||
StructureDataType struct = new StructureDataType(CATEGORY_PATH, getMyStructureName(), 0);
|
||||
struct.add(SwiftUtils.PTR_RELATIVE, "Stub",
|
||||
"A relative pointer to an Objective-C resilient class stub.");
|
||||
return struct;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,71 @@
|
||||
/* ###
|
||||
* IP: GHIDRA
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package ghidra.app.util.bin.format.swift.types;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import ghidra.app.util.bin.BinaryReader;
|
||||
import ghidra.app.util.bin.format.swift.SwiftTypeMetadataStructure;
|
||||
import ghidra.program.model.data.DataType;
|
||||
import ghidra.program.model.data.StructureDataType;
|
||||
import ghidra.util.exception.DuplicateNameException;
|
||||
|
||||
/**
|
||||
* Represents a Swift {@code TargetOverrideTableHeader} structure
|
||||
*
|
||||
* @see <a href="https://github.com/swiftlang/swift/blob/main/include/swift/ABI/Metadata.h">swift/ABI/Metadata.h</a>
|
||||
*/
|
||||
public class TargetOverrideTableHeader extends SwiftTypeMetadataStructure {
|
||||
|
||||
private long numEntries;
|
||||
|
||||
/**
|
||||
* Creates a new {@link TargetOverrideTableHeader}
|
||||
*
|
||||
* @param reader A {@link BinaryReader} positioned at the start of the structure
|
||||
* @throws IOException if there was an IO-related problem creating the structure
|
||||
*/
|
||||
public TargetOverrideTableHeader(BinaryReader reader) throws IOException {
|
||||
super(reader.getPointerIndex());
|
||||
numEntries = reader.readNextUnsignedInt();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@return the number of MethodOverrideDescriptor records following the vtable override header
|
||||
* in the class's nominal type descriptor}
|
||||
*/
|
||||
public long getNumEntries() {
|
||||
return numEntries;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getStructureName() {
|
||||
return TargetOverrideTableHeader.class.getSimpleName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDescription() {
|
||||
return "override table header";
|
||||
}
|
||||
|
||||
@Override
|
||||
public DataType toDataType() throws DuplicateNameException, IOException {
|
||||
StructureDataType struct = new StructureDataType(CATEGORY_PATH, getStructureName(), 0);
|
||||
struct.add(DWORD, "NumEntries",
|
||||
"The number of MethodOverrideDescriptor records following the vtable override header in the class's nominal type descriptor.");
|
||||
return struct;
|
||||
}
|
||||
}
|
||||
@@ -16,24 +16,33 @@
|
||||
package ghidra.app.util.bin.format.swift.types;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import ghidra.app.util.bin.BinaryReader;
|
||||
import ghidra.app.util.bin.format.swift.SwiftTypeMetadataStructure;
|
||||
import ghidra.app.util.bin.format.swift.SwiftUtils;
|
||||
import ghidra.program.model.data.*;
|
||||
import ghidra.program.model.data.DataType;
|
||||
import ghidra.program.model.data.StructureDataType;
|
||||
import ghidra.util.exception.DuplicateNameException;
|
||||
|
||||
/**
|
||||
* Represents a Swift TargetProtocolConformanceDescriptor structure
|
||||
* Represents a Swift {@code TargetProtocolConformanceDescriptor} structure
|
||||
*
|
||||
* @see <a href="https://github.com/swiftlang/swift/blob/main/include/swift/ABI/Metadata.h">swift/ABI/Metadata.h</a>
|
||||
*/
|
||||
public final class TargetProtocolConformanceDescriptor extends SwiftTypeMetadataStructure {
|
||||
|
||||
private int protocolDescriptor;
|
||||
private int nominalTypeDescriptor;
|
||||
private int protocolWitnessTable;
|
||||
private int conformanceFlags;
|
||||
private int protocol;
|
||||
private int typeRef;
|
||||
private int witnessTablePattern;
|
||||
private ConformanceFlags flags;
|
||||
|
||||
// Trailing objects
|
||||
private TargetRelativeContextPointer retroactiveContext;
|
||||
private TargetResilientWitnessHeader resilientWitnessHeader;
|
||||
private List<TargetResilientWitness> resilientWitnesses = new ArrayList<>();
|
||||
private TargetGenericWitnessTable genericWitnessTable;
|
||||
|
||||
/**
|
||||
* Creates a new {@link TargetProtocolConformanceDescriptor}
|
||||
@@ -43,46 +52,98 @@ public final class TargetProtocolConformanceDescriptor extends SwiftTypeMetadata
|
||||
*/
|
||||
public TargetProtocolConformanceDescriptor(BinaryReader reader) throws IOException {
|
||||
super(reader.getPointerIndex());
|
||||
protocolDescriptor = reader.readNextInt();
|
||||
nominalTypeDescriptor = reader.readNextInt();
|
||||
protocolWitnessTable = reader.readNextInt();
|
||||
conformanceFlags = reader.readNextInt();
|
||||
protocol = reader.readNextInt();
|
||||
typeRef = reader.readNextInt();
|
||||
witnessTablePattern = reader.readNextInt();
|
||||
flags = new ConformanceFlags(reader);
|
||||
|
||||
if (flags.isRetroactive()) {
|
||||
retroactiveContext = new TargetRelativeContextPointer(reader);
|
||||
}
|
||||
|
||||
if (flags.hasResilientWitnesses()) {
|
||||
resilientWitnessHeader = new TargetResilientWitnessHeader(reader);
|
||||
for (int i = 0; i < resilientWitnessHeader.getNumWitnesses(); i++) {
|
||||
resilientWitnesses.add(new TargetResilientWitness(reader));
|
||||
}
|
||||
}
|
||||
|
||||
if (flags.hasGenericWitnessTable()) {
|
||||
genericWitnessTable = new TargetGenericWitnessTable(reader);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the protocol being conformed to
|
||||
*
|
||||
* @return The protocol being conformed to
|
||||
* {@return the protocol being conformed to}
|
||||
*/
|
||||
public int getProtocolDescriptor() {
|
||||
return protocolDescriptor;
|
||||
public int getProtocol() {
|
||||
return protocol;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets some description of the type that conforms to the protocol
|
||||
*
|
||||
* @return Some description of the type that conforms to the protocol
|
||||
* {@return some description of the type that conforms to the protocol}
|
||||
*/
|
||||
public int getNominalTypeDescriptor() {
|
||||
return nominalTypeDescriptor;
|
||||
public int getTypeRef() {
|
||||
return typeRef;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the witness table pattern, which may also serve as the witness table
|
||||
*
|
||||
* @return The witness table pattern, which may also serve as the witness table
|
||||
* {@return the witness table pattern, which may also serve as the witness table}
|
||||
*/
|
||||
public int getProtocolWitnessTable() {
|
||||
return protocolWitnessTable;
|
||||
public int getWitnessTablePattern() {
|
||||
return witnessTablePattern;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets various flags, including the kind of conformance
|
||||
*
|
||||
* @return Various flags, including the kind of conformance
|
||||
* {@return various flags, including the kind of conformance}
|
||||
*/
|
||||
public int getConformanceFlags() {
|
||||
return conformanceFlags;
|
||||
public ConformanceFlags getConformanceFlags() {
|
||||
return flags;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@return the {@link TargetRelativeContextPointer retroactive context}, or {@code null} if it
|
||||
* doesn't exist}
|
||||
*/
|
||||
public TargetRelativeContextPointer getRetroactiveContext() {
|
||||
return retroactiveContext;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@return the {@link TargetResilientWitnessHeader}, or {@code null} if it doesn't exist}
|
||||
*/
|
||||
public TargetResilientWitnessHeader getResilientWitnessHeader() {
|
||||
return resilientWitnessHeader;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@return the {@link List} of resilient witnesses}
|
||||
*/
|
||||
public List<TargetResilientWitness> getResilientWitnesses() {
|
||||
return resilientWitnesses;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@return the {@link TargetGenericWitnessTable}, or {@code null} if it doesn't exist}
|
||||
*/
|
||||
public TargetGenericWitnessTable getGenericWitnessTable() {
|
||||
return genericWitnessTable;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<SwiftTypeMetadataStructure> getTrailingObjects() {
|
||||
List<SwiftTypeMetadataStructure> ret = new ArrayList<>();
|
||||
if (retroactiveContext != null) {
|
||||
ret.add(retroactiveContext);
|
||||
}
|
||||
if (resilientWitnessHeader != null) {
|
||||
ret.add(resilientWitnessHeader);
|
||||
ret.addAll(resilientWitnesses);
|
||||
}
|
||||
if (genericWitnessTable != null) {
|
||||
ret.add(genericWitnessTable);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -97,14 +158,13 @@ public final class TargetProtocolConformanceDescriptor extends SwiftTypeMetadata
|
||||
|
||||
@Override
|
||||
public DataType toDataType() throws DuplicateNameException, IOException {
|
||||
StructureDataType struct = new StructureDataType(getStructureName(), 0);
|
||||
struct.add(DWORD, "ProtocolDescriptor", "The protocol being conformed to");
|
||||
struct.add(SwiftUtils.PTR_RELATIVE, "NominalTypeDescriptor",
|
||||
StructureDataType struct = new StructureDataType(CATEGORY_PATH, getStructureName(), 0);
|
||||
struct.add(SwiftUtils.PTR_RELATIVE_MASKED, "Protocol", "The protocol being conformed to");
|
||||
struct.add(SwiftUtils.PTR_RELATIVE, "TypeRef",
|
||||
"Some description of the type that conforms to the protocol");
|
||||
struct.add(DWORD, "ProtocolWitnessTable",
|
||||
struct.add(DWORD, "WitnessTablePattern",
|
||||
"The witness table pattern, which may also serve as the witness table");
|
||||
struct.add(DWORD, "ConformanceFlags", "Various flags, including the kind of conformance");
|
||||
struct.setCategoryPath(new CategoryPath(DATA_TYPE_CATEGORY));
|
||||
struct.add(flags.toDataType(), "Flags", "Various flags, including the kind of conformance");
|
||||
return struct;
|
||||
}
|
||||
|
||||
|
||||
@@ -16,16 +16,18 @@
|
||||
package ghidra.app.util.bin.format.swift.types;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import ghidra.app.util.bin.BinaryReader;
|
||||
import ghidra.app.util.bin.format.swift.SwiftTypeMetadataStructure;
|
||||
import ghidra.app.util.bin.format.swift.SwiftUtils;
|
||||
import ghidra.program.model.data.CategoryPath;
|
||||
import ghidra.program.model.data.DataType;
|
||||
import ghidra.program.model.data.StructureDataType;
|
||||
import ghidra.util.exception.DuplicateNameException;
|
||||
|
||||
/**
|
||||
* Represents a Swift TargetProtocolDescriptor structure
|
||||
* Represents a Swift {@code TargetProtocolDescriptor} structure
|
||||
*
|
||||
* @see <a href="https://github.com/swiftlang/swift/blob/main/include/swift/ABI/Metadata.h">swift/ABI/Metadata.h</a>
|
||||
*/
|
||||
@@ -36,6 +38,9 @@ public final class TargetProtocolDescriptor extends TargetContextDescriptor {
|
||||
private int numRequirements;
|
||||
private int associatedTypeNames;
|
||||
|
||||
private List<TargetGenericRequirementsDescriptor> requirementsInSig = new ArrayList<>();
|
||||
private List<TargetProtocolRequirement> requirements = new ArrayList<>();
|
||||
|
||||
/**
|
||||
* Creates a new {@link TargetProtocolDescriptor}
|
||||
*
|
||||
@@ -48,49 +53,70 @@ public final class TargetProtocolDescriptor extends TargetContextDescriptor {
|
||||
numRequirementsInSig = reader.readNextInt();
|
||||
numRequirements = reader.readNextInt();
|
||||
associatedTypeNames = reader.readNextInt();
|
||||
|
||||
for (int i = 0; i < numRequirementsInSig; i++) {
|
||||
requirementsInSig.add(new TargetGenericRequirementsDescriptor(reader));
|
||||
}
|
||||
for (int i = 0; i < numRequirements; i++) {
|
||||
requirements.add(new TargetProtocolRequirement(reader));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the name of the protocol
|
||||
*
|
||||
* @return The name of the protocol
|
||||
* {@return the name of the protocol}
|
||||
*/
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the number of generic requirements in the requirement signature of the protocol
|
||||
*
|
||||
* @return The number of generic requirements in the requirement signature of the protocol
|
||||
* {@return the number of generic requirements in the requirement signature of the protocol}
|
||||
*/
|
||||
public int getNumRequirementsInSignature() {
|
||||
return numRequirementsInSig;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the number of requirements in the protocol
|
||||
*
|
||||
* @return The number of requirements in the protocol
|
||||
* {@return the number of requirements in the protocol}
|
||||
*/
|
||||
public int getNumRequirements() {
|
||||
return numRequirements;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the associated type names
|
||||
*
|
||||
* @return The associated type names
|
||||
* @return the associated type names}
|
||||
*/
|
||||
public int getAssociatedTypeNames() {
|
||||
return associatedTypeNames; // TODO: it's a list...improve
|
||||
}
|
||||
|
||||
/**
|
||||
* {@return a {@link List} of generic requirements in the requirement signature of the protocol}
|
||||
*/
|
||||
public List<TargetGenericRequirementsDescriptor> getRequirementsInSignature() {
|
||||
return requirementsInSig;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@return a {@link List} of requirements in the protocol}
|
||||
*/
|
||||
public List<TargetProtocolRequirement> getRequirements() {
|
||||
return requirements;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<SwiftTypeMetadataStructure> getTrailingObjects() {
|
||||
List<SwiftTypeMetadataStructure> ret = new ArrayList<>();
|
||||
ret.addAll(requirementsInSig);
|
||||
ret.addAll(requirements);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getStructureName() {
|
||||
return TargetProtocolDescriptor.class.getSimpleName();
|
||||
@@ -103,15 +129,14 @@ public final class TargetProtocolDescriptor extends TargetContextDescriptor {
|
||||
|
||||
@Override
|
||||
public DataType toDataType() throws DuplicateNameException, IOException {
|
||||
StructureDataType struct = new StructureDataType(getStructureName(), 0);
|
||||
StructureDataType struct = new StructureDataType(CATEGORY_PATH, getStructureName(), 0);
|
||||
struct.add(super.toDataType(), super.getStructureName(), "");
|
||||
struct.add(SwiftUtils.PTR_STRING, "Name", "The name of the protocol");
|
||||
struct.add(DWORD, "NumRequirementsInSignature",
|
||||
"The number of generic requirements in the requirement signature of the protocol");
|
||||
struct.add(DWORD, "NumRequirements", "The number of requirements in the protocol");
|
||||
struct.add(DWORD, "AssociatedTypeNames",
|
||||
struct.add(SwiftUtils.PTR_RELATIVE, "AssociatedTypeNames",
|
||||
"Associated type names, as a space-separated list in the same order as the requirements");
|
||||
struct.setCategoryPath(new CategoryPath(DATA_TYPE_CATEGORY));
|
||||
return struct;
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,79 @@
|
||||
/* ###
|
||||
* IP: GHIDRA
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package ghidra.app.util.bin.format.swift.types;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import ghidra.app.util.bin.BinaryReader;
|
||||
import ghidra.app.util.bin.format.swift.SwiftTypeMetadataStructure;
|
||||
import ghidra.app.util.bin.format.swift.SwiftUtils;
|
||||
import ghidra.program.model.data.*;
|
||||
import ghidra.util.exception.DuplicateNameException;
|
||||
|
||||
public class TargetProtocolRequirement extends SwiftTypeMetadataStructure {
|
||||
|
||||
private ProtocolRequirementFlags flags;
|
||||
private int impl;
|
||||
|
||||
/**
|
||||
* Creates a new {@link TargetProtocolRequirement}
|
||||
*
|
||||
* @param reader A {@link BinaryReader} positioned at the start of the structure
|
||||
* @throws IOException if there was an IO-related problem creating the structure
|
||||
*/
|
||||
public TargetProtocolRequirement(BinaryReader reader) throws IOException {
|
||||
super(reader.getPointerIndex());
|
||||
flags = new ProtocolRequirementFlags(reader);
|
||||
impl = reader.readNextInt();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@return the flags}
|
||||
*/
|
||||
public ProtocolRequirementFlags getFlags() {
|
||||
return flags;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@return the optional default implementation of the protocol}
|
||||
*/
|
||||
public int getImpl() {
|
||||
return impl;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getStructureName() {
|
||||
return TargetProtocolRequirement.class.getSimpleName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDescription() {
|
||||
return "protocol requirement";
|
||||
}
|
||||
|
||||
@Override
|
||||
public DataType toDataType() throws DuplicateNameException, IOException {
|
||||
UnionDataType union = new UnionDataType(CATEGORY_PATH,
|
||||
"Union_DefaultFuncImplementation_DefaultImplementation");
|
||||
union.add(SwiftUtils.PTR_RELATIVE, "DefaultFuncImplementation", null);
|
||||
union.add(SwiftUtils.PTR_RELATIVE, "DefaultImplementation", null);
|
||||
|
||||
StructureDataType struct = new StructureDataType(CATEGORY_PATH, getStructureName(), 0);
|
||||
struct.add(flags.toDataType(), "Flags", null);
|
||||
struct.add(union, "Implementation", "The optional default implementation.");
|
||||
return struct;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,67 @@
|
||||
/* ###
|
||||
* IP: GHIDRA
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package ghidra.app.util.bin.format.swift.types;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import ghidra.app.util.bin.BinaryReader;
|
||||
import ghidra.app.util.bin.format.swift.SwiftTypeMetadataStructure;
|
||||
import ghidra.app.util.bin.format.swift.SwiftUtils;
|
||||
import ghidra.program.model.data.DataType;
|
||||
import ghidra.util.exception.DuplicateNameException;
|
||||
|
||||
/**
|
||||
* Represents a Swift {@code TargetRelativeContextPointer} structure
|
||||
*
|
||||
* @see <a href="https://github.com/swiftlang/swift/blob/main/include/swift/ABI/MetadataRef.h">swift/ABI/MetadataRef.h</a>
|
||||
*/
|
||||
public class TargetRelativeContextPointer extends SwiftTypeMetadataStructure {
|
||||
|
||||
private int value;
|
||||
|
||||
/**
|
||||
* Creates a new {@link TargetRelativeContextPointer}
|
||||
*
|
||||
* @param reader A {@link BinaryReader} positioned at the start of the structure
|
||||
* @throws IOException if there was an IO-related problem creating the structure
|
||||
*/
|
||||
public TargetRelativeContextPointer(BinaryReader reader) throws IOException {
|
||||
super(reader.getPointerIndex());
|
||||
value = reader.readNextInt();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@return the pointer value}
|
||||
*/
|
||||
public long getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getStructureName() {
|
||||
return TargetRelativeContextPointer.class.getSimpleName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDescription() {
|
||||
return "relative context pointer";
|
||||
}
|
||||
|
||||
@Override
|
||||
public DataType toDataType() throws DuplicateNameException, IOException {
|
||||
return SwiftUtils.PTR_RELATIVE_MASKED;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,72 @@
|
||||
/* ###
|
||||
* IP: GHIDRA
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package ghidra.app.util.bin.format.swift.types;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import ghidra.app.util.bin.BinaryReader;
|
||||
import ghidra.app.util.bin.format.swift.SwiftTypeMetadataStructure;
|
||||
import ghidra.program.model.data.*;
|
||||
import ghidra.util.exception.DuplicateNameException;
|
||||
|
||||
/**
|
||||
* Represents a Swift {@code TargetRelativeContextPointer} structure
|
||||
*
|
||||
* @see <a href="https://github.com/swiftlang/swift/blob/main/include/swift/ABI/Metadata.h">swift/ABI/Metadata.h</a>
|
||||
*/
|
||||
public class TargetRelativeProtocolRequirementPointer extends SwiftTypeMetadataStructure {
|
||||
|
||||
public static final TypeDef dataType =
|
||||
new PointerTypedefBuilder(Pointer32DataType.dataType, null)
|
||||
.type(PointerType.RELATIVE)
|
||||
.bitMask(~1)
|
||||
.build();
|
||||
|
||||
private int value;
|
||||
|
||||
/**
|
||||
* Creates a new {@link TargetRelativeProtocolRequirementPointer}
|
||||
*
|
||||
* @param reader A {@link BinaryReader} positioned at the start of the structure
|
||||
* @throws IOException if there was an IO-related problem creating the structure
|
||||
*/
|
||||
public TargetRelativeProtocolRequirementPointer(BinaryReader reader) throws IOException {
|
||||
super(reader.getPointerIndex());
|
||||
value = reader.readNextInt();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@return the pointer value}
|
||||
*/
|
||||
public long getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getStructureName() {
|
||||
return TargetRelativeProtocolRequirementPointer.class.getSimpleName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDescription() {
|
||||
return "relative protocol requirement pointer";
|
||||
}
|
||||
|
||||
@Override
|
||||
public DataType toDataType() throws DuplicateNameException, IOException {
|
||||
return dataType;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,78 @@
|
||||
/* ###
|
||||
* IP: GHIDRA
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package ghidra.app.util.bin.format.swift.types;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import ghidra.app.util.bin.BinaryReader;
|
||||
import ghidra.app.util.bin.format.swift.SwiftTypeMetadataStructure;
|
||||
import ghidra.app.util.bin.format.swift.SwiftUtils;
|
||||
import ghidra.program.model.data.DataType;
|
||||
import ghidra.program.model.data.StructureDataType;
|
||||
import ghidra.util.exception.DuplicateNameException;
|
||||
|
||||
/**
|
||||
* Represents a Swift {@code TargetResilientSuperclass} structure
|
||||
*
|
||||
* @see <a href="https://github.com/swiftlang/swift/blob/main/include/swift/ABI/Metadata.h">swift/ABI/Metadata.h</a>
|
||||
*/
|
||||
public class TargetResilientSuperclass extends SwiftTypeMetadataStructure {
|
||||
|
||||
private int superclass;
|
||||
|
||||
/**
|
||||
* Create a new {@link TargetResilientSuperclass}
|
||||
*
|
||||
* @param reader A {@link BinaryReader} positioned at the start of the structure
|
||||
* @throws IOException if there was an IO-related problem creating the structure
|
||||
*/
|
||||
public TargetResilientSuperclass(BinaryReader reader) throws IOException {
|
||||
super(reader.getPointerIndex());
|
||||
superclass = reader.readNextInt();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@return the superclass of this class, or 0 if there isn't one}
|
||||
*/
|
||||
public int getSuperclass() {
|
||||
return superclass;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getStructureName() {
|
||||
return getMyStructureName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDescription() {
|
||||
return "resilient superclass";
|
||||
}
|
||||
|
||||
/**
|
||||
* {@return this class's structure name (will not be affected by subclass's name)}
|
||||
*/
|
||||
private final String getMyStructureName() {
|
||||
return TargetResilientSuperclass.class.getSimpleName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public DataType toDataType() throws DuplicateNameException, IOException {
|
||||
StructureDataType struct = new StructureDataType(CATEGORY_PATH, getMyStructureName(), 0);
|
||||
struct.add(SwiftUtils.PTR_RELATIVE, "Superclass", "The superclass of this class.");
|
||||
return struct;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,79 @@
|
||||
/* ###
|
||||
* IP: GHIDRA
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package ghidra.app.util.bin.format.swift.types;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import ghidra.app.util.bin.BinaryReader;
|
||||
import ghidra.app.util.bin.format.swift.SwiftTypeMetadataStructure;
|
||||
import ghidra.app.util.bin.format.swift.SwiftUtils;
|
||||
import ghidra.program.model.data.*;
|
||||
import ghidra.util.exception.DuplicateNameException;
|
||||
|
||||
public class TargetResilientWitness extends SwiftTypeMetadataStructure {
|
||||
|
||||
private TargetRelativeProtocolRequirementPointer requirement;
|
||||
private int impl;
|
||||
|
||||
/**
|
||||
* Creates a new {@link TargetResilientWitness}
|
||||
*
|
||||
* @param reader A {@link BinaryReader} positioned at the start of the structure
|
||||
* @throws IOException if there was an IO-related problem creating the structure
|
||||
*/
|
||||
public TargetResilientWitness(BinaryReader reader) throws IOException {
|
||||
super(reader.getPointerIndex());
|
||||
requirement = new TargetRelativeProtocolRequirementPointer(reader);
|
||||
impl = reader.readNextInt();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@return the requirement}
|
||||
*/
|
||||
public TargetRelativeProtocolRequirementPointer getRequirement() {
|
||||
return requirement;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@return the implementation}
|
||||
*/
|
||||
public int getImpl() {
|
||||
return impl;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getStructureName() {
|
||||
return TargetResilientWitness.class.getSimpleName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDescription() {
|
||||
return "resilient witness";
|
||||
}
|
||||
|
||||
@Override
|
||||
public DataType toDataType() throws DuplicateNameException, IOException {
|
||||
UnionDataType union = new UnionDataType(CATEGORY_PATH,
|
||||
"Union_Impl_FuncImpl");
|
||||
union.add(SwiftUtils.PTR_RELATIVE, "Impl", null);
|
||||
union.add(SwiftUtils.PTR_RELATIVE, "FuncImpl", null);
|
||||
|
||||
StructureDataType struct = new StructureDataType(CATEGORY_PATH, getStructureName(), 0);
|
||||
struct.add(TargetRelativeProtocolRequirementPointer.dataType, "Requirement", null);
|
||||
struct.add(union, "Implementation", null);
|
||||
return struct;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,69 @@
|
||||
/* ###
|
||||
* IP: GHIDRA
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package ghidra.app.util.bin.format.swift.types;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import ghidra.app.util.bin.BinaryReader;
|
||||
import ghidra.app.util.bin.format.swift.SwiftTypeMetadataStructure;
|
||||
import ghidra.program.model.data.DataType;
|
||||
import ghidra.program.model.data.StructureDataType;
|
||||
import ghidra.util.exception.DuplicateNameException;
|
||||
|
||||
/**
|
||||
* Represents a Swift {@code TargetResilientWitnessHeader} structure
|
||||
*
|
||||
* @see <a href="https://github.com/swiftlang/swift/blob/main/include/swift/ABI/Metadata.h">swift/ABI/Metadata.h</a>
|
||||
*/
|
||||
public class TargetResilientWitnessHeader extends SwiftTypeMetadataStructure {
|
||||
|
||||
private long numWitnesses;
|
||||
|
||||
/**
|
||||
* Creates a new {@link TargetResilientWitnessHeader}
|
||||
*
|
||||
* @param reader A {@link BinaryReader} positioned at the start of the structure
|
||||
* @throws IOException if there was an IO-related problem creating the structure
|
||||
*/
|
||||
public TargetResilientWitnessHeader(BinaryReader reader) throws IOException {
|
||||
super(reader.getPointerIndex());
|
||||
numWitnesses = reader.readNextUnsignedInt();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@return the number of witnesses}
|
||||
*/
|
||||
public long getNumWitnesses() {
|
||||
return numWitnesses;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getStructureName() {
|
||||
return TargetResilientWitnessHeader.class.getSimpleName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDescription() {
|
||||
return "resilient witness header";
|
||||
}
|
||||
|
||||
@Override
|
||||
public DataType toDataType() throws DuplicateNameException, IOException {
|
||||
StructureDataType struct = new StructureDataType(CATEGORY_PATH, getStructureName(), 0);
|
||||
struct.add(DWORD, "NumWitnesses", null);
|
||||
return struct;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,114 @@
|
||||
/* ###
|
||||
* IP: GHIDRA
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package ghidra.app.util.bin.format.swift.types;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import ghidra.app.util.bin.BinaryReader;
|
||||
import ghidra.app.util.bin.format.swift.SwiftTypeMetadataStructure;
|
||||
import ghidra.app.util.bin.format.swift.SwiftUtils;
|
||||
import ghidra.program.model.data.*;
|
||||
import ghidra.util.exception.DuplicateNameException;
|
||||
|
||||
/**
|
||||
* Represents a Swift {@code TargetSingletonMetadataInitialization} structure
|
||||
*
|
||||
* @see <a href="https://github.com/swiftlang/swift/blob/main/include/swift/ABI/Metadata.h">swift/ABI/Metadata.h</a>
|
||||
*/
|
||||
public class TargetSingletonMetadataInitialization extends SwiftTypeMetadataStructure {
|
||||
|
||||
private ContextDescriptorFlags flags;
|
||||
|
||||
private int initializationCache;
|
||||
private int incompleteMetadata;
|
||||
private int resilientPattern;
|
||||
private int completionFunction;
|
||||
|
||||
/**
|
||||
* Creates a new {@link TargetSingletonMetadataInitialization}
|
||||
*
|
||||
* @param reader A {@link BinaryReader} positioned at the start of the structure
|
||||
* @param flags The {@link ContextDescriptorFlags}
|
||||
* @throws IOException if there was an IO-related problem creating the structure
|
||||
*/
|
||||
public TargetSingletonMetadataInitialization(BinaryReader reader, ContextDescriptorFlags flags)
|
||||
throws IOException {
|
||||
super(reader.getPointerIndex());
|
||||
this.flags = flags;
|
||||
initializationCache = reader.readNextInt();
|
||||
incompleteMetadata = reader.readNextInt();
|
||||
resilientPattern = incompleteMetadata;
|
||||
completionFunction = reader.readNextInt();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@return the initialization cache}
|
||||
*/
|
||||
public int getInitializationCache() {
|
||||
return initializationCache;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@return the incomplete metadata for structs, enums, and classes if there is no resilient
|
||||
* ancestry; otherwise, 0}
|
||||
*/
|
||||
public int getIncompleteMetadata() {
|
||||
return !flags.hasClassResilientSuperclass() ? incompleteMetadata : 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@return a pattern used to allocation and initialize metadata for this class if there is a
|
||||
* resilient superclass; otherwise, 0}
|
||||
*/
|
||||
public int getResilientPattern() {
|
||||
return flags.hasClassResilientSuperclass() ? resilientPattern : 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@return the completion function (the pattern will always be null, even for a resilient
|
||||
* class)}
|
||||
*/
|
||||
public int getCompletionFunction() {
|
||||
return completionFunction;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getStructureName() {
|
||||
return TargetSingletonMetadataInitialization.class.getSimpleName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDescription() {
|
||||
return "singleton metadata initialization";
|
||||
}
|
||||
|
||||
@Override
|
||||
public DataType toDataType() throws DuplicateNameException, IOException {
|
||||
UnionDataType union =
|
||||
new UnionDataType(CATEGORY_PATH, "Union_IncompleteMetadata_ResilientPattern");
|
||||
union.add(SwiftUtils.PTR_RELATIVE, "IncompleteMetadata",
|
||||
"The incomplete metadata, for structs, enums and classes without resilient ancestry.");
|
||||
union.add(SwiftUtils.PTR_RELATIVE, "ResilientPattern",
|
||||
"If the classes descriptor has a resilient superclass, this points at a pattern used to allcoate and initialize metadata for this class, since its size and contents is not known at compile time.");
|
||||
|
||||
StructureDataType struct = new StructureDataType(CATEGORY_PATH, getStructureName(), 0);
|
||||
struct.add(SwiftUtils.PTR_RELATIVE, "InitializationCache", "The initialization cache.");
|
||||
struct.add(union, union.getName(), null);
|
||||
struct.add(SwiftUtils.PTR_RELATIVE, "CompletionFunction",
|
||||
"The completion function. The pattern will always be null, even for a resilient class.");
|
||||
return struct;
|
||||
}
|
||||
}
|
||||
@@ -16,15 +16,17 @@
|
||||
package ghidra.app.util.bin.format.swift.types;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import ghidra.app.util.bin.BinaryReader;
|
||||
import ghidra.program.model.data.CategoryPath;
|
||||
import ghidra.app.util.bin.format.swift.SwiftTypeMetadataStructure;
|
||||
import ghidra.program.model.data.DataType;
|
||||
import ghidra.program.model.data.StructureDataType;
|
||||
import ghidra.util.exception.DuplicateNameException;
|
||||
|
||||
/**
|
||||
* Represents a Swift TargetStructDescriptor structure
|
||||
* Represents a Swift {@code TargetStructDescriptor} structure
|
||||
*
|
||||
* @see <a href="https://github.com/swiftlang/swift/blob/main/include/swift/ABI/Metadata.h">swift/ABI/Metadata.h</a>
|
||||
*/
|
||||
@@ -33,6 +35,11 @@ public final class TargetStructDescriptor extends TargetTypeContextDescriptor {
|
||||
private int numFields;
|
||||
private int fieldOffsetVectorOffset;
|
||||
|
||||
// Trailing objects
|
||||
private TargetTypeGenericContextDescriptorHeader genericHeader;
|
||||
private TargetSingletonMetadataInitialization singleton;
|
||||
private TargetForeignMetadataInitialization foreign;
|
||||
|
||||
/**
|
||||
* Creates a new {@link TargetStructDescriptor}
|
||||
*
|
||||
@@ -43,30 +50,93 @@ public final class TargetStructDescriptor extends TargetTypeContextDescriptor {
|
||||
super(reader);
|
||||
numFields = reader.readNextInt();
|
||||
fieldOffsetVectorOffset = reader.readNextInt();
|
||||
|
||||
if (flags.isGeneric()) {
|
||||
genericHeader = new TargetTypeGenericContextDescriptorHeader(reader);
|
||||
}
|
||||
|
||||
switch (flags.getMetadataInitialization()) {
|
||||
case NoMetadataInitialization:
|
||||
break;
|
||||
case SingletonMetadataInitialization:
|
||||
singleton = new TargetSingletonMetadataInitialization(reader, flags);
|
||||
break;
|
||||
case ForeignMetadataInitialization:
|
||||
foreign = new TargetForeignMetadataInitialization(reader);
|
||||
break;
|
||||
}
|
||||
|
||||
if (flags.isGeneric() &&
|
||||
flags.hasCanonicalMetadataPrespecializationsOrSingletonMetadataPonter()) {
|
||||
throw new IOException("Unimplemented TargetCanonicalSpecializedMetadatas detected.");
|
||||
}
|
||||
|
||||
if (flags.hasInvertableProtocols()) {
|
||||
throw new IOException("Unimplemented InvertibleProtocolSet detected.");
|
||||
}
|
||||
|
||||
if (!flags.isGeneric() &&
|
||||
flags.hasCanonicalMetadataPrespecializationsOrSingletonMetadataPonter()) {
|
||||
throw new IOException("Unimplemented TargetSingletonMetadataPointer detected.");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the number of stored properties in the struct. If there is a field offset vector,
|
||||
* this is its length.
|
||||
|
||||
* @return The number of stored properties in the struct. If there is a field offset vector,
|
||||
* this is its length.
|
||||
* {@return the number of stored properties in the struct (if there is a field offset vector,
|
||||
* this is its length}
|
||||
*/
|
||||
public int getNumFields() {
|
||||
return numFields;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the offset of the field offset vector for this struct's stored properties in its
|
||||
* metadata, if any. 0 means there is no field offset vector.
|
||||
*
|
||||
* @return The offset of the field offset vector for this struct's stored properties in its
|
||||
* metadata, if any. 0 means there is no field offset vector.
|
||||
* {@return the offset of the field offset vector for this struct's stored properties in its
|
||||
* metadata, if any. 0 means there is no field offset vector}
|
||||
*/
|
||||
public int getFieldOffsetVectorOffset() {
|
||||
return fieldOffsetVectorOffset;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@return the {@link TargetTypeGenericContextDescriptorHeader}, or {@code null} if it doesn't
|
||||
* exist}
|
||||
*/
|
||||
public TargetTypeGenericContextDescriptorHeader getGenericHeader() {
|
||||
return genericHeader;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@return the {@link TargetSingletonMetadataInitialization}, or {@code null} if it doesn't
|
||||
* exist}
|
||||
*/
|
||||
public TargetSingletonMetadataInitialization getTargetSingletonMetadataInitialization() {
|
||||
return singleton;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@return the {@link TargetForeignMetadataInitialization}, or {@code null} if it doesn't
|
||||
* exist}
|
||||
*/
|
||||
public TargetForeignMetadataInitialization getTargetForeignMetadataInitialization() {
|
||||
return foreign;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<SwiftTypeMetadataStructure> getTrailingObjects() {
|
||||
List<SwiftTypeMetadataStructure> ret = new ArrayList<>();
|
||||
if (genericHeader != null) {
|
||||
ret.add(genericHeader);
|
||||
ret.addAll(genericHeader.getTrailingObjects());
|
||||
}
|
||||
if (singleton != null) {
|
||||
ret.add(singleton);
|
||||
}
|
||||
if (foreign != null) {
|
||||
ret.add(foreign);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getStructureName() {
|
||||
return TargetStructDescriptor.class.getSimpleName();
|
||||
@@ -79,13 +149,12 @@ public final class TargetStructDescriptor extends TargetTypeContextDescriptor {
|
||||
|
||||
@Override
|
||||
public DataType toDataType() throws DuplicateNameException, IOException {
|
||||
StructureDataType struct = new StructureDataType(getStructureName(), 0);
|
||||
StructureDataType struct = new StructureDataType(CATEGORY_PATH, getStructureName(), 0);
|
||||
struct.add(super.toDataType(), super.getStructureName(), "");
|
||||
struct.add(DWORD, "NumFields",
|
||||
"The number of stored properties in the struct. If there is a field offset vector, this is its length.");
|
||||
struct.add(DWORD, "FieldOffsetVectorOffset",
|
||||
"The offset of the field offset vector for this struct's stored properties in its metadata, if any. 0 means there is no field offset vector.");
|
||||
struct.setCategoryPath(new CategoryPath(DATA_TYPE_CATEGORY));
|
||||
return struct;
|
||||
}
|
||||
|
||||
|
||||
@@ -20,11 +20,12 @@ import java.util.Map;
|
||||
|
||||
import ghidra.app.util.bin.BinaryReader;
|
||||
import ghidra.app.util.bin.format.swift.SwiftUtils;
|
||||
import ghidra.program.model.data.*;
|
||||
import ghidra.program.model.data.DataType;
|
||||
import ghidra.program.model.data.StructureDataType;
|
||||
import ghidra.util.exception.DuplicateNameException;
|
||||
|
||||
/**
|
||||
* Represents a Swift TargetTypeContextDescriptor structure
|
||||
* Represents a Swift {@code TargetTypeContextDescriptor} structure
|
||||
*
|
||||
* @see <a href="https://github.com/swiftlang/swift/blob/main/include/swift/ABI/Metadata.h">swift/ABI/Metadata.h</a>
|
||||
*/
|
||||
@@ -48,39 +49,32 @@ public class TargetTypeContextDescriptor extends TargetContextDescriptor {
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the name of the type
|
||||
*
|
||||
* @return The name of the type
|
||||
* {@return the name of the type}
|
||||
*/
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the pointer to the metadata access function for this type
|
||||
*
|
||||
* @return The pointer to the metadata access function for this type
|
||||
* {@return the pointer to the metadata access function for this type}
|
||||
*/
|
||||
public int getAccessFunctionPtr() {
|
||||
return accessFunctionPtr;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the pointer to the field descriptor for the type, if any
|
||||
*
|
||||
* @return The pointer to the field descriptor for the type, if any
|
||||
* {@return the pointer to the field descriptor for the type, if any}
|
||||
*/
|
||||
public int getFields() {
|
||||
return fields;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets this {@link TargetTypeContextDescriptor}'s {@link FieldDescriptor}
|
||||
* {@return this {@link TargetTypeContextDescriptor}'s {@link FieldDescriptor}, or {@code null}
|
||||
* if it doesn't have one}
|
||||
*
|
||||
* @param fieldDescriptors A {@link Map} of {@link FieldDescriptor}'s keyed by their base
|
||||
* addresses
|
||||
* @return This {@link TargetTypeContextDescriptor}'s {@link FieldDescriptor}, or null if it
|
||||
* doesn't have one
|
||||
*/
|
||||
public FieldDescriptor getFieldDescriptor(Map<Long, FieldDescriptor> fieldDescriptors) {
|
||||
FieldDescriptor fieldDescriptor =
|
||||
@@ -104,9 +98,7 @@ public class TargetTypeContextDescriptor extends TargetContextDescriptor {
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets this class's structure name (will not be affected by subclass's name)
|
||||
*
|
||||
* @return This class's structure name
|
||||
* {@return this class's structure name (will not be affected by subclass's name)}
|
||||
*/
|
||||
private final String getMyStructureName() {
|
||||
return TargetTypeContextDescriptor.class.getSimpleName();
|
||||
@@ -114,14 +106,13 @@ public class TargetTypeContextDescriptor extends TargetContextDescriptor {
|
||||
|
||||
@Override
|
||||
public DataType toDataType() throws DuplicateNameException, IOException {
|
||||
StructureDataType struct = new StructureDataType(getMyStructureName(), 0);
|
||||
StructureDataType struct = new StructureDataType(CATEGORY_PATH, getMyStructureName(), 0);
|
||||
struct.add(super.toDataType(), super.getStructureName(), "");
|
||||
struct.add(SwiftUtils.PTR_STRING, "Name", "The name of the type");
|
||||
struct.add(SwiftUtils.PTR_RELATIVE, "AccessFunctionPtr",
|
||||
"A pointer to the metadata access function for this type");
|
||||
struct.add(SwiftUtils.PTR_RELATIVE, "Fields",
|
||||
"A pointer to the field descriptor for the type, if any");
|
||||
struct.setCategoryPath(new CategoryPath(DATA_TYPE_CATEGORY));
|
||||
return struct;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,98 @@
|
||||
/* ###
|
||||
* IP: GHIDRA
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package ghidra.app.util.bin.format.swift.types;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
|
||||
import ghidra.app.util.bin.BinaryReader;
|
||||
import ghidra.app.util.bin.format.swift.SwiftTypeMetadataStructure;
|
||||
import ghidra.app.util.bin.format.swift.SwiftUtils;
|
||||
import ghidra.program.model.data.DataType;
|
||||
import ghidra.program.model.data.StructureDataType;
|
||||
import ghidra.util.exception.DuplicateNameException;
|
||||
|
||||
/**
|
||||
* Represents a Swift {@code TargetTypeGenericContextDescriptorHeader} structure
|
||||
*
|
||||
* @see <a href="https://github.com/swiftlang/swift/blob/main/include/swift/ABI/Metadata.h">swift/ABI/Metadata.h</a>
|
||||
*/
|
||||
public class TargetTypeGenericContextDescriptorHeader extends SwiftTypeMetadataStructure {
|
||||
|
||||
private int instantiationCache;
|
||||
private int defaultInstallationPattern;
|
||||
private TargetGenericContextDescriptorHeader base;
|
||||
|
||||
/**
|
||||
* Creates a new {@link TargetTypeGenericContextDescriptorHeader}
|
||||
*
|
||||
* @param reader A {@link BinaryReader} positioned at the start of the structure
|
||||
* @throws IOException if there was an IO-related problem creating the structure
|
||||
*/
|
||||
public TargetTypeGenericContextDescriptorHeader(BinaryReader reader) throws IOException {
|
||||
super(reader.getPointerIndex());
|
||||
instantiationCache = reader.readNextInt();
|
||||
defaultInstallationPattern = reader.readNextInt();
|
||||
base = new TargetGenericContextDescriptorHeader(reader);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@return the metadata instantiation cache}
|
||||
*/
|
||||
public int getInstantiationCache() {
|
||||
return instantiationCache;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@return the default instantiation pattern}
|
||||
*/
|
||||
public int getDefaultInstallationPattern() {
|
||||
return defaultInstallationPattern;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@return the base header}
|
||||
*/
|
||||
public TargetGenericContextDescriptorHeader getBaseHeader() {
|
||||
return base;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<SwiftTypeMetadataStructure> getTrailingObjects() {
|
||||
return base.getTrailingObjects();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getStructureName() {
|
||||
return TargetTypeGenericContextDescriptorHeader.class.getSimpleName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDescription() {
|
||||
return "type generic context descriptor header";
|
||||
}
|
||||
|
||||
@Override
|
||||
public DataType toDataType() throws DuplicateNameException, IOException {
|
||||
StructureDataType struct = new StructureDataType(CATEGORY_PATH, getStructureName(), 0);
|
||||
struct.add(SwiftUtils.PTR_RELATIVE, "InstantiationCache",
|
||||
"The metadata instantiation cache.");
|
||||
struct.add(SwiftUtils.PTR_RELATIVE, "DefaultInstantiationPattern",
|
||||
"The default instantiation pattern.");
|
||||
struct.add(base.toDataType(), "Base", "The base header.");
|
||||
return struct;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,80 @@
|
||||
/* ###
|
||||
* IP: GHIDRA
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package ghidra.app.util.bin.format.swift.types;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import ghidra.app.util.bin.BinaryReader;
|
||||
import ghidra.app.util.bin.format.swift.SwiftTypeMetadataStructure;
|
||||
import ghidra.program.model.data.DataType;
|
||||
import ghidra.program.model.data.StructureDataType;
|
||||
import ghidra.util.exception.DuplicateNameException;
|
||||
|
||||
/**
|
||||
* Represents a Swift {@code TargetVTableDescriptorHeader} structure
|
||||
*
|
||||
* @see <a href="https://github.com/swiftlang/swift/blob/main/include/swift/ABI/Metadata.h">swift/ABI/Metadata.h</a>
|
||||
*/
|
||||
public class TargetVTableDescriptorHeader extends SwiftTypeMetadataStructure {
|
||||
|
||||
private long vtableOffset;
|
||||
private long vtableSize;
|
||||
|
||||
/**
|
||||
* Creates a new {@link TargetVTableDescriptorHeader}
|
||||
*
|
||||
* @param reader A {@link BinaryReader} positioned at the start of the structure
|
||||
* @throws IOException if there was an IO-related problem creating the structure
|
||||
*/
|
||||
public TargetVTableDescriptorHeader(BinaryReader reader) throws IOException {
|
||||
super(reader.getPointerIndex());
|
||||
vtableOffset = reader.readNextUnsignedInt();
|
||||
vtableSize = reader.readNextUnsignedInt();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@return the offset of the vtable for this class in its metadata, if any, in words}
|
||||
*/
|
||||
public long getVTableOffset() {
|
||||
return vtableOffset;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@return the number of vtable entries}
|
||||
*/
|
||||
public long getVTableSize() {
|
||||
return vtableSize;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getStructureName() {
|
||||
return TargetVTableDescriptorHeader.class.getSimpleName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDescription() {
|
||||
return "vtable descriptor header";
|
||||
}
|
||||
|
||||
@Override
|
||||
public DataType toDataType() throws DuplicateNameException, IOException {
|
||||
StructureDataType struct = new StructureDataType(CATEGORY_PATH, getStructureName(), 0);
|
||||
struct.add(DWORD, "VTableOffset",
|
||||
"The offset of the vtable for this class in its metadata, if any, in words.");
|
||||
struct.add(DWORD, "VTableSize", "The number of vtable entries.");
|
||||
return struct;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,76 @@
|
||||
/* ###
|
||||
* IP: GHIDRA
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package ghidra.app.util.bin.format.swift.types;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Arrays;
|
||||
|
||||
import ghidra.app.util.bin.StructConverter;
|
||||
import ghidra.app.util.bin.format.swift.SwiftTypeMetadataStructure;
|
||||
import ghidra.program.model.data.DataType;
|
||||
import ghidra.program.model.data.EnumDataType;
|
||||
import ghidra.util.exception.DuplicateNameException;
|
||||
|
||||
/**
|
||||
* Swift {@code TypeReferenceKind} values
|
||||
*
|
||||
* @see <a href="https://github.com/swiftlang/swift/blob/main/include/swift/ABI/MetadataValues.h">swift/ABI/MetadataValues.h</a>
|
||||
*/
|
||||
public enum TypeReferenceKind implements StructConverter {
|
||||
|
||||
DirectTypeDescriptor(0),
|
||||
IndirectTypeDescriptor(1),
|
||||
DirectObjCClassName(2),
|
||||
IndirectObjCClass(3);
|
||||
|
||||
private int value;
|
||||
|
||||
/**
|
||||
* Creates a new {@link TypeReferenceKind}
|
||||
*
|
||||
* @param value The kind value
|
||||
*/
|
||||
private TypeReferenceKind(int value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@return the kind value}
|
||||
*/
|
||||
public int getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@return the {@link TypeReferenceKind} with the given kind value, or {@code null} if it
|
||||
* does not exist}
|
||||
*
|
||||
* @param value The kind value to get the value of
|
||||
*/
|
||||
public static TypeReferenceKind valueOf(int value) {
|
||||
return Arrays.stream(values()).filter(e -> e.getValue() == value).findFirst().orElse(null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public DataType toDataType() throws DuplicateNameException, IOException {
|
||||
EnumDataType dt = new EnumDataType(SwiftTypeMetadataStructure.CATEGORY_PATH,
|
||||
TypeReferenceKind.class.getSimpleName(), 1);
|
||||
for (TypeReferenceKind kind : values()) {
|
||||
dt.add(kind.name(), kind.getValue());
|
||||
}
|
||||
return dt;
|
||||
}
|
||||
}
|
||||
@@ -56,6 +56,7 @@ public enum SwiftDemangledNodeKind {
|
||||
LazyProtocolWitnessTableAccessor,
|
||||
LocalDeclName,
|
||||
MergedFunction,
|
||||
MethodDescriptor,
|
||||
ModifyAccessor,
|
||||
Module,
|
||||
ModuleDescriptor,
|
||||
|
||||
@@ -87,6 +87,7 @@ public abstract class SwiftNode {
|
||||
case LazyProtocolWitnessTableAccessor -> new SwiftLazyProtocolWitnessTableAccessorNode();
|
||||
case LocalDeclName -> new SwiftLocalDeclNameNode();
|
||||
case MergedFunction -> new SwiftGenericPassthroughNode();
|
||||
case MethodDescriptor -> new SwiftGenericDescriptorNode();
|
||||
case ModifyAccessor -> new SwiftModifyAccessorNode();
|
||||
case Module -> new SwiftGenericTextNode();
|
||||
case ModuleDescriptor -> new SwiftGenericDescriptorNode();
|
||||
|
||||
Reference in New Issue
Block a user