GP-4306 - PDB - cleanup some types pertaining to vftptrs and methods

This commit is contained in:
ghizard 2024-02-09 09:23:56 -05:00
parent bc24351495
commit 1470713dbb
11 changed files with 154 additions and 54 deletions

View file

@ -104,8 +104,9 @@ public abstract class AbstractFieldListMsType extends AbstractMsType {
}
/**
* Returns the (ordered?) {@link List}<{@link AbstractMsType}> of type members types of
* this field list.
* Returns the (ordered?) {@link List}<{@link MsTypeField}> of type members types of
* this field list. This is a hodge-podge of other types form the field list. This list
* should generally not be used outside of this class
* @return Field list.
*/
public List<MsTypeField> getMemberList() {
@ -113,7 +114,7 @@ public abstract class AbstractFieldListMsType extends AbstractMsType {
}
/**
* Returns the (ordered?) {@link List}&lt;{@link AbstractMsType}&gt; of other types. (We have
* Returns the (ordered?) {@link List}&lt;{@link MsTypeField}&gt; of other types. (We have
* separated these out, but are unsure about what they are at this time.)
* @return List of other types.
*/
@ -122,7 +123,7 @@ public abstract class AbstractFieldListMsType extends AbstractMsType {
}
/**
* Returns the (ordered?) {@link List}&lt;{@link AbstractMsType}&gt; of non-static members
* Returns the (ordered?) {@link List}&lt;{@link AbstractMemberMsType}&gt; of non-static members
* from this field list
* @return non-static members
*/
@ -131,8 +132,17 @@ public abstract class AbstractFieldListMsType extends AbstractMsType {
}
/**
* Returns the (ordered?) {@link List}&lt;{@link AbstractMsType}&gt; of VFT pointer records
* from this field list
* Returns the (ordered?) {@link List}&lt;{@link AbstractStaticMemberMsType}&gt; of static
* members from this field list
* @return non-static members
*/
public List<AbstractStaticMemberMsType> getStaticMembers() {
return staticMemberList;
}
/**
* Returns the (ordered?) {@link List}&lt;{@link AbstractVirtualFunctionTablePointerMsType}&gt;
* of VFT pointer records from this field list
* @return VFT pointer records
*/
public List<AbstractVirtualFunctionTablePointerMsType> getVftPointers() {
@ -140,9 +150,9 @@ public abstract class AbstractFieldListMsType extends AbstractMsType {
}
/**
* Returns the (ordered?) {@link List}&lt;{@link AbstractNestedTypeMsType}&gt; of enumerates
* from this field list
* @return enumerates
* Returns the (ordered?) {@link List}&lt;{@link AbstractNestedTypeMsType}&gt; of nested
* types from this field list
* @return nested types
*/
public List<AbstractNestedTypeMsType> getNestedTypes() {
return nestedTypeList;

View file

@ -43,6 +43,31 @@ public abstract class AbstractMethodRecordMs extends AbstractParsableItem {
this.pdb = pdb;
}
/**
* Returns the attributes of this procedure
* @return the attributes
*/
public ClassFieldMsAttributes getAttributes() {
return attributes;
}
/**
* Returns the record number of the data type (?) for this procedure
* @return the record number
*/
public RecordNumber getProcedureTypeRecordNumber() {
return procedureRecordNumber;
}
/**
* Returns the offset of the procedure in the VFTable if intro/virtual. Value of -1 means
* there was not a value
* @return the offset
*/
public long getOptionalOffset() {
return optionalOffset;
}
@Override
public void emit(StringBuilder builder) {
// Making this up; no API for output.

View file

@ -25,7 +25,7 @@ import ghidra.app.util.bin.format.pdb2.pdbreader.*;
*/
public abstract class AbstractOneMethodMsType extends AbstractMsType implements MsTypeField {
protected ClassFieldMsAttributes attribute;
protected ClassFieldMsAttributes attributes;
protected RecordNumber procedureTypeRecordNumber;
protected long offsetInVFTableIfIntroVirtual;
protected String name;
@ -41,11 +41,11 @@ public abstract class AbstractOneMethodMsType extends AbstractMsType implements
public AbstractOneMethodMsType(AbstractPdb pdb, PdbByteReader reader, int recordNumberSize,
StringParseType strType) throws PdbException {
super(pdb, reader);
attribute = new ClassFieldMsAttributes(reader);
attributes = new ClassFieldMsAttributes(reader);
procedureTypeRecordNumber =
RecordNumber.parse(pdb, reader, RecordCategory.TYPE, recordNumberSize);
if ((attribute.getProperty() == ClassFieldMsAttributes.Property.INTRO) ||
(attribute.getProperty() == ClassFieldMsAttributes.Property.INTRO_PURE)) {
if ((attributes.getProperty() == ClassFieldMsAttributes.Property.INTRO) ||
(attributes.getProperty() == ClassFieldMsAttributes.Property.INTRO_PURE)) {
offsetInVFTableIfIntroVirtual = reader.parseUnsignedIntVal();
}
else {
@ -55,12 +55,41 @@ public abstract class AbstractOneMethodMsType extends AbstractMsType implements
reader.skipPadding();
}
@Override
public String getName() {
return name;
}
/**
* Returns the record number of the data type for this procedure
* @return the record number
*/
public RecordNumber getProcedureTypeRecordNumber() {
return procedureTypeRecordNumber;
}
/**
* Returns the attributes of this procedure
* @return the attributes
*/
public ClassFieldMsAttributes getAttributes() {
return attributes;
}
/**
* Returns the offset of the procedure in the VFTable if intro/virtual
* @return the offset
*/
public long getOffsetInVFTableIfIntroVirtual() {
return offsetInVFTableIfIntroVirtual;
}
@Override
public void emit(StringBuilder builder, Bind bind) {
// No API for this. Just outputting something that might be useful.
// At this time, not doing anything with bind here; don't think it is warranted.
builder.append("<");
builder.append(attribute);
builder.append(attributes);
builder.append(": ");
builder.append(pdb.getTypeRecord(procedureTypeRecordNumber));
builder.append(",");

View file

@ -47,6 +47,27 @@ public abstract class AbstractOverloadedMethodMsType extends AbstractMsType impl
}
@Override
public String getName() {
return name;
}
/**
* Returns the number of methods overloaded with the name
* @return the number of methods
*/
public int getCount() {
return count;
}
/**
* Returns the record number of the method list for this overloaded method name
* @return the record number
*/
public RecordNumber getTypeMethodListRecordNumber() {
return methodListRecordNumber;
}
@Override
public void emit(StringBuilder builder, Bind bind) {
// No API for this. Just outputting something that might be useful.

View file

@ -25,7 +25,7 @@ import ghidra.app.util.bin.format.pdb2.pdbreader.*;
*/
public abstract class AbstractStaticMemberMsType extends AbstractMsType implements MsTypeField {
protected ClassFieldMsAttributes attribute;
protected ClassFieldMsAttributes attributes;
protected RecordNumber fieldTypeRecordNumber;
protected String name;
@ -43,13 +43,29 @@ public abstract class AbstractStaticMemberMsType extends AbstractMsType implemen
return name;
}
/**
* Returns the record number of the data type for this member
* @return the record number
*/
public RecordNumber getFieldTypeRecordNumber() {
return fieldTypeRecordNumber;
}
/**
* Returns the attributes of this procedure
* @return the attributes
*/
public ClassFieldMsAttributes getAttributes() {
return attributes;
}
@Override
public void emit(StringBuilder builder, Bind bind) {
// No API for this.
builder.append(name);
pdb.getTypeRecord(fieldTypeRecordNumber).emit(builder, Bind.NONE);
StringBuilder myBuilder = new StringBuilder();
myBuilder.append(attribute);
myBuilder.append(attributes);
myBuilder.append(": ");
builder.insert(0, myBuilder);
}

View file

@ -37,12 +37,6 @@ public abstract class AbstractVirtualFunctionTablePointerMsType extends Abstract
super(pdb, reader);
}
@Override
public void emit(StringBuilder builder, Bind bind) {
builder.append("VFTablePtr: ");
builder.append(pdb.getTypeRecord(pointerTypeRecordNumber));
}
/**
* Returns the record number of the pointer type.
* @return the record number of the pointer type.
@ -51,4 +45,18 @@ public abstract class AbstractVirtualFunctionTablePointerMsType extends Abstract
return pointerTypeRecordNumber;
}
/**
* Returns the pointer offset.
* @return the offset.
*/
public int getOffset() {
return 0;
}
@Override
public void emit(StringBuilder builder, Bind bind) {
builder.append("VFTablePtr: ");
builder.append(pdb.getTypeRecord(pointerTypeRecordNumber));
}
}

View file

@ -23,9 +23,9 @@ import ghidra.app.util.bin.format.pdb2.pdbreader.*;
* Note: we do not necessarily understand each of these data type classes. Refer to the
* base class for more information.
*/
public abstract class AbstractVirtualFunctionTablePointerWithOffsetMsType extends AbstractMsType {
public abstract class AbstractVirtualFunctionTablePointerWithOffsetMsType
extends AbstractVirtualFunctionTablePointerMsType {
protected RecordNumber pointerTypeRecordNumber;
protected int offset;
/**
@ -45,18 +45,11 @@ public abstract class AbstractVirtualFunctionTablePointerWithOffsetMsType extend
offset = reader.parseInt();
}
@Override
public void emit(StringBuilder builder, Bind bind) {
builder.append("VFTablePtr<off=");
builder.append(offset);
builder.append(">: ");
builder.append(pdb.getTypeRecord(pointerTypeRecordNumber));
}
/**
* Returns the record number of the pointer type.
* @return the record number of the pointer type.
*/
@Override
public RecordNumber getPointerTypeRecordNumber() {
return pointerTypeRecordNumber;
}
@ -65,8 +58,17 @@ public abstract class AbstractVirtualFunctionTablePointerWithOffsetMsType extend
* Returns the pointer offset.
* @return the offset.
*/
@Override
public int getOffset() {
return offset;
}
@Override
public void emit(StringBuilder builder, Bind bind) {
builder.append("VFTablePtr<off=");
builder.append(offset);
builder.append(">: ");
builder.append(pdb.getTypeRecord(pointerTypeRecordNumber));
}
}

View file

@ -36,7 +36,7 @@ public class StaticMember16MsType extends AbstractStaticMemberMsType {
public StaticMember16MsType(AbstractPdb pdb, PdbByteReader reader) throws PdbException {
super(pdb, reader);
fieldTypeRecordNumber = RecordNumber.parse(pdb, reader, RecordCategory.TYPE, 16);
attribute = new ClassFieldMsAttributes(reader);
attributes = new ClassFieldMsAttributes(reader);
name = reader.parseString(pdb, StringParseType.StringSt);
reader.skipPadding();
}

View file

@ -35,7 +35,7 @@ public class StaticMemberMsType extends AbstractStaticMemberMsType {
*/
public StaticMemberMsType(AbstractPdb pdb, PdbByteReader reader) throws PdbException {
super(pdb, reader);
attribute = new ClassFieldMsAttributes(reader);
attributes = new ClassFieldMsAttributes(reader);
fieldTypeRecordNumber = RecordNumber.parse(pdb, reader, RecordCategory.TYPE, 32);
name = reader.parseString(pdb, StringParseType.StringNt);
reader.align4();

View file

@ -35,7 +35,7 @@ public class StaticMemberStMsType extends AbstractStaticMemberMsType {
*/
public StaticMemberStMsType(AbstractPdb pdb, PdbByteReader reader) throws PdbException {
super(pdb, reader);
attribute = new ClassFieldMsAttributes(reader);
attributes = new ClassFieldMsAttributes(reader);
fieldTypeRecordNumber = RecordNumber.parse(pdb, reader, RecordCategory.TYPE, 32);
name = reader.parseString(pdb, StringParseType.StringSt);
reader.align4();

View file

@ -19,7 +19,6 @@ import ghidra.app.util.bin.format.pdb2.pdbreader.PdbException;
import ghidra.app.util.bin.format.pdb2.pdbreader.RecordNumber;
import ghidra.app.util.bin.format.pdb2.pdbreader.type.*;
import ghidra.program.model.data.DataType;
import ghidra.program.model.data.VoidDataType;
import ghidra.util.exception.CancelledException;
/**
@ -36,7 +35,8 @@ public class VirtualFunctionTablePointerTypeApplier extends MsTypeApplier {
* @param applicator {@link DefaultPdbApplicator} for which this class is working.
* @throws IllegalArgumentException Upon invalid arguments.
*/
public VirtualFunctionTablePointerTypeApplier(DefaultPdbApplicator applicator) throws IllegalArgumentException {
public VirtualFunctionTablePointerTypeApplier(DefaultPdbApplicator applicator)
throws IllegalArgumentException {
super(applicator);
}
@ -61,20 +61,10 @@ public class VirtualFunctionTablePointerTypeApplier extends MsTypeApplier {
throws PdbException, CancelledException {
// usually no record number, so cannot retrieve or store from/to applicator
DataType dataType;
if (type instanceof AbstractVirtualFunctionTablePointerWithOffsetMsType vftPtrWOffset) {
dataType =
applyPointer(vftPtrWOffset.getPointerTypeRecordNumber(), fixupContext, breakCycle);
}
else if (type instanceof AbstractVirtualFunctionTablePointerMsType vftPtr) {
dataType = applyPointer(vftPtr.getPointerTypeRecordNumber(), fixupContext, breakCycle);
}
else {
dataType = VoidDataType.dataType;
applicator.appendLogMsg(
"PDB Warning: Type not handled: " + type.getClass().getSimpleName());
}
AbstractVirtualFunctionTablePointerMsType vftPtrType = validateType(type);
RecordNumber recordNumber = vftPtrType.getPointerTypeRecordNumber();
DataType dataType = applyPointer(recordNumber, fixupContext, breakCycle);
// unlike regular pointer, we are resolving vft pointer
dataType = applicator.resolve(dataType);
@ -93,15 +83,14 @@ public class VirtualFunctionTablePointerTypeApplier extends MsTypeApplier {
return null;
}
private static AbstractMsType validateType(AbstractMsType type)
private static AbstractVirtualFunctionTablePointerMsType validateType(AbstractMsType type)
throws IllegalArgumentException {
if (!(type instanceof AbstractVirtualFunctionTablePointerMsType) &&
!(type instanceof AbstractVirtualFunctionTablePointerWithOffsetMsType)) {
if (!(type instanceof AbstractVirtualFunctionTablePointerMsType vftPtrType)) {
throw new IllegalArgumentException(
"PDB Incorrectly applying " + type.getClass().getSimpleName() + " to " +
VirtualFunctionTablePointerTypeApplier.class.getSimpleName());
}
return type;
return vftPtrType;
}
}